diff --git a/platformio.ini b/platformio.ini index f3caa585e6..580150d16f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -134,9 +134,9 @@ build_flags = -D DECODE_LG=true ;-Dregister= # remove warnings in C++17 due to use of deprecated register keyword by the FastLED library ;; warning: this breaks framework code on ESP32-C3 and ESP32-S2 -DWLED_USE_MY_CONFIG - ; -D USERMOD_SENSORSTOMQTT - #For ADS1115 sensor uncomment following - ; -D USERMOD_ADS1115 + ;-D USERMOD_SENSORSTOMQTT # Enable Send sensor data to MQTT Usermod + ;-D USERMOD_ADS1115 # Enable ADS1115 sensor Usermod + ;-D USERMOD_LDR_DUSK_DAWN # Enable LDR Dusk Dawn Usermod build_unflags = diff --git a/usermods/LDR_Dusk_Dawn_v2/README.md b/usermods/LDR_Dusk_Dawn_v2/README.md new file mode 100755 index 0000000000..f7d81f8fd5 --- /dev/null +++ b/usermods/LDR_Dusk_Dawn_v2/README.md @@ -0,0 +1,26 @@ +# LDR_Dusk_Dawn_v2 +This usermod will obtain readings from a Light Dependent Resistor (LDR) and will turn on/off specific presets based on those readings. This is useful for exterior lighting situations where you want the lights to only be on when it is dark out. + +# Installation +Uncomment the "-D USERMOD_LDR_DUSK_DAWN" line from platformio.ini and build. +``` +build_flags = +... + ;-D USERMOD_SENSORSTOMQTT # Enable MQTT Usermod + ;-D USERMOD_ADS1115 # Enable ADS1115 sensor Usermod + -D USERMOD_LDR_DUSK_DAWN # Enable LDR Dusk Dawn Usermod +``` + +# Usermod Settings +Setting | Description | Default +--- | --- | --- +Enabled | Enable/Disable the LDR functionality. | Disabled +LDR Pin | The analog capable pin your LDR is connected to. | 34 +Threshold Minutes | The number of minutes of consistent readings above/below the on/off threshold before the LED state will change. | 5 +Threshold | The analog read value threshold from the LDR. Readings lower than this number will count towards changing the LED state to off. You can see the current LDR reading by going into the info section when LDR functionality is enabled. | 1000 +On Preset | The WLED preset to be used for the LED on state. | 1 +Off Preset | The WLED preset to be used for the LED off state. | 2 + +## Author +[@jeffwdh](https://github.com/jeffwdh) +jeffwdh@tarball.ca diff --git a/usermods/LDR_Dusk_Dawn_v2/usermod_LDR_Dusk_Dawn_v2.h b/usermods/LDR_Dusk_Dawn_v2/usermod_LDR_Dusk_Dawn_v2.h new file mode 100755 index 0000000000..9cef708487 --- /dev/null +++ b/usermods/LDR_Dusk_Dawn_v2/usermod_LDR_Dusk_Dawn_v2.h @@ -0,0 +1,122 @@ +#pragma once +#include "wled.h" + +class LDR_Dusk_Dawn_v2 : public Usermod { + private: + // Defaults + bool ldrEnabled = false; + int ldrPin = 34; //A2 on Adafruit Huzzah32 + int ldrThresholdMinutes = 5; // How many minutes of readings above/below threshold until it switches LED state + int ldrThreshold = 1000; // Readings higher than this number will turn off LED. + int ldrOnPreset = 1; // Default "On" Preset + int ldrOffPreset = 2; // Default "Off" Preset + + // Variables + bool ldrEnabledPreviously = false; // Was LDR enabled for the previous check? First check is always no. + int ldrOffCount; // Number of readings above the threshold + int ldrOnCount; // Number of readings below the threshold + int ldrReading; // Last LDR reading + int ldrLEDState; // Current LED on/off state + unsigned long lastMillis = 0; + static const char _name[]; + + public: + void setup() { + } + + void loop() { + // Only update every 10 seconds + if (millis() - lastMillis > 10000) { + if (ldrEnabled == true) { + // Default state is off + if (ldrEnabledPreviously == false) { + applyPreset(ldrOffPreset); + ldrEnabledPreviously = true; + ldrLEDState = 0; + } + + // Get LDR reading and increment counter by number of seconds since last read + ldrReading = analogRead(ldrPin); + if (ldrReading <= ldrThreshold) { + ldrOnCount = ldrOnCount + 10; + ldrOffCount = 0; + } else { + ldrOffCount = ldrOffCount + 10; + ldrOnCount = 0; + } + + if (ldrOnCount >= (ldrThresholdMinutes * 60)) { + ldrOnCount = 0; + // If LEDs were previously off, turn on + if (ldrLEDState == 0) { + applyPreset(ldrOnPreset); + ldrLEDState = 1; + } + } + + if (ldrOffCount >= (ldrThresholdMinutes * 60)) { + ldrOffCount = 0; + // If LEDs were previously on, turn off + if (ldrLEDState == 1) { + applyPreset(ldrOffPreset); + ldrLEDState = 0; + } + } + } else { + // LDR is disabled, reset variables to default + ldrReading = 0; + ldrOnCount = 0; + ldrOffCount = 0; + ldrLEDState = 0; + ldrEnabledPreviously = false; + } + lastMillis = millis(); + } + } + + void addToConfig(JsonObject& root) { + JsonObject top = root.createNestedObject(FPSTR(_name)); + top["Enabled"] = ldrEnabled; + top["LDR Pin"] = ldrPin; + top["Threshold Minutes"] = ldrThresholdMinutes; + top["Threshold"] = ldrThreshold; + top["On Preset"] = ldrOnPreset; + top["Off Preset"] = ldrOffPreset; + } + + bool readFromConfig(JsonObject& root) { + JsonObject top = root[FPSTR(_name)]; + bool configComplete = !top.isNull(); + configComplete &= getJsonValue(top["Enabled"], ldrEnabled); + configComplete &= getJsonValue(top["LDR Pin"], ldrPin); + configComplete &= getJsonValue(top["Threshold Minutes"], ldrThresholdMinutes); + configComplete &= getJsonValue(top["Threshold"], ldrThreshold); + configComplete &= getJsonValue(top["On Preset"], ldrOnPreset); + configComplete &= getJsonValue(top["Off Preset"], ldrOffPreset); + return configComplete; + } + + void addToJsonInfo(JsonObject& root) { + // If "u" object does not exist yet we need to create it + JsonObject user = root["u"]; + if (user.isNull()) user = root.createNestedObject("u"); + + JsonArray LDR_Enabled = user.createNestedArray("LDR dusk/dawn enabled"); + LDR_Enabled.add(ldrEnabled); + + JsonArray LDR_Reading = user.createNestedArray("LDR reading"); + LDR_Reading.add(ldrReading); + + JsonArray LDR_State = user.createNestedArray("LDR turned LEDs on"); + LDR_State.add(bool(ldrLEDState)); + + // Optional debug information: + //JsonArray LDR_On_Count = user.createNestedArray("LDR on count"); + //LDR_On_Count.add(ldrOnCount); + + //JsonArray LDR_Off_Count = user.createNestedArray("LDR off count"); + //LDR_Off_Count.add(ldrOffCount); + } +}; + +const char LDR_Dusk_Dawn_v2::_name[] PROGMEM = "LDR_Dusk_Dawn_v2"; diff --git a/wled00/const.h b/wled00/const.h index 6ee8345182..60d12ee2e5 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -150,6 +150,7 @@ #define USERMOD_ID_KLIPPER 40 //Usermod Klipper percentage #define USERMOD_ID_WIREGUARD 41 //Usermod "wireguard.h" #define USERMOD_ID_INTERNAL_TEMPERATURE 42 //Usermod "usermod_internal_temperature.h" +#define USERMOD_ID_LDR_DUSK_DAWN 43 //Usermod "usermod_LDR_Dusk_Dawn_V2.h" //Access point behavior #define AP_BEHAVIOR_BOOT_NO_CONN 0 //Open AP when no connection after boot diff --git a/wled00/usermods_list.cpp b/wled00/usermods_list.cpp index 6184571acc..024e2bdc9c 100644 --- a/wled00/usermods_list.cpp +++ b/wled00/usermods_list.cpp @@ -197,6 +197,9 @@ #include "../usermods/pwm_outputs/usermod_pwm_outputs.h" #endif +#ifdef USERMOD_LDR_DUSK_DAWN +#include "../usermods/LDR_Dusk_Dawn_v2/usermod_LDR_Dusk_Dawn_v2.h" +#endif void registerUsermods() { @@ -373,4 +376,8 @@ void registerUsermods() #ifdef USERMOD_INTERNAL_TEMPERATURE usermods.add(new InternalTemperatureUsermod()); #endif + + #ifdef USERMOD_LDR_DUSK_DAWN + usermods.add(new LDR_Dusk_Dawn_v2()); + #endif }