Enhance DALI bridge: add BridgeOperation and BridgeDaliTarget support, refactor address resolution and provisioning methods
This commit is contained in:
@@ -18,6 +18,8 @@ struct BacnetObjectBinding {
|
||||
BridgeObjectType objectType = BridgeObjectType::unknown;
|
||||
int objectInstance = -1;
|
||||
std::string property;
|
||||
BridgeOperation operation = BridgeOperation::unknown;
|
||||
BridgeDaliTarget target;
|
||||
};
|
||||
|
||||
class DaliBacnetBridge {
|
||||
|
||||
+2
-2
@@ -55,8 +55,8 @@ class DaliBridgeEngine {
|
||||
DaliBridgeResult executeResolved(const DaliBridgeRequest& request,
|
||||
const BridgeModel* model,
|
||||
BridgeOperation operation);
|
||||
std::optional<int> resolveShortAddress(const DaliBridgeRequest& request,
|
||||
const BridgeModel* model) const;
|
||||
std::optional<int> resolveTargetAddress(const DaliBridgeRequest& request,
|
||||
const BridgeModel* model) const;
|
||||
std::optional<int> resolveRawAddress(const DaliBridgeRequest& request,
|
||||
const BridgeModel* model) const;
|
||||
std::optional<int> resolveRawCommand(const DaliBridgeRequest& request,
|
||||
|
||||
@@ -25,6 +25,12 @@ enum class BridgeObjectType {
|
||||
multiStateValue = 9,
|
||||
};
|
||||
|
||||
enum class BridgeDaliTargetKind {
|
||||
shortAddress = 0,
|
||||
group = 1,
|
||||
broadcast = 2,
|
||||
};
|
||||
|
||||
enum class BridgeOperation {
|
||||
unknown = 0,
|
||||
send = 1,
|
||||
@@ -46,6 +52,7 @@ enum class BridgeOperation {
|
||||
getEmergencyFailureStatus = 17,
|
||||
startEmergencyFunctionTest = 18,
|
||||
stopEmergencyTest = 19,
|
||||
startEmergencyDurationTest = 20,
|
||||
};
|
||||
|
||||
enum class BridgeValueEncoding {
|
||||
@@ -80,12 +87,15 @@ struct BridgeExternalPoint {
|
||||
};
|
||||
|
||||
struct BridgeDaliTarget {
|
||||
BridgeDaliTargetKind kind = BridgeDaliTargetKind::shortAddress;
|
||||
std::optional<int> shortAddress;
|
||||
std::optional<int> groupAddress;
|
||||
std::optional<int> rawAddress;
|
||||
std::optional<int> rawCommand;
|
||||
|
||||
static BridgeDaliTarget fromJson(const DaliValue::Object* json);
|
||||
DaliValue::Object toJson() const;
|
||||
std::optional<int> logicalAddress() const;
|
||||
};
|
||||
|
||||
struct BridgeModel {
|
||||
@@ -110,6 +120,9 @@ BridgeProtocolKind bridgeProtocolKindFromString(const std::string& value);
|
||||
const char* bridgeObjectTypeToString(BridgeObjectType type);
|
||||
BridgeObjectType bridgeObjectTypeFromString(const std::string& value);
|
||||
|
||||
const char* bridgeDaliTargetKindToString(BridgeDaliTargetKind kind);
|
||||
BridgeDaliTargetKind bridgeDaliTargetKindFromString(const std::string& value);
|
||||
|
||||
const char* bridgeOperationToString(BridgeOperation operation);
|
||||
BridgeOperation bridgeOperationFromString(const std::string& value);
|
||||
|
||||
|
||||
@@ -34,6 +34,9 @@ class BridgeProvisioningStore {
|
||||
esp_err_t save(const BridgeRuntimeConfig& config) const;
|
||||
esp_err_t load(BridgeRuntimeConfig* config) const;
|
||||
esp_err_t clear() const;
|
||||
esp_err_t saveObject(const char* key, const DaliValue::Object& object) const;
|
||||
esp_err_t loadObject(const char* key, DaliValue::Object* object) const;
|
||||
esp_err_t clearKey(const char* key) const;
|
||||
|
||||
private:
|
||||
std::string nvsNamespace_;
|
||||
|
||||
@@ -44,7 +44,8 @@ std::optional<BacnetObjectBinding> DaliBacnetBridge::findObject(BridgeObjectType
|
||||
if (!model.external.property.empty() && model.external.property != property) {
|
||||
continue;
|
||||
}
|
||||
return BacnetObjectBinding{model.id, objectType, objectInstance, property};
|
||||
return BacnetObjectBinding{model.id, objectType, objectInstance, property,
|
||||
model.operation, model.dali};
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
@@ -57,7 +58,8 @@ std::vector<BacnetObjectBinding> DaliBacnetBridge::describeObjects() const {
|
||||
}
|
||||
bindings.push_back(BacnetObjectBinding{model.id, model.external.objectType,
|
||||
model.external.objectInstance.value(),
|
||||
model.external.property});
|
||||
model.external.property, model.operation,
|
||||
model.dali});
|
||||
}
|
||||
return bindings;
|
||||
}
|
||||
+42
-33
@@ -135,7 +135,7 @@ DaliBridgeResult DaliBridgeEngine::executeResolved(const DaliBridgeRequest& requ
|
||||
return result;
|
||||
}
|
||||
case BridgeOperation::setBrightness: {
|
||||
const auto address = resolveShortAddress(request, model);
|
||||
const auto address = resolveTargetAddress(request, model);
|
||||
const auto value = resolveIntValue(request, model);
|
||||
if (!address.has_value() || !value.has_value()) {
|
||||
result.error = "missing address/value";
|
||||
@@ -146,7 +146,7 @@ DaliBridgeResult DaliBridgeEngine::executeResolved(const DaliBridgeRequest& requ
|
||||
break;
|
||||
}
|
||||
case BridgeOperation::setBrightnessPercent: {
|
||||
const auto address = resolveShortAddress(request, model);
|
||||
const auto address = resolveTargetAddress(request, model);
|
||||
const auto value = resolveDoubleValue(request);
|
||||
if (!address.has_value() || !value.has_value()) {
|
||||
result.error = "missing address/value";
|
||||
@@ -157,43 +157,43 @@ DaliBridgeResult DaliBridgeEngine::executeResolved(const DaliBridgeRequest& requ
|
||||
break;
|
||||
}
|
||||
case BridgeOperation::on: {
|
||||
const auto address = resolveShortAddress(request, model);
|
||||
const auto address = resolveTargetAddress(request, model);
|
||||
if (!address.has_value()) {
|
||||
result.error = "missing short address";
|
||||
result.error = "missing target address";
|
||||
return result;
|
||||
}
|
||||
result.ok = base_.on(address.value());
|
||||
break;
|
||||
}
|
||||
case BridgeOperation::off: {
|
||||
const auto address = resolveShortAddress(request, model);
|
||||
const auto address = resolveTargetAddress(request, model);
|
||||
if (!address.has_value()) {
|
||||
result.error = "missing short address";
|
||||
result.error = "missing target address";
|
||||
return result;
|
||||
}
|
||||
result.ok = base_.off(address.value());
|
||||
break;
|
||||
}
|
||||
case BridgeOperation::recallMaxLevel: {
|
||||
const auto address = resolveShortAddress(request, model);
|
||||
const auto address = resolveTargetAddress(request, model);
|
||||
if (!address.has_value()) {
|
||||
result.error = "missing short address";
|
||||
result.error = "missing target address";
|
||||
return result;
|
||||
}
|
||||
result.ok = base_.recallMaxLevel(address.value());
|
||||
break;
|
||||
}
|
||||
case BridgeOperation::recallMinLevel: {
|
||||
const auto address = resolveShortAddress(request, model);
|
||||
const auto address = resolveTargetAddress(request, model);
|
||||
if (!address.has_value()) {
|
||||
result.error = "missing short address";
|
||||
result.error = "missing target address";
|
||||
return result;
|
||||
}
|
||||
result.ok = base_.recallMinLevel(address.value());
|
||||
break;
|
||||
}
|
||||
case BridgeOperation::setColorTemperature: {
|
||||
const auto address = resolveShortAddress(request, model);
|
||||
const auto address = resolveTargetAddress(request, model);
|
||||
const auto value = resolveIntValue(request, model);
|
||||
if (!address.has_value() || !value.has_value()) {
|
||||
result.error = "missing address/value";
|
||||
@@ -204,9 +204,9 @@ DaliBridgeResult DaliBridgeEngine::executeResolved(const DaliBridgeRequest& requ
|
||||
break;
|
||||
}
|
||||
case BridgeOperation::getBrightness: {
|
||||
const auto address = resolveShortAddress(request, model);
|
||||
const auto address = resolveTargetAddress(request, model);
|
||||
if (!address.has_value()) {
|
||||
result.error = "missing short address";
|
||||
result.error = "missing target address";
|
||||
return result;
|
||||
}
|
||||
const auto value = base_.getBright(address.value());
|
||||
@@ -219,9 +219,9 @@ DaliBridgeResult DaliBridgeEngine::executeResolved(const DaliBridgeRequest& requ
|
||||
break;
|
||||
}
|
||||
case BridgeOperation::getStatus: {
|
||||
const auto address = resolveShortAddress(request, model);
|
||||
const auto address = resolveTargetAddress(request, model);
|
||||
if (!address.has_value()) {
|
||||
result.error = "missing short address";
|
||||
result.error = "missing target address";
|
||||
return result;
|
||||
}
|
||||
const auto value = base_.getStatus(address.value());
|
||||
@@ -235,9 +235,9 @@ DaliBridgeResult DaliBridgeEngine::executeResolved(const DaliBridgeRequest& requ
|
||||
break;
|
||||
}
|
||||
case BridgeOperation::getColorTemperature: {
|
||||
const auto address = resolveShortAddress(request, model);
|
||||
const auto address = resolveTargetAddress(request, model);
|
||||
if (!address.has_value()) {
|
||||
result.error = "missing short address";
|
||||
result.error = "missing target address";
|
||||
return result;
|
||||
}
|
||||
const auto value = dt8_.getColorTemperature(address.value());
|
||||
@@ -250,9 +250,9 @@ DaliBridgeResult DaliBridgeEngine::executeResolved(const DaliBridgeRequest& requ
|
||||
break;
|
||||
}
|
||||
case BridgeOperation::getColorStatus: {
|
||||
const auto address = resolveShortAddress(request, model);
|
||||
const auto address = resolveTargetAddress(request, model);
|
||||
if (!address.has_value()) {
|
||||
result.error = "missing short address";
|
||||
result.error = "missing target address";
|
||||
return result;
|
||||
}
|
||||
const auto value = dt8_.getColorStatus(address.value());
|
||||
@@ -273,9 +273,9 @@ DaliBridgeResult DaliBridgeEngine::executeResolved(const DaliBridgeRequest& requ
|
||||
break;
|
||||
}
|
||||
case BridgeOperation::getEmergencyLevel: {
|
||||
const auto address = resolveShortAddress(request, model);
|
||||
const auto address = resolveTargetAddress(request, model);
|
||||
if (!address.has_value()) {
|
||||
result.error = "missing short address";
|
||||
result.error = "missing target address";
|
||||
return result;
|
||||
}
|
||||
const auto value = dt1_.getEmergencyLevel(address.value());
|
||||
@@ -288,9 +288,9 @@ DaliBridgeResult DaliBridgeEngine::executeResolved(const DaliBridgeRequest& requ
|
||||
break;
|
||||
}
|
||||
case BridgeOperation::getEmergencyStatus: {
|
||||
const auto address = resolveShortAddress(request, model);
|
||||
const auto address = resolveTargetAddress(request, model);
|
||||
if (!address.has_value()) {
|
||||
result.error = "missing short address";
|
||||
result.error = "missing target address";
|
||||
return result;
|
||||
}
|
||||
const auto status = dt1_.getEmergencyStatusDecoded(address.value());
|
||||
@@ -311,9 +311,9 @@ DaliBridgeResult DaliBridgeEngine::executeResolved(const DaliBridgeRequest& requ
|
||||
break;
|
||||
}
|
||||
case BridgeOperation::getEmergencyFailureStatus: {
|
||||
const auto address = resolveShortAddress(request, model);
|
||||
const auto address = resolveTargetAddress(request, model);
|
||||
if (!address.has_value()) {
|
||||
result.error = "missing short address";
|
||||
result.error = "missing target address";
|
||||
return result;
|
||||
}
|
||||
const auto status = dt1_.getDT1TestStatusDetailed(address.value());
|
||||
@@ -337,18 +337,27 @@ DaliBridgeResult DaliBridgeEngine::executeResolved(const DaliBridgeRequest& requ
|
||||
break;
|
||||
}
|
||||
case BridgeOperation::startEmergencyFunctionTest: {
|
||||
const auto address = resolveShortAddress(request, model);
|
||||
const auto address = resolveTargetAddress(request, model);
|
||||
if (!address.has_value()) {
|
||||
result.error = "missing short address";
|
||||
result.error = "missing target address";
|
||||
return result;
|
||||
}
|
||||
result.ok = dt1_.startFunctionTestCmd(address.value());
|
||||
break;
|
||||
}
|
||||
case BridgeOperation::stopEmergencyTest: {
|
||||
const auto address = resolveShortAddress(request, model);
|
||||
case BridgeOperation::startEmergencyDurationTest: {
|
||||
const auto address = resolveTargetAddress(request, model);
|
||||
if (!address.has_value()) {
|
||||
result.error = "missing short address";
|
||||
result.error = "missing target address";
|
||||
return result;
|
||||
}
|
||||
result.ok = dt1_.startDurationTestCmd(address.value());
|
||||
break;
|
||||
}
|
||||
case BridgeOperation::stopEmergencyTest: {
|
||||
const auto address = resolveTargetAddress(request, model);
|
||||
if (!address.has_value()) {
|
||||
result.error = "missing target address";
|
||||
return result;
|
||||
}
|
||||
result.ok = dt1_.stopTest(address.value());
|
||||
@@ -366,13 +375,13 @@ DaliBridgeResult DaliBridgeEngine::executeResolved(const DaliBridgeRequest& requ
|
||||
return result;
|
||||
}
|
||||
|
||||
std::optional<int> DaliBridgeEngine::resolveShortAddress(const DaliBridgeRequest& request,
|
||||
const BridgeModel* model) const {
|
||||
std::optional<int> DaliBridgeEngine::resolveTargetAddress(const DaliBridgeRequest& request,
|
||||
const BridgeModel* model) const {
|
||||
if (request.shortAddress.has_value()) {
|
||||
return request.shortAddress;
|
||||
}
|
||||
if (model != nullptr) {
|
||||
return model->dali.shortAddress;
|
||||
return model->dali.logicalAddress();
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
+92
-2
@@ -7,6 +7,9 @@
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr int kDaliGroupBaseAddress = 64;
|
||||
constexpr int kDaliBroadcastAddress = 127;
|
||||
|
||||
std::string normalize(const std::string& value) {
|
||||
std::string out = value;
|
||||
std::transform(out.begin(), out.end(), out.begin(), [](unsigned char ch) {
|
||||
@@ -88,7 +91,37 @@ BridgeDaliTarget BridgeDaliTarget::fromJson(const DaliValue::Object* json) {
|
||||
if (json == nullptr) {
|
||||
return target;
|
||||
}
|
||||
target.shortAddress = getObjectInt(*json, "shortAddress");
|
||||
const auto explicit_kind = bridgeDaliTargetKindFromString(
|
||||
getObjectString(*json, "kind")
|
||||
.value_or(getObjectString(*json, "targetKind").value_or("")));
|
||||
const auto shared_address = getObjectInt(*json, "address");
|
||||
const auto short_address = getObjectInt(*json, "shortAddress");
|
||||
const auto group_address = getObjectInt(*json, "groupAddress").has_value()
|
||||
? getObjectInt(*json, "groupAddress")
|
||||
: getObjectInt(*json, "group");
|
||||
const bool broadcast = getObjectBool(*json, "broadcast").value_or(false);
|
||||
|
||||
target.kind = explicit_kind;
|
||||
if (explicit_kind == BridgeDaliTargetKind::shortAddress) {
|
||||
target.shortAddress = shared_address;
|
||||
} else if (explicit_kind == BridgeDaliTargetKind::group) {
|
||||
target.groupAddress = shared_address;
|
||||
}
|
||||
if (short_address.has_value()) {
|
||||
target.shortAddress = short_address;
|
||||
if (explicit_kind != BridgeDaliTargetKind::broadcast) {
|
||||
target.kind = BridgeDaliTargetKind::shortAddress;
|
||||
}
|
||||
}
|
||||
if (group_address.has_value()) {
|
||||
target.groupAddress = group_address;
|
||||
if (explicit_kind != BridgeDaliTargetKind::broadcast) {
|
||||
target.kind = BridgeDaliTargetKind::group;
|
||||
}
|
||||
}
|
||||
if (broadcast) {
|
||||
target.kind = BridgeDaliTargetKind::broadcast;
|
||||
}
|
||||
target.rawAddress = getObjectInt(*json, "rawAddress");
|
||||
target.rawCommand = getObjectInt(*json, "rawCommand");
|
||||
return target;
|
||||
@@ -96,12 +129,44 @@ BridgeDaliTarget BridgeDaliTarget::fromJson(const DaliValue::Object* json) {
|
||||
|
||||
DaliValue::Object BridgeDaliTarget::toJson() const {
|
||||
DaliValue::Object out;
|
||||
if (shortAddress.has_value()) out["shortAddress"] = shortAddress.value();
|
||||
out["kind"] = bridgeDaliTargetKindToString(kind);
|
||||
switch (kind) {
|
||||
case BridgeDaliTargetKind::shortAddress:
|
||||
if (shortAddress.has_value()) {
|
||||
out["address"] = shortAddress.value();
|
||||
out["shortAddress"] = shortAddress.value();
|
||||
}
|
||||
break;
|
||||
case BridgeDaliTargetKind::group:
|
||||
if (groupAddress.has_value()) {
|
||||
out["address"] = groupAddress.value();
|
||||
out["groupAddress"] = groupAddress.value();
|
||||
}
|
||||
break;
|
||||
case BridgeDaliTargetKind::broadcast:
|
||||
out["broadcast"] = true;
|
||||
break;
|
||||
}
|
||||
if (rawAddress.has_value()) out["rawAddress"] = rawAddress.value();
|
||||
if (rawCommand.has_value()) out["rawCommand"] = rawCommand.value();
|
||||
return out;
|
||||
}
|
||||
|
||||
std::optional<int> BridgeDaliTarget::logicalAddress() const {
|
||||
switch (kind) {
|
||||
case BridgeDaliTargetKind::shortAddress:
|
||||
return shortAddress;
|
||||
case BridgeDaliTargetKind::group:
|
||||
if (!groupAddress.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return kDaliGroupBaseAddress + groupAddress.value();
|
||||
case BridgeDaliTargetKind::broadcast:
|
||||
return kDaliBroadcastAddress;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
BridgeModel BridgeModel::fromJson(const DaliValue::Object& json) {
|
||||
BridgeModel model;
|
||||
model.id = getObjectString(json, "id").value_or("");
|
||||
@@ -210,6 +275,26 @@ BridgeObjectType bridgeObjectTypeFromString(const std::string& value) {
|
||||
return BridgeObjectType::unknown;
|
||||
}
|
||||
|
||||
const char* bridgeDaliTargetKindToString(BridgeDaliTargetKind kind) {
|
||||
switch (kind) {
|
||||
case BridgeDaliTargetKind::shortAddress:
|
||||
return "short_address";
|
||||
case BridgeDaliTargetKind::group:
|
||||
return "group";
|
||||
case BridgeDaliTargetKind::broadcast:
|
||||
return "broadcast";
|
||||
default:
|
||||
return "short_address";
|
||||
}
|
||||
}
|
||||
|
||||
BridgeDaliTargetKind bridgeDaliTargetKindFromString(const std::string& value) {
|
||||
const std::string normalized = normalize(value);
|
||||
if (normalized == "group") return BridgeDaliTargetKind::group;
|
||||
if (normalized == "broadcast") return BridgeDaliTargetKind::broadcast;
|
||||
return BridgeDaliTargetKind::shortAddress;
|
||||
}
|
||||
|
||||
const char* bridgeOperationToString(BridgeOperation operation) {
|
||||
switch (operation) {
|
||||
case BridgeOperation::send:
|
||||
@@ -250,6 +335,8 @@ const char* bridgeOperationToString(BridgeOperation operation) {
|
||||
return "start_emergency_function_test";
|
||||
case BridgeOperation::stopEmergencyTest:
|
||||
return "stop_emergency_test";
|
||||
case BridgeOperation::startEmergencyDurationTest:
|
||||
return "start_emergency_duration_test";
|
||||
case BridgeOperation::unknown:
|
||||
default:
|
||||
return "unknown";
|
||||
@@ -279,6 +366,9 @@ BridgeOperation bridgeOperationFromString(const std::string& value) {
|
||||
return BridgeOperation::startEmergencyFunctionTest;
|
||||
}
|
||||
if (normalized == "stop_emergency_test") return BridgeOperation::stopEmergencyTest;
|
||||
if (normalized == "start_emergency_duration_test") {
|
||||
return BridgeOperation::startEmergencyDurationTest;
|
||||
}
|
||||
return BridgeOperation::unknown;
|
||||
}
|
||||
|
||||
|
||||
+127
-63
@@ -143,6 +143,98 @@ DaliValue bacnetToJson(const BacnetBridgeConfig& config) {
|
||||
return DaliValue(std::move(out));
|
||||
}
|
||||
|
||||
esp_err_t saveJsonObject(const std::string& nvs_namespace, const char* key,
|
||||
const DaliValue::Object& object) {
|
||||
if (key == nullptr || key[0] == '\0') {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nvs_handle_t handle;
|
||||
esp_err_t err = nvs_open(nvs_namespace.c_str(), NVS_READWRITE, &handle);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(kTag, "nvs_open(save %s) failed: %s", key, esp_err_to_name(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
cJSON* root = toCjson(DaliValue(object));
|
||||
char* raw = cJSON_PrintUnformatted(root);
|
||||
if (raw == nullptr) {
|
||||
cJSON_Delete(root);
|
||||
nvs_close(handle);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
err = nvs_set_str(handle, key, raw);
|
||||
if (err == ESP_OK) {
|
||||
err = nvs_commit(handle);
|
||||
}
|
||||
|
||||
cJSON_Delete(root);
|
||||
cJSON_free(raw);
|
||||
nvs_close(handle);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(kTag, "save %s failed: %s", key, esp_err_to_name(err));
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t loadJsonObject(const std::string& nvs_namespace, const char* key,
|
||||
DaliValue::Object* object) {
|
||||
if (object == nullptr || key == nullptr || key[0] == '\0') {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nvs_handle_t handle;
|
||||
esp_err_t err = nvs_open(nvs_namespace.c_str(), NVS_READONLY, &handle);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
std::string payload;
|
||||
err = readString(handle, key, &payload);
|
||||
nvs_close(handle);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
cJSON* root = cJSON_Parse(payload.c_str());
|
||||
if (root == nullptr) {
|
||||
return ESP_ERR_INVALID_RESPONSE;
|
||||
}
|
||||
|
||||
const DaliValue value = fromCjson(root);
|
||||
cJSON_Delete(root);
|
||||
const auto* parsed = value.asObject();
|
||||
if (parsed == nullptr) {
|
||||
return ESP_ERR_INVALID_RESPONSE;
|
||||
}
|
||||
|
||||
*object = *parsed;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t clearStoredKey(const std::string& nvs_namespace, const char* key) {
|
||||
if (key == nullptr || key[0] == '\0') {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nvs_handle_t handle;
|
||||
esp_err_t err = nvs_open(nvs_namespace.c_str(), NVS_READWRITE, &handle);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = nvs_erase_key(handle, key);
|
||||
if (err == ESP_ERR_NVS_NOT_FOUND) {
|
||||
err = ESP_OK;
|
||||
}
|
||||
if (err == ESP_OK) {
|
||||
err = nvs_commit(handle);
|
||||
}
|
||||
nvs_close(handle);
|
||||
return err;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
BridgeRuntimeConfig BridgeRuntimeConfig::fromJson(const DaliValue::Object& json) {
|
||||
@@ -182,33 +274,7 @@ DaliValue::Object BridgeRuntimeConfig::toJson() const {
|
||||
}
|
||||
|
||||
esp_err_t BridgeProvisioningStore::save(const BridgeRuntimeConfig& config) const {
|
||||
nvs_handle_t handle;
|
||||
esp_err_t err = nvs_open(nvsNamespace_.c_str(), NVS_READWRITE, &handle);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(kTag, "nvs_open(save) failed: %s", esp_err_to_name(err));
|
||||
return err;
|
||||
}
|
||||
|
||||
cJSON* root = toCjson(DaliValue(config.toJson()));
|
||||
char* raw = cJSON_PrintUnformatted(root);
|
||||
if (raw == nullptr) {
|
||||
cJSON_Delete(root);
|
||||
nvs_close(handle);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
err = nvs_set_str(handle, kKeyConfig, raw);
|
||||
if (err == ESP_OK) {
|
||||
err = nvs_commit(handle);
|
||||
}
|
||||
|
||||
cJSON_Delete(root);
|
||||
cJSON_free(raw);
|
||||
nvs_close(handle);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(kTag, "save failed: %s", esp_err_to_name(err));
|
||||
}
|
||||
return err;
|
||||
return saveJsonObject(nvsNamespace_, kKeyConfig, config.toJson());
|
||||
}
|
||||
|
||||
esp_err_t BridgeProvisioningStore::load(BridgeRuntimeConfig* config) const {
|
||||
@@ -216,51 +282,31 @@ esp_err_t BridgeProvisioningStore::load(BridgeRuntimeConfig* config) const {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nvs_handle_t handle;
|
||||
esp_err_t err = nvs_open(nvsNamespace_.c_str(), NVS_READONLY, &handle);
|
||||
DaliValue::Object object;
|
||||
const esp_err_t err = loadJsonObject(nvsNamespace_, kKeyConfig, &object);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
std::string payload;
|
||||
err = readString(handle, kKeyConfig, &payload);
|
||||
nvs_close(handle);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
cJSON* root = cJSON_Parse(payload.c_str());
|
||||
if (root == nullptr) {
|
||||
return ESP_ERR_INVALID_RESPONSE;
|
||||
}
|
||||
|
||||
const DaliValue value = fromCjson(root);
|
||||
cJSON_Delete(root);
|
||||
const auto* object = value.asObject();
|
||||
if (object == nullptr) {
|
||||
return ESP_ERR_INVALID_RESPONSE;
|
||||
}
|
||||
|
||||
*config = BridgeRuntimeConfig::fromJson(*object);
|
||||
*config = BridgeRuntimeConfig::fromJson(object);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t BridgeProvisioningStore::clear() const {
|
||||
nvs_handle_t handle;
|
||||
esp_err_t err = nvs_open(nvsNamespace_.c_str(), NVS_READWRITE, &handle);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
return clearStoredKey(nvsNamespace_, kKeyConfig);
|
||||
}
|
||||
|
||||
err = nvs_erase_key(handle, kKeyConfig);
|
||||
if (err == ESP_ERR_NVS_NOT_FOUND) {
|
||||
err = ESP_OK;
|
||||
}
|
||||
if (err == ESP_OK) {
|
||||
err = nvs_commit(handle);
|
||||
}
|
||||
nvs_close(handle);
|
||||
return err;
|
||||
esp_err_t BridgeProvisioningStore::saveObject(const char* key,
|
||||
const DaliValue::Object& object) const {
|
||||
return saveJsonObject(nvsNamespace_, key, object);
|
||||
}
|
||||
|
||||
esp_err_t BridgeProvisioningStore::loadObject(const char* key, DaliValue::Object* object) const {
|
||||
return loadJsonObject(nvsNamespace_, key, object);
|
||||
}
|
||||
|
||||
esp_err_t BridgeProvisioningStore::clearKey(const char* key) const {
|
||||
return clearStoredKey(nvsNamespace_, key);
|
||||
}
|
||||
|
||||
#else
|
||||
@@ -284,4 +330,22 @@ esp_err_t BridgeProvisioningStore::load(BridgeRuntimeConfig* config) const {
|
||||
|
||||
esp_err_t BridgeProvisioningStore::clear() const { return -1; }
|
||||
|
||||
esp_err_t BridgeProvisioningStore::saveObject(const char* key,
|
||||
const DaliValue::Object& object) const {
|
||||
(void)key;
|
||||
(void)object;
|
||||
return -1;
|
||||
}
|
||||
|
||||
esp_err_t BridgeProvisioningStore::loadObject(const char* key, DaliValue::Object* object) const {
|
||||
(void)key;
|
||||
(void)object;
|
||||
return -1;
|
||||
}
|
||||
|
||||
esp_err_t BridgeProvisioningStore::clearKey(const char* key) const {
|
||||
(void)key;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user