forked from murmlgrmpf/Arduheat
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cBoiler.h
124 lines (98 loc) · 3.27 KB
/
cBoiler.h
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
#ifndef cBoiler_h
#define cBoiler_h
#include "Arduino.h"
#include "PinDefinitions.h"
#include "cTemp.h"
#include "cPump.h"
#include "cValve.h"
#include "cRooms.h"
#include "cWarmWater.h"
#include <cPID.h>
#include <ArduinoJson.h>
// Charge Margins Warmwater and Heating
#define WMargin 10.0
#define HMargin 3.0
#define HeatingPeriodHorizon 1000*60*60*36
class cBoiler
{
public:
/// Creates a Boiler object
cBoiler(cRooms* Rooms_,cWarmWater* WarmWater_);
/// SpTempCharge is the minimum temperature that is needed to charge the boiler.
double getSpTempCharge(void) // Rename: SpTemp
{
double SpTempCharge = TempReserve2.get()+HMargin;
if (bneedChargeHeating)
SpTempCharge = Rooms->getSpHeating() + HMargin;
if (needChargeWarmWater())
SpTempCharge = WarmWater->SpTemp + WMargin;
return (SpTempCharge);
}
boolean needChargeWarmWater(void)
{
// Hysteresis by top and head temperature sensors.
// If top falls below setpoint: charge. If head gets above setpoint: dont charge.
if (WarmWater->SpTemp+HMargin > TempTop.get()) bneedChargeWarmWater = true;
if (WarmWater->SpTemp < TempHead.get()) bneedChargeWarmWater = false;
return bneedChargeWarmWater;
}
boolean needChargeHeating(boolean needHeating)
{
// Hysteresis by TempReserve1 and 2 or no need for heating the rooms.
// If TempReserve1 falls below setpoint and heating of the rooms is needed: charge.
// If TempReserve2 comes above setpoint or heating of the rooms not needed: dont charge.
if ((Rooms->getSpHeating() > TempReserve1.get()) && needHeating) bneedChargeHeating = true;
if ((Rooms->getSpHeating() < TempReserve2.get()) || !needHeating) bneedChargeHeating = false;
return bneedChargeHeating;
}
void charge(float TempHeatSource, boolean bneedSink = false)
{
boolean need = (bneedChargeWarmWater || bneedChargeHeating || bneedSink);
if (need) // if charging is needed, charging is fixed to true
bCharging = true;
else // Hysteresis
{
if (getSpTempCharge() < TempHeatSource)
bCharging = true;
if (getSpTempCharge()-2 > TempHeatSource)
bCharging = false;
}
Valve.set((bDischarging || bCharging)); // Open Valve if charging or discharging
double SpTemp = 0.0;
boolean HeatingPeriod = (millis()- Rooms->lastHeating < HeatingPeriodHorizon);
if (HeatingPeriod)
SpTemp = max(getSpTempCharge(), Rooms->getSpHeating()+HMargin);
else
{
SpTemp = max(getSpTempCharge(), WarmWater->SpTemp + WMargin);
Rooms->lastHeating = millis()-HeatingPeriodHorizon; // Rolling horizon for overflow of millis
}
if (bCharging) // Run Pump
Pump.run(SpTemp, TempHeatSource);
else // Stop Charging: Stop PID and Pump
Pump.run();
}
void discharge( boolean bNeedSourceBoiler )
{
bDischarging = bNeedSourceBoiler;
Valve.set((bDischarging || bCharging)); // Open Valve if charging or discharging
}
void triggerChargeWarmWater() {bneedChargeWarmWater = true;};
void getData(JsonObject& root);
cValve Valve;
cPump Pump;
// May become private again (debug)
cTempSensor TempCharge;
cTempSensor TempTop;
cTempSensor TempHead;
cTempSensor TempReserve2;
cTempSensor TempReserve1;
private:
cRooms* Rooms;
cWarmWater* WarmWater;
boolean bneedChargeWarmWater;
boolean bneedChargeHeating;
boolean bDischarging;
boolean bCharging;
};
#endif