Files
Flipdot-display/src/esp32/logic/display_controller.cpp
T

179 lines
3.6 KiB
C++
Raw Normal View History

#include "logic/display_controller.h"
#include "config.h"
#include "logic/schedule.h"
DisplayController::DisplayController(DisplayPower &power, Frames &frames) : _power(power), _frames(frames)
{
}
2026-10-13 01:52:34 +02:00
void DisplayController::setSettings(const ScheduleSettings &schedule, const ClockSettings &clock)
{
_schedule = schedule;
_clock = clock;
_content_revision++; // e.g. evening time changed: redraw
}
void DisplayController::setEffectTime(uint32_t ms)
{
_effect_time = ms;
}
2026-10-13 01:52:34 +02:00
void DisplayController::setPage(Page page)
{
_page = page;
_content_revision++;
}
void DisplayController::pageChanged()
{
_content_revision++;
}
void DisplayController::showLive(uint32_t now)
{
_live = true;
_live_since = now;
_content_revision++;
}
void DisplayController::stopLive()
{
_live = false;
_content_revision++;
}
bool DisplayController::liveActive() const
{
return _live;
}
void DisplayController::setPowerEnabled(bool enabled)
{
_power_enabled = enabled;
}
bool DisplayController::powerEnabled() const
{
return _power_enabled;
}
2026-10-13 01:34:04 +02:00
void DisplayController::update(uint32_t now, bool time_valid, int hour, int minute, bool wifi_connected)
{
2026-10-13 01:34:04 +02:00
if (wifi_connected)
_wifi_lost = false;
else if (!_wifi_lost)
{
_wifi_lost = true;
_wifi_lost_since = now;
}
2026-10-13 01:52:34 +02:00
bool show_no_wifi = _clock.no_wifi_screen && _wifi_lost && now - _wifi_lost_since >= NO_WIFI_SHOW_TIME;
if (_live && now - _live_since >= LIVE_TIMEOUT)
stopLive();
2026-10-13 01:34:04 +02:00
// Switched off elsewhere (power timer, Nano flashing): the Nano lost its frame
if (!_power.isOn())
_screen = Screen::Unknown;
if (_off_timer.expired(now))
{
_power.off();
_screen = Screen::Unknown;
return;
}
if (!_power_enabled)
{
if (_power.isOn())
{
_showOnce(Screen::Off);
_off_timer.request(now, CLEAR_BEFORE_OFF_TIME + _effect_time);
}
return;
}
2026-10-13 01:52:34 +02:00
// Live mode from the web UI: shown right away, whatever the time
if (_live)
{
_off_timer.cancel();
_ensureOn();
_showOnce(Screen::Live);
return;
}
// Keep the boot screen until the time is known
if (!time_valid)
return;
2026-10-13 01:52:34 +02:00
switch (scheduleFor(hour, minute, _schedule))
{
case ScheduleMode::Night:
if (_power.isOn())
{
_showOnce(Screen::Off);
_off_timer.request(now, POWER_OFF_DELAY);
}
break;
case ScheduleMode::Clock:
_off_timer.cancel();
2026-10-13 01:52:34 +02:00
_ensureOn();
if (_page == Page::Clock)
_showClock(hour, minute, show_no_wifi);
else
_showOnce(Screen::Page);
break;
case ScheduleMode::Standby:
2026-10-13 01:52:34 +02:00
// Flipdots keep their image without power, so the last image stays visible
if (_power.isOn())
_off_timer.request(now, POWER_OFF_DELAY);
break;
}
}
2026-10-13 01:52:34 +02:00
void DisplayController::_ensureOn()
{
if (_power.isOn())
return;
_power.on();
_screen = Screen::Unknown;
}
2026-10-13 01:34:04 +02:00
void DisplayController::_showClock(int hour, int minute, bool no_wifi)
{
2026-10-13 01:34:04 +02:00
Screen screen = no_wifi ? Screen::NoWifi : Screen::Clock;
2026-10-13 01:52:34 +02:00
bool evening = isEvening(hour, minute, _clock);
if (_screen == screen && _shown_hour == hour && _shown_minute == minute && _shown_evening == evening &&
_shown_revision == _content_revision)
return;
2026-10-13 01:34:04 +02:00
if (no_wifi)
_frames.noWifi(hour, minute);
else
2026-10-13 01:52:34 +02:00
_frames.clock(hour, minute, evening);
2026-10-13 01:34:04 +02:00
_screen = screen;
_shown_hour = hour;
_shown_minute = minute;
2026-10-13 01:52:34 +02:00
_shown_evening = evening;
_shown_revision = _content_revision;
}
2026-10-13 01:52:34 +02:00
// Screens without the time: only sent again when they or their content changed
void DisplayController::_showOnce(Screen screen)
{
2026-10-13 01:52:34 +02:00
if (_screen == screen && _shown_revision == _content_revision)
return;
2026-10-13 01:52:34 +02:00
switch (screen)
{
case Screen::Page:
_frames.page();
break;
case Screen::Live:
_frames.live();
break;
default:
_frames.off();
2026-10-13 01:52:34 +02:00
break;
}
_screen = screen;
_shown_revision = _content_revision;
}