From d3885f735deb5a51077043e64e89dc263c97a017 Mon Sep 17 00:00:00 2001 From: proddy Date: Fri, 15 Mar 2019 21:12:00 +0100 Subject: [PATCH] merged in Dallas changes from JewelZB --- CHANGELOG.md | 1 + src/ds18.cpp | 13 +++++------ src/ds18.h | 9 ++++---- src/ems-esp.ino | 59 ++++++++++++++++++++++++++++++++++++++++++++++++- src/my_config.h | 4 ++++ 5 files changed, 73 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e9cb81fdc..0ebf296a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - system command to show ESP stats - crash command to see stack of last system crash, with .py files to track stack dump +- publish dallas external temp sensors to MQTT (Thanks @JewelZB) ### Fixed diff --git a/src/ds18.cpp b/src/ds18.cpp index a95c60441..e3607a15a 100644 --- a/src/ds18.cpp +++ b/src/ds18.cpp @@ -25,10 +25,11 @@ DS18::~DS18() { } // init -uint8_t DS18::setup(uint8_t gpio) { +uint8_t DS18::setup(uint8_t gpio, bool parasite) { uint8_t count; - _gpio = gpio; + _gpio = gpio; + _parasite = (parasite ? 1 : 0); // OneWire if (_wire) @@ -62,8 +63,7 @@ void DS18::loop() { // Start conversion _wire->reset(); _wire->skip(); - _wire->write(DS18_CMD_START_CONVERSION, DS18_PARASITE); - + _wire->write(DS18_CMD_START_CONVERSION, _parasite); } else { // Read scratchpads for (unsigned char index = 0; index < _devices.size(); index++) { @@ -161,7 +161,7 @@ double DS18::getValue(unsigned char index) { uint8_t * data = _devices[index].data; if (OneWire::crc8(data, DS18_DATA_SIZE - 1) != data[DS18_DATA_SIZE - 1]) { - return 0; + return DS18_CRC_ERROR; } int16_t raw = (data[1] << 8) | data[0]; @@ -182,9 +182,6 @@ double DS18::getValue(unsigned char index) { } double value = (float)raw / 16.0; - if (value == DS18_DISCONNECTED) { - return 0; - } return value; } diff --git a/src/ds18.h b/src/ds18.h index d4dd9cfeb..db7c78758 100644 --- a/src/ds18.h +++ b/src/ds18.h @@ -20,8 +20,8 @@ #define DS18_CHIP_DS1825 0x3B #define DS18_DATA_SIZE 9 -#define DS18_PARASITE 1 #define DS18_DISCONNECTED -127 +#define DS18_CRC_ERROR -126 #define GPIO_NONE 0x99 #define DS18_READ_INTERVAL 2000 // Force sensor read & cache every 2 seconds @@ -39,7 +39,7 @@ class DS18 { DS18(); ~DS18(); - uint8_t setup(uint8_t gpio); + uint8_t setup(uint8_t gpio, bool parasite); void loop(); char * getDeviceString(char * s, unsigned char index); double getValue(unsigned char index); @@ -50,6 +50,7 @@ class DS18 { uint8_t loadDevices(); OneWire * _wire; - uint8_t _count; // # devices - uint8_t _gpio; // the sensor pin + uint8_t _count; // # devices + uint8_t _gpio; // the sensor pin + uint8_t _parasite; // parasite mode }; diff --git a/src/ems-esp.ino b/src/ems-esp.ino index 634de71a0..43c521f3a 100644 --- a/src/ems-esp.ino +++ b/src/ems-esp.ino @@ -35,6 +35,9 @@ DS18 ds18; #define PUBLISHVALUES_TIME 120 // every 2 minutes publish MQTT values Ticker publishValuesTimer; +#define PUBLISHSENSORVALUES_TIME 180 // every 3 minutes publish MQTT sensor values +Ticker publishSensorValuesTimer; + #define SYSTEMCHECK_TIME 20 // every 20 seconds check if Boiler is online Ticker systemCheckTimer; @@ -67,6 +70,7 @@ typedef struct { uint8_t dallas_sensors; // count of dallas sensors uint8_t led_gpio; uint8_t dallas_gpio; + uint8_t dallas_parasite; } _EMSESP_Status; typedef struct { @@ -414,6 +418,32 @@ void showInfo() { } } +// send all dallas sensor values as a JSON package to MQTT +void publishSensorValues() { + StaticJsonDocument doc; + bool hasdata = false; + + // see if the sensor values have changed, if so send + //JsonObject & sensors = jsonBuffer.createObject(); + JsonObject sensors = doc.to(); + for (uint8_t i = 0; i < EMSESP_Status.dallas_sensors; i++) { + double sensorValue = ds18.getValue(i); + if(sensorValue != DS18_DISCONNECTED && sensorValue != DS18_CRC_ERROR) { + char label[8] = {0}; + char valuestr[8] = {0}; // for formatting temp + sprintf(label,"temp_%d",(i+1)); + sensors[label] = _float_to_char(valuestr, sensorValue); + hasdata = true; + } + } + + if (hasdata) { + char data[MQTT_MAX_SIZE] = {0}; + serializeJson(doc, data, sizeof(data)); + myESP.mqttPublish(TOPIC_EXTERNAL_SENSORS, data); + } +} + // send values via MQTT // a json object is created for the boiler and one for the thermostat // CRC check is done to see if there are changes in the values since the last send to avoid too much wifi traffic @@ -607,6 +637,11 @@ bool FSCallback(MYESP_FSACTION action, const JsonObject json) { EMSESP_Status.dallas_gpio = EMSESP_DALLAS_GPIO; // default value } + // dallas_gpio + if (!(EMSESP_Status.dallas_gpio = json["dallas_parasite"])) { + EMSESP_Status.dallas_parasite = EMSESP_DALLAS_PARASITE; // default value + } + // thermostat_type if (!(EMS_Thermostat.type_id = json["thermostat_type"])) { EMS_Thermostat.type_id = EMSESP_THERMOSTAT_TYPE; // set default @@ -629,6 +664,7 @@ bool FSCallback(MYESP_FSACTION action, const JsonObject json) { json["led"] = EMSESP_Status.led_enabled; json["led_gpio"] = EMSESP_Status.led_gpio; json["dallas_gpio"] = EMSESP_Status.dallas_gpio; + json["dallas_parasite"] = EMSESP_Status.dallas_parasite; json["thermostat_type"] = EMS_Thermostat.type_id; json["boiler_type"] = EMS_Boiler.type_id; json["test_mode"] = EMSESP_Status.test_mode; @@ -686,6 +722,17 @@ bool SettingsCallback(MYESP_FSACTION action, uint8_t wc, const char * setting, c ok = true; } + // dallas_parasite + if ((strcmp(setting, "dallas_parasite") == 0) && (wc == 2)) { + if (strcmp(value, "true") == 0) { + EMSESP_Status.dallas_parasite = true; + ok = true; + } else if (strcmp(value, "false") == 0) { + EMSESP_Status.dallas_parasite = false; + ok = true; + } + } + // thermostat_type if (strcmp(setting, "thermostat_type") == 0) { EMS_Thermostat.type_id = ((wc == 2) ? (uint8_t)strtol(value, 0, 16) : EMS_ID_NONE); @@ -704,6 +751,7 @@ bool SettingsCallback(MYESP_FSACTION action, uint8_t wc, const char * setting, c myDebug(" led=%s", EMSESP_Status.led_enabled ? "on" : "off"); myDebug(" led_gpio=%d", EMSESP_Status.led_gpio); myDebug(" dallas_gpio=%d", EMSESP_Status.dallas_gpio); + myDebug(" dallas_parasite=%s", EMSESP_Status.dallas_parasite ? "on" : "off"); if (EMS_Thermostat.type_id == EMS_ID_NONE) { myDebug(" thermostat_type="); @@ -997,6 +1045,13 @@ void initEMSESP() { EMSESP_Shower.doingColdShot = false; } +// publish external dallas sensor temperature values to MQTT +void do_publishSensorValues() { + if (EMSESP_Status.dallas_sensors != 0) { + publishSensorValues(); + } +} + // call PublishValues without forcing, so using CRC to see if we really need to publish void do_publishValues() { // don't publish if we're not connected to the EMS bus @@ -1177,6 +1232,7 @@ void setup() { if (!EMSESP_Status.test_mode) { publishValuesTimer.attach(PUBLISHVALUES_TIME, do_publishValues); // post MQTT values regularUpdatesTimer.attach(REGULARUPDATES_TIME, do_regularUpdates); // regular reads from the EMS + publishSensorValuesTimer.attach(PUBLISHSENSORVALUES_TIME, do_publishSensorValues); // post MQTT sensor values } // set pin for LED @@ -1187,7 +1243,8 @@ void setup() { } // check for Dallas sensors - EMSESP_Status.dallas_sensors = ds18.setup(EMSESP_Status.dallas_gpio); // returns #sensors + EMSESP_Status.dallas_sensors = ds18.setup(EMSESP_Status.dallas_gpio, EMSESP_Status.dallas_parasite); // returns #sensors + } // diff --git a/src/my_config.h b/src/my_config.h index b9300c250..3fea91258 100644 --- a/src/my_config.h +++ b/src/my_config.h @@ -49,6 +49,9 @@ #define BOILER_SHOWER_ALERT 0 // enable (1) to send alert of cold water when shower time limit has exceeded #define SHOWER_MAX_DURATION 420000 // in ms. 7 minutes, before trigger a shot of cold water +// MQTT for EXTERNAL SENSORS +#define TOPIC_EXTERNAL_SENSORS "sensors" // for sending sensor values to MQTT + //////////////////////////////////////////////////////////////////////////////////////////////////// // THESE DEFAULT VALUES CAN ALSO BE SET AND STORED WITHTIN THE APPLICATION (see 'set' command) // // ALTHOUGH YOU MAY ALSO HARDCODE THEM HERE BUT THEY WILL BE OVERWRITTEN WITH NEW RELEASE UPDATES // @@ -64,6 +67,7 @@ // set this if using an external temperature sensor like a DS18B20 // D5 is the default on bbqkees' board #define EMSESP_DALLAS_GPIO D5 +#define EMSESP_DALLAS_PARASITE false // By default the EMS bus will be scanned for known devices based on product ids in ems_devices.h // You can override the Thermostat and Boiler types here