Hallo,
Ich entwickle eine Anwendung für Shellies der zweiten Generation mit per Scheduling ausgelöstem Schalten.
device: shelly plus 1
firmware: 0.14.1, alternativ getestet mit 0.13.0
Mein schedule job:
{"id":1,"enable":true,"timespec":"0 * * * * *","calls":[{"method":"Script.Eval","params":{"id":1,"code":"clockTrigger(5000)"}}]}
Dieser bewirkt zu jeder vollen Minute den Aufruf der Funktion clockTrigger mit 5000 (ms) als Parameter, welche das unten stehenden Skript enthält.
Und hier mein bisheriges Skript:
let debug = true; // set to false if no need for prints
let Config = {
ClockEvent: "trigger",
PubTopic: "develop/event"
};
let Status = {
ScriptId: null, // the id of this script, using in schedule job
PulseTs: null // last clock trigger timestamp, in development use ram instead of nvs
};
// script.eval function to trigger the clock pulse
function clockTrigger (duration) {
Shelly.emitEvent("clock", {key:Config.ClockEvent, value:duration});
return duration;
}
// get the stored timestamp of a clock event
function getPulseTs () {
return Status.PulseTs; // in release get the timestamp from KVS
}
// put the new timestamp of a clock event
function putPulseTs (ts) {
Status.PulseTs = ts; // in release put the timestamp into KVS
}
function pulseOut(duration) { // simulation
if (debug) print("pulse on");
//Shelly.call("switch.set", {"id":0, "on":true});
//Shelly.call("http.get", {url: "127.0.0.1/rpc/switch.set?id=0&on=true"});
MQTT.publish(Config.PubTopic, '{"pulse":true}');
Timer.set(duration, false,
function(){
if (debug) print("pulse off");
//Shelly.call("switch.set", {"id":0, "on":false});
//Shelly.call("http.get", {url: "127.0.0.1/rpc/switch.toggle?id=0"});
MQTT.publish(Config.PubTopic, '{"pulse":false}');
}
);
}
// the handler of a clock event
function clockEvent (data) { // send clock pulse
if (debug) print("clock event: ", JSON.stringify(data));
// get the time difference from last clock pulse to now
let Last = getPulseTs();
let dt = null;
if (Last!==null) dt = data.ts - Last;
if (dt!==null) {
if (debug) print("dt: ", dt);
// do something with the information in dt
let missing = Math.round(dt/60) - 1;
if (missing>0) {
if (debug) print("missing pulses: ", missing);
// send the missing pulses
}
}
putPulseTs(data.ts);
pulseOut(data.data.value);
}
// the event handler of this script
Shelly.addEventHandler(
function (event) {
if (event.info.data.key===Config.ClockEvent) {
clockEvent(event.info);
return;
}
if (debug) print(JSON.stringify(event));
}
);
// get the id of this script for extensions in future
Status.ScriptId = Shelly.getCurrentScriptId();
Alles anzeigen
Der Abbruch des Skript ereignet sich in der Funktion pulseOut, wenn geschaltet wird - Zeilen 31 und Zeilen 37.
Das Skript arbeitet einwandfrei, wenn die Schaltmethodenaufrufe auskommentiert sind.
Die Methoden http.get habe ich nur zwecks Fehlersuche eingesetzt. Sie sind also nur alternativ zu switch.set bzw. switch.toggle zu verstehen.
Wenn ich die Schaltmethoden einbaue, bspw. per switch.set, gibt es den Skriptabbruch mit der Fehlermeldung:
"onEvent callback error: type error"
Ich kann keinen Typfehler finden. Dieser müsste sich in den Shelly.call Aufrufen zum schalten befinden, da ohne diese Aufrufe das Skript fehlerfrei abgearbeitet wird.
Manchmal erscheint diese Meldung beim Einschalten, spätestens nach dem Ausschalten - verlässlich reproduzierbar.
Mir fällt nichts mehr ein, was ich noch tun kann, um diesen Fehler zu beseitigen oder mich der Ursache zu nähern.