mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 16:29:51 +03:00
added RC20 and SM200 to MQTT
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
10
src/MyESP.h
10
src/MyESP.h
@@ -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();
|
||||||
|
|
||||||
|
|||||||
106
src/ems-esp.cpp
106
src/ems-esp.cpp
@@ -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 HeatPump
|
// 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();
|
||||||
|
|||||||
84
src/ems.cpp
84
src/ems.cpp
@@ -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 {
|
||||||
|
myDebug_P(PSTR("<--- %s(0x%02X)"), EMS_Types[type_index].typeString, type);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
_printMessage(EMS_RxTelegram, i); // print with index to the Type string
|
_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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
#define APP_VERSION "1.9.5b44"
|
#define APP_VERSION "1.9.5b45"
|
||||||
|
|||||||
Reference in New Issue
Block a user