mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 16:29:51 +03:00
SM10 MQTT support
This commit is contained in:
@@ -396,6 +396,7 @@ void showInfo() {
|
||||
_renderFloatValue(" Collector temperature", "C", EMS_Other.SM10collectorTemp);
|
||||
_renderFloatValue(" Bottom temperature", "C", EMS_Other.SM10bottomTemp);
|
||||
_renderIntValue(" Pump modulation", "%", EMS_Other.SM10pumpModulation);
|
||||
_renderBoolValue(" Pump active", EMS_Other.SM10pump);
|
||||
}
|
||||
|
||||
myDebug(""); // newline
|
||||
@@ -486,6 +487,7 @@ void publishValues(bool force) {
|
||||
static uint8_t last_boilerActive = 0xFF; // for remembering last setting of the tap water or heating on/off
|
||||
static uint32_t previousBoilerPublishCRC = 0; // CRC check for boiler values
|
||||
static uint32_t previousThermostatPublishCRC = 0; // CRC check for thermostat values
|
||||
static uint32_t previousOtherPublishCRC = 0; // CRC check for other values (e.g. SM10)
|
||||
|
||||
JsonObject rootBoiler = doc.to<JsonObject>();
|
||||
|
||||
@@ -595,6 +597,36 @@ void publishValues(bool force) {
|
||||
myESP.mqttPublish(TOPIC_THERMOSTAT_DATA, data);
|
||||
}
|
||||
}
|
||||
|
||||
// handle the other values separately
|
||||
// For SM10 Solar Module
|
||||
if (EMS_Other.SM10) {
|
||||
// build new json object
|
||||
doc.clear();
|
||||
JsonObject rootSM10 = doc.to<JsonObject>();
|
||||
|
||||
rootSM10[SM10_COLLECTORTEMP] = _float_to_char(s, EMS_Other.SM10collectorTemp);
|
||||
rootSM10[SM10_BOTTOMTEMP] = _float_to_char(s, EMS_Other.SM10bottomTemp);
|
||||
rootSM10[SM10_PUMPMODULATION] = _int_to_char(s, EMS_Other.SM10pumpModulation);
|
||||
rootSM10[SM10_PUMP] = _bool_to_char(s, EMS_Other.SM10pump);
|
||||
|
||||
data[0] = '\0'; // reset data for next package
|
||||
serializeJson(doc, data, sizeof(data));
|
||||
|
||||
// calculate new CRC
|
||||
crc.reset();
|
||||
for (size_t i = 0; i < measureJson(doc) - 1; i++) {
|
||||
crc.update(data[i]);
|
||||
}
|
||||
fchecksum = crc.finalize();
|
||||
if ((previousOtherPublishCRC != fchecksum) || force) {
|
||||
previousOtherPublishCRC = fchecksum;
|
||||
myDebugLog("Publishing SM10 data via MQTT");
|
||||
|
||||
// send values via MQTT
|
||||
myESP.mqttPublish(TOPIC_SM10_DATA, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sets the shower timer on/off
|
||||
@@ -1387,6 +1419,7 @@ void loop() {
|
||||
myESP.loop();
|
||||
|
||||
// check Dallas sensors, every 2 seconds
|
||||
// these values are published to MQTT seperately via the timer publishSensorValuesTimer
|
||||
if (EMSESP_Status.dallas_sensors != 0) {
|
||||
ds18.loop();
|
||||
}
|
||||
|
||||
117
src/ems.cpp
117
src/ems.cpp
@@ -238,6 +238,7 @@ void ems_init() {
|
||||
EMS_Other.SM10collectorTemp = EMS_VALUE_FLOAT_NOTSET; // collector temp from SM10
|
||||
EMS_Other.SM10bottomTemp = EMS_VALUE_FLOAT_NOTSET; // bottom temp from SM10
|
||||
EMS_Other.SM10pumpModulation = EMS_VALUE_INT_NOTSET; // modulation solar pump SM10
|
||||
EMS_Other.SM10pump = EMS_VALUE_INT_NOTSET; // pump active
|
||||
|
||||
// calculated values
|
||||
EMS_Boiler.tapwaterActive = EMS_VALUE_INT_NOTSET; // Hot tap water is on/off
|
||||
@@ -1143,6 +1144,51 @@ void _process_RCOutdoorTempMessage(uint8_t src, uint8_t * data, uint8_t length)
|
||||
// add support here if you're reading external sensors
|
||||
}
|
||||
|
||||
/*
|
||||
* SM10Monitor - type 0x97
|
||||
*/
|
||||
void _process_SM10Monitor(uint8_t src, uint8_t * data, uint8_t length) {
|
||||
EMS_Other.SM10collectorTemp = _toFloat(2, data); // collector temp from SM10
|
||||
EMS_Other.SM10bottomTemp = _toFloat(5, data); // bottom temp from SM10
|
||||
EMS_Other.SM10pumpModulation = data[4]; // modulation solar pump
|
||||
EMS_Other.SM10pump = bitRead(data[6], 1); // active if bit 1 is set (to 1)
|
||||
|
||||
EMS_Sys_Status.emsRefreshed = true; // triggers a send the values back via MQTT
|
||||
}
|
||||
|
||||
/**
|
||||
* UBASetPoint 0x1A
|
||||
*/
|
||||
void _process_SetPoints(uint8_t src, uint8_t * data, uint8_t length) {
|
||||
/*
|
||||
if (EMS_Sys_Status.emsLogging == EMS_SYS_LOGGING_VERBOSE) {
|
||||
if (length != 0) {
|
||||
uint8_t setpoint = data[0];
|
||||
uint8_t hk_power = data[1];
|
||||
uint8_t ww_power = data[2];
|
||||
myDebug(" SetPoint=%d, hk_power=%d, ww_power=%d", setpoint, hk_power, ww_power);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* process_RCTime - type 0x06 - date and time from a thermostat - 14 bytes long
|
||||
* common for all thermostats
|
||||
*/
|
||||
void _process_RCTime(uint8_t src, uint8_t * data, uint8_t length) {
|
||||
if ((EMS_Thermostat.model_id == EMS_MODEL_EASY) || (EMS_Thermostat.model_id == EMS_MODEL_BOSCHEASY)) {
|
||||
return; // not supported
|
||||
}
|
||||
|
||||
EMS_Thermostat.hour = data[2];
|
||||
EMS_Thermostat.minute = data[4];
|
||||
EMS_Thermostat.second = data[5];
|
||||
EMS_Thermostat.day = data[3];
|
||||
EMS_Thermostat.month = data[1];
|
||||
EMS_Thermostat.year = data[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* type 0x02 - get the firmware version and type of an EMS device
|
||||
* look up known devices via the product id and setup if not already set
|
||||
@@ -1272,48 +1318,6 @@ void _process_Version(uint8_t src, uint8_t * data, uint8_t length) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SM10Monitor - type 0x97
|
||||
*/
|
||||
void _process_SM10Monitor(uint8_t src, uint8_t * data, uint8_t length) {
|
||||
EMS_Other.SM10collectorTemp = _toFloat(2, data); // collector temp from SM10
|
||||
EMS_Other.SM10bottomTemp = _toFloat(5, data); // bottom temp from SM10
|
||||
EMS_Other.SM10pumpModulation = data[4]; // modulation solar pump
|
||||
}
|
||||
|
||||
/**
|
||||
* UBASetPoint 0x1A
|
||||
*/
|
||||
void _process_SetPoints(uint8_t src, uint8_t * data, uint8_t length) {
|
||||
/*
|
||||
if (EMS_Sys_Status.emsLogging == EMS_SYS_LOGGING_VERBOSE) {
|
||||
if (length != 0) {
|
||||
uint8_t setpoint = data[0];
|
||||
uint8_t hk_power = data[1];
|
||||
uint8_t ww_power = data[2];
|
||||
myDebug(" SetPoint=%d, hk_power=%d, ww_power=%d", setpoint, hk_power, ww_power);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* process_RCTime - type 0x06 - date and time from a thermostat - 14 bytes long
|
||||
* common for all thermostats
|
||||
*/
|
||||
void _process_RCTime(uint8_t src, uint8_t * data, uint8_t length) {
|
||||
if ((EMS_Thermostat.model_id == EMS_MODEL_EASY) || (EMS_Thermostat.model_id == EMS_MODEL_BOSCHEASY)) {
|
||||
return; // not supported
|
||||
}
|
||||
|
||||
EMS_Thermostat.hour = data[2];
|
||||
EMS_Thermostat.minute = data[4];
|
||||
EMS_Thermostat.second = data[5];
|
||||
EMS_Thermostat.day = data[3];
|
||||
EMS_Thermostat.month = data[1];
|
||||
EMS_Thermostat.year = data[0];
|
||||
}
|
||||
|
||||
/*
|
||||
* Figure out the boiler and thermostat types
|
||||
*/
|
||||
@@ -1486,9 +1490,9 @@ char * ems_getThermostatDescription(char * buffer) {
|
||||
if (!ems_getThermostatEnabled()) {
|
||||
strlcpy(buffer, "<not enabled>", size);
|
||||
} else {
|
||||
// find the boiler details
|
||||
int i = 0;
|
||||
bool found = false;
|
||||
int i = 0;
|
||||
bool found = false;
|
||||
char tmp[6] = {0};
|
||||
|
||||
// scan through known ID types
|
||||
while (i < _Thermostat_Types_max) {
|
||||
@@ -1498,16 +1502,15 @@ char * ems_getThermostatDescription(char * buffer) {
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (found) {
|
||||
strlcpy(buffer, Thermostat_Types[i].model_string, size);
|
||||
} else {
|
||||
strlcpy(buffer, "Generic Type", size);
|
||||
strlcpy(buffer, "TypeID: 0x", size);
|
||||
strlcat(buffer, _hextoa(EMS_Thermostat.type_id, tmp), size);
|
||||
}
|
||||
|
||||
char tmp[6] = {0};
|
||||
strlcat(buffer, " [Type ID: 0x", size);
|
||||
strlcat(buffer, _hextoa(EMS_Thermostat.type_id, tmp), size);
|
||||
strlcat(buffer, "] Product ID:", size);
|
||||
strlcat(buffer, " Product ID:", size);
|
||||
strlcat(buffer, itoa(EMS_Thermostat.product_id, tmp, 10), size);
|
||||
strlcat(buffer, " Version:", size);
|
||||
strlcat(buffer, EMS_Thermostat.version, size);
|
||||
@@ -1524,9 +1527,9 @@ char * ems_getBoilerDescription(char * buffer) {
|
||||
if (!ems_getBoilerEnabled()) {
|
||||
strlcpy(buffer, "<not enabled>", size);
|
||||
} else {
|
||||
// find the boiler details
|
||||
int i = 0;
|
||||
bool found = false;
|
||||
int i = 0;
|
||||
bool found = false;
|
||||
char tmp[6] = {0};
|
||||
|
||||
// scan through known ID types
|
||||
while (i < _Boiler_Types_max) {
|
||||
@@ -1539,13 +1542,11 @@ char * ems_getBoilerDescription(char * buffer) {
|
||||
if (found) {
|
||||
strlcpy(buffer, Boiler_Types[i].model_string, size);
|
||||
} else {
|
||||
strlcpy(buffer, "Generic Type", size);
|
||||
strlcpy(buffer, "TypeID: 0x", size);
|
||||
strlcat(buffer, _hextoa(EMS_Boiler.type_id, tmp), size);
|
||||
}
|
||||
|
||||
char tmp[6] = {0};
|
||||
strlcat(buffer, " [Type ID: 0x", size);
|
||||
strlcat(buffer, _hextoa(EMS_Boiler.type_id, tmp), size);
|
||||
strlcat(buffer, "] Product ID:", size);
|
||||
strlcat(buffer, " Product ID:", size);
|
||||
strlcat(buffer, itoa(EMS_Boiler.product_id, tmp, 10), size);
|
||||
strlcat(buffer, " Version:", size);
|
||||
strlcat(buffer, EMS_Boiler.version, size);
|
||||
|
||||
@@ -232,6 +232,7 @@ typedef struct {
|
||||
float SM10collectorTemp; // collector temp from SM10
|
||||
float SM10bottomTemp; // bottom temp from SM10
|
||||
uint8_t SM10pumpModulation; // modulation solar pump
|
||||
uint8_t SM10pump; // pump active
|
||||
} _EMS_Other;
|
||||
|
||||
// Thermostat data
|
||||
@@ -308,7 +309,7 @@ void ems_startupTelegrams();
|
||||
|
||||
// private functions
|
||||
uint8_t _crcCalculator(uint8_t * data, uint8_t len);
|
||||
void _processType(_EMS_RxTelegram *EMS_RxTelegram);
|
||||
void _processType(_EMS_RxTelegram * EMS_RxTelegram);
|
||||
void _debugPrintPackage(const char * prefix, _EMS_RxTelegram * EMS_RxTelegram, const char * color);
|
||||
void _ems_clearTxData();
|
||||
int _ems_findBoilerModel(uint8_t model_id);
|
||||
|
||||
@@ -39,6 +39,13 @@
|
||||
#define TOPIC_BOILER_CMD_WWTEMP "boiler_cmd_wwtemp" // for received boiler wwtemp changes via MQTT
|
||||
#define TOPIC_BOILER_CMD_COMFORT "boiler_cmd_comfort" // for received boiler ww comfort setting via MQTT
|
||||
|
||||
// MQTT for SM10 Solar Module
|
||||
#define TOPIC_SM10_DATA "sm10_data" // topic name
|
||||
#define SM10_COLLECTORTEMP "temp" // collector temp
|
||||
#define SM10_BOTTOMTEMP "bottomtemp" // bottom temp
|
||||
#define SM10_PUMPMODULATION "pumpmodulation" // pump modulation
|
||||
#define SM10_PUMP "pump" // pump active
|
||||
|
||||
// shower time
|
||||
#define TOPIC_SHOWERTIME "showertime" // for sending shower time results
|
||||
#define TOPIC_SHOWER_TIMER "shower_timer" // toggle switch for enabling the shower logic
|
||||
@@ -49,6 +56,7 @@
|
||||
#define TOPIC_EXTERNAL_SENSORS "sensors" // for sending sensor values to MQTT
|
||||
#define PAYLOAD_EXTERNAL_SENSORS "temp_%d" // for formatting the payload for each external dallas sensor
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// THESE DEFAULT VALUES CAN ALSO BE SET AND STORED WITHTIN THE APPLICATION (see 'set' command) //
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Reference in New Issue
Block a user