Mal ein paar Wochen später:
das System läuft jetzt super stabil. Keine Abbrüche mehr.
VIELEN DANK für die Hilfe und Tips!
Mal ein paar Wochen später:
das System läuft jetzt super stabil. Keine Abbrüche mehr.
VIELEN DANK für die Hilfe und Tips!
Hi,
ich wollte nur mal so was loswerden.
Schöne dass es hier weiter geht!
Mein Shortcut in der Adressleiste: SF
damit ändert sich bei mir einfach nix
Einfach mal so super off topic
Viele Grüsse
Hi,
sorry, ich war am Wochenende unterwegs.
Nein leider noch nicht. Ich wollte es erstmal zum Laufen bringen.
Die Ursache würde ich demnächst angehen. Da die Kiste nicht bei mir läuft, wollte ich den Code dort klein halten. Ich müsste es in den lokalen Speicher schreiben. Das wäre normalerweise ja nicht notwendig.
Den Teil versuche ich bei meinem... ich suche noch nach einer Anwendung für mich
Evtl hol ich mir demnächst auch ein bisschen PV. dann wird das was.
Für die Mitleser: Better Safe than Sorry. ist hier der Ansatz. Also lieber ein Try/catch mehr. Ist mein TakeAway
Hi,
Zwischenstand heute:
Alles läuft.
Dein Vorschlag hab ich verstanden.
Allerdings gefällt es mir nicht so.
Die Typprüfung ist hier nicht ganz so safe (deswegen war ich ja echt froh über deinen Tip bei dem | 0;)
Da Javascript hier ja echt sehr offen ist, finde ich das andere besser zu lesen. auch wenn länger.
Kompromiss:?!
so habe gerade die Möglichkeit gehabt ein Update einzuspielen.
jetzt sind 2 Ebenen mit Try/Catch versehen.
Zusätzlich alle "undefined" abgefangen.
Aufgeräumt habe ich auch ein wenig. (Sinnlosen "null" entfernt)
Ebenso das Schalten der Stages bisschen besser lesbar gemacht.
Das Abfragen des aktuellen Tages in einen eigenen Timer gepackt und nur einmal am Tag abgefragt.
let powerPerLine = 2000;
// Do not change code below this line!
let powerAverage = powerPerLine + 1234;
let current = powerPerLine + 1234;
let averageValues = 1;
let myState = 0;
let myunixdayint = 0;
let mycount = 0;
// will be different later:
let maxThreshold = 0;
let minThreshold = -1 * powerPerLine;
let dataPollTimer = null;
let unixdayPollTimer = null;
function startMonitor() {
dataPollTimer = Timer.set(10 * 1000,
true,
function () {
try {
getData();
powerAverage = (powerAverage * averageValues + current) / (averageValues + 1);
print("powerAverage " + powerAverage);
// only use every third calls result
mycount = mycount + 1;
if(mycount < 3) {
return;
}
mycount = 0;
if(powerAverage > maxThreshold) {
myState = myState - 1;
}
if(powerAverage < minThreshold) {
myState = myState + 1;
}
// make sure that only allowed states are used
if(myState < 0)
myState = 0;
if(myState > 3)
myState = 3;
print("myState " + myState);
// modulo 3 for day cycling of switches
let switch1 = myunixdayint % 3;
let switch2 = (myunixdayint + 1) % 3;
let switch3 = (myunixdayint + 2) % 3;
value1 = false;
if(myState > 0) {
value1 = true;
}
value2 = false;
if(myState > 1) {
value2 = true;
}
value3 = false;
if(myState > 2) {
value3 = true;
}
print("value1 " + value1 + ", value2 " + value2 + ", value3 " + value3);
Shelly.call("Switch.Set", {"id": switch1, "on": value1});
Shelly.call("Switch.Set", {"id": switch2, "on": value2});
Shelly.call("Switch.Set", {"id": switch3, "on": value3});
} catch(exception) {
print("exception: ", JSON.stringify(exception));
}
}
);
}
function getData() {
Shelly.call("HTTP.GET", {
url: 'http://192.168.178.119/cm?cmnd=status%2010'
},
function (res, error_code, error_msg, ud) {
try {
// if call is not successful, this should prevent the outputs from beeing turned on
current = powerPerLine + 1234;
if (error_code !== 0) {
print("error " + JSON.stringify(error_code));
}
else if (res.code === 200) {
let st = JSON.parse(res.body);
if(undefined !== st.StatusSNS.SML.z16_7_0) {
current = st.StatusSNS.SML.z16_7_0;
print("current " + current);
}
};
} catch(exception) {
print("exception: ", JSON.stringify(exception));
}
}
);
};
function startDatePoll() {
// get date is once per day enough
unixdayPollTimer = Timer.set(8640 * 1000,
true,
function () {
try {
getDate();
} catch(exception) {
print("exception: ", JSON.stringify(exception));
}
}
);
}
function getDate() {
Shelly.call("Sys.GetStatus",
{},
function(result, err_code, err_message, user_data) {
try {
if (err_code === 0) {
// processing successful result
myunixdayint = Math.floor(result.unixtime / 86400);
print("myunixdayint " + myunixdayint);
}
} catch(exception) {
print("exception: ", JSON.stringify(exception));
}
}
);
}
//ensure the day is read before start
getDate();
startDatePoll();
startMonitor();
Alles anzeigen
Parallel habe ich noch eine Sicherung eingebaut, dass wenn das Script stribt, es wenigsten nicht im angeschalteten Zustand hängen bleibt.
Alle 10 Minuten schaltet das einfach mal ab. Das sollte nicht stören.
let turnOffTimer = null;
function turnOff() {
turnOffTimer = Timer.set(600 * 1000,
true,
function () {
try {
Shelly.call("Switch.Set", {"id": 1, "on": false});
Shelly.call("Switch.Set", {"id": 2, "on": false});
Shelly.call("Switch.Set", {"id": 3, "on": false});
} catch(exception) {
print("exception: ", JSON.stringify(exception));
}
}
);
}
turnOff();
Alles anzeigen
Hi,
ich habe jetzt an jeder Stelle wo ein Objekt referenziert wird eine Abfrage ob es "defined" ist drin.
Leider hat das noch nicht gereicht.
Ich werde im nächsten Schritt das Try/Catch versuchen.
Und danach zur Sicherheit den Schedule.
Aktueller Code:
let powerPerLine = 2000;
let powerAverage = powerPerLine + 1234;
let current = powerPerLine + 1234;
let averageValues = 1;
let maxThreshold = 0;
let minThreshold = 0;
let myState = 0;
let myunixdayint = 0;
let mycount = 0;
// Do not change code below this line!
let alertTimer = null;
function startMonitor() {
alertTimer = Timer.set(10 * 1000,
true,
function () {
getData();
getDate();
powerAverage = (powerAverage * averageValues + current) / (averageValues + 1);
print("----- LOG -----");
print("powerCurrent " + JSON.stringify(current) + ", powerAverage " + JSON.stringify(powerAverage));
mycount = mycount + 1;
if(mycount < 3) {
return;
}
mycount = 0;
// get this info from in input switch
// Version A
maxThreshold = 0;
minThreshold = -1 * powerPerLine;
if(powerAverage > maxThreshold) {
myState = myState - 1;
}
if(powerAverage < minThreshold) {
myState = myState + 1;
}
// make sure that only allowed states are used
if(myState < 0)
myState = 0;
if(myState > 3)
myState = 3;
// modulo 3 for day cycling of switches
let switch1 = myunixdayint % 3;
let switch2 = (myunixdayint + 1) % 3;
let switch3 = (myunixdayint + 2) % 3;
print("minThreshold " + JSON.stringify(minThreshold) + ", maxThreshold " + JSON.stringify(maxThreshold));
print("myState " + JSON.stringify(myState) + ", myunixdayint " + JSON.stringify(myunixdayint));
// make it more generic
if(myState === 0) {
Shelly.call("Switch.Set", {"id": switch1, "on": false});
Shelly.call("Switch.Set", {"id": switch2, "on": false});
Shelly.call("Switch.Set", {"id": switch3, "on": false});
}
if(myState === 1) {
Shelly.call("Switch.Set", {"id": switch1, "on": true});
Shelly.call("Switch.Set", {"id": switch2, "on": false});
Shelly.call("Switch.Set", {"id": switch3, "on": false});
}
if(myState === 2) {
Shelly.call("Switch.Set", {"id": switch1, "on": true});
Shelly.call("Switch.Set", {"id": switch2, "on": true});
Shelly.call("Switch.Set", {"id": switch3, "on": false});
}
if(myState === 3) {
Shelly.call("Switch.Set", {"id": switch1, "on": true});
Shelly.call("Switch.Set", {"id": switch2, "on": true});
Shelly.call("Switch.Set", {"id": switch3, "on": true});
}
},
null
);
}
function getData() {
Shelly.call("HTTP.GET", {
url: 'http://192.168.178.119/cm?cmnd=status%2010'
},
function (res, error_code, error_msg, ud) {
// if call is not successful, this should prevent the outputs from beeing turned on
current = powerPerLine + 1234;
if (error_code !== 0) {
print("error" + JSON.stringify(error_code));
// Not read response if there is an error, to avoid that the script stops
}
else if (res.code === 200) {
let st = JSON.parse(res.body);
if(undefined !== st.StatusSNS.SML.z16_7_0) {
current = st.StatusSNS.SML.z16_7_0;
}
};
},
null
);
};
function getDate() {
Shelly.call("Sys.GetStatus",
{},
function(result, err_code, err_message, user_data) {
if (err_code === 0) {
// processing successful result
if(undefined !== result.unixtime) {
myunixdayint = result.unixtime / 86400 | 0;
}
}
},
null
);
}
startMonitor();
Alles anzeigen
Hi,
hier mal die aktuelle Rückmeldung zu meinem Problem:
Soweit sieht es aus, dass es stabil läuft.
Also vermutlich ein zugriff auf ein undefined object.
Auch wenn da super easy ist. Mir war es nicht klar, dass es das Script stoppt.
Was dazu gelernt
DANKE!!
so hab jetzt mal eine Änderung eingebaut.
(WiFi ist wieder verbunden und auch mit meiner Cloud verknüpft, dh ich kann von überall schauen. Leider ohne Log)
Welche Logging Möglichkeiten gibt es noch ausser die direkte Console?
Im nächsten Schritt würde den try/catch mit rein machen.
und dann (quasi als Rettungsnetz, den Timer)
Hi,
der bitshake/hichi/volkszähler soll einzig den SmartMeter anzapfen und die aktuellen Werte ausspucken.
D1 Mini ESP ist es dann wohl geworden. Dazu ein 3D Printed Gehäuse mit IR Diode und LeseDiode. (aber vorkonfiguriert, ich war für den ersten Schuss zu faul)
Per URL (die hattest du ja im Skript gefunden) sieht man das alles in einem JSON. Grundlage ist eine Tasmota FW.
Das Shelly kann mit den Werten und recht simpel dann ermitteln ob genug Strom da ist um einen 3 Phasen Wasserspeicher zu befeuern. (in eben 3 Stufen)
Damit eben nicht immer der gleiche Heizstab als erstes anspringt, habe ich das Modulo genommen.
Berry Programm? Meinst du auf einem Raspberry? das ist schon zu "gross".
Eine SD Karte die kaputt gehen kann... stromverbrauch... baugrösse... updates... so einiges.
Ich hatte vom Shelly Scripting gelesen und dachte, so eine funktionalität lässt sich doch da abbilden.
Und ja es geht... wenn auch (noch nicht fertig)
die Inputs wollte ich verwenden für mehr Flexibilität.
3 Schaltzustände wollte ich abbilden.
Wie vorher, Wärmepumpe gibt vor, ob es angeht oder nicht.
Bei 0-2000 W Überschuss soll es hochregeln
bei -2000 - 0 W Überschuss soll es hochregeln
und das Ganze per Umschalter am Shelly. (aber das war wie gesagt Zukunftsmusik und ist für den aktuellen Fall nicht wichtig.)
werde ich mir alles reinziehen!
und berichten. vermutlich packe ich es morgen!
wie gesagt, das auslesen der Inputs hat zu einem Fehler geführt. Vermutlich habe ich zu tief genestet....
Vielen Dank!!!
Grässlicher Code, sorry.
kann ich verstehen wenn das nicht gefällt.
Als Hintergrund. Bin selbst Software Engineer. Und das "Framework" Shelly hat mich doch gefordert. Wieviel geht und wieviel eben nicht.
Bin dann mit Codeschnipseln gestartet, da ich es anders nicht zum Laufen bekommen habe.
den alert Timer zb. habe ich nicht verstanden, aber hier im Forum als "state of the art" gefunden.
Echtes "komplettes" JavaScript ist ja nicht zu machen. Von daher musste ich mich mit dem zufrieden geben.
Wenn ich hier Tips bekomme, wende ich die selbstverständlich liebend gerne an.
ich hatte hier mal angefangen:
Aber es kam nicht viel Rückmeldung ...
Alles anzeigenDa gibt es einen semantischen Widerspruch im Skript.
Zeile 14:
Zeile 90:
Wozu gehört diese IP Adresse?%20 ist der Code eines Leerzeichens. ?
Hab's gelesen - Volkszähler.
Vielleicht, aber nicht wahrscheinlich, bringt die Antwort des Zählers das Skript irgendwie "aus dem Takt".
Ich schaue mir das Skript weiter an ...
Eigentlich ist hier kein Widerspruch.
Oben sind Variablen... zb wann das Ding arbeiten soll usw. / wieviel Leistung ein Kanal hat
Unten drunter kommt das Skript, und soll mein Kumpel nix ändern.
Wie gesagt ist eher Prototyp.
JSON.stringify() hatte ich aus einem bestimmten Grund verwendet.
Ohne das hat das Print nicht richtig funktioniert.
Wenn ich das richtig sehe, habe ich auch nirgendwo überhaupt JSON in der Ausgabe drin.
Vielleicht hat es an der Version gelegen. Kann ich aber nicht mehr sagen.
Hi,
erstmal vielen Dank für die Antwort!
Dass das Skript noch nicht ganz fertig ist, war mir bewusst.
Da mein Kumpel fast 50km weg wohnt und mir bis zur Installation nicht klar war ob das überhaupt so funktionieren kann, ist es eher als Prototyp zu sehen.
Die meisten Sachen habe ich mir auch zusammengeklickt.
Hauptsächlich hier aus dem Forum.
Und klar ist kürzer besser
Mir ist leider noch nicht ganz klar, welcher Umfang im Shelly drin ist und welcher nicht.
Zb. habe ich versucht die Inputs einzulesen und das Skript hat sich direkt verabschiedet. Vermutlich einfach nicht die richtige Notation verwendet.
Im Nachhinein, ist x|0 natürlich nicht schön. Hat halt erstmal zum Ziel geführt.
Da ich die Anlage selbst nicht bei mir habe, habe ich einfach so wenig wie möglich Anpassungen vorgenommen.
Hi,
da ich nicht lange basteln wollte habe ich mir den hier gekauft:
bitShake SmartMeterReader WiFi Set IR Lesekopf TASMOTA vorinstalliert WLAN MQTT
Also denke das ist schon das was du meinst. Oder?
Evtl. muss ich ein Fehlerhandling für das JSON einbauen. Macht auf jeden Fall Sinn.
Wlan abdrehen, klingt auch nach ner Idee. Ich hoffe mal, dass ich Mittwoch da hin komme. Sind halt 50km. Da ist remote Wlan abdrehen nicht so einfach
Hi,
erstmal danke!
Also Strom aus und wieder an bringt das System auch wieder in einen lauffähigen Zustand.
Mich wundert dass es aufhört.
Setup ist folgendes:
Ich habe einen Tasmota Volkszähler installiert.
Hier wird dann ein JSON ausgelesen und der aktuelle Wert der Leistung verwendet.
Je nachdem wieviel Überschuss vom Dach kommt wird dann ein Kanal mehr dazu genommen (ist ein 3 Phasen Heizstab im Wasserspeicher).
über den Tag seit 1970 wird dann entschieden welcher der erste Kanal ist, damit nicht Heizstab öfter an ist. (Durchrollieren)
Die Anlage ist bei einem Kumpel installiert. Er wollte so wenig wie möglich Equipment (also keine Zentrale) haben.
Das mit dem Timeout klingt gut. Wie kann ich das am besten testen?
Den Partner ausschalten hab ich schon versucht, Diese Situation verkraftet das Skript gut. Also es funktioniert weiterhin.
Kann es sein, dass es hier einen begrenzten Aufruf Stack oder so gibt?
Den Input auslesen habe ich nicht hinbekommen, da ist das Skript immer ausgestiegen.
Hi,
Log gibt es leider keines...
Sobald das Script in stop geht, sieht man nichts mehr.
Oder gibt es noch andere Wege ein Log zu bekommen.
Hier wäre das Script. Wie gesagt es läuft 7-10 Tage einfach durch und tut was es soll.
Vielleicht ist auch an einer oder mehr Stellen Speicher vergessen aufzuräumen (oder von mir anders schlecht gescriptet)
Tips/Ideen wären da echt willkommen
Die aktuellste Version ist hier:
https://github.com/subbamaggus/shelly_pv_to_waterheater
Oder als Kopie:
let powerPerLine = 2000;
let powerAverage = powerPerLine + 1234;
let current = powerPerLine + 1234;
let averageValues = 1;
let maxThreshold = 0;
let minThreshold = 0;
let myState = 0;
let myunixdayint = 0;
let mycount = 0;
// Do not change code below this line!
let alertTimer = null;
function startMonitor() {
alertTimer = Timer.set(10 * 1000,
true,
function () {
getData();
getDate();
powerAverage = (powerAverage * averageValues + current) / (averageValues + 1);
print("----- LOG -----");
print("powerCurrent " + JSON.stringify(current) + ", powerAverage " + JSON.stringify(powerAverage));
mycount = mycount + 1;
if(mycount < 3) {
return;
}
mycount = 0;
// get this info from in input switch
// Version A
maxThreshold = 0;
minThreshold = -1 * powerPerLine;
if(powerAverage > maxThreshold) {
myState = myState - 1;
}
if(powerAverage < minThreshold) {
myState = myState + 1;
}
// make sure that only allowed states are used
if(myState < 0)
myState = 0;
if(myState > 3)
myState = 3;
// modulo 3 for day cycling of switches
let switch1 = myunixdayint % 3;
let switch2 = (myunixdayint + 1) % 3;
let switch3 = (myunixdayint + 2) % 3;
print("minThreshold " + JSON.stringify(minThreshold) + ", maxThreshold " + JSON.stringify(maxThreshold));
print("myState " + JSON.stringify(myState) + ", myunixdayint " + JSON.stringify(myunixdayint));
// make it more generic
if(myState === 0) {
Shelly.call("Switch.Set", {"id": switch1, "on": false});
Shelly.call("Switch.Set", {"id": switch2, "on": false});
Shelly.call("Switch.Set", {"id": switch3, "on": false});
}
if(myState === 1) {
Shelly.call("Switch.Set", {"id": switch1, "on": true});
Shelly.call("Switch.Set", {"id": switch2, "on": false});
Shelly.call("Switch.Set", {"id": switch3, "on": false});
}
if(myState === 2) {
Shelly.call("Switch.Set", {"id": switch1, "on": true});
Shelly.call("Switch.Set", {"id": switch2, "on": true});
Shelly.call("Switch.Set", {"id": switch3, "on": false});
}
if(myState === 3) {
Shelly.call("Switch.Set", {"id": switch1, "on": true});
Shelly.call("Switch.Set", {"id": switch2, "on": true});
Shelly.call("Switch.Set", {"id": switch3, "on": true});
}
},
null
);
}
function getData() {
Shelly.call("HTTP.GET", {
url: 'http://192.168.178.119/cm?cmnd=status%2010'
},
function (res, error_code, error_msg, ud) {
// if call is not successful, this should prevent the outputs from beeing turned on
current = powerPerLine + 1234;
if (error_code !== 0) {
print("error" + JSON.stringify(error_code));
// Not read response if there is an error, to avoid that the script stops
}
else if (res.code === 200) {
let st = JSON.parse(res.body);
current = st.StatusSNS.SML.z16_7_0;
};
},
null
);
};
function getDate() {
Shelly.call("Sys.GetStatus",
{},
function(result, err_code, err_message, user_data) {
if (err_code === 0) {
// processing successful result
myunixdayint = result.unixtime / 86400 | 0;
}
},
null
);
}
startMonitor();
Alles anzeigen
Hi zusammen,
ich habe es in Englisch versucht. Vielleicht ist deutsch besser.
Seit ein paar Wochen habe ich ein Shelly Pro 3 am Laufen.
Die Funktion ist so wie gewünscht.
Allerdings stopt das Script alle paar Tage.
Wenn ich dann schaue, muss ich es einfach neu starten und alles läuft wieder.
FW Update ist das neueste installiert.
Habe ich den falschen Ansatz gewählt?
Gibt es Tips/Ideen wie ich das lösen kann?
Vielen Dank!
Hi all,
ii recently implemented a script with a Shelly Pro 3:
It works pretty good/as expected.
But there is one thing that is bothering me:
Like once a week the script is in "stopped" state.
As soon as I hit the "start" word, it will restart and everything works fine.
(attached the scenario where is running)
Does anyone know why this is happening?
How can i prevent the Shelly from doing that?
The console output is empty since it is not running anymore.
I updated it to the latest firmware and problem is still there.
Thanx
maggus
Hi all,
so i gut my script up and running.
if someone is interested:
https://github.com/subbamaggus/shelly_pv_to_waterheater
the timing with reading a value was crucial.
i had to add a loop for that.
cheers!
so.
i got my script running.
for all of you who are interested... the script is supposed to read from a hichi (volkszaehler) wifi device. get the current powerflow and then decides to enable a heating element (3 Phases)
Since i dont have a hichi yet. i tested with a regular json.
the solution is meant to be stand alone without any other home technology like openhab/iobroker/...
not finished yet. but the basic functionality is working.
let powerPerLine = 1500;
let powerAverage = 1040;
let averageValues = 3;
let current = 0;
let maxThreshold = 0;
let minThreshold = 0;
let myState = 0;
// Do not change code below this line!
let alertTimer = null;
function startMonitor() {
alertTimer = Timer.set(10 * 1000,
true,
function () {
getData();
powerAverage = (powerAverage * averageValues + current) / (averageValues + 1);
if("VersionA") {
maxThreshold = powerPerLine;
minThreshold = 0;
}
else { // Version B
maxThreshold = 0;
minThreshold = -1 * powerPerLine;
}
if(powerAverage > maxThreshold) {
myState = myState + 1;
}
if(powerAverage < minThreshold) {
myState = myState - 1;
}
if(myState < 0)
myState = 0;
if(myState > 3)
myState = 3;
print("myState " + JSON.stringify(myState));
print("current" + JSON.stringify(current));
print("powerAverage " + JSON.stringify(powerAverage));
print("minThreshold" + JSON.stringify(minThreshold));
print("maxThreshold" + JSON.stringify(maxThreshold));
// modulo 3 for day switching of switches
// make it more generic
if(myState === 0) {
Shelly.call("Switch.Set", {"id": 0, "on": false});
Shelly.call("Switch.Set", {"id": 1, "on": false});
Shelly.call("Switch.Set", {"id": 2, "on": false});
}
if(myState === 1) {
Shelly.call("Switch.Set", {"id": 0, "on": true});
Shelly.call("Switch.Set", {"id": 1, "on": false});
Shelly.call("Switch.Set", {"id": 2, "on": false});
}
if(myState === 2) {
Shelly.call("Switch.Set", {"id": 0, "on": true});
Shelly.call("Switch.Set", {"id": 1, "on": true});
Shelly.call("Switch.Set", {"id": 2, "on": false});
}
if(myState === 3) {
Shelly.call("Switch.Set", {"id": 0, "on": true});
Shelly.call("Switch.Set", {"id": 1, "on": true});
Shelly.call("Switch.Set", {"id": 2, "on": true});
}
},
null
);
}
function getData() {
Shelly.call("HTTP.GET", {
url: 'http://192.168.178.69/strom/'
},
function (res, error_code, error_msg, ud) {
if (error_code !== 0) {
print("error" + JSON.stringify(error_code));
// Not read response if there is an error, to avoid that the script stops
}
else if (res.code === 200) {
let st = JSON.parse(res.body);
current = st.psaldo;
print("current " + JSON.stringify(current));
};
},
null
);
};
startMonitor();
Alles anzeigen