Public Access
Add a web UI to the clock firmware
- Web UI on port 80: live view of the display, choose the page (clock or a bitmap), bitmaps (list, show, live, edit, delete), draw / image upload with conversion in the browser, live mode, settings, Home Assistant - Live view from a shadow buffer in the BROSE9323 driver (shownPixel) - Settings in NVS with the original behaviour as defaults: schedule times, quarter hours, yawning Pikachu, No WiFi screen, flip time, status LED, Home Assistant broker (restart on change) - Bitmaps on LittleFS; new 320 KB partition, ota slots now 1.31 MB - DisplayController: pages, live mode, settings; app.cpp holds the objects - README for the recovery app; docs for the web UI - Tests: settings, time parsing, bitmap format and names, schedule with settings, pages and live mode (95 total) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c9e0800e36
commit
2b1ac12ed7
34 files changed
+1989
-117
No files matched your search
@@ -0,0 +1,58 @@
|
||||
#include "logic/settings.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "logic/bitmap_format.h"
|
||||
|
||||
static bool terminated(const char *text, int size)
|
||||
{
|
||||
return memchr(text, '\0', size) != nullptr;
|
||||
}
|
||||
|
||||
const char *validateSettings(const Settings &s)
|
||||
{
|
||||
if (!terminated(s.page, sizeof(s.page)) ||
|
||||
(strcmp(s.page, PAGE_CLOCK) != 0 && !validBitmapName(s.page)))
|
||||
return "Unknown page";
|
||||
|
||||
const ScheduleSettings &t = s.schedule;
|
||||
if (t.day_start >= MINUTES_PER_DAY || t.late_start > MINUTES_PER_DAY || t.night_start > MINUTES_PER_DAY)
|
||||
return "Times must be between 00:00 and 24:00";
|
||||
if (t.day_start > t.late_start || t.late_start > t.night_start)
|
||||
return "The times must be in order: day start, late evening, night";
|
||||
|
||||
if (s.clock.evening_start >= MINUTES_PER_DAY)
|
||||
return "The evening must start before 24:00";
|
||||
|
||||
if (s.flip_time < SETTINGS_FLIP_TIME_MIN || s.flip_time > SETTINGS_FLIP_TIME_MAX)
|
||||
return "The flip time must be between 50 and 2000 us";
|
||||
|
||||
const HomeAssistantSettings &ha = s.home_assistant;
|
||||
if (!terminated(ha.host, sizeof(ha.host)) || !terminated(ha.user, sizeof(ha.user)) ||
|
||||
!terminated(ha.password, sizeof(ha.password)))
|
||||
return "Home Assistant text too long";
|
||||
if (ha.port == 0)
|
||||
return "Invalid MQTT port";
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool parseTime(const char *text, uint16_t &minutes)
|
||||
{
|
||||
if (text == nullptr)
|
||||
return false;
|
||||
int hour = 0, minute = 0;
|
||||
char extra;
|
||||
if (sscanf(text, "%d:%d%c", &hour, &minute, &extra) != 2)
|
||||
return false;
|
||||
if (hour < 0 || minute < 0 || minute > 59 || hour * 60 + minute > MINUTES_PER_DAY)
|
||||
return false;
|
||||
minutes = hour * 60 + minute;
|
||||
return true;
|
||||
}
|
||||
|
||||
void formatTime(uint16_t minutes, char *out)
|
||||
{
|
||||
snprintf(out, 6, "%02u:%02u", (unsigned)(minutes / 60) % 100, (unsigned)(minutes % 60));
|
||||
}
|
||||
Reference in new issue
Block a user