#include "logic/settings.h" #include #include #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)) || !validBitmapName(s.page)) return "Unknown page"; if (!terminated(s.off_page, sizeof(s.off_page)) || (s.off_page[0] && !validBitmapName(s.off_page))) return "Unknown off image"; 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.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 DriveSettings &d = s.drive; if (d.flip_gap > 5000) return "The flip gap must be between 0 and 5000 us"; if (d.pulses < 1 || d.pulses > 3) return "Pulses must be 1, 2 or 3"; if (d.effect >= DRIVE_EFFECT_COUNT) return "Unknown refresh effect"; if (d.effect_time < 100 || d.effect_time > 10000) return "The effect time must be between 100 and 10000 ms"; if (s.refresh.dots > REFRESH_MINUTES_MAX || s.refresh.image > REFRESH_MINUTES_MAX) return "Refresh intervals must be between 0 and 1440 minutes"; 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)) || !terminated(ha.api_url, sizeof(ha.api_url)) || !terminated(ha.token, sizeof(ha.token)) || !terminated(s.plex_user, sizeof(s.plex_user))) return "Home Assistant text too long"; if (ha.port == 0) return "Invalid MQTT port"; if (ha.api_url[0] && strncmp(ha.api_url, "http://", 7) != 0) return "The Home Assistant URL must start with http:// (https is not supported)"; return nullptr; } uint32_t effectTime(const DriveSettings &drive) { if (drive.effect == DRIVE_EFFECT_INSTANT) return 0; if (drive.effect == DRIVE_EFFECT_PUSH || drive.effect == DRIVE_EFFECT_RANDOM) return drive.effect_time + DRIVE_PUSH_EXTRA_TIME; return drive.effect_time; } 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)); }