generated from skills/github-pages
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathHeishaMon_Rules_BlB4_commented.txt
494 lines (469 loc) · 27.3 KB
/
HeishaMon_Rules_BlB4_commented.txt
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
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
-- this rules set can't be loaded directly onto HeishaMon but can be minified via the minify tool https://github.com/klaashoekstra94/heishamon_rules_minify
--
--[[
This is my ruleset I use on my HeishaMon to control my Panasonic Heat Pump in combination with an Opentherm thermostat. I try to keep it as univeral as possible but it is at the end taylored to my situation and needs. You can just copy it and start using it (at your own risk) or, better, you can use is as inspiration for your own rules set.
**My environment:**
a) Panasonic WH-MDC07J3E5 Heat Pump used for heating and DHW (external tank);
b) HeishaMon Large with CZ-TAW1 on proxy port (but I don't use this CZ-TAW1 actively);
c) Honeywell Evohome Opentherm Thermostat (R8810 bridge) connected via OpenTherm Gateway;
d) Honeywell Evohome & OpenTherm Gateway integration in Home Assistant to communicate RoomTemperatureDelta to HeishaMon rules as chSetpoint from Evohome is not reliable and target room temperature and current room temperature are not communicated towards 'boiler';
e) Settings Heat Pump: Operating_Mode_State: 0, Heating_Mode: 0, Cooling_Mode: 1, Buffer_Installed: 0, DHW_Installed: 1, Pump_Flowrate_Mode: 0, Optional_PCB: 0, Z1_Sensor_Settings: 0
**My Requirements for the Rules Set:**
1) Max Pump Speed based on HP status 1) DHW, 2) HEAT/COOL (and the outside temp as well), IDLE flow;
2) QuiteMode based on time (e.g. at night) & for Heat/Cool at start Compressor until Compressor Frequency < 30 Hz.;
3) DHW production if DHWTemp is (too) low, every day at fixed time if DHWTemp < DHWTargetTemp + DHWDelta and 1 x per week (at #SterilizationDay) a Sterilization run;
4) Sync OT values with HP values to have correct (status) values from HP communicated to OT Thermostat;
5) OT Thermostat HP control: 1) switch off HP (water circulation pump) when ?chEnable is 0 (for a certain time) or room temperature too high;
6) TaShift function to 1) lower Compressor frequency asap by lowering Ta and increasing HeatDelta, 2) extend the run time if Heat loss is less than minimum HP Power and 3) adapt Ta based on RoomTempDelta.
7) Remoteoverride function to selectively swith off some functions via Home Assistant;
**Remoteoverride**
Purpose: By default the HP is controlled by the rules, including switching on/off the HP. For safety and other reasons it's wise to be able to switch the HW off by the controller or via MQTT and to prevent the rules will switch the HP on again. For different reasons there could be reasons to switch off some functions on a relative easy remote way. This is implemented via the #Remoteoverride parameter which can be set/manipulated by the @SetZ2HeatRequestTemperature parameter, this parameter is not in use in my (1 zone) installation.
functions NOT running with #Remoteoverride value:
-1: HeatPumpState will not be changed (this is to prevent ruleset will modify HeatPumpState during e.g. maintenance
1: TaShift
2: TaShift, QuietMode
3: TaShift, QuietMode, OpenThermThermostat
4: TaShift, QuietMode, OpenThermThermostat, DHW
5: TaShift, QuietMode, OpenThermThermostat, DHW, pumpDuty
**System#Boot**
*Purpose*: 1) define which functions are active (#allow variables), 2) initial values of global variable(s) used in the ruleset and 3) start 2 main timers, 1 for time & day references, the other one to trigger all acitve functions.
*Explanation*: By default all functions are enabled (the #allow... variables), you can disable them by setting to 0. 1 Variable has to be set according needs, e.g. Debug can be set to 0 (no debug) or to 1 (basis debug), #LegionallaRunDay can be set 1 to 7. Except #FirstBoot all other global variables are default set to -1 so you can monitor the results of the functions easily. In the System#Boot loop timer 1 is triggered after 60 seconds to give time to fill all variables from HP, OT and 1W.
*Called by*: system Boot
rule 01]]
on System#Boot then
print('BLB Heishamon_rules20241211.txt');
#allowDHW = 1;
#allowOTT = 1;
#allowTaShift= 1;
#allowHeatDelta = 1; -- HeatDelta isn't a seperate rule but part of TaShift
#allowPumpDuty = 1;
#allowQuietMode = 1;
#allowSyncHP = 1;
#allowSyncOT = 1;
#chEnable = -1; -- #chEnable is clean ?chEnable
#chEnableOffTime = -1; -- Time ?chEnable goes off
#chEnableTimeOff = -1; -- ?chEnable Off Timer (duration)
#CompFreqTarget = -1; -- Compressor Frequency target (depending on outside temperature)
#CompRunTime = -1; -- Duration (in minutes) the compressor is running
#CompRunSec = -1; -- Duration (in seconds) the compressor is running during start phase
#CompState = -1; -- Compressor running state (0/1)
#CompStateChangeTime = -1; -- Time the compressor started running
#Debug = 1; -- Perform Debug actions (0 = off) depending on the debug level
#DHWRun = -1; -- DHWrun state (0/1)
#FirstBoot = 1; -- 1 initiates boot up routine
#Heat = -1; -- HP in OM which includes Heat
-- #HeatDelta = 5; -- HeatDelta (To - Tr temp difference) 20241209 not implemented yet
#HPStateP = -1; -- Previous Heat Pump state
#HPStateR = -1; -- Required Heat Pump state
#MaxPumpDuty = -1; -- Maximum Pumpduty value which fits my installation (~ 11l/m)
#MOT = -1; -- Current Main Outlet Temperature (@Main_Outlet_Temp)
#OMP = -1; -- Previous Operating Mode
#OutsideTemp = -1; -- OusideTemp is taken every 15 minutes to keep it stable
#OMR = -1; -- Required Operating Mode
#QMR = -1; -- Required Quiet Mode
#RemoteOverRide = -1; -- Remote override value
#RoomTempDelta = -1; -- Delta between Room Setpoint and Room Temp (positive = temp above setpoint)
#RoomTempControl = -1; -- Shift Ta as result of #RoomTempDelta
#SHifT = -1; -- Shift Ta Temperature
#SterilizationDay = 7; -- Day of the week the Sterilization Run must be performed (1 = Sunday, 7 = Saturday)
#Time = -1; -- Current Time(formula: %day * 1440 + %hour * 60 + %minute)
#SoftStartControl = -1; -- Shift Ta temperature for soft start control and run time extension.
setTimer(1,60); -- main timer which calls all functions
setTimer(2,10); -- timer for time reference
end
--[[
**TaShift** (Target Temp Manipulations)
*Purpose*: 1) lower Target Temp to softstart the compressor run when heat loss < minimum power HP, 2) extend compressor runtime by shifting TTo (Target Temp Outlet) if To (Temp Outlet) is higher than TTo, 3) Adapt TTo as result of RoomTempDiff and 4) switch off compressor under certain conditions (e.g. roomtemperature too high) by shifting Target Temp maximum down.
*Explanation*: at a certain (high) outside Temperature the minimum power of the HP is higher than the heat lost and as a result the compressor will switch off if To > TTo + 2 degrees. This can lead to short compressor run times and the purpose of this function is to extend the runtime by shifting the Target Temp up. The maximum shift is based on outside temperature and below a certain outside temperature (<=6 degrees) the shift will not be set (as not required).
*Result*: @SetZ1HeatRequestTemperature set to required value
*Called by*: timer=1
rule 02]]
on TaShift then
if #allowTaShift > 0 then #allowTaShift = #allowTaShift + 1; end -- #allowTaShift is set to 0 by change of @Main_Outlet_Temp and @Z1_Water_Target_Temp
if #allowTaShift > 20 then #allowTaShift = 2; end -- #run TaShift at least every 15 * 20 = 300 seconds (5 minutes)
if (#CompRunTime < 15 || #allowTaShift == 2) && #DHWRun < 1 && @ThreeWay_Valve_State == 0 then -- run TaShift every 15 seconds during compressor start phase (the first 15 minutes) during Heat
#SHifT = @Z1_Heat_Request_Temp;
if #CompState > 0 then -- Compressor is running
TaShift2(); -- actions when compressor are running in rule TaShift2() due to error HeishaMon FW.
--[[
if #allowHeatDelta == 1 then -- 20241209 not implemented yet! Increase HeatDelta first minutes compressorrun to lower the compfreq asap.
$HD = -1;
if #CompRunTime > -1 && #CompRunTime < 3 then
$HD = #HeatDelta + 5; -- increase default HeatDelta with 5
elseif #CompRunTime > 20 && #CompRunTime < 25 then -- return to default HeatDelta
$HD = #HeatDelta;
end
if @Heat_Delta != $HD && $HD > 0 then @SetFloorHeatDelta = $HD; end -- set only when value changed
end
]]
else -- Compressor is not running
$StopTime = - 2 * #OutsideTemp - 30; -- define stoptime depending on outside temperature
if #CompState == 0 && #CompRunTime > $StopTime && #CompRunTime < 2 then -- compressor is off for a relative short time (depending on outside temperature)
#SHifT = -5; -- SHifT to -5 to avoid short cycle
else -- stoptime is over
#SHifT = 0; -- SHifT back to 0
end
end
if (%hour > 22 || %hour < 7) && #OutsideTemp < 3 && #SHifT > -3 && (@Main_Outlet_Temp - @Z1_Water_Target_Temp) < 0.5 && #CompState > 0 then
#SHifT = -1 + #SHifT; -- SHifT -1 to switch off compressor a bit earlier Between 23h and 7h
end
#SHifT = min(max(#SHifT, -5), 5); -- keep #SHifT in the range -5 to +5
if #SHifT != @Z1_Heat_Request_Temp && #RemoteOverRide < 1 then -- set only when value changed
@SetZ1HeatRequestTemperature = #SHifT;
end
end
end
-- rule 03
on TaShift2 then -- part of TaShift but separated due to HeishaMon firmware error
$WarTemp = @Z1_Water_Target_Temp - @Z1_Heat_Request_Temp; -- define the WAR temp (this temp is in my setup controlled by HP)
if #CompRunSec < 180 && #CompState == 1 then -- phase 1 (compressor run time < 180 seconds and not if rules are recently loaded (#CompState == 2))
#SoftStartControl = ceil(@Main_Outlet_Temp - 4 + ceil(#CompRunSec / 60)) - $WarTemp; -- start with low TTo, but going up in time to lower Hz asap without switching off
$a = 1; $b = ', CRS < 180';
elseif #CompRunTime < (300 - 5 * #OutsideTemp) then -- phase 2, main control period, keep TTo below To to keep Hz low but not too low to switch off
if @Main_Outlet_Temp > #MOT then -- a hysteresis is build in to avoid TTo jumping up and down too much
#SoftStartControl = ceil(@Main_Outlet_Temp - 1.8) - $WarTemp;
else
#SoftStartControl = ceil(@Main_Outlet_Temp - 1.5) - $WarTemp;
end
$a = 2; $b = concat(', CRT < ', (300 - 5 * #OutsideTemp));
elseif #SoftStartControl > 0 then -- phase 3, returning back to 0 over time if SoftStartControl > 0
$a = 3; $b = ', Back to 0';
if #CompRunTime / 60 == round(#CompRunTime / 60) then
#SoftStartControl = #SoftStartControl - 1;
end
else -- phase 4, no SoftStartControl anymore
$a = 4; $b = ', TaShift Finished';
end
#MOT = @Main_Outlet_Temp; -- set #MOT to compare current MOT during next run
#RoomTempControl = round(#RoomTempDelta * #RoomTempDelta * -6); -- set #RoomTempControl to shift TTo based on #RoomTempDelta
if #RoomTempDelta < 0 then #RoomTempControl = #RoomTempControl * -1; end -- correct sign
#SHifT = #SoftStartControl;
if #CompRunTime > 20 || #RoomTempControl > 0 then #SHifT = #SoftStartControl + #RoomTempControl; end -- #ShifT is combination of both SSC and RTC
if ($a == 2 || $a == 3) && (@Main_Outlet_Temp - $WarTemp - #SHifT) > 1.8 then -- make sure #SHifT is not set too low to prevent compressor switch off
#SHifT = ceil(@Main_Outlet_Temp - 1.8) - $WarTemp;
$a = $a + 10; $b = concat($b,' ( limit #SHifT)');
end
if #Debug > 0 || #RemoteOverRide > 0 then print('TaM phase ', $a, $b, ' CRS: ', #CompRunSec, ' CRT: ', #CompRunTime, ' RTD: ', #RoomTempDelta, ' SSC: ', #SoftStartControl, ' RTC: ', #RoomTempControl, ' SHifT: ', #SHifT, ' MOT: ', @Main_Outlet_Temp, ' Z1T: ', @Z1_Water_Target_Temp); end
end
--[[
**OperatingMode**
*Purpose*: change Operating Mode (between Heat and Heat + DHW)
*Explanation*: sets OperatingMode to #OMRR
*Called by*: DHW
rule 04]]
on OperatingMode then
if @Operating_Mode_State != #OMR then @SetOperationMode = #OMR; end -- set only when value changed
end
--[[
**HeatPumpState**
*Purpose*: switch HP on or off
*Explanation*: sets Heatpump state to #HPStateR, only if #RemoteOverRide is not set (to -1).
*Called by*: OpenThermThermostat, DHW
rule 05]]
on HeatPumpState then
if @Heatpump_State != #HPStateR && #RemoteOverRide != -1 then @SetHeatpump = #HPStateR; end -- set only when value changed and #RemoteOverRide != 0
end
--[[
**OpenThermThermostat** (OpenTherm Thermostat)
*Purpose*: to control the HP Heat prodcution by the Opentherm Thermostat.
*Explanation*: The main control is ?chEnable; chEnable does have similar function as an ON/OFF thermostat (as my Evohome Opentherm thermostat doesn't provide a stable chSetpoint value I'm not using chSetpoint anymore).
The HP will be switched ON if #chEnable == 1 and @Main_Outlet_Temp < 25 degrees. This last condition is to prevend the HP will be switched ON too soon, e.g. if water is too hot as result of a DHW run or recent compressor run.
The HP will be switched OFF if all of the following conditions are true: a) chEnable > 30 minutes OFF (or chEnable > 15 minutes OFF AND compressor > 15 minutes OFF) and b) compressor is OFF or running > 60 minutes and c) outside temperature > -4 degrees. This last condition is to keep the waterpump running at low temperatures.
By default this function is checked every 30 seconds except when heatpump is switched off if will run only after 10 minutes.
*Called by*: timer=1
06]]
on OpenThermThermostat then
if #allowOTT == 1 && #RemoteOverRide < 3 && #DHWRun < 1 && @ThreeWay_Valve_State == 0 && @Defrosting_State == 0 then
#allowOTT = 2;
if #chEnable == 1 && #RoomTempDelta < 0.3 && #HPStateR != 1 then -- Heat request is when chEnable == 1 and #RoomTempDelta < 0.3
if #Debug > 0 then print('OTTx chE: ', #chEnable, ' RTD: ', #RoomTempDelta, 'HPSR: ', #HPStateR);end
#HPStateR = 1; -- Set HP ON (HP State 1) if Heat Request
HeatPumpState();
else
$OTT = 0; -- for debugging reasons this if/elseif is setup. Switch off is allowed when:
if #RoomTempDelta > 0.7 then -- #RoomTempDelta is high (> 0.7)
$OTT = 1;
elseif #chEnableOffTime > 30 then -- #ChEnable is off for more than 30 minutes
$OTT = 2;
elseif #chEnableOffTime > 15 && #CompRunTime < -15 then -- #ChEnable is off for more than 15 minutes and compressor is off for more than 15 minutes
$OTT = 3;
elseif #chEnableOffTime > 5 && %hour > 22 then -- #ChEnable is off for more than 5 minutes and time is after 23h
$OTT = 4;
end
if $OTT > 0 && @ThreeWay_Valve_State == 0 && (#CompRunTime > 60 || #CompState == 0) && #OutsideTemp > -5 && #HPStateR != 0 then -- additional conditions to really switch off Heat Pump.
if #Debug > 0 then print('OTTx: ', $OTT, ' RTD: ', #RoomTempDelta, ' chEOT: ', #chEnableOffTime, ' CRT: ', #CompRunTime, ' h: ', %hour, ' TWV: ', @ThreeWay_Valve_State, ' CS: ', #CompState, #OutsideTemp);end
#HPStateR = 0; -- Set HP OFF (HP State 0) if no Heat Request anymore
HeatPumpState();
if @Operating_Mode_State != 0 then @SetOperationMode = 0;end -- if, for whatever reason OM != 0 then OM = 0
end
end
setTimer(4,60); -- run every minute (but only when #heat = 1, see syncHP
end
end
--[[
**DHW**
*Purpose*: 1) to have hot water available & 2) to do weekly sterilization run.
*Explanation*: DHW run will be done: 1) every day after 13h (most efficient time of the day) if DHW temp is below default threshold (@DHW_Heat_Delta), 2) after 9h if DHW temp is 5 degrees below default threshold and 3) immediately if DHW Temp is 10 degrees below default threshold. If day is #SterilizationDay a DHW run + sterilization run will always be performed, also if default threshold is not passed. If a DHW run is performed after 11h on the day before #SterilizationDay the sterilization run will be perfored on this day and the Sterilization run will be skiped on SterilizationDay itself. OM 4 is used to give the HP the option to produce heat during Sterilization run on external element. After the DHW run the previous OM and HPState will be restored. Defrost state is checked to prevent returning back from DHW run to previous OM if Defrost is performed during DHW run. This function runs every 15 minutes.
*Called by*: timer=1
rule 07]]
on DHW then
if #allowDHW == 1 && #RemoteOverRide < 4 then
#allowDHW = 2;
if @ThreeWay_Valve_State == 0 && (@DHW_Temp < (@DHW_Target_Temp + @DHW_Heat_Delta - 10) || (%hour > 9 && @DHW_Temp < (@DHW_Target_Temp + @DHW_Heat_Delta - 5))|| (%hour == 13 && (%day == #SterilizationDay || @DHW_Temp < (@DHW_Target_Temp + @DHW_Heat_Delta)))) then -- DHW run if conditions are right
#DHWRun = 1; -- set #DHWrun to 1 to make sure no rules will interfear during DHW run.
#OMP = @Operating_Mode_State; -- store current OM in #OMP to be able to go back to this OM after the DHW run
#HPStateP = @Heatpump_State; -- store current HPS in #HPStateP to be able to go back to this HPS after the DHW run
if #OMP == 0 then -- set #OMR (Requested OM) depending on current OM
#OMR = 4;
elseif #OMP == 1 then
#OMR = 5;
else
#OMR = 3;
end
OperatingMode(); -- change OM
#HPStateR = 1; -- set #HPStateR (Requested HP state) to 1
HeatPumpState(); -- change HP state
end
if #DHWRun > 0 then -- if DHW run is ongoing
if %day > (#SterilizationDay - 2) && %hour > 10 && @DHW_Temp > 47 && @Sterilization_State != 1 then
@SetForceSterilization = 1; -- set Sterilization during DHW run on #SterilizationDay or #SterilizationDay - 1
#SterilizationDay = #SterilizationDay + 10; -- add 10 to prevent Sterilization on #SterilizationDay itself
end
if @ThreeWay_Valve_State == 0 && @DHW_Temp >= @DHW_Target_Temp && @Defrosting_State == 0 && @Sterilization_State == 0 then
#OMR = max(0,#OMP); -- set #OMR to previous OM
#OMP = @Operating_Mode_State; -- set #OMP to current OM
OperatingMode(); -- return to previous OM after DHW run
#HPStateR = #HPStateP; -- set #HPStateR to #HPStateP (previous HP State)
HeatPumpState(); -- return to previous HPState
#HPStateP = 1; -- set #HPStateP (previous HS State to 1 (during DHW run)
#DHWRun = 0; -- reset #DHWrun back to 0
end
end
if %day == (#SterilizationDay -10) then #SterilizationDay = #SterilizationDay - 10; end -- reset #SterilizationDay back to original value if #Sterilization run was done on #SterilizationDay - 1
setTimer(6,900); -- run this rule every 15 minutes.
end
end
--[[
**PumpDuty**
*Purpose*: to set the (max)PumpSpeed depening in the Operation Mode (Heat/Cool, DHW or Idle) and for Heat/Cool the speed will depend on the outside temperature as well to make sure enough energy can be transported. The main reason for this function is to avoid water running sounds in the piping an radiators.
*Explanation*: During DHW run the maxPumpDuty will be high (140) to allow high power transport to the boiler & during DHW run the piping doesn't produce noice. Almost at the end of the run the maxPumpSpeed is reduced (to 90) to avoid short noice peak when 3way valve returs back to 0. If @Pump_Flowrate_mode == 1 (direct) maxPumpDuty will be set based on actual water flow (see below), else the actual water flow will not be used as feedback as the HP controls pump duty itselfs based on dT.
During Heat maxPumpDuty will be set in such way the water flow will 10 to 14 liter per minute depending on the outside temperature.
During Idle maxPumpDuty will be set in such way the water flow will be 8 liter per minute.
When HP switches off maxPumpDuty will be set back to default value.
*Called by*: timer=1
rule 08]]
on pumpDuty then
if #allowPumpDuty == 1 && #RemoteOverRide < 5 then
#allowPumpDuty = 2;
#MaxPumpDuty = 82; -- default value !!!
if @ThreeWay_Valve_State == 1 then -- set value during DHW run
#MaxPumpDuty = 140; -- value during DHW run !!!
if (@Sterilization_State == 0 && @DHW_Temp > @DHW_Target_Temp) || (@Sterilization_State == 1 && @DHW_Temp > 57) then
#MaxPumpDuty = #MaxPumpDuty - 10; -- lower value at the end of the DHW run to recude noice if 3way valve swich back to room
end
elseif @Heatpump_State == 1 then -- Set value for non-DHW run and HP state ON.
if @Compressor_Freq == 0 && @Defrosting_State != 1 then
#MaxPumpDuty = 82; -- this value is used for water cicrulation when compressor is off (between the runs) !!!
elseif @Operating_Mode_State == 1 then -- OM Cool
#MaxPumpDuty = 92; -- fixed value during Cool !!!
else -- set value during heat based on required flow from 10 l/m @ 11 degrees or higher and 14 l/m @ -3 degrees or lower. !!!
$QFH = 10; $QFL = 14; $tH = 11; $tL = -3;
if #OutsideTemp >= $tH then
$MaxPumpFlow = $QFH;
elseif #OutsideTemp <= $tL then
$MaxPumpFlow = $QFL;
else
$MaxPumpFlow = ceil($QFH + ($tH - #OutsideTemp) * ($QFL - $QFH) / ($tH - $tL));
end
if @Pump_Flow > 1 && @Pump_Flow < 8 && #MaxPumpDuty <= @Max_Pump_Duty then -- increase value to prevent E62 error if waterflow is too low.
#MaxPumpDuty = @Max_Pump_Duty + 1;
else
#MaxPumpDuty = 55 + floor($MaxPumpFlow * 3);
if (@Pump_Speed / @Pump_Flow) > 145 then
if @Pump_Flow > 8 then
#MaxPumpDuty = @Max_Pump_Duty - 1; -- decrease value if possible
else
#MaxPumpDuty = @Max_Pump_Duty;
end
end
end
end
end
#MaxPumpDuty = max(#MaxPumpDuty, 82); -- prevent lower values than 82 !!!
if @Max_Pump_Duty != #MaxPumpDuty then @SetMaxPumpDuty = #MaxPumpDuty; end -- set only when value changed
setTimer(5, 60); -- run this rule every minute.
end
end
--[[
**QuietMode**
*Purpose*: to define #RQuietMode value based on outside temperature and time of day.
*Explanation*: Quiet Mode is used for 2 reasons: 1) to limit the noice from the HP during night time, 2) to limit the startup power (which comes with noice as well) to prevent short runs. During DHW mode in dayTime the QuietMode level will be 1 step reduced to have more power available. This function runs every 2 minutes.
*Called by*: timer=1
rule 09]]
on QuietMode then
if #allowQuietMode == 1 && #RemoteOverRide < 2 && @Defrosting_State == 0 then
#allowQuietMode = 2;
if #OutsideTemp < 3 || (#OutsideTemp < 5 && #CompFreqTarget == 34) then
#CompFreqTarget = 34;
else
#CompFreqTarget = 24;
end
if #CompRunTime < 3 && @Compressor_Freq > 33 then
#QMR = 3;
elseif @Compressor_Freq < #CompFreqTarget || (#QMR == 0 && @Compressor_Freq < #CompFreqTarget + 6) then
#QMR = 0;
elseif @Compressor_Freq < #CompFreqTarget + 6 || (#QMR == 1 && @Compressor_Freq < #CompFreqTarget + 12) then
#QMR = 1;
elseif @Compressor_Freq < #CompFreqTarget + 26 || (#QMR == 2 && @Compressor_Freq < #CompFreqTarget + 32) then
#QMR = 2;
else
#QMR = 3;
end
if #QMR > 1 && @ThreeWay_Valve_State == 1 && %hour > 9 && %hour < 17 then #QMR = -1 + #QMR; end
setTimer(3,120); -- run this rule every 2 minutes.
if @Defrosting_State == 1 || #CompState < 1 || #CompRunTime < 5 || %hour < 7 then #QMR = 3; end -- always QM3 during all these conditions
if #QMR != @Quiet_Mode_Level then @SetQuietMode = #QMR; end -- set only when value changed
end
end
--[[
**syncOT** (synchOpenTherm)
*Purpose*: 1) synchronizes several ?opentherm values with their corresponding @heatpump values and vice versa, 2) sync #chEnable with ?chEnable, 3) set #chEnableTimeOff variable.
*Explanation*: Most of the sync is straight forward, ?chEnable is sometime switched off for a short moment, the logic keeps #chEnable 1 as long as ?chEnable is 0 for less than 5 minutes or ?chSetpoint = 10. #chEnableTimeOff is used in OTTThermostat to swich off compressor and/or water pump. ?maxTSet is only cynch with #MaxTa when #MaxTa is set. During Defrost both ?chState & DHWState are set to 0. This function runs every 15 seconds (in same pace as Timer=1)
*Result*: #chE(nable), #chETimeOff
*Called by*: timer=1
rule 10]]
on syncOT then
if #allowSyncOT == 1 then
#allowSyncOT = 2;
?outletTemp = round(@Main_Outlet_Temp);
?inletTemp = round(@Main_Inlet_Temp);
?outsideTemp = #OutsideTemp;
?dhwTemp = round(@DHW_Temp);
?dhwSetpoint = @DHW_Target_Temp;
if ?chEnable == 1 then
#chEnable = 1;
if #chEnableTimeOff != -1 then
#chEnableTimeOff = -1;
#chEnableOffTime= -1;
end
else
if #chEnableTimeOff == -1 then #chEnableTimeOff = #Time; end
#chEnableOffTime= #Time - #chEnableTimeOff;
if #chEnableOffTime> 5 then #chEnable = 0; end
end
?maxTSet = @Z1_Water_Target_Temp + 5;
?relativeModulation = round(@Compressor_Current / 15 * 100);
if #CompState > 0 then
?flameState = 1;
if @Heat_Power_Consumption > 0 then ?chState = 1; else ?chState = 0; end
if @DHW_Power_Consumption > 0 then ?dhwState = 1; else ?dhwState = 0; end
if @Cool_Power_Consumption > 0 then ?coolingState = 1; else ?coolingState = 0; end
else
?flameState = 0;
?chState = 0;
?dhwState = 0;
?coolingState = 0;
end
$RoomSetpoint = min(max(?roomTempSet, 10), 22);
#RoomTempDelta = max(min(20 - $RoomSetpoint, 5), -5); -- replace 20 with ?roomTemp if your thermostat is providing a good, stable value.
setTimer(7,30);
end
end
--[[
**syncHP** (sync Heat Pump variable)
*Purpose*: 1) synchronizes several @heatpump values to use them in several functions
*Called by*: timer=1
rule 11]]
on syncHP then
if #allowSyncHP == 1 then
#allowSyncHP = 2;
if @Operating_Mode_State == 0 || @Operating_Mode_State == 4 then
#Heat = 1;
else
#Heat = 0;
end
if (%minute % 15) == 0 then #OutsideTemp = @Outside_Temp; end
#RemoteOverRide = @Z2_Heat_Request_Temp;
setTimer(8,30);
end
end
--[[
rule 12]]
on @Compressor_Freq then
if @Compressor_Freq > 18 && #CompState == 0 then
#CompStateChangeTime = #Time;
#CompState = 1;
#CompRunSec = 0;
setTimer(9,5);
elseif @Compressor_Freq < 18 && #CompState > 0 then
#CompStateChangeTime = #Time;
#CompState = 0;
end
end
--[[
rule 13]]
on @Main_Outlet_Temp then
if #allowTaShift > 0 then #allowTaShift = 1; end
end
--[[
rule 14]]
on @Z1_Water_Target_Temp then
if #allowTaShift > 0 then #allowTaShift = 1; end
end
--[[
rule 15]]
on timer=1 then
setTimer(1,15);
if #FirstBoot == 1 then
#CompStateChangeTime= #Time;
#RoomTempDelta = 0;
if @Compressor_Freq > 18 then
#CompState = 2;
else
#CompState = 0;
@SetZ1HeatRequestTemperature = 0;
end
#SHifT = @Z1_Heat_Request_Temp;
#OutsideTemp = @Outside_Temp;
if @ThreeWay_Valve_State == 1 && #allowDHW == 1 then #DHWRun = 2; end
#FirstBoot = 2;
else
syncHP();
syncOT();
QuietMode();
pumpDuty();
DHW();
if #Heat == 1 then
OpenThermThermostat();
TaShift();
end
end
end
--[[
rule 16]]
on timer=2 then
#Time = %day * 1440 + %hour * 60 + %minute;
if @Compressor_Freq > 18 then
#CompRunTime = #Time - #CompStateChangeTime;
if #CompRunTime< 0 then
#CompRunTime = #Time - #CompStateChangeTime + 10080;
end
else
#CompRunTime = #CompStateChangeTime - #Time;
end
setTimer(2,60);
end
--[[
rule 17 till 22]]
on timer=3 then #allowQuietMode = 1; end
on timer=4 then #allowOTT = 1; end
on timer=5 then #allowPumpDuty = 1; end
on timer=6 then #allowDHW = 1; end
on timer=7 then #allowSyncOT = 1; end
on timer=8 then #allowSyncHP = 1; end
--[[
rule 23]]
on timer=9 then
#CompRunSec = #CompRunSec + 5;
if #CompRunSec < 600 then setTimer(9,5); end
end