[ONOFF] ESP32 Attempt to recover previous actuator state when power has been lost and overcurrent detection change (#1494)
And set the trigger of overCurrent to 2 consecutive measures
This commit is contained in:
1 parent
fa636bae0f
commit
1cdf6558a9
5 files changed
+164
-39
No files matched your search
@@ -39,7 +39,13 @@ Goes ON for 25 ms, then back to OFF:
|
|||||||
Goes OFF for 25 ms, then back to ON:
|
Goes OFF for 25 ms, then back to ON:
|
||||||
`mosquitto_pub -t home/OpenMQTTGateway_MEGA/commands/MQTTtoONOFF -m '{"gpio":15,"cmd":"low_pulse","pulse_length":25}'`
|
`mosquitto_pub -t home/OpenMQTTGateway_MEGA/commands/MQTTtoONOFF -m '{"gpio":15,"cmd":"low_pulse","pulse_length":25}'`
|
||||||
|
|
||||||
Be aware that outputs are OFF by default when the board first start.
|
Behavior at start in case of power loss (ESP32 only):
|
||||||
|
The module will record per default the last state of the actuator and attempt to recover it upon restart.
|
||||||
|
Example: if your relay is ON and a power outage occurs, when the power comes back the firmware will attempt to switch ON the relay again.
|
||||||
|
|
||||||
|
If you don't want this behavior you can set the macro `USE_LAST_STATE_ON_RESTART` to `false` at build time or use the command below at runtime:
|
||||||
|
`mosquitto_pub -t home/OpenMQTTGateway_MEGA/commands/MQTTtoONOFF/config -m '{"uselaststate":false,"save":true}"'`
|
||||||
|
The key `save` will persist the configuration upon restarts.
|
||||||
|
|
||||||
## FASTLED
|
## FASTLED
|
||||||
### The FASTLED module support 2 different operation modes
|
### The FASTLED module support 2 different operation modes
|
||||||
|
|||||||
+111
-8
@@ -30,22 +30,90 @@
|
|||||||
|
|
||||||
#ifdef ZactuatorONOFF
|
#ifdef ZactuatorONOFF
|
||||||
|
|
||||||
|
# ifdef ESP32
|
||||||
|
// Global struct to store live ONOFF configuration data
|
||||||
|
ONOFFConfig_s ONOFFConfig;
|
||||||
|
|
||||||
|
void ONOFFConfig_init() {
|
||||||
|
ONOFFConfig.ONOFFState = !ACTUATOR_ON;
|
||||||
|
ONOFFConfig.useLastStateOnStart = USE_LAST_STATE_ON_RESTART;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ONOFFConfig_fromJson(JsonObject& ONOFFdata) {
|
||||||
|
Config_update(ONOFFdata, "uselaststate", ONOFFConfig.useLastStateOnStart);
|
||||||
|
Config_update(ONOFFdata, "cmd", ONOFFConfig.ONOFFState);
|
||||||
|
|
||||||
|
if (ONOFFdata.containsKey("erase") && ONOFFdata["erase"].as<bool>()) {
|
||||||
|
// Erase config from NVS (non-volatile storage)
|
||||||
|
preferences.begin(Gateway_Short_Name, false);
|
||||||
|
preferences.remove("ONOFFConfig");
|
||||||
|
preferences.end();
|
||||||
|
Log.notice(F("ONOFF config erased" CR));
|
||||||
|
return; // Erase prevails on save, so skipping save
|
||||||
|
}
|
||||||
|
if (ONOFFdata.containsKey("save") && ONOFFdata["save"].as<bool>()) {
|
||||||
|
StaticJsonDocument<JSON_MSG_BUFFER> jsonBuffer;
|
||||||
|
JsonObject jo = jsonBuffer.to<JsonObject>();
|
||||||
|
jo["uselaststate"] = ONOFFConfig.useLastStateOnStart;
|
||||||
|
jo["cmd"] = ONOFFConfig.ONOFFState;
|
||||||
|
// Save config into NVS (non-volatile storage)
|
||||||
|
String conf = "";
|
||||||
|
serializeJson(jsonBuffer, conf);
|
||||||
|
preferences.begin(Gateway_Short_Name, false);
|
||||||
|
preferences.putString("ONOFFConfig", conf);
|
||||||
|
preferences.end();
|
||||||
|
Log.notice(F("ONOFF config saved" CR));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ONOFFConfig_load() {
|
||||||
|
StaticJsonDocument<JSON_MSG_BUFFER> jsonBuffer;
|
||||||
|
preferences.begin(Gateway_Short_Name, true);
|
||||||
|
auto error = deserializeJson(jsonBuffer, preferences.getString("ONOFFConfig", "{}"));
|
||||||
|
preferences.end();
|
||||||
|
if (error) {
|
||||||
|
Log.error(F("ONOFF config deserialization failed: %s, buffer capacity: %u" CR), error.c_str(), jsonBuffer.capacity());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (jsonBuffer.isNull()) {
|
||||||
|
Log.warning(F("ONOFF config is null" CR));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
JsonObject jo = jsonBuffer.as<JsonObject>();
|
||||||
|
ONOFFConfig_fromJson(jo);
|
||||||
|
Log.notice(F("ONOFF config loaded" CR));
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
void ONOFFConfig_init(){};
|
||||||
|
void ONOFFConfig_fromJson(JsonObject& ONOFFdata){};
|
||||||
|
void ONOFFConfig_load(){};
|
||||||
|
# endif
|
||||||
|
|
||||||
void setupONOFF() {
|
void setupONOFF() {
|
||||||
# ifdef MAX_CURRENT_ACTUATOR
|
# ifdef MAX_CURRENT_ACTUATOR
|
||||||
xTaskCreate(overLimitCurrent, "overLimitCurrent", 2500, NULL, 10, NULL);
|
xTaskCreate(overLimitCurrent, "overLimitCurrent", 4000, NULL, 10, NULL);
|
||||||
# endif
|
# endif
|
||||||
# ifdef MAX_TEMP_ACTUATOR
|
# ifdef MAX_TEMP_ACTUATOR
|
||||||
xTaskCreate(overLimitTemp, "overLimitTemp", 2500, NULL, 10, NULL);
|
xTaskCreate(overLimitTemp, "overLimitTemp", 4000, NULL, 10, NULL);
|
||||||
|
# endif
|
||||||
|
# ifdef ESP32
|
||||||
|
ONOFFConfig_init();
|
||||||
|
ONOFFConfig_load();
|
||||||
|
Log.notice(F("Target state on restart: %T" CR), ONOFFConfig.ONOFFState);
|
||||||
|
Log.notice(F("Use last state on restart: %T" CR), ONOFFConfig.useLastStateOnStart);
|
||||||
# endif
|
# endif
|
||||||
pinMode(ACTUATOR_ONOFF_GPIO, OUTPUT);
|
pinMode(ACTUATOR_ONOFF_GPIO, OUTPUT);
|
||||||
|
# ifdef ACTUATOR_ONOFF_DEFAULT
|
||||||
|
digitalWrite(ACTUATOR_ONOFF_GPIO, ACTUATOR_ONOFF_DEFAULT);
|
||||||
|
# elif defined(ESP32)
|
||||||
|
if (ONOFFConfig.useLastStateOnStart)
|
||||||
|
digitalWrite(ACTUATOR_ONOFF_GPIO, ONOFFConfig.ONOFFState);
|
||||||
|
# endif
|
||||||
if (digitalRead(ACTUATOR_ONOFF_GPIO) == ACTUATOR_ON) {
|
if (digitalRead(ACTUATOR_ONOFF_GPIO) == ACTUATOR_ON) {
|
||||||
PowerIndicatorON();
|
PowerIndicatorON();
|
||||||
} else {
|
} else {
|
||||||
PowerIndicatorOFF();
|
PowerIndicatorOFF();
|
||||||
}
|
}
|
||||||
# ifdef ACTUATOR_ONOFF_DEFAULT
|
|
||||||
digitalWrite(ACTUATOR_ONOFF_GPIO, ACTUATOR_ONOFF_DEFAULT);
|
|
||||||
# endif
|
|
||||||
Log.trace(F("ZactuatorONOFF setup done" CR));
|
Log.trace(F("ZactuatorONOFF setup done" CR));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,6 +133,13 @@ void MQTTtoONOFF(char* topicOri, JsonObject& ONOFFdata) {
|
|||||||
} else {
|
} else {
|
||||||
PowerIndicatorOFF();
|
PowerIndicatorOFF();
|
||||||
}
|
}
|
||||||
|
# ifdef ESP32
|
||||||
|
if (ONOFFConfig.useLastStateOnStart) {
|
||||||
|
ONOFFdata["save"] = true;
|
||||||
|
ONOFFConfig_fromJson(ONOFFdata);
|
||||||
|
ONOFFdata.remove("save");
|
||||||
|
}
|
||||||
|
# endif
|
||||||
// we acknowledge the sending by publishing the value to an acknowledgement topic
|
// we acknowledge the sending by publishing the value to an acknowledgement topic
|
||||||
pub(subjectGTWONOFFtoMQTT, ONOFFdata);
|
pub(subjectGTWONOFFtoMQTT, ONOFFdata);
|
||||||
} else {
|
} else {
|
||||||
@@ -91,6 +166,25 @@ void MQTTtoONOFF(char* topicOri, JsonObject& ONOFFdata) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (cmpToMainTopic(topicOri, subjectMQTTtoONOFFset)) {
|
||||||
|
Log.trace(F("MQTTtoONOFF json set" CR));
|
||||||
|
/*
|
||||||
|
* Configuration modifications priorities:
|
||||||
|
* First `init=true` and `load=true` commands are executed (if both are present, INIT prevails on LOAD)
|
||||||
|
* Then parameters included in json are taken in account
|
||||||
|
* Finally `erase=true` and `save=true` commands are executed (if both are present, ERASE prevails on SAVE)
|
||||||
|
*/
|
||||||
|
if (ONOFFdata.containsKey("init") && ONOFFdata["init"].as<bool>()) {
|
||||||
|
// Restore the default (initial) configuration
|
||||||
|
ONOFFConfig_init();
|
||||||
|
} else if (ONOFFdata.containsKey("load") && ONOFFdata["load"].as<bool>()) {
|
||||||
|
// Load the saved configuration, if not initialised
|
||||||
|
ONOFFConfig_load();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load config from json if available
|
||||||
|
ONOFFConfig_fromJson(ONOFFdata);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
@@ -135,7 +229,7 @@ void overLimitTemp(void* pvParameters) {
|
|||||||
Log.trace(F("Internal temperature of the ESP32 %F" CR), internalTempc);
|
Log.trace(F("Internal temperature of the ESP32 %F" CR), internalTempc);
|
||||||
// We switch OFF the actuator if the temperature of the ESP32 is more than MAX_TEMP_ACTUATOR two consecutive times, so as to avoid false single readings to trigger the relay OFF.
|
// We switch OFF the actuator if the temperature of the ESP32 is more than MAX_TEMP_ACTUATOR two consecutive times, so as to avoid false single readings to trigger the relay OFF.
|
||||||
if (internalTempc > MAX_TEMP_ACTUATOR && previousInternalTempc > MAX_TEMP_ACTUATOR) {
|
if (internalTempc > MAX_TEMP_ACTUATOR && previousInternalTempc > MAX_TEMP_ACTUATOR) {
|
||||||
if (digitalRead(ACTUATOR_ONOFF_GPIO) == ACTUATOR_ON) { // This could be with thew previous condition, but it is better to trigger the digitalRead only if the previous condition is met
|
if (digitalRead(ACTUATOR_ONOFF_GPIO) == ACTUATOR_ON) { // This could be with the previous condition, but it is better to trigger the digitalRead only if the previous condition is met to avoid the digitalRead
|
||||||
Log.error(F("[ActuatorONOFF] OverTemperature detected ( %F > %F ) switching OFF Actuator" CR), internalTempc, MAX_TEMP_ACTUATOR);
|
Log.error(F("[ActuatorONOFF] OverTemperature detected ( %F > %F ) switching OFF Actuator" CR), internalTempc, MAX_TEMP_ACTUATOR);
|
||||||
ActuatorTrigger();
|
ActuatorTrigger();
|
||||||
CriticalIndicatorON();
|
CriticalIndicatorON();
|
||||||
@@ -152,16 +246,18 @@ void overLimitTemp(void* pvParameters) {
|
|||||||
# ifdef MAX_CURRENT_ACTUATOR
|
# ifdef MAX_CURRENT_ACTUATOR
|
||||||
void overLimitCurrent(void* pvParameters) {
|
void overLimitCurrent(void* pvParameters) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
static float previousCurrent = 0;
|
||||||
float current = getRN8209current();
|
float current = getRN8209current();
|
||||||
Log.trace(F("RN8209 Current %F" CR), current);
|
Log.trace(F("RN8209 Current %F" CR), current);
|
||||||
// We switch OFF the actuator if the current of the RN8209 is more than MAX_CURRENT_ACTUATOR.
|
// We switch OFF the actuator if the current of the RN8209 is more than MAX_CURRENT_ACTUATOR.
|
||||||
if (current > MAX_CURRENT_ACTUATOR) {
|
if (current > MAX_CURRENT_ACTUATOR && previousCurrent > MAX_CURRENT_ACTUATOR) {
|
||||||
if (digitalRead(ACTUATOR_ONOFF_GPIO) == ACTUATOR_ON) { // This could be with thew previous condition, but it is better to trigger the digitalRead only if the previous condition is met
|
if (digitalRead(ACTUATOR_ONOFF_GPIO) == ACTUATOR_ON) { // This could be with the previous condition, but it is better to trigger the digitalRead only if the previous condition is met to avoid the digitalRead
|
||||||
Log.error(F("[ActuatorONOFF] OverCurrent detected ( %F > %F ) switching OFF Actuator" CR), current, MAX_CURRENT_ACTUATOR);
|
Log.error(F("[ActuatorONOFF] OverCurrent detected ( %F > %F ) switching OFF Actuator" CR), current, MAX_CURRENT_ACTUATOR);
|
||||||
ActuatorTrigger();
|
ActuatorTrigger();
|
||||||
CriticalIndicatorON();
|
CriticalIndicatorON();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
previousCurrent = current;
|
||||||
vTaskDelay(TimeBetweenReadingCurrent);
|
vTaskDelay(TimeBetweenReadingCurrent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -185,6 +281,13 @@ void ActuatorTrigger() {
|
|||||||
StaticJsonDocument<JSON_MSG_BUFFER> jsonBuffer;
|
StaticJsonDocument<JSON_MSG_BUFFER> jsonBuffer;
|
||||||
JsonObject ONOFFdata = jsonBuffer.to<JsonObject>();
|
JsonObject ONOFFdata = jsonBuffer.to<JsonObject>();
|
||||||
ONOFFdata["cmd"] = (int)level;
|
ONOFFdata["cmd"] = (int)level;
|
||||||
|
# ifdef ESP32
|
||||||
|
if (ONOFFConfig.useLastStateOnStart) {
|
||||||
|
ONOFFdata["save"] = true;
|
||||||
|
ONOFFConfig_fromJson(ONOFFdata);
|
||||||
|
ONOFFdata.remove("save");
|
||||||
|
}
|
||||||
|
# endif
|
||||||
pub(subjectGTWONOFFtoMQTT, ONOFFdata);
|
pub(subjectGTWONOFFtoMQTT, ONOFFdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
-30
@@ -101,20 +101,6 @@ void BTConfig_init() {
|
|||||||
unsigned long timeBetweenConnect = 0;
|
unsigned long timeBetweenConnect = 0;
|
||||||
unsigned long timeBetweenActive = 0;
|
unsigned long timeBetweenActive = 0;
|
||||||
|
|
||||||
template <typename T> // Declared here to avoid pre-compilation issue (missing "template" in auto declaration by pio)
|
|
||||||
void BTConfig_update(JsonObject& data, const char* key, T& var);
|
|
||||||
template <typename T>
|
|
||||||
void BTConfig_update(JsonObject& data, const char* key, T& var) {
|
|
||||||
if (data.containsKey(key)) {
|
|
||||||
if (var != data[key].as<T>()) {
|
|
||||||
var = data[key].as<T>();
|
|
||||||
Log.notice(F("BT config %s changed: %s" CR), key, data[key].as<String>());
|
|
||||||
} else {
|
|
||||||
Log.notice(F("BT config %s unchanged: %s" CR), key, data[key].as<String>());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void stateBTMeasures(bool start) {
|
void stateBTMeasures(bool start) {
|
||||||
StaticJsonDocument<JSON_MSG_BUFFER> jsonBuffer;
|
StaticJsonDocument<JSON_MSG_BUFFER> jsonBuffer;
|
||||||
JsonObject jo = jsonBuffer.to<JsonObject>();
|
JsonObject jo = jsonBuffer.to<JsonObject>();
|
||||||
@@ -150,7 +136,7 @@ void stateBTMeasures(bool start) {
|
|||||||
|
|
||||||
void BTConfig_fromJson(JsonObject& BTdata, bool startup = false) {
|
void BTConfig_fromJson(JsonObject& BTdata, bool startup = false) {
|
||||||
// Attempts to connect to eligible devices or not
|
// Attempts to connect to eligible devices or not
|
||||||
BTConfig_update(BTdata, "bleconnect", BTConfig.bleConnect);
|
Config_update(BTdata, "bleconnect", BTConfig.bleConnect);
|
||||||
// Identify AdaptiveScan deactivation to pass to continuous mode
|
// Identify AdaptiveScan deactivation to pass to continuous mode
|
||||||
if (startup == false) {
|
if (startup == false) {
|
||||||
if (BTdata.containsKey("adaptivescan") && BTdata["adaptivescan"] == false && BTConfig.adaptiveScan == true) {
|
if (BTdata.containsKey("adaptivescan") && BTdata["adaptivescan"] == false && BTConfig.adaptiveScan == true) {
|
||||||
@@ -161,37 +147,37 @@ void BTConfig_fromJson(JsonObject& BTdata, bool startup = false) {
|
|||||||
BTdata["intervalacts"] = TimeBtwActive;
|
BTdata["intervalacts"] = TimeBtwActive;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BTConfig_update(BTdata, "adaptivescan", BTConfig.adaptiveScan);
|
Config_update(BTdata, "adaptivescan", BTConfig.adaptiveScan);
|
||||||
// Time before before active scan
|
// Time before before active scan
|
||||||
// Scan interval set
|
// Scan interval set
|
||||||
if (BTdata.containsKey("interval") && BTdata["interval"] != 0)
|
if (BTdata.containsKey("interval") && BTdata["interval"] != 0)
|
||||||
BTConfig_update(BTdata, "interval", BTConfig.BLEinterval);
|
Config_update(BTdata, "interval", BTConfig.BLEinterval);
|
||||||
// Define if the scan is adaptive or not
|
// Define if the scan is adaptive or not
|
||||||
BTConfig_update(BTdata, "intervalacts", BTConfig.intervalActiveScan);
|
Config_update(BTdata, "intervalacts", BTConfig.intervalActiveScan);
|
||||||
// Time before a connect set
|
// Time before a connect set
|
||||||
BTConfig_update(BTdata, "intervalcnct", BTConfig.intervalConnect);
|
Config_update(BTdata, "intervalcnct", BTConfig.intervalConnect);
|
||||||
// publish all BLE devices discovered or only the identified sensors (like temperature sensors)
|
// publish all BLE devices discovered or only the identified sensors (like temperature sensors)
|
||||||
BTConfig_update(BTdata, "onlysensors", BTConfig.pubOnlySensors);
|
Config_update(BTdata, "onlysensors", BTConfig.pubOnlySensors);
|
||||||
// Home Assistant presence message
|
// Home Assistant presence message
|
||||||
BTConfig_update(BTdata, "hasspresence", BTConfig.presenceEnable);
|
Config_update(BTdata, "hasspresence", BTConfig.presenceEnable);
|
||||||
// Home Assistant presence message topic
|
// Home Assistant presence message topic
|
||||||
BTConfig_update(BTdata, "presenceTopic", BTConfig.presenceTopic);
|
Config_update(BTdata, "presenceTopic", BTConfig.presenceTopic);
|
||||||
// Home Assistant presence message use iBeacon UUID
|
// Home Assistant presence message use iBeacon UUID
|
||||||
BTConfig_update(BTdata, "presenceUseBeaconUuid", BTConfig.presenceUseBeaconUuid);
|
Config_update(BTdata, "presenceUseBeaconUuid", BTConfig.presenceUseBeaconUuid);
|
||||||
// MinRSSI set
|
// MinRSSI set
|
||||||
BTConfig_update(BTdata, "minrssi", BTConfig.minRssi);
|
Config_update(BTdata, "minrssi", BTConfig.minRssi);
|
||||||
// Send undecoded device data
|
// Send undecoded device data
|
||||||
BTConfig_update(BTdata, "extDecoderEnable", BTConfig.extDecoderEnable);
|
Config_update(BTdata, "extDecoderEnable", BTConfig.extDecoderEnable);
|
||||||
// Topic to send undecoded device data
|
// Topic to send undecoded device data
|
||||||
BTConfig_update(BTdata, "extDecoderTopic", BTConfig.extDecoderTopic);
|
Config_update(BTdata, "extDecoderTopic", BTConfig.extDecoderTopic);
|
||||||
// Sets whether to filter publishing
|
// Sets whether to filter publishing
|
||||||
BTConfig_update(BTdata, "filterConnectable", BTConfig.filterConnectable);
|
Config_update(BTdata, "filterConnectable", BTConfig.filterConnectable);
|
||||||
// Publish advertisment data
|
// Publish advertisment data
|
||||||
BTConfig_update(BTdata, "pubadvdata", BTConfig.pubAdvData);
|
Config_update(BTdata, "pubadvdata", BTConfig.pubAdvData);
|
||||||
// Use iBeacon UUID as topic, instead of sender (random) MAC address
|
// Use iBeacon UUID as topic, instead of sender (random) MAC address
|
||||||
BTConfig_update(BTdata, "pubBeaconUuidForTopic", BTConfig.pubBeaconUuidForTopic);
|
Config_update(BTdata, "pubBeaconUuidForTopic", BTConfig.pubBeaconUuidForTopic);
|
||||||
// Disable Whitelist & Blacklist
|
// Disable Whitelist & Blacklist
|
||||||
BTConfig_update(BTdata, "ignoreWBlist", (BTConfig.ignoreWBlist));
|
Config_update(BTdata, "ignoreWBlist", (BTConfig.ignoreWBlist));
|
||||||
|
|
||||||
stateBTMeasures(startup);
|
stateBTMeasures(startup);
|
||||||
|
|
||||||
|
|||||||
@@ -33,9 +33,14 @@ extern void MQTTtoONOFF(char* topicOri, JsonObject& RFdata);
|
|||||||
/*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/
|
/*-------------DEFINE YOUR MQTT PARAMETERS BELOW----------------*/
|
||||||
#define subjectMQTTtoONOFF "/commands/MQTTtoONOFF"
|
#define subjectMQTTtoONOFF "/commands/MQTTtoONOFF"
|
||||||
#define subjectGTWONOFFtoMQTT "/ONOFFtoMQTT"
|
#define subjectGTWONOFFtoMQTT "/ONOFFtoMQTT"
|
||||||
|
#define subjectMQTTtoONOFFset "/commands/MQTTtoONOFF/config"
|
||||||
|
|
||||||
#define ONKey "setON"
|
#define ONKey "setON"
|
||||||
#define OFFKey "setOFF"
|
#define OFFKey "setOFF"
|
||||||
|
|
||||||
|
#ifndef USE_LAST_STATE_ON_RESTART
|
||||||
|
# define USE_LAST_STATE_ON_RESTART true // Define if we use the last state upon a power restart
|
||||||
|
#endif
|
||||||
#ifndef ACTUATOR_ON
|
#ifndef ACTUATOR_ON
|
||||||
# define ACTUATOR_ON LOW // LOW or HIGH, set to the output level of the GPIO pin to turn the actuator on.
|
# define ACTUATOR_ON LOW // LOW or HIGH, set to the output level of the GPIO pin to turn the actuator on.
|
||||||
#endif
|
#endif
|
||||||
@@ -71,4 +76,15 @@ extern void MQTTtoONOFF(char* topicOri, JsonObject& RFdata);
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
/*----------------CONFIGURABLE PARAMETERS-----------------*/
|
||||||
|
struct ONOFFConfig_s {
|
||||||
|
bool ONOFFState; // Recorded actuator state
|
||||||
|
bool useLastStateOnStart; // Do we use the recorded actuator state on start
|
||||||
|
};
|
||||||
|
|
||||||
|
// Global struct to store live ONOFF configuration data
|
||||||
|
extern ONOFFConfig_s ONOFFConfig;
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -279,6 +279,20 @@ ESP8266WiFiMulti wifiMulti;
|
|||||||
// client link to pubsub MQTT
|
// client link to pubsub MQTT
|
||||||
PubSubClient client;
|
PubSubClient client;
|
||||||
|
|
||||||
|
template <typename T> // Declared here to avoid pre-compilation issue (missing "template" in auto declaration by pio)
|
||||||
|
void Config_update(JsonObject& data, const char* key, T& var);
|
||||||
|
template <typename T>
|
||||||
|
void Config_update(JsonObject& data, const char* key, T& var) {
|
||||||
|
if (data.containsKey(key)) {
|
||||||
|
if (var != data[key].as<T>()) {
|
||||||
|
var = data[key].as<T>();
|
||||||
|
Log.notice(F("Config %s changed: %s" CR), key, data[key].as<String>());
|
||||||
|
} else {
|
||||||
|
Log.notice(F("Config %s unchanged: %s" CR), key, data[key].as<String>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void revert_hex_data(const char* in, char* out, int l) {
|
void revert_hex_data(const char* in, char* out, int l) {
|
||||||
//reverting array 2 by 2 to get the data in good order
|
//reverting array 2 by 2 to get the data in good order
|
||||||
int i = l - 2, j = 0;
|
int i = l - 2, j = 0;
|
||||||
|
|||||||
Reference in new issue
Block a user