Files
roro9stack/src/services/power_service.cpp
T
twislaandClaude Opus 5.5 de8af6ed92
CI / build (pull_request) Successful in 1m52s
Site / build (pull_request) Successful in 12s
Notes: edit a text file of any size (#47)
The editor held the whole note in memory and stopped at 16 KB. It now keeps
a window of the file around the cursor, and the rest on the card as a list
of pieces (notes::NoteDocument). Memory with a note open is what it was.

Up to 64 KB a save rewrites the file, as before. Above, the five-second
save appends what changed to <note>.edit, and the file is rewritten on
leaving the note, with a progress bar. After a power cut, opening the note
picks the edit up where it was saved; a rewrite cut short is finished or
dropped, never half applied.

Also: Ctrl with Fn+Up/Down go to the start and end of the note; the
consoles' `key` command takes ctrl-, alt- and shift-; the Storage App's
`e` no longer refuses a big file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
2026-10-07 15:39:45 +02:00

63 lines
2.1 KiB
C++

#include "power_service.h"
#include <M5Cardputer.h>
#include <esp_sleep.h>
#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() {
poweringOff_ = true;
if (beforePowerOff) beforePowerOff();
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<gpio_num_t>(pins::kButtonG0), 0);
esp_deep_sleep_start();
}
} // namespace roro