@@ -6,10 +6,10 @@ Copyright 2018, Ihor Melnyk
6
6
#include " OpenTherm.h"
7
7
8
8
OpenTherm::OpenTherm (int inPin, int outPin, bool isSlave):
9
+ status(OpenThermStatus::NOT_INITIALIZED),
9
10
inPin(inPin),
10
11
outPin(outPin),
11
- isSlave(isSlave),
12
- status(OpenThermStatus::NOT_INITIALIZED),
12
+ isSlave(isSlave),
13
13
response(0 ),
14
14
responseStatus(OpenThermResponseStatus::NONE),
15
15
responseTimestamp(0 ),
@@ -24,16 +24,16 @@ void OpenTherm::begin(void(*handleInterruptCallback)(void), void(*processRespons
24
24
pinMode (outPin, OUTPUT);
25
25
if (handleInterruptCallback != NULL ) {
26
26
this ->handleInterruptCallback = handleInterruptCallback;
27
- attachInterrupt (digitalPinToInterrupt (inPin), handleInterruptCallback, CHANGE);
27
+ attachInterrupt (digitalPinToInterrupt (inPin), handleInterruptCallback, CHANGE);
28
28
}
29
29
activateBoiler ();
30
30
status = OpenThermStatus::READY;
31
- this ->processResponseCallback = processResponseCallback;
31
+ this ->processResponseCallback = processResponseCallback;
32
32
}
33
33
34
34
void OpenTherm::begin (void (*handleInterruptCallback)(void ))
35
35
{
36
- begin (handleInterruptCallback, NULL );
36
+ begin (handleInterruptCallback, NULL );
37
37
}
38
38
39
39
bool ICACHE_RAM_ATTR OpenTherm::isReady ()
@@ -66,7 +66,7 @@ void OpenTherm::sendBit(bool high) {
66
66
}
67
67
68
68
bool OpenTherm::sendRequestAync (unsigned long request)
69
- {
69
+ {
70
70
// Serial.println("Request: " + String(request, HEX));
71
71
noInterrupts ();
72
72
const bool ready = isReady ();
@@ -83,21 +83,21 @@ bool OpenTherm::sendRequestAync(unsigned long request)
83
83
for (int i = 31 ; i >= 0 ; i--) {
84
84
sendBit (bitRead (request, i));
85
85
}
86
- sendBit (HIGH); // stop bit
86
+ sendBit (HIGH); // stop bit
87
87
setIdleState ();
88
88
89
- status = OpenThermStatus::RESPONSE_WAITING;
90
- responseTimestamp = micros ();
89
+ status = OpenThermStatus::RESPONSE_WAITING;
90
+ responseTimestamp = micros ();
91
91
return true ;
92
92
}
93
93
94
94
unsigned long OpenTherm::sendRequest (unsigned long request)
95
- {
95
+ {
96
96
if (!sendRequestAync (request)) return 0 ;
97
97
while (!isReady ()) {
98
98
process ();
99
99
yield ();
100
- }
100
+ }
101
101
return response;
102
102
}
103
103
@@ -111,9 +111,9 @@ bool OpenTherm::sendResponse(unsigned long request)
111
111
for (int i = 31 ; i >= 0 ; i--) {
112
112
sendBit (bitRead (request, i));
113
113
}
114
- sendBit (HIGH); // stop bit
114
+ sendBit (HIGH); // stop bit
115
115
setIdleState ();
116
- status = OpenThermStatus::READY;
116
+ status = OpenThermStatus::READY;
117
117
return true ;
118
118
}
119
119
@@ -123,16 +123,16 @@ OpenThermResponseStatus OpenTherm::getLastResponseStatus()
123
123
}
124
124
125
125
void ICACHE_RAM_ATTR OpenTherm::handleInterrupt ()
126
- {
127
- if (isReady ())
128
- {
129
- if (isSlave && readState () == HIGH) {
130
- status = OpenThermStatus::RESPONSE_WAITING;
131
- }
132
- else {
133
- return ;
134
- }
135
- }
126
+ {
127
+ if (isReady ())
128
+ {
129
+ if (isSlave && readState () == HIGH) {
130
+ status = OpenThermStatus::RESPONSE_WAITING;
131
+ }
132
+ else {
133
+ return ;
134
+ }
135
+ }
136
136
137
137
unsigned long newTs = micros ();
138
138
if (status == OpenThermStatus::RESPONSE_WAITING) {
@@ -151,7 +151,7 @@ void ICACHE_RAM_ATTR OpenTherm::handleInterrupt()
151
151
responseTimestamp = newTs;
152
152
responseBitIndex = 0 ;
153
153
}
154
- else {
154
+ else {
155
155
status = OpenThermStatus::RESPONSE_INVALID;
156
156
responseTimestamp = newTs;
157
157
}
@@ -172,40 +172,40 @@ void ICACHE_RAM_ATTR OpenTherm::handleInterrupt()
172
172
}
173
173
174
174
void OpenTherm::process ()
175
- {
175
+ {
176
176
noInterrupts ();
177
177
OpenThermStatus st = status;
178
178
unsigned long ts = responseTimestamp;
179
- interrupts ();
179
+ interrupts ();
180
180
181
181
if (st == OpenThermStatus::READY) return ;
182
182
unsigned long newTs = micros ();
183
183
if (st != OpenThermStatus::NOT_INITIALIZED && (newTs - ts) > 1000000 ) {
184
- status = OpenThermStatus::READY;
184
+ status = OpenThermStatus::READY;
185
185
responseStatus = OpenThermResponseStatus::TIMEOUT;
186
186
if (processResponseCallback != NULL ) {
187
187
processResponseCallback (response, responseStatus);
188
- }
189
- }
190
- else if (st == OpenThermStatus::RESPONSE_INVALID) {
191
- status = OpenThermStatus::DELAY;
188
+ }
189
+ }
190
+ else if (st == OpenThermStatus::RESPONSE_INVALID) {
191
+ status = OpenThermStatus::DELAY;
192
192
responseStatus = OpenThermResponseStatus::INVALID;
193
193
if (processResponseCallback != NULL ) {
194
194
processResponseCallback (response, responseStatus);
195
- }
195
+ }
196
196
}
197
197
else if (st == OpenThermStatus::RESPONSE_READY) {
198
- status = OpenThermStatus::DELAY;
198
+ status = OpenThermStatus::DELAY;
199
199
responseStatus = (isSlave ? isValidRequest (response) : isValidResponse (response)) ? OpenThermResponseStatus::SUCCESS : OpenThermResponseStatus::INVALID;
200
200
if (processResponseCallback != NULL ) {
201
201
processResponseCallback (response, responseStatus);
202
- }
202
+ }
203
203
}
204
204
else if (st == OpenThermStatus::DELAY) {
205
205
if ((newTs - ts) > 100000 ) {
206
206
status = OpenThermStatus::READY;
207
207
}
208
- }
208
+ }
209
209
}
210
210
211
211
bool OpenTherm::parity (unsigned long frame) // odd parity
@@ -221,13 +221,13 @@ bool OpenTherm::parity(unsigned long frame) //odd parity
221
221
222
222
OpenThermMessageType OpenTherm::getMessageType (unsigned long message)
223
223
{
224
- OpenThermMessageType msg_type = static_cast <OpenThermMessageType>((message >> 28 ) & 7 );
225
- return msg_type;
224
+ OpenThermMessageType msg_type = static_cast <OpenThermMessageType>((message >> 28 ) & 7 );
225
+ return msg_type;
226
226
}
227
227
228
228
OpenThermMessageID OpenTherm::getDataID (unsigned long frame)
229
229
{
230
- return (OpenThermMessageID)((frame >> 16 ) & 0xFF );
230
+ return (OpenThermMessageID)((frame >> 16 ) & 0xFF );
231
231
}
232
232
233
233
unsigned long OpenTherm::buildRequest (OpenThermMessageType type, OpenThermMessageID id, unsigned int data)
@@ -243,11 +243,11 @@ unsigned long OpenTherm::buildRequest(OpenThermMessageType type, OpenThermMessag
243
243
244
244
unsigned long OpenTherm::buildResponse (OpenThermMessageType type, OpenThermMessageID id, unsigned int data)
245
245
{
246
- unsigned long response = data;
247
- response |= type << 28 ;
248
- response |= ((unsigned long )id) << 16 ;
249
- if (parity (response)) response |= (1ul << 31 );
250
- return response;
246
+ unsigned long response = data;
247
+ response |= type << 28 ;
248
+ response |= ((unsigned long )id) << 16 ;
249
+ if (parity (response)) response |= (1ul << 31 );
250
+ return response;
251
251
}
252
252
253
253
bool OpenTherm::isValidResponse (unsigned long response)
@@ -259,48 +259,48 @@ bool OpenTherm::isValidResponse(unsigned long response)
259
259
260
260
bool OpenTherm::isValidRequest (unsigned long request)
261
261
{
262
- if (parity (request)) return false ;
263
- byte msgType = (request << 1 ) >> 29 ;
264
- return msgType == READ_DATA || msgType == WRITE_DATA;
262
+ if (parity (request)) return false ;
263
+ byte msgType = (request << 1 ) >> 29 ;
264
+ return msgType == READ_DATA || msgType == WRITE_DATA;
265
265
}
266
266
267
267
void OpenTherm::end () {
268
- if (this ->handleInterruptCallback != NULL ) {
268
+ if (this ->handleInterruptCallback != NULL ) {
269
269
detachInterrupt (digitalPinToInterrupt (inPin));
270
270
}
271
271
}
272
272
273
273
const char *OpenTherm::statusToString (OpenThermResponseStatus status)
274
274
{
275
275
switch (status) {
276
- case NONE: return " NONE" ;
276
+ case NONE: return " NONE" ;
277
277
case SUCCESS: return " SUCCESS" ;
278
278
case INVALID: return " INVALID" ;
279
279
case TIMEOUT: return " TIMEOUT" ;
280
- default : return " UNKNOWN" ;
280
+ default : return " UNKNOWN" ;
281
281
}
282
282
}
283
283
284
284
const char *OpenTherm::messageTypeToString (OpenThermMessageType message_type)
285
285
{
286
286
switch (message_type) {
287
- case READ_DATA: return " READ_DATA" ;
288
- case WRITE_DATA: return " WRITE_DATA" ;
289
- case INVALID_DATA: return " INVALID_DATA" ;
290
- case RESERVED: return " RESERVED" ;
291
- case READ_ACK: return " READ_ACK" ;
292
- case WRITE_ACK: return " WRITE_ACK" ;
293
- case DATA_INVALID: return " DATA_INVALID" ;
287
+ case READ_DATA: return " READ_DATA" ;
288
+ case WRITE_DATA: return " WRITE_DATA" ;
289
+ case INVALID_DATA: return " INVALID_DATA" ;
290
+ case RESERVED: return " RESERVED" ;
291
+ case READ_ACK: return " READ_ACK" ;
292
+ case WRITE_ACK: return " WRITE_ACK" ;
293
+ case DATA_INVALID: return " DATA_INVALID" ;
294
294
case UNKNOWN_DATA_ID: return " UNKNOWN_DATA_ID" ;
295
- default : return " UNKNOWN" ;
295
+ default : return " UNKNOWN" ;
296
296
}
297
297
}
298
298
299
299
// building requests
300
300
301
301
unsigned long OpenTherm::buildSetBoilerStatusRequest (bool enableCentralHeating, bool enableHotWater, bool enableCooling, bool enableOutsideTemperatureCompensation, bool enableCentralHeating2) {
302
302
unsigned int data = enableCentralHeating | (enableHotWater << 1 ) | (enableCooling << 2 ) | (enableOutsideTemperatureCompensation << 3 ) | (enableCentralHeating2 << 4 );
303
- data <<= 8 ;
303
+ data <<= 8 ;
304
304
return buildRequest (OpenThermMessageType::READ_DATA, OpenThermMessageID::Status, data);
305
305
}
306
306
@@ -349,11 +349,6 @@ float OpenTherm::getFloat(const unsigned long response) const {
349
349
return f;
350
350
}
351
351
352
- float OpenTherm::getTemperature (unsigned long response) {
353
- float temperature = isValidResponse (response) ? getFloat (response) : 0 ;
354
- return temperature;
355
- }
356
-
357
352
unsigned int OpenTherm::temperatureToData (float temperature) {
358
353
if (temperature < 0 ) temperature = 0 ;
359
354
if (temperature > 100 ) temperature = 100 ;
@@ -363,8 +358,8 @@ unsigned int OpenTherm::temperatureToData(float temperature) {
363
358
364
359
// basic requests
365
360
366
- unsigned long OpenTherm::setBoilerStatus (bool enableCentralHeating, bool enableHotWater, bool enableCooling, bool enableOutsideTemperatureCompensation, bool enableCentralHeating2) {
367
- return sendRequest (buildSetBoilerStatusRequest (enableCentralHeating, enableHotWater, enableCooling, enableOutsideTemperatureCompensation, enableCentralHeating2));
361
+ unsigned long OpenTherm::setBoilerStatus (bool enableCentralHeating, bool enableHotWater, bool enableCooling, bool enableOutsideTemperatureCompensation, bool enableCentralHeating2) {
362
+ return sendRequest (buildSetBoilerStatusRequest (enableCentralHeating, enableHotWater, enableCooling, enableOutsideTemperatureCompensation, enableCentralHeating2));
368
363
}
369
364
370
365
bool OpenTherm::setBoilerTemperature (float temperature) {
@@ -374,5 +369,24 @@ bool OpenTherm::setBoilerTemperature(float temperature) {
374
369
375
370
float OpenTherm::getBoilerTemperature () {
376
371
unsigned long response = sendRequest (buildGetBoilerTemperatureRequest ());
377
- return getTemperature (response);
372
+ return isValidResponse (response) ? getFloat (response) : 0 ;
373
+ }
374
+
375
+ float OpenTherm::getReturnTemperature () {
376
+ unsigned long response = sendRequest (buildRequest (OpenThermRequestType::READ, OpenThermMessageID::Tret, 0 ));
377
+ return isValidResponse (response) ? getFloat (response) : 0 ;
378
+ }
379
+
380
+ float OpenTherm::getModulation () {
381
+ unsigned long response = sendRequest (buildRequest (OpenThermRequestType::READ, OpenThermMessageID::RelModLevel, 0 ));
382
+ return isValidResponse (response) ? getFloat (response) : 0 ;
383
+ }
384
+
385
+ float OpenTherm::getPressure () {
386
+ unsigned long response = sendRequest (buildRequest (OpenThermRequestType::READ, OpenThermMessageID::CHPressure, 0 ));
387
+ return isValidResponse (response) ? getFloat (response) : 0 ;
388
+ }
389
+
390
+ unsigned char OpenTherm::getFault () {
391
+ return ((sendRequest (buildRequest (OpenThermRequestType::READ, OpenThermMessageID::ASFflags, 0 )) >> 8 ) & 0xff );
378
392
}
0 commit comments