feat(boards): add device detection and text scrolling support

This commit is contained in:
2026-02-19 21:46:33 -08:00
parent 913373ca72
commit 66f09c3468
12 changed files with 290 additions and 11 deletions

View File

@@ -304,8 +304,10 @@ void DoorbellLogic::onSerialCommand(const String& cmd) {
Serial.println();
Serial.printf("[NET] %s RSSI:%d IP:%s\n", _state.wifiSsid.c_str(), _state.wifiRssi,
_state.ipAddr.c_str());
} else if(cmd == "board") {
Serial.printf("[BOARD] %s\n", _board);
} else
Serial.println(F("[CMD] alert|silence|reboot|dashboard|off|status"));
Serial.println(F("[CMD] alert|silence|reboot|dashboard|off|status|board"));
}
void DoorbellLogic::setScreen(ScreenID s) {

View File

@@ -23,6 +23,7 @@ public:
void processSerial();
const ScreenState& getScreenState() const { return _state; }
const char* getBoard() const { return _board; }
/// Externally trigger silence (e.g. hold-to-silence gesture).
void silenceAlert();

View File

@@ -1,5 +1,6 @@
#pragma once
#include <Arduino.h>
#include <cstdint>
struct Layout {
@@ -36,6 +37,89 @@ struct Layout {
uint16_t y = row * (tileH + gap);
return Layout(x, y, tileW, tileH);
}
Layout clamp(uint16_t maxW, uint16_t maxH) const {
return Layout(
x < maxW ? x : maxW, y < maxH ? y : maxH, w <= maxW ? w : maxW, h <= maxH ? h : maxH);
}
Layout padded(uint16_t padding) const {
uint16_t newX = x + padding;
uint16_t newY = y + padding;
uint16_t newW = w > 2 * padding ? w - 2 * padding : 0;
uint16_t newH = h > 2 * padding ? h - 2 * padding : 0;
return Layout(newX, newY, newW, newH);
}
bool contains(uint16_t px, uint16_t py) const {
return px >= x && px < x + w && py >= y && py < y + h;
}
};
class TextScroller {
public:
TextScroller()
: _text()
, _scrollOffset(0)
, _lastUpdateMs(0)
, _scrollSpeed(50)
, _pauseMs(2000) { }
void setText(const char* text) {
if(text != _text.c_str()) {
_text = text;
_scrollOffset = 0;
_lastUpdateMs = 0;
_paused = false;
}
}
void setScrollSpeed(uint16_t msPerPixel) { _scrollSpeed = msPerPixel; }
void setPauseDuration(uint16_t ms) { _pauseMs = ms; }
template <typename DrawFn> void render(DrawFn draw, uint16_t maxWidth) {
uint32_t now = millis();
if(_text.length() <= maxWidth / 8) {
draw(0, _text.c_str());
return;
}
if(!_paused && now - _lastUpdateMs > _scrollSpeed) {
_scrollOffset++;
_lastUpdateMs = now;
if(_scrollOffset > (int)_text.length() * 6) {
_paused = true;
_pauseStartMs = now;
}
}
if(_paused && now - _pauseStartMs > _pauseMs) {
_paused = false;
_scrollOffset = 0;
_lastUpdateMs = now;
}
int16_t x = -_scrollOffset;
char buf[2] = { 0 };
for(size_t i = 0; i < _text.length(); i++) {
buf[0] = _text.charAt(i);
if(x + 8 > 0 && x < (int)maxWidth) {
draw(x, buf);
}
x += 6;
}
}
private:
String _text;
int16_t _scrollOffset;
uint32_t _lastUpdateMs;
uint32_t _pauseStartMs;
uint16_t _scrollSpeed;
uint16_t _pauseMs;
bool _paused;
};
struct TileMetrics {