diff --git a/include/devices.h b/include/devices.h index 1bd3fe5..9c1e90c 100644 --- a/include/devices.h +++ b/include/devices.h @@ -37,13 +37,13 @@ namespace Devices { auto brightnessMqtt = Builder::instance(new Number{ "Brightness", "brightness", [](const char* msg) { - Display::Brightness::set(String{ msg }.toInt()); + Display::brightness = String{ msg }.toInt(); } - }).withMin(BRIGHTNESS_MIN).withMax(BRIGHTNESS_MAX).withStep(BRIGHTNESS_STEP).restoreStateFromCommand().build(); + }).withMin(Display::Brightness::MIN).withMax(Display::Brightness::MAX).withStep(1).restoreStateFromCommand().build(); auto hourFormatMqtt = Builder::instance(new Switch{ "Format 24h", "format_24h", [](const char* msg) { - strcmp("ON", msg) == 0 ? Display::changeHourFormat24(true) : Display::changeHourFormat24(false); + Display::hourFormat24 = (strcmp("ON", msg) == 0); } }).restoreStateFromCommand().build(); Number* displayTimerMqtt = Builder::instance(new Number{ "Timer duration", "timer_duration", @@ -131,14 +131,14 @@ namespace Devices { } void setup() { - Display::hourFormatChangedCallback = []{ + Display::hourFormat24.registerCallback([]{ hourFormatMqtt->updateState(Display::hourFormat24); - }; - Display::Brightness::brightnessChangedCallback = []{ - brightnessMqtt->updateState(Display::Brightness::current); - }; - Display::Timer::remainingCallback = [](int8 current){ + }); + Display::brightness.registerCallback([]{ + brightnessMqtt->updateState(Display::brightness); + }); + Display::Timer::timer.registerCallback([](int8 current){ timerRemainingMqtt->updateState(to_string(current).c_str()); - }; + }); } } \ No newline at end of file diff --git a/include/display.h b/include/display.h index dce6e48..6e798e4 100644 --- a/include/display.h +++ b/include/display.h @@ -8,17 +8,23 @@ #include "bme.h" #define DISPLAY_ADDRESS 0x70 -#define BRIGHTNESS_MIN 0 -#define BRIGHTNESS_MAX 15 -#define BRIGHTNESS_STEP 1 -#define BRIGHTNESS_NIGHT BRIGHTNESS_MIN -#define BRIGHTNESS_DAY 11 #define MILLISECONDS(value) value*TASK_MILLISECOND #define SECONDS(value) value*TASK_SECOND #define MINUTES(value) value*TASK_MINUTE #define DISPLAY_SENSOR_ITERATIONS 2+1 #define DISPLAY_DELAY (SECONDS(2)) +typedef void (*callback_t)(); + +template +struct CallbackAware { + void registerCallback(T f) { + callback = f; + } +protected: + T callback; +}; + namespace Display { void displayTime(); @@ -56,35 +62,77 @@ namespace Display { tDisplayTime.enable(); }); - bool hourFormat24 = false; - void (*hourFormatChangedCallback)(); + struct HourFormat : public CallbackAware { + + operator bool() { + return format24; + } + + void operator=(bool value) { + format24 = value; + tDisplayTime.restart(); + if (callback) callback(); + } + private: + bool format24 = false; + } hourFormat24; // Create display object Adafruit_7segment clockDisplay = Adafruit_7segment(); - namespace Brightness { - uint8_t current = BRIGHTNESS_NIGHT; - void (*brightnessChangedCallback)(); + struct Brightness : public CallbackAware { + static constexpr uint8 MIN = 0; + static constexpr uint8 MAX = 15; + static constexpr uint8 DAY = 11; + static constexpr uint8 NIGHT = MIN; - void set(uint8_t value) { - current = value % (BRIGHTNESS_MAX + 1); + void operator=(uint8 value) { + current = value % (MAX + 1); clockDisplay.setBrightness(current); - if (brightnessChangedCallback) brightnessChangedCallback(); + if (callback) callback(); } - void change(bool increase) { - increase ? set(current + BRIGHTNESS_STEP) : set(current - BRIGHTNESS_STEP); + operator uint8() { + return current; } - } + + private: + uint8 current = NIGHT; + } brightness; namespace Timer { - int8 timer = 0, current = 0; - void (*remainingCallback)(int8); + typedef void (*remaining_callback_t)(int8); + struct : public CallbackAware { + + void operator=(int8 value) { + initial = remaining = value; + } + + operator int8() { + return remaining; + } + + void start() { + remaining = initial + 1; + } + + void decrease() { + remaining--; + if (callback) callback(remaining); + } + + bool atBeginning() { + return initial == remaining; + } + + private: + int8 initial = 0, remaining = 0; + } timer; Task tDisplayTimer(SECONDS(10), TASK_ONCE + 1, []{ - if (current >= 0) { - clockDisplay.print(current, DEC); + if (timer >= 0) { + clockDisplay.print(timer, DEC); clockDisplay.writeDisplay(); } }, &ts, false, @@ -100,18 +148,17 @@ namespace Display { Task tTimer(MINUTES(1), TASK_FOREVER, []{ static constexpr uint8 threshold = 16; - current--; - if (current == timer) { + timer.decrease(); + if (timer.atBeginning()) { if (timer <= threshold) tDisplayTimer.setIterations(TASK_FOREVER); tDisplayTimer.restart(); - } else if (current == threshold) { + } else if (timer == threshold) { tDisplayTimer.setIterations(TASK_FOREVER); tDisplayTimer.restart(); } - if (remainingCallback) remainingCallback(current); }, &ts, false, []{ - current = timer+1; + timer.start(); return true; }, []{ @@ -155,11 +202,11 @@ namespace Display { Ntp::tUpdateTime.restart(); } if (currentHour == 8) { - Brightness::set(BRIGHTNESS_DAY); + brightness = Brightness::DAY; Wifi::tConnect.enable(); } if (currentHour == 17) { - Brightness::set(BRIGHTNESS_NIGHT); + brightness = Brightness::NIGHT; } } static int currentMin = -1; @@ -194,7 +241,7 @@ namespace Display { tDisplaySensor.setCallback(&displayTemp); } - void displayValue(uint8_t value) { + void displayValue(uint8 value) { tDisplayTime.disable(); clockDisplay.print(value, HEX); clockDisplay.writeDisplay(); @@ -224,15 +271,9 @@ namespace Display { clockDisplay.writeDisplay(); } - void changeHourFormat24(bool format24) { - hourFormat24 = format24; - tDisplayTime.restart(); - if (hourFormatChangedCallback) hourFormatChangedCallback(); - } - void setup() { clockDisplay.begin(DISPLAY_ADDRESS); - clockDisplay.setBrightness(Brightness::current); + clockDisplay.setBrightness(brightness); tDisplayTime.enable(); } }