From 31220b3fded73ed85fb61ba1b98cd3bedb1b84de Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 25 Jun 2023 08:54:11 +0200 Subject: [PATCH] fix webEntity commands --- .../src/project/DashboardDevicesDialog.tsx | 12 ++-- src/command.cpp | 13 ++++ src/web/WebDataService.cpp | 10 +-- src/web/WebEntityService.cpp | 66 +++++++++++++++---- src/web/WebEntityService.h | 1 + 5 files changed, 80 insertions(+), 22 deletions(-) diff --git a/interface/src/project/DashboardDevicesDialog.tsx b/interface/src/project/DashboardDevicesDialog.tsx index f2ff2bc33..19103959a 100644 --- a/interface/src/project/DashboardDevicesDialog.tsx +++ b/interface/src/project/DashboardDevicesDialog.tsx @@ -94,12 +94,12 @@ const DashboarDevicesDialog = ({ } let helperText = '<'; - if (dv.u !== DeviceValueUOM.NONE) { + if (dv.s) { helperText += 'n'; - if (dv.m && dv.x) { + if (dv.m !== undefined && dv.x !== undefined) { + helperText += ' between ' + dv.m + ' and ' + dv.x; - } - if (dv.s) { + } else { helperText += ' , step ' + dv.s; } } else { @@ -144,7 +144,7 @@ const DashboarDevicesDialog = ({ ))} - ) : editItem.u !== DeviceValueUOM.NONE ? ( + ) : editItem.s || editItem.u !== DeviceValueUOM.NONE ? ( {setUom(editItem.u)} }} diff --git a/src/command.cpp b/src/command.cpp index 1f5cb1fc6..3bb89fd69 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -602,6 +602,19 @@ void Command::show_all(uuid::console::Shell & shell) { shell.print(COLOR_RESET); show(shell, EMSdevice::DeviceType::SYSTEM, true); + // show Custom + if (EMSESP::webEntityService.has_commands()) { + shell.print(COLOR_BOLD_ON); + shell.print(COLOR_YELLOW); + shell.printf(" %s: ", EMSdevice::device_type_2_device_name(EMSdevice::DeviceType::CUSTOM)); + shell.println(COLOR_RESET); + shell.printf(" info: %slists all values %s*", COLOR_BRIGHT_CYAN, COLOR_BRIGHT_RED); + shell.println(COLOR_RESET); + shell.printf(" commands: %slists all commands %s*", COLOR_BRIGHT_CYAN, COLOR_BRIGHT_RED); + shell.print(COLOR_RESET); + show(shell, EMSdevice::DeviceType::CUSTOM, true); + } + // show scheduler if (EMSESP::webSchedulerService.has_commands()) { shell.print(COLOR_BOLD_ON); diff --git a/src/web/WebDataService.cpp b/src/web/WebDataService.cpp index 054082011..472f94d10 100644 --- a/src/web/WebDataService.cpp +++ b/src/web/WebDataService.cpp @@ -242,7 +242,7 @@ void WebDataService::write_device_value(AsyncWebServerRequest * request, JsonVar // the data could be in any format, but we need string // authenticated is always true JsonVariant data = dv["v"]; // the value in any format - uint8_t return_code = CommandRet::OK; + uint8_t return_code = CommandRet::NOT_FOUND; uint8_t device_type = emsdevice->device_type(); if (data.is()) { return_code = Command::call(device_type, cmd, data.as(), true, id, output); @@ -279,16 +279,16 @@ void WebDataService::write_device_value(AsyncWebServerRequest * request, JsonVar auto * response = new AsyncJsonResponse(false, EMSESP_JSON_SIZE_SMALL); JsonObject output = response->getRoot(); JsonVariant data = dv["v"]; // the value in any format - uint8_t return_code = CommandRet::OK; + uint8_t return_code = CommandRet::NOT_FOUND; uint8_t device_type = EMSdevice::DeviceType::CUSTOM; - if (data.is()) { + if (data.is()) { + return_code = Command::call(device_type, cmd, data.as(), true, id, output); + } else if (data.is()) { char s[10]; return_code = Command::call(device_type, cmd, Helpers::render_value(s, data.as(), 0), true, id, output); } else if (data.is()) { char s[10]; return_code = Command::call(device_type, cmd, Helpers::render_value(s, data.as(), 1), true, id, output); - } else if (data.is()) { - return_code = Command::call(device_type, cmd, data.as() ? "true" : "false", true, id, output); } if (return_code != CommandRet::OK) { EMSESP::logger().err("Write command failed %s (%s)", (const char *)output["message"], Command::return_code_string(return_code).c_str()); diff --git a/src/web/WebEntityService.cpp b/src/web/WebEntityService.cpp index a52d8fc1b..7fbc20630 100644 --- a/src/web/WebEntityService.cpp +++ b/src/web/WebEntityService.cpp @@ -83,10 +83,12 @@ StateUpdateResult WebEntity::update(JsonObject & root, WebEntity & webEntity) { entityItem.value = EMS_VALUE_DEFAULT_SHORT; } else if (entityItem.value_type == DeviceValueType::USHORT) { entityItem.value = EMS_VALUE_DEFAULT_USHORT; - } else { // if (entityItem.value_type == DeviceValueType::ULONG || entityItem.valuetype == DeviceValueType::TIME) { + } else { // if (entityItem.value_type == DeviceValueType::ULONG || entityItem.value_type == DeviceValueType::TIME) { entityItem.value = EMS_VALUE_DEFAULT_ULONG; } - + if (entityItem.factor == 0) { + entityItem.factor = 1; + } webEntity.entityItems.push_back(entityItem); // add to list if (entityItem.writeable) { @@ -108,13 +110,13 @@ StateUpdateResult WebEntity::update(JsonObject & root, WebEntity & webEntity) { bool WebEntityService::command_setvalue(const char * value, const std::string name) { EMSESP::webEntityService.read([&](WebEntity & webEntity) { entityItems = &webEntity.entityItems; }); for (EntityItem & entityItem : *entityItems) { - if (entityItem.name == name) { + if (Helpers::toLower(entityItem.name) == Helpers::toLower(name)) { if (entityItem.value_type == DeviceValueType::BOOL) { bool v; if (!Helpers::value2bool(value, v)) { return false; } - EMSESP::send_write_request(entityItem.type_id, entityItem.device_id, entityItem.offset, v ? entityItem.type_id > 0xFF ? 1 : 0xFF : 0, 0); + EMSESP::send_write_request(entityItem.type_id, entityItem.device_id, entityItem.offset, v ? 0xFF : 0, 0); } else { float f; if (!Helpers::value2float(value, f)) { @@ -226,6 +228,7 @@ bool WebEntityService::get_value_info(JsonObject & output, const char * cmd) { if (Helpers::toLower(entity.name) == Helpers::toLower(command_s)) { output["name"] = entity.name; output["uom"] = EMSdevice::uom_to_string(entity.uom); + output["type"] = entity.value_type == DeviceValueType::BOOL ? "boolean" : F_(number); output["readable"] = true; output["writeable"] = entity.writeable; output["visible"] = true; @@ -311,19 +314,47 @@ void WebEntityService::publish(const bool force) { config["name"] = entityItem.name.c_str(); char topic[Mqtt::MQTT_TOPIC_MAX_SIZE]; - snprintf(topic, sizeof(topic), "sensor/%s/custom_%s/config", Mqtt::basename().c_str(), entityItem.name.c_str()); - //char command_topic[Mqtt::MQTT_TOPIC_MAX_SIZE]; - // snprintf(command_topic, sizeof(command_topic), "%s/custom/%s", Mqtt::basename().c_str(), entityItem.name.c_str()); - // config["cmd_t"] = command_topic; - + if (entityItem.writeable) { + if (entityItem.value_type == DeviceValueType::BOOL) { + snprintf(topic, sizeof(topic), "switch/%s/custom_%s/config", Mqtt::basename().c_str(), entityItem.name.c_str()); + } else if (Mqtt::discovery_type() == Mqtt::discoveryType::HOMEASSISTANT) { + snprintf(topic, sizeof(topic), "number/%s/custom_%s/config", Mqtt::basename().c_str(), entityItem.name.c_str()); + } else { + snprintf(topic, sizeof(topic), "sensor/%s/custom_%s/config", Mqtt::basename().c_str(), entityItem.name.c_str()); + } + char command_topic[Mqtt::MQTT_TOPIC_MAX_SIZE]; + snprintf(command_topic, sizeof(command_topic), "%s/custom/%s", Mqtt::basename().c_str(), entityItem.name.c_str()); + config["cmd_t"] = command_topic; + } else { + if (entityItem.value_type == DeviceValueType::BOOL) { + snprintf(topic, sizeof(topic), "binary_sensor/%s/custom_%s/config", Mqtt::basename().c_str(), entityItem.name.c_str()); + } else { + snprintf(topic, sizeof(topic), "sensor/%s/custom_%s/config", Mqtt::basename().c_str(), entityItem.name.c_str()); + } + } + if (entityItem.value_type == DeviceValueType::BOOL) { + // applies to both Binary Sensor (read only) and a Switch (for a command) + if (EMSESP::system_.bool_format() == BOOL_FORMAT_TRUEFALSE) { + config["pl_on"] = true; + config["pl_off"] = false; + } else if (EMSESP::system_.bool_format() == BOOL_FORMAT_10) { + config["pl_on"] = 1; + config["pl_off"] = 0; + } else { + char result[12]; + config["pl_on"] = Helpers::render_boolean(result, true); + config["pl_off"] = Helpers::render_boolean(result, false); + } + } JsonObject dev = config.createNestedObject("dev"); JsonArray ids = dev.createNestedArray("ids"); ids.add("ems-esp"); // add "availability" section Mqtt::add_avty_to_doc(stat_t, config.as(), val_cond); - Mqtt::queue_ha(topic, config.as()); - ha_registered_ = true; + if (Mqtt::queue_ha(topic, config.as())) { + ha_registered_ = true; + } } } if (output.size() > 0) { @@ -349,6 +380,15 @@ uint8_t WebEntityService::count_entities() { return count; } +uint8_t WebEntityService::has_commands() { + EMSESP::webEntityService.read([&](WebEntity & webEntity) { entityItems = &webEntity.entityItems; }); + uint8_t count = 0; + for (const EntityItem & entity : *entityItems) { + count += entity.writeable ? 1 : 0; + } + return count; +} + // send to dashboard, msgpack don't like serialized, use number void WebEntityService::generate_value_web(JsonObject & output) { EMSESP::webEntityService.read([&](WebEntity & webEntity) { entityItems = &webEntity.entityItems; }); @@ -362,6 +402,10 @@ void WebEntityService::generate_value_web(JsonObject & output) { obj["u"] = entity.uom; if (entity.writeable) { obj["c"] = entity.name; + if (entity.value_type != DeviceValueType::BOOL) { + char s[10]; + obj["s"] = Helpers::render_value(s, entity.factor, 1); + } } switch (entity.value_type) { diff --git a/src/web/WebEntityService.h b/src/web/WebEntityService.h index 9010cacf1..05160ee1a 100644 --- a/src/web/WebEntityService.h +++ b/src/web/WebEntityService.h @@ -60,6 +60,7 @@ class WebEntityService : public StatefulService { void fetch(); void render_value(JsonObject & output, EntityItem entity, const bool useVal = false, const bool web = false); uint8_t count_entities(); + uint8_t has_commands(); void generate_value_web(JsonObject & output);