|
|
|
|
@@ -57,7 +57,47 @@ class UsermodTemperature : public Usermod {
|
|
|
|
|
static const char _parasitePin[];
|
|
|
|
|
|
|
|
|
|
//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];
|
|
|
|
|
int16_t result; // raw data from sensor
|
|
|
|
|
float retVal = -127.0f;
|
|
|
|
|
@@ -90,9 +130,9 @@ class UsermodTemperature : public Usermod {
|
|
|
|
|
}
|
|
|
|
|
for (byte i=1; i<9; i++) data[0] &= data[i];
|
|
|
|
|
return data[0]==0xFF ? -127.0f : retVal;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void requestTemperatures() {
|
|
|
|
|
void UsermodTemperature::requestTemperatures() {
|
|
|
|
|
DEBUG_PRINTLN(F("Requesting temperature."));
|
|
|
|
|
oneWire->reset();
|
|
|
|
|
oneWire->skip(); // skip ROM
|
|
|
|
|
@@ -100,9 +140,9 @@ class UsermodTemperature : public Usermod {
|
|
|
|
|
if (parasite && parasitePin >=0 ) digitalWrite(parasitePin, HIGH); // has to happen within 10us (open MOSFET)
|
|
|
|
|
lastTemperaturesRequest = millis();
|
|
|
|
|
waitingForConversion = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void readTemperature() {
|
|
|
|
|
void UsermodTemperature::readTemperature() {
|
|
|
|
|
if (parasite && parasitePin >=0 ) digitalWrite(parasitePin, LOW); // deactivate power (close MOSFET)
|
|
|
|
|
temperature = readDallas();
|
|
|
|
|
lastMeasurement = millis();
|
|
|
|
|
@@ -110,9 +150,9 @@ class UsermodTemperature : public Usermod {
|
|
|
|
|
//DEBUG_PRINTF("Read temperature %2.1f.\n", temperature); // does not work properly on 8266
|
|
|
|
|
DEBUG_PRINT(F("Read temperature "));
|
|
|
|
|
DEBUG_PRINTLN(temperature);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool findSensor() {
|
|
|
|
|
bool UsermodTemperature::findSensor() {
|
|
|
|
|
DEBUG_PRINTLN(F("Searching for sensor..."));
|
|
|
|
|
uint8_t deviceAddress[8] = {0,0,0,0,0,0,0,0};
|
|
|
|
|
// find out if we have DS18xxx sensor attached
|
|
|
|
|
@@ -136,10 +176,10 @@ class UsermodTemperature : public Usermod {
|
|
|
|
|
}
|
|
|
|
|
DEBUG_PRINTLN(F("Sensor NOT found."));
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifndef WLED_DISABLE_MQTT
|
|
|
|
|
void publishHomeAssistantAutodiscovery() {
|
|
|
|
|
void UsermodTemperature::publishHomeAssistantAutodiscovery() {
|
|
|
|
|
if (!WLED_MQTT_CONNECTED) return;
|
|
|
|
|
|
|
|
|
|
char json_str[1024], buf[128];
|
|
|
|
|
@@ -159,12 +199,10 @@ class UsermodTemperature : public Usermod {
|
|
|
|
|
sprintf_P(buf, PSTR("homeassistant/sensor/%s/config"), escapedMac.c_str());
|
|
|
|
|
mqtt->publish(buf, 0, true, json_str, payload_size);
|
|
|
|
|
HApublished = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
void setup() {
|
|
|
|
|
void UsermodTemperature::setup() {
|
|
|
|
|
int retries = 10;
|
|
|
|
|
sensorFound = 0;
|
|
|
|
|
temperature = -127.0f; // default to -127, DS18B20 only goes down to -50C
|
|
|
|
|
@@ -194,9 +232,9 @@ class UsermodTemperature : public Usermod {
|
|
|
|
|
}
|
|
|
|
|
lastMeasurement = millis() - readingInterval + 10000;
|
|
|
|
|
initDone = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void loop() {
|
|
|
|
|
void UsermodTemperature::loop() {
|
|
|
|
|
if (!enabled || !sensorFound || strip.isUpdating()) return;
|
|
|
|
|
|
|
|
|
|
static uint8_t errorCount = 0;
|
|
|
|
|
@@ -242,43 +280,33 @@ class UsermodTemperature : public Usermod {
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
/**
|
|
|
|
|
* connected() is called every time the WiFi is (re)connected
|
|
|
|
|
* Use it to initialize network interfaces
|
|
|
|
|
*/
|
|
|
|
|
//void connected() {}
|
|
|
|
|
//void UsermodTemperature::connected() {}
|
|
|
|
|
|
|
|
|
|
#ifndef WLED_DISABLE_MQTT
|
|
|
|
|
/**
|
|
|
|
|
/**
|
|
|
|
|
* subscribe to MQTT topic if needed
|
|
|
|
|
*/
|
|
|
|
|
void onMqttConnect(bool sessionPresent) {
|
|
|
|
|
void UsermodTemperature::onMqttConnect(bool sessionPresent) {
|
|
|
|
|
//(re)subscribe to required topics
|
|
|
|
|
//char subuf[64];
|
|
|
|
|
if (mqttDeviceTopic[0] != 0) {
|
|
|
|
|
publishHomeAssistantAutodiscovery();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#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.
|
|
|
|
|
* 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
|
|
|
|
|
*/
|
|
|
|
|
void addToJsonInfo(JsonObject& root) {
|
|
|
|
|
void UsermodTemperature::addToJsonInfo(JsonObject& root) {
|
|
|
|
|
// dont add temperature to info if we are disabled
|
|
|
|
|
if (!enabled) return;
|
|
|
|
|
|
|
|
|
|
@@ -293,37 +321,37 @@ class UsermodTemperature : public Usermod {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
temp.add(degC ? getTemperatureC() : getTemperatureF());
|
|
|
|
|
temp.add(degC ? F("°C") : F("°F"));
|
|
|
|
|
temp.add(getTemperature());
|
|
|
|
|
temp.add(getTemperatureUnit());
|
|
|
|
|
|
|
|
|
|
JsonObject sensor = root[F("sensor")];
|
|
|
|
|
if (sensor.isNull()) sensor = root.createNestedObject(F("sensor"));
|
|
|
|
|
temp = sensor.createNestedArray(F("temp"));
|
|
|
|
|
temp.add(degC ? temperature : (float)temperature * 1.8f + 32);
|
|
|
|
|
temp.add(degC ? F("°C") : F("°F"));
|
|
|
|
|
}
|
|
|
|
|
temp = sensor.createNestedArray(F("temperature"));
|
|
|
|
|
temp.add(getTemperature());
|
|
|
|
|
temp.add(getTemperatureUnit());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
/**
|
|
|
|
|
* 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
|
|
|
|
|
*/
|
|
|
|
|
//void addToJsonState(JsonObject &root)
|
|
|
|
|
//{
|
|
|
|
|
//}
|
|
|
|
|
//void UsermodTemperature::addToJsonState(JsonObject &root)
|
|
|
|
|
//{
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
/**
|
|
|
|
|
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
|
|
|
|
//void readFromJsonState(JsonObject &root) {
|
|
|
|
|
// if (!initDone) return; // prevent crash on boot applyPreset()
|
|
|
|
|
//}
|
|
|
|
|
//void UsermodTemperature::readFromJsonState(JsonObject &root) {
|
|
|
|
|
// if (!initDone) return; // prevent crash on boot applyPreset()
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
/**
|
|
|
|
|
* 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}}
|
|
|
|
|
JsonObject top = root.createNestedObject(FPSTR(_name)); // usermodname
|
|
|
|
|
top[FPSTR(_enabled)] = enabled;
|
|
|
|
|
@@ -333,14 +361,14 @@ class UsermodTemperature : public Usermod {
|
|
|
|
|
top[FPSTR(_parasite)] = parasite;
|
|
|
|
|
top[FPSTR(_parasitePin)] = parasitePin;
|
|
|
|
|
DEBUG_PRINTLN(F("Temperature config saved."));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
/**
|
|
|
|
|
* readFromConfig() is called before setup() to populate properties from values stored in cfg.json
|
|
|
|
|
*
|
|
|
|
|
* 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}}
|
|
|
|
|
int8_t newTemperaturePin = temperaturePin;
|
|
|
|
|
DEBUG_PRINT(FPSTR(_name));
|
|
|
|
|
@@ -379,21 +407,22 @@ class UsermodTemperature : public Usermod {
|
|
|
|
|
}
|
|
|
|
|
// use "return !top["newestParameter"].isNull();" when updating Usermod with new features
|
|
|
|
|
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("',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("',1,'<i>(for external MOSFET)</i>');")); // 0 is field type, 1 is actual field
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint16_t getId()
|
|
|
|
|
{
|
|
|
|
|
return USERMOD_ID_TEMPERATURE;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
float UsermodTemperature::getTemperature() {
|
|
|
|
|
return degC ? getTemperatureC() : getTemperatureF();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char *UsermodTemperature::getTemperatureUnit() {
|
|
|
|
|
return degC ? "°C" : "°F";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// strings to reduce flash memory usage (used more than twice)
|
|
|
|
|
const char UsermodTemperature::_name[] PROGMEM = "Temperature";
|
|
|
|
|
|