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
void MyESP::mqttPublish(const char * topic, const char * payload) {
_mqttQueue(topic, payload, _mqtt_retain);
bool MyESP::mqttPublish(const char * topic, const char * payload) {
return (_mqttQueue(topic, payload, _mqtt_retain));
}
void MyESP::mqttPublish(const char * topic, JsonDocument payload) {
_mqttQueue(topic, payload, _mqtt_retain);
bool MyESP::mqttPublish(const char * topic, JsonDocument payload) {
return (_mqttQueue(topic, payload, _mqtt_retain));
}
// MQTT Publish
void MyESP::mqttPublish(const char * topic, const char * payload, bool retain) {
_mqttQueue(topic, payload, retain);
bool MyESP::mqttPublish(const char * topic, const char * payload, bool retain) {
return (_mqttQueue(topic, payload, retain));
}
void MyESP::mqttPublish(const char * topic, JsonDocument payload, bool retain) {
_mqttQueue(topic, payload, retain);
bool MyESP::mqttPublish(const char * topic, JsonDocument payload, bool retain) {
return (_mqttQueue(topic, payload, retain));
}
// 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) {
if (!mqttClient.connected() || _mqtt_queue.size() >= MQTT_QUEUE_MAX_SIZE || !_hasValue(topic)) {
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
// 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) {
if (!mqttClient.connected() || _mqtt_queue.size() >= MQTT_QUEUE_MAX_SIZE || !_hasValue(topic)) {
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
mqtt_message_t element;
element.topic = strdup(topic);
@@ -484,11 +494,9 @@ bool MyESP::_mqttQueue(const char * topic, JsonDocument payload, bool retain) {
element.retry_count = 0;
// reserve space for buffer and serialize json into it
const size_t capacity = measureJson(payload) + 1;
if (capacity) {
element.payload = (char *)malloc(capacity);
serializeJson(payload, (char *)element.payload, capacity);
}
capacity++; // add one more to cover the EOL
element.payload = (char *)malloc(capacity);
serializeJson(payload, (char *)element.payload, capacity);
#ifdef MYESP_DEBUG
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
#define MyESP_h
#define MYESP_VERSION "1.2.31"
#define MYESP_VERSION "1.2.32"
#include <ArduinoJson.h>
#include <ArduinoOTA.h>
@@ -280,10 +280,10 @@ class MyESP {
bool isMQTTConnected();
bool mqttSubscribe(const char * topic);
void mqttUnsubscribe(const char * topic);
void mqttPublish(const char * topic, const char * payload);
void mqttPublish(const char * topic, const char * payload, bool retain);
void mqttPublish(const char * topic, JsonDocument payload);
void mqttPublish(const char * topic, JsonDocument payload, bool retain);
bool mqttPublish(const char * topic, const char * payload);
bool mqttPublish(const char * topic, const char * payload, bool retain);
bool mqttPublish(const char * topic, JsonDocument payload);
bool mqttPublish(const char * topic, JsonDocument payload, bool retain);
void setMQTT(mqtt_callback_f callback);
bool mqttUseNestedJson();

View File

@@ -566,14 +566,14 @@ void scanDallas() {
}
// send all dallas sensor values as a JSON package to MQTT
void publishSensorValues() {
bool publishSensorValues() {
// don't send if MQTT is connected
if (!myESP.isMQTTConnected() || (EMSESP_Settings.publish_time == -1)) {
return;
return false;
}
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
@@ -604,7 +604,7 @@ void publishSensorValues() {
if (hasdata) {
myDebugLog("Publishing external sensor data via MQTT");
}
return; // exit
return true; // exit
}
// 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) {
myDebugLog("Publishing external sensor data via MQTT");
return (myESP.mqttPublish(TOPIC_EXTERNAL_SENSORS, doc));
}
return false;
}
// 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/
DynamicJsonDocument doc(capacity);
JsonObject rootBoiler = doc.to<JsonObject>();
@@ -762,9 +763,6 @@ void publishEMSValues_boiler() {
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
// 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
@@ -773,10 +771,12 @@ void publishEMSValues_boiler() {
myESP.mqttPublish(TOPIC_BOILER_HEATING_ACTIVE, EMS_Boiler.heatingActive == 1 ? "1" : "0");
last_boilerActive = ((EMS_Boiler.tapwaterActive << 1) + EMS_Boiler.heatingActive); // remember last state
}
return (myESP.mqttPublish(TOPIC_BOILER_DATA, doc));
}
// handle the thermostat values
void publishEMSValues_thermostat() {
bool publishEMSValues_thermostat() {
StaticJsonDocument<MYESP_JSON_MAXSIZE_MEDIUM> doc;
JsonObject rootThermostat = doc.to<JsonObject>();
JsonObject dataThermostat;
@@ -868,14 +868,12 @@ void publishEMSValues_thermostat() {
myESP.mqttPublish(TOPIC_THERMOSTAT_DATA, data);
}
if (has_data) {
myDebugLog("Publishing thermostat data via MQTT");
}
return (has_data);
}
// publish mixing data
// only sending if we have an active hc
void publishEMSValues_mixing() {
bool publishEMSValues_mixing() {
char s[20]; // for formatting strings
StaticJsonDocument<MYESP_JSON_MAXSIZE_MEDIUM> doc;
JsonObject rootMixing = doc.to<JsonObject>();
@@ -920,13 +918,15 @@ void publishEMSValues_mixing() {
}
if (has_data) {
myDebugLog("Publishing mixing data via MQTT");
myESP.mqttPublish(TOPIC_MIXING_DATA, doc);
return true;
}
return false;
}
// For SM10 and SM100/SM200 Solar Modules
void publishEMSValues_solar() {
bool publishEMSValues_solar() {
StaticJsonDocument<MYESP_JSON_MAXSIZE_SMALL> doc;
JsonObject rootSM = doc.to<JsonObject>();
@@ -936,6 +936,9 @@ void publishEMSValues_solar() {
if (EMS_SolarModule.bottomTemp > EMS_VALUE_SHORT_NOTSET) {
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) {
rootSM[SM_PUMPMODULATION] = EMS_SolarModule.pumpModulation;
}
@@ -943,6 +946,10 @@ void publishEMSValues_solar() {
char s[20];
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) {
rootSM[SM_PUMPWORKMIN] = (float)EMS_SolarModule.pumpWorkMin;
}
@@ -956,12 +963,12 @@ void publishEMSValues_solar() {
rootSM[SM_ENERGYTOTAL] = (float)EMS_SolarModule.EnergyTotal / 10;
}
myDebugLog("Publishing solar module data via MQTT");
myESP.mqttPublish(TOPIC_SM_DATA, doc);
return (myESP.mqttPublish(TOPIC_SM_DATA, doc));
}
// handle HeatPump
void publishEMSValues_heatpump() {
// handle Heat Pump
// returns true if added to MQTT queue went ok
bool publishEMSValues_heatpump() {
StaticJsonDocument<MYESP_JSON_MAXSIZE_SMALL> doc;
JsonObject rootHP = doc.to<JsonObject>();
@@ -972,12 +979,13 @@ void publishEMSValues_heatpump() {
rootHP[HP_PUMPSPEED] = EMS_HeatPump.HPSpeed;
}
myDebugLog("Publishing peat pump data via MQTT");
myESP.mqttPublish(TOPIC_HP_DATA, doc);
myDebugLog("Publishing heat pump data via MQTT");
return (myESP.mqttPublish(TOPIC_HP_DATA, doc));
}
// Publish shower data
void do_publishShowerData() {
// returns true if added to MQTT queue went ok
bool do_publishShowerData() {
StaticJsonDocument<MYESP_JSON_MAXSIZE_SMALL> doc;
JsonObject rootShower = doc.to<JsonObject>();
rootShower[TOPIC_SHOWER_TIMER] = EMSESP_Settings.shower_timer ? "1" : "0";
@@ -995,41 +1003,73 @@ void do_publishShowerData() {
}
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
// 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
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)) {
publishEMSValues_thermostat();
thermo = publishEMSValues_thermostat();
ems_Device_remove_flags(EMS_DEVICE_UPDATE_FLAG_THERMOSTAT); // unset flag
}
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
}
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
}
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
}
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
}
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
@@ -1038,7 +1078,7 @@ void publishValues(bool force, bool send_sensor) {
return;
}
myDebugLog("Starting scheduled MQTT publish...");
// myDebugLog("Starting scheduled MQTT publish...");
publishEMSValues(force);
if (send_sensor) {
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
}
/**
* 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
* For reading the temp values only
@@ -2814,13 +2837,16 @@ void ems_testTelegram(uint8_t test_num) {
*/
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
{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
{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_UBAMonitorSlow, "UBAMonitorSlow", _process_UBAMonitorSlow},
{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_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
{EMS_DEVICE_UPDATE_FLAG_THERMOSTAT, EMS_TYPE_RC10Set, "RC10Set", _process_RC10Set},
{EMS_DEVICE_UPDATE_FLAG_THERMOSTAT, EMS_TYPE_RC10StatusMessage, "RC10StatusMessage", _process_RC10StatusMessage},
@@ -2854,6 +2884,8 @@ const _EMS_Type EMS_Types[] = {
// RC20 and RC20RF
{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_RC20StatusMessage2, "RC20StatusMessage2", _process_RC20StatusMessage2},
{EMS_DEVICE_UPDATE_FLAG_THERMOSTAT, EMS_TYPE_RC20StatusMessage3, "RC20StatusMessage3", _process_RC20StatusMessage3},
// RC30
{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
*/
int8_t _ems_findType(uint16_t type) {
if (type == 0) {
return -1;
}
uint8_t i = 0;
bool typeFound = false;
// scan through known ID types
@@ -2923,7 +2959,7 @@ int8_t _ems_findType(uint16_t type) {
/**
* 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
if (EMS_Sys_Status.emsLogging < EMS_SYS_LOGGING_THERMOSTAT) {
return;
@@ -2957,11 +2993,14 @@ void _printMessage(_EMS_RxTelegram * EMS_RxTelegram, const int show_type) {
}
// print type
// if we're been given an index to the type string, use that
if (length) {
char buffer[16];
strlcat(output_str, ", ", sizeof(output_str));
if (show_type != -1) {
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));
@@ -3002,38 +3041,43 @@ void _printMessage(_EMS_RxTelegram * EMS_RxTelegram, const int show_type) {
* and then call its callback if there is one defined
*/
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
if (EMS_RxTelegram->data_length == 0) {
_printMessage(EMS_RxTelegram);
_printMessage(EMS_RxTelegram, type_index);
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;
if ((dest != EMS_ID_NONE) && (dest != EMS_Sys_Status.emsbusid)) {
_printMessage(EMS_RxTelegram);
_printMessage(EMS_RxTelegram, type_index);
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
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 {
_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
if ((EMS_Types[i].processType_cb) != nullptr) {
(void)EMS_Types[i].processType_cb(EMS_RxTelegram);
ems_Device_add_flags(EMS_Types[i].device_flag); // see if we need to flag something has changed
if ((EMS_Types[type_index].processType_cb) != nullptr) {
(void)EMS_Types[type_index].processType_cb(EMS_RxTelegram);
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;

View File

@@ -27,6 +27,7 @@
#define EMS_TYPE_UBAMonitorSlow 0x19 // 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_MC10Status 0x2A
#define EMS_TYPE_UBAParameterWW 0x33
#define EMS_TYPE_UBATotalUptimeMessage 0x14
#define EMS_TYPE_UBAFlags 0x35
@@ -109,6 +110,9 @@
#define EMS_OFFSET_RC20StatusMessage_setpoint 1 // setpoint 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_OFFSET_RC20Set_mode 23 // position of thermostat mode
#define EMS_OFFSET_RC20Set_temp 28 // position of thermostat setpoint temperature

View File

@@ -61,9 +61,11 @@
// MQTT for SM10/SM100/SM200 Solar Module
#define TOPIC_SM_DATA "sm_data" // topic name
#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_PUMP "pump" // pump active
#define SM_VALVESTATUS "valvestatus" // valve status
#define SM_ENERGYLASTHOUR "energylasthour" // energy last hour
#define SM_ENERGYTODAY "energytoday" // energy today
#define SM_ENERGYTOTAL "energytotal" // energy total

View File

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