Public Access
104 lines
3.4 KiB
C++
104 lines
3.4 KiB
C++
#include "web/page_json.h"
|
|||
|
|
|
||
|
|
#include <Arduino.h>
|
||
|
|
#include <string.h>
|
||
|
|
|
||
|
|
#include "logic/settings.h"
|
||
|
|
|
||
|
|
static const char *const TYPES[] = {"clock", "date", "ha", "text"};
|
||
|
|
static const char *const ALIGNS[] = {"left", "center", "right"};
|
||
|
|
static const char *const OVERLAYS[] = {"top", "box", "invert"};
|
||
|
|
static const char *const LANGUAGES[] = {"nl", "en"};
|
||
|
|
|
||
|
|
template <size_t N> static int indexOf(const char *const (&names)[N], const char *name)
|
||
|
|
{
|
||
|
|
for (size_t i = 0; i < N; i++)
|
||
|
|
if (name && strcmp(names[i], name) == 0)
|
||
|
|
return i;
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
void pageToJson(const DynamicPage &page, JsonObject out)
|
||
|
|
{
|
||
|
|
char time[6];
|
||
|
|
JsonArray slots = out["slots"].to<JsonArray>();
|
||
|
|
for (int i = 0; i < page.slot_count; i++)
|
||
|
|
{
|
||
|
|
JsonObject slot = slots.add<JsonObject>();
|
||
|
|
formatTime(page.slots[i].start, time);
|
||
|
|
slot["start"] = String(time);
|
||
|
|
slot["bitmap"] = page.slots[i].bitmap;
|
||
|
|
}
|
||
|
|
JsonArray elements = out["elements"].to<JsonArray>();
|
||
|
|
for (int i = 0; i < page.element_count; i++)
|
||
|
|
{
|
||
|
|
const PageElement &e = page.elements[i];
|
||
|
|
JsonObject o = elements.add<JsonObject>();
|
||
|
|
o["type"] = TYPES[(int)e.type];
|
||
|
|
o["x"] = e.x;
|
||
|
|
o["y"] = e.y;
|
||
|
|
o["align"] = ALIGNS[(int)e.align];
|
||
|
|
o["overlay"] = OVERLAYS[(int)e.overlay];
|
||
|
|
o["font"] = e.font;
|
||
|
|
o["format"] = e.format;
|
||
|
|
o["language"] = LANGUAGES[(int)e.language];
|
||
|
|
o["decimals"] = e.decimals;
|
||
|
|
o["text"] = e.text;
|
||
|
|
o["suffix"] = e.suffix;
|
||
|
|
o["entity"] = e.entity;
|
||
|
|
o["attribute"] = e.attribute;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// False when the text does not fit
|
||
|
|
static bool copyText(JsonVariantConst value, char *out, size_t size)
|
||
|
|
{
|
||
|
|
const char *text = value | "";
|
||
|
|
if (strlen(text) >= size)
|
||
|
|
return false;
|
||
|
|
strcpy(out, text);
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
const char *pageFromJson(JsonVariantConst in, DynamicPage &page)
|
||
|
|
{
|
||
|
|
page = DynamicPage();
|
||
|
|
JsonArrayConst slots = in["slots"];
|
||
|
|
JsonArrayConst elements = in["elements"];
|
||
|
|
if (slots.size() > (size_t)PAGE_SLOTS)
|
||
|
|
return "Too many time slots (8 at most)";
|
||
|
|
if (elements.size() > (size_t)PAGE_ELEMENTS)
|
||
|
|
return "Too many elements (8 at most)";
|
||
|
|
|
||
|
|
for (JsonVariantConst s : slots)
|
||
|
|
{
|
||
|
|
PageSlot &slot = page.slots[page.slot_count++];
|
||
|
|
if (!parseTime(s["start"] | "", slot.start))
|
||
|
|
return "Times must look like 08:30";
|
||
|
|
if (!copyText(s["bitmap"], slot.bitmap, sizeof(slot.bitmap)))
|
||
|
|
return "Bitmap name too long";
|
||
|
|
}
|
||
|
|
|
||
|
|
for (JsonVariantConst o : elements)
|
||
|
|
{
|
||
|
|
PageElement &e = page.elements[page.element_count++];
|
||
|
|
int type = indexOf(TYPES, o["type"]), align = indexOf(ALIGNS, o["align"] | "left"),
|
||
|
|
overlay = indexOf(OVERLAYS, o["overlay"] | "top"), language = indexOf(LANGUAGES, o["language"] | "nl");
|
||
|
|
if (type < 0 || align < 0 || overlay < 0 || language < 0)
|
||
|
|
return "Unknown element setting";
|
||
|
|
e.type = (ElementType)type;
|
||
|
|
e.align = (Align)align;
|
||
|
|
e.overlay = (Overlay)overlay;
|
||
|
|
e.language = (Language)language;
|
||
|
|
// Range checks are in validatePage(); out of range numbers must not wrap
|
||
|
|
e.x = constrain(o["x"] | 0, -1000, 1000);
|
||
|
|
e.y = constrain(o["y"] | 0, -1000, 1000);
|
||
|
|
e.format = constrain(o["format"] | 0, 0, 255);
|
||
|
|
e.decimals = constrain(o["decimals"] | (int)DECIMALS_AS_IS, -100, 100);
|
||
|
|
if (!copyText(o["font"], e.font, sizeof(e.font)) || !copyText(o["text"], e.text, sizeof(e.text)) ||
|
||
|
|
!copyText(o["suffix"], e.suffix, sizeof(e.suffix)) || !copyText(o["entity"], e.entity, sizeof(e.entity)) ||
|
||
|
|
!copyText(o["attribute"], e.attribute, sizeof(e.attribute)))
|
||
|
|
return "Text too long (32 characters, unit 16, entity 64)";
|
||
|
|
}
|
||
|
|
return validatePage(page);
|
||
|
|
}
|