Shelly jobs
Automatisch Shelly Regeln (jobs) zum Ein- und Ausschalten über openHAB steuern.
Folgendes Problem musste gelöst werden:
Ich benötige einen Schalter (shelly), der zu einer gewissen Zeit hh:mm ausschaltet und 15 Minuten später wieder einschaltet. Alle 15 Minuten wird überprüft, ob der shelly erreichbar ist. Wenn ja, dann wird die Aus- und Einschaltzeit um 1 Stunde nach hinten verschoben.
Der Grund für diesen Vorgang ist folgender:
Der Shelly steuert ein Modem, welches örtlich getrennt und in einem anderen Netz (LAN mit unterschiedlicher IP Range) liegt. Wenn der shelly nicht erreichbar ist, dann soll der Schalter das Modem vom Stromnetz nehmen, sprich ausschalten und nach 15 Minuten wieder einschalten (mit Strom versorgen).
Den erste Versuch habe ich mit einem shelly 1 (1.Generation) durchgeführt.
Folgedes benötigt man dafür im openHAB:
Thing http:url:sh5 "shelly5"[
baseURL="http://x.x.x.x",
commandMethod="POST", refresh=10 ] {
Channels:
// eine Möglichkeit zum Auslesen über JSONPATH
Type string : Schedule_Rules [
stateExtension = "/settings/relay/0",
stateTransformation = "JSONPATH:$.schedule_rules"]
// oder über ein Java Script parsen
Type string : Schedule_Rules_js [
stateExtension = "/settings/relay/0",
stateTransformation = "JS:shelly_schedule.js",
commandExtension = "/settings/relay/0?schedule_rules=%2$s"] }
// HTTP item
String sh5_Schedule_Rules_js " {channel="http:url:sh5:Schedule_Rules_js"}
// MQTT item
Type string : sh5Time [stateTopic="shellies/shelly5/info",
transformationPattern="JSONPATH:$.time"]
Transform: shelly_schedule.js
(function(x){
var json=JSON.parse(x);
var str=JSON.stringify(json.schedule_rules);
//var y = JSON.parse(str);
return str;
})(input)
Damit kann man dann eine Regel erstellen, die gewünschten Einstellungen durchführt:
rule "sh5 Update schedule_rule"
when
// kann man z.B alle 15 Minuten durch einen MQTT
// sh5Announce.sendCommand("announce") erzwingen
Item sh5Info changed
then
// sh5Time im Format hh:mm
// Ausschaltzeit auf plus 1 Stunde setzen
// Einschaltzeit auf plus 1 Stunde und 15 Minuten setzen
var strHour = sh5Time.state.toString.substring(0,2)
var strMinute = sh5Time.state.toString.substring(3,5)
var nMinute = Integer.parseInt(strMinute)
var nHour = Integer.parseInt(strHour)
nHour = (nHour + 1) % 24
var nHour1 = nHour
if ((nMinute + 15) >= 60) {
nHour1 = (nHour + 1) % 24
}
nMinute = (nMinute + 15) % 60
strHour = String.format("%02d", nHour)
val strHour1 = String.format("%02d", nHour1)
val strMinute1 = String.format("%02d",nMinute)
var strTime = strHour1 + strMinute1
// das Format lautet StundeMinute - Wochentage - ein oder aus
// z.B.: sh5_Schedule_Rules_js.sendCommand("1345-0123456-off,1400-0123456-on")
val rule_off = strHour + strMinute + "-0123456-off"
val rule_on = strTime + "-0123456-on"
sh5_Schedule_Rules_js.sendCommand(rule_off + "," + rule_on)
Das Ganze funktioniert perfekt. Die Regel des Shelly wird alle 15 Minuten getriggert und setzt die Ein- und Ausschaltzeiten um 1 Stunde nach hinten, wenn er erreichbar ist
Leider habe ich nicht bedacht, dass der Shelly ja in einem anderen Netz liegt als der openHAB Server. Damit ist die Lösung über HTTP nicht brauchbar. Er muss über MQTT angesteuert werden.
Leider habe ich keine Möglichkeit gefunden das bei den Shellies der 1. Generation per MQTT zu machen, aber bei der 2. Generation. Dafür wurde ein Shelly 2 PM herangezogen.
ACHTUNG: Bei der 2. Generation hat sich die MQTT Steuerung grundlegend geändert.
// MQTT thing mit commandTopic rpc
Thing topic shelly2 {
Type string : sh2RPC [stateTopicTopic="shelly2/rpc",
commandTopic="shelly2/rpc"] }
// MQTT item
String sh2RPC {channel="mqtt:topic:mosquitto:shelly2:sh2RPC"}
rule "sh2 Update schedule_rule"
when
Item sh2Status changed
then {
var json = ""
// z.B.: einen Job mit id=2 löschen
json = '{"src": "shellyplus2pm-xxx",
"method": "Schedule.Delete",
"params": {"id":2} }' // löscht eintrag mit id=2
// alle Jobs löschen
json = '{"id" : 1,
"src" : "shellyplus2pm-xxx",
"method" : "Schedule.DeleteAll" }'
// einen job anlegen z.B. um 22:00 ausschalten
json = '{"id": 1,
"src": "shellyplus2pm-fcb467a6a1f4",
"method": "Schedule.Create",
"params": {"timespec": "0 0 22 * * *",
"calls": [{ "method": "Switch.Set",
"params":{"id":0,"on":false} }]}}'
// einen job anlegen z.B. um 22:15 einschalten
json = '{"id": 2,
"src": "shellyplus2pm-xxx",
"method": "Schedule.Create",
"params": {"timespec": "0 15 22 * * *","
calls": [{ "method": "Switch.Set",
"params":{"id":0,"on":true} }]}}'
// einen job (mit id=2) verändern, job aktivieren und Zeit setzten
json = '{"id": 1,
"src": "shellyplus2pm-xxx",
"method": "Schedule.Update",
"params": {"id":2,
"enable": true,
"timespec": "0 15 23 * * *"}}'
sh2RPC.sendCommand(json) // MQTT Kommando senden
}
Das funktioniert super, auch über Netzgrenzen hinweg.
Man muss natürlich den Shelly so konfigurieren, dass er den MQTT Broker erreicht, z.B. über einen dynamischen DNS und einer Portweiterleitung.