#include "openknx_idf/ets_memory_loader.h" #include "openknx_idf/esp_idf_platform.h" #include "knx/bau07B0.h" #include "knx/property.h" #include #include #include namespace gateway::openknx { namespace { void CollectAssociation(uint16_t group_address, uint16_t group_object_number, void* context) { auto* associations = static_cast*>(context); if (associations == nullptr) { return; } associations->push_back(EtsAssociation{group_address, group_object_number}); } bool IsErasedMemory(const uint8_t* data, size_t size) { if (data == nullptr) { return false; } return std::all_of(data, data + size, [](uint8_t value) { return value == 0xff; }); } constexpr uint16_t kReg1DaliManufacturerId = 0x00a4; constexpr uint8_t kReg1DaliApplicationNumber = 0x01; constexpr uint8_t kReg1DaliApplicationVersion = 0x05; constexpr uint8_t kReg1DaliOrderNumber[10] = {'R', 'E', 'G', '1', '-', 'D', 'a', 'l', 'i', 0}; void ApplyReg1DaliIdentity(Bau07B0& device, EspIdfPlatform& platform) { device.deviceObject().manufacturerId(kReg1DaliManufacturerId); device.deviceObject().bauNumber(platform.uniqueSerialNumber()); device.deviceObject().orderNumber(kReg1DaliOrderNumber); const uint8_t program_version[5] = {0x00, 0xa4, 0x00, kReg1DaliApplicationNumber, kReg1DaliApplicationVersion}; device.parameters().property(PID_PROG_VERSION)->write(program_version); } } // namespace EtsMemorySnapshot LoadEtsMemorySnapshot(const std::string& nvs_namespace) { EspIdfPlatform platform(nullptr, nvs_namespace.c_str()); EtsMemorySnapshot snapshot; const uint8_t* memory = platform.getNonVolatileMemoryStart(); const size_t memory_size = platform.getNonVolatileMemorySize(); if (memory == nullptr || memory_size == 0 || IsErasedMemory(memory, memory_size)) { return snapshot; } auto device = std::make_unique(platform); ApplyReg1DaliIdentity(*device, platform); device->readMemory(); snapshot.configured = device->configured(); snapshot.individual_address = device->deviceObject().individualAddress(); device->forEachEtsAssociation(CollectAssociation, &snapshot.associations); std::sort(snapshot.associations.begin(), snapshot.associations.end(), [](const EtsAssociation& lhs, const EtsAssociation& rhs) { if (lhs.group_address != rhs.group_address) { return lhs.group_address < rhs.group_address; } return lhs.group_object_number < rhs.group_object_number; }); snapshot.associations.erase( std::unique(snapshot.associations.begin(), snapshot.associations.end(), [](const EtsAssociation& lhs, const EtsAssociation& rhs) { return lhs.group_address == rhs.group_address && lhs.group_object_number == rhs.group_object_number; }), snapshot.associations.end()); return snapshot; } } // namespace gateway::openknx