mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 08:19:52 +03:00
code cleanup, thermostat mqtt changes, dallas sensor to 2 precision doubles
This commit is contained in:
@@ -5,12 +5,12 @@
|
||||
- "heat"
|
||||
- "off"
|
||||
|
||||
mode_state_topic: "home/ems-esp/thermostat_data"
|
||||
current_temperature_topic: "home/ems-esp/thermostat_data"
|
||||
temperature_state_topic: "home/ems-esp/thermostat_data"
|
||||
mode_state_topic: "home/ems-esp/thermostat_data1"
|
||||
current_temperature_topic: "home/ems-esp/thermostat_data1"
|
||||
temperature_state_topic: "home/ems-esp/thermostat_data1"
|
||||
|
||||
temperature_command_topic: "home/ems-esp/thermostat_cmd_temp"
|
||||
mode_command_topic: "home/ems-esp/thermostat_cmd_mode"
|
||||
temperature_command_topic: "home/ems-esp/thermostat_cmd_temp1"
|
||||
mode_command_topic: "home/ems-esp/thermostat_cmd_mode1"
|
||||
|
||||
mode_state_template: "{{ value_json.thermostat_mode }}"
|
||||
current_temperature_template: "{{ value_json.thermostat_currtemp }}"
|
||||
|
||||
@@ -417,8 +417,7 @@ uint8_t _getThermostatMode(uint8_t hc_num) {
|
||||
} else if (mode == 1) {
|
||||
thermoMode = 0;
|
||||
}
|
||||
}
|
||||
else { // default for all other thermostats
|
||||
} else { // default for all other thermostats
|
||||
if (mode == 0) {
|
||||
thermoMode = 3; // night
|
||||
} else if (mode == 1) {
|
||||
@@ -684,7 +683,7 @@ void showInfo() {
|
||||
for (uint8_t hc_num = 1; hc_num <= EMS_THERMOSTAT_MAXHC; hc_num++) {
|
||||
if (EMS_Mixing.hc[hc_num - 1].active) {
|
||||
myDebug_P(PSTR(" Mixing Circuit %d"), hc_num);
|
||||
_renderShortValue(" Current flow temperature", "C", EMS_Mixing.hc[hc_num - 1].flowTemp);
|
||||
_renderUShortValue(" Current flow temperature", "C", EMS_Mixing.hc[hc_num - 1].flowTemp);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -722,22 +721,22 @@ void publishSensorValues() {
|
||||
|
||||
bool hasdata = false;
|
||||
char label[8] = {0};
|
||||
// char valuestr[8] = {0}; // for formatting temp
|
||||
|
||||
// see if the sensor values have changed, if so send
|
||||
// see if the sensor values have changed, if so send it on
|
||||
for (uint8_t i = 0; i < EMSESP_Settings.dallas_sensors; i++) {
|
||||
double sensorValue = ds18.getValue(i);
|
||||
// round to 2 decimal places. from https://arduinojson.org/v6/faq/how-to-configure-the-serialization-of-floats/
|
||||
double sensorValue = (int)(ds18.getValue(i) * 100 + 0.5) / 100.0;
|
||||
if (sensorValue != DS18_DISCONNECTED && sensorValue != DS18_CRC_ERROR) {
|
||||
sprintf(label, PAYLOAD_EXTERNAL_SENSORS, (i + 1));
|
||||
// sensors[label] = _float_to_char(valuestr, sensorValue);
|
||||
sensors[label] = sensorValue; // TODO check if works
|
||||
hasdata = true;
|
||||
sensors[label] = sensorValue;
|
||||
hasdata = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasdata) {
|
||||
char data[200] = {0};
|
||||
serializeJson(doc, data, sizeof(data));
|
||||
myDebugLog("Publishing external sensor data via MQTT");
|
||||
myESP.mqttPublish(TOPIC_EXTERNAL_SENSORS, data);
|
||||
}
|
||||
}
|
||||
@@ -872,20 +871,16 @@ void publishValues(bool force) {
|
||||
|
||||
// handle the thermostat values
|
||||
if (ems_getThermostatEnabled()) {
|
||||
uint8_t total_active_hc = 0; // number of HCs
|
||||
bool hc_1_active = EMS_Thermostat.hc[EMS_THERMOSTAT_DEFAULTHC - 1].active; // do we have HC1 active?
|
||||
for (uint8_t hc_v = 1; hc_v <= EMS_THERMOSTAT_MAXHC; hc_v++) {
|
||||
_EMS_Thermostat_HC * thermostat = &EMS_Thermostat.hc[hc_v - 1];
|
||||
|
||||
// only send if we have an active Heating Circuit with real data
|
||||
if (thermostat->active) {
|
||||
total_active_hc++; // increase count for #HCs we encounter
|
||||
|
||||
// build new json object
|
||||
doc.clear();
|
||||
JsonObject rootThermostat = doc.to<JsonObject>();
|
||||
|
||||
rootThermostat[THERMOSTAT_HC] = _int_to_char(s, thermostat->hc); // heating circuit 1..4
|
||||
// rootThermostat[THERMOSTAT_HC] = _int_to_char(s, thermostat->hc); // heating circuit 1..4
|
||||
|
||||
// different logic depending on thermostat types
|
||||
if (ems_getThermostatModel() == EMS_MODEL_EASY) {
|
||||
@@ -949,14 +944,10 @@ void publishValues(bool force) {
|
||||
if ((previousThermostatPublishCRC != fchecksum) || force) {
|
||||
previousThermostatPublishCRC = fchecksum;
|
||||
char thermostat_topicname[20];
|
||||
strlcpy(thermostat_topicname, TOPIC_THERMOSTAT_DATA, sizeof(thermostat_topicname)); // "thermostat_data"
|
||||
// if we have more than 1 active Heating Circuit
|
||||
// or this is single HC and its not HC1
|
||||
// append topic name with the HC number
|
||||
if ((total_active_hc > 1) || ((total_active_hc == 1) && (!hc_1_active))) {
|
||||
char buffer[4];
|
||||
strlcat(thermostat_topicname, itoa(total_active_hc, buffer, 10), sizeof(thermostat_topicname));
|
||||
}
|
||||
char buffer[4];
|
||||
// "thermostat_data" + Heating Cicruit #
|
||||
strlcpy(thermostat_topicname, TOPIC_THERMOSTAT_DATA, sizeof(thermostat_topicname));
|
||||
strlcat(thermostat_topicname, itoa(hc_v, buffer, 10), sizeof(thermostat_topicname));
|
||||
myDebugLog("Publishing thermostat data via MQTT");
|
||||
myESP.mqttPublish(thermostat_topicname, data);
|
||||
}
|
||||
@@ -1456,7 +1447,8 @@ void TelnetCommandCallback(uint8_t wc, const char * commandLine) {
|
||||
}
|
||||
|
||||
if (strcmp(first_cmd, "publish") == 0) {
|
||||
publishValues(true);
|
||||
do_publishValues();
|
||||
do_publishSensorValues();
|
||||
ok = true;
|
||||
}
|
||||
|
||||
@@ -1666,33 +1658,25 @@ void MQTTCallback(unsigned int type, const char * topic, const char * message) {
|
||||
// subscribe to the 4 heating circuits
|
||||
char topic_s[50];
|
||||
char buffer[4];
|
||||
|
||||
// subscribe to the normal batch to be backwards compatible
|
||||
myESP.mqttSubscribe(TOPIC_THERMOSTAT_CMD_TEMP);
|
||||
myESP.mqttSubscribe(TOPIC_THERMOSTAT_CMD_MODE);
|
||||
myESP.mqttSubscribe(TOPIC_THERMOSTAT_CMD_DAYTEMP);
|
||||
myESP.mqttSubscribe(TOPIC_THERMOSTAT_CMD_NIGHTTEMP);
|
||||
myESP.mqttSubscribe(TOPIC_THERMOSTAT_CMD_HOLIDAYTEMP);
|
||||
|
||||
for (uint8_t hc = 1; hc <= EMS_THERMOSTAT_MAXHC; hc++) {
|
||||
strlcpy(topic_s, TOPIC_THERMOSTAT_CMD_TEMP, sizeof(topic_s));
|
||||
strlcat(topic_s, itoa(hc, buffer, 10), sizeof(topic_s)); // add 1-4 at the end
|
||||
strlcat(topic_s, itoa(hc, buffer, 10), sizeof(topic_s));
|
||||
myESP.mqttSubscribe(topic_s);
|
||||
|
||||
strlcpy(topic_s, TOPIC_THERMOSTAT_CMD_MODE, sizeof(topic_s));
|
||||
strlcat(topic_s, itoa(hc, buffer, 10), sizeof(topic_s)); // add 1-4 at the end
|
||||
strlcat(topic_s, itoa(hc, buffer, 10), sizeof(topic_s));
|
||||
myESP.mqttSubscribe(topic_s);
|
||||
|
||||
strlcpy(topic_s, TOPIC_THERMOSTAT_CMD_DAYTEMP, sizeof(topic_s));
|
||||
strlcat(topic_s, itoa(hc, buffer, 10), sizeof(topic_s)); // add 1-4 at the end
|
||||
strlcat(topic_s, itoa(hc, buffer, 10), sizeof(topic_s));
|
||||
myESP.mqttSubscribe(topic_s);
|
||||
|
||||
strlcpy(topic_s, TOPIC_THERMOSTAT_CMD_NIGHTTEMP, sizeof(topic_s));
|
||||
strlcat(topic_s, itoa(hc, buffer, 10), sizeof(topic_s)); // add 1-4 at the end
|
||||
strlcat(topic_s, itoa(hc, buffer, 10), sizeof(topic_s));
|
||||
myESP.mqttSubscribe(topic_s);
|
||||
|
||||
strlcpy(topic_s, TOPIC_THERMOSTAT_CMD_HOLIDAYTEMP, sizeof(topic_s));
|
||||
strlcat(topic_s, itoa(hc, buffer, 10), sizeof(topic_s)); // add 1-4 at the end
|
||||
strlcat(topic_s, itoa(hc, buffer, 10), sizeof(topic_s));
|
||||
myESP.mqttSubscribe(topic_s);
|
||||
}
|
||||
|
||||
@@ -2187,16 +2171,17 @@ void loop() {
|
||||
// the main loop
|
||||
myESP.loop();
|
||||
|
||||
// check Dallas sensors, every 2 seconds
|
||||
// check Dallas sensors, using same schedule as publish_time (default 2 mins)
|
||||
// these values are published to MQTT separately via the timer publishSensorValuesTimer
|
||||
if (EMSESP_Settings.dallas_sensors != 0) {
|
||||
ds18.loop();
|
||||
}
|
||||
|
||||
// publish the values to MQTT, only if the values have changed
|
||||
// publish all the values to MQTT, only if the values have changed
|
||||
// although we don't want to publish when doing a deep scan of the thermostat
|
||||
if (ems_getEmsRefreshed() && (scanThermostat_count == 0)) {
|
||||
publishValues(false);
|
||||
do_publishSensorValues();
|
||||
ems_setEmsRefreshed(false); // reset
|
||||
}
|
||||
|
||||
|
||||
51
src/ems.cpp
51
src/ems.cpp
@@ -210,7 +210,7 @@ _EMS_Thermostat EMS_Thermostat; // for thermostat
|
||||
_EMS_SolarModule EMS_SolarModule; // for solar modules
|
||||
_EMS_HeatPump EMS_HeatPump; // for heatpumps
|
||||
_EMS_Mixing EMS_Mixing; // for mixing devices
|
||||
_EMS_Other EMS_Other; // for other known EMS devices
|
||||
_EMS_Other EMS_Other; // for other known EMS devices
|
||||
|
||||
// CRC lookup table with poly 12 for faster checking
|
||||
const uint8_t ems_crc_table[] = {0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24, 0x26,
|
||||
@@ -1489,13 +1489,12 @@ void _process_EasyStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
|
||||
|
||||
void _process_MMPLUSStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
|
||||
uint8_t hc = (EMS_RxTelegram->type - EMS_TYPE_MMPLUSStatusMessage_HC1); // 0 to 3
|
||||
if (hc > 4) {
|
||||
if (hc > EMS_THERMOSTAT_MAXHC) {
|
||||
return; // invalid type
|
||||
}
|
||||
EMS_Mixing.hc[hc].active = true;
|
||||
|
||||
if (EMS_RxTelegram->data_length == 1) {
|
||||
|
||||
} else if (EMS_RxTelegram->data_length > 8) {
|
||||
EMS_Mixing.hc[hc].flowTemp = _toShort(EMS_OFFSET_MMPLUSStatusMessage_flow_temp);
|
||||
}
|
||||
@@ -1508,7 +1507,7 @@ void _process_MMPLUSStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
|
||||
void _process_RCPLUSStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
|
||||
// figure out which heating circuit
|
||||
uint8_t hc = (EMS_RxTelegram->type - EMS_TYPE_RCPLUSStatusMessage_HC1); // 0 to 3
|
||||
if (hc > 4) {
|
||||
if (hc > EMS_THERMOSTAT_MAXHC) {
|
||||
return; // invalid type
|
||||
}
|
||||
EMS_Thermostat.hc[hc].active = true;
|
||||
@@ -1567,7 +1566,7 @@ void _process_JunkersStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
|
||||
EMS_Thermostat.hc[hc].curr_roomTemp = _toShort(EMS_OFFSET_JunkersStatusMessage_curr); // value is * 10
|
||||
EMS_Thermostat.hc[hc].setpoint_roomTemp = _toShort(EMS_OFFSET_JunkersStatusMessage_setpoint); // value is * 10
|
||||
EMS_Thermostat.hc[hc].mode = _toByte(EMS_OFFSET_JunkersStatusMessage_mode);
|
||||
EMS_Sys_Status.emsRefreshed = true; // triggers a send the values back via MQTT
|
||||
EMS_Sys_Status.emsRefreshed = true; // triggers a send the values back via MQTT
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2203,47 +2202,12 @@ void _process_Version(_EMS_RxTelegram * EMS_RxTelegram) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* See if we have a Junkers Heatronic 3 compatible device
|
||||
* Do a read command for the version with the src having the MSB set
|
||||
*/
|
||||
void _ems_detectJunkers() {
|
||||
#ifdef JUNKERS_DETECT
|
||||
char s[30] = {0};
|
||||
snprintf(s, sizeof(s), "%02X %02X %02X 00 %02X", (EMS_ID_ME | 0x80), (EMS_ID_BOILER | 0x080), EMS_TYPE_Version, EMS_MAX_TELEGRAM_LENGTH);
|
||||
ems_sendRawTelegram(s);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Figure out the boiler and thermostat types
|
||||
*/
|
||||
void ems_discoverModels() {
|
||||
myDebug_P(PSTR("Starting auto discover of EMS devices..."));
|
||||
ems_doReadCommand(EMS_TYPE_UBADevices, EMS_ID_BOILER);
|
||||
|
||||
// ems_startupTelegrams();
|
||||
|
||||
// TODO remove this part eventually, ems_discoverModels()
|
||||
/*
|
||||
|
||||
// boiler...
|
||||
// ems_doReadCommand(EMS_TYPE_Version, EMS_ID_BOILER);
|
||||
// _ems_detectJunkers(); // special hack for Junkers detection
|
||||
|
||||
ems_doReadCommand(EMS_TYPE_Version, EMS_ID_SM); // check if there is Solar Module available
|
||||
ems_doReadCommand(EMS_TYPE_Version, EMS_ID_HP); // check if there is HeatPump Module available
|
||||
|
||||
// thermostat...
|
||||
// if it hasn't been set, auto discover it
|
||||
if (EMS_Thermostat.device_id == EMS_ID_NONE) {
|
||||
ems_scanDevices(); // auto-discover it
|
||||
} else {
|
||||
// set the model as hardcoded (see my_devices.h) and fetch the version and product id
|
||||
ems_doReadCommand(EMS_TYPE_Version, EMS_Thermostat.device_id);
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2592,9 +2556,6 @@ void ems_scanDevices() {
|
||||
for (uint8_t device_id : Device_Ids) {
|
||||
ems_doReadCommand(EMS_TYPE_Version, device_id);
|
||||
}
|
||||
|
||||
// add a check for Junkers onto the queue
|
||||
_ems_detectJunkers();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2845,7 +2806,7 @@ void ems_setThermostatTemp(float temperature, uint8_t hc_num, uint8_t temptype)
|
||||
return;
|
||||
}
|
||||
|
||||
if (hc_num < 1 || hc_num > 4) {
|
||||
if (hc_num < 1 || hc_num > EMS_THERMOSTAT_MAXHC) {
|
||||
myDebug_P(PSTR("Invalid HC number"));
|
||||
return;
|
||||
}
|
||||
@@ -2955,7 +2916,7 @@ void ems_setThermostatMode(uint8_t mode, uint8_t hc_num) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (hc_num < 1 || hc_num > 4) {
|
||||
if (hc_num < 1 || hc_num > EMS_THERMOSTAT_MAXHC) {
|
||||
myDebug_P(PSTR("Invalid HC number"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -276,7 +276,6 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
uint8_t product_id;
|
||||
uint8_t device_id;
|
||||
char model_string[50];
|
||||
} _Mixing_Device;
|
||||
|
||||
@@ -378,10 +377,10 @@ typedef struct {
|
||||
uint8_t model_id;
|
||||
uint8_t product_id;
|
||||
char version[10];
|
||||
uint8_t hc; // heating circuit 1,2, 3 or 4
|
||||
bool active; // true if there is data for this HC
|
||||
uint8_t hc; // heating circuit 1, 2, 3 or 4
|
||||
bool active; // true if there is data for this HC
|
||||
|
||||
uint8_t flowTemp;
|
||||
uint16_t flowTemp;
|
||||
} _EMS_Mixing_HC;
|
||||
|
||||
// Mixer data
|
||||
|
||||
Reference in New Issue
Block a user