The files contained in this repository can be downloaded to your computer using a svn client.
On Linux you simply type the command displayed below.

This URL has Read-Only access.

Statistics
| Revision:

root / trunk / DomotiGa / Thermostat.module @ 550

History | View | Annotate | Download (8.9 kB)

1
' Gambas module file
2
3
PUBLIC tThermostat AS Timer
4
PUBLIC NO_TEMP AS Integer = 1000
5
PRIVATE aDerogatedHeating AS NEW Collection
6
PRIVATE aPreviousRequestedTemperature AS NEW Collection
7
8
PUBLIC SUB Run()
9
10
  ' start poll timer for digitemp
11
  tThermostat = NEW Timer AS "tThermostat"
12
  tThermostat.Delay = Main.iThermostatPollTime * 1000 
13
  tThermostat.Start
14
15
END
16
17
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
18
' gets called at each timer event
19
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20
PUBLIC SUB tThermostat_Timer()
21
22
  ' do the job
23
  DoTheJob()
24
25
END
26
27
PUBLIC SUB DoTheJob()
28
29
  DIM dtCurrent AS Date
30
  DIM iScen, iHeat AS Integer
31
  DIM rSched, rHeat AS Result
32
  DIM fRequestedTemp, fMeasuredTemp AS Float
33
  DIM sStatusDev, sStatusReg, sDeviceName, sRegulatorName AS String
34
  DIM sOnDev AS String = "On"
35
  DIM sOffDev AS String = "Off"
36
  DIM sOnReg AS String = "On"
37
  DIM sOffReg AS String = "Off"
38
  DIM bOutOfDeviceOffset AS Boolean
39
40
  ' get current date/time
41
  dtCurrent = Now()
42
  ' get active scenario
43
  iScen = GetActiveScenario()
44
  ' get scenario's schedules
45
  rSched = Main.hDB.Exec("SELECT * FROM thermostat_schedule WHERE scenario=&1", iScen)
46
  IF rSched THEN
47
    IF rSched.Count THEN
48
    ' for each schedule
49
      FOR EACH rSched
50
        ' get schedule's heating
51
        iHeat = rSched!heating
52
        rHeat = Main.hDB.Exec("SELECT * FROM thermostat_heating WHERE id=&1", iHeat)
53
        IF rHeat THEN
54
          IF rHeat.Count THEN
55
            IF Main.bThermostatDebug THEN Main.WriteDebugLog("[Thermostat] Working on heating : " & rHeat!name)
56
            ' check for constant change
57
            fRequestedTemp = GetRequestedTempForHeating(iScen, iHeat)
58
            IF aPreviousRequestedTemperature.Exist(iHeat) THEN
59
              IF aPreviousRequestedTemperature[iHeat] <> fRequestedTemp THEN
60
                DeleteDerogateHeating(iHeat)
61
                Main.WriteLog("[Thermostat] Ending derogation for : " & rHeat!name)
62
                IF Main.bThermostatDebug THEN Main.WriteDebugLog("[Thermostat] Ending derogation for : " & rHeat!name)
63
              ENDIF
64
              aPreviousRequestedTemperature[iHeat] = fRequestedTemp
65
            ELSE
66
              aPreviousRequestedTemperature.Add(fRequestedTemp, iHeat)
67
            ENDIF
68
            ' get requested temp
69
            fRequestedTemp = GetDerogateHeating(iHeat)
70
            IF fRequestedTemp = NO_TEMP THEN
71
              fRequestedTemp = GetRequestedTempForHeating(iScen, iHeat)
72
            ENDIF
73
            ' get real temp
74
            fMeasuredTemp = CFloat(Replace(Devices.GetCurrentValueForDevice(rHeat!sensor, 1), ",", ".", gb.String)) 
75
            IF Main.bThermostatDebug THEN Main.WriteDebugLog("[Thermostat] Requested temp is : " & fRequestedTemp & "/Measured temp is : " & fMeasuredTemp)
76
            sDeviceName = Devices.FindNameForDevice(rHeat!device)
77
            sStatusDev = Devices.GetValueForDevice(sDeviceName)
78
            IF rHeat!regulator <> 0 THEN sRegulatorName = Devices.FindNameForDevice(rHeat!regulator)
79
            IF rHeat!deviceInverted = TRUE THEN
80
              sOnDev = "Off"
81
              sOffDev = "On"
82
            ELSE
83
              sOnDev = "On"
84
              sOffDev = "Off"
85
            ENDIF
86
            IF rHeat!regulatorInverted = TRUE THEN
87
              sOnReg = "Off"
88
              sOffReg = "On"
89
            ELSE
90
              sOnReg = "On"
91
              sOffReg = "Off"
92
            ENDIF
93
            bOutOfDeviceOffset = FALSE
94
            IF NOT (isInsideLatency(rHeat!device, rHeat!deviceLatency)) THEN
95
              ' compare requested temp to sensor's one
96
              IF fMeasuredTemp + rHeat!deviceOffsetBottom <= fRequestedTemp THEN
97
              ' too cold
98
              bOutOfDeviceOffset = TRUE
99
                IF sStatusDev = sOffDev THEN
100
                  IF Main.bThermostatDebug THEN Main.WriteDebugLog("[Thermostat] Too cold here. Switching On device : " & sDeviceName)
101
                  Devices.SetDevice(sDeviceName, sOnDev)
102
                  IF sRegulatorName THEN Devices.SetDevice(sRegulatorName, sOnReg)
103
                ENDIF
104
              ENDIF
105
              IF fMeasuredTemp - rHeat!deviceOffsetTop >= fRequestedTemp THEN
106
              ' too hot
107
              bOutOfDeviceOffset = TRUE
108
                IF sStatusDev = sOnDev THEN
109
                  IF Main.bThermostatDebug THEN Main.WriteDebugLog("[Thermostat] Too hot here. Switching Off device : " & sDeviceName)
110
                  Devices.SetDevice(sDeviceName, sOffDev)
111
                  IF sRegulatorName THEN Devices.SetDevice(sRegulatorName, sOffReg)
112
                ENDIF
113
              ENDIF
114
              IF NOT (bOutOfDeviceOffset) THEN
115
                IF sRegulatorName THEN
116
                  sStatusReg = Devices.GetValueForDevice(sRegulatorName)
117
                  IF fMeasuredTemp + rHeat!regulatorOffsetBottom <= fRequestedTemp THEN
118
                  ' little cold
119
                    IF sStatusReg = sOffReg THEN
120
                      IF Main.bThermostatDebug THEN Main.WriteDebugLog("[Thermostat] Little cold here. Switching On regulator : " & sRegulatorName)
121
                      Devices.SetDevice(sRegulatorName, sOnReg)
122
                    ENDIF
123
                  ENDIF
124
                  IF fMeasuredTemp - rHeat!regulatorOffsetTop >= fRequestedTemp THEN
125
                  ' little hot
126
                    IF sStatusReg = sOnReg THEN
127
                      IF Main.bThermostatDebug THEN Main.WriteDebugLog("[Thermostat] Little hot here. Switching Off regulator : " & sRegulatorName)
128
                      Devices.SetDevice(sRegulatorName, sOffReg)
129
                    ENDIF
130
                  ENDIF
131
                ENDIF
132
              ENDIF
133
            ENDIF
134
          ENDIF
135
        ENDIF
136
      NEXT
137
    ENDIF
138
  ENDIF
139
140
END
141
142
PRIVATE FUNCTION GetActiveScenario() AS Integer
143
144
  DIM rResultScen AS result
145
146
  rResultScen = Main.hDB.Exec("SELECT id, name FROM thermostat_scenarii WHERE name=&1", Main.GlobalVar["Thermostat_Mode"])
147
  IF rResultScen THEN
148
    IF rResultScen.Count >= 1 THEN
149
      IF Main.bThermostatDebug THEN Main.WriteDebugLog("[Thermostat] Active scenario is : " & Main.GlobalVar["Thermostat_Mode"])
150
      RETURN rResultScen!id
151
    ENDIF
152
  ENDIF
153
  RETURN 0
154
155
END
156
157
PUBLIC FUNCTION GetRequestedTempForHeating(iScenario AS Integer, iHeating AS Integer) AS Float
158
159
  DIM sSql AS String
160
  DIM rTemp AS Result
161
  DIM fReturn AS Float
162
163
  sSql = "SELECT curtime() as curtime, dayofweek(curdate()) as curday, day, time,name, value FROM `thermostat_schedule_entry` se , `thermostat_constant` "
164
  sSql &= " c where c.id=se.constant AND dayofweek(curdate()) = Day AND se.scenario = &1 AND se.heating = &2 order by Day, Time "
165
  rTemp = Main.hDB.Exec(sSql, iScenario, iHeating)
166
  IF rTemp THEN
167
    IF rTemp.Count THEN
168
      FOR EACH rTemp
169
        IF rTemp!curtime >= rTemp!time AND rTemp!curday >= rTemp!day THEN
170
          fReturn = rTemp!value
171
        ELSE
172
          BREAK
173
        ENDIF
174
      NEXT
175
      RETURN fReturn
176
    ENDIF
177
  ENDIF
178
  RETURN NO_TEMP
179
180
END
181
182
PUBLIC FUNCTION GetNextRequestedTempForHeating(iScenario AS Integer, iHeating AS Integer) AS Float
183
184
  DIM sSql AS String
185
  DIM rTemp AS Result
186
  DIM fCurrentReq, fReturn AS Float
187
188
  sSql = "SELECT curtime() as curtime,  time,name, value FROM `thermostat_schedule_entry` se , `thermostat_constant` "
189
  sSql = sSql & " c where c.id=se.constant AND dayofweek(curdate()) = Day AND se.scenario = &1 AND se.heating = &2 order by Time "
190
  rTemp = Main.hDB.Exec(sSql, iScenario, iHeating)
191
  IF rTemp THEN
192
    IF rTemp.Count THEN
193
      FOR EACH rTemp
194
        IF rTemp!curtime >= rTemp!time THEN
195
          ' before now
196
          fCurrentReq = rTemp!value
197
        ELSE
198
          fReturn = rTemp!value
199
          IF fCurrentReq <> fReturn THEN RETURN fReturn
200
        ENDIF
201
      NEXT
202
    ENDIF
203
  ENDIF
204
  RETURN NO_TEMP
205
206
END
207
208
PRIVATE FUNCTION isInsideLatency(iDevice AS Integer, iLatency AS Integer) AS Boolean
209
210
  DIM rDev AS Result
211
212
  rDev = Main.hDB.Exec("select * from devices where id=&1", iDevice)
213
  IF rDev THEN
214
    IF rDev.Count >= 1 THEN
215
      IF DateDiff(rDev!lastchanged, Now(), gb.Minute) <= iLatency THEN
216
        IF Main.bThermostatDebug THEN Main.WriteDebugLog("[Thermostat] Inside latency, nothing to do here.")
217
        RETURN TRUE
218
      ENDIF
219
    ENDIF
220
  ENDIF
221
  RETURN FALSE
222
223
END
224
225
PUBLIC SUB SetDerogateHeating(iScen AS Integer, iHeat AS Integer, fTemp AS Float)
226
227
  IF aDerogatedHeating.Exist(iHeat) THEN
228
    IF GetRequestedTempForHeating(iscen, iheat) = fTemp THEN
229
      aDerogatedHeating.Remove(iHeat)
230
    ELSE
231
      aDerogatedHeating[iHeat] = fTemp
232
    ENDIF
233
  ELSE
234
    ' not found
235
    aDerogatedHeating.Add(fTemp, iHeat)
236
  ENDIF
237
238
END
239
240
PUBLIC FUNCTION GetDerogateHeating(iHeat AS Integer) AS Float
241
242
  IF aDerogatedHeating.Exist(iHeat) THEN
243
    RETURN aDerogatedHeating[iHeat]
244
  ELSE
245
    RETURN NO_TEMP
246
  ENDIF
247
248
END
249
250
PUBLIC SUB DeleteAllDerogateHeating()
251
252
  IF aDerogatedHeating.Count THEN
253
    Main.WriteLog("[Thermostat] Ending All derogated temp")
254
    aDerogatedHeating.Clear
255
  ENDIF
256
257
END
258
259
PUBLIC SUB DeleteDerogateHeating(iHeat AS Integer)
260
261
  IF aDerogatedHeating.Exist(iHeat) THEN aDerogatedHeating.Remove(iHeat)
262
263
END