From 4bc8621910962cb09126ea8f3168258c946566f7 Mon Sep 17 00:00:00 2001 From: Jon Date: Fri, 5 Jun 2020 07:16:40 +0900 Subject: [PATCH] Ds1820 HADiscovery (#621) * DS18b20 HADiscovery * Allow Multiple DS18b20 Sensors * Optimize Bus Scan * Update Docs Co-authored-by: Jonathan Michael Wells --- docs/use/sensors.md | 12 +++- main/ZmqttDiscovery.ino | 5 ++ main/ZsensorDS1820.ino | 142 ++++++++++++++++++++++++---------------- main/config_DS1820.h | 1 + 4 files changed, 104 insertions(+), 56 deletions(-) diff --git a/docs/use/sensors.md b/docs/use/sensors.md index 3ada367..da450b4 100644 --- a/docs/use/sensors.md +++ b/docs/use/sensors.md @@ -19,4 +19,14 @@ You will receive the HTU21 sensor readings every TimeBetweenReadinghtu21 (set in `home/OpenMQTTGateway/CLIMAtoMQTT/htu {"tempc":25.34064,"tempf":77.61314,"hum":56.53052}` -If you don't want to resend values that haven't changed you can set htu21_always = false in config_HTU21.h \ No newline at end of file +If you don't want to resend values that haven't changed you can set htu21_always = false in config_HTU21.h + +### DS18x20 +You will receive the DS18x20 sensor readings every DS1820_INTERVAL_SEC (set into config_DS1820.h) (60s by default). +Each sensor will be published under the following topic using each sensors' address. + +`home/OpenMQTTGateway/CLIMAtoMQTT/ds1820/0x0000000000000000 {"temp":27.8,"unit":"C","type":"DS18B20","res":"12bit\n","addr":"0x28616411907650bc"}` + +The units for temperature readings are sent in Celcius by default can be changed to ferenheight by setting DS1820_FAHRENHEIT = true in in config_DS1820.h + +If you don't want to resend values that haven't changed you can set DS1820_ALWAYS = false in config_DS1820.h \ No newline at end of file diff --git a/main/ZmqttDiscovery.ino b/main/ZmqttDiscovery.ino index 51ed4d7..7e9f406 100644 --- a/main/ZmqttDiscovery.ino +++ b/main/ZmqttDiscovery.ino @@ -323,6 +323,11 @@ void pubMqttDiscovery() } #endif +#ifdef ZsensorDS1820 + // Publish any DS1820 sensors found on the OneWire bus + pubOneWire_HADiscovery(); +#endif + #ifdef ZactuatorONOFF Log.trace(F("actuatorONOFFDiscovery" CR)); char *actuatorONOFF[8] = {"switch", "actuatorONOFF", "", "", "", "{\"cmd\":1}", "{\"cmd\":0}", ""}; diff --git a/main/ZsensorDS1820.ino b/main/ZsensorDS1820.ino index 94e5ae7..3ebc66a 100644 --- a/main/ZsensorDS1820.ino +++ b/main/ZsensorDS1820.ino @@ -44,63 +44,63 @@ void setupZsensorDS1820() Log.trace(F("DS1820: configured pin: %d for 1-wire bus" CR), DS1820_OWBUS_PIN ); ds1820.begin(); - // locate device(s) on 1-wire bus - Log.notice(F("DS1820: Found %d devices" CR), ds1820.getDeviceCount()); + // Search the OneWire bus for all devices + uint8_t numDevicesOnBus = ds1820.getDeviceCount(); - // determine device addresses on 1-wire bus - if (owbus.search(ds1820_address)) + // locate device(s) on 1-wire bus + Log.notice(F("DS1820: Found %d devices" CR), numDevicesOnBus); + + // Cycle though all of the devices on the OneWire bus + for (int deviceIndex = 0; deviceIndex < numDevicesOnBus && ds1820_count < OW_MAX_SENSORS; deviceIndex++) { - do { - // we only care about Dallas DS18X20 1-wire devices - if (ds1820_address[0] == 0x10 || ds1820_address[0] == 0x28 || - ds1820_address[0] == 0x22 || ds1820_address[0] == 0x3B) + // get the next device on the OneWire bus and confirm it is a sensor the library can handle (Dallas DS18X20 1-wire devices) + if ( ds1820.getAddress(ds1820_address, deviceIndex) && ds1820.validFamily(ds1820_address) ) + { + ds1820_addr[ds1820_count] = String("0x"); + for (uint8_t i = 0; i < 8; i++) + { + if (ds1820_address[i] < 0x10) ds1820_addr[ds1820_count] += String("0"); + ds1820_devices[ds1820_count][i] = ds1820_address[i]; + ds1820_addr[ds1820_count] += String(ds1820_address[i], HEX); + } + + // set the resolution and thus conversion timing + if (ds1820_address[0] == 0x10) { - ds1820_addr[ds1820_count] = String("0x"); - for (uint8_t i = 0; i < 8; i++) - { - if (ds1820_address[i] < 0x10) ds1820_addr[ds1820_count] += String("0"); - ds1820_devices[ds1820_count][i] = ds1820_address[i]; - ds1820_addr[ds1820_count] += String(ds1820_address[i], HEX); - } - - // set the resolution and thus conversion timing - if (ds1820_address[0] == 0x10) - { - // DS1820/DS18S20 have no resolution configuration register, - // both have a 9-bit temperature register. Resolutions greater - // than 9-bit can be calculated using the data from the temperature, - // and COUNT REMAIN and COUNT PER °C registers in the scratchpad. - // The resolution of the calculation depends on the model. - ds1820_type[ds1820_count] = String("DS1820/DS18S20"); - } - else if (ds1820_address[0] == 0x28) - { - // DS18B20 and 18B22 are capable of different resolutions (9-12 bit) - ds1820_type[ds1820_count] = String("DS18B20"); - ds1820.setResolution(ds1820_address, DS1820_RESOLUTION); - } - else if (ds1820_address[0] == 0x22) - { - ds1820_type[ds1820_count] = String("DS1822"); - ds1820.setResolution(ds1820_address, DS1820_RESOLUTION); - } - else - { - ds1820_type[ds1820_count] = String("DS1825"); - ds1820.setResolution(ds1820_address, DS1820_RESOLUTION); - } - ds1820_resolution[ds1820_count] = ds1820.getResolution(ds1820_address); - Log.trace(F("DS1820: Device %d, Type: %s, Address: %s, Resolution: %d" CR), - ds1820_count, - (char *)ds1820_type[ds1820_count].c_str(), - (char *)ds1820_addr[ds1820_count].c_str(), - ds1820_resolution[ds1820_count]); - ds1820_count++; - } - } while (owbus.search(ds1820_address)); - - } - else + // DS1820/DS18S20 have no resolution configuration register, + // both have a 9-bit temperature register. Resolutions greater + // than 9-bit can be calculated using the data from the temperature, + // and COUNT REMAIN and COUNT PER °C registers in the scratchpad. + // The resolution of the calculation depends on the model. + ds1820_type[ds1820_count] = String("DS1820/DS18S20"); + } + else if (ds1820_address[0] == 0x28) + { + // DS18B20 and 18B22 are capable of different resolutions (9-12 bit) + ds1820_type[ds1820_count] = String("DS18B20"); + ds1820.setResolution(ds1820_address, DS1820_RESOLUTION); + } + else if (ds1820_address[0] == 0x22) + { + ds1820_type[ds1820_count] = String("DS1822"); + ds1820.setResolution(ds1820_address, DS1820_RESOLUTION); + } + else + { + ds1820_type[ds1820_count] = String("DS1825"); + ds1820.setResolution(ds1820_address, DS1820_RESOLUTION); + } + ds1820_resolution[ds1820_count] = ds1820.getResolution(ds1820_address); + Log.trace(F("DS1820: Device %d, Type: %s, Address: %s, Resolution: %d" CR), + ds1820_count, + (char *)ds1820_type[ds1820_count].c_str(), + (char *)ds1820_addr[ds1820_count].c_str(), + ds1820_resolution[ds1820_count]); + ds1820_count++; + } + } + + if (ds1820.getDS18Count() == 0) { Log.error(F("DS1820: Failed to enumerate sensors on 1-wire bus. Check your pin assignment!" CR)); } @@ -110,6 +110,38 @@ void setupZsensorDS1820() ds1820.setWaitForConversion(false); } +void pubOneWire_HADiscovery() +{ + // If zmqttDiscovery is enabled, create a sensor topic for each DS18b20 sensor found on the bus, using addr as uniqueID +#ifdef ZmqttDiscovery + Log.notice(F("CreateDiscoverySensor - Found %d" CR), ds1820_count); + for (int index=0; index