Rules di perangkat
Rules di perangkat menjalankan logika sederhana langsung di Sentinel, tanpa menunggu server dan tanpa jaringan: bila suhu t1 ≥ 30 °C selama 10 detik, nyalakan kipas o1, kirim event, dan tulis teks di LCD. Rules bersifat deklaratif (JSON yang divalidasi penuh), bukan skrip.
Mengirim rules
Section titled “Mengirim rules”
| Topik | m/<workspace>/c/<channel>/<mac>/rules (dari server) atau sentinel/<mac>/rules (LAN rak) |
| Payload | {"rules_ver": <bilangan bulat>, "rules": [ … ]} |
| Semantik | mengganti seluruh set. Rule yang tidak ada di pesan dihapus; "rules": [] menghapus semua |
| QoS / retain | 1 / ya |
| Laporan | …/rules/reported (retained): rules_ver, count, hash, bytes, rejected, limits |
Dari terminal:
python3 Tools/celestianctl.py rules <mac> --file Tools/rules-contoh.jsonpython3 Tools/celestianctl.py rules <mac> --clearpython3 Tools/celestianctl.py rules <mac> --get # unduh set yang berlaku + bandingkan hashRule yang salah ditolak sendiri dengan alasan di rejected, rule lain tetap berjalan. Status di server: tersinkron bila rules_ver sama dan rejected kosong.
Bentuk rule
Section titled “Bentuk rule”{ "id": "kipas_rak", "en": true, "if": {"all": [ {"src": "t1", "op": ">=", "v": 30, "hyst": 2}, {"src": "d1", "op": "==", "v": false} ]}, "for_s": 20, "cooldown_s": 60, "then": [ {"do": "out", "o": "o1", "state": "follow"}, {"do": "event", "val": "t1"}, {"do": "lcd", "text": "KIPAS ON T1={t1}"} ], "else": [{"do": "event"}]}| Field | Wajib | Arti |
|---|---|---|
id |
ya | huruf kecil, angka, _; diawali huruf; maks. 12; unik. Dipakai di metrik rule_<id> |
en |
tidak (true) |
false = disimpan tetapi tidak dievaluasi |
if |
ya | tepat satu kunci: all (semua klausa benar) atau any (salah satu), berisi 1–4 klausa |
for_s |
tidak (0) |
0 … 3600. Kondisi harus benar terus selama ini sebelum rule aktif |
cooldown_s |
tidak (0) |
0 … 86400. Setelah rule tidak aktif, ia tidak boleh aktif lagi selama ini (mis. melindungi kompresor) |
then |
ya | aksi saat rule menjadi aktif |
else |
tidak | aksi saat rule menjadi tidak aktif |
Klausa
Section titled “Klausa”{"src": <sumber>, "op": <operator>, "v": <nilai>, "hyst": <histeresis>}
Sumber src |
Tipe | Catatan |
|---|---|---|
t1…t4 |
angka °C | sudah termasuk tN_offset_c; tidak tersedia bila slot kosong/mati/sensor hilang |
temp_ambient, humidity |
angka | SHT41 |
voltage, current, power_draw |
angka | PZEM-004T |
d1…d4 |
boolean | aktif setelah polaritas dN_active |
| nama metrik sumber Modbus | angka atau boolean | mis. rak1_power; lihat di bawah |
rule.<id>, o1…o4, alarm_level, f1…f4 |
sumber status (di bawah) |
Sumber dirujuk dengan ID slot (t1, d1), bukan tN_name, karena nama bisa diganti.
| Tipe sumber | Operator | v |
hyst |
|---|---|---|---|
| angka | > >= < <= == != |
angka | 0 … 1000; hanya untuk > >= < <= |
| boolean | == != |
true / false |
tidak boleh ada |
Histeresis: klausa > / >= menjadi benar saat nilai memenuhi dan kembali salah saat nilai < v − hyst; klausa < / <= kembali salah saat nilai > v + hyst. Untuk == pada angka, perbandingan float eksak jarang berguna; pakai rentang dengan dua klausa.
Evaluasi
Section titled “Evaluasi”Rule dievaluasi terus-menerus (suhu dan listrik diperbarui tiap 2 detik, input digital segera setelah debounce).
- Tiap klausa dihitung (dengan histeresis). Klausa yang sumbernya tidak tersedia mempertahankan hasil sebelumnya (awalnya
false). all/anymenghasilkan kondisi benar atau salah.- Kondisi benar memulai hitungan
for_s; kondisi salah membatalkannya. - Hitungan selesai dan
cooldown_slewat: rule menjadi aktif, aksithendijalankan. - Rule aktif lalu kondisi salah: rule menjadi tidak aktif segera (tanpa jeda), aksi
elsedijalankan, dancooldown_sdimulai.
| Aksi | Bentuk | Perilaku |
|---|---|---|
event |
{"do":"event","val":"t1"} |
menerbitkan event metrik boolean rule_<id>: true di then, false di else. Dengan val, ikut rule_<id>_value. Pola yang disarankan: event di then dan else, supaya server melihat mulai dan selesai |
out |
{"do":"out","o":"o1","state":true|false|"follow","s":30} |
follow (hanya di then): HIDUP saat rule aktif, otomatis MATI saat tidak aktif. s (1…86400): MATI sendiri setelah sekian detik (pulsa, atau pengaman) |
lcd |
{"do":"lcd","text":"KIPAS ON T1={t1}"} |
hanya di then; teks tampil di baris bawah Ringkasan selama rule aktif. Maks. 40 karakter; teks lebih dari 20 karakter digulir; placeholder {<sumber angka>} diganti nilai (satu desimal), maks. 2 per teks |
flag |
{"do":"flag","f":"f1","state":true} |
menaikkan atau menurunkan flag (lihat di bawah) |
Aturan output:
- Satu output hanya boleh dikuasai satu rule
follow. Rulefollowkedua untuk output yang sama ditolak. Untuk “kipas hidup bilat1ataut2tinggi”, pakai satu rule denganany. - Perintah manual (
cmd output, serialout) tetap bekerja dan menang sampai transisi rule berikutnya pada output itu. - Slot yang dimatikan (
oN_en=false): aksi dilewati; PCF8574 tidak menjawab: aksi ditunda dan dicoba lagi selama rule masih di fase itu. - Mode pemeliharaan hanya membisukan buzzer; rule tetap berjalan.
Telemetri membawa rule_<id> (status aktif, boolean) untuk setiap rule yang en: true, supaya server tahu keadaan walau event terlewat. Awalan rule_ dicadangkan; nama slot tidak boleh memakainya.
Ekspresi, sumber status, flag, dan jadwal
Section titled “Ekspresi, sumber status, flag, dan jadwal”Fitur ini ada sejak firmware 0.16.0 dan dilaporkan di rules/reported.limits.features (expr, ref, flag, win).
Ekspresi. Klausa angka boleh memakai expr sebagai ganti src:
{"expr": "t1 - t2", "op": ">", "v": 5, "hyst": 1}Operator + - * /, kurung, dan fungsi abs (1 argumen), min, max, avg (2 sampai 4 argumen). Batas: 48 karakter, 12 simpul, kedalaman kurung 4. Pembagian dengan nol menghasilkan “tidak tersedia”. Aksi event boleh memakai "val" berupa ekspresi.
Sumber status. rule.<id> (status aktif rule lain), o1…o4 (keadaan output sebenarnya), alarm_level (0, 1, 2), dan f1…f4. Rule yang bergantung pada rule lain, output, atau flag membentuk graf yang harus tanpa siklus; rule dalam siklus ditolak (siklus: a -> b -> a). Maks. 4 rule.<id> berbeda per rule.
Flag. f1…f4, boolean volatil (false saat boot dan saat set diganti), diubah dengan aksi flag. Telemetri membawa flag_f1…. Cocok untuk penahan: alarm yang tertahan sampai tombol reset ditekan.
Jadwal. Klausa jendela waktu:
{"win": {"from": "08:00", "to": "17:00", "days": "1-5"}}Waktu lokal (memakai tz_offset_min, tanpa DST); from inklusif, to eksklusif; jendela boleh melewati tengah malam; days opsional, 1 = Senin … 7 = Minggu ("1-5", "1,3,5-7"). Bila jam belum sinkron, klausa mempertahankan hasil sebelumnya.
{"rules_ver": 9, "rules": [ {"id": "pompa", "if": {"all": [{"src": "t1", "op": ">=", "v": 60, "hyst": 3}]}, "then": [{"do": "out", "o": "o1", "state": "follow"}, {"do": "event"}], "else": [{"do": "event"}]}, {"id": "katup", "if": {"all": [{"src": "rule.pompa", "op": "==", "v": true}]}, "for_s": 30, "then": [{"do": "out", "o": "o2", "state": "follow"}]}]}{"rules_ver": 10, "rules": [ {"id": "tahan", "if": {"all": [{"src": "t1", "op": ">=", "v": 80}]}, "then": [{"do": "flag", "f": "f1", "state": true}]}, {"id": "reset", "if": {"all": [{"src": "d2", "op": "==", "v": true}]}, "then": [{"do": "flag", "f": "f1", "state": false}]}, {"id": "sirene", "if": {"all": [{"src": "f1", "op": "==", "v": true}]}, "then": [{"do": "out", "o": "o3", "state": "follow"}, {"do": "lcd", "text": "TAHAN T1={t1}"}]}]}{"rules_ver": 11, "rules": [ {"id": "selisih", "if": {"all": [ {"expr": "abs(t1 - t2)", "op": ">", "v": 5, "hyst": 1}, {"win": {"from": "08:00", "to": "17:00", "days": "1-5"}}]}, "for_s": 60, "then": [{"do": "event", "val": "t1 - t2"}], "else": [{"do": "event"}]}]}Rules atas metrik Modbus
Section titled “Rules atas metrik Modbus”Klausa src boleh berupa nama metrik sumber Modbus (mis. rak1_power); jenis (angka atau boolean) ditentukan dari v. Rule yang merujuk metrik yang belum ada dimuat dalam keadaan dormant (tidak pernah aktif, bukan rejected) dan dilaporkan di rules/reported.dormant; ia dievaluasi begitu sumbernya muncul. Dengan demikian urutan pengiriman sources dan rules tidak perlu dijaga. Maks. 32 nama metrik sumber berbeda per set rules. Alarm bawaan (alarm_*, buzzer) hanya untuk metrik bawaan; alarm untuk meter Modbus dibuat dengan rules.
| Batas | Nilai |
|---|---|
| Jumlah rule | 12 |
Ukuran pesan rules |
3500 byte (ini yang biasanya mengikat: sekitar 8 rule terpanjang, atau 12 rule umum) |
| Kondisi per rule / aksi per fase | 4 / 4 |
Panjang id |
12 karakter |
| Flag | 4 |
Menerapkan dengan konfirmasi (confirm_s)
Section titled “Menerapkan dengan konfirmasi (confirm_s)”Tambahkan "confirm_s": N (30 … 3600) di pesan rules. Set dijalankan sementara dan hanya di RAM; cmd rules_confirm dengan hash set itu menjadikannya permanen. Tanpa konfirmasi dalam N detik, node kembali sendiri ke set terkonfirmasi (rule yang aktif ditutup, event penutup terkirim). Kirim confirm_s hanya ke node yang melaporkan limits.confirm_s_min.
| Hal | Perilaku |
|---|---|
| Pesan dengan hash sama dengan set yang menunggu atau yang berjalan | tanpa efek (jendela tidak dimulai ulang) |
| Reboot saat menunggu | set yang menunggu hilang; node boot dengan set terkonfirmasi (bukan pembatalan) |
| Set yang dibatalkan | ditolak bila dikirim lagi dengan byte yang sama (set dibatalkan sebelumnya) |
rules_rollback saat menunggu |
pembatalan eksplisit |
| Laporan | confirm_s, pending_confirm_s, confirmed_hash, rolled_back_hash, rolled_back_reason (unconfirmed, cancelled, superseded) |
python3 Tools/celestianctl.py rules <mac> --file rules.json --confirm-s 120python3 Tools/celestianctl.py rules <mac> --confirm 8a3030f6Mengunduh dan membatalkan
Section titled “Mengunduh dan membatalkan”cmd get_rulesmembalas isi set apa adanya di…/rules/current(tidak retained), dan ringkasan dicmd/result.hashdi laporan adalah CRC-32 byte pesan yang berlaku.cmd rules_rollbackmemuat set sebelumnya dari penyimpanan A/B (bolak-balik). Node menerima pesan retained lama lagi saat tersambung ulang, jadi server harus ikut mengganti set yang diinginkannya.