#pragma once #include #include "JsonCoordinateMapping.h" #include #include "FsUtils.h" class Configuration { public: Configuration(const JsonObject& data); const char* get(const char* key, const char* defaultVal) const; int get(const char* key, int defaultVal) const; bool get(const char* key, bool defaultVal) const; private: const JsonObject& m_json; }; class ConfigTaskMixin : public virtual Loopable { public: void handleEvent(const InputEvent &evt) override; void loop() override {} virtual void handleConfigChange(const Configuration& config) {} }; struct HardwareConfig { uint8_t version = 3; uint8_t checksum = 0; struct Data { char loadedProfile[16] = {0}; uint8_t lastRed = 255; uint8_t lastGreen = 255; uint8_t lastBlue = 255; char lastScene[16] = {0}; }; Data data; static HardwareConfig load(); void save(); bool isValid() const; static constexpr uint16_t MAX_LED_NUM = 512; private: uint8_t getCRC() const; static constexpr uint8_t CRC7_POLY = 0x91; }; // A task that manages the EEPROM settings and coord mapping when modified via // Particle. This allows for multiple devices with wildly different displays to // run the same code struct ConfigService: public Task { ConfigService() : Task("Configuration") {state = Task::Running;} void onStart(); void loop() override; void handleEvent(const InputEvent &evt) override; const CoordinateMapping* coordMap() const { return &m_jsonMap; } const char* loadedProfile() const; void overrideProfile(const char* profileName); const std::vector& commands() const override; 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: HardwareConfig m_config; JsonCoordinateMapping m_jsonMap; const char* m_overrideProfile = nullptr; bool loadProfile(const char* name); bool loadMap(const String& mapName); void doSave(Args& args, Print& print); void doSetProfile(Args& args, Print& print); void doCoordMap(Args& args, Print& print); void doMapList(Args& args, Print& print); };