code cleanup, thermostat mqtt changes, dallas sensor to 2 precision doubles

This commit is contained in:
Paul
2019-10-06 21:55:28 +02:00
parent f24812d71f
commit a5719800a3
4 changed files with 40 additions and 95 deletions

View File

@@ -5,12 +5,12 @@
- "heat" - "heat"
- "off" - "off"
mode_state_topic: "home/ems-esp/thermostat_data" mode_state_topic: "home/ems-esp/thermostat_data1"
current_temperature_topic: "home/ems-esp/thermostat_data" current_temperature_topic: "home/ems-esp/thermostat_data1"
temperature_state_topic: "home/ems-esp/thermostat_data" temperature_state_topic: "home/ems-esp/thermostat_data1"
temperature_command_topic: "home/ems-esp/thermostat_cmd_temp" temperature_command_topic: "home/ems-esp/thermostat_cmd_temp1"
mode_command_topic: "home/ems-esp/thermostat_cmd_mode" mode_command_topic: "home/ems-esp/thermostat_cmd_mode1"
mode_state_template: "{{ value_json.thermostat_mode }}" mode_state_template: "{{ value_json.thermostat_mode }}"
current_temperature_template: "{{ value_json.thermostat_currtemp }}" current_temperature_template: "{{ value_json.thermostat_currtemp }}"

View File

@@ -417,8 +417,7 @@ uint8_t _getThermostatMode(uint8_t hc_num) {
} else if (mode == 1) { } else if (mode == 1) {
thermoMode = 0; thermoMode = 0;
} }
} } else { // default for all other thermostats
else { // default for all other thermostats
if (mode == 0) { if (mode == 0) {
thermoMode = 3; // night thermoMode = 3; // night
} else if (mode == 1) { } else if (mode == 1) {
@@ -684,7 +683,7 @@ void showInfo() {
for (uint8_t hc_num = 1; hc_num <= EMS_THERMOSTAT_MAXHC; hc_num++) { for (uint8_t hc_num = 1; hc_num <= EMS_THERMOSTAT_MAXHC; hc_num++) {
if (EMS_Mixing.hc[hc_num - 1].active) { if (EMS_Mixing.hc[hc_num - 1].active) {
myDebug_P(PSTR(" Mixing Circuit %d"), hc_num); 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,15 +721,14 @@ void publishSensorValues() {
bool hasdata = false; bool hasdata = false;
char label[8] = {0}; 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++) { 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) { if (sensorValue != DS18_DISCONNECTED && sensorValue != DS18_CRC_ERROR) {
sprintf(label, PAYLOAD_EXTERNAL_SENSORS, (i + 1)); sprintf(label, PAYLOAD_EXTERNAL_SENSORS, (i + 1));
// sensors[label] = _float_to_char(valuestr, sensorValue); sensors[label] = sensorValue;
sensors[label] = sensorValue; // TODO check if works
hasdata = true; hasdata = true;
} }
} }
@@ -738,6 +736,7 @@ void publishSensorValues() {
if (hasdata) { if (hasdata) {
char data[200] = {0}; char data[200] = {0};
serializeJson(doc, data, sizeof(data)); serializeJson(doc, data, sizeof(data));
myDebugLog("Publishing external sensor data via MQTT");
myESP.mqttPublish(TOPIC_EXTERNAL_SENSORS, data); myESP.mqttPublish(TOPIC_EXTERNAL_SENSORS, data);
} }
} }
@@ -872,20 +871,16 @@ void publishValues(bool force) {
// handle the thermostat values // handle the thermostat values
if (ems_getThermostatEnabled()) { 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++) { for (uint8_t hc_v = 1; hc_v <= EMS_THERMOSTAT_MAXHC; hc_v++) {
_EMS_Thermostat_HC * thermostat = &EMS_Thermostat.hc[hc_v - 1]; _EMS_Thermostat_HC * thermostat = &EMS_Thermostat.hc[hc_v - 1];
// only send if we have an active Heating Circuit with real data // only send if we have an active Heating Circuit with real data
if (thermostat->active) { if (thermostat->active) {
total_active_hc++; // increase count for #HCs we encounter
// build new json object // build new json object
doc.clear(); doc.clear();
JsonObject rootThermostat = doc.to<JsonObject>(); 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 // different logic depending on thermostat types
if (ems_getThermostatModel() == EMS_MODEL_EASY) { if (ems_getThermostatModel() == EMS_MODEL_EASY) {
@@ -949,14 +944,10 @@ void publishValues(bool force) {
if ((previousThermostatPublishCRC != fchecksum) || force) { if ((previousThermostatPublishCRC != fchecksum) || force) {
previousThermostatPublishCRC = fchecksum; previousThermostatPublishCRC = fchecksum;
char thermostat_topicname[20]; 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]; char buffer[4];
strlcat(thermostat_topicname, itoa(total_active_hc, buffer, 10), sizeof(thermostat_topicname)); // "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"); myDebugLog("Publishing thermostat data via MQTT");
myESP.mqttPublish(thermostat_topicname, data); myESP.mqttPublish(thermostat_topicname, data);
} }
@@ -1456,7 +1447,8 @@ void TelnetCommandCallback(uint8_t wc, const char * commandLine) {
} }
if (strcmp(first_cmd, "publish") == 0) { if (strcmp(first_cmd, "publish") == 0) {
publishValues(true); do_publishValues();
do_publishSensorValues();
ok = true; ok = true;
} }
@@ -1666,33 +1658,25 @@ void MQTTCallback(unsigned int type, const char * topic, const char * message) {
// subscribe to the 4 heating circuits // subscribe to the 4 heating circuits
char topic_s[50]; char topic_s[50];
char buffer[4]; 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++) { for (uint8_t hc = 1; hc <= EMS_THERMOSTAT_MAXHC; hc++) {
strlcpy(topic_s, TOPIC_THERMOSTAT_CMD_TEMP, sizeof(topic_s)); 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); myESP.mqttSubscribe(topic_s);
strlcpy(topic_s, TOPIC_THERMOSTAT_CMD_MODE, sizeof(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); myESP.mqttSubscribe(topic_s);
strlcpy(topic_s, TOPIC_THERMOSTAT_CMD_DAYTEMP, sizeof(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); myESP.mqttSubscribe(topic_s);
strlcpy(topic_s, TOPIC_THERMOSTAT_CMD_NIGHTTEMP, sizeof(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); myESP.mqttSubscribe(topic_s);
strlcpy(topic_s, TOPIC_THERMOSTAT_CMD_HOLIDAYTEMP, sizeof(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); myESP.mqttSubscribe(topic_s);
} }
@@ -2187,16 +2171,17 @@ void loop() {
// the main loop // the main loop
myESP.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 // these values are published to MQTT separately via the timer publishSensorValuesTimer
if (EMSESP_Settings.dallas_sensors != 0) { if (EMSESP_Settings.dallas_sensors != 0) {
ds18.loop(); 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 // although we don't want to publish when doing a deep scan of the thermostat
if (ems_getEmsRefreshed() && (scanThermostat_count == 0)) { if (ems_getEmsRefreshed() && (scanThermostat_count == 0)) {
publishValues(false); publishValues(false);
do_publishSensorValues();
ems_setEmsRefreshed(false); // reset ems_setEmsRefreshed(false); // reset
} }

View File

@@ -1489,13 +1489,12 @@ void _process_EasyStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
void _process_MMPLUSStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) { void _process_MMPLUSStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
uint8_t hc = (EMS_RxTelegram->type - EMS_TYPE_MMPLUSStatusMessage_HC1); // 0 to 3 uint8_t hc = (EMS_RxTelegram->type - EMS_TYPE_MMPLUSStatusMessage_HC1); // 0 to 3
if (hc > 4) { if (hc > EMS_THERMOSTAT_MAXHC) {
return; // invalid type return; // invalid type
} }
EMS_Mixing.hc[hc].active = true; EMS_Mixing.hc[hc].active = true;
if (EMS_RxTelegram->data_length == 1) { if (EMS_RxTelegram->data_length == 1) {
} else if (EMS_RxTelegram->data_length > 8) { } else if (EMS_RxTelegram->data_length > 8) {
EMS_Mixing.hc[hc].flowTemp = _toShort(EMS_OFFSET_MMPLUSStatusMessage_flow_temp); 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) { void _process_RCPLUSStatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
// figure out which heating circuit // figure out which heating circuit
uint8_t hc = (EMS_RxTelegram->type - EMS_TYPE_RCPLUSStatusMessage_HC1); // 0 to 3 uint8_t hc = (EMS_RxTelegram->type - EMS_TYPE_RCPLUSStatusMessage_HC1); // 0 to 3
if (hc > 4) { if (hc > EMS_THERMOSTAT_MAXHC) {
return; // invalid type return; // invalid type
} }
EMS_Thermostat.hc[hc].active = true; EMS_Thermostat.hc[hc].active = true;
@@ -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 * Figure out the boiler and thermostat types
*/ */
void ems_discoverModels() { void ems_discoverModels() {
myDebug_P(PSTR("Starting auto discover of EMS devices...")); myDebug_P(PSTR("Starting auto discover of EMS devices..."));
ems_doReadCommand(EMS_TYPE_UBADevices, EMS_ID_BOILER); 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) { for (uint8_t device_id : Device_Ids) {
ems_doReadCommand(EMS_TYPE_Version, device_id); 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; return;
} }
if (hc_num < 1 || hc_num > 4) { if (hc_num < 1 || hc_num > EMS_THERMOSTAT_MAXHC) {
myDebug_P(PSTR("Invalid HC number")); myDebug_P(PSTR("Invalid HC number"));
return; return;
} }
@@ -2955,7 +2916,7 @@ void ems_setThermostatMode(uint8_t mode, uint8_t hc_num) {
return; return;
} }
if (hc_num < 1 || hc_num > 4) { if (hc_num < 1 || hc_num > EMS_THERMOSTAT_MAXHC) {
myDebug_P(PSTR("Invalid HC number")); myDebug_P(PSTR("Invalid HC number"));
return; return;
} }

View File

@@ -276,7 +276,6 @@ typedef struct {
typedef struct { typedef struct {
uint8_t product_id; uint8_t product_id;
uint8_t device_id;
char model_string[50]; char model_string[50];
} _Mixing_Device; } _Mixing_Device;
@@ -378,10 +377,10 @@ typedef struct {
uint8_t model_id; uint8_t model_id;
uint8_t product_id; uint8_t product_id;
char version[10]; char version[10];
uint8_t hc; // heating circuit 1,2, 3 or 4 uint8_t hc; // heating circuit 1, 2, 3 or 4
bool active; // true if there is data for this HC bool active; // true if there is data for this HC
uint8_t flowTemp; uint16_t flowTemp;
} _EMS_Mixing_HC; } _EMS_Mixing_HC;
// Mixer data // Mixer data