Files
OpenMQTTGateway/main/sensorDS1820.cpp
Ryan Powell 585df9a420 [SYS] Update arduino core to 3.1.1 + refactor ino to cpp (#2177)
* Update arduino core to 3.1.1

* Fix Blufi build

* Update arduinojson, fix build errors with idf

* Fix narrowing

* fix RF builds

* WIP-Convert ino files to cpp

* Fix pilight build

* Fix Somfy actuator build.

* Update esp32dev-rf partition

* Fix Weatherstation build

* Fix GFSunInverter build

* Fix esp32dev-ir build

* Fix ble-aws build

* Fix eth builds

* Fix m5Stack missing pins_arduino.h

* Fix build errors for M5 stack/tough, others are upstream issues.

* Fix RTL 433 build - remaining errors are from radolib

* Fix nodemcu build

* fix 2g builds

* Fix serial build

* Fix actuator on off builds

* Fix SSD1306 build - remaining errors are from radiolib

* Fix multiple definition of OTAserver_cert

* Fix nodemcu rf2 build

* Fix ADC builds

* Fix sensor builds

* Fix LORA builds

* Fix multi-receiver builds - remaining errors are in radiolib

* Fix fastled builds

* Fix theegns board builds

* Fix broker builds

* Update fastled - old version failed all-test build

* Fix RN8209 builds

* Fix max temp actuator builds

* Fix PWM builds

* Fix C37 sensor builds

* Fix HTU21 builds

* Fix INA266 builds

* Fix undefined variables in mqtt discovery

* Fix webui build

* Fix fastled invalid pin error

* Fix wifi manual setup builds

* Fix onewire/all-test build - bin too big error remaining

* Fix theengs plug build

* Fix rfbridge builds

* Fix blufi builds

* Fix undefined functions in serial

* Fix preprocessor definition checks

* Set IDF log level to erre

* Add delay in loop to prevent watchdog timeout

* Use xTaskCreateUniveral to support single core processors

* Remove old HTTPUpdate files - upsteam fixed.

* Cleanup and move common declarations to header file

* Use custom partiton table to fix builds where bin is too large

* Update M5StickC - fixs esp32-m5stick-c-ble build

* Revert to Arduino core 2.x for builds with incompatible libs

* Remove "Z" from file names and rename omg_common to TheengsCommon

* Fix gateway name when using MAC with new Arduino core

* Update IDF config to reduce loop task stack use

* Update esp-nimble-cpp version, corrects BLE uppercase ID's

* Update wifi manager to fix watchdog timeout error
2025-05-06 19:35:50 -05:00

187 lines
8.2 KiB
C++

/*
Theengs OpenMQTTGateway - We Unite Sensors in One Open-Source Interface
Act as a wifi or ethernet gateway between your 433mhz/infrared IR/BLE signal and a MQTT broker
Send and receiving command by MQTT
DS1820 1-wire temperature sensor addon
Copyright: (c) 2020 Lars Wessels
This file is part of OpenMQTTGateway.
OpenMQTTGateway is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenMQTTGateway is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "User_config.h"
#ifdef ZsensorDS1820
# include <DallasTemperature.h>
# include <OneWire.h>
# include "TheengsCommon.h"
# include "config_DS1820.h"
OneWire owbus(DS1820_OWBUS_GPIO);
DallasTemperature ds1820(&owbus);
DeviceAddress ds1820_address, ds1820_devices[OW_MAX_SENSORS];
static uint8_t ds1820_count = 0;
static uint8_t ds1820_resolution[OW_MAX_SENSORS];
static String ds1820_type[OW_MAX_SENSORS];
static String ds1820_addr[OW_MAX_SENSORS];
extern void createDiscovery(const char* sensor_type,
const char* st_topic, const char* s_name, const char* unique_id,
const char* availability_topic, const char* device_class, const char* value_template,
const char* payload_on, const char* payload_off, const char* unit_of_meas,
int off_delay,
const char* payload_available, const char* payload_not_available, bool gateway_entity, const char* cmd_topic,
const char* device_name, const char* device_manufacturer, const char* device_model, const char* device_id, bool retainCmd,
const char* state_class, const char* state_off, const char* state_on, const char* enum_options, const char* command_template);
void setupZsensorDS1820() {
Log.trace(F("DS1820: configured pin: %d for 1-wire bus" CR), DS1820_OWBUS_GPIO);
ds1820.begin();
// Search the OneWire bus for all devices
uint8_t numDevicesOnBus = ds1820.getDeviceCount();
// 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++) {
// 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/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 GPIO assignment!" CR));
}
// make requestTemperatures() non-blocking
// we've to take that conversion is triggered some time before reading temperature values!
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
# include "config_mqttDiscovery.h"
// If zmqtt discovery is enabled, create a sensor topic for each DS18b20 sensor found on the bus, using addr as uniqueID
if (SYSConfig.discovery) {
for (int index = 0; index < ds1820_count; index++) {
createDiscovery("sensor",
(char*)(String(OW_TOPIC) + "/" + ds1820_addr[index]).c_str(),
(char*)("DS12B20_" + String(index + 1) + "_c").c_str(),
(char*)(ds1820_addr[index] + "_c").c_str(),
will_Topic,
"temperature",
jsonTempc,
"", "", "°C",
0, "", "", true, "",
"", "", "", "", false,
stateClassMeasurement // state class
);
}
}
# endif
}
void MeasureDS1820Temp() {
static float persisted_temp[OW_MAX_SENSORS];
static unsigned long timeDS1820 = 0;
static boolean triggeredConversion = false;
float current_temp[OW_MAX_SENSORS];
// trigger temperature conversion some time before actually
// calling getTempC() to make reading temperatures non-blocking
if (!triggeredConversion && ((millis() - timeDS1820) > (DS1820_INTERVAL_SEC * 1000UL - DS1820_CONV_TIME))) {
Log.trace(F("DS1820: Trigger temperature conversion..." CR));
ds1820.requestTemperatures();
triggeredConversion = true;
} else if (triggeredConversion && ((millis() - timeDS1820) > DS1820_INTERVAL_SEC * 1000UL)) {
timeDS1820 = millis();
triggeredConversion = false;
if (ds1820_count < 1) {
Log.error(F("DS1820: Failed to identify any temperature sensors on 1-wire bus during setup!" CR));
} else {
Log.trace(F("DS1820: Reading temperature(s) from %d sensor(s)..." CR), ds1820_count);
StaticJsonDocument<JSON_MSG_BUFFER> DS1820dataBuffer;
JsonObject DS1820data = DS1820dataBuffer.to<JsonObject>();
for (uint8_t i = 0; i < ds1820_count; i++) {
current_temp[i] = round(ds1820.getTempC(ds1820_devices[i]) * 10) / 10.0;
if (current_temp[i] == -127) {
Log.error(F("DS1820: Device %s currently disconnected!" CR), (char*)ds1820_addr[i].c_str());
} else if (DS1820_ALWAYS || current_temp[i] != persisted_temp[i]) {
DS1820data["tempf"] = (float)DallasTemperature::toFahrenheit(current_temp[i]);
DS1820data["tempc"] = (float)current_temp[i];
if (DS1820_DETAILS) {
DS1820data["type"] = ds1820_type[i];
DS1820data["res"] = String(ds1820_resolution[i]) + String("bit");
DS1820data["addr"] = ds1820_addr[i];
}
String origin = String(OW_TOPIC) + "/" + ds1820_addr[i];
DS1820data["origin"] = origin;
enqueueJsonObject(DS1820data);
if (SYSConfig.powerMode > 0)
ready_to_sleep = true;
} else {
Log.trace(F("DS1820: Temperature for device %s didn't change, don't publish it." CR), (char*)ds1820_addr[i].c_str());
}
persisted_temp[i] = current_temp[i];
}
}
}
}
#endif