|
| 1 | +#pragma once |
| 2 | + |
| 3 | +#include "wled.h" |
| 4 | + |
| 5 | +//v2 usermod that allows to change brightness and color using a rotary encoder, |
| 6 | +//change between modes by pressing a button (many encoders have one included) |
| 7 | +class UsermodBrightnessFollowSun : public Usermod |
| 8 | +{ |
| 9 | +private: |
| 10 | + static const char _name[]; |
| 11 | + static const char _enabled[]; |
| 12 | + static const char _update_interval[]; |
| 13 | + static const char _min_bri[]; |
| 14 | + static const char _max_bri[]; |
| 15 | + static const char _relax_hour[]; |
| 16 | + |
| 17 | +private: |
| 18 | + bool enabled = false; //WLEDMM |
| 19 | + unsigned long update_interval = 60; |
| 20 | + unsigned long update_interval_ms = 60000; |
| 21 | + int min_bri = 1; |
| 22 | + int max_bri = 255; |
| 23 | + float relax_hour = 0; |
| 24 | + int relaxSec = 0; |
| 25 | + unsigned long lastUMRun = 0; |
| 26 | +public: |
| 27 | + |
| 28 | + void setup() {}; |
| 29 | + |
| 30 | + float mapFloat(float inputValue, float inMin, float inMax, float outMin, float outMax) { |
| 31 | + if (inMax == inMin) |
| 32 | + return outMin; |
| 33 | + |
| 34 | + inputValue = constrain(inputValue, inMin, inMax); |
| 35 | + |
| 36 | + return ((inputValue - inMin) * (outMax - outMin) / (inMax - inMin)) + outMin; |
| 37 | + } |
| 38 | + |
| 39 | + uint16_t getId() override |
| 40 | + { |
| 41 | + return USERMOD_ID_BRIGHTNESS_FOLLOW_SUN; |
| 42 | + } |
| 43 | + |
| 44 | + void update() |
| 45 | + { |
| 46 | + if (sunrise == 0 || sunset == 0 || localTime == 0) |
| 47 | + return; |
| 48 | + |
| 49 | + int curSec = elapsedSecsToday(localTime); |
| 50 | + int sunriseSec = elapsedSecsToday(sunrise); |
| 51 | + int sunsetSec = elapsedSecsToday(sunset); |
| 52 | + int sunMiddleSec = sunriseSec + (sunsetSec-sunriseSec)/2; |
| 53 | + |
| 54 | + int relaxSecH = sunriseSec-relaxSec; |
| 55 | + int relaxSecE = sunsetSec+relaxSec; |
| 56 | + |
| 57 | + int briSet = 0; |
| 58 | + if (curSec >= relaxSecH && curSec <= relaxSecE) { |
| 59 | + float timeMapToAngle = curSec < sunMiddleSec ? |
| 60 | + mapFloat(curSec, sunriseSec, sunMiddleSec, 0, M_PI/2.0) : |
| 61 | + mapFloat(curSec, sunMiddleSec, sunsetSec, M_PI/2.0, M_PI); |
| 62 | + float sinValue = sin_t(timeMapToAngle); |
| 63 | + briSet = min_bri + (max_bri-min_bri)*sinValue; |
| 64 | + } |
| 65 | + |
| 66 | + bri = briSet; |
| 67 | + stateUpdated(CALL_MODE_DIRECT_CHANGE); |
| 68 | +} |
| 69 | + |
| 70 | + void loop() override |
| 71 | + { |
| 72 | + if (!enabled || strip.isUpdating()) |
| 73 | + return; |
| 74 | + |
| 75 | + if (millis() - lastUMRun < update_interval_ms) |
| 76 | + return; |
| 77 | + lastUMRun = millis(); |
| 78 | + |
| 79 | + update(); |
| 80 | + } |
| 81 | + |
| 82 | + void addToConfig(JsonObject& root) |
| 83 | + { |
| 84 | + JsonObject top = root.createNestedObject(FPSTR(_name)); // usermodname |
| 85 | + |
| 86 | + top[FPSTR(_enabled)] = enabled; |
| 87 | + top[FPSTR(_update_interval)] = update_interval; |
| 88 | + top[FPSTR(_min_bri)] = min_bri; |
| 89 | + top[FPSTR(_max_bri)] = max_bri; |
| 90 | + top[FPSTR(_relax_hour)] = relax_hour; |
| 91 | + } |
| 92 | + |
| 93 | + bool readFromConfig(JsonObject& root) |
| 94 | + { |
| 95 | + JsonObject top = root[FPSTR(_name)]; |
| 96 | + if (top.isNull()) { |
| 97 | + DEBUG_PRINTF("[%s] No config found. (Using defaults.)\n", _name); |
| 98 | + return false; |
| 99 | + } |
| 100 | + |
| 101 | + bool configComplete = true; |
| 102 | + |
| 103 | + configComplete &= getJsonValue(top[FPSTR(_enabled)], enabled, false); |
| 104 | + configComplete &= getJsonValue(top[FPSTR(_update_interval)], update_interval, 60); |
| 105 | + configComplete &= getJsonValue(top[FPSTR(_min_bri)], min_bri, 1); |
| 106 | + configComplete &= getJsonValue(top[FPSTR(_max_bri)], max_bri, 255); |
| 107 | + configComplete &= getJsonValue(top[FPSTR(_relax_hour)], relax_hour, 0); |
| 108 | + |
| 109 | + update_interval = constrain(update_interval, 1, SECS_PER_HOUR); |
| 110 | + min_bri = constrain(min_bri, 1, 255); |
| 111 | + max_bri = constrain(max_bri, 1, 255); |
| 112 | + relax_hour = constrain(relax_hour, 0, 6); |
| 113 | + |
| 114 | + update_interval_ms = update_interval*1000; |
| 115 | + relaxSec = SECS_PER_HOUR*relax_hour; |
| 116 | + |
| 117 | + lastUMRun = 0; |
| 118 | + update(); |
| 119 | + |
| 120 | + return configComplete; |
| 121 | + } |
| 122 | +}; |
| 123 | + |
| 124 | + |
| 125 | +const char UsermodBrightnessFollowSun::_name[] PROGMEM = "Brightness Follow Sun"; |
| 126 | +const char UsermodBrightnessFollowSun::_enabled[] PROGMEM = "Enabled"; |
| 127 | +const char UsermodBrightnessFollowSun::_update_interval[] PROGMEM = "Update Interval Sec"; |
| 128 | +const char UsermodBrightnessFollowSun::_min_bri[] PROGMEM = "Min Brightness"; |
| 129 | +const char UsermodBrightnessFollowSun::_max_bri[] PROGMEM = "Max Brightness"; |
| 130 | +const char UsermodBrightnessFollowSun::_relax_hour[] PROGMEM = "Relax Hour"; |
0 commit comments