Skip to content

Commit 53d8b3e

Browse files
committed
Merge branch 'dev' into main
2 parents 6e00cb0 + 2beb69d commit 53d8b3e

File tree

5 files changed

+59
-33
lines changed

5 files changed

+59
-33
lines changed

OTGW-Core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,7 @@ enum OpenThermStatus {
455455
* Use f88(), u16() or s16() functions to get appropriate value of data packet according to id of message.
456456
*/
457457
struct OpenthermData {
458+
byte master; //1=master, 0=slave
458459
byte type;
459460
byte id;
460461
byte valueHB;

OTGW-Core.ino

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,8 @@ uint16_t print_status()
476476
{
477477
char _flag8_master[8] {0};
478478
char _flag8_slave[8] {0};
479-
//bit: [clear/0, set/1]
479+
480+
//bit: [clear/0, set/1]
480481
// 0: CH enable [ CH is disabled, CH is enabled]
481482
// 1: DHW enable [ DHW is disabled, DHW is enabled]
482483
// 2: Cooling enable [ Cooling is disabled, Cooling is enabled]]
@@ -505,7 +506,6 @@ uint16_t print_status()
505506
sendMQTTData("ch2_enable", (((OTdata.valueHB) & 0x10) ? "ON" : "OFF"));
506507
sendMQTTData("summerwintertime", (((OTdata.valueHB) & 0x20) ? "ON" : "OFF"));
507508
sendMQTTData("dhw_blocking", (((OTdata.valueHB) & 0x40) ? "ON" : "OFF"));
508-
509509
//Slave
510510
// 0: fault indication [ no fault, fault ]
511511
// 1: CH mode [CH not active, CH active]
@@ -538,7 +538,6 @@ uint16_t print_status()
538538
sendMQTTData("diagnostic_indicator", (((OTdata.valueLB) & 0x40) ? "ON" : "OFF"));
539539
sendMQTTData("eletric_production", (((OTdata.valueLB) & 0x80) ? "ON" : "OFF"));
540540

541-
542541
uint16_t _value = OTdata.u16();
543542
OTGWDebugTf("Status u16 [%04x] _value [%04x] hb [%02x] lb [%02x]\r\n", OTdata.u16(), _value, OTdata.valueHB, OTdata.valueLB);
544543
return _value;
@@ -954,15 +953,16 @@ uint16_t print_daytime()
954953
}
955954

956955

957-
//===================[ Send buffer to OTGW ]=============================
958-
// - zorg dat er maar 1 call is waar er data NAAR de otgw wordt gestuurd. In die call, store die commando's in een queue
959-
// - zorg dat er maar 1 call is waar inkomende data van de otgw word verwerkt. Filter die data op command response (3rd char == ':') en compare met queue.
960-
// - met een timer of ander loopje, check if een command in de queue te oud is. (now() - received > 5 sec ofzo) en dan stuur nogmaals
961-
// - voeg een counter toe hoe vaak een command verstuurd is, stop na 5x en gooi een error op de bus/mqtt etc.
956+
//===================[ Command Queue implementatoin ]=============================
962957

963958
#define OTGW_CMD_RETRY 5
964-
#define OTGW_CMD_INTERVAL 5
965-
959+
#define OTGW_CMD_INTERVAL_MS 5000
960+
#define OTGW_DELAY_SEND_MS 1000
961+
/*
962+
addOTWGcmdtoqueue adds a command to the queue.
963+
First it checks the queue, if the command is in the queue, it's updated.
964+
Otherwise it's simply added to the queue, unless there are no free queue slots.
965+
*/
966966
void addOTWGcmdtoqueue(const char* buf, int len){
967967
if ((len < 3) || (buf[2] != '=')){
968968
//no valid command of less then 2 bytes
@@ -991,13 +991,18 @@ void addOTWGcmdtoqueue(const char* buf, int len){
991991
else OTGWDebugTf("CmdQueue: Adding cmd end of queue, slot [%d]\r\n", insertptr);
992992

993993
//insert to the queue
994-
OTGWDebugTf("CmdQueue: Insert queue in slot[%d]:[%s]\r\n", insertptr, cmdqueue[insertptr].cmd);
994+
OTGWDebugTf("CmdQueue: Insert queue in slot[%d]:", insertptr);
995+
OTGWDebug("cmd[");
996+
for (int i = 0; i < len; i++) {
997+
OTGWDebug((char)buf[i]);
998+
}
999+
OTGWDebugf("] (%d)\r\n", len);
9951000
memset(cmdqueue[insertptr].cmd, 0, sizeof(cmdqueue[insertptr].cmd));
9961001
if (len>=sizeof(cmdqueue[insertptr].cmd)) len = sizeof(cmdqueue[insertptr].cmd)-1; //never longer than the buffer
9971002
memcpy(cmdqueue[insertptr].cmd, buf, len);
9981003
cmdqueue[insertptr].cmdlen = len;
9991004
cmdqueue[insertptr].retrycnt = 0;
1000-
cmdqueue[insertptr].due = millis()+20000; //due right away
1005+
cmdqueue[insertptr].due = millis() + OTGW_DELAY_SEND_MS; //due right away
10011006

10021007
//if not found
10031008
if (!foundcmd) {
@@ -1016,12 +1021,12 @@ void addOTWGcmdtoqueue(const char* buf, int len){
10161021
*/
10171022
void handleOTGWqueue(){
10181023
for (int i = 0; i<cmdptr; i++) {
1019-
OTGWDebugTf("CmdQueue: Checking due in queue slot[%d]:[%d]<[%d]\r\n", i, millis(), cmdqueue[i].due);
1020-
if (now() > cmdqueue[i].due) {
1024+
OTGWDebugTf("CmdQueue: Checking due in queue slot[%d]:[%d]=>[%d]\r\n", i, millis(), cmdqueue[i].due);
1025+
if (millis() >= cmdqueue[i].due) {
10211026
OTGWDebugTf("CmdQueue: Queue slot [%d] due\r\n", i);
10221027
sendOTGW(cmdqueue[i].cmd, cmdqueue[i].cmdlen);
10231028
cmdqueue[i].retrycnt++;
1024-
cmdqueue[i].due = millis() + OTGW_CMD_INTERVAL * 1000; //seconds
1029+
cmdqueue[i].due = millis() + OTGW_CMD_INTERVAL_MS;
10251030
if (cmdqueue[i].retrycnt >= OTGW_CMD_RETRY){
10261031
//max retry reached, so delete command from queue
10271032
for (int j=i; j<cmdptr; j++){
@@ -1088,6 +1093,12 @@ void checkOTGWcmdqueue(const char *buf, int len){
10881093
}
10891094
}
10901095

1096+
1097+
//===================[ Send buffer to OTGW ]=============================
1098+
/*
1099+
sendOTGW(const char* buf, int len) sends a string to the serial OTGW device.
1100+
The buffer is send out to OTGW on the serial device instantly, as long as there is space in the buffer.
1101+
*/
10911102
int sendOTGW(const char* buf, int len)
10921103
{
10931104
//Send the buffer to OTGW when the Serial interface is available
@@ -1119,11 +1130,13 @@ int sendOTGW(const char* buf, int len)
11191130
/*
11201131
This function checks if the string received is a valid "raw OT message".
11211132
Raw OTmessages are 9 chars long and start with TBARE when talking to OTGW PIC.
1133+
Message is not an OTmessage if length is not 9 long OR 3th char is ':' (= OTGW command response)
11221134
*/
11231135
bool isvalidotmsg(const char *buf, int len){
11241136
char *chk = "TBARE";
1125-
bool _ret = (len==9);
1126-
_ret &= (strchr(chk, buf[0])!=NULL);
1137+
bool _ret = (len==9); //check 9 chars long
1138+
_ret &= (buf[2]!=':'); //not a otgw command response
1139+
_ret &= (strchr(chk, buf[0])!=NULL); //1 char matches any of 'B', 'T', 'A', 'R' or 'E'
11271140
return _ret;
11281141
}
11291142

@@ -1142,19 +1155,23 @@ void processOTGW(const char *buf, int len){
11421155
if (isvalidotmsg(buf, len)) {
11431156
//OT protocol messages are 9 chars long
11441157
if (settingMQTTOTmessage) sendMQTTData("otmessage", buf);
1158+
11451159
// source of otmsg
1160+
OTdata.master = 0;
11461161
if (buf[0]=='B')
11471162
{
11481163
OTGWDebugT("Boiler ");
1149-
epochBoilerlastseen = now();
1164+
epochBoilerlastseen = now();
1165+
OTdata.master = 1;
11501166
} else if (buf[0]=='T')
11511167
{
11521168
OTGWDebugT("Thermostat ");
11531169
epochThermostatlastseen = now();
11541170
} else if (buf[0]=='R')
11551171
{
11561172
OTGWDebugT("Request Boiler ");
1157-
epochBoilerlastseen = now();
1173+
epochBoilerlastseen = now();
1174+
OTdata.master = 1;
11581175
} else if (buf[0]=='A')
11591176
{
11601177
OTGWDebugT("Answer Themostat ");
@@ -1164,6 +1181,9 @@ void processOTGW(const char *buf, int len){
11641181
OTGWDebugT("Parity error ");
11651182
}
11661183

1184+
//print OTmessage to debug
1185+
OTGWDebugf("[%s] ", buf);
1186+
11671187
//If the Boiler or Thermostat messages have not been seen for 30 seconds, then set the state to false.
11681188
bOTGWboilerstate = (now() < (epochBoilerlastseen+30));
11691189
bOTGWthermostatstate = (now() < (epochThermostatlastseen+30));
@@ -1180,7 +1200,7 @@ void processOTGW(const char *buf, int len){
11801200

11811201
const char *bufval = buf + 1;
11821202
uint32_t value = strtoul(bufval, NULL, 16);
1183-
// Debugf("msg=[%s] value=[%08x]", bufval, value);
1203+
//Debugf("value=[%08x]", value);
11841204

11851205
//split 32bit value into the relevant OT protocol parts
11861206
OTdata.type = (value >> 28) & 0x7; // byte 1 = take 3 bits that define msg msgType
@@ -1223,6 +1243,7 @@ void processOTGW(const char *buf, int len){
12231243
// }
12241244

12251245
switch (static_cast<OpenThermMessageID>(OTdata.id)) {
1246+
case OT_Statusflags: if (OTdata.master==1) OTdataObject.Statusflags = print_status(); break;
12261247
case OT_TSet: OTdataObject.TSet = print_f88(); break;
12271248
case OT_CoolingControl: OTdataObject.CoolingControl = print_f88(); break;
12281249
case OT_TsetCH2: OTdataObject.TsetCH2 = print_f88(); break;
@@ -1248,7 +1269,6 @@ void processOTGW(const char *buf, int len){
12481269
case OT_Hcratio: OTdataObject.Hcratio = print_f88(); break;
12491270
case OT_OpenThermVersionMaster: OTdataObject.OpenThermVersionMaster = print_f88(); break;
12501271
case OT_OpenThermVersionSlave: OTdataObject.OpenThermVersionSlave = print_f88(); break;
1251-
case OT_Statusflags: OTdataObject.Statusflags = print_status(); break;
12521272
case OT_ASFflags: OTdataObject.ASFflags = print_ASFflags(); break;
12531273
case OT_MasterConfigMemberIDcode: OTdataObject.MasterConfigMemberIDcode = print_mastermemberid(); break;
12541274
case OT_SlaveConfigMemberIDcode: OTdataObject.SlaveConfigMemberIDcode = print_slavememberid(); break;

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ Looking for the documentation, go here (work in progress): <br> https://github.
5050

5151
| Version | Release notes |
5252
|-|-|
53-
| 0.8.4 | Adding MsgID for Solar Storage<br>Verbose Status parsing for Ventlation / Heatrecovery<br>Adding msgid 113/114 unsuccessful burnerstart / flame too low<br>Added smartpower configruation detection<br>Added 2.3 spec status bits for (summer/winter time, dhw blocking, service indicator, electric production)<br>Adding PS=1 detection (WebUI notification)<br>Fix: restore settings issue|
53+
| 0.8.5 | Bugfix: Queue bug never sending the command (reporter: @jvinckers)|Small improvement to status parsing, only resturned status from slave gets parsed now.|
54+
| 0.8.4 | Adding MsgID for Solar Storage<br>Verbose Status parsing for Ventlation / Heatrecovery<br>Adding msgid 113/114 unsuccessful burnerstart / flame too low<br>Added
55+
smartpower configruation detection<br>Added 2.3 spec status bits for (summer/winter time, dhw blocking, service indicator, electric production)<br>Adding PS=1 detection (WebUI notification)<br>Fix: restore settings issue|
5456
| 0.8.3 | New feature: Unique ID is configurable (thanks to @RobR)<br>New feature: GPIO pins follow status bits (master/slave) (thanks to @sjorsjuhmaniac)<br>Improved: Detecting online status of thermostat and boiler<br>Improved: MQTT Debug error logging<br>Fixed bug: reconnect MQTT timer and changed wait for reconnect to 42 seconds<br>Added: Rest API command now uses queues for sending commands<br>Fixed bug: msgid 32/33 type switch around<br>Changed: Solar Storage and Collector now proper names (breaking change)|
5557
| 0.8.2 | Added: Command Queue to MQTT command topic<br>Bugfix: Values not updating in WebUI fixed<br>Added: verbose debug modes<br> Added check for littlefs githash<br>Added: Interval setting for sensor readout<br>Adding: Send OTGW commands on boot<br>Bugfix: Hostname now actually changes if needed.|
5658
| 0.8.1 | Improved ot msg processing<br>MQTT: added `otgw-firmware/version`, `otgw-firmware/reboot_count`, `otgw-firmware/version` and `otgw-firmware/uptime` (seconds)<br>Bugfix: typoo in topic name `master_low_off_pomp_control_function` -> `master_low_off_pump_control_function`<br>Bugfix: Home Assistant thermostat operation mode (flame icon) template<br>Feature: Add support for Dallas temperature sensors, defaults GPIO10, pushes data to `otgw-firmware/sensors/<Dallas-sensor-ID>` |

data/mqttha.cfg

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,6 @@
144144
%homeassistant%/sensor/%node_id%/solar_storage_mode_status/config , {"avty_t": "%mqtt_pub_topic%", "dev": {"identifiers": "%node_id%", "manufacturer": "Schelte Bron", "model": "otgw-nodo", "name": "OpenTherm Gateway (%hostname%)", "sw_version": "%version%"}, "uniq_id": "%node_id%-solar_storage_mode_status", "name": "%hostname%_solar_storage_mode_status", "stat_t": "%mqtt_pub_topic%/solar_storage_mode_status", "unit_of_measurement": "", "value_template": "{{ value }}" }
145145
%homeassistant%/sensor/%node_id%/solar_storage_slave_status/config , {"avty_t": "%mqtt_pub_topic%", "dev": {"identifiers": "%node_id%", "manufacturer": "Schelte Bron", "model": "otgw-nodo", "name": "OpenTherm Gateway (%hostname%)", "sw_version": "%version%"}, "uniq_id": "%node_id%-solar_storage_slave_status", "name": "%hostname%_solar_storage_slave_status", "stat_t": "%mqtt_pub_topic%/solar_storage_slave_status", "unit_of_measurement": "", "value_template": "{{ value }}" }
146146
// split
147+
%homeassistant%/sensor/%node_id%/FanSpeed/config , {"avty_t": "%mqtt_pub_topic%", "dev": {"identifiers": "%node_id%", "manufacturer": "Schelte Bron", "model": "otgw-nodo", "name": "OpenTherm Gateway (%hostname%)", "sw_version": "%version%"}, "uniq_id": "%node_id%-FanSpeed", "name": "%hostname%_FanSpeed", "stat_t": "%mqtt_pub_topic%/FanSpeed", "unit_of_measurement": "rpm", "value_template": "{{ value }}" }
148+
%homeassistant%/sensor/%node_id%/ElectricalCurrentBurnerFlame/config , {"avty_t": "%mqtt_pub_topic%", "dev": {"identifiers": "%node_id%", "manufacturer": "Schelte Bron", "model": "otgw-nodo", "name": "OpenTherm Gateway (%hostname%)", "sw_version": "%version%"}, "uniq_id": "%node_id%-ElectricalCurrentBurnerFlame", "name": "%hostname%_ElectricalCurrentBurnerFlame", "stat_t": "%mqtt_pub_topic%/ElectricalCurrentBurnerFlame", "unit_of_measurement": "uA", "value_template": "{{ value }}" }
149+
// split

version.h

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
//The version number conforms to semver.org format
22
#define _VERSION_MAJOR 0
33
#define _VERSION_MINOR 8
4-
#define _VERSION_PATCH 4
5-
#define _VERSION_BUILD 997
6-
#define _VERSION_GITHASH "f39b68a"
4+
#define _VERSION_PATCH 5
5+
#define _VERSION_BUILD 1026
6+
#define _VERSION_GITHASH "7bbf52f"
77
//#define _VERSION_PRERELEASE beta //uncomment to define prerelease labels: alpha - beta - rc
8-
#define _VERSION_DATE "02-05-2021"
9-
#define _VERSION_TIME "17:52:56"
10-
#define _SEMVER_CORE "0.8.4"
11-
#define _SEMVER_BUILD "0.8.4+997"
12-
#define _SEMVER_GITHASH "0.8.4+f39b68a"
13-
#define _SEMVER_FULL "0.8.4+f39b68a"
14-
#define _SEMVER_NOBUILD "0.8.4 (02-05-2021)"
15-
#define _VERSION "0.8.4+f39b68a (02-05-2021)"
8+
#define _VERSION_DATE "30-06-2021"
9+
#define _VERSION_TIME "21:49:43"
10+
#define _SEMVER_CORE "0.8.5"
11+
#define _SEMVER_BUILD "0.8.5+1026"
12+
#define _SEMVER_GITHASH "0.8.5+7bbf52f"
13+
#define _SEMVER_FULL "0.8.5+7bbf52f"
14+
#define _SEMVER_NOBUILD "0.8.5 (30-06-2021)"
15+
#define _VERSION "0.8.5+7bbf52f (30-06-2021)"
1616
//The version information is created automatically, more information here: https://github.com/rvdbreemen/autoinc-semver

0 commit comments

Comments
 (0)