#include "power_service.h" #include #include #include "platform/pins.h" namespace roro { PowerService::PowerService(const Settings& settings) : settings_(settings), policy_(settings.getInt(Setting::DimTimeoutS) * 1000, settings.getInt(Setting::OffTimeoutS) * 1000) {} void PowerService::start() { pinMode(pins::kButtonG0, INPUT_PULLUP); policy_.activity(millis()); applyScreen(ScreenState::On); } void PowerService::tick(uint32_t nowMs) { policy_.setTimeouts(settings_.getInt(Setting::DimTimeoutS) * 1000, settings_.getInt(Setting::OffTimeoutS) * 1000); applyScreen(policy_.update(nowMs)); bool pressed = digitalRead(pins::kButtonG0) == LOW; if (button_.update(pressed, nowMs) == ButtonAction::LongPress) powerOff(); } void PowerService::applyScreen(ScreenState state) { auto& display = M5Cardputer.Display; int percent = settings_.getInt(Setting::Brightness); int target = state == ScreenState::On ? percent : state == ScreenState::Dimmed ? percent / 4 : 0; if (state == applied_ && target == appliedBrightness_) return; if (state == ScreenState::Off) display.sleep(); else if (applied_ == ScreenState::Off) display.wakeup(); display.setBrightness(target * 255 / 100); applied_ = state; appliedBrightness_ = target; } void PowerService::powerOff() { auto& display = M5Cardputer.Display; display.wakeup(); display.setBrightness(settings_.getInt(Setting::Brightness) * 255 / 100); display.fillScreen(TFT_BLACK); display.setTextColor(TFT_WHITE); display.drawCenterString("Powering off", display.width() / 2, display.height() / 2 - 8); // G0 wakes the device on a low level, so wait for release or it would wake immediately. while (digitalRead(pins::kButtonG0) == LOW) delay(10); delay(300); display.sleep(); display.setBrightness(0); esp_sleep_enable_ext0_wakeup(static_cast(pins::kButtonG0), 0); esp_deep_sleep_start(); } } // namespace roro