Skip to content

Commit f15a0fe

Browse files
authored
Merge pull request #397 from IgorYbema/main
release v3.2.3
2 parents 34e9965 + 1137f37 commit f15a0fe

17 files changed

+165
-61
lines changed

HeishaMon/HeishaMon.ino

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
#define LWIP_INTERNAL
23

34
#include <ESP8266WiFi.h>
@@ -1013,6 +1014,9 @@ void timer_cb(int nr) {
10131014
case -1: {
10141015
LittleFS.begin();
10151016
LittleFS.format();
1017+
//create first boot file
1018+
File startupFile = LittleFS.open("/heishamon", "w");
1019+
startupFile.close();
10161020
WiFi.disconnect(true);
10171021
timerqueue_insert(1, 0, -2);
10181022
} break;
@@ -1142,11 +1146,13 @@ void send_panasonic_query() {
11421146
send_command(panasonicQuery, PANASONICQUERYSIZE);
11431147
panasonicQuery[3] = 0x10; //setting 4th back to 0x10 for normal data request next time
11441148
} else if (!extraDataBlockChecked) {
1145-
extraDataBlockChecked = true;
1146-
log_message(_F("Checking if connected heatpump has extra data"));
1147-
panasonicQuery[3] = 0x21;
1148-
send_command(panasonicQuery, PANASONICQUERYSIZE);
1149-
panasonicQuery[3] = 0x10;
1149+
if ((actData[0] == 0x71) && (actData[193] == 0) ) { //do we have data but 0 value in heat consumptiom power, then assume K or L series
1150+
extraDataBlockChecked = true;
1151+
log_message(_F("Checking if connected heatpump has extra data"));
1152+
panasonicQuery[3] = 0x21;
1153+
send_command(panasonicQuery, PANASONICQUERYSIZE);
1154+
panasonicQuery[3] = 0x10;
1155+
}
11501156
}
11511157
}
11521158

HeishaMon/HeishaOT.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ struct heishaOTDataStruct_t heishaOTDataStruct[] = {
3030
{ "flameState", TBOOL, { .b = false }, 1 }, //provides current flame state to thermostat
3131
{ "chState", TBOOL, { .b = false }, 1 }, //provides if boiler is in centrale heating state
3232
{ "dhwState", TBOOL, { .b = false }, 1 }, //provides if boiler is in dhw heating state
33+
{ "roomSetOverride", TFLOAT, { .f = 0 }, 1 }, //provides a room setpoint override ID9 (not implemented completly in heishamon)
3334
{ NULL, 0, 0, 0 }
3435
};
3536

@@ -225,7 +226,7 @@ void processOTRequest(unsigned long request, OpenThermResponseStatus status) {
225226
unsigned long data = ot.temperatureToData(getOTStructMember(_F("inletTemp"))->value.f);
226227
otResponse = ot.buildResponse(OpenThermMessageType::READ_ACK, OpenThermMessageID::Tret, data);
227228
} else {
228-
otResponse = ot.buildResponse(OpenThermMessageType::DATA_INVALID, OpenThermMessageID::Tboiler, request & 0xffff);
229+
otResponse = ot.buildResponse(OpenThermMessageType::DATA_INVALID, OpenThermMessageID::Tret, request & 0xffff);
229230
}
230231
} break;
231232
case OpenThermMessageID::Tdhw: {
@@ -234,7 +235,7 @@ void processOTRequest(unsigned long request, OpenThermResponseStatus status) {
234235
unsigned long data = ot.temperatureToData(getOTStructMember(_F("dhwTemp"))->value.f);
235236
otResponse = ot.buildResponse(OpenThermMessageType::READ_ACK, OpenThermMessageID::Tdhw, data);
236237
} else {
237-
otResponse = ot.buildResponse(OpenThermMessageType::DATA_INVALID, OpenThermMessageID::Tboiler, request & 0xffff);
238+
otResponse = ot.buildResponse(OpenThermMessageType::DATA_INVALID, OpenThermMessageID::Tdhw, request & 0xffff);
238239
}
239240
} break;
240241
case OpenThermMessageID::Toutside: {
@@ -244,9 +245,21 @@ void processOTRequest(unsigned long request, OpenThermResponseStatus status) {
244245
otResponse = ot.buildResponse(OpenThermMessageType::READ_ACK, OpenThermMessageID::Toutside, data);
245246

246247
} else {
247-
otResponse = ot.buildResponse(OpenThermMessageType::DATA_INVALID, OpenThermMessageID::Tboiler, request & 0xffff);
248+
otResponse = ot.buildResponse(OpenThermMessageType::DATA_INVALID, OpenThermMessageID::Toutside, request & 0xffff);
249+
}
250+
} break;
251+
case OpenThermMessageID::TrOverride: {
252+
log_message(_F("OpenTherm: Received read room set override temp"));
253+
if (getOTStructMember(_F("roomSetOverride"))->value.f > -99) {
254+
unsigned long data = ot.temperatureToData(getOTStructMember(_F("roomSetOverride"))->value.f);
255+
otResponse = ot.buildResponse(OpenThermMessageType::READ_ACK, OpenThermMessageID::TrOverride, data);
256+
257+
} else {
258+
otResponse = ot.buildResponse(OpenThermMessageType::DATA_INVALID, OpenThermMessageID::TrOverride, request & 0xffff);
248259
}
249260
} break;
261+
262+
250263
/*
251264
case OpenThermMessageID::ASFflags: {
252265
log_message(_F("OpenTherm: Received read ASF flags"));

HeishaMon/decode.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -313,20 +313,15 @@ void decode_heatpump_data_extra(char* data, char* actDataExtra, PubSubClient &mq
313313
for (unsigned int Topic_Number = 0 ; Topic_Number < NUMBER_OF_TOPICS_EXTRA ; Topic_Number++) {
314314
String Topic_Value;
315315
Topic_Value = getDataValueExtra(data, Topic_Number);
316-
{
317-
char log_msg[256];
318-
sprintf_P(log_msg, PSTR("testing XTOP%d %s: %s"), Topic_Number, xtopics[Topic_Number], Topic_Value.c_str());
319-
log_message(log_msg);
320-
}
321-
316+
322317
if ((updatenow) || ( getDataValueExtra(actDataExtra, Topic_Number) != Topic_Value )) {
323318
char log_msg[256];
324319
char mqtt_topic[256];
325320
sprintf_P(log_msg, PSTR("received XTOP%d %s: %s"), Topic_Number, xtopics[Topic_Number], Topic_Value.c_str());
326321
log_message(log_msg);
327322
sprintf_P(mqtt_topic, PSTR("%s/%s/%s"), mqtt_topic_base, mqtt_topic_xvalues, xtopics[Topic_Number]);
328323
mqtt_client.publish(mqtt_topic, Topic_Value.c_str(), MQTT_RETAIN_VALUES);
329-
rules_event_cb(_F("^"),xtopics[Topic_Number]);
324+
rules_event_cb(_F("@"), xtopics[Topic_Number]);
330325
}
331326
}
332327
}

HeishaMon/decode.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ void resetlastalldatatime();
99

1010
String getDataValue(char* data, unsigned int Topic_Number);
1111
String getDataValueExtra(char* data, unsigned int Topic_Number);
12+
String getOptDataValue(char* data, unsigned int Topic_Number);
1213
void decode_heatpump_data(char* data, char* actData, PubSubClient &mqtt_client, void (*log_message)(char*), char* mqtt_topic_base, unsigned int updateAllTime);
1314
void decode_heatpump_data_extra(char* data, char* actDataExtra, PubSubClient &mqtt_client, void (*log_message)(char*), char* mqtt_topic_base, unsigned int updateAllTime);
1415
void decode_optional_heatpump_data(char* data, char* actOptDat, PubSubClient &mqtt_client, void (*log_message)(char*), char* mqtt_topic_base, unsigned int updateAllTime);
@@ -136,12 +137,12 @@ static const char optTopics[][20] PROGMEM = {
136137
};
137138

138139
static const char xtopics[][MAX_TOPIC_LEN] PROGMEM = {
139-
"Heat_Power_Consumption", //XTOP0
140-
"Cool_Power_Consumption", //XTOP1
141-
"DHW_Power_Consumption", //XTOP2
142-
"Heat_Power_Production", //XTOP3
143-
"Cool_Power_Production", //XTOP4
144-
"DHW_Power_Production", //XTOP5
140+
"Heat_Power_Consumption_Extra", //XTOP0
141+
"Cool_Power_Consumption_Extra", //XTOP1
142+
"DHW_Power_Consumption_Extra", //XTOP2
143+
"Heat_Power_Production_Extra", //XTOP3
144+
"Cool_Power_Production_Extra", //XTOP4
145+
"DHW_Power_Production_Extra", //XTOP5
145146
};
146147

147148
static const byte xtopicBytes[] PROGMEM = { //can store the index as byte (8-bit unsigned humber) as there aren't more then 255 bytes (actually only 203 bytes) to decode

HeishaMon/rules.cpp

Lines changed: 111 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,15 @@
2727
#include "commands.h"
2828

2929
#define MAXCOMMANDSINBUFFER 10
30+
#define OPTDATASIZE 20
3031

3132
bool send_command(byte* command, int length);
3233

3334
extern int dallasDevicecount;
3435
extern dallasDataStruct *actDallasData;
3536
extern settingsStruct heishamonSettings;
3637
extern char actData[DATASIZE];
38+
extern char actOptData[OPTDATASIZE];
3739
extern char actDataExtra[DATASIZE];
3840
extern String openTherm[2];
3941
static uint8_t parsing = 0;
@@ -173,7 +175,6 @@ static int is_variable(char *text, unsigned int *pos, unsigned int size) {
173175
break;
174176
}
175177
}
176-
177178
if(match == 0) {
178179
int nrtopics = sizeof(topics)/sizeof(topics[0]);
179180
for(x=0;x<nrtopics;x++) {
@@ -187,6 +188,32 @@ static int is_variable(char *text, unsigned int *pos, unsigned int size) {
187188
}
188189
}
189190
}
191+
if(match == 0) {
192+
int nrtopics = sizeof(optTopics)/sizeof(optTopics[0]);
193+
for(x=0;x<nrtopics;x++) {
194+
char cpy[MAX_TOPIC_LEN];
195+
memcpy_P(&cpy, optTopics[x], MAX_TOPIC_LEN);
196+
size_t len = strlen(cpy);
197+
if(size-1 == len && strnicmp(&text[(*pos)+1], cpy, len) == 0) {
198+
i = len+1;
199+
match = 1;
200+
break;
201+
}
202+
}
203+
}
204+
if(match == 0) {
205+
int nrtopics = sizeof(xtopics)/sizeof(xtopics[0]);
206+
for(x=0;x<nrtopics;x++) {
207+
char cpy[MAX_TOPIC_LEN];
208+
memcpy_P(&cpy, xtopics[x], MAX_TOPIC_LEN);
209+
size_t len = strlen(cpy);
210+
if(size-1 == len && strnicmp(&text[(*pos)+1], cpy, len) == 0) {
211+
i = len+1;
212+
match = 1;
213+
break;
214+
}
215+
}
216+
}
190217
if(match == 0) {
191218
return -1;
192219
}
@@ -227,27 +254,56 @@ static int is_event(char *text, unsigned int *pos, unsigned int size) {
227254
}
228255
}
229256

230-
int nroptcommands = sizeof(optionalCommands)/sizeof(optionalCommands[0]);
231-
for(x=0;x<nroptcommands;x++) {
232-
optCmdStruct cmd;
233-
memcpy_P(&cmd, &optionalCommands[x], sizeof(cmd));
234-
size_t len = strlen(cmd.name);
235-
if(size-1 == len && strnicmp(&text[(*pos)+1], cmd.name, len) == 0) {
236-
i = len+1;
237-
match = 1;
238-
break;
257+
if(match == 0) {
258+
int nroptcommands = sizeof(optionalCommands)/sizeof(optionalCommands[0]);
259+
for(x=0;x<nroptcommands;x++) {
260+
optCmdStruct cmd;
261+
memcpy_P(&cmd, &optionalCommands[x], sizeof(cmd));
262+
size_t len = strlen(cmd.name);
263+
if(size-1 == len && strnicmp(&text[(*pos)+1], cmd.name, len) == 0) {
264+
i = len+1;
265+
match = 1;
266+
break;
267+
}
239268
}
240269
}
241-
242-
int nrtopics = sizeof(topics)/sizeof(topics[0]);
243-
for(x=0;x<nrtopics;x++) {
244-
size_t len = strlen_P(topics[x]);
245-
char cpy[len];
246-
memcpy_P(&cpy, &topics[x], len);
247-
if(size-1 == len && strnicmp(&text[(*pos)+1], cpy, len) == 0) {
248-
i = len+1;
249-
match = 1;
250-
break;
270+
if(match == 0) {
271+
int nrtopics = sizeof(topics)/sizeof(topics[0]);
272+
for(x=0;x<nrtopics;x++) {
273+
size_t len = strlen_P(topics[x]);
274+
char cpy[len];
275+
memcpy_P(&cpy, &topics[x], len);
276+
if(size-1 == len && strnicmp(&text[(*pos)+1], cpy, len) == 0) {
277+
i = len+1;
278+
match = 1;
279+
break;
280+
}
281+
}
282+
}
283+
if(match == 0) {
284+
int nrtopics = sizeof(optTopics)/sizeof(optTopics[0]);
285+
for(x=0;x<nrtopics;x++) {
286+
size_t len = strlen_P(optTopics[x]);
287+
char cpy[len];
288+
memcpy_P(&cpy, &optTopics[x], len);
289+
if(size-1 == len && strnicmp(&text[(*pos)+1], cpy, len) == 0) {
290+
i = len+1;
291+
match = 1;
292+
break;
293+
}
294+
}
295+
}
296+
if(match == 0) {
297+
int nrtopics = sizeof(xtopics)/sizeof(xtopics[0]);
298+
for(x=0;x<nrtopics;x++) {
299+
size_t len = strlen_P(xtopics[x]);
300+
char cpy[len];
301+
memcpy_P(&cpy, &xtopics[x], len);
302+
if(size-1 == len && strnicmp(&text[(*pos)+1], cpy, len) == 0) {
303+
i = len+1;
304+
match = 1;
305+
break;
306+
}
251307
}
252308
}
253309
if(match == 0) {
@@ -548,11 +604,42 @@ static unsigned char *vm_value_get(struct rules_t *obj, uint16_t token) {
548604
}
549605
}
550606
}
551-
}
552-
if(node->token[0] == '&') {
553-
for(i=0;i<NUMBER_OF_TOPICS_EXTRA;i++) {
607+
for(i=0;i<NUMBER_OF_OPT_TOPICS;i++) {
554608
char cpy[MAX_TOPIC_LEN];
555609
memcpy_P(&cpy, topics[i], MAX_TOPIC_LEN);
610+
if(stricmp(cpy, (char *)&node->token[1]) == 0) {
611+
String dataValue = actOptData[0] == '\0' ? "" : getOptDataValue(actOptData, i);
612+
char *str = (char *)dataValue.c_str();
613+
if(strlen(str) == 0) {
614+
memset(&vnull, 0, sizeof(struct vm_vnull_t));
615+
vnull.type = VNULL;
616+
vnull.ret = token;
617+
618+
return (unsigned char *)&vnull;
619+
} else {
620+
float var = atof(str);
621+
float nr = 0;
622+
623+
// mosquitto_publish
624+
if(modff(var, &nr) == 0) {
625+
memset(&vinteger, 0, sizeof(struct vm_vinteger_t));
626+
vinteger.type = VINTEGER;
627+
vinteger.value = (int)var;
628+
629+
return (unsigned char *)&vinteger;
630+
} else {
631+
memset(&vfloat, 0, sizeof(struct vm_vfloat_t));
632+
vfloat.type = VFLOAT;
633+
vfloat.value = var;
634+
635+
return (unsigned char *)&vfloat;
636+
}
637+
}
638+
}
639+
}
640+
for(i=0;i<NUMBER_OF_TOPICS_EXTRA;i++) {
641+
char cpy[MAX_TOPIC_LEN];
642+
memcpy_P(&cpy, xtopics[i], MAX_TOPIC_LEN);
556643
if(stricmp(cpy, (char *)&node->token[1]) == 0) {
557644
String dataValue = actDataExtra[0] == '\0' ? "" : getDataValueExtra(actDataExtra, i);
558645
char *str = (char *)dataValue.c_str();
@@ -583,7 +670,7 @@ static unsigned char *vm_value_get(struct rules_t *obj, uint16_t token) {
583670
}
584671
}
585672
}
586-
}
673+
}
587674
if(node->token[0] == '%') {
588675
if(stricmp((char *)&node->token[1], "hour") == 0) {
589676
time_t now = time(NULL);

HeishaMon/version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
static const char* heishamon_version = "3.2";
1+
static const char* heishamon_version = "3.2.3";

HeishaMon/webfunctions.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,7 +1159,7 @@ int handleJsonOutput(struct webserver_t *client, char* actData, char* actDataExt
11591159
client->content--; // The webserver also increases by 1
11601160
} else if ((client->content - NUMBER_OF_TOPICS - 1) < extraTopics) {
11611161
if (client->content == NUMBER_OF_TOPICS + 1) {
1162-
webserver_send_content_P(client, PSTR("],\"heatpump extra\":["), 20);
1162+
webserver_send_content_P(client, PSTR("],\"heatpump extra\":["), 20);
11631163
}
11641164
for (uint8_t topic = (client->content - NUMBER_OF_TOPICS - 1); topic < extraTopics && topic < (client->content - NUMBER_OF_TOPICS + 4) ; topic++) {
11651165

@@ -1260,11 +1260,11 @@ int showRules(struct webserver_t *client) {
12601260

12611261
if (len1 > 0) {
12621262
webserver_send_content(client, content, len1);
1263-
if (len1 < BUFFER_SIZE) {
1263+
if (len1 < BUFFER_SIZE || client->content * BUFFER_SIZE == len) {
12641264
if (f) {
12651265
if (*f) {
12661266
f->close();
1267-
}
1267+
}
12681268
delete f;
12691269
}
12701270
client->userdata = NULL;

HeishaMon/webfunctions.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ struct settingsStruct {
4949
bool logMqtt = false; //log to mqtt from start
5050
bool logHexdump = false; //log hexdump from start
5151
bool logSerial1 = true; //log to serial1 (gpio2) from start
52-
bool opentherm = true; //opentherm enable flag, current default true for opentherm build
52+
bool opentherm = false; //opentherm enable flag
5353

5454
s0SettingsStruct s0Settings[NUM_S0_COUNTERS];
5555
gpioSettingsStruct gpioSettings;

MQTT-Topics.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ TOP11 | main/Operations_Hours | Heatpump operating time (Hour)
3131
TOP12 | main/Operations_Counter | Heatpump starts (counter)
3232
TOP13 | main/Main_Schedule_State | Main thermostat schedule state (inactive - active)
3333
TOP14 | main/Outside_Temp | Outside ambient temperature (°C)
34-
TOP15 | main/Heat_Energy_Production | Thermal heat power production (Watt)
35-
TOP16 | main/Heat_Energy_Consumption | Elektrical heat power consumption at heat mode (Watt)
34+
TOP15 | main/Heat_Power_Production | Thermal heat power production (Watt)
35+
TOP16 | main/Heat_Power_Consumption | Elektrical heat power consumption at heat mode (Watt)
3636
TOP17 | main/Powerful_Mode_Time | Powerful state in minutes (0, 1, 2 or 3 x 30min)
3737
TOP18 | main/Quiet_Mode_Level | Quiet mode level (0, 1, 2, 3)
3838
TOP19 | main/Holiday_Mode_State | Holiday mode (0=off, 1=scheduled, 2=active)
@@ -54,10 +54,10 @@ TOP34 | main/Z2_Heat_Request_Temp | Zone 2 Heat Requested shift temp (-5 to 5) o
5454
TOP35 | main/Z2_Cool_Request_Temp | Zone 2 Cool Requested shift temp (-5 to 5) or direct cool temp (5 to 20)
5555
TOP36 | main/Z1_Water_Temp | Zone 1 Water outlet temperature (°C)
5656
TOP37 | main/Z2_Water_Temp | Zone 2 Water outlet temperature (°C)
57-
TOP38 | main/Cool_Energy_Production | Thermal cooling power production (Watt)
58-
TOP39 | main/Cool_Energy_Consumption | Elektrical cooling power consumption (Watt)
59-
TOP40 | main/DHW_Energy_Production | Thermal DHW power production (Watt)
60-
TOP41 | main/DHW_Energy_Consumption | Elektrical DHW power consumption (Watt)
57+
TOP38 | main/Cool_Power_Production | Thermal cooling power production (Watt)
58+
TOP39 | main/Cool_Power_Consumption | Elektrical cooling power consumption (Watt)
59+
TOP40 | main/DHW_Power_Production | Thermal DHW power production (Watt)
60+
TOP41 | main/DHW_Power_Consumption | Elektrical DHW power consumption (Watt)
6161
TOP42 | main/Z1_Water_Target_Temp | Zone 1 water target temperature (°C)
6262
TOP43 | main/Z2_Water_Target_Temp | Zone 2 water target temperature (°C)
6363
TOP44 | main/Error | Last active Error from Heat Pump
@@ -191,7 +191,9 @@ SET27 | SetBufferDelta | Set buffer tank delta | 0 - 10
191191
SET28 | SetBuffer | Set buffer installed | 0=not installed, 1=installed
192192
SET29 | SetHeatingOffOutdoorTemp | Set Outdoor Temperature to stop heating | 5 to 35
193193

194-
*If you operate your heatpump with direct temperature setup: topics ending xxxRequestTemperature will set the absolute target temperature*
194+
*If you operate your heatpump in water mode with direct temperature setup: topics ending xxxRequestTemperature will set the absolute target temperature.*
195+
196+
*But if you operature your heatpump in internal/external thermostat or thermistor mode with direct temperature, you can not use these SET15 and other topics to set the direct temperature. The direct temperature in that modes is stored in the high target compenstation curve value. So to change the requested direct temperature in those modes, use the SET16 to set this value. Maybe this weird behaviour is different for newer heatpump types. So if your heatpump works different, please feel free to updates this note in github.*
195197

196198
*To send Heating/Cooling Curves on topic SET16 you need to send a flattened JSON document. For example:*
197199

0 commit comments

Comments
 (0)