Temperature usermod rewrite

This commit is contained in:
Blaz Kristan 2023-05-11 17:33:09 +02:00
parent bf6a18a414
commit cdfc0f6b71
4 changed files with 353 additions and 351 deletions

View File

@ -1,13 +1,12 @@
; Options ; Options
; ------- ; -------
; USERMOD_DALLASTEMPERATURE - define this to have this user mod included wled00\usermods_list.cpp ; USERMOD_DALLASTEMPERATURE - define this to have this user mod included wled00\usermods_list.cpp
; USERMOD_DALLASTEMPERATURE_CELSIUS - define this to report temperatures in degrees celsius, otherwise fahrenheit will be reported
; USERMOD_DALLASTEMPERATURE_MEASUREMENT_INTERVAL - the number of milliseconds between measurements, defaults to 60 seconds ; USERMOD_DALLASTEMPERATURE_MEASUREMENT_INTERVAL - the number of milliseconds between measurements, defaults to 60 seconds
; USERMOD_DALLASTEMPERATURE_FIRST_MEASUREMENT_AT - the number of milliseconds after boot to take first measurement, defaults to 20 seconds
; ;
[env:d1_mini_usermod_dallas_temperature_C] [env:d1_mini_usermod_dallas_temperature_C]
extends = env:d1_mini extends = env:d1_mini
build_flags = ${common.build_flags_esp8266} -D USERMOD_DALLASTEMPERATURE -D USERMOD_DALLASTEMPERATURE_CELSIUS build_flags = ${common.build_flags_esp8266} -D USERMOD_DALLASTEMPERATURE
lib_deps = ${env.lib_deps} lib_deps = ${env.lib_deps}
milesburton/DallasTemperature@^3.9.0 paulstoffregen/OneWire@~2.3.7
OneWire@~2.3.5 # you may want to use following with ESP32
; https://github.com/blazoncek/OneWire.git # fixes Sensor error on ESP32

View File

@ -7,6 +7,8 @@ May be expanded with support for different sensor types in the future.
If temperature sensor is not detected during boot, this usermod will be disabled. If temperature sensor is not detected during boot, this usermod will be disabled.
Maintained by @blazoncek
## Installation ## Installation
Copy the example `platformio_override.ini` to the root directory. This file should be placed in the same directory as `platformio.ini`. Copy the example `platformio_override.ini` to the root directory. This file should be placed in the same directory as `platformio.ini`.
@ -14,7 +16,7 @@ Copy the example `platformio_override.ini` to the root directory. This file sho
### Define Your Options ### Define Your Options
* `USERMOD_DALLASTEMPERATURE` - enables this user mod wled00/usermods_list.cpp * `USERMOD_DALLASTEMPERATURE` - enables this user mod wled00/usermods_list.cpp
* `USERMOD_DALLASTEMPERATURE_FIRST_MEASUREMENT_AT` - number of milliseconds after boot to take first measurement, defaults to 20000 ms * `USERMOD_DALLASTEMPERATURE_MEASUREMENT_INTERVAL` - number of milliseconds between measurements, defaults to 60000 ms (60s)
All parameters can be configured at runtime via the Usermods settings page, including pin, temperature in degrees Celsius or Farenheit and measurement interval. All parameters can be configured at runtime via the Usermods settings page, including pin, temperature in degrees Celsius or Farenheit and measurement interval.
@ -27,7 +29,6 @@ All parameters can be configured at runtime via the Usermods settings page, incl
If you are using `platformio_override.ini`, you should be able to refresh the task list and see your custom task, for example `env:d1_mini_usermod_dallas_temperature_C`. If you are using `platformio_override.ini`, you should be able to refresh the task list and see your custom task, for example `env:d1_mini_usermod_dallas_temperature_C`.
If you are not using `platformio_override.ini`, you might have to uncomment `OneWire@~2.3.5 under` `[common]` section in `platformio.ini`: If you are not using `platformio_override.ini`, you might have to uncomment `OneWire@~2.3.5 under` `[common]` section in `platformio.ini`:
```ini ```ini
@ -43,8 +44,9 @@ default_envs = d1_mini
lib_deps = lib_deps =
... ...
#For Dallas sensor uncomment following line #For Dallas sensor uncomment following line
OneWire@~2.3.5 OneWire@~2.3.7
... # ... or you may want to use following with ESP32
; https://github.com/blazoncek/OneWire.git # fixes Sensor error on ESP32...
``` ```
## Change Log ## Change Log
@ -56,3 +58,6 @@ lib_deps =
* Report the number of seconds until the first read in the info screen instead of sensor error * Report the number of seconds until the first read in the info screen instead of sensor error
2021-04 2021-04
* Adaptation for runtime configuration. * Adaptation for runtime configuration.
2023-05
* Rewrite to conform to newer recommendations.
* Recommended @blazoncek fork of OneWire for ESP32 to avoid Sensor error

View File

@ -57,7 +57,47 @@ class UsermodTemperature : public Usermod {
static const char _parasitePin[]; static const char _parasitePin[];
//Dallas sensor quick (& dirty) reading. Credit to - Author: Peter Scargill, August 17th, 2013 //Dallas sensor quick (& dirty) reading. Credit to - Author: Peter Scargill, August 17th, 2013
float readDallas() { float readDallas();
void requestTemperatures();
void readTemperature();
bool findSensor();
#ifndef WLED_DISABLE_MQTT
void publishHomeAssistantAutodiscovery();
#endif
public:
/*
* API calls te enable data exchange between WLED modules
*/
inline float getTemperatureC() { return temperature; }
inline float getTemperatureF() { return temperature * 1.8f + 32.0f; }
float getTemperature();
const char *getTemperatureUnit();
uint16_t getId() { return USERMOD_ID_TEMPERATURE; }
void setup();
void loop();
//void connected();
#ifndef WLED_DISABLE_MQTT
void onMqttConnect(bool sessionPresent);
#endif
//void onUpdateBegin(bool init);
//bool handleButton(uint8_t b);
//void handleOverlayDraw();
void addToJsonInfo(JsonObject& root);
//void addToJsonState(JsonObject &root);
//void readFromJsonState(JsonObject &root);
void addToConfig(JsonObject &root);
bool readFromConfig(JsonObject &root);
void appendConfigData();
};
//Dallas sensor quick (& dirty) reading. Credit to - Author: Peter Scargill, August 17th, 2013
float UsermodTemperature::readDallas() {
byte data[9]; byte data[9];
int16_t result; // raw data from sensor int16_t result; // raw data from sensor
float retVal = -127.0f; float retVal = -127.0f;
@ -92,7 +132,7 @@ class UsermodTemperature : public Usermod {
return data[0]==0xFF ? -127.0f : retVal; return data[0]==0xFF ? -127.0f : retVal;
} }
void requestTemperatures() { void UsermodTemperature::requestTemperatures() {
DEBUG_PRINTLN(F("Requesting temperature.")); DEBUG_PRINTLN(F("Requesting temperature."));
oneWire->reset(); oneWire->reset();
oneWire->skip(); // skip ROM oneWire->skip(); // skip ROM
@ -102,7 +142,7 @@ class UsermodTemperature : public Usermod {
waitingForConversion = true; waitingForConversion = true;
} }
void readTemperature() { void UsermodTemperature::readTemperature() {
if (parasite && parasitePin >=0 ) digitalWrite(parasitePin, LOW); // deactivate power (close MOSFET) if (parasite && parasitePin >=0 ) digitalWrite(parasitePin, LOW); // deactivate power (close MOSFET)
temperature = readDallas(); temperature = readDallas();
lastMeasurement = millis(); lastMeasurement = millis();
@ -112,7 +152,7 @@ class UsermodTemperature : public Usermod {
DEBUG_PRINTLN(temperature); DEBUG_PRINTLN(temperature);
} }
bool findSensor() { bool UsermodTemperature::findSensor() {
DEBUG_PRINTLN(F("Searching for sensor...")); DEBUG_PRINTLN(F("Searching for sensor..."));
uint8_t deviceAddress[8] = {0,0,0,0,0,0,0,0}; uint8_t deviceAddress[8] = {0,0,0,0,0,0,0,0};
// find out if we have DS18xxx sensor attached // find out if we have DS18xxx sensor attached
@ -139,7 +179,7 @@ class UsermodTemperature : public Usermod {
} }
#ifndef WLED_DISABLE_MQTT #ifndef WLED_DISABLE_MQTT
void publishHomeAssistantAutodiscovery() { void UsermodTemperature::publishHomeAssistantAutodiscovery() {
if (!WLED_MQTT_CONNECTED) return; if (!WLED_MQTT_CONNECTED) return;
char json_str[1024], buf[128]; char json_str[1024], buf[128];
@ -162,9 +202,7 @@ class UsermodTemperature : public Usermod {
} }
#endif #endif
public: void UsermodTemperature::setup() {
void setup() {
int retries = 10; int retries = 10;
sensorFound = 0; sensorFound = 0;
temperature = -127.0f; // default to -127, DS18B20 only goes down to -50C temperature = -127.0f; // default to -127, DS18B20 only goes down to -50C
@ -196,7 +234,7 @@ class UsermodTemperature : public Usermod {
initDone = true; initDone = true;
} }
void loop() { void UsermodTemperature::loop() {
if (!enabled || !sensorFound || strip.isUpdating()) return; if (!enabled || !sensorFound || strip.isUpdating()) return;
static uint8_t errorCount = 0; static uint8_t errorCount = 0;
@ -248,13 +286,13 @@ class UsermodTemperature : public Usermod {
* connected() is called every time the WiFi is (re)connected * connected() is called every time the WiFi is (re)connected
* Use it to initialize network interfaces * Use it to initialize network interfaces
*/ */
//void connected() {} //void UsermodTemperature::connected() {}
#ifndef WLED_DISABLE_MQTT #ifndef WLED_DISABLE_MQTT
/** /**
* subscribe to MQTT topic if needed * subscribe to MQTT topic if needed
*/ */
void onMqttConnect(bool sessionPresent) { void UsermodTemperature::onMqttConnect(bool sessionPresent) {
//(re)subscribe to required topics //(re)subscribe to required topics
//char subuf[64]; //char subuf[64];
if (mqttDeviceTopic[0] != 0) { if (mqttDeviceTopic[0] != 0) {
@ -263,22 +301,12 @@ class UsermodTemperature : public Usermod {
} }
#endif #endif
/*
* API calls te enable data exchange between WLED modules
*/
inline float getTemperatureC() {
return (float)temperature;
}
inline float getTemperatureF() {
return (float)temperature * 1.8f + 32;
}
/* /*
* addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API. * addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API.
* Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI. * Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI.
* Below it is shown how this could be used for e.g. a light sensor * Below it is shown how this could be used for e.g. a light sensor
*/ */
void addToJsonInfo(JsonObject& root) { void UsermodTemperature::addToJsonInfo(JsonObject& root) {
// dont add temperature to info if we are disabled // dont add temperature to info if we are disabled
if (!enabled) return; if (!enabled) return;
@ -293,21 +321,21 @@ class UsermodTemperature : public Usermod {
return; return;
} }
temp.add(degC ? getTemperatureC() : getTemperatureF()); temp.add(getTemperature());
temp.add(degC ? F("°C") : F("°F")); temp.add(getTemperatureUnit());
JsonObject sensor = root[F("sensor")]; JsonObject sensor = root[F("sensor")];
if (sensor.isNull()) sensor = root.createNestedObject(F("sensor")); if (sensor.isNull()) sensor = root.createNestedObject(F("sensor"));
temp = sensor.createNestedArray(F("temp")); temp = sensor.createNestedArray(F("temperature"));
temp.add(degC ? temperature : (float)temperature * 1.8f + 32); temp.add(getTemperature());
temp.add(degC ? F("°C") : F("°F")); temp.add(getTemperatureUnit());
} }
/** /**
* addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object). * addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
* Values in the state object may be modified by connected clients * Values in the state object may be modified by connected clients
*/ */
//void addToJsonState(JsonObject &root) //void UsermodTemperature::addToJsonState(JsonObject &root)
//{ //{
//} //}
@ -316,14 +344,14 @@ class UsermodTemperature : public Usermod {
* Values in the state object may be modified by connected clients * Values in the state object may be modified by connected clients
* Read "<usermodname>_<usermodparam>" from json state and and change settings (i.e. GPIO pin) used. * Read "<usermodname>_<usermodparam>" from json state and and change settings (i.e. GPIO pin) used.
*/ */
//void readFromJsonState(JsonObject &root) { //void UsermodTemperature::readFromJsonState(JsonObject &root) {
// if (!initDone) return; // prevent crash on boot applyPreset() // if (!initDone) return; // prevent crash on boot applyPreset()
//} //}
/** /**
* addToConfig() (called from set.cpp) stores persistent properties to cfg.json * addToConfig() (called from set.cpp) stores persistent properties to cfg.json
*/ */
void addToConfig(JsonObject &root) { void UsermodTemperature::addToConfig(JsonObject &root) {
// we add JSON object: {"Temperature": {"pin": 0, "degC": true}} // we add JSON object: {"Temperature": {"pin": 0, "degC": true}}
JsonObject top = root.createNestedObject(FPSTR(_name)); // usermodname JsonObject top = root.createNestedObject(FPSTR(_name)); // usermodname
top[FPSTR(_enabled)] = enabled; top[FPSTR(_enabled)] = enabled;
@ -340,7 +368,7 @@ class UsermodTemperature : public Usermod {
* *
* The function should return true if configuration was successfully loaded or false if there was no configuration. * The function should return true if configuration was successfully loaded or false if there was no configuration.
*/ */
bool readFromConfig(JsonObject &root) { bool UsermodTemperature::readFromConfig(JsonObject &root) {
// we look for JSON object: {"Temperature": {"pin": 0, "degC": true}} // we look for JSON object: {"Temperature": {"pin": 0, "degC": true}}
int8_t newTemperaturePin = temperaturePin; int8_t newTemperaturePin = temperaturePin;
DEBUG_PRINT(FPSTR(_name)); DEBUG_PRINT(FPSTR(_name));
@ -381,19 +409,20 @@ class UsermodTemperature : public Usermod {
return !top[FPSTR(_parasitePin)].isNull(); return !top[FPSTR(_parasitePin)].isNull();
} }
void appendConfigData() void UsermodTemperature::appendConfigData() {
{
oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":")); oappend(String(FPSTR(_parasite)).c_str()); oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":")); oappend(String(FPSTR(_parasite)).c_str());
oappend(SET_F("',1,'<i>(if no Vcc connected)</i>');")); // 0 is field type, 1 is actual field oappend(SET_F("',1,'<i>(if no Vcc connected)</i>');")); // 0 is field type, 1 is actual field
oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":")); oappend(String(FPSTR(_parasitePin)).c_str()); oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":")); oappend(String(FPSTR(_parasitePin)).c_str());
oappend(SET_F("',1,'<i>(for external MOSFET)</i>');")); // 0 is field type, 1 is actual field oappend(SET_F("',1,'<i>(for external MOSFET)</i>');")); // 0 is field type, 1 is actual field
} }
uint16_t getId() float UsermodTemperature::getTemperature() {
{ return degC ? getTemperatureC() : getTemperatureF();
return USERMOD_ID_TEMPERATURE; }
const char *UsermodTemperature::getTemperatureUnit() {
return degC ? "°C" : "°F";
} }
};
// strings to reduce flash memory usage (used more than twice) // strings to reduce flash memory usage (used more than twice)
const char UsermodTemperature::_name[] PROGMEM = "Temperature"; const char UsermodTemperature::_name[] PROGMEM = "Temperature";

View File

@ -1,31 +0,0 @@
#include "wled.h"
/*
* Register your v2 usermods here!
*/
/*
* Add/uncomment your usermod filename here (and once more below)
* || || ||
* \/ \/ \/
*/
//#include "usermod_v2_example.h"
#ifdef USERMOD_DALLASTEMPERATURE
#include "../usermods/Temperature/usermod_temperature.h"
#endif
//#include "usermod_v2_empty.h"
void registerUsermods()
{
/*
* Add your usermod class name here
* || || ||
* \/ \/ \/
*/
//usermods.add(new MyExampleUsermod());
#ifdef USERMOD_DALLASTEMPERATURE
usermods.add(new UsermodTemperature());
#endif
//usermods.add(new UsermodRenameMe());
}