config: first version of storing pixel maps and configs in SPIFFS
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed

This commit is contained in:
2023-02-18 16:14:00 +01:00
parent 07e6e98673
commit f0abdc0567
5 changed files with 144 additions and 176 deletions

View File

@@ -1,8 +1,16 @@
#include "./Config.h"
#include "./Static.h"
#include "./Sequencer.h"
#include <ArduinoLog.h>
#include <ArduinoJson.h>
#include <EEPROM.h>
#include <LittleFS.h>
#include <vector>
StaticJsonDocument<256> jsonConfig;
constexpr uint16_t HardwareConfig::MAX_LED_NUM;
HardwareConfig
@@ -15,7 +23,7 @@ HardwareConfig::load() {
#ifndef BOARD_TEENSY
EEPROM.end();
#endif
Log.notice("Loaded config version %d, CRC %d", ret.version, ret.checksum);
Log.notice("config: Loaded SRAM config version %d, CRC %d", ret.version, ret.checksum);
return ret;
}
@@ -33,18 +41,10 @@ HardwareConfig::save() {
#endif
}
LinearCoordinateMapping
HardwareConfig::toCoordMap() const
{
auto pixelCount = min(HardwareConfig::MAX_LED_NUM, std::max((uint16_t)1, data.pixelCount));
auto startPixel = min(pixelCount, std::max((uint16_t)1, data.startPixel));
return LinearCoordinateMapping{pixelCount, startPixel};
}
bool
HardwareConfig::isValid() const
{
return version == 2 && checksum == getCRC() && data.pixelCount <= MAX_LED_NUM;
return version == 3 && checksum == getCRC();
}
uint8_t
@@ -68,18 +68,82 @@ HardwareConfig::getCRC() const
void
ConfigService::onStart()
{
Log.notice("Starting configuration service...");
Log.notice("config: Starting configuration service...");
m_config = HardwareConfig::load();
if (m_config.isValid()) {
Log.notice("Configuration found!");
Log.notice("config: Configuration found!");
} else {
Log.notice("No configuration found. Writing defaults...");
Log.notice("config: No configuration found. Writing defaults...");
m_config = HardwareConfig{};
m_config.save();
}
m_coordMap = m_config.toCoordMap();
if (strlen(m_config.data.loadedProfile) == 0) {
strcpy(m_config.data.loadedProfile, "default");
}
loadProfile(m_config.data.loadedProfile);
}
Log.notice("Configured to use %d pixels, starting at %d", m_config.data.pixelCount, m_config.data.startPixel);
void
ConfigService::loadMap(const String& mapName)
{
String fname = String("/maps/") + mapName + ".json";
if (LittleFS.exists(fname)) {
File configFile = LittleFS.open(fname, "r");
Log.notice("config: Loading coordinate map %s", mapName.c_str());
deserializeJson(jsonConfig, configFile);
configFile.close();
JsonArray strideList = jsonConfig["strides"];
m_jsonMap.load(strideList);
} else {
Log.warning("config: Couldn't load coordinate map %s!!! Defaulting to linear mapping.", mapName.c_str());
m_jsonMap.loadDefault();
}
}
void
ConfigService::loadProfile(const char* profileName)
{
Log.notice("config: Loading profile %s...", profileName);
String fname = String("/profiles/") + profileName + ".json";
LittleFS.begin();
if (LittleFS.exists(fname)) {
File configFile = LittleFS.open(fname, "r");
jsonConfig.clear();
deserializeJson(jsonConfig, configFile);
configFile.close();
JsonObject sceneList = jsonConfig["scenes"];
std::vector<Sequencer::Scene> scenes;
for(JsonPair pair : sceneList) {
Log.notice("config: \tFound scene %s", pair.key().c_str());
std::vector<const char*> patterns;
for(const char* taskName : pair.value().as<JsonArray>()) {
patterns.push_back(taskName);
}
scenes.push_back(Sequencer::Scene{pair.key().c_str(), patterns});
}
Static<Sequencer>::instance()->setScenes(std::move(scenes));
JsonArray taskList = jsonConfig["tasks"];
Log.notice("config: Starting %d tasks", taskList.size());
for(int i = 0; i < taskList.size();i++) {
MainLoop::instance()->dispatch(InputEvent{InputEvent::StartThing, taskList[i].as<const char*>()});
}
Log.notice("config: Loaded!");
} else {
Log.warning("config: Could not load profile %s!", profileName);
}
String configName = jsonConfig["surfaceMap"];
jsonConfig.clear();
loadMap(configName);
LittleFS.end();
Log.notice("config: Configured to use %d pixels", m_jsonMap.physicalPixelCount());
PhysicalCoordinates topLeft = m_jsonMap.virtualToPhysicalCoords({0, 0});
PhysicalCoordinates bottomRight = m_jsonMap.virtualToPhysicalCoords({255, 255});
Log.verbose(" (0,0) -> (%d, %d) -> %d", topLeft.x, topLeft.y, m_jsonMap.physicalCoordsToIndex(topLeft));
Log.verbose(" (255,255) -> (%d, %d) -> %d", bottomRight.x, bottomRight.y, m_jsonMap.physicalCoordsToIndex(bottomRight));
}
void
@@ -87,24 +151,22 @@ ConfigService::loop()
{
}
const char*
ConfigService::loadedProfile() const
{
return m_config.data.loadedProfile;
}
void
ConfigService::handleEvent(const InputEvent &evt)
{
switch(evt.intent) {
case InputEvent::SetDisplayLength:
//Log.info("Updating pixel count from %d to %d", m_coordMap.pixelCount, evt.asInt());
m_config.data.pixelCount = evt.asInt();
m_coordMap = m_config.toCoordMap();
//Log.info("Count is now %d", m_coordMap.pixelCount);
break;
case InputEvent::SetDisplayOffset:
//Log.info("Updating pixel offset from %d to %d", m_coordMap.startPixel, evt.asInt());
m_config.data.startPixel = evt.asInt();
m_coordMap = m_config.toCoordMap();
//Log.info("Offset is now %d", m_coordMap.startPixel);
break;
case InputEvent::LoadConfigurationByName:
Log.notice("Reloading configuration %s", evt.asString());
strcpy(m_config.data.loadedProfile, evt.asString());
loadProfile(evt.asString());
case InputEvent::SaveConfigurationRequest:
//Log.info("Saving configuration");
Log.notice("Saving configuration");
m_config.save();
break;
default: