Skip to content

Commit

Permalink
Publish peripherals on boot
Browse files Browse the repository at this point in the history
  • Loading branch information
lptr committed Nov 11, 2024
1 parent 27ceec2 commit 94d4520
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 12 deletions.
8 changes: 6 additions & 2 deletions main/devices/Device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -455,19 +455,22 @@ class Device {
// We want RTC to be in sync before we start setting up peripherals
kernel.getRtcInSyncState().awaitSet();

JsonDocument peripheralsInitDoc;
JsonArray peripheralsInitJson = peripheralsInitDoc.to<JsonArray>();

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();
Log.info("Loading configuration for %d user-configured peripherals",
peripheralsConfig.size());
bool peripheralError = false;
for (auto& perpheralConfig : peripheralsConfig) {
if (!peripheralManager.createPeripheral(perpheralConfig.get())) {
if (!peripheralManager.createPeripheral(perpheralConfig.get(), peripheralsInitJson)) {
peripheralError = true;
}
}
Expand All @@ -492,6 +495,7 @@ class Device {
json["bootCount"] = bootCount++;
json["time"] = duration_cast<seconds>(system_clock::now().time_since_epoch()).count();
json["state"] = static_cast<int>(initState);
json["peripherals"].to<JsonArray>().set(peripheralsInitJson);
json["sleepWhenIdle"] = kernel.sleepManager.sleepWhenIdle;
},
MqttDriver::Retention::NoRetain, MqttDriver::QoS::AtLeastOnce, ticks::max());
Expand Down
27 changes: 17 additions & 10 deletions main/peripherals/Peripheral.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ class PeripheralFactoryBase {
, peripheralType(peripheralType) {
}

virtual unique_ptr<PeripheralBase> createPeripheral(const String& name, const String& jsonConfig, shared_ptr<MqttDriver::MqttRoot> mqttRoot, PeripheralServices& services) = 0;
virtual unique_ptr<PeripheralBase> createPeripheral(const String& name, const String& jsonConfig, shared_ptr<MqttDriver::MqttRoot> mqttRoot, PeripheralServices& services, JsonObject& initConfigJson) = 0;

const String factoryType;
const String peripheralType;
Expand All @@ -134,7 +134,7 @@ class PeripheralFactory : public PeripheralFactoryBase {
, deviceConfigArgs(std::forward<TDeviceConfigArgs>(deviceConfigArgs)...) {
}

unique_ptr<PeripheralBase> createPeripheral(const String& name, const String& jsonConfig, shared_ptr<MqttDriver::MqttRoot> mqttRoot, PeripheralServices& services) override {
unique_ptr<PeripheralBase> createPeripheral(const String& name, const String& jsonConfig, shared_ptr<MqttDriver::MqttRoot> mqttRoot, PeripheralServices& services, JsonObject& initConfigJson) override {
// Use short prefix because SPIFFS has a 32 character limit
ConfigurationFile<TConfig>* configFile = new ConfigurationFile<TConfig>(FileSystem::get(), "/p/" + name);
mqttRoot->subscribe("config", [name, configFile](const String&, const JsonObject& configJson) {
Expand All @@ -149,10 +149,9 @@ class PeripheralFactory : public PeripheralFactoryBase {
deviceConfig.loadFromString(jsonConfig);
unique_ptr<Peripheral<TConfig>> peripheral = createPeripheral(name, deviceConfig, mqttRoot, services);
peripheral->configure(configFile->config);
mqttRoot->publish("init", [&](JsonObject& json) {
auto config = json["config"].to<JsonObject>();
configFile->config.store(config, false);
});

// Store configuration in init message
configFile->config.store(initConfigJson, false);
return peripheral;
}

Expand Down Expand Up @@ -184,7 +183,7 @@ class PeripheralManager
factories.insert(std::make_pair(factory.factoryType, std::reference_wrapper<PeripheralFactoryBase>(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;
Expand All @@ -198,23 +197,31 @@ class PeripheralManager

String name = deviceConfig.name.get();
String type = deviceConfig.type.get();
JsonObject initJson = peripheralsInitJson.add<JsonObject>();
deviceConfig.store(initJson, true);
try {
Lock lock(stateMutex);
if (state == State::Stopped) {
Log.error("Not creating peripheral '%s' because the peripheral manager is stopped",
name.c_str());
return false;
}
unique_ptr<PeripheralBase> peripheral = createPeripheral(name, type, deviceConfig.params.get().get());
JsonDocument initConfigDoc;
JsonObject initConfigJson = initConfigDoc.to<JsonObject>();
unique_ptr<PeripheralBase> peripheral = createPeripheral(name, type, deviceConfig.params.get().get(), initConfigJson);
initJson["config"].to<JsonObject>().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;
}
}
Expand Down Expand Up @@ -254,7 +261,7 @@ class PeripheralManager
Property<JsonAsString> params { this, "params" };
};

unique_ptr<PeripheralBase> createPeripheral(const String& name, const String& factoryType, const String& configJson) {
unique_ptr<PeripheralBase> 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);
Expand All @@ -264,7 +271,7 @@ class PeripheralManager
const String& peripheralType = it->second.get().peripheralType;
shared_ptr<MqttDriver::MqttRoot> 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 {
Expand Down

0 comments on commit 94d4520

Please sign in to comment.