Exemple de scripturi
Scripturi TapHome complete: împărțire sigură, 0 în locul unei valori necunoscute, reglarea intensității cu LINEAR, alarme Modbus și atribute de service, HTTP și JSON, script listener MQTT și Wake on LAN.
Scripturi complete pentru sarcini frecvente. Rețetele pentru smart rules funcționează în orice instalație; exemplele Modbus și Packet parser provin din depozitele oficiale de șabloane pentru Modbus și Packet parser. Numele scurte precum Se, va1 sau St sunt abrevierile valorilor dispozitivelor alese în editorul de scripturi; numele precum StatusJson sau plugTopic sunt variabile ale modulului.
Rețete pentru smart rules
Împărțirea sigură a două valori
Împărțirea la o valoare a dispozitivului care este 0 oprește scriptul cu Line in script: 1 Message: Division by zero. Încadrați împărțirea va1/va2 în forma de funcție a lui IF. Aceasta evaluează doar ramura aleasă, așa că împărțirea se execută doar când împărțitorul este mai mare decât 0:
IF(va2 > 0, va1/va2, 0);
# Result: 0 when va2 is 0, otherwise va1 divided by va2Când împărțitorul poate fi negativ, testați în schimb va2 <> 0. Mai multe în Erori.
Scrierea lui 0 în locul unei valori necunoscute
O valoare necunoscută a dispozitivului, de exemplu de la un senzor în eroare, este NaN. Pentru a scrie în schimb 0, testați-o cu ISNAN — modelul este IF(ISNAN(x), 0, x):
IF(ISNAN(Se), 0, Se);
# Result: 0 while the value of Se is unknown, otherwise the value of SeO comparație precum Se = NaN este o eroare de parsare. Când valoarea poate fi și Null (nicio valoare), testați mai întâi ISNULL; OR sare peste partea dreaptă de îndată ce partea stângă este TRUE:
IF(ISNULL(Se) OR ISNAN(Se), 0, Se);Reglarea intensității cu LINEAR
LINEAR transpune un interval de valori de intrare într-un interval de valori de ieșire, ceea ce este modul obișnuit de a calcula un nivel de intensitate. Nivelul unui dimmer merge de la 0 (oprit) la 1 (100 %). Într-o smart rule Formulă cu un dimmer ca ieșire, acest script reduce intensitatea luminii pe măsură ce lumina zilei crește de la 0 la 500 lx (Se este senzorul de lumină):
LINEAR(Se, 0, 1, 500, 0);
# Result: 1 at 0 lx, 0.5 at 250 lx, 0 at 500 lx and moreÎn afara intervalului de intrare rezultatul rămâne la capătul cel mai apropiat (BOUNDS, varianta implicită). Pentru a păstra un nivel minim, ridicați ieșirea inferioară: LINEAR(Se, 0, 1, 500, 0.1) nu coboară niciodată sub 10 %. Detalii în LINEAR.
Exemple Modbus
Erori ale dispozitivului dintr-un registru de alarmă
Un script de citire al unui invertor Solax transformă un registru de stare și un cuvânt de alarmă pe 32 de biți în erori ale dispozitivului:
VAR reg := MODBUSR(A, 0x09, UInt16);
IF(reg = 3, ADDERROR("Run Mode Fault"));
IF(reg = 4, ADDERROR("Run Mode Permanent Fault"));
VAR x3 := MODBUSR(A, 0x0040, Uint32);
IF(GETBIT(x3, 0) = 1, ADDERROR("TZ Protect Fault"));
IF(GETBIT(x3, 1) = 1, ADDERROR("Grid Lost Fault"));
IF(GETBIT(x3, 2) = 1, ADDERROR("Grid Volt Fault"));
IF(GETBIT(x3, 15) = 1, ADDERROR("Off-grid Overload"));Atribut de service din câmpuri de biți
Un atribut de service Komfovent afișează cei patru octeți ai unui registru pe 32 de biți ca text cu puncte:
VAR reg := MODBUSR(H, 22, Uint32);
VAR first := GETBITS(reg, 0, 8);
VAR second := GETBITS(reg, 8, 8);
VAR third := GETBITS(reg, 16, 8);
VAR last := GETBITS(reg, 24, 8);
RETURN(last + "." + third + "." + second + "." + first);
# Result: text such as "1.2.3.4"Acțiune de service cu un parametru
Parametrii unei acțiuni de service sunt variabile numite după abrevierea lor. O acțiune a contorului Eastron SDM120 scrie parametrul ei ID în holding register 20:
MODBUSW(H, 20, Float, ID)Decodificarea unei enumerări
Un registru de stare al invertorului Huawei SUN2000 devine un text ușor de citit cu SWITCH:
VAR state := MODBUSR(H, 32089, Uint16);
SWITCH(state,
0, "Idle: Initializing",
1, "Idle: Detecting ISO",
256, "Starting",
512, "On-Grid",
768, "Shutdown: Fault",
"Unknown");Exemple Packet parser
Cerere HTTP cu tratarea erorilor
SENDHTTPREQUEST returnează un obiect httpresponse. Acest script de citire (Forecast.solar) păstrează corpul răspunsului în variabila output pentru parsarea ulterioară și raportează o cerere eșuată ca eroare a dispozitivului:
VAR response := SENDHTTPREQUEST("/estimate/" + Latitude + "/" + Longitude + "/"
+ PV_declination + "/" + PV_azimuth + "/" + PV_kWp,
"GET", "", "Accept: application/json");
IF response.IsSuccess
output := response.Content;
ELSE
ADDERROR(response.StatusCode + " (" + response.ReasonPhrase + ")");
ENDTimpul de funcționare din JSON
Un atribut de service Shelly 1PM formatează timpul de funcționare în secunde din JSON-ul de stare păstrat în variabilă:
VAR upTimeSeconds := PARSEJSON(StatusJson, "uptime");
VAR days := FLOOR(upTimeSeconds / 86400, 1);
upTimeSeconds := MOD(upTimeSeconds, 86400);
VAR hours := FLOOR(upTimeSeconds / 3600, 1);
upTimeSeconds := MOD(upTimeSeconds, 3600);
VAR minutes := FLOOR(upTimeSeconds / 60, 1);
days + " day(s) " + hours + "h " + minutes + "m";
# Result: for 191820 seconds "2 day(s) 5h 17m"Prețul spot pentru perioada curentă
Un script de citire descarcă prețurile de astăzi de pe okte.sk:
VAR today := TOSTRING(NOW(), "yyyy-MM-dd");
VAR response := SENDHTTPREQUEST("/api/v1/dam/results?deliveryDayFrom=" + today
+ "&deliveryDayTo=" + today);
IF response.IsSuccess
output := response.Content;
ELSE
ADDERROR(response.StatusCode + " (" + response.ReasonPhrase + ")");
ENDUn atribut de service alege apoi o perioadă cu un filtru JSONPath:
PARSEJSON(output, "$[?(@.period == 1)].price") + " EUR"Buclă peste un tablou JSON
Cu TRUE ca al treilea argument, PARSEJSON returnează Null după ultimul element în loc să eșueze, ceea ce încheie bucla:
VAR response := SENDHTTPREQUEST("/api/taphomeapi/v1/discovery", "GET", "",
"Authorization: TapHome " + API_token);
IF response.IsSuccess
VAR ret := "";
VAR i := 0;
VAR id := PARSEJSON(response.Content, "$.devices[0].deviceId", TRUE);
WHILE !ISNULL(id)
ret := ret + "(" + id + ") ";
ret := ret + PARSEJSON(response.Content, "$.devices[" + TOSTRING(i) + "].name", TRUE);
ret := ret + " - " + PARSEJSON(response.Content, "$.devices[" + TOSTRING(i) + "].type", TRUE);
ret := ret + "\n";
i := i + 1;
id := PARSEJSON(response.Content, "$.devices[" + TOSTRING(i) + "].deviceId", TRUE);
LOOP
RETURN(ret);
ENDValidarea unei variabile a modulului într-un script listener
Un script listener MQTT pentru Shelly verifică mai întâi că variabila modulului plugTopic a fost completată, apoi convertește puterea citită din W în kW:
IF(INDEXOF(plugTopic, "shelly1pm-deviceid") = 0)
ADDERROR("Set correct 'plugTopic' value in module variables. "
+ "Topic format is 'shelly1pm-<deviceid>'.");
RETURN(-1);
END
IF(RECEIVEDMSG.TOPIC = "shellies/" + plugTopic + "/relay/0/power")
VAR valueP := TOSTRING(RECEIVEDMSG.PAYLOAD);
Ed := IF(ISNULL(valueP), NaN, TODOUBLE(valueP) / 1000.0);
ENDWake on LAN
Un buton UDP trimite un pachet magic. Variabila modulului MAC conține adresa ca text ("12 34 56 78 9a bc"); BYTECOLLECTION ignoră spațiile:
VAR magicPacket := BYTECOLLECTION("FF FF FF FF FF FF " + MAC + MAC + MAC + MAC
+ MAC + MAC + MAC + MAC + MAC + MAC + MAC + MAC + MAC + MAC + MAC + MAC);
SENDDATA(magicPacket);