diff --git a/main/devices/Device.hpp b/main/devices/Device.hpp index 3711d1fa..1df914c5 100644 --- a/main/devices/Device.hpp +++ b/main/devices/Device.hpp @@ -455,11 +455,14 @@ class Device { // We want RTC to be in sync before we start setting up peripherals kernel.getRtcInSyncState().awaitSet(); + JsonDocument peripheralsInitDoc; + JsonArray peripheralsInitJson = peripheralsInitDoc.to(); + auto builtInPeripheralsCofig = deviceDefinition.getBuiltInPeripherals(); Log.debug("Loading configuration for %d built-in peripherals", builtInPeripheralsCofig.size()); for (auto& perpheralConfig : builtInPeripheralsCofig) { - peripheralManager.createPeripheral(perpheralConfig); + peripheralManager.createPeripheral(perpheralConfig, peripheralsInitJson); } auto& peripheralsConfig = deviceConfig.peripherals.get(); @@ -467,7 +470,7 @@ class Device { peripheralsConfig.size()); bool peripheralError = false; for (auto& perpheralConfig : peripheralsConfig) { - if (!peripheralManager.createPeripheral(perpheralConfig.get())) { + if (!peripheralManager.createPeripheral(perpheralConfig.get(), peripheralsInitJson)) { peripheralError = true; } } @@ -492,6 +495,7 @@ class Device { json["bootCount"] = bootCount++; json["time"] = duration_cast(system_clock::now().time_since_epoch()).count(); json["state"] = static_cast(initState); + json["peripherals"].to().set(peripheralsInitJson); json["sleepWhenIdle"] = kernel.sleepManager.sleepWhenIdle; }, MqttDriver::Retention::NoRetain, MqttDriver::QoS::AtLeastOnce, ticks::max()); diff --git a/main/peripherals/Peripheral.hpp b/main/peripherals/Peripheral.hpp index 1dabf9b6..f88f969c 100644 --- a/main/peripherals/Peripheral.hpp +++ b/main/peripherals/Peripheral.hpp @@ -115,7 +115,7 @@ class PeripheralFactoryBase { , peripheralType(peripheralType) { } - virtual unique_ptr createPeripheral(const String& name, const String& jsonConfig, shared_ptr mqttRoot, PeripheralServices& services) = 0; + virtual unique_ptr createPeripheral(const String& name, const String& jsonConfig, shared_ptr mqttRoot, PeripheralServices& services, JsonObject& initConfigJson) = 0; const String factoryType; const String peripheralType; @@ -134,7 +134,7 @@ class PeripheralFactory : public PeripheralFactoryBase { , deviceConfigArgs(std::forward(deviceConfigArgs)...) { } - unique_ptr createPeripheral(const String& name, const String& jsonConfig, shared_ptr mqttRoot, PeripheralServices& services) override { + unique_ptr createPeripheral(const String& name, const String& jsonConfig, shared_ptr mqttRoot, PeripheralServices& services, JsonObject& initConfigJson) override { // Use short prefix because SPIFFS has a 32 character limit ConfigurationFile* configFile = new ConfigurationFile(FileSystem::get(), "/p/" + name); mqttRoot->subscribe("config", [name, configFile](const String&, const JsonObject& configJson) { @@ -149,10 +149,9 @@ class PeripheralFactory : public PeripheralFactoryBase { deviceConfig.loadFromString(jsonConfig); unique_ptr> peripheral = createPeripheral(name, deviceConfig, mqttRoot, services); peripheral->configure(configFile->config); - mqttRoot->publish("init", [&](JsonObject& json) { - auto config = json["config"].to(); - configFile->config.store(config, false); - }); + + // Store configuration in init message + configFile->config.store(initConfigJson, false); return peripheral; } @@ -184,7 +183,7 @@ class PeripheralManager factories.insert(std::make_pair(factory.factoryType, std::reference_wrapper(factory))); } - bool createPeripheral(const String& peripheralConfig) { + bool createPeripheral(const String& peripheralConfig, JsonArray peripheralsInitJson) { Log.info("Creating peripheral with config: %s", peripheralConfig.c_str()); PeripheralDeviceConfiguration deviceConfig; @@ -198,6 +197,8 @@ class PeripheralManager String name = deviceConfig.name.get(); String type = deviceConfig.type.get(); + JsonObject initJson = peripheralsInitJson.add(); + deviceConfig.store(initJson, true); try { Lock lock(stateMutex); if (state == State::Stopped) { @@ -205,16 +206,22 @@ class PeripheralManager name.c_str()); return false; } - unique_ptr peripheral = createPeripheral(name, type, deviceConfig.params.get().get()); + JsonDocument initConfigDoc; + JsonObject initConfigJson = initConfigDoc.to(); + unique_ptr peripheral = createPeripheral(name, type, deviceConfig.params.get().get(), initConfigJson); + initJson["config"].to().set(initConfigJson); peripherals.push_back(move(peripheral)); + return true; } catch (const std::exception& e) { Log.error("Failed to create '%s' peripheral '%s' because %s", type.c_str(), name.c_str(), e.what()); + initJson["error"] = e.what(); return false; } catch (...) { Log.error("Failed to create '%s' peripheral '%s' because of an unknown exception", type.c_str(), name.c_str()); + initJson["error"] = "unknown exception"; return false; } } @@ -254,7 +261,7 @@ class PeripheralManager Property params { this, "params" }; }; - unique_ptr createPeripheral(const String& name, const String& factoryType, const String& configJson) { + unique_ptr createPeripheral(const String& name, const String& factoryType, const String& configJson, JsonObject& initConfigJson) { Log.debug("Creating peripheral '%s' with factory '%s'", name.c_str(), factoryType.c_str()); auto it = factories.find(factoryType); @@ -264,7 +271,7 @@ class PeripheralManager const String& peripheralType = it->second.get().peripheralType; shared_ptr mqttRoot = mqttDeviceRoot->forSuffix("peripherals/" + peripheralType + "/" + name); PeripheralFactoryBase& factory = it->second.get(); - return factory.createPeripheral(name, configJson, mqttRoot, services); + return factory.createPeripheral(name, configJson, mqttRoot, services, initConfigJson); } enum class State {