config: implement commands to change profiles and save settings

This commit is contained in:
Torrie Fischer 2023-12-11 07:59:47 +01:00
parent 57f1ca837c
commit d592810b3b
2 changed files with 113 additions and 2 deletions

View File

@ -53,7 +53,7 @@ Configuration::get(const char* key, bool defaultVal) const
} }
} }
StaticJsonDocument<1024> jsonConfig; StaticJsonDocument<2048> jsonConfig;
constexpr uint16_t HardwareConfig::MAX_LED_NUM; constexpr uint16_t HardwareConfig::MAX_LED_NUM;
@ -154,6 +154,11 @@ ConfigService::loadMap(const String& mapName)
deserializeJson(jsonConfig, configFile); deserializeJson(jsonConfig, configFile);
configFile.close(); configFile.close();
JsonArray strideList = jsonConfig["strides"]; JsonArray strideList = jsonConfig["strides"];
if (jsonConfig.containsKey("rotation")) {
m_jsonMap.rotation = jsonConfig["rotation"];
} else {
m_jsonMap.rotation = 0;
}
m_jsonMap.load(strideList); m_jsonMap.load(strideList);
return true; return true;
} else { } else {
@ -213,8 +218,9 @@ ConfigService::loadProfile(const char* profileName)
m_jsonMap.loadDefault(); m_jsonMap.loadDefault();
} }
Log.notice("config: Loaded!"); Log.notice("config: Loaded!");
strcpy(m_config.data.loadedProfile, profileName);
} else { } else {
Log.warning("config: Could not load profile %s!", profileName); Log.warning("config: Could not find profile json %s!", fname.c_str());
return false; return false;
} }
@ -254,5 +260,56 @@ ConfigService::handleEvent(const InputEvent &evt)
} }
} }
void
doMapList(Args& args, Print& out)
{
static const auto conf = Static<ConfigService>::instance();
out.println("Available maps:");
LittleFS.begin();
for(auto it = conf->mapsBegin();it != conf->mapsEnd(); it++) {
out.println(*it);
}
LittleFS.end();
}
void
doSave(Args& args, Print& print)
{
MainLoop::instance()->dispatch(InputEvent::SaveConfigurationRequest);
}
static String s;
void
doSetProfile(Args& args, Print& out)
{
s = args[1];
MainLoop::instance()->dispatch(InputEvent{InputEvent::LoadConfigurationByName, s.c_str()});
}
void
doCoordMap(Args& args, Print& out)
{
VirtualCoordinates coords{atoi(args[1].c_str()), atoi(args[2].c_str())};
auto map = Static<ConfigService>::instance()->coordMap();
auto pPos = map->virtualToPhysicalCoords(coords);
auto idx = map->physicalCoordsToIndex(pPos);
char buf[32];
sprintf(buf, "(%d, %d) -> (%d, %d) -> %d", coords.x, coords.y, pPos.x, pPos.y, idx);
out.println(buf);
}
const std::vector<Command>&
ConfigService::commands() const
{
static const std::vector<Command> _commands = {
{"save", doSave},
{"profile", doSetProfile},
{"maps", doMapList},
{"coordmap", doCoordMap}
};
return _commands;
}
STATIC_ALLOC(ConfigService); STATIC_ALLOC(ConfigService);
STATIC_TASK(ConfigService); STATIC_TASK(ConfigService);

View File

@ -2,6 +2,7 @@
#include <Figments.h> #include <Figments.h>
#include "JsonCoordinateMapping.h" #include "JsonCoordinateMapping.h"
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include <LittleFS.h>
class Configuration { class Configuration {
public: public:
@ -59,6 +60,59 @@ struct ConfigService: public Task {
const char* loadedProfile() const; const char* loadedProfile() const;
void overrideProfile(const char* profileName); void overrideProfile(const char* profileName);
const char* getConfigValue(const char* key) const; const char* getConfigValue(const char* key) const;
const std::vector<Command>& commands() const override;
struct filename_iterator: public std::iterator<std::input_iterator_tag, const char*> {
Dir dir;
String ret;
bool valid;
const char* suffix;
explicit filename_iterator() : suffix(NULL), valid(false) {}
explicit filename_iterator(const char* path, const char* suffix) : dir(LittleFS.openDir(path)), valid(true), suffix(suffix) {
next();
}
void next() {
if (!valid) {
return;
}
int extPos = -1;
do {
valid = dir.next();
Log.info("valid %F", valid);
if (valid) {
String fname = dir.fileName();
extPos = fname.lastIndexOf(suffix);
Log.info("compare %s %d", fname.c_str(), extPos);
if (extPos != -1) {
ret = fname.substring(0, extPos);
Log.info("found %s", ret.c_str());
}
}
} while (valid && extPos == -1);
}
filename_iterator& operator++() {
next();
return *this;
}
filename_iterator& operator++(int) {filename_iterator ret = *this; ++(*this); return ret;}
bool operator==(const filename_iterator &other) const { return valid == other.valid;}
bool operator!=(const filename_iterator &other) const { return !(*this == other); }
const char* operator*() const {
if (!valid) {
return NULL;
}
return ret.c_str();
}
};
filename_iterator mapsBegin() const { return filename_iterator("/maps/", ".json"); }
filename_iterator mapsEnd() const { return filename_iterator(); }
filename_iterator profilesBegin() const { return filename_iterator("/profiles/", ".json"); }
filename_iterator profilesEnd() const { return filename_iterator(); }
private: private:
HardwareConfig m_config; HardwareConfig m_config;