added RC20 and SM200 to MQTT

This commit is contained in:
Paul
2020-02-26 18:14:51 +01:00
parent e08efa7475
commit 52d8231229
7 changed files with 171 additions and 73 deletions

View File

@@ -432,22 +432,24 @@ void MyESP::_printMQTTQueue() {
} }
// Publish using the user's custom retain flag // Publish using the user's custom retain flag
void MyESP::mqttPublish(const char * topic, const char * payload) { bool MyESP::mqttPublish(const char * topic, const char * payload) {
_mqttQueue(topic, payload, _mqtt_retain); return (_mqttQueue(topic, payload, _mqtt_retain));
} }
void MyESP::mqttPublish(const char * topic, JsonDocument payload) { bool MyESP::mqttPublish(const char * topic, JsonDocument payload) {
_mqttQueue(topic, payload, _mqtt_retain); return (_mqttQueue(topic, payload, _mqtt_retain));
} }
// MQTT Publish // MQTT Publish
void MyESP::mqttPublish(const char * topic, const char * payload, bool retain) { bool MyESP::mqttPublish(const char * topic, const char * payload, bool retain) {
_mqttQueue(topic, payload, retain); return (_mqttQueue(topic, payload, retain));
} }
void MyESP::mqttPublish(const char * topic, JsonDocument payload, bool retain) { bool MyESP::mqttPublish(const char * topic, JsonDocument payload, bool retain) {
_mqttQueue(topic, payload, retain); return (_mqttQueue(topic, payload, retain));
} }
// put a payload string into the queue // put a payload string into the queue
// can't have empty topic
// returns false if can't add to queue
bool MyESP::_mqttQueue(const char * topic, const char * payload, bool retain) { bool MyESP::_mqttQueue(const char * topic, const char * payload, bool retain) {
if (!mqttClient.connected() || _mqtt_queue.size() >= MQTT_QUEUE_MAX_SIZE || !_hasValue(topic)) { if (!mqttClient.connected() || _mqtt_queue.size() >= MQTT_QUEUE_MAX_SIZE || !_hasValue(topic)) {
return false; return false;
@@ -471,11 +473,19 @@ bool MyESP::_mqttQueue(const char * topic, const char * payload, bool retain) {
} }
// convert json doc to a string buffer and place on queue // convert json doc to a string buffer and place on queue
// can't have empty payload or topic
// returns false if can't add to queue
bool MyESP::_mqttQueue(const char * topic, JsonDocument payload, bool retain) { bool MyESP::_mqttQueue(const char * topic, JsonDocument payload, bool retain) {
if (!mqttClient.connected() || _mqtt_queue.size() >= MQTT_QUEUE_MAX_SIZE || !_hasValue(topic)) { if (!mqttClient.connected() || _mqtt_queue.size() >= MQTT_QUEUE_MAX_SIZE || !_hasValue(topic)) {
return false; return false;
} }
// check for empty JSON doc - we don't like those
size_t capacity = measureJson(payload);
if (!capacity) {
return false;
}
// create a new message // create a new message
mqtt_message_t element; mqtt_message_t element;
element.topic = strdup(topic); element.topic = strdup(topic);
@@ -484,11 +494,9 @@ bool MyESP::_mqttQueue(const char * topic, JsonDocument payload, bool retain) {
element.retry_count = 0; element.retry_count = 0;
// reserve space for buffer and serialize json into it // reserve space for buffer and serialize json into it
const size_t capacity = measureJson(payload) + 1; capacity++; // add one more to cover the EOL
if (capacity) {
element.payload = (char *)malloc(capacity); element.payload = (char *)malloc(capacity);
serializeJson(payload, (char *)element.payload, capacity); serializeJson(payload, (char *)element.payload, capacity);
}
#ifdef MYESP_DEBUG #ifdef MYESP_DEBUG
myDebug_P(PSTR("[MQTT] Adding to queue: #%d [%s] %s"), _mqtt_queue.size(), element.topic, element.payload); myDebug_P(PSTR("[MQTT] Adding to queue: #%d [%s] %s"), _mqtt_queue.size(), element.topic, element.payload);

View File

@@ -9,7 +9,7 @@
#ifndef MyESP_h #ifndef MyESP_h
#define MyESP_h #define MyESP_h
#define MYESP_VERSION "1.2.31" #define MYESP_VERSION "1.2.32"
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include <ArduinoOTA.h> #include <ArduinoOTA.h>
@@ -280,10 +280,10 @@ class MyESP {
bool isMQTTConnected(); bool isMQTTConnected();
bool mqttSubscribe(const char * topic); bool mqttSubscribe(const char * topic);
void mqttUnsubscribe(const char * topic); void mqttUnsubscribe(const char * topic);
void mqttPublish(const char * topic, const char * payload); bool mqttPublish(const char * topic, const char * payload);
void mqttPublish(const char * topic, const char * payload, bool retain); bool mqttPublish(const char * topic, const char * payload, bool retain);
void mqttPublish(const char * topic, JsonDocument payload); bool mqttPublish(const char * topic, JsonDocument payload);
void mqttPublish(const char * topic, JsonDocument payload, bool retain); bool mqttPublish(const char * topic, JsonDocument payload, bool retain);
void setMQTT(mqtt_callback_f callback); void setMQTT(mqtt_callback_f callback);
bool mqttUseNestedJson(); bool mqttUseNestedJson();

View File

@@ -566,14 +566,14 @@ void scanDallas() {
} }
// send all dallas sensor values as a JSON package to MQTT // send all dallas sensor values as a JSON package to MQTT
void publishSensorValues() { bool publishSensorValues() {
// don't send if MQTT is connected // don't send if MQTT is connected
if (!myESP.isMQTTConnected() || (EMSESP_Settings.publish_time == -1)) { if (!myESP.isMQTTConnected() || (EMSESP_Settings.publish_time == -1)) {
return; return false;
} }
if (!EMSESP_Settings.dallas_sensors) { if (!EMSESP_Settings.dallas_sensors) {
return; // no sensors attached return false; // no sensors attached
} }
// each payload per sensor is 30 bytes so calculate if we have enough space // each payload per sensor is 30 bytes so calculate if we have enough space
@@ -604,7 +604,7 @@ void publishSensorValues() {
if (hasdata) { if (hasdata) {
myDebugLog("Publishing external sensor data via MQTT"); myDebugLog("Publishing external sensor data via MQTT");
} }
return; // exit return true; // exit
} }
// group all sensors together - https://github.com/proddy/EMS-ESP/issues/327 // group all sensors together - https://github.com/proddy/EMS-ESP/issues/327
@@ -625,15 +625,16 @@ void publishSensorValues() {
} }
} }
myESP.mqttPublish(TOPIC_EXTERNAL_SENSORS, doc);
if (hasdata) { if (hasdata) {
myDebugLog("Publishing external sensor data via MQTT"); myDebugLog("Publishing external sensor data via MQTT");
return (myESP.mqttPublish(TOPIC_EXTERNAL_SENSORS, doc));
} }
return false;
} }
// publish Boiler data via MQTT // publish Boiler data via MQTT
void publishEMSValues_boiler() { bool publishEMSValues_boiler() {
const size_t capacity = JSON_OBJECT_SIZE(41); // must recalculate if more objects addded https://arduinojson.org/v6/assistant/ const size_t capacity = JSON_OBJECT_SIZE(41); // must recalculate if more objects addded https://arduinojson.org/v6/assistant/
DynamicJsonDocument doc(capacity); DynamicJsonDocument doc(capacity);
JsonObject rootBoiler = doc.to<JsonObject>(); JsonObject rootBoiler = doc.to<JsonObject>();
@@ -762,9 +763,6 @@ void publishEMSValues_boiler() {
rootBoiler["ServiceCodeNumber"] = EMS_Boiler.serviceCode; rootBoiler["ServiceCodeNumber"] = EMS_Boiler.serviceCode;
} }
myDebugLog("Publishing boiler data via MQTT");
myESP.mqttPublish(TOPIC_BOILER_DATA, doc);
// see if the heating or hot tap water has changed, if so send // see if the heating or hot tap water has changed, if so send
// last_boilerActive stores heating in bit 1 and tap water in bit 2 // last_boilerActive stores heating in bit 1 and tap water in bit 2
static uint8_t last_boilerActive = 0xFF; // for remembering last setting of the tap water or heating on/off static uint8_t last_boilerActive = 0xFF; // for remembering last setting of the tap water or heating on/off
@@ -773,10 +771,12 @@ void publishEMSValues_boiler() {
myESP.mqttPublish(TOPIC_BOILER_HEATING_ACTIVE, EMS_Boiler.heatingActive == 1 ? "1" : "0"); myESP.mqttPublish(TOPIC_BOILER_HEATING_ACTIVE, EMS_Boiler.heatingActive == 1 ? "1" : "0");
last_boilerActive = ((EMS_Boiler.tapwaterActive << 1) + EMS_Boiler.heatingActive); // remember last state last_boilerActive = ((EMS_Boiler.tapwaterActive << 1) + EMS_Boiler.heatingActive); // remember last state
} }
return (myESP.mqttPublish(TOPIC_BOILER_DATA, doc));
} }
// handle the thermostat values // handle the thermostat values
void publishEMSValues_thermostat() { bool publishEMSValues_thermostat() {
StaticJsonDocument<MYESP_JSON_MAXSIZE_MEDIUM> doc; StaticJsonDocument<MYESP_JSON_MAXSIZE_MEDIUM> doc;
JsonObject rootThermostat = doc.to<JsonObject>(); JsonObject rootThermostat = doc.to<JsonObject>();
JsonObject dataThermostat; JsonObject dataThermostat;
@@ -868,14 +868,12 @@ void publishEMSValues_thermostat() {
myESP.mqttPublish(TOPIC_THERMOSTAT_DATA, data); myESP.mqttPublish(TOPIC_THERMOSTAT_DATA, data);
} }
if (has_data) { return (has_data);
myDebugLog("Publishing thermostat data via MQTT");
}
} }
// publish mixing data // publish mixing data
// only sending if we have an active hc // only sending if we have an active hc
void publishEMSValues_mixing() { bool publishEMSValues_mixing() {
char s[20]; // for formatting strings char s[20]; // for formatting strings
StaticJsonDocument<MYESP_JSON_MAXSIZE_MEDIUM> doc; StaticJsonDocument<MYESP_JSON_MAXSIZE_MEDIUM> doc;
JsonObject rootMixing = doc.to<JsonObject>(); JsonObject rootMixing = doc.to<JsonObject>();
@@ -920,13 +918,15 @@ void publishEMSValues_mixing() {
} }
if (has_data) { if (has_data) {
myDebugLog("Publishing mixing data via MQTT");
myESP.mqttPublish(TOPIC_MIXING_DATA, doc); myESP.mqttPublish(TOPIC_MIXING_DATA, doc);
return true;
} }
return false;
} }
// For SM10 and SM100/SM200 Solar Modules // For SM10 and SM100/SM200 Solar Modules
void publishEMSValues_solar() { bool publishEMSValues_solar() {
StaticJsonDocument<MYESP_JSON_MAXSIZE_SMALL> doc; StaticJsonDocument<MYESP_JSON_MAXSIZE_SMALL> doc;
JsonObject rootSM = doc.to<JsonObject>(); JsonObject rootSM = doc.to<JsonObject>();
@@ -936,6 +936,9 @@ void publishEMSValues_solar() {
if (EMS_SolarModule.bottomTemp > EMS_VALUE_SHORT_NOTSET) { if (EMS_SolarModule.bottomTemp > EMS_VALUE_SHORT_NOTSET) {
rootSM[SM_BOTTOMTEMP] = (float)EMS_SolarModule.bottomTemp / 10; rootSM[SM_BOTTOMTEMP] = (float)EMS_SolarModule.bottomTemp / 10;
} }
if (EMS_SolarModule.bottomTemp2 > EMS_VALUE_SHORT_NOTSET) {
rootSM[SM_BOTTOMTEMP2] = (float)EMS_SolarModule.bottomTemp2 / 10;
}
if (EMS_SolarModule.pumpModulation != EMS_VALUE_INT_NOTSET) { if (EMS_SolarModule.pumpModulation != EMS_VALUE_INT_NOTSET) {
rootSM[SM_PUMPMODULATION] = EMS_SolarModule.pumpModulation; rootSM[SM_PUMPMODULATION] = EMS_SolarModule.pumpModulation;
} }
@@ -943,6 +946,10 @@ void publishEMSValues_solar() {
char s[20]; char s[20];
rootSM[SM_PUMP] = _bool_to_char(s, EMS_SolarModule.pump); rootSM[SM_PUMP] = _bool_to_char(s, EMS_SolarModule.pump);
} }
if (EMS_SolarModule.valveStatus != EMS_VALUE_BOOL_NOTSET) {
char s[20];
rootSM[SM_VALVESTATUS] = _bool_to_char(s, EMS_SolarModule.valveStatus);
}
if (EMS_SolarModule.pumpWorkMin != EMS_VALUE_LONG_NOTSET) { if (EMS_SolarModule.pumpWorkMin != EMS_VALUE_LONG_NOTSET) {
rootSM[SM_PUMPWORKMIN] = (float)EMS_SolarModule.pumpWorkMin; rootSM[SM_PUMPWORKMIN] = (float)EMS_SolarModule.pumpWorkMin;
} }
@@ -956,12 +963,12 @@ void publishEMSValues_solar() {
rootSM[SM_ENERGYTOTAL] = (float)EMS_SolarModule.EnergyTotal / 10; rootSM[SM_ENERGYTOTAL] = (float)EMS_SolarModule.EnergyTotal / 10;
} }
myDebugLog("Publishing solar module data via MQTT"); return (myESP.mqttPublish(TOPIC_SM_DATA, doc));
myESP.mqttPublish(TOPIC_SM_DATA, doc);
} }
// handle Heat Pump // handle Heat Pump
void publishEMSValues_heatpump() { // returns true if added to MQTT queue went ok
bool publishEMSValues_heatpump() {
StaticJsonDocument<MYESP_JSON_MAXSIZE_SMALL> doc; StaticJsonDocument<MYESP_JSON_MAXSIZE_SMALL> doc;
JsonObject rootHP = doc.to<JsonObject>(); JsonObject rootHP = doc.to<JsonObject>();
@@ -972,12 +979,13 @@ void publishEMSValues_heatpump() {
rootHP[HP_PUMPSPEED] = EMS_HeatPump.HPSpeed; rootHP[HP_PUMPSPEED] = EMS_HeatPump.HPSpeed;
} }
myDebugLog("Publishing peat pump data via MQTT"); myDebugLog("Publishing heat pump data via MQTT");
myESP.mqttPublish(TOPIC_HP_DATA, doc); return (myESP.mqttPublish(TOPIC_HP_DATA, doc));
} }
// Publish shower data // Publish shower data
void do_publishShowerData() { // returns true if added to MQTT queue went ok
bool do_publishShowerData() {
StaticJsonDocument<MYESP_JSON_MAXSIZE_SMALL> doc; StaticJsonDocument<MYESP_JSON_MAXSIZE_SMALL> doc;
JsonObject rootShower = doc.to<JsonObject>(); JsonObject rootShower = doc.to<JsonObject>();
rootShower[TOPIC_SHOWER_TIMER] = EMSESP_Settings.shower_timer ? "1" : "0"; rootShower[TOPIC_SHOWER_TIMER] = EMSESP_Settings.shower_timer ? "1" : "0";
@@ -995,41 +1003,73 @@ void do_publishShowerData() {
} }
myDebugLog("Publishing shower data via MQTT"); myDebugLog("Publishing shower data via MQTT");
myESP.mqttPublish(TOPIC_SHOWER_DATA, doc, false); // Publish MQTT forcing retain to be off return (myESP.mqttPublish(TOPIC_SHOWER_DATA, doc, false)); // Publish MQTT forcing retain to be off
} }
// send values via MQTT // send values via MQTT
// a json object is created for each device type // a json object is created for each device type
void publishEMSValues(bool force) { bool publishEMSValues(bool force) {
// don't send if MQTT is not connected or EMS bus is not connected // don't send if MQTT is not connected or EMS bus is not connected
if (!myESP.isMQTTConnected() || (!ems_getBusConnected()) || (EMSESP_Settings.publish_time == -1)) { if (!myESP.isMQTTConnected() || (!ems_getBusConnected()) || (EMSESP_Settings.publish_time == -1)) {
return; return false;
} }
bool thermo = false;
bool boiler = false;
bool mixing = false;
bool solar = false;
bool heatpump = false;
if (ems_getThermostatEnabled() && (ems_Device_has_flags(EMS_DEVICE_UPDATE_FLAG_THERMOSTAT) || force)) { if (ems_getThermostatEnabled() && (ems_Device_has_flags(EMS_DEVICE_UPDATE_FLAG_THERMOSTAT) || force)) {
publishEMSValues_thermostat(); thermo = publishEMSValues_thermostat();
ems_Device_remove_flags(EMS_DEVICE_UPDATE_FLAG_THERMOSTAT); // unset flag ems_Device_remove_flags(EMS_DEVICE_UPDATE_FLAG_THERMOSTAT); // unset flag
} }
if (ems_getBoilerEnabled() && (ems_Device_has_flags(EMS_DEVICE_UPDATE_FLAG_BOILER) || force)) { if (ems_getBoilerEnabled() && (ems_Device_has_flags(EMS_DEVICE_UPDATE_FLAG_BOILER) || force)) {
publishEMSValues_boiler(); boiler = publishEMSValues_boiler();
ems_Device_remove_flags(EMS_DEVICE_UPDATE_FLAG_BOILER); // unset flag ems_Device_remove_flags(EMS_DEVICE_UPDATE_FLAG_BOILER); // unset flag
} }
if (ems_getMixingModuleEnabled() && (ems_Device_has_flags(EMS_DEVICE_UPDATE_FLAG_MIXING) || force)) { if (ems_getMixingModuleEnabled() && (ems_Device_has_flags(EMS_DEVICE_UPDATE_FLAG_MIXING) || force)) {
publishEMSValues_mixing(); mixing = publishEMSValues_mixing();
ems_Device_remove_flags(EMS_DEVICE_UPDATE_FLAG_MIXING); // unset flag ems_Device_remove_flags(EMS_DEVICE_UPDATE_FLAG_MIXING); // unset flag
} }
if (ems_getSolarModuleEnabled() && (ems_Device_has_flags(EMS_DEVICE_UPDATE_FLAG_SOLAR) || force)) { if (ems_getSolarModuleEnabled() && (ems_Device_has_flags(EMS_DEVICE_UPDATE_FLAG_SOLAR) || force)) {
publishEMSValues_solar(); solar = publishEMSValues_solar();
ems_Device_remove_flags(EMS_DEVICE_UPDATE_FLAG_SOLAR); // unset flag ems_Device_remove_flags(EMS_DEVICE_UPDATE_FLAG_SOLAR); // unset flag
} }
if (ems_getHeatPumpEnabled() && (ems_Device_has_flags(EMS_DEVICE_UPDATE_FLAG_HEATPUMP) || force)) { if (ems_getHeatPumpEnabled() && (ems_Device_has_flags(EMS_DEVICE_UPDATE_FLAG_HEATPUMP) || force)) {
publishEMSValues_heatpump(); heatpump = publishEMSValues_heatpump();
ems_Device_remove_flags(EMS_DEVICE_UPDATE_FLAG_HEATPUMP); // unset flag ems_Device_remove_flags(EMS_DEVICE_UPDATE_FLAG_HEATPUMP); // unset flag
} }
if (!thermo && !boiler && !mixing && !solar && !heatpump) {
return false; // nothing was sent
}
// print
char log_s[50];
strlcpy(log_s, "Publishing MQTT data for:", sizeof(log_s));
if (thermo) {
strlcat(log_s, " thermostat", sizeof(log_s));
}
if (boiler) {
strlcat(log_s, " boiler", sizeof(log_s));
}
if (mixing) {
strlcat(log_s, " mixing", sizeof(log_s));
}
if (solar) {
strlcat(log_s, " solar", sizeof(log_s));
}
if (heatpump) {
strlcat(log_s, " heatpump", sizeof(log_s));
}
myDebugLog(log_s);
return true;
} }
// publishes value via MQTT // publishes value via MQTT
@@ -1038,7 +1078,7 @@ void publishValues(bool force, bool send_sensor) {
return; return;
} }
myDebugLog("Starting scheduled MQTT publish..."); // myDebugLog("Starting scheduled MQTT publish...");
publishEMSValues(force); publishEMSValues(force);
if (send_sensor) { if (send_sensor) {
publishSensorValues(); publishSensorValues();

View File

@@ -1146,6 +1146,29 @@ void _process_RC10StatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].curr_roomTemp, EMS_OFFSET_RC10StatusMessage_curr); // is * 10 _setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].curr_roomTemp, EMS_OFFSET_RC10StatusMessage_curr); // is * 10
} }
/**
* type 0xAD - data from the RC20 thermostat (0x17)
* e.g. 17 00 AD 0D 2E
*/
void _process_RC20StatusMessage2(_EMS_RxTelegram * EMS_RxTelegram) {
uint8_t hc = EMS_THERMOSTAT_DEFAULTHC - 1; // use HC1
EMS_Thermostat.hc[hc].active = true;
_setValue8(EMS_RxTelegram, &EMS_Thermostat.hc[hc].setpoint_roomTemp, 0); // is * 2, force as single byte
}
/**
* type 0xAE - data from the RC20 thermostat (0x17)
* e.g. 17 00 AE 00 80 12 2E 00 D0 00 00 64
*/
void _process_RC20StatusMessage3(_EMS_RxTelegram * EMS_RxTelegram) {
uint8_t hc = EMS_THERMOSTAT_DEFAULTHC - 1; // use HC1
EMS_Thermostat.hc[hc].active = true;
// _setValue8(EMS_RxTelegram, &EMS_Thermostat.hc[hc].setpoint_roomTemp, EMS_OFFSET_RC20StatusMessage_setpoint); // is * 2, force as single byte
//_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].curr_roomTemp, EMS_OFFSET_RC20StatusMessage_curr); // is * 10
}
/** /**
* type 0x91 - data from the RC20 thermostat (0x17) - 15 bytes long * type 0x91 - data from the RC20 thermostat (0x17) - 15 bytes long
* For reading the temp values only * For reading the temp values only
@@ -2814,13 +2837,16 @@ void ems_testTelegram(uint8_t test_num) {
*/ */
const _EMS_Type EMS_Types[] = { const _EMS_Type EMS_Types[] = {
// types that we know about but don't have handlers yet
{EMS_DEVICE_UPDATE_FLAG_NONE, EMS_TYPE_UBAFlags, "UBAFlags", nullptr},
{EMS_DEVICE_UPDATE_FLAG_NONE, EMS_TYPE_UBAMaintenanceStatusMessage, "UBAMaintenanceStatusMessage", nullptr},
{EMS_DEVICE_UPDATE_FLAG_NONE, EMS_TYPE_MC10Status, "MC10Status", nullptr},
// common // common
{EMS_DEVICE_UPDATE_FLAG_NONE, EMS_TYPE_Version, "Version", _process_Version}, {EMS_DEVICE_UPDATE_FLAG_NONE, EMS_TYPE_Version, "Version", _process_Version},
{EMS_DEVICE_UPDATE_FLAG_NONE, EMS_TYPE_UBADevices, "UBADevices", _process_UBADevices},
{EMS_DEVICE_UPDATE_FLAG_NONE, EMS_TYPE_RCTime, "RCTime", _process_RCTime},
{EMS_DEVICE_UPDATE_FLAG_THERMOSTAT, EMS_TYPE_RCOutdoorTempMessage, "RCOutdoorTempMessage", _process_RCOutdoorTempMessage},
// UBA/Boiler // UBA/Boiler
{EMS_DEVICE_UPDATE_FLAG_NONE, EMS_TYPE_UBADevices, "UBADevices", _process_UBADevices},
{EMS_DEVICE_UPDATE_FLAG_BOILER, EMS_TYPE_UBAMonitorFast, "UBAMonitorFast", _process_UBAMonitorFast}, {EMS_DEVICE_UPDATE_FLAG_BOILER, EMS_TYPE_UBAMonitorFast, "UBAMonitorFast", _process_UBAMonitorFast},
{EMS_DEVICE_UPDATE_FLAG_BOILER, EMS_TYPE_UBAMonitorSlow, "UBAMonitorSlow", _process_UBAMonitorSlow}, {EMS_DEVICE_UPDATE_FLAG_BOILER, EMS_TYPE_UBAMonitorSlow, "UBAMonitorSlow", _process_UBAMonitorSlow},
{EMS_DEVICE_UPDATE_FLAG_BOILER, EMS_TYPE_UBAMonitorWWMessage, "UBAMonitorWWMessage", _process_UBAMonitorWWMessage}, {EMS_DEVICE_UPDATE_FLAG_BOILER, EMS_TYPE_UBAMonitorWWMessage, "UBAMonitorWWMessage", _process_UBAMonitorWWMessage},
@@ -2847,6 +2873,10 @@ const _EMS_Type EMS_Types[] = {
{EMS_DEVICE_UPDATE_FLAG_HEATPUMP, EMS_TYPE_HPMonitor1, "HeatPumpMonitor1", _process_HPMonitor1}, {EMS_DEVICE_UPDATE_FLAG_HEATPUMP, EMS_TYPE_HPMonitor1, "HeatPumpMonitor1", _process_HPMonitor1},
{EMS_DEVICE_UPDATE_FLAG_HEATPUMP, EMS_TYPE_HPMonitor2, "HeatPumpMonitor2", _process_HPMonitor2}, {EMS_DEVICE_UPDATE_FLAG_HEATPUMP, EMS_TYPE_HPMonitor2, "HeatPumpMonitor2", _process_HPMonitor2},
// Thermostats...
{EMS_DEVICE_UPDATE_FLAG_NONE, EMS_TYPE_RCTime, "RCTime", _process_RCTime},
{EMS_DEVICE_UPDATE_FLAG_THERMOSTAT, EMS_TYPE_RCOutdoorTempMessage, "RCOutdoorTempMessage", _process_RCOutdoorTempMessage},
// RC10 // RC10
{EMS_DEVICE_UPDATE_FLAG_THERMOSTAT, EMS_TYPE_RC10Set, "RC10Set", _process_RC10Set}, {EMS_DEVICE_UPDATE_FLAG_THERMOSTAT, EMS_TYPE_RC10Set, "RC10Set", _process_RC10Set},
{EMS_DEVICE_UPDATE_FLAG_THERMOSTAT, EMS_TYPE_RC10StatusMessage, "RC10StatusMessage", _process_RC10StatusMessage}, {EMS_DEVICE_UPDATE_FLAG_THERMOSTAT, EMS_TYPE_RC10StatusMessage, "RC10StatusMessage", _process_RC10StatusMessage},
@@ -2854,6 +2884,8 @@ const _EMS_Type EMS_Types[] = {
// RC20 and RC20RF // RC20 and RC20RF
{EMS_DEVICE_UPDATE_FLAG_THERMOSTAT, EMS_TYPE_RC20Set, "RC20Set", _process_RC20Set}, {EMS_DEVICE_UPDATE_FLAG_THERMOSTAT, EMS_TYPE_RC20Set, "RC20Set", _process_RC20Set},
{EMS_DEVICE_UPDATE_FLAG_THERMOSTAT, EMS_TYPE_RC20StatusMessage, "RC20StatusMessage", _process_RC20StatusMessage}, {EMS_DEVICE_UPDATE_FLAG_THERMOSTAT, EMS_TYPE_RC20StatusMessage, "RC20StatusMessage", _process_RC20StatusMessage},
{EMS_DEVICE_UPDATE_FLAG_THERMOSTAT, EMS_TYPE_RC20StatusMessage2, "RC20StatusMessage2", _process_RC20StatusMessage2},
{EMS_DEVICE_UPDATE_FLAG_THERMOSTAT, EMS_TYPE_RC20StatusMessage3, "RC20StatusMessage3", _process_RC20StatusMessage3},
// RC30 // RC30
{EMS_DEVICE_UPDATE_FLAG_THERMOSTAT, EMS_TYPE_RC30Set, "RC30Set", _process_RC30Set}, {EMS_DEVICE_UPDATE_FLAG_THERMOSTAT, EMS_TYPE_RC30Set, "RC30Set", _process_RC30Set},
@@ -2906,6 +2938,10 @@ uint8_t _EMS_Types_max = ArraySize(EMS_Types);
* or -1 if not found * or -1 if not found
*/ */
int8_t _ems_findType(uint16_t type) { int8_t _ems_findType(uint16_t type) {
if (type == 0) {
return -1;
}
uint8_t i = 0; uint8_t i = 0;
bool typeFound = false; bool typeFound = false;
// scan through known ID types // scan through known ID types
@@ -2923,7 +2959,7 @@ int8_t _ems_findType(uint16_t type) {
/** /**
* print the telegram * print the telegram
*/ */
void _printMessage(_EMS_RxTelegram * EMS_RxTelegram, const int show_type) { void _printMessage(_EMS_RxTelegram * EMS_RxTelegram, const int8_t show_type) {
// only print if we have logging enabled // only print if we have logging enabled
if (EMS_Sys_Status.emsLogging < EMS_SYS_LOGGING_THERMOSTAT) { if (EMS_Sys_Status.emsLogging < EMS_SYS_LOGGING_THERMOSTAT) {
return; return;
@@ -2957,11 +2993,14 @@ void _printMessage(_EMS_RxTelegram * EMS_RxTelegram, const int show_type) {
} }
// print type // print type
// if we're been given an index to the type string, use that
if (length) { if (length) {
char buffer[16]; char buffer[16];
strlcat(output_str, ", ", sizeof(output_str)); strlcat(output_str, ", ", sizeof(output_str));
if (show_type != -1) { if (show_type != -1) {
strlcat(output_str, EMS_Types[show_type].typeString, sizeof(output_str)); strlcat(output_str, EMS_Types[show_type].typeString, sizeof(output_str));
} else {
strlcat(output_str, "Type", sizeof(output_str));
} }
strlcat(output_str, "(0x", sizeof(output_str)); strlcat(output_str, "(0x", sizeof(output_str));
@@ -3002,38 +3041,43 @@ void _printMessage(_EMS_RxTelegram * EMS_RxTelegram, const int show_type) {
* and then call its callback if there is one defined * and then call its callback if there is one defined
*/ */
void _ems_processTelegram(_EMS_RxTelegram * EMS_RxTelegram) { void _ems_processTelegram(_EMS_RxTelegram * EMS_RxTelegram) {
// first see if we know which type this. -1 if not found.
uint16_t type = EMS_RxTelegram->type;
int8_t type_index = _ems_findType(type);
// ignore telegrams that don't have any data // ignore telegrams that don't have any data
if (EMS_RxTelegram->data_length == 0) { if (EMS_RxTelegram->data_length == 0) {
_printMessage(EMS_RxTelegram); _printMessage(EMS_RxTelegram, type_index);
return; return;
} }
// we're only interested in broadcast messages (dest is 0x00) or ones for us // we're only interested in broadcast messages (dest is 0x00) or ones sent to us
uint8_t dest = EMS_RxTelegram->dest; uint8_t dest = EMS_RxTelegram->dest;
if ((dest != EMS_ID_NONE) && (dest != EMS_Sys_Status.emsbusid)) { if ((dest != EMS_ID_NONE) && (dest != EMS_Sys_Status.emsbusid)) {
_printMessage(EMS_RxTelegram); _printMessage(EMS_RxTelegram, type_index);
return; return;
} }
// see if we recognize the type first by scanning our known EMS types list
uint16_t type = EMS_RxTelegram->type;
int8_t i = _ems_findType(type);
if (i == -1) {
_printMessage(EMS_RxTelegram);
return; // not found
}
// we have a matching type ID, print the detailed telegram to the console // we have a matching type ID, print the detailed telegram to the console
if (EMS_Sys_Status.emsLogging == EMS_SYS_LOGGING_BASIC) { if (EMS_Sys_Status.emsLogging == EMS_SYS_LOGGING_BASIC) {
myDebug_P(PSTR("<--- %s(0x%02X)"), EMS_Types[i].typeString, type); if (type == -1) {
myDebug_P(PSTR("<--- Type(0x%02X)"), type);
} else { } else {
_printMessage(EMS_RxTelegram, i); // print with index to the Type string myDebug_P(PSTR("<--- %s(0x%02X)"), EMS_Types[type_index].typeString, type);
}
} else {
_printMessage(EMS_RxTelegram, type_index); // print with index to the Type string
}
// quit if we don't know how to handle this type
if (type_index == -1) {
return;
} }
// process it by calling its respective callback function // process it by calling its respective callback function
if ((EMS_Types[i].processType_cb) != nullptr) { if ((EMS_Types[type_index].processType_cb) != nullptr) {
(void)EMS_Types[i].processType_cb(EMS_RxTelegram); (void)EMS_Types[type_index].processType_cb(EMS_RxTelegram);
ems_Device_add_flags(EMS_Types[i].device_flag); // see if we need to flag something has changed ems_Device_add_flags(EMS_Types[type_index].device_flag); // see if we need to flag something has changed
} }
EMS_Sys_Status.emsTxStatus = EMS_TX_STATUS_IDLE; EMS_Sys_Status.emsTxStatus = EMS_TX_STATUS_IDLE;

View File

@@ -27,6 +27,7 @@
#define EMS_TYPE_UBAMonitorSlow 0x19 // is an automatic monitor broadcast #define EMS_TYPE_UBAMonitorSlow 0x19 // is an automatic monitor broadcast
#define EMS_TYPE_UBAMonitorWWMessage 0x34 // is an automatic monitor broadcast #define EMS_TYPE_UBAMonitorWWMessage 0x34 // is an automatic monitor broadcast
#define EMS_TYPE_UBAMaintenanceStatusMessage 0x1C // is an automatic monitor broadcast #define EMS_TYPE_UBAMaintenanceStatusMessage 0x1C // is an automatic monitor broadcast
#define EMS_TYPE_MC10Status 0x2A
#define EMS_TYPE_UBAParameterWW 0x33 #define EMS_TYPE_UBAParameterWW 0x33
#define EMS_TYPE_UBATotalUptimeMessage 0x14 #define EMS_TYPE_UBATotalUptimeMessage 0x14
#define EMS_TYPE_UBAFlags 0x35 #define EMS_TYPE_UBAFlags 0x35
@@ -109,6 +110,9 @@
#define EMS_OFFSET_RC20StatusMessage_setpoint 1 // setpoint temp #define EMS_OFFSET_RC20StatusMessage_setpoint 1 // setpoint temp
#define EMS_OFFSET_RC20StatusMessage_curr 2 // current temp #define EMS_OFFSET_RC20StatusMessage_curr 2 // current temp
#define EMS_TYPE_RC20StatusMessage2 0xAD
#define EMS_TYPE_RC20StatusMessage3 0xAE
#define EMS_TYPE_RC20Set 0xA8 // for setting values like temp and mode #define EMS_TYPE_RC20Set 0xA8 // for setting values like temp and mode
#define EMS_OFFSET_RC20Set_mode 23 // position of thermostat mode #define EMS_OFFSET_RC20Set_mode 23 // position of thermostat mode
#define EMS_OFFSET_RC20Set_temp 28 // position of thermostat setpoint temperature #define EMS_OFFSET_RC20Set_temp 28 // position of thermostat setpoint temperature

View File

@@ -61,9 +61,11 @@
// MQTT for SM10/SM100/SM200 Solar Module // MQTT for SM10/SM100/SM200 Solar Module
#define TOPIC_SM_DATA "sm_data" // topic name #define TOPIC_SM_DATA "sm_data" // topic name
#define SM_COLLECTORTEMP "collectortemp" // collector temp #define SM_COLLECTORTEMP "collectortemp" // collector temp
#define SM_BOTTOMTEMP "bottomtemp" // bottom temp #define SM_BOTTOMTEMP "bottomtemp" // bottom temp1
#define SM_BOTTOMTEMP2 "bottomtemp2" // bottom temp2
#define SM_PUMPMODULATION "pumpmodulation" // pump modulation #define SM_PUMPMODULATION "pumpmodulation" // pump modulation
#define SM_PUMP "pump" // pump active #define SM_PUMP "pump" // pump active
#define SM_VALVESTATUS "valvestatus" // valve status
#define SM_ENERGYLASTHOUR "energylasthour" // energy last hour #define SM_ENERGYLASTHOUR "energylasthour" // energy last hour
#define SM_ENERGYTODAY "energytoday" // energy today #define SM_ENERGYTODAY "energytoday" // energy today
#define SM_ENERGYTOTAL "energytotal" // energy total #define SM_ENERGYTOTAL "energytotal" // energy total

View File

@@ -1 +1 @@
#define APP_VERSION "1.9.5b44" #define APP_VERSION "1.9.5b45"