fixes for #263, MQTT flooding,

This commit is contained in:
Paul
2019-12-20 14:53:12 +01:00
parent a0e265c119
commit 33d930b7cd
5 changed files with 120 additions and 149 deletions

View File

@@ -110,5 +110,5 @@ board = d1_mini
build_type = release
build_flags = ${common.build_flags} ${common.custom_flags}
extra_scripts =
pre:scripts/pre_script.py
;pre:scripts/pre_script.py
scripts/main_script.py

View File

@@ -33,9 +33,8 @@ DS18 ds18;
#define APP_URL_API "https://api.github.com/repos/proddy/EMS-ESP"
// timers, all values are in seconds
#define DEFAULT_PUBLISHTIME 0
#define DEFAULT_PUBLISHTIME 10 // 10 seconds
Ticker publishValuesTimer;
Ticker publishSensorValuesTimer;
bool _need_first_publish = true; // this ensures on boot we always send out MQTT messages
@@ -824,9 +823,39 @@ void publishEMSValues(bool force) {
}
}
// call PublishValues without forcing
// Publish shower data
bool do_publishShowerData() {
StaticJsonDocument<200> doc;
JsonObject rootShower = doc.to<JsonObject>();
rootShower[TOPIC_SHOWER_TIMER] = EMSESP_Settings.shower_timer ? "1" : "0";
rootShower[TOPIC_SHOWER_ALERT] = EMSESP_Settings.shower_alert ? "1" : "0";
// only publish shower duration if there is a value
char s[50] = {0};
if (EMSESP_Shower.duration > SHOWER_MIN_DURATION) {
char buffer[16] = {0};
strlcpy(s, itoa((uint8_t)((EMSESP_Shower.duration / (1000 * 60)) % 60), buffer, 10), sizeof(s));
strlcat(s, " minutes and ", sizeof(s));
strlcat(s, itoa((uint8_t)((EMSESP_Shower.duration / 1000) % 60), buffer, 10), sizeof(s));
strlcat(s, " seconds", sizeof(s));
rootShower[TOPIC_SHOWER_DURATION] = s;
}
char data[300] = {0};
serializeJson(doc, data, sizeof(data));
myDebugLog("Publishing shower data via MQTT");
// Publish MQTT forcing retain to be off
return (myESP.mqttPublish(TOPIC_SHOWER_DATA, data, false));
}
// call PublishValues with forcing forcing
void do_publishValues() {
publishEMSValues(true); // force publish
myDebugLog("Starting scheduled MQTT publish...");
publishEMSValues(false);
publishSensorValues();
do_publishShowerData();
}
// callback to light up the LED, called via Ticker every second
@@ -851,6 +880,7 @@ void do_systemCheck() {
// force calls to get data from EMS for the types that aren't sent as broadcasts
// only if we have a EMS connection
// which will cause the values to get published
void do_regularUpdates() {
if (ems_getBusConnected() && !ems_getTxDisabled()) {
myDebugLog("Fetching data from EMS devices");
@@ -936,33 +966,6 @@ bool LoadSaveCallback(MYESP_FSACTION_t action, JsonObject settings) {
return false;
}
// Publish shower data
bool do_publishShowerData() {
StaticJsonDocument<200> doc;
JsonObject rootShower = doc.to<JsonObject>();
rootShower[TOPIC_SHOWER_TIMER] = EMSESP_Settings.shower_timer ? "1" : "0";
rootShower[TOPIC_SHOWER_ALERT] = EMSESP_Settings.shower_alert ? "1" : "0";
// only publish shower duration if there is a value
char s[50] = {0};
if (EMSESP_Shower.duration > SHOWER_MIN_DURATION) {
char buffer[16] = {0};
strlcpy(s, itoa((uint8_t)((EMSESP_Shower.duration / (1000 * 60)) % 60), buffer, 10), sizeof(s));
strlcat(s, " minutes and ", sizeof(s));
strlcat(s, itoa((uint8_t)((EMSESP_Shower.duration / 1000) % 60), buffer, 10), sizeof(s));
strlcat(s, " seconds", sizeof(s));
rootShower[TOPIC_SHOWER_DURATION] = s;
}
char data[300] = {0};
serializeJson(doc, data, sizeof(data));
myDebugLog("Publishing shower data via MQTT");
// Publish MQTT forcing retain to be off
return (myESP.mqttPublish(TOPIC_SHOWER_DATA, data, false));
}
// callback for custom settings when showing Stored Settings with the 'set' command
// wc is number of arguments after the 'set' command
// returns true if the setting was recognized and changed and should be saved back to SPIFFs
@@ -1087,7 +1090,7 @@ bool SetListCallback(MYESP_FSACTION_t action, uint8_t wc, const char * setting,
if (EMSESP_Settings.publish_time) {
myDebug_P(PSTR(" publish_time=%d"), EMSESP_Settings.publish_time);
} else {
myDebug_P(PSTR(" publish_time=0 (always publish when data received)"), EMSESP_Settings.publish_time);
myDebug_P(PSTR(" publish_time=0 (always publish on data received)"), EMSESP_Settings.publish_time);
}
}
@@ -1154,8 +1157,6 @@ void TelnetCommandCallback(uint8_t wc, const char * commandLine) {
if (strcmp(first_cmd, "publish") == 0) {
do_publishValues();
publishSensorValues();
do_publishShowerData();
ok = true;
}
@@ -1886,16 +1887,14 @@ void setup() {
}
}
// enable regular checks
// enable regular checks to fetch data and publish
if (!EMSESP_Settings.listen_mode) {
regularUpdatesTimer.attach(REGULARUPDATES_TIME, do_regularUpdates); // regular reads from the EMS
}
// set timers for MQTT publish
// only if publish_time is not 0 (automatic mode)
// set timers for MQTT publish, only if publish_time is not 0 (automatic mode)
if (EMSESP_Settings.publish_time) {
publishValuesTimer.attach(EMSESP_Settings.publish_time, do_publishValues); // post MQTT EMS values
publishSensorValuesTimer.attach(EMSESP_Settings.publish_time, publishSensorValues); // post MQTT dallas sensor values
publishValuesTimer.attach(EMSESP_Settings.publish_time, do_publishValues); // post MQTT EMS values
}
// set pin for LED
@@ -1905,10 +1904,11 @@ void setup() {
ledcheckTimer.attach_ms(LEDCHECK_TIME, do_ledcheck); // blink heartbeat LED
}
// system check
systemCheckTimer.attach(SYSTEMCHECK_TIME, do_systemCheck); // check if EMS is reachable
// check for Dallas sensors
EMSESP_Settings.dallas_sensors = ds18.setup(EMSESP_Settings.dallas_gpio, EMSESP_Settings.dallas_parasite); // returns #sensors
systemCheckTimer.attach(SYSTEMCHECK_TIME, do_systemCheck); // check if EMS is reachable
}
//
@@ -1918,7 +1918,6 @@ void loop() {
myESP.loop(); // handle telnet, mqtt, wifi etc
// check Dallas sensors, using same schedule as publish_time (default 2 mins in DS18_READ_INTERVAL)
// these values are published to MQTT separately via the timer publishSensorValuesTimer
if (EMSESP_Settings.dallas_sensors) {
ds18.loop();
}

View File

@@ -325,13 +325,21 @@ uint8_t _crcCalculator(uint8_t * data, uint8_t len) {
return crc;
}
// validate we have data at the offset (index) requested
// returns -1 if out of bounds
int8_t _getDataPosition(_EMS_RxTelegram * EMS_RxTelegram, uint8_t index) {
int8_t pos = index - EMS_RxTelegram->offset; // get adjusted index position based on offset
return (pos >= EMS_RxTelegram->data_length) ? -1 : pos; // return -1 if out of bounds
}
// unsigned short
void _setValue(_EMS_RxTelegram * EMS_RxTelegram, uint16_t * param_op, uint8_t index) {
if (index >= EMS_RxTelegram->data_length) {
int8_t pos = _getDataPosition(EMS_RxTelegram, index);
if (pos < 0) {
return;
}
uint16_t value = (EMS_RxTelegram->data[index] << 8) + EMS_RxTelegram->data[index + 1];
uint16_t value = (EMS_RxTelegram->data[pos] << 8) + EMS_RxTelegram->data[pos + 1];
// check for undefined/unset values, 0x8000
if (value == EMS_VALUE_USHORT_NOTSET) {
@@ -343,14 +351,15 @@ void _setValue(_EMS_RxTelegram * EMS_RxTelegram, uint16_t * param_op, uint8_t in
// signed short
void _setValue(_EMS_RxTelegram * EMS_RxTelegram, int16_t * param_op, uint8_t index) {
if (index >= EMS_RxTelegram->data_length) {
int8_t pos = _getDataPosition(EMS_RxTelegram, index);
if (pos < 0) {
return;
}
int16_t value = (EMS_RxTelegram->data[index] << 8) + EMS_RxTelegram->data[index + 1];
int16_t value = (EMS_RxTelegram->data[pos] << 8) + EMS_RxTelegram->data[pos + 1];
// check for undefined/unset values, 0x8000
if ((value == EMS_VALUE_SHORT_NOTSET) || (EMS_RxTelegram->data[index] == 0x7D)) {
if ((value == EMS_VALUE_SHORT_NOTSET) || (EMS_RxTelegram->data[pos] == 0x7D)) {
return;
}
@@ -359,38 +368,42 @@ void _setValue(_EMS_RxTelegram * EMS_RxTelegram, int16_t * param_op, uint8_t ind
// Byte
void _setValue(_EMS_RxTelegram * EMS_RxTelegram, uint8_t * param_op, uint8_t index) {
if (index >= EMS_RxTelegram->data_length) {
int8_t pos = _getDataPosition(EMS_RxTelegram, index);
if (pos < 0) {
return;
}
*param_op = (uint8_t)EMS_RxTelegram->data[index];
*param_op = (uint8_t)EMS_RxTelegram->data[pos];
}
// convert signed short to single 8 byte, for setpoint thermostat temperatures that don't store their temps in 2 bytes
void _setValue8(_EMS_RxTelegram * EMS_RxTelegram, int16_t * param_op, uint8_t index) {
if (index >= EMS_RxTelegram->data_length) {
int8_t pos = _getDataPosition(EMS_RxTelegram, index);
if (pos < 0) {
return;
}
*param_op = EMS_RxTelegram->data[index];
*param_op = EMS_RxTelegram->data[pos];
}
// Long
void _setValue(_EMS_RxTelegram * EMS_RxTelegram, uint32_t * param_op, uint8_t index) {
if (index >= EMS_RxTelegram->data_length) {
int8_t pos = _getDataPosition(EMS_RxTelegram, index);
if (pos < 0) {
return;
}
*param_op = (uint32_t)((EMS_RxTelegram->data[index] << 16) + (EMS_RxTelegram->data[index + 1] << 8) + (EMS_RxTelegram->data[index + 2]));
*param_op = (uint32_t)((EMS_RxTelegram->data[pos] << 16) + (EMS_RxTelegram->data[pos + 1] << 8) + (EMS_RxTelegram->data[pos + 2]));
}
// bit from a byte
void _setValue(_EMS_RxTelegram * EMS_RxTelegram, uint8_t * param_op, uint8_t index, uint8_t bit) {
if (index >= EMS_RxTelegram->data_length) {
int8_t pos = _getDataPosition(EMS_RxTelegram, index);
if (pos < 0) {
return;
}
*param_op = (uint8_t)(((EMS_RxTelegram->data[index]) >> (bit)) & 0x01);
*param_op = (uint8_t)(((EMS_RxTelegram->data[pos]) >> (bit)) & 0x01);
}
void ems_setTxMode(uint8_t mode) {
@@ -1019,7 +1032,7 @@ void _process_UBAMonitorFast(_EMS_RxTelegram * EMS_RxTelegram) {
_setValue(EMS_RxTelegram, &EMS_Boiler.sysPress, 17); // is *10
// read the service code / installation status as appears on the display
if (EMS_RxTelegram->data_length > 18) {
if ((EMS_RxTelegram->data_length > 18) && (EMS_RxTelegram->offset == 0)) {
EMS_Boiler.serviceCodeChar[0] = char(EMS_RxTelegram->data[18]); // ascii character 1
EMS_Boiler.serviceCodeChar[1] = char(EMS_RxTelegram->data[19]); // ascii character 2
EMS_Boiler.serviceCodeChar[2] = '\0'; // null terminate string
@@ -1042,7 +1055,7 @@ void _process_UBAMonitorFast2(_EMS_RxTelegram * EMS_RxTelegram) {
_setValue(EMS_RxTelegram, &EMS_Boiler.flameCurr, 19);
// read the service code / installation status as appears on the display
if (EMS_RxTelegram->data_length > 4) {
if ((EMS_RxTelegram->data_length > 4) && (EMS_RxTelegram->offset == 0)) {
EMS_Boiler.serviceCodeChar[0] = char(EMS_RxTelegram->data[4]); // ascii character 1
EMS_Boiler.serviceCodeChar[1] = char(EMS_RxTelegram->data[5]); // ascii character 2
EMS_Boiler.serviceCodeChar[2] = '\0';
@@ -1222,36 +1235,20 @@ void _process_RCPLUSStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
}
EMS_Thermostat.hc[hc].active = true;
// handle single data values. data will always be at position data[0]
if (EMS_RxTelegram->data_length == 1) {
switch (EMS_RxTelegram->offset) {
case EMS_OFFSET_RCPLUSStatusMessage_curr: // setpoint target temp
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].curr_roomTemp, 0); // value is * 10
break;
case EMS_OFFSET_RCPLUSStatusMessage_setpoint: // current target temp
EMS_Thermostat.hc[hc].setpoint_roomTemp = EMS_RxTelegram->data[0]; // convert to single byte, value is * 2
break;
case EMS_OFFSET_RCPLUSStatusMessage_currsetpoint: // current setpoint temp, e.g. Thermostat -> all, telegram: 10 00 FF 06 01 A5 22
EMS_Thermostat.hc[hc].setpoint_roomTemp = EMS_RxTelegram->data[0]; // convert to single byte, value is * 2
break;
case EMS_OFFSET_RCPLUSStatusMessage_mode: // thermostat mode auto/manual
// manual : 10 00 FF 0A 01 A5 02
// auto : 10 00 FF 0A 01 A5 03
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].mode, 0,
0); // bit 1, mode (auto=1 or manual=0). Note this may be bit 2 - still need to validate
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].day_mode, 0, 1); // get day mode flag
// the whole telegram
// e.g. Thermostat -> all, telegram: 10 00 FF 00 01 A5 00 D7 21 00 00 00 00 30 01 84 01 01 03 01 84 01 F1 00 00 11 01 00 08 63 00
// 10 00 FF 00 01 A5 80 00 01 30 28 00 30 28 01 54 03 03 01 01 54 02 A8 00 00 11 01 03 FF FF 00
// or prtial, e.g. for modes:
// manual : 10 00 FF 0A 01 A5 02
// auto : 10 00 FF 0A 01 A5 03
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].curr_roomTemp, EMS_OFFSET_RCPLUSStatusMessage_curr); // value is * 10
_setValue8(EMS_RxTelegram, &EMS_Thermostat.hc[hc].setpoint_roomTemp, EMS_OFFSET_RCPLUSStatusMessage_setpoint); // convert to single byte, value is * 2
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].day_mode, EMS_OFFSET_RCPLUSStatusMessage_mode, 1);
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].mode, EMS_OFFSET_RCPLUSStatusMessage_mode, 0); // bit 1, mode (auto=1 or manual=0)
break;
}
} else if (EMS_RxTelegram->data_length > 20) {
// the whole telegram
// e.g. Thermostat -> all, telegram: 10 00 FF 00 01 A5 00 D7 21 00 00 00 00 30 01 84 01 01 03 01 84 01 F1 00 00 11 01 00 08 63 00
// 10 00 FF 00 01 A5 80 00 01 30 28 00 30 28 01 54 03 03 01 01 54 02 A8 00 00 11 01 03 FF FF 00
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].curr_roomTemp, EMS_OFFSET_RCPLUSStatusMessage_curr); // value is * 10
_setValue8(EMS_RxTelegram, &EMS_Thermostat.hc[hc].setpoint_roomTemp, EMS_OFFSET_RCPLUSStatusMessage_setpoint); // convert to single byte, value is * 2
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].day_mode, EMS_OFFSET_RCPLUSStatusMessage_mode, 1);
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].mode, EMS_OFFSET_RCPLUSStatusMessage_mode, 0); // bit 1, mode (auto=1 or manual=0)
}
// TODO figure out current setpoint temp at offset 6
// e.g. Thermostat -> all, telegram: 10 00 FF 06 01 A5 22
// EMS_Thermostat.hc[hc].setpoint_roomTemp = EMS_RxTelegram->data[EMS_OFFSET_RCPLUSStatusMessage_currsetpoint];
}
/**
@@ -1267,15 +1264,13 @@ void _process_RCPLUSStatusMode(_EMS_RxTelegram * EMS_RxTelegram) {
* for FW100: 90 00 FF 00 00 6F 03 02 00 D7 00 DA F3 34 00 C4
*/
void _process_JunkersStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
if (EMS_RxTelegram->offset == 0 && EMS_RxTelegram->data_length > 1) {
uint8_t hc = EMS_THERMOSTAT_DEFAULTHC - 1; // use HC1
EMS_Thermostat.hc[hc].active = true;
uint8_t hc = EMS_THERMOSTAT_DEFAULTHC - 1; // use HC1
EMS_Thermostat.hc[hc].active = true;
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].curr_roomTemp, EMS_OFFSET_JunkersStatusMessage_curr); // value is * 10
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].setpoint_roomTemp, EMS_OFFSET_JunkersStatusMessage_setpoint); // value is * 10
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].day_mode, EMS_OFFSET_JunkersStatusMessage_daymode); // 3 = day, 2 = night
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].mode, EMS_OFFSET_JunkersStatusMessage_mode); // 1 = manual, 2 = auto
}
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].curr_roomTemp, EMS_OFFSET_JunkersStatusMessage_curr); // value is * 10
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].setpoint_roomTemp, EMS_OFFSET_JunkersStatusMessage_setpoint); // value is * 10
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].day_mode, EMS_OFFSET_JunkersStatusMessage_daymode); // 3 = day, 2 = night
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].mode, EMS_OFFSET_JunkersStatusMessage_mode); // 1 = manual, 2 = auto
}
/**
@@ -1290,25 +1285,18 @@ void _process_RCPLUSSetMessage(_EMS_RxTelegram * EMS_RxTelegram) {
uint8_t hc = EMS_THERMOSTAT_DEFAULTHC - 1; // use HC1
EMS_Thermostat.hc[hc].active = true;
// check for one data value
// but ignore values of 0xFF, e.g. 10 00 FF 08 01 B9 FF
if ((EMS_RxTelegram->data_length == 1) && (EMS_RxTelegram->data[0] != 0xFF)) {
// check for setpoint temps, e.g. Thermostat -> all, type 0x01B9, telegram: 10 00 FF 08 01 B9 26
if ((EMS_RxTelegram->offset == EMS_OFFSET_RCPLUSSet_temp_setpoint) || (EMS_RxTelegram->offset == EMS_OFFSET_RCPLUSSet_manual_setpoint)) {
_setValue8(EMS_RxTelegram, &EMS_Thermostat.hc[hc].setpoint_roomTemp, 0); // single byte conversion, value is * 2
} else if (EMS_RxTelegram->offset == EMS_OFFSET_RCPLUSSet_mode) {
// check for mode, eg. 10 00 FF 08 01 B9 FF
EMS_Thermostat.hc[hc].mode = (EMS_RxTelegram->data[0] == 0xFF); // Auto = xFF, Manual = x00 (auto=1 or manual=0)
}
return; // quit
// ignore single values of 0xFF, e.g. 10 00 FF 08 01 B9 FF
if ((EMS_RxTelegram->data_length == 1) && (EMS_RxTelegram->data[0] == 0xFF)) {
return;
}
// check for long broadcasts
if (EMS_RxTelegram->offset == 0) {
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].mode, EMS_OFFSET_RCPLUSSet_mode);
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].daytemp, EMS_OFFSET_RCPLUSSet_temp_comfort2); // is * 2
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].nighttemp, EMS_OFFSET_RCPLUSSet_temp_eco); // is * 2
}
// check for setpoint temps, e.g. Thermostat -> all, type 0x01B9, telegram: 10 00 FF 08 01 B9 26
// NOTE when setting the room temp we pick from two values, hopefully one is correct!
_setValue8(EMS_RxTelegram, &EMS_Thermostat.hc[hc].setpoint_roomTemp, EMS_OFFSET_RCPLUSSet_temp_setpoint); // single byte conversion, value is * 2
_setValue8(EMS_RxTelegram, &EMS_Thermostat.hc[hc].setpoint_roomTemp, EMS_OFFSET_RCPLUSSet_manual_setpoint); // single byte conversion, value is * 2
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].mode, EMS_OFFSET_RCPLUSSet_mode); // Auto = xFF, Manual = x00 eg. 10 00 FF 08 01 B9 FF
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].daytemp, EMS_OFFSET_RCPLUSSet_temp_comfort2); // is * 2
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].nighttemp, EMS_OFFSET_RCPLUSSet_temp_eco); // is * 2
}
/**
@@ -1417,11 +1405,6 @@ void _process_SM10Monitor(_EMS_RxTelegram * EMS_RxTelegram) {
* 30 00 FF 00 02 62 01 A1 - for bottom temps
*/
void _process_SM100Monitor(_EMS_RxTelegram * EMS_RxTelegram) {
// only process the complete telegram, not partial
if (EMS_RxTelegram->offset) {
return;
}
_setValue(EMS_RxTelegram, &EMS_SolarModule.collectorTemp, 0); // is *10
_setValue(EMS_RxTelegram, &EMS_SolarModule.bottomTemp, 2); // is *10
}
@@ -1432,22 +1415,14 @@ void _process_SM100Monitor(_EMS_RxTelegram * EMS_RxTelegram) {
* 30 00 FF 09 02 64 1E = 30%
*/
void _process_SM100Status(_EMS_RxTelegram * EMS_RxTelegram) {
if (EMS_RxTelegram->offset == 0) {
_setValue(EMS_RxTelegram, &EMS_SolarModule.pumpModulation, 9); // check for complete telegram
} else if (EMS_RxTelegram->offset == 0x09) {
_setValue(EMS_RxTelegram, &EMS_SolarModule.pumpModulation, 0); // data at offset 09
}
_setValue(EMS_RxTelegram, &EMS_SolarModule.pumpModulation, 9); // check for complete telegram
}
/*
* SM100Status2 - type 0x026A EMS+ for pump on/off at offset 0x0A
*/
void _process_SM100Status2(_EMS_RxTelegram * EMS_RxTelegram) {
if (EMS_RxTelegram->offset == 0) {
_setValue(EMS_RxTelegram, &EMS_SolarModule.pump, 10, 2); // 03=off 04=on
} else if (EMS_RxTelegram->offset == 0x0A) {
_setValue(EMS_RxTelegram, &EMS_SolarModule.pump, 0, 2); // 03=off 04=on at offset 0A
}
_setValue(EMS_RxTelegram, &EMS_SolarModule.pump, 10, 2); // 03=off 04=on
}
/*
@@ -1479,18 +1454,11 @@ void _process_HPMonitor2(_EMS_RxTelegram * EMS_RxTelegram) {
* e.g. B0 00 FF 00 00 03 32 00 00 00 00 13 00 D6 00 00 00 FB D0 F0
*/
void _process_ISM1StatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
if (EMS_RxTelegram->offset == 0) {
_setValue(EMS_RxTelegram, &EMS_SolarModule.collectorTemp, 4); // Collector Temperature
_setValue(EMS_RxTelegram, &EMS_SolarModule.bottomTemp, 6); // Temperature Bottom of Solar Boiler
_setValue(EMS_RxTelegram, &EMS_SolarModule.EnergyLastHour, 2); // Solar Energy produced in last hour - is * 10 and handled in ems-esp.cpp
_setValue(EMS_RxTelegram, &EMS_SolarModule.pump, 8, 0); // Solar pump on (1) or off (0)
_setValue(EMS_RxTelegram, &EMS_SolarModule.pumpWorkMin, 10);
}
if (EMS_RxTelegram->offset == 4) {
// e.g. B0 00 FF 04 00 03 02 E5
_setValue(EMS_RxTelegram, &EMS_SolarModule.collectorTemp, 0); // Collector Temperature
}
_setValue(EMS_RxTelegram, &EMS_SolarModule.collectorTemp, 4); // Collector Temperature
_setValue(EMS_RxTelegram, &EMS_SolarModule.bottomTemp, 6); // Temperature Bottom of Solar Boiler
_setValue(EMS_RxTelegram, &EMS_SolarModule.EnergyLastHour, 2); // Solar Energy produced in last hour - is * 10 and handled in ems-esp.cpp
_setValue(EMS_RxTelegram, &EMS_SolarModule.pump, 8, 0); // Solar pump on (1) or off (0)
_setValue(EMS_RxTelegram, &EMS_SolarModule.pumpWorkMin, 10);
}
@@ -1498,11 +1466,12 @@ void _process_ISM1StatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
* Junkers ISM1 Solar Module - type 0x0001 EMS+ for setting values
*/
void _process_ISM1Set(_EMS_RxTelegram * EMS_RxTelegram) {
if (EMS_RxTelegram->offset == 6) {
// e.g. 90 30 FF 06 00 01 50 (CRC=2C)
// to implement: change max solar boiler temperature
EMS_SolarModule.setpoint_maxBottomTemp = EMS_RxTelegram->data[0];
}
// e.g. 90 30 FF 06 00 01 50
// only trigger if at offset 6
_setValue(EMS_RxTelegram, &EMS_SolarModule.setpoint_maxBottomTemp, 6);
// TODO: we may need to convert this to a single byte like
// EMS_SolarModule.setpoint_maxBottomTemp = EMS_RxTelegram->data[0];
}
/**
@@ -1523,7 +1492,7 @@ void _process_SetPoints(_EMS_RxTelegram * EMS_RxTelegram) {
myDebug_P(PSTR(" Boiler flow temp %s C, Warm Water power %d %"), s, ww_power);
*/
myDebug_P(PSTR(" Boiler flow temperature is %d C"), setpoint);
myDebug_P(PSTR("Boiler flow temperature is %d C"), setpoint);
}
}
}
@@ -2387,7 +2356,7 @@ void ems_setThermostatMode(uint8_t mode, uint8_t hc_num) {
*/
void ems_setWarmWaterTemp(uint8_t temperature) {
// check for invalid temp values
if ((temperature < 30) || (temperature > EMS_BOILER_TAPWATER_TEMPERATURE_MAX)) {
if ((temperature < EMS_BOILER_TAPWATER_TEMPERATURE_MIN) || (temperature > EMS_BOILER_TAPWATER_TEMPERATURE_MAX)) {
return;
}
@@ -2429,7 +2398,9 @@ void ems_setFlowTemp(uint8_t temperature) {
EMS_TxTelegram.length = EMS_MIN_TELEGRAM_LENGTH;
EMS_TxTelegram.dataValue = temperature; // int value to compare against
EMS_TxTelegram.type_validate = EMS_TYPE_UBASetPoints; // validate
// EMS_TxTelegram.type_validate = EMS_TYPE_UBASetPoints; // validate
EMS_TxTelegram.type_validate = EMS_ID_NONE; // don't validate after the write
EMS_TxTelegram.comparisonOffset = EMS_OFFSET_UBASetPoints_flowtemp;
EMS_TxTelegram.comparisonValue = temperature;
EMS_TxTelegram.comparisonPostRead = EMS_TYPE_UBASetPoints;

View File

@@ -66,8 +66,9 @@ typedef enum {
#define EMS_BOILER_BURNPOWER_TAPWATER 100
#define EMS_BOILER_SELFLOWTEMP_HEATING 30 // was 70, changed to 30 for https://github.com/proddy/EMS-ESP/issues/193
// define maximum setable tapwater temperature
// define min & maximum setable tapwater temperature
#define EMS_BOILER_TAPWATER_TEMPERATURE_MAX 60
#define EMS_BOILER_TAPWATER_TEMPERATURE_MIN 30
#define EMS_TX_TELEGRAM_QUEUE_MAX 50 // max size of Tx FIFO queue. Number of Tx records to send.

View File

@@ -1 +1 @@
#define APP_VERSION "1.9.5b2"
#define APP_VERSION "1.9.5b3"