-
Notifications
You must be signed in to change notification settings - Fork 0
/
aduroH2.rules
431 lines (372 loc) · 15.6 KB
/
aduroH2.rules
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
var Timer setboilerTimer = null
var Timer waitTimer = null
var Timer AduroNightTimer = null
var Timer RestartTimer = null
var Timer Restart2Timer = null
var Timer AduroH2_runstatusON_stringTimer = null
var Timer AduroH2_runstatusOFF_stringTimer = null
var Timer aduroh2_settemp_Output_strTimer = null
var Timer InitWoodBurnTimer1 = null
var Timer InitWoodBurnTimer2 = null
rule "process Aduro InitWoodBurn ON"
when
Item AduroH2_InitWoodBurn changed from OFF to ON or
Item AduroH2_InitWoodBurn received command ON
then
if (aduroh2_Xonoff_switch.state == ON) { // Store existing state of oven (ON or OFF) so that it can be set back after InitWoodBurn is done/finished
aduroh2_InitWoodBurn_Stored_Xonoff_switch.sendCommand(ON)
} else {
aduroh2_InitWoodBurn_Stored_Xonoff_switch.sendCommand(OFF)
}
val storesettemp = (aduroh2_Xsettemp.state as DecimalType)
aduroh2_InitWoodBurn_Stored_Xsettemp.postUpdate(storesettemp) // Store existing settemp of oven (degrees) so that it can be set back after InitWoodBurn is done/finished
if (aduroh2_opdata_smoke_temp.state < 100) {
if (aduroh2_opdata_boiler_temp.state > aduroh2_Xsetboiler_temp_Lowerlimit.state) {
val calcsettemp = (aduroh2_opdata_boiler_temp.state as DecimalType) + 2
aduroh2_Xsettemp.sendCommand(calcsettemp) // Set settemp so high that the oven will start burning (2 degrees over current room temp)
}
if (aduroh2_Xonoff_switch.state == OFF) {
aduroh2_Xonoff_switch.sendCommand(ON) // This should turn pellet oven on
}
} else {
logInfo("ADURO", "InitWoodBurn cannot initiate as smoke temp is too high")
AduroH2_InitWoodBurn.sendCommand(OFF) // This will reset the InitWoodBurn to OFF
}
end
rule "InitWoodBurn check if enough"
when
Item aduroh2_opdata_state changed or
Item aduroh2_opdata_smoke_temp changed
then
if (aduroh2_opdata_state.state == 5 && aduroh2_opdata_smoke_temp.state > 120 && AduroH2_InitWoodBurn.state == ON) {
// This will turn InitWoodBurn off when the smoke temp is higher than 120 and the pellet oven is burning normally (state = 5)
// as it is then assumed that the oven has been burning for a little while and turned on the wood in the oven.
// If this is not enough to start the wood to burn, the 120 degrees needs to be set higher...
val resetsettemp = (aduroh2_InitWoodBurn_Stored_Xsettemp.state as DecimalType)
aduroh2_Xsettemp.sendCommand(resetsettemp) // Set settemp back to what it was at initburn initiation
InitWoodBurnTimer2 = createTimer(now.plusSeconds(10), [|
// Wait 10 sec to allow for sync of status
if (aduroh2_InitWoodBurn_Stored_Xonoff_switch.state == OFF) {
aduroh2_Xonoff_switch.sendCommand(OFF)
}
AduroH2_InitWoodBurn.sendCommand(OFF)
])
/*
AduroH2_set_runstatusOFF.sendCommand(ON)
InitWoodBurnTimer1 = createTimer(now.plusMinutes(1), [|
// Wait one minute to allow for sync of status
val resetsettemp = (aduroh2_InitWoodBurn_Stored_Xsettemp.state as DecimalType)
aduroh2_Xsettemp.sendCommand(resetsettemp) // Set settemp back to what it was at initburn initiation
InitWoodBurnTimer2 = createTimer(now.plusMinutes(1), [|
// Wait one minute to allow for sync of status
if (aduroh2_InitWoodBurn_Stored_Xonoff_switch.state == ON) {
aduroh2_Xonoff_switch.sendCommand(ON)
} else {
aduroh2_Xonoff_switch.sendCommand(OFF)
}
AduroH2_InitWoodBurn.sendCommand(OFF)
])
])
*/
}
end
rule "Aduro RunstatusOFF check execution"
when
Item AduroH2_runstatusOFF_string received update
then
if (AduroH2_runstatusOFF_string.state != "OK") {
if (aduroh2_execcommand_errors.state < 3) {
logInfo("ADURO", "Runstatus=OFF was not accepted by H2. Retrying")
aduroh2_execcommand_errors.postUpdate(aduroh2_execcommand_errors.state as DecimalType + 1)
AduroH2_set_runstatusOFF.sendCommand(ON)
} else {
AduroH2_runstatusOFF_stringTimer = createTimer(now.plusMinutes(3), [|
logInfo("ADURO", "After 3 try trying again after 3 min and resetting error counter")
aduroh2_execcommand_errors.postUpdate(0)
AduroH2_set_runstatusOFF.sendCommand(ON)
])
}
} else {
aduroh2_execcommand_errors.postUpdate(0)
}
end
rule "Aduro RunstatusON check execution"
when
Item AduroH2_runstatusON_string received update
then
if (AduroH2_runstatusON_string.state != "OK") {
if (aduroh2_execcommand_errors.state < 3) {
logInfo("ADURO", "Runstatus=ON was not accepted by H2. Retrying")
aduroh2_execcommand_errors.postUpdate(aduroh2_execcommand_errors.state as DecimalType + 1)
AduroH2_set_runstatusON.sendCommand(ON)
} else {
AduroH2_runstatusON_stringTimer = createTimer(now.plusMinutes(3), [|
logInfo("ADURO", "After 3 try trying again after 3 min and resetting error counter")
aduroh2_execcommand_errors.postUpdate(0)
AduroH2_set_runstatusON.sendCommand(ON)
])
}
} else {
aduroh2_execcommand_errors.postUpdate(0)
}
end
rule "Handle status change OFF Aduro"
when
Item aduroh2_Xonoff_switch received command OFF
then
if (AduroH2_Switch.state == ON) {
AduroH2_set_runstatusOFF.sendCommand(ON)
logInfo("ADURO", "Status ændret til OFF")
AduroH2_Switch.postUpdate(OFF)
}
end
rule "Handle status change ON Aduro"
when
Item aduroh2_Xonoff_switch received command ON
then
// Hold Settemp
if (AduroH2_Switch.state == OFF) {
AduroH2_set_runstatusON.sendCommand(ON)
logInfo("ADURO", "Status ændret til Hold Settemp Temperaturen")
}
end
rule "Aduro Dont heat at night unless very cold"
when
Time cron "0 0 4 1/1 * ? *" // Check day at 04:00
then
if (AduroH2_NightPause.state == ON && aduroh2_Xonoff_switch.state == ON && aduroh2_Xsettemp.state as DecimalType > 17) {
val storeXsettemp = aduroh2_Xsettemp.state as DecimalType
aduroh2_Xsettemp.sendCommand(17)
if (TraceSwitch.state == ON) {
sendTelegram("bot1", "ADURO: Er gået på 17 grader kl. 04.00. Settemp stod på %s grader", storeXsettemp)
}
AduroNightTimer = createTimer(now.plusHours(3), [|
aduroh2_Xsettemp.sendCommand(storeXsettemp)
if (TraceSwitch.state == ON) {
sendTelegram("bot1", "ADURO: Er gået tilbage på %s grader efter 3 timer", storeXsettemp)
}
])
}
end
rule "Aduro Handle Restart at alarm"
when
Item AduroH2_Alarm changed from OFF to ON
then
logInfo("ADURO", "Alarm received")
if (aduroh2_opdata_state.state == 28) {
logInfo("ADURO", "Alarm is just a simple door-open. No action undetaken...")
} else {
if (AduroH2_AutoAlarmSolveSwitch.state == ON) {
logInfo("ADURO", "Autoresolve ON - waiting 10 min to restart")
RestartTimer = createTimer(now.plusMinutes(10), [|
logInfo("ADURO", "Autoresolve ON - now attempting restart")
logInfo("ADURO", "Autoresolving/restart; turning OFF first. Will turn ON after 1 min")
AduroH2_set_runstatusOFF.sendCommand(ON)
Restart2Timer = createTimer(now.plusMinutes(1), [|
logInfo("ADURO", "Autoresolving/restart; turning ON again")
AduroH2_set_runstatusON.sendCommand(ON)
sendTelegram("bot1", "ADURO: Autorestart 10 min efter alarm er forsøgt")
])
])
}
}
end
rule "Get aduroh2_opdata_Output_str"
when
Time cron "0 0/1 * 1/1 * ? *" // Check every 1 minute
then
aduroh2_opdata_Run_switch.sendCommand ( ON )
setboilerTimer = createTimer(now.plusSeconds(18), [|
aduroh2_setboiler_Run_switch.sendCommand ( ON )
])
end
rule "Sync Aduro On/OFF"
when
Item aduroh2_opdata_off_on_alarm changed
then
switch aduroh2_opdata_off_on_alarm.state.toString {
case "0": {
if (aduroh2_opdata_state.state.toString != "9") { // Ignore changes if state is "Wood Burning"
AduroH2_Switch.sendCommand(OFF)
if (AduroH2_Alarm.state == ON) {
AduroH2_Alarm.sendCommand(OFF)
}
if (aduroh2_Xonoff_switch.state == ON) {
aduroh2_Xonoff_switch.postUpdate(OFF)
}
}
}
case "1": {
AduroH2_Switch.sendCommand(ON)
if (AduroH2_Alarm.state == ON) {
AduroH2_Alarm.sendCommand(OFF)
}
if (aduroh2_Xonoff_switch.state == OFF) {
aduroh2_Xonoff_switch.postUpdate(ON)
}
}
case "2": {
AduroH2_Switch.sendCommand(OFF)
AduroH2_Alarm.sendCommand(ON)
}
}
end
rule "Calc upper and lower temps Aduro"
when
Item aduroh2_setboiler_temp received update
then
val upperTemp = aduroh2_setboiler_temp.state as DecimalType + aduroh2_setboiler_diff_over.state as DecimalType
val lowerTemp = aduroh2_setboiler_temp.state as DecimalType - aduroh2_setboiler_diff_under.state as DecimalType
aduroh2_Xsetboiler_temp_Upperlimit.postUpdate(upperTemp)
aduroh2_Xsetboiler_temp_Lowerlimit.postUpdate(lowerTemp)
end
rule "String State Aduro"
when
Item aduroh2_opdata_state changed or
Item aduroh2_opdata_substate changed
then
var String xState = ""
var String xSubstate = ""
val xOpdata_State = aduroh2_opdata_state.state as DecimalType
val xOpdata_Substate = aduroh2_opdata_substate.state as DecimalType
switch xOpdata_State {
case 0: { xState = "Wait" }
case 2: { xState = "Ignition" }
case 4: { xState = "Ignition 2" }
case 5: { xState = "Normal power" }
case 6: { xState = "Room temperature reached" }
case 9: { xState = "Wood burning" }
case 13: { xState = "Ignition Failed" }
case 14: { xState = "Stopped by button"
if (aduroh2_Xonoff_switch.state == ON) {
aduroh2_Xonoff_switch.postUpdate(OFF)
}
}
case 20: { xState = "No Fire" }
case 28: { xState = "Door Open" }
default: { xState = "State undefined" + aduroh2_opdata_state.state.toString }
}
switch xOpdata_Substate {
case 4: { xSubstate = "Wait" }
case 6: { xSubstate = "Wait" }
}
if (xSubstate == "") {
aduroh2_Xopdata_state_text.sendCommand(xState)
} else {
aduroh2_Xopdata_state_text.sendCommand(xSubstate + " (" + xState + ")")
}
end
rule "Convert aduroh2_opdata_Output_str to Items"
when
Item aduroh2_opdata_Output_str changed
then
if (aduroh2_opdata_Output_str.state.toString.substring(0, 9) != "Traceback") {
// Rumtemperatur
val aduroh2_opdata_boiler_temp_newValue = transform("REGEX", ".*operating_data/boiler_temp=(\\d*.\\d*)\n.*", aduroh2_opdata_Output_str.state.toString)
if (aduroh2_opdata_boiler_temp_newValue != aduroh2_opdata_boiler_temp.state) {
aduroh2_opdata_boiler_temp.postUpdate( aduroh2_opdata_boiler_temp_newValue )
}AduroH2_Switch
// Røgtemperatur
val aduroh2_opdata_smoke_temp_newValue = transform("REGEX", ".*operating_data/smoke_temp=(\\d*.\\d*)\n.*", aduroh2_opdata_Output_str.state.toString)
if (aduroh2_opdata_smoke_temp_newValue != aduroh2_opdata_smoke_temp.state) {
aduroh2_opdata_smoke_temp.postUpdate( aduroh2_opdata_smoke_temp_newValue )
}
val aduroh2_opdata_milli_ampere_newValue = transform("REGEX", ".*operating_data/milli_ampere=(\\d*)\n.*", aduroh2_opdata_Output_str.state.toString)
if (aduroh2_opdata_milli_ampere_newValue != aduroh2_opdata_milli_ampere.state) {
aduroh2_opdata_milli_ampere.postUpdate( aduroh2_opdata_milli_ampere_newValue )
}
val aduroh2_opdata_power_pct_newValue = transform("REGEX", ".*operating_data/power_pct=(\\d*)\n.*", aduroh2_opdata_Output_str.state.toString)
if (aduroh2_opdata_power_pct_newValue != aduroh2_opdata_power_pct.state) {
aduroh2_opdata_power_pct.postUpdate( aduroh2_opdata_power_pct_newValue )
}
// Ønsket rumtemperatur
val aduroh2_opdata_boiler_ref_newValue = transform("REGEX", ".*operating_data/boiler_ref=(\\d*.\\d*)\n.*", aduroh2_opdata_Output_str.state.toString)
if (aduroh2_opdata_boiler_ref_newValue != aduroh2_opdata_boiler_ref.state) {
aduroh2_opdata_boiler_ref.postUpdate( aduroh2_opdata_boiler_ref_newValue )
}
// 6=ON but Room temperature reached, 14=OFF/Slukket på knap, 20=ON, warming?
val aduroh2_opdata_state_newValue = transform("REGEX", ".*operating_data/state=(\\d*)\n.*", aduroh2_opdata_Output_str.state.toString)
if (aduroh2_opdata_state_newValue != aduroh2_opdata_state.state) {
aduroh2_opdata_state.postUpdate( aduroh2_opdata_state_newValue )
}
// 0=warm to req room temp., 1=Warm level 1 (low), 2=Warm level 2 (mid), 4=Warm level 3 (high)
val aduroh2_opdata_substate_newValue = transform("REGEX", ".*operating_data/substate=(\\d*)\n.*", aduroh2_opdata_Output_str.state.toString)
if (aduroh2_opdata_substate_newValue != aduroh2_opdata_substate.state) {
aduroh2_opdata_substate.postUpdate( aduroh2_opdata_substate_newValue )
}
// 0=OFF?, 1=ON but waiting, 2=OFF Alarm
val aduroh2_opdata_off_on_alarm_newValue = transform("REGEX", ".*operating_data/off_on_alarm=(\\d*)\n.*", aduroh2_opdata_Output_str.state.toString)
if (aduroh2_opdata_off_on_alarm_newValue != aduroh2_opdata_off_on_alarm.state) {
aduroh2_opdata_off_on_alarm.postUpdate( aduroh2_opdata_off_on_alarm_newValue )
}
} else {
logInfo("ADURO", "Get operating_data gave TRACEBACK")
}
end
rule "Convert aduroh2_setboiler_Output_str String to Items"
when
Item aduroh2_setboiler_Output_str changed
then
if (aduroh2_setboiler_Output_str.state.toString.substring(0, 9) != "Traceback") {
val aduroh2_setboiler_temp_newValue = transform("REGEX", ".*settings/boiler/temp=(\\d*)\n.*", aduroh2_setboiler_Output_str.state.toString)
if (aduroh2_setboiler_temp_newValue != aduroh2_setboiler_temp.state) {
aduroh2_setboiler_temp.postUpdate( aduroh2_setboiler_temp_newValue )
}
val aduroh2_setboiler_diff_over_newValue = transform("REGEX", ".*settings/boiler/diff_over=(\\d*)\n.*", aduroh2_setboiler_Output_str.state.toString)
if (aduroh2_setboiler_diff_over_newValue != aduroh2_setboiler_diff_over.state) {
aduroh2_setboiler_diff_over.postUpdate( aduroh2_setboiler_diff_over_newValue )
}
val aduroh2_setboiler_diff_under_newValue = transform("REGEX", ".*settings/boiler/diff_under=(\\d*)\n.*", aduroh2_setboiler_Output_str.state.toString)
if (aduroh2_setboiler_diff_under_newValue != aduroh2_setboiler_diff_under.state) {
aduroh2_setboiler_diff_under.postUpdate( aduroh2_setboiler_diff_under_newValue )
}
} else {
logInfo("ADURO", "Get settings/boiler gave TRACEBACK")
}
end
rule "Aduro Xsettemp changed"
when
Item aduroh2_Xsettemp received command
then
waitTimer = createTimer(now.plusSeconds(4), [|
if (aduroh2_setboiler_temp.state.toString != aduroh2_Xsettemp.state.toString) {
aduroh2_settemp_Run_Args.sendCommand(aduroh2_Xsettemp.state.toString)
}
])
end
rule "Aduro setboiler_temp changed"
when
Item aduroh2_setboiler_temp changed
then
if (aduroh2_setboiler_temp.state.toString != aduroh2_Xsettemp.state.toString) {
aduroh2_Xsettemp.sendCommand(aduroh2_setboiler_temp.state as DecimalType)
}
end
rule "Aduro Settemp begin your execution"
when
Item aduroh2_settemp_Run_Args received command
then
if (aduroh2_settemp_Run_switch.state != ON) {
aduroh2_settemp_Run_switch.sendCommand(ON)
}
end
rule "Aduro Settemp check execution"
when
Item aduroh2_settemp_Output_str received update
then
if (aduroh2_settemp_Output_str.state != "OK") {
if (aduroh2_execcommand_errors.state < 3) {
logInfo("ADURO", "Settemp update was not accepted by H2. Retrying")
aduroh2_execcommand_errors.postUpdate(aduroh2_execcommand_errors.state as DecimalType + 1)
aduroh2_settemp_Run_switch.sendCommand(ON)
} else {
aduroh2_settemp_Output_strTimer = createTimer(now.plusMinutes(3), [|
logInfo("ADURO", "After 3 try trying again after 3 min and resetting error counter")
aduroh2_execcommand_errors.postUpdate(0)
aduroh2_settemp_Run_switch.sendCommand(ON)
])
}
} else {
aduroh2_execcommand_errors.postUpdate(0)
}
end