From 7ea63898f7c877d92fa3e4ae81f93153c9d476ec Mon Sep 17 00:00:00 2001 From: Jussi Isotalo Date: Fri, 24 Nov 2023 20:37:28 +0200 Subject: [PATCH] ## [2.8.1] - 24.11.2023 (2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Jos laittelle ei ole annettu nimeä, näytetään nimen tilalla "Ei asetettu" - Päivitetty kääntämisprosessia --- CHANGELOG.md | 11 +++- README.md | 65 ++++++++++++++++-------- after-build.js | 2 +- dist/shelly-porssisahko-user-config.js | 2 +- dist/shelly-porssisahko-user-override.js | 4 +- dist/shelly-porssisahko.js | 2 +- package.json | 4 +- shelly-builder.js | 56 ++++++++++++-------- src/shelly-porssisahko.js | 2 +- src/statics/tab-status.js | 2 +- 10 files changed, 98 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e9951ee..2e2b91b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ 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.8.1] - 24.11.2023 (2) +- Jos laittelle ei ole annettu nimeä, näytetään nimen tilalla "Ei asetettu" +- Päivitetty kääntämisprosessia + ## [2.8.0] - 24.11.2023 - Uusi ominaisuus: Laitteen nimi näytetään tilasivulla - Asetetaan Shellyn omista asetuksista @@ -16,7 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Skriptin asetukset voidaan määrittää ilman web-käyttöliittymää skriptistä - Käyttäjä voi lisätä oman funktion `USER_CONFIG`, joka muuttaa asetukset - Mahdollistaa asetukset muuttamisen esim. Shellyn pilvipalvelun kautta (skriptiä editoimalla) - - Katso esimerkki: [https://github.com/jisotalo/shelly-porssisahko/#asetukset-suoraan-skriptiin-ilman-käyttöliittymää](https://github.com/jisotalo/shelly-porssisahko/#asetukset-suoraan-skriptiin-ilman-käyttöliittymää) + - Katso esimerkki: [https://github.com/jisotalo/shelly-porssisahko/#esimerkki-asetukset-suoraan-skriptiin-ilman-käyttöliittymää](https://github.com/jisotalo/shelly-porssisahko/#esimerkki-asetukset-suoraan-skriptiin-ilman-käyttöliittymää) ## [2.7.2] - 10.11.2023 - Bugikorjaus: Hintojen haku ei toiminut klo 00-02 välillä @@ -100,12 +104,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Versio 2 julkaistu (tehty täysin uusiksi) # In English +## [2.8.1] - 24.11.2023 (2) +- If device has no name, a description about it is shown + ## [2.8.0] - 24.11.2023 - New feature: Device name is shown in status page - New feature: User can add scripts to change the output command - See examples: [https://github.com/jisotalo/shelly-porssisahko/#lisätoiminnot-ja-omat-skriptit](https://github.com/jisotalo/shelly-porssisahko/#lisätoiminnot-ja-omat-skriptit) - New feature: user can add settings to the script instead of UI - - See example: [https://github.com/jisotalo/shelly-porssisahko/#asetukset-suoraan-skriptiin-ilman-käyttöliittymää](https://github.com/jisotalo/shelly-porssisahko/#asetukset-suoraan-skriptiin-ilman-käyttöliittymää) + - See example: [https://github.com/jisotalo/shelly-porssisahko/#esimerkki-asetukset-suoraan-skriptiin-ilman-käyttöliittymää](https://github.com/jisotalo/shelly-porssisahko/#esimerkki-asetukset-suoraan-skriptiin-ilman-käyttöliittymää) ## [2.7.2] - 10.11.2023 diff --git a/README.md b/README.md index 68a2922..139babe 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ Käyttää suoraan Viron kantaverkkoyhtiön [elering.ee](https://dashboard.eleri * Oma web-serveri Shellyn sisällä ja siinä pyörivä käyttöliittymä * Valvonta ja konfigurointi selaimen avulla * Ei tarvitse rekisteröityä mihinkään +* Konfiguroitavuus ja hienosäätö mahdollisesta skripteillä * Kolme ohjaustapaa: * **käsiohjaus** - yksinkertaisesti ohjaus päälle/pois * **hintaraja** - jos hinta on alle rajan, laitetaan ohjaus päälle @@ -50,10 +51,10 @@ Käyttää suoraan Viron kantaverkkoyhtiön [elering.ee](https://dashboard.eleri + [Ohjaustapa: Jakson halvimmat tunnit](#ohjaustapa-jakson-halvimmat-tunnit) + [Toiminnot](#toiminnot) - [Lisätoiminnot ja omat skriptit](#lisätoiminnot-ja-omat-skriptit) - + [Hinnan ja keskiarvon hyödyntäminen](#hinnan-ja-keskiarvon-hyödyntäminen) - + [Lämpötilaohjaus (Shelly Plus Add-On ja DS18B20)](#lämpötilaohjaus-shelly-plus-add-on-ja-ds18b20) - + [Ulkolämpötilan hakeminen sääpalvelusta ja sen hyödyntäminen](#ulkolämpötilan-hakeminen-sääpalvelusta-ja-sen-hyödyntäminen) - + [Asetukset suoraan skriptiin (ilman käyttöliittymää)](#asetukset-suoraan-skriptiin-ilman-käyttöliittymää) + + [Esimerkki: Hinnan ja keskiarvon hyödyntäminen](#esimerkki-hinnan-ja-keskiarvon-hyödyntäminen) + + [Esimerkki: Lämpötilaohjaus (Shelly Plus Add-On ja DS18B20)](#esimerkki-lämpötilaohjaus-shelly-plus-add-on-ja-ds18b20) + + [Esimerkki: Ulkolämpötilan hakeminen sääpalvelusta ja sen hyödyntäminen](#esimerkki-ulkolämpötilan-hakeminen-sääpalvelusta-ja-sen-hyödyntäminen) + + [Esimerkki: Asetukset suoraan skriptiin (ilman käyttöliittymää)](#esimerkki-asetukset-suoraan-skriptiin-ilman-käyttöliittymää) - [Kysymyksiä ja vastauksia](#kysymyksiä-ja-vastauksia) - [Teknistä tietoa ja kehitysympäristö](#teknistä-tietoa-ja-kehitysympäristö) + [Lyhyesti](#lyhyesti) @@ -223,25 +224,42 @@ Valitaan kolme perättäistä tuntia. Valitaan kello 17-19 koska niiden hinnan k ## Lisätoiminnot ja omat skriptit -Versiosta 2.8.0 lähtien voi skriptiin lisätä omaa toiminnallisuutta helposti. Jos päivität skriptin library-painikkeen kautta, omat lisäykset luonnollisesti poistuvat. +Versiosta 2.8.0 lähtien on mahdollista lisätä omaa toiminnallisuutta pörssisähköohjuksen rinnalle. Tämä tapahtuu lisäämällä omaa koodia skriptin perään, kuten alla olevassa kuvassa. -Kun skripti on todennut ohjauksen tilan, kutsuu se funktiota `USER_OVERRIDE`, mikäli se on määritelty. +**Library**-painikkeen alta löytyy myös näitä esimerkkejä. -`USER_OVERRIDE(cmd, state, callback)` +![image](https://github.com/jisotalo/shelly-porssisahko/assets/13457157/52837e3c-5b06-4929-8571-4676898d6dc1) + +**Ohjauksen muutokset (USER_OVERRIDE)** + +Kun skripti on todennut ohjauksen tilan, kutsuu se funktiota `USER_OVERRIDE`, mikäli se on määritelty. Tässä funktiossa voidaan vielä tehdä viime hetken muutoksia skriptin ohjaukseen. + +`USER_OVERRIDE(cmd: boolean, state: object, callback: function(boolean)) => void` | parametri | tyyppi | selite | | --- | --- | --- | | `cmd` | `boolean` | Skriptin määrittämä lopullinen komento (ennen mahdollista käänteistä ohjausta) | `state` | `object` | Skriptin tila. Selitykset koodissa: https://github.com/jisotalo/shelly-porssisahko/blob/master/src/shelly-porssisahko.js#L82 (esim `state.s.p.now`) | `callback` | `function(boolean)` | Takaisinkutsufunktio, jota **täytyy** kutsua lopullisella komennolla, esim: `callback(true)` +| *`paluuarvo`* | `void` | Ei paluuarvoa -Koodi siis lisätään pörssisähköskriptin perään, kuten alla kuvassa: -![image](https://github.com/jisotalo/shelly-porssisahko/assets/13457157/52837e3c-5b06-4929-8571-4676898d6dc1) +**Asetusten muuttaminen skriptistä (USER_CONFIG)** -### Hinnan ja keskiarvon hyödyntäminen +Kun skripti on hakenut asetukset muistista, kutsuu se funktiota `USER_CONFIG`, mikäli se on määritelty. Tässä funktiossa voidaan ylikirjoittaa yksittäisiä tai kaikki asetukset. Näin asetukset voidaan määrittää skriptissä ilman käyttöliittymää (esim. Shellyn pilvipalvelun kautta). + +`USER_CONFIG(config: object) => object` + +| parametri | tyyppi | selite | +| --- | --- | --- | +| `config` | `object` | Skriptin tämänhetkiset asetukset +| *`paluuarvo`* | `object` | Lopulliset asetukset, joita halutaan käyttää -*Huomaa: try..catch on tärkeä, jotta mahdollisen bugin sattuessa ohjaus toimii silti.* +### Esimerkki: Hinnan ja keskiarvon hyödyntäminen + +Tämä esimerkki näyttää kuinka voi hyödyntää hintatietoja ohjauksen hienosäätöön. + +*Huom: try..catch on tärkeä, jotta mahdollisen bugin sattuessa ohjaus ei lakkaa toimimasta* ```js function USER_OVERRIDE(cmd, state, callback) { @@ -263,17 +281,17 @@ function USER_OVERRIDE(cmd, state, callback) { } ``` -### Lämpötilaohjaus (Shelly Plus Add-On ja DS18B20) +### Esimerkki: Lämpötilaohjaus (Shelly Plus Add-On ja DS18B20) -Voit myös asentaa esimerkin **Library**-painikkeen takaa (kuten itse skriptin). - -*Huomaa: try..catch on tärkeä, jotta mahdollisen bugin sattuessa ohjaus toimii silti.* +Tämä esimerkki näyttää, kuinka voi hyödyntää lämpötilamittausta ohjauksen hienosäädössä. Tämän voit myös asentaa esimerkin **Library**-painikkeen takaa (kuten itse skriptin). Käyttää lämpötila-anturia, jonka id on 100. -* Jos lämpötila on yli 15 astetta, asetetaan lähtö aina pois +* Jos lämpötila on yli 15 astetta, asetetaan lähtö aina pois * Jos lämpötila on alle 5 astetta, asetetaan se aina päälle * Muuten annetaan ohjata pörssisähköohjauksen mukaan +*Huom: try..catch on tärkeä, jotta mahdollisen bugin sattuessa ohjaus toimii silti.* + ```js function USER_OVERRIDE(cmd, state, callback) { try { @@ -281,7 +299,7 @@ function USER_OVERRIDE(cmd, state, callback) { let temp = Shelly.getComponentStatus("temperature:100"); - if (temp == undefined) { + if (!temp) { throw new Error("Kyseistä lämpötila-anturia ei löytynyt"); } @@ -304,11 +322,11 @@ function USER_OVERRIDE(cmd, state, callback) { } ``` -### Ulkolämpötilan hakeminen sääpalvelusta ja sen hyödyntäminen +### Esimerkki: Ulkolämpötilan hakeminen sääpalvelusta ja sen hyödyntäminen Tulossa. -### Asetukset suoraan skriptiin (ilman käyttöliittymää) +### Esimerkki: Asetukset suoraan skriptiin (ilman käyttöliittymää) Jos et halua käyttää tai pysty käyttämään selainpohjaista käyttöliittymää, voidaan asetukset määrittää myös skriptissä (versiosta 2.8.0 alkaen). Tämä tapahtuu lisäämällä skriptin perään uusi funktio `USER_CONFIG`. @@ -318,7 +336,7 @@ Tämä myös mahdollistaa asetusten muuttamisen esimerkiksi etänä Shellyn pilv Lisää seuraava koodi skriptin perään ylläolevan kuvan mukaisesti ja muokkaa asetukset kohdilleen. Voit myös asentaa esimerkin **Library**-painikkeen takaa (kuten itse skriptin). -Huomaa, että käyttöliittymän asetusmuutokset eivät tämän jälkeen vaikuta. +Huomaa, että käyttöliittymästä tehdyt asetusmuutokset ylikirjoitetaan. ```js function USER_CONFIG(config) { @@ -407,6 +425,13 @@ Aseta ohjaustavaksi `jakson halvimmat tunnit` ja päivän siirtohinnaksi `999` c Versiosta 2.6.0 lähtien tämä onnistuu valitsemalla ohjaustavaksi `hintaraja` ja asettamalla hintarajaksi arvon `avg`. +### Miksi laitteen nimen kohdalla lukee "Ei asetettu"? + +Et ole asettanut laitteelle nimeä Shellyn hallinnasta. Nimen voit asettaa `Settings` -> `Device name` alta. + +Huomaa, että tehdasasetuksena nimen kohdalla lukee lukee laitteen malli. Tämä näkyy silti pörssisähköskriptille tyhjänä. + + ## Teknistä tietoa ja kehitysympäristö ### Lyhyesti diff --git a/after-build.js b/after-build.js index c547d1a..3431505 100644 --- a/after-build.js +++ b/after-build.js @@ -13,7 +13,7 @@ function USER_OVERRIDE(cmd, state, callback) { let temp = Shelly.getComponentStatus("temperature:100"); - if (temp == undefined) { + if (!temp) { throw new Error("Kyseistä lämpötila-anturia ei löytynyt"); } diff --git a/dist/shelly-porssisahko-user-config.js b/dist/shelly-porssisahko-user-config.js index 353341d..5ce7aa6 100644 --- a/dist/shelly-porssisahko-user-config.js +++ b/dist/shelly-porssisahko-user-config.js @@ -1,4 +1,4 @@ -let C_HIST=24,C_ERRC=3,C_ERRD=120,C_DEF={mode:0,m0:{cmd:0},m1:{lim:0},m2:{per:24,cnt:0,lim:-999,sq:0,m:999},vat:24,day:0,night:0,bk:0,err:0,out:0,fh:0,inv:0},l={s:{v:"2.8.0",dn:"",st:0,cmd:0,chkTs:0,errCnt:0,errTs:0,upTs:0,timeOK:0,configOK:0,fCmdTs:0,tz:"+02:00",p:{ts:0,now:0,low:0,high:0,avg:0}},p:[],h:[],c:C_DEF},c=!1,r=!1;function o(t,s){s-=t;return 0<=s&&s<3600}function a(t){return Math.floor((t?t.getTime():Date.now())/1e3)}function n(t,s,e){let n=t.toString();for(;n.length=C_ERRC&&a(t)-l.s.errTs=C_ERRC&&(l.s.errCnt=0);return s}()){let s=new Date;i(s);try{let t=s.getFullYear()+"-"+n(1+s.getMonth(),2,"0")+"-"+n(f(s),2,"0")+"T00:00:00"+l.s.tz.replace("+","%2b");var e=t.replace("T00:00:00","T23:59:59");let c={url:"https://dashboard.elering.ee/api/nps/price/csv?fields=fi&start="+t+"&end="+e,timeout:5,ssl_ca:"*"};s=null,t=null,Shelly.call("HTTP.GET",c,function(s,t,e){c=null;try{if(0!==t||null==s||200!==s.code||!s.body_b64)throw Error("conn.err ("+e+") "+JSON.stringify(s));{s.headers=null,e=s.message=null,l.p=[],l.s.p.high=-999,l.s.p.low=999,s.body_b64=atob(s.body_b64),s.body_b64=s.body_b64.substring(1+s.body_b64.indexOf("\n"));let t=0;for(;0<=t;){s.body_b64=s.body_b64.substring(t);var n=[t=0,0];if(0===(t=1+s.body_b64.indexOf('"',t)))break;n[0]=+s.body_b64.substring(t,s.body_b64.indexOf('"',t)),t=2+s.body_b64.indexOf('"',t),t=2+s.body_b64.indexOf(';"',t),n[1]=+(""+s.body_b64.substring(t,s.body_b64.indexOf('"',t)).replace(",",".")),n[1]=n[1]/10*(100+(0l.s.p.high&&(l.s.p.high=n[1]),n[1]=C_HIST;)l.h.splice(0,1);l.h.push([a(),r?1:0]),n&&n(!0)}else n&&n(!1)},t)}0===l.c.mode?(r=1===l.c.m0.cmd,l.s.st=1):l.s.timeOK&&0l.p.length-1);ind++)r.push(ind);if(l.c.m2.sq){let s=999,e=0;for(h=0;h<=r.length-l.c.m2.cnt;h++){let t=0;for(m=h;m("avg"==l.c.m2.m?l.s.p.avg:l.c.m2.m)&&(r=!1,l.s.st=11)):l.s.timeOK?(l.s.st=7,t=1<=C_ERRC&&a(t)-c.s.errTs=C_ERRC&&(c.s.errCnt=0);return s}()){let s=new Date;i(s);try{let t=s.getFullYear()+"-"+n(1+s.getMonth(),2,"0")+"-"+n(f(s),2,"0")+"T00:00:00"+c.s.tz.replace("+","%2b");var e=t.replace("T00:00:00","T23:59:59");let l={url:"https://dashboard.elering.ee/api/nps/price/csv?fields=fi&start="+t+"&end="+e,timeout:5,ssl_ca:"*"};s=null,t=null,Shelly.call("HTTP.GET",l,function(s,t,e){l=null;try{if(0!==t||null==s||200!==s.code||!s.body_b64)throw Error("conn.err ("+e+") "+JSON.stringify(s));{s.headers=null,e=s.message=null,c.p=[],c.s.p.high=-999,c.s.p.low=999,s.body_b64=atob(s.body_b64),s.body_b64=s.body_b64.substring(1+s.body_b64.indexOf("\n"));let t=0;for(;0<=t;){s.body_b64=s.body_b64.substring(t);var n=[t=0,0];if(0===(t=1+s.body_b64.indexOf('"',t)))break;n[0]=+s.body_b64.substring(t,s.body_b64.indexOf('"',t)),t=2+s.body_b64.indexOf('"',t),t=2+s.body_b64.indexOf(';"',t),n[1]=+(""+s.body_b64.substring(t,s.body_b64.indexOf('"',t)).replace(",",".")),n[1]=n[1]/10*(100+(0c.s.p.high&&(c.s.p.high=n[1]),n[1]=C_HIST;)c.h.splice(0,1);c.h.push([a(),r?1:0]),n&&n(!0)}else n&&n(!1)},t)}0===c.c.mode?(r=1===c.c.m0.cmd,c.s.st=1):c.s.timeOK&&0c.p.length-1);ind++)r.push(ind);if(c.c.m2.sq){let s=999,e=0;for(g=0;g<=r.length-c.c.m2.cnt;g++){let t=0;for(m=g;m("avg"==c.c.m2.m?c.s.p.avg:c.c.m2.m)&&(r=!1,c.s.st=11)):c.s.timeOK?(c.s.st=7,t=1<=C_ERRC&&a(t)-l.s.errTs=C_ERRC&&(l.s.errCnt=0);return s}()){let s=new Date;i(s);try{let t=s.getFullYear()+"-"+n(1+s.getMonth(),2,"0")+"-"+n(f(s),2,"0")+"T00:00:00"+l.s.tz.replace("+","%2b");var e=t.replace("T00:00:00","T23:59:59");let c={url:"https://dashboard.elering.ee/api/nps/price/csv?fields=fi&start="+t+"&end="+e,timeout:5,ssl_ca:"*"};s=null,t=null,Shelly.call("HTTP.GET",c,function(s,t,e){c=null;try{if(0!==t||null==s||200!==s.code||!s.body_b64)throw Error("conn.err ("+e+") "+JSON.stringify(s));{s.headers=null,e=s.message=null,l.p=[],l.s.p.high=-999,l.s.p.low=999,s.body_b64=atob(s.body_b64),s.body_b64=s.body_b64.substring(1+s.body_b64.indexOf("\n"));let t=0;for(;0<=t;){s.body_b64=s.body_b64.substring(t);var n=[t=0,0];if(0===(t=1+s.body_b64.indexOf('"',t)))break;n[0]=+s.body_b64.substring(t,s.body_b64.indexOf('"',t)),t=2+s.body_b64.indexOf('"',t),t=2+s.body_b64.indexOf(';"',t),n[1]=+(""+s.body_b64.substring(t,s.body_b64.indexOf('"',t)).replace(",",".")),n[1]=n[1]/10*(100+(0l.s.p.high&&(l.s.p.high=n[1]),n[1]=C_HIST;)l.h.splice(0,1);l.h.push([a(),r?1:0]),n&&n(!0)}else n&&n(!1)},t)}0===l.c.mode?(r=1===l.c.m0.cmd,l.s.st=1):l.s.timeOK&&0l.p.length-1);ind++)r.push(ind);if(l.c.m2.sq){let s=999,e=0;for(h=0;h<=r.length-l.c.m2.cnt;h++){let t=0;for(m=h;m("avg"==l.c.m2.m?l.s.p.avg:l.c.m2.m)&&(r=!1,l.s.st=11)):l.s.timeOK?(l.s.st=7,t=1<=C_ERRC&&a(t)-c.s.errTs=C_ERRC&&(c.s.errCnt=0);return s}()){let s=new Date;i(s);try{let t=s.getFullYear()+"-"+n(1+s.getMonth(),2,"0")+"-"+n(f(s),2,"0")+"T00:00:00"+c.s.tz.replace("+","%2b");var e=t.replace("T00:00:00","T23:59:59");let l={url:"https://dashboard.elering.ee/api/nps/price/csv?fields=fi&start="+t+"&end="+e,timeout:5,ssl_ca:"*"};s=null,t=null,Shelly.call("HTTP.GET",l,function(s,t,e){l=null;try{if(0!==t||null==s||200!==s.code||!s.body_b64)throw Error("conn.err ("+e+") "+JSON.stringify(s));{s.headers=null,e=s.message=null,c.p=[],c.s.p.high=-999,c.s.p.low=999,s.body_b64=atob(s.body_b64),s.body_b64=s.body_b64.substring(1+s.body_b64.indexOf("\n"));let t=0;for(;0<=t;){s.body_b64=s.body_b64.substring(t);var n=[t=0,0];if(0===(t=1+s.body_b64.indexOf('"',t)))break;n[0]=+s.body_b64.substring(t,s.body_b64.indexOf('"',t)),t=2+s.body_b64.indexOf('"',t),t=2+s.body_b64.indexOf(';"',t),n[1]=+(""+s.body_b64.substring(t,s.body_b64.indexOf('"',t)).replace(",",".")),n[1]=n[1]/10*(100+(0c.s.p.high&&(c.s.p.high=n[1]),n[1]=C_HIST;)c.h.splice(0,1);c.h.push([a(),r?1:0]),n&&n(!0)}else n&&n(!1)},t)}0===c.c.mode?(r=1===c.c.m0.cmd,c.s.st=1):c.s.timeOK&&0c.p.length-1);ind++)r.push(ind);if(c.c.m2.sq){let s=999,e=0;for(g=0;g<=r.length-c.c.m2.cnt;g++){let t=0;for(m=g;m("avg"==c.c.m2.m?c.s.p.avg:c.c.m2.m)&&(r=!1,c.s.st=11)):c.s.timeOK?(c.s.st=7,t=1<=C_ERRC&&a(t)-l.s.errTs=C_ERRC&&(l.s.errCnt=0);return s}()){let s=new Date;i(s);try{let t=s.getFullYear()+"-"+n(1+s.getMonth(),2,"0")+"-"+n(f(s),2,"0")+"T00:00:00"+l.s.tz.replace("+","%2b");var e=t.replace("T00:00:00","T23:59:59");let c={url:"https://dashboard.elering.ee/api/nps/price/csv?fields=fi&start="+t+"&end="+e,timeout:5,ssl_ca:"*"};s=null,t=null,Shelly.call("HTTP.GET",c,function(s,t,e){c=null;try{if(0!==t||null==s||200!==s.code||!s.body_b64)throw Error("conn.err ("+e+") "+JSON.stringify(s));{s.headers=null,e=s.message=null,l.p=[],l.s.p.high=-999,l.s.p.low=999,s.body_b64=atob(s.body_b64),s.body_b64=s.body_b64.substring(1+s.body_b64.indexOf("\n"));let t=0;for(;0<=t;){s.body_b64=s.body_b64.substring(t);var n=[t=0,0];if(0===(t=1+s.body_b64.indexOf('"',t)))break;n[0]=+s.body_b64.substring(t,s.body_b64.indexOf('"',t)),t=2+s.body_b64.indexOf('"',t),t=2+s.body_b64.indexOf(';"',t),n[1]=+(""+s.body_b64.substring(t,s.body_b64.indexOf('"',t)).replace(",",".")),n[1]=n[1]/10*(100+(0l.s.p.high&&(l.s.p.high=n[1]),n[1]=C_HIST;)l.h.splice(0,1);l.h.push([a(),r?1:0]),n&&n(!0)}else n&&n(!1)},t)}0===l.c.mode?(r=1===l.c.m0.cmd,l.s.st=1):l.s.timeOK&&0l.p.length-1);ind++)r.push(ind);if(l.c.m2.sq){let s=999,e=0;for(h=0;h<=r.length-l.c.m2.cnt;h++){let t=0;for(m=h;m("avg"==l.c.m2.m?l.s.p.avg:l.c.m2.m)&&(r=!1,l.s.st=11)):l.s.timeOK?(l.s.st=7,t=1<=C_ERRC&&a(t)-c.s.errTs=C_ERRC&&(c.s.errCnt=0);return s}()){let s=new Date;i(s);try{let t=s.getFullYear()+"-"+n(1+s.getMonth(),2,"0")+"-"+n(f(s),2,"0")+"T00:00:00"+c.s.tz.replace("+","%2b");var e=t.replace("T00:00:00","T23:59:59");let l={url:"https://dashboard.elering.ee/api/nps/price/csv?fields=fi&start="+t+"&end="+e,timeout:5,ssl_ca:"*"};s=null,t=null,Shelly.call("HTTP.GET",l,function(s,t,e){l=null;try{if(0!==t||null==s||200!==s.code||!s.body_b64)throw Error("conn.err ("+e+") "+JSON.stringify(s));{s.headers=null,e=s.message=null,c.p=[],c.s.p.high=-999,c.s.p.low=999,s.body_b64=atob(s.body_b64),s.body_b64=s.body_b64.substring(1+s.body_b64.indexOf("\n"));let t=0;for(;0<=t;){s.body_b64=s.body_b64.substring(t);var n=[t=0,0];if(0===(t=1+s.body_b64.indexOf('"',t)))break;n[0]=+s.body_b64.substring(t,s.body_b64.indexOf('"',t)),t=2+s.body_b64.indexOf('"',t),t=2+s.body_b64.indexOf(';"',t),n[1]=+(""+s.body_b64.substring(t,s.body_b64.indexOf('"',t)).replace(",",".")),n[1]=n[1]/10*(100+(0c.s.p.high&&(c.s.p.high=n[1]),n[1]=C_HIST;)c.h.splice(0,1);c.h.push([a(),r?1:0]),n&&n(!0)}else n&&n(!1)},t)}0===c.c.mode?(r=1===c.c.m0.cmd,c.s.st=1):c.s.timeOK&&0c.p.length-1);ind++)r.push(ind);if(c.c.m2.sq){let s=999,e=0;for(g=0;g<=r.length-c.c.m2.cnt;g++){let t=0;for(m=g;m("avg"==c.c.m2.m?c.s.p.avg:c.c.m2.m)&&(r=!1,c.s.st=11)):c.s.timeOK?(c.s.st=7,t=1< { let trimmedData = minified.replace(/[\n\r]/g, ''); trimmedData = trimmedData.replace(/\s+/g, " "); -/* - if (filePath.endsWith(".css")) { - trimmedData = trimmedData.replaceAll("{ ", "{"); - trimmedData = trimmedData.replaceAll(" {", "{"); - trimmedData = trimmedData.replaceAll(" }", "}"); - trimmedData = trimmedData.replaceAll("} ", "}"); - trimmedData = trimmedData.replaceAll(": ", ":"); - trimmedData = trimmedData.replaceAll("; ", ";"); - } -*/ + /* + if (filePath.endsWith(".css")) { + trimmedData = trimmedData.replaceAll("{ ", "{"); + trimmedData = trimmedData.replaceAll(" {", "{"); + trimmedData = trimmedData.replaceAll(" }", "}"); + trimmedData = trimmedData.replaceAll("} ", "}"); + trimmedData = trimmedData.replaceAll(": ", ":"); + trimmedData = trimmedData.replaceAll("; ", ";"); + } + */ outputBuffer = Buffer.from(trimmedData, 'utf8'); if (GZIP) { @@ -301,11 +301,13 @@ const createDistFile = async (filePath, distPath, isShellyScript) => { } /** - * Uploads all script files from ./src to the Shelly + * Uploads script file/s() from ./dist to the Shelly * Orders by name */ -const uploadAll = async () => { - let files = await fs.readdir('./dist', { recursive: false }); +const upload = async (files = []) => { + if (!files || files.length === 0) { + files = await fs.readdir('./dist', { recursive: false }); + } for (let file of files.sort()) { const distPath = path.join('./dist', file); @@ -327,16 +329,17 @@ const uploadAll = async () => { } /** - * Builds and creates ./dist files + * Builds and creates ./dist files from all ./src files */ -const buildAll = async () => { +const build = async (files = []) => { await fs.rm('./dist', { recursive: true, force: true }); await fs.mkdir('./dist'); await fs.mkdir('./dist/statics'); - let files = await fs.readdir('./src/statics', { recursive: false }); + //Static files (build all) + let staticFiles = await fs.readdir('./src/statics', { recursive: false }); - for (let file of files.sort()) { + for (let file of staticFiles.sort()) { const filePath = path.join('./src/statics', file); const distPath = path.join('./dist/statics', file); @@ -349,7 +352,10 @@ const buildAll = async () => { } - files = await fs.readdir('./src', { recursive: false }); + //Shelly files (build all or provided ones) + if (!files || files.length === 0) { + files = await fs.readdir('./src', { recursive: false }); + } for (let file of files.sort()) { const filePath = path.join('./src', file); @@ -425,7 +431,7 @@ const uploadAndBuildAll = async () => { } const listenUdp = async () => { - fs.unlink("./log.txt").catch(err => {}); + fs.unlink("./log.txt").catch(err => { }); const socket = dgram.createSocket('udp4'); @@ -455,12 +461,20 @@ const listenUdp = async () => { const args = process.argv.splice(2); switch (args[0]) { + case '--buildAll': + build(); + break; + case '--build': - buildAll(); + build([args[1]]); + break; + + case '--uploadAll': + upload(); break; case '--upload': - uploadAll(); + upload([args[1]]); break; case '--debug': diff --git a/src/shelly-porssisahko.js b/src/shelly-porssisahko.js index 59b9bfe..2a4b175 100644 --- a/src/shelly-porssisahko.js +++ b/src/shelly-porssisahko.js @@ -82,7 +82,7 @@ let C_DEF = { let _ = { s: { /** version number */ - v: "2.8.0", + v: "2.8.1", /** Device name */ dn: '', /** status as number */ diff --git a/src/statics/tab-status.js b/src/statics/tab-status.js index e418952..7a59bd8 100644 --- a/src/statics/tab-status.js +++ b/src/statics/tab-status.js @@ -28,7 +28,7 @@ qs("#s-cmd").style.color = s.cmd ? "green" : "red"; qs("#s-mode").innerHTML = MODE_STR[c.mode]; - qs("#s-dn").innerHTML = s.dn; + qs("#s-dn").innerHTML = s.dn ? s.dn : 'Ei asetettu'; qs("#s-now").innerHTML = pricesOK ? `${s.p.now.toFixed(2)} c/kWh` : ""; qs("#s-st").innerHTML = (s.st === 9 ? STATE_STR[s.st].replace("%s", formatDateTime(new Date(s.fCmdTs * 1000), false))