Skip to content

Commit

Permalink
v.2.12.2
Browse files Browse the repository at this point in the history
## [2.12.2] - 06.03.2024
- Uusi ominaisuus: Vapaavalintaiset ajanjaksot
  - Voi valita yhden tai kaksi vapaavalintaista ajanjaksoa ja niille halutut tuntimääräät
  - Esim *"kolme halvinta tuntia yöllä kello 00-06 väliltä ja yksi halvin tunti illalla kello 18-21 väliltä"*
  • Loading branch information
jisotalo authored Mar 6, 2024
1 parent 633a4ea commit ed13adb
Show file tree
Hide file tree
Showing 18 changed files with 346 additions and 146 deletions.
13 changes: 0 additions & 13 deletions .github/ISSUE_TEMPLATE/bugiraportti.md

This file was deleted.

10 changes: 0 additions & 10 deletions .github/ISSUE_TEMPLATE/muu-asia.md

This file was deleted.

9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

# Suomeksi
## [2.12.2] - 06.03.2024
- Uusi ominaisuus: Vapaavalintaiset ajanjaksot
- Voi valita yhden tai kaksi vapaavalintaista ajanjaksoa ja niille halutut tuntimääräät
- Esim *"kolme halvinta tuntia yöllä kello 00-06 väliltä ja yksi halvin tunti illalla kello 18-21 väliltä"*

## [2.11.2] - 05.02.2024
- Bugikorjaus: Hinnan keskiarvon laskennan virhe
- Alussa laskenta näytti oikein, mutta joka päivä virhe alkoi kasvaa suuremmaksi
Expand Down Expand Up @@ -145,6 +150,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Versio 2 julkaistu (tehty täysin uusiksi)

# In English
## [2.12.2] - 06.03.2024
- New feature: custom hour ranges
- Can configure one or two custom time ranges and number of cheapest hours for each

## [2.11.2] - 05.02.2024
- Bug fix: Average price calculation

Expand Down
132 changes: 104 additions & 28 deletions README.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/shelly-porssisahko-addon-temp-hours.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/shelly-porssisahko-addon-temp.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/shelly-porssisahko-ht-sensor-temp.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/shelly-porssisahko-override-avg-price.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/shelly-porssisahko-user-config.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/shelly-porssisahko.js

Large diffs are not rendered by default.

19 changes: 12 additions & 7 deletions shelly-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ const { promisify } = require('node:util');
const dgram = require('node:dgram');

//Settings
const BASE_URL = "http://192.168.68.105";
const BASE_URL = "http://192.168.68.100";
const RPC_URL = `${BASE_URL}/rpc`;
const MAX_CODE_CHUNK_SIZE = 1024;
const GZIP = true;
const UDP_DEBUG_PORT = 8001;
const MAX_STATIC_FILE_SIZE = 3000; //Max file size served with shelly HTTP in bytes
const MAX_SCRIPT_SIZE = 15000; //Max script size allowed in bytes
const MAX_STATIC_FILE_SIZE = -1; //Max file size served with shelly HTTP in bytes
const MAX_SCRIPT_SIZE = -1; //Max script size allowed in bytes

const log = (...args) => {
let time = new Date().toISOString();
Expand Down Expand Up @@ -200,7 +200,6 @@ const createDistFile = async (filePath, distPath, isShellyScript) => {
log(`createDistFile(): Minifying script "${filePath}"...`);
let data = (await fs.readFile(filePath)).toString();

//TODO: Move this after minify()?
if (isShellyScript) {
let staticFileMatches = data.matchAll(/\#\[(.*)\]/gm);
for (const staticFileMatch of staticFileMatches) {
Expand Down Expand Up @@ -397,10 +396,12 @@ const printStats = async () => {
}

log(` ${file}`);
if (MAX_STATIC_FILE_SIZE - fileInfo.size < 100) {
if (MAX_STATIC_FILE_SIZE > 0 && MAX_STATIC_FILE_SIZE - fileInfo.size < 100) {
log(` ${(fileInfo.size / 1024.0).toFixed(1)} KB\t${(MAX_STATIC_FILE_SIZE - fileInfo.size)} bytes left (used ${(fileInfo.size / MAX_STATIC_FILE_SIZE * 100.0).toFixed(0)} %) <---- WARNING!!!`);
} else {
} else if (MAX_STATIC_FILE_SIZE > 0) {
log(` ${(fileInfo.size / 1024.0).toFixed(1)} KB\t${(MAX_STATIC_FILE_SIZE - fileInfo.size)} bytes left (used ${(fileInfo.size / MAX_STATIC_FILE_SIZE * 100.0).toFixed(0)} %)`);
} else {
log(` ${(fileInfo.size / 1024.0).toFixed(1)} KB`);
}
}

Expand All @@ -420,7 +421,11 @@ const printStats = async () => {
}

log(` ${file}`);
log(` ${(fileInfo.size / 1024.0).toFixed(1)} KB\t${(MAX_SCRIPT_SIZE - fileInfo.size)} bytes left (used ${(fileInfo.size / MAX_SCRIPT_SIZE * 100.0).toFixed(0)} %)`);
if (MAX_SCRIPT_SIZE > 0) {
log(` ${(fileInfo.size / 1024.0).toFixed(1)} KB\t${(MAX_SCRIPT_SIZE - fileInfo.size)} bytes left (used ${(fileInfo.size / MAX_SCRIPT_SIZE * 100.0).toFixed(0)} %)`);
} else {
log(` ${(fileInfo.size / 1024.0).toFixed(1)} KB`);
}
count++;
}
log('');
Expand Down
2 changes: 1 addition & 1 deletion shelly-library.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{
"fname": "dist/shelly-porssisahko.js",
"title": "Pörssisähköohjaus (shelly-porssisahko.js)",
"description": "Pörssisähköohjaus Shellyyn. Klikaa Insert code -painiketta skriptin asentamiseksi. Github-sivu: https://github.com/jisotalo/shelly-porssisahko"
"description": "Pörssisähköohjaus Shellyyn. Klikaa Import code -painiketta skriptin asentamiseksi. Github-sivu: https://github.com/jisotalo/shelly-porssisahko"
},
{
"fname": "dist/shelly-porssisahko-override-avg-price.js",
Expand Down
137 changes: 96 additions & 41 deletions src/shelly-porssisahko.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ let C_DEF = {
},
/** Settings for mode 2 (cheapest hours) */
m2: {
/** Period length [h] (example: 24 -> cheapest hours during 24h) */
/** Period length (-1 = custom range) [h] (example: 24 -> cheapest hours during 24h) */
per: 24,
/** How many cheapest hours */
cnt: 0,
Expand All @@ -48,7 +48,17 @@ let C_DEF = {
/** Should the hours be sequential / in a row [0/1] */
sq: 0,
/** Maximum price limit [c/kWh] */
m: 999
m: 999,
/** Custom period start hour */
ps: 0,
/** Custom period end hour */
pe: 23,
/** Custom period 2 start hour */
ps2: 0,
/** Custom period 2 end hour */
pe2: 23,
/** How many cheapest hours (custom period 2) */
cnt2: 0,
},
/** VAT added to spot price [%] */
vat: 24,
Expand Down Expand Up @@ -78,7 +88,7 @@ let C_DEF = {
let _ = {
s: {
/** version number */
v: "2.11.2",
v: "2.12.2",
/** Device name */
dn: '',
/** status as number */
Expand Down Expand Up @@ -170,6 +180,16 @@ function isCurrentHour(value, now) {
return diff >= 0 && diff < (60 * 60);
}

/**
* Limits the value to min..max range
* @param {number} min
* @param {number} value
* @param {number} max
*/
function limit(min, value, max) {
return Math.min(max, Math.max(min, value));
}

/**
* Returns epoch time (seconds) without decimals
*
Expand Down Expand Up @@ -256,7 +276,7 @@ function log(data) {
* Adds command to history
*/
function addHistory() {
while (_.h.length >= C_HIST) {
while (C_HIST > 0 && _.h.length >= C_HIST) {
_.h.splice(0, 1);
}
_.h.push([epoch(), cmd ? 1 : 0, _.s.st]);
Expand Down Expand Up @@ -815,43 +835,75 @@ function logic() {
}

} catch (err) {
log("logic() - virhe:" + err);
log("logic() - virhe:" + JSON.stringify(err));
loopRunning = false;
}
}

/**
* Returns true if current hour is one of the cheapest
*
* NOTE: Variables are here outside function() as it caused memory issues
* (for loop i variable suddenly changed to something very odd)
* Perhaps the stack was getting too full or something because of multiple for() loops?
* This worked!
* DEV. NOTE:
* Variables are intentionally in global scope outside isCheapestHour()
*
* There were memory issues with for-loops (random values)
* Perhaps the stack was getting too full or something because of multiple for() loops
*
* This fixes the operation
*/
let _perStart = 0;
let _ind = 0;
let _ind2 = 0;
let _i = 0;
let _j = 0;
let _k = 0;
let _inc = 0;
let _cnt = 0;
let _start = 0;
let _end = 0;
function isCheapestHour() {
if (_.c.m2.cn == 0) {
return;
}

//Safety check
_.c.m2.cnt = Math.min(_.c.m2.cnt, _.c.m2.per);
//Safety checks
_.c.m2.ps = limit(0, _.c.m2.ps, 23);
_.c.m2.pe = limit(_.c.m2.ps, _.c.m2.pe, 24);
_.c.m2.ps2 = limit(0, _.c.m2.ps2, 23);
_.c.m2.pe2 = limit(_.c.m2.ps2, _.c.m2.pe2, 24);
_.c.m2.cnt = limit(0, _.c.m2.cnt, _.c.m2.per > 0 ? _.c.m2.per : _.c.m2.pe - _.c.m2.ps);
_.c.m2.cnt2 = limit(0, _.c.m2.cnt2, _.c.m2.pe2 - _.c.m2.ps2);

//This is (and needs to be) 1:1 in both frontend and backend code
let cheapest = [];

for (_perStart = 0; _perStart < _.p[0].length; _perStart += _.c.m2.per) {
//Select increment (a little hacky - to support custom periods too)
_inc = _.c.m2.per < 0 ? 1 : _.c.m2.per;

for (_i = 0; _i < _.p[0].length; _i += _inc) {
_cnt = (_.c.m2.per == -2 && _i >= 1 ? _.c.m2.cnt2 : _.c.m2.cnt);

//Safety check
if (_cnt <= 0)
continue;

//Create array of indexes in selected period
let order = [];
for (ind = _perStart; ind < _perStart + _.c.m2.per; ind++) {

//If custom period -> select hours from that range. Otherwise use this period
_start = _i;
_end = (_i + _.c.m2.per);

if (_.c.m2.per < 0 && _i == 0) {
//Custom period 1
_start = _.c.m2.ps;
_end = _.c.m2.pe;

} else if (_.c.m2.per == -2 && _i == 1) {
//Custom period 2
_start = _.c.m2.ps2;
_end = _.c.m2.pe2;
}

for (_j = _start; _j < _end; _j++) {
//If we have less hours than 24 then skip the rest from the end
if (ind > _.p[0].length - 1)
if (_j > _.p[0].length - 1)
break;

order.push(ind);
order.push(_j);
}

if (_.c.m2.sq) {
Expand All @@ -860,40 +912,47 @@ function isCheapestHour() {
let avg = 999;
let startIndex = 0;

for (_ind = 0; _ind <= order.length - _.c.m2.cnt; _ind++) {
for (_j = 0; _j <= order.length - _cnt; _j++) {
let sum = 0;

//Calculate sum of these sequential hours
for (_ind2 = _ind; _ind2 < _ind + _.c.m2.cnt; _ind2++) {
sum += _.p[0][order[_ind2]][1];
for (_k = _j; _k < _j + _cnt; _k++) {
sum += _.p[0][order[_k]][1];
};

//If average price of these sequential hours is lower -> it's better
if (sum / _.c.m2.cnt < avg) {
avg = sum / _.c.m2.cnt;
startIndex = _ind;
if (sum / _cnt < avg) {
avg = sum / _cnt;
startIndex = _j;
}
}

for (_ind = startIndex; _ind < startIndex + _.c.m2.cnt; _ind++) {
cheapest.push(order[_ind]);
for (_j = startIndex; _j < startIndex + _cnt; _j++) {
cheapest.push(order[_j]);
}

} else {
//Sort indexes by price
for (_ind = 1; _ind < order.length; _ind++) {
let temp = order[_ind];
_j = 0;

for (_k = 1; _k < order.length; _k++) {
let temp = order[_k];

for (_ind2 = _ind - 1; _ind2 >= 0 && _.p[0][temp][1] < _.p[0][order[_ind2]][1]; _ind2--) {
order[_ind2 + 1] = order[_ind2];
for (_j = _k - 1; _j >= 0 && _.p[0][temp][1] < _.p[0][order[_j]][1]; _j--) {
order[_j + 1] = order[_j];
}
order[_ind2 + 1] = temp;
order[_j + 1] = temp;
}

//Select the cheapest ones
for (_ind = 0; _ind < _.c.m2.cnt; _ind++) {
cheapest.push(order[_ind]);
for (_j = 0; _j < _cnt; _j++) {
cheapest.push(order[_j]);
}
}

//If custom period, quit when all periods are done (1 or 2 periods)
if (_.c.m2.per == -1 || (_.c.m2.per == -2 && _i >= 1))
break;
}

//Check if current hour is cheap enough
Expand All @@ -910,10 +969,6 @@ function isCheapestHour() {
}
}

_perStart = null;
_ind = null;
_ind2 = null;

return res;
}

Expand Down
2 changes: 1 addition & 1 deletion src/statics/dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* This file is loaded only during local development
*/
/** URL of the shelly */
URL = "http://192.168.68.105";
URL = "http://192.168.68.100";

/** URL of the logic script */
URLS = `${URL}/script/1`;
Expand Down
6 changes: 3 additions & 3 deletions src/statics/s.css
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ body {
float: left;
}

.ts {
.ts, .h {
display: none;
}

Expand Down Expand Up @@ -128,7 +128,7 @@ table.cc>tbody>tr>td:first-child, .bg, table.sm tr:first-child {
}

@media(max-width: 480px) {
table.m>tbody>tr>td {
table.m>tbody>tr>td, label {
display: block;
width: 100%;
}
Expand Down Expand Up @@ -173,7 +173,7 @@ td {
}

.w180 {
width: 180px;
width: 185px;
}

.mt10 {
Expand Down
Loading

0 comments on commit ed13adb

Please sign in to comment.