mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 00:09:51 +03:00
Change name of entity within WebUI #612
This commit is contained in:
@@ -260,7 +260,7 @@ const SettingsCustomization: FC = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await EMSESP.writeMaskedEntities({
|
const response = await EMSESP.writeCustomEntities({
|
||||||
id: devices?.devices[selectedDevice].i,
|
id: devices?.devices[selectedDevice].i,
|
||||||
entity_ids: masked_entities
|
entity_ids: masked_entities
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
DeviceData,
|
DeviceData,
|
||||||
DeviceEntity,
|
DeviceEntity,
|
||||||
UniqueID,
|
UniqueID,
|
||||||
MaskedEntities,
|
CustomEntities,
|
||||||
WriteValue,
|
WriteValue,
|
||||||
WriteSensor,
|
WriteSensor,
|
||||||
WriteAnalog,
|
WriteAnalog,
|
||||||
@@ -63,8 +63,8 @@ export function readDeviceEntities(unique_id: UniqueID): AxiosPromise<DeviceEnti
|
|||||||
return AXIOS_BIN.post('/deviceEntities', unique_id);
|
return AXIOS_BIN.post('/deviceEntities', unique_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function writeMaskedEntities(maskedEntities: MaskedEntities): AxiosPromise<void> {
|
export function writeCustomEntities(customEntities: CustomEntities): AxiosPromise<void> {
|
||||||
return AXIOS.post('/maskedEntities', maskedEntities);
|
return AXIOS.post('/customEntities', customEntities);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function writeValue(writevalue: WriteValue): AxiosPromise<void> {
|
export function writeValue(writevalue: WriteValue): AxiosPromise<void> {
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ export interface DeviceEntity {
|
|||||||
w: boolean; // writeable
|
w: boolean; // writeable
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MaskedEntities {
|
export interface CustomEntities {
|
||||||
id: number;
|
id: number;
|
||||||
entity_ids: string[];
|
entity_ids: string[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -302,7 +302,7 @@ const EMSESP_BOARDPROFILE_ENDPOINT = REST_ENDPOINT_ROOT + 'boardProfile'
|
|||||||
const EMSESP_WRITE_VALUE_ENDPOINT = REST_ENDPOINT_ROOT + 'writeValue'
|
const EMSESP_WRITE_VALUE_ENDPOINT = REST_ENDPOINT_ROOT + 'writeValue'
|
||||||
const EMSESP_WRITE_SENSOR_ENDPOINT = REST_ENDPOINT_ROOT + 'writeSensor'
|
const EMSESP_WRITE_SENSOR_ENDPOINT = REST_ENDPOINT_ROOT + 'writeSensor'
|
||||||
const EMSESP_WRITE_ANALOG_ENDPOINT = REST_ENDPOINT_ROOT + 'writeAnalog'
|
const EMSESP_WRITE_ANALOG_ENDPOINT = REST_ENDPOINT_ROOT + 'writeAnalog'
|
||||||
const EMSESP_MASKED_ENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'maskedEntities'
|
const EMSESP_CUSTOM_ENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'customEntities'
|
||||||
const EMSESP_RESET_CUSTOMIZATIONS_ENDPOINT = REST_ENDPOINT_ROOT + 'resetCustomizations'
|
const EMSESP_RESET_CUSTOMIZATIONS_ENDPOINT = REST_ENDPOINT_ROOT + 'resetCustomizations'
|
||||||
|
|
||||||
settings = {
|
settings = {
|
||||||
@@ -978,7 +978,7 @@ function updateMask(entity, de, dd) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rest_server.post(EMSESP_MASKED_ENTITIES_ENDPOINT, (req, res) => {
|
rest_server.post(EMSESP_CUSTOM_ENTITIES_ENDPOINT, (req, res) => {
|
||||||
const id = req.body.id
|
const id = req.body.id
|
||||||
console.log('customization id = ' + id)
|
console.log('customization id = ' + id)
|
||||||
console.log(req.body.entity_ids)
|
console.log(req.body.entity_ids)
|
||||||
|
|||||||
@@ -37,18 +37,18 @@ void AnalogSensor::start() {
|
|||||||
EMSdevice::DeviceType::ANALOGSENSOR,
|
EMSdevice::DeviceType::ANALOGSENSOR,
|
||||||
F_(info),
|
F_(info),
|
||||||
[&](const char * value, const int8_t id, JsonObject & output) { return command_info(value, id, output); },
|
[&](const char * value, const int8_t id, JsonObject & output) { return command_info(value, id, output); },
|
||||||
F_(info_cmd));
|
uuid::read_flash_string(F_(info_cmd)));
|
||||||
Command::add(
|
Command::add(
|
||||||
EMSdevice::DeviceType::ANALOGSENSOR,
|
EMSdevice::DeviceType::ANALOGSENSOR,
|
||||||
F_(setvalue),
|
F_(setvalue),
|
||||||
[&](const char * value, const int8_t id) { return command_setvalue(value, id); },
|
[&](const char * value, const int8_t id) { return command_setvalue(value, id); },
|
||||||
F("set io value"),
|
"set io value", // TODO this needs translating
|
||||||
CommandFlag::ADMIN_ONLY);
|
CommandFlag::ADMIN_ONLY);
|
||||||
Command::add(
|
Command::add(
|
||||||
EMSdevice::DeviceType::ANALOGSENSOR,
|
EMSdevice::DeviceType::ANALOGSENSOR,
|
||||||
F_(commands),
|
F_(commands),
|
||||||
[&](const char * value, const int8_t id, JsonObject & output) { return command_commands(value, id, output); },
|
[&](const char * value, const int8_t id, JsonObject & output) { return command_commands(value, id, output); },
|
||||||
F_(commands_cmd));
|
uuid::read_flash_string(F_(commands_cmd)));
|
||||||
|
|
||||||
Mqtt::subscribe(EMSdevice::DeviceType::ANALOGSENSOR, "analogsensor/#", nullptr); // use empty function callback
|
Mqtt::subscribe(EMSdevice::DeviceType::ANALOGSENSOR, "analogsensor/#", nullptr); // use empty function callback
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -264,15 +264,15 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char *
|
|||||||
|
|
||||||
if ((value == nullptr) || (strlen(value) == 0)) {
|
if ((value == nullptr) || (strlen(value) == 0)) {
|
||||||
if (EMSESP::system_.readonly_mode()) {
|
if (EMSESP::system_.readonly_mode()) {
|
||||||
LOG_INFO(F("[readonly] Calling command '%s/%s' (%s)"), dname.c_str(), cmd, read_flash_string(cf->description_).c_str());
|
LOG_INFO(F("[readonly] Calling command '%s/%s' (%s)"), dname.c_str(), cmd, cf->description_.c_str());
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG(F("Calling command '%s/%s' (%s)"), dname.c_str(), cmd, read_flash_string(cf->description_).c_str());
|
LOG_DEBUG(F("Calling command '%s/%s' (%s)"), dname.c_str(), cmd, cf->description_.c_str());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (EMSESP::system_.readonly_mode()) {
|
if (EMSESP::system_.readonly_mode()) {
|
||||||
LOG_INFO(F("[readonly] Calling command '%s/%s' (%s) with value %s"), dname.c_str(), cmd, read_flash_string(cf->description_).c_str(), value);
|
LOG_INFO(F("[readonly] Calling command '%s/%s' (%s) with value %s"), dname.c_str(), cmd, cf->description_.c_str(), value);
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG(F("Calling command '%s/%s' (%s) with value %s"), dname.c_str(), cmd, read_flash_string(cf->description_).c_str(), value);
|
LOG_DEBUG(F("Calling command '%s/%s' (%s) with value %s"), dname.c_str(), cmd, cf->description_.c_str(), value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,14 +299,14 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char *
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add a command to the list, which does not return json
|
// add a command to the list, which does not return json
|
||||||
void Command::add(const uint8_t device_type, const __FlashStringHelper * cmd, const cmd_function_p cb, const __FlashStringHelper * description, uint8_t flags) {
|
void Command::add(const uint8_t device_type, const __FlashStringHelper * cmd, const cmd_function_p cb, const std::string & description, uint8_t flags) {
|
||||||
// if the command already exists for that device type don't add it
|
// if the command already exists for that device type don't add it
|
||||||
if (find_command(device_type, read_flash_string(cmd).c_str()) != nullptr) {
|
if (find_command(device_type, read_flash_string(cmd).c_str()) != nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the description is empty, it's hidden which means it will not show up in Web API or Console as an available command
|
// if the description is empty, it's hidden which means it will not show up in Web API or Console as an available command
|
||||||
if (description == nullptr) {
|
if (description.empty()) {
|
||||||
flags |= CommandFlag::HIDDEN;
|
flags |= CommandFlag::HIDDEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,7 +314,7 @@ void Command::add(const uint8_t device_type, const __FlashStringHelper * cmd, co
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add a command to the list, which does return a json object as output
|
// add a command to the list, which does return a json object as output
|
||||||
void Command::add(const uint8_t device_type, const __FlashStringHelper * cmd, const cmd_json_function_p cb, const __FlashStringHelper * description, uint8_t flags) {
|
void Command::add(const uint8_t device_type, const __FlashStringHelper * cmd, const cmd_json_function_p cb, const std::string & description, uint8_t flags) {
|
||||||
// if the command already exists for that device type don't add it
|
// if the command already exists for that device type don't add it
|
||||||
if (find_command(device_type, read_flash_string(cmd).c_str()) != nullptr) {
|
if (find_command(device_type, read_flash_string(cmd).c_str()) != nullptr) {
|
||||||
return;
|
return;
|
||||||
@@ -364,7 +364,7 @@ bool Command::list(const uint8_t device_type, JsonObject & output) {
|
|||||||
|
|
||||||
for (const auto & cl : sorted_cmds) {
|
for (const auto & cl : sorted_cmds) {
|
||||||
for (const auto & cf : cmdfunctions_) {
|
for (const auto & cf : cmdfunctions_) {
|
||||||
if ((cf.device_type_ == device_type) && !cf.has_flags(CommandFlag::HIDDEN) && cf.description_ && (cl == read_flash_string(cf.cmd_))) {
|
if ((cf.device_type_ == device_type) && !cf.has_flags(CommandFlag::HIDDEN) && !cf.description_.empty() && (cl == read_flash_string(cf.cmd_))) {
|
||||||
output[cl] = cf.description_;
|
output[cl] = cf.description_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -404,7 +404,7 @@ void Command::show(uuid::console::Shell & shell, uint8_t device_type, bool verbo
|
|||||||
for (const auto & cl : sorted_cmds) {
|
for (const auto & cl : sorted_cmds) {
|
||||||
// find and print the description
|
// find and print the description
|
||||||
for (const auto & cf : cmdfunctions_) {
|
for (const auto & cf : cmdfunctions_) {
|
||||||
if ((cf.device_type_ == device_type) && !cf.has_flags(CommandFlag::HIDDEN) && cf.description_ && (cl == read_flash_string(cf.cmd_))) {
|
if ((cf.device_type_ == device_type) && !cf.has_flags(CommandFlag::HIDDEN) && !cf.description_.empty() && (cl == read_flash_string(cf.cmd_))) {
|
||||||
uint8_t i = cl.length();
|
uint8_t i = cl.length();
|
||||||
shell.print(" ");
|
shell.print(" ");
|
||||||
if (cf.has_flags(MQTT_SUB_FLAG_HC)) {
|
if (cf.has_flags(MQTT_SUB_FLAG_HC)) {
|
||||||
@@ -424,7 +424,7 @@ void Command::show(uuid::console::Shell & shell, uint8_t device_type, bool verbo
|
|||||||
shell.print(EMSdevice::tag_to_string(DeviceValueTAG::TAG_DEVICE_DATA_WW));
|
shell.print(EMSdevice::tag_to_string(DeviceValueTAG::TAG_DEVICE_DATA_WW));
|
||||||
shell.print(' ');
|
shell.print(' ');
|
||||||
}
|
}
|
||||||
shell.print(read_flash_string(cf.description_));
|
shell.print(cf.description_.c_str());
|
||||||
if (!cf.has_flags(CommandFlag::ADMIN_ONLY)) {
|
if (!cf.has_flags(CommandFlag::ADMIN_ONLY)) {
|
||||||
shell.print(' ');
|
shell.print(' ');
|
||||||
shell.print(COLOR_BRIGHT_RED);
|
shell.print(COLOR_BRIGHT_RED);
|
||||||
|
|||||||
@@ -59,14 +59,14 @@ class Command {
|
|||||||
const __FlashStringHelper * cmd_;
|
const __FlashStringHelper * cmd_;
|
||||||
const cmd_function_p cmdfunction_;
|
const cmd_function_p cmdfunction_;
|
||||||
const cmd_json_function_p cmdfunction_json_;
|
const cmd_json_function_p cmdfunction_json_;
|
||||||
const __FlashStringHelper * description_;
|
const std::string description_;
|
||||||
|
|
||||||
CmdFunction(const uint8_t device_type,
|
CmdFunction(const uint8_t device_type,
|
||||||
const uint8_t flags,
|
const uint8_t flags,
|
||||||
const __FlashStringHelper * cmd,
|
const __FlashStringHelper * cmd,
|
||||||
const cmd_function_p cmdfunction,
|
const cmd_function_p cmdfunction,
|
||||||
const cmd_json_function_p cmdfunction_json,
|
const cmd_json_function_p cmdfunction_json,
|
||||||
const __FlashStringHelper * description)
|
const std::string & description)
|
||||||
: device_type_(device_type)
|
: device_type_(device_type)
|
||||||
, flags_(flags)
|
, flags_(flags)
|
||||||
, cmd_(cmd)
|
, cmd_(cmd)
|
||||||
@@ -102,14 +102,14 @@ class Command {
|
|||||||
static void add(const uint8_t device_type,
|
static void add(const uint8_t device_type,
|
||||||
const __FlashStringHelper * cmd,
|
const __FlashStringHelper * cmd,
|
||||||
const cmd_function_p cb,
|
const cmd_function_p cb,
|
||||||
const __FlashStringHelper * description,
|
const std::string & description,
|
||||||
uint8_t flags = CommandFlag::MQTT_SUB_FLAG_DEFAULT);
|
uint8_t flags = CommandFlag::MQTT_SUB_FLAG_DEFAULT);
|
||||||
|
|
||||||
// callback function taking value, id and a json object for its output
|
// callback function taking value, id and a json object for its output
|
||||||
static void add(const uint8_t device_type,
|
static void add(const uint8_t device_type,
|
||||||
const __FlashStringHelper * cmd,
|
const __FlashStringHelper * cmd,
|
||||||
const cmd_json_function_p cb,
|
const cmd_json_function_p cb,
|
||||||
const __FlashStringHelper * description,
|
const std::string & description,
|
||||||
uint8_t flags = CommandFlag::MQTT_SUB_FLAG_DEFAULT);
|
uint8_t flags = CommandFlag::MQTT_SUB_FLAG_DEFAULT);
|
||||||
|
|
||||||
static void show_all(uuid::console::Shell & shell);
|
static void show_all(uuid::console::Shell & shell);
|
||||||
|
|||||||
@@ -50,12 +50,12 @@ void DallasSensor::start() {
|
|||||||
EMSdevice::DeviceType::DALLASSENSOR,
|
EMSdevice::DeviceType::DALLASSENSOR,
|
||||||
F_(info),
|
F_(info),
|
||||||
[&](const char * value, const int8_t id, JsonObject & output) { return command_info(value, id, output); },
|
[&](const char * value, const int8_t id, JsonObject & output) { return command_info(value, id, output); },
|
||||||
F_(info_cmd));
|
uuid::read_flash_string(F_(info_cmd)));
|
||||||
Command::add(
|
Command::add(
|
||||||
EMSdevice::DeviceType::DALLASSENSOR,
|
EMSdevice::DeviceType::DALLASSENSOR,
|
||||||
F_(commands),
|
F_(commands),
|
||||||
[&](const char * value, const int8_t id, JsonObject & output) { return command_commands(value, id, output); },
|
[&](const char * value, const int8_t id, JsonObject & output) { return command_commands(value, id, output); },
|
||||||
F_(commands_cmd));
|
uuid::read_flash_string(F_(commands_cmd)));
|
||||||
|
|
||||||
Mqtt::subscribe(EMSdevice::DeviceType::DALLASSENSOR, "dallasssensor/#", nullptr); // use empty function callback
|
Mqtt::subscribe(EMSdevice::DeviceType::DALLASSENSOR, "dallasssensor/#", nullptr); // use empty function callback
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -444,13 +444,13 @@ void EMSdevice::add_device_value(uint8_t tag,
|
|||||||
for (std::string entity_id : entityCustomization.entity_ids) {
|
for (std::string entity_id : entityCustomization.entity_ids) {
|
||||||
// if there is an appended custom name, strip it to get the true entity name
|
// if there is an appended custom name, strip it to get the true entity name
|
||||||
// and extract the new custom name
|
// and extract the new custom name
|
||||||
std::string matched_entity;
|
std::string shortname;
|
||||||
auto custom_name_pos = entity_id.find('|');
|
auto custom_name_pos = entity_id.find('|');
|
||||||
bool has_custom_name = (custom_name_pos != std::string::npos);
|
bool has_custom_name = (custom_name_pos != std::string::npos);
|
||||||
if (has_custom_name) {
|
if (has_custom_name) {
|
||||||
matched_entity = entity_id.substr(2, custom_name_pos - 2);
|
shortname = entity_id.substr(2, custom_name_pos - 2);
|
||||||
} else {
|
} else {
|
||||||
matched_entity = entity_id.substr(2);
|
shortname = entity_id.substr(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -465,7 +465,7 @@ void EMSdevice::add_device_value(uint8_t tag,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// we found the device entity
|
// we found the device entity
|
||||||
if (matched_entity == entity) {
|
if (shortname == entity) {
|
||||||
// get Mask
|
// get Mask
|
||||||
uint8_t mask = Helpers::hextoint(entity_id.substr(0, 2).c_str());
|
uint8_t mask = Helpers::hextoint(entity_id.substr(0, 2).c_str());
|
||||||
state = mask << 4; // set state high bits to flag, turn off active and ha flags
|
state = mask << 4; // set state high bits to flag, turn off active and ha flags
|
||||||
@@ -506,8 +506,7 @@ void EMSdevice::add_device_value(uint8_t tag,
|
|||||||
|
|
||||||
// add the command to our library
|
// add the command to our library
|
||||||
// cmd is the short_name and the description is the fullname
|
// cmd is the short_name and the description is the fullname
|
||||||
// TODO this needs adapting to take the custom fullname since its not a FPTR()
|
Command::add(device_type_, short_name, f, Helpers::translated_word(fullname), flags);
|
||||||
Command::add(device_type_, short_name, f, Helpers::translated_fword(fullname), flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// single list of options
|
// single list of options
|
||||||
@@ -989,34 +988,59 @@ void EMSdevice::generate_values_web_customization(JsonArray & output) {
|
|||||||
|
|
||||||
// set mask per device entity based on the id which is prefixed with the 2 char hex mask value
|
// set mask per device entity based on the id which is prefixed with the 2 char hex mask value
|
||||||
// returns true if the entity has a mask set (not 0 the default)
|
// returns true if the entity has a mask set (not 0 the default)
|
||||||
void EMSdevice::mask_entity(const std::string & entity_id) {
|
void EMSdevice::setCustomEntity(const std::string & entity_id) {
|
||||||
for (auto & dv : devicevalues_) {
|
for (auto & dv : devicevalues_) {
|
||||||
std::string entity_name =
|
std::string entity_name =
|
||||||
dv.tag < DeviceValueTAG::TAG_HC1 ? read_flash_string(dv.short_name) : tag_to_string(dv.tag) + "/" + read_flash_string(dv.short_name);
|
dv.tag < DeviceValueTAG::TAG_HC1 ? read_flash_string(dv.short_name) : tag_to_string(dv.tag) + "/" + read_flash_string(dv.short_name);
|
||||||
if (entity_name == entity_id.substr(2)) {
|
|
||||||
// this entity has a new mask set
|
// extra shortname
|
||||||
|
std::string shortname;
|
||||||
|
auto custom_name_pos = entity_id.find('|');
|
||||||
|
bool has_custom_name = (custom_name_pos != std::string::npos);
|
||||||
|
if (has_custom_name) {
|
||||||
|
shortname = entity_id.substr(2, custom_name_pos - 2);
|
||||||
|
} else {
|
||||||
|
shortname = entity_id.substr(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity_name == shortname) {
|
||||||
|
// check the masks
|
||||||
uint8_t current_mask = dv.state >> 4;
|
uint8_t current_mask = dv.state >> 4;
|
||||||
uint8_t new_mask = Helpers::hextoint(entity_id.substr(0, 2).c_str()); // first character contains mask flags
|
uint8_t new_mask = Helpers::hextoint(entity_id.substr(0, 2).c_str()); // first character contains mask flags
|
||||||
|
|
||||||
|
// if it's a new mask, reconfigure HA
|
||||||
if (Mqtt::ha_enabled() && ((current_mask ^ new_mask) & (DeviceValueState::DV_READONLY >> 4))) {
|
if (Mqtt::ha_enabled() && ((current_mask ^ new_mask) & (DeviceValueState::DV_READONLY >> 4))) {
|
||||||
// remove ha config on change of dv_readonly flag
|
// remove ha config on change of dv_readonly flag
|
||||||
dv.remove_state(DeviceValueState::DV_HA_CONFIG_CREATED);
|
dv.remove_state(DeviceValueState::DV_HA_CONFIG_CREATED);
|
||||||
Mqtt::publish_ha_sensor_config(dv, "", "", true); // delete topic (remove = true)
|
Mqtt::publish_ha_sensor_config(dv, "", "", true); // delete topic (remove = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// always write the mask
|
||||||
dv.state = ((dv.state & 0x0F) | (new_mask << 4)); // set state high bits to flag
|
dv.state = ((dv.state & 0x0F) | (new_mask << 4)); // set state high bits to flag
|
||||||
|
|
||||||
|
// set the custom name if it has one
|
||||||
|
if (has_custom_name) {
|
||||||
|
dv.custom_fullname = entity_id.substr(custom_name_pos + 1);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// populate a string vector with entities that have masks set
|
// populate a string vector with entities that have masks set or have a custom name
|
||||||
void EMSdevice::getMaskedEntities(std::vector<std::string> & entity_ids) {
|
void EMSdevice::getCustomEntities(std::vector<std::string> & entity_ids) {
|
||||||
for (const auto & dv : devicevalues_) {
|
for (const auto & dv : devicevalues_) {
|
||||||
std::string entity_name =
|
std::string entity_name =
|
||||||
dv.tag < DeviceValueTAG::TAG_HC1 ? read_flash_string(dv.short_name) : tag_to_string(dv.tag) + "/" + read_flash_string(dv.short_name);
|
dv.tag < DeviceValueTAG::TAG_HC1 ? read_flash_string(dv.short_name) : tag_to_string(dv.tag) + "/" + read_flash_string(dv.short_name);
|
||||||
uint8_t mask = dv.state >> 4;
|
uint8_t mask = dv.state >> 4;
|
||||||
|
|
||||||
if (mask) {
|
if (mask || !dv.custom_fullname.empty()) {
|
||||||
entity_ids.push_back(Helpers::hextoa(mask, false) + entity_name);
|
if (dv.custom_fullname.empty()) {
|
||||||
|
entity_ids.push_back(Helpers::hextoa(mask, false) + entity_name);
|
||||||
|
} else {
|
||||||
|
entity_ids.push_back(Helpers::hextoa(mask, false) + entity_name + "|" + dv.custom_fullname);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,8 +187,8 @@ class EMSdevice {
|
|||||||
void list_device_entries(JsonObject & output) const;
|
void list_device_entries(JsonObject & output) const;
|
||||||
void add_handlers_ignored(const uint16_t handler);
|
void add_handlers_ignored(const uint16_t handler);
|
||||||
|
|
||||||
void mask_entity(const std::string & entity_id);
|
void setCustomEntity(const std::string & entity_id);
|
||||||
void getMaskedEntities(std::vector<std::string> & entity_ids);
|
void getCustomEntities(std::vector<std::string> & entity_ids);
|
||||||
|
|
||||||
using process_function_p = std::function<void(std::shared_ptr<const Telegram>)>;
|
using process_function_p = std::function<void(std::shared_ptr<const Telegram>)>;
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ DeviceValue::DeviceValue(uint8_t device_type,
|
|||||||
int8_t numeric_operator,
|
int8_t numeric_operator,
|
||||||
const __FlashStringHelper * const short_name,
|
const __FlashStringHelper * const short_name,
|
||||||
const __FlashStringHelper * const * fullname,
|
const __FlashStringHelper * const * fullname,
|
||||||
const std::string & custom_fullname,
|
std::string & custom_fullname,
|
||||||
uint8_t uom,
|
uint8_t uom,
|
||||||
bool has_cmd,
|
bool has_cmd,
|
||||||
int16_t min,
|
int16_t min,
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ class DeviceValue {
|
|||||||
uint8_t options_size; // number of options in the char array, calculated
|
uint8_t options_size; // number of options in the char array, calculated
|
||||||
const __FlashStringHelper * const short_name; // used in MQTT and API
|
const __FlashStringHelper * const short_name; // used in MQTT and API
|
||||||
const __FlashStringHelper * const * fullname; // used in Web and Console, is translated
|
const __FlashStringHelper * const * fullname; // used in Web and Console, is translated
|
||||||
const std::string custom_fullname; // optional, from customization
|
std::string custom_fullname; // optional, from customization
|
||||||
uint8_t uom; // DeviceValueUOM::*
|
uint8_t uom; // DeviceValueUOM::*
|
||||||
bool has_cmd; // true if there is a Console/MQTT command which matches the short_name
|
bool has_cmd; // true if there is a Console/MQTT command which matches the short_name
|
||||||
int16_t min; // min range
|
int16_t min; // min range
|
||||||
@@ -169,7 +169,7 @@ class DeviceValue {
|
|||||||
int8_t numeric_operator,
|
int8_t numeric_operator,
|
||||||
const __FlashStringHelper * const short_name,
|
const __FlashStringHelper * const short_name,
|
||||||
const __FlashStringHelper * const * fullname,
|
const __FlashStringHelper * const * fullname,
|
||||||
const std::string & custom_fullname,
|
std::string & custom_fullname,
|
||||||
uint8_t uom,
|
uint8_t uom,
|
||||||
bool has_cmd,
|
bool has_cmd,
|
||||||
int16_t min,
|
int16_t min,
|
||||||
|
|||||||
@@ -1052,25 +1052,25 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const
|
|||||||
[device_type](const char * value, const int8_t id, JsonObject & output) {
|
[device_type](const char * value, const int8_t id, JsonObject & output) {
|
||||||
return command_info(device_type, output, id, EMSdevice::OUTPUT_TARGET::API_VERBOSE);
|
return command_info(device_type, output, id, EMSdevice::OUTPUT_TARGET::API_VERBOSE);
|
||||||
},
|
},
|
||||||
F_(info_cmd));
|
uuid::read_flash_string(F_(info_cmd)));
|
||||||
Command::add(
|
Command::add(
|
||||||
device_type,
|
device_type,
|
||||||
F("values"),
|
F("values"),
|
||||||
[device_type](const char * value, const int8_t id, JsonObject & output) {
|
[device_type](const char * value, const int8_t id, JsonObject & output) {
|
||||||
return command_info(device_type, output, id, EMSdevice::OUTPUT_TARGET::API_SHORTNAMES); // HIDDEN command showing short names, used in e.g. /api/boiler
|
return command_info(device_type, output, id, EMSdevice::OUTPUT_TARGET::API_SHORTNAMES); // HIDDEN command showing short names, used in e.g. /api/boiler
|
||||||
},
|
},
|
||||||
nullptr,
|
"",
|
||||||
CommandFlag::HIDDEN); // this command is hidden
|
CommandFlag::HIDDEN); // this command is hidden
|
||||||
Command::add(
|
Command::add(
|
||||||
device_type,
|
device_type,
|
||||||
F_(commands),
|
F_(commands),
|
||||||
[device_type](const char * value, const int8_t id, JsonObject & output) { return command_commands(device_type, output, id); },
|
[device_type](const char * value, const int8_t id, JsonObject & output) { return command_commands(device_type, output, id); },
|
||||||
F_(commands_cmd));
|
uuid::read_flash_string(F_(commands_cmd)));
|
||||||
Command::add(
|
Command::add(
|
||||||
device_type,
|
device_type,
|
||||||
F_(entities),
|
F_(entities),
|
||||||
[device_type](const char * value, const int8_t id, JsonObject & output) { return command_entities(device_type, output, id); },
|
[device_type](const char * value, const int8_t id, JsonObject & output) { return command_entities(device_type, output, id); },
|
||||||
F_(entities_cmd));
|
uuid::read_flash_string(F_(entities_cmd)));
|
||||||
|
|
||||||
// MQTT subscribe to the device e.g. "ems-esp/boiler/#"
|
// MQTT subscribe to the device e.g. "ems-esp/boiler/#"
|
||||||
Mqtt::subscribe(device_type, EMSdevice::device_type_2_device_name(device_type) + "/#", nullptr);
|
Mqtt::subscribe(device_type, EMSdevice::device_type_2_device_name(device_type) + "/#", nullptr);
|
||||||
|
|||||||
@@ -958,7 +958,7 @@ void Mqtt::publish_system_ha_sensor_config(uint8_t type, const __FlashStringHelp
|
|||||||
JsonArray ids = dev_json.createNestedArray("ids");
|
JsonArray ids = dev_json.createNestedArray("ids");
|
||||||
ids.add("ems-esp");
|
ids.add("ems-esp");
|
||||||
|
|
||||||
auto fullname = read_flash_string(name); // TODO make sure it works, it may need a std::move()?
|
auto fullname = read_flash_string(name);
|
||||||
|
|
||||||
publish_ha_sensor_config(type, DeviceValueTAG::TAG_HEARTBEAT, fullname, EMSdevice::DeviceType::SYSTEM, entity, uom, false, false, nullptr, 0, 0, 0, dev_json);
|
publish_ha_sensor_config(type, DeviceValueTAG::TAG_HEARTBEAT, fullname, EMSdevice::DeviceType::SYSTEM, entity, uom, false, false, nullptr, 0, 0, 0, dev_json);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -291,7 +291,8 @@ void System::syslog_init() {
|
|||||||
syslog_.hostname(hostname().c_str());
|
syslog_.hostname(hostname().c_str());
|
||||||
|
|
||||||
// register the command
|
// register the command
|
||||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(syslog), System::command_syslog_level, F("change the syslog level"), CommandFlag::ADMIN_ONLY);
|
// TODO translate this
|
||||||
|
Command::add(EMSdevice::DeviceType::SYSTEM, F_(syslog), System::command_syslog_level, "change the syslog level", CommandFlag::ADMIN_ONLY);
|
||||||
|
|
||||||
} else if (was_enabled) {
|
} else if (was_enabled) {
|
||||||
// in case service is still running, this flushes the queue
|
// in case service is still running, this flushes the queue
|
||||||
@@ -695,23 +696,26 @@ void System::system_check() {
|
|||||||
// commands - takes static function pointers
|
// commands - takes static function pointers
|
||||||
void System::commands_init() {
|
void System::commands_init() {
|
||||||
// Command::add(EMSdevice::DeviceType::SYSTEM, F_(pin), System::command_pin, F("set a GPIO on/off"), CommandFlag::ADMIN_ONLY);
|
// Command::add(EMSdevice::DeviceType::SYSTEM, F_(pin), System::command_pin, F("set a GPIO on/off"), CommandFlag::ADMIN_ONLY);
|
||||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(send), System::command_send, F("send a telegram"), CommandFlag::ADMIN_ONLY);
|
|
||||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(fetch), System::command_fetch, F("refresh all EMS values"), CommandFlag::ADMIN_ONLY);
|
// TODO these should be translated too
|
||||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(restart), System::command_restart, F("restart EMS-ESP"), CommandFlag::ADMIN_ONLY);
|
Command::add(EMSdevice::DeviceType::SYSTEM, F_(send), System::command_send, "send a telegram", CommandFlag::ADMIN_ONLY);
|
||||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(watch), System::command_watch, F("watch incoming telegrams"));
|
Command::add(EMSdevice::DeviceType::SYSTEM, F_(fetch), System::command_fetch, "refresh all EMS values", CommandFlag::ADMIN_ONLY);
|
||||||
|
Command::add(EMSdevice::DeviceType::SYSTEM, F_(restart), System::command_restart, "restart EMS-ESP", CommandFlag::ADMIN_ONLY);
|
||||||
|
Command::add(EMSdevice::DeviceType::SYSTEM, F_(watch), System::command_watch, "watch incoming telegrams");
|
||||||
|
|
||||||
// register syslog command in syslog init
|
// register syslog command in syslog init
|
||||||
// Command::add(EMSdevice::DeviceType::SYSTEM, F_(syslog), System::command_syslog_level, F("set syslog level"), CommandFlag::ADMIN_ONLY);
|
// Command::add(EMSdevice::DeviceType::SYSTEM, F_(syslog), System::command_syslog_level, F("set syslog level"), CommandFlag::ADMIN_ONLY);
|
||||||
|
|
||||||
if (Mqtt::enabled()) {
|
if (Mqtt::enabled()) {
|
||||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(publish), System::command_publish, F("force a MQTT publish"));
|
Command::add(EMSdevice::DeviceType::SYSTEM, F_(publish), System::command_publish, "force a MQTT publish");
|
||||||
}
|
}
|
||||||
|
|
||||||
// these commands will return data in JSON format
|
// these commands will return data in JSON format
|
||||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(info), System::command_info, F("show system status"));
|
Command::add(EMSdevice::DeviceType::SYSTEM, F_(info), System::command_info, "show system status");
|
||||||
Command::add(EMSdevice::DeviceType::SYSTEM, F_(commands), System::command_commands, F("fetch system commands"));
|
Command::add(EMSdevice::DeviceType::SYSTEM, F_(commands), System::command_commands, "fetch system commands");
|
||||||
|
|
||||||
#if defined(EMSESP_DEBUG)
|
#if defined(EMSESP_DEBUG)
|
||||||
Command::add(EMSdevice::DeviceType::SYSTEM, F("test"), System::command_test, F("run a specific test"));
|
Command::add(EMSdevice::DeviceType::SYSTEM, F("test"), System::command_test, "run a specific test");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// MQTT subscribe "ems-esp/system/#"
|
// MQTT subscribe "ems-esp/system/#"
|
||||||
|
|||||||
@@ -616,7 +616,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
|||||||
for (const auto & emsdevice : EMSESP::emsdevices) {
|
for (const auto & emsdevice : EMSESP::emsdevices) {
|
||||||
if (emsdevice->unique_id() == 1) { // boiler
|
if (emsdevice->unique_id() == 1) { // boiler
|
||||||
std::string a = "07wwseltemp";
|
std::string a = "07wwseltemp";
|
||||||
emsdevice->mask_entity(a);
|
emsdevice->setCustomEntity(a);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ WebCustomizationService::WebCustomizationService(AsyncWebServer * server, FS * f
|
|||||||
securityManager,
|
securityManager,
|
||||||
AuthenticationPredicates::IS_AUTHENTICATED)
|
AuthenticationPredicates::IS_AUTHENTICATED)
|
||||||
, _fsPersistence(WebCustomization::read, WebCustomization::update, this, fs, EMSESP_CUSTOMIZATION_FILE)
|
, _fsPersistence(WebCustomization::read, WebCustomization::update, this, fs, EMSESP_CUSTOMIZATION_FILE)
|
||||||
, _masked_entities_handler(MASKED_ENTITIES_PATH,
|
, _masked_entities_handler(CUSTOM_ENTITIES_PATH,
|
||||||
securityManager->wrapCallback(std::bind(&WebCustomizationService::masked_entities, this, _1, _2),
|
securityManager->wrapCallback(std::bind(&WebCustomizationService::custom_entities, this, _1, _2),
|
||||||
AuthenticationPredicates::IS_AUTHENTICATED))
|
AuthenticationPredicates::IS_AUTHENTICATED))
|
||||||
, _device_entities_handler(DEVICE_ENTITIES_PATH,
|
, _device_entities_handler(DEVICE_ENTITIES_PATH,
|
||||||
securityManager->wrapCallback(std::bind(&WebCustomizationService::device_entities, this, _1, _2),
|
securityManager->wrapCallback(std::bind(&WebCustomizationService::device_entities, this, _1, _2),
|
||||||
@@ -85,6 +85,7 @@ void WebCustomization::read(WebCustomization & settings, JsonObject & root) {
|
|||||||
entityJson["product_id"] = entityCustomization.product_id;
|
entityJson["product_id"] = entityCustomization.product_id;
|
||||||
entityJson["device_id"] = entityCustomization.device_id;
|
entityJson["device_id"] = entityCustomization.device_id;
|
||||||
|
|
||||||
|
// entries are in the form <XX><shortname>[|optional customname] e.g "08heatingactive|heating is on"
|
||||||
JsonArray masked_entityJson = entityJson.createNestedArray("entity_ids");
|
JsonArray masked_entityJson = entityJson.createNestedArray("entity_ids");
|
||||||
for (std::string entity_id : entityCustomization.entity_ids) {
|
for (std::string entity_id : entityCustomization.entity_ids) {
|
||||||
masked_entityJson.add(entity_id);
|
masked_entityJson.add(entity_id);
|
||||||
@@ -97,9 +98,8 @@ void WebCustomization::read(WebCustomization & settings, JsonObject & root) {
|
|||||||
StateUpdateResult WebCustomization::update(JsonObject & root, WebCustomization & settings) {
|
StateUpdateResult WebCustomization::update(JsonObject & root, WebCustomization & settings) {
|
||||||
#ifdef EMSESP_STANDALONE
|
#ifdef EMSESP_STANDALONE
|
||||||
// invoke some fake data for testing
|
// invoke some fake data for testing
|
||||||
// using https://arduinojson.org/v5/assistant/
|
const char * json = "{\"sensors\":[],\"analogs\":[],\"masked_entities\":[{\"product_id\":123,\"device_id\":8,\"entity_ids\":[\"08heatingactive|my custom "
|
||||||
const char * json =
|
"name for heating active\",\"08tapwateractive\"]}]}";
|
||||||
"{\"sensors\":[],\"analogs\":[],\"masked_entities\":[{\"product_id\":123,\"device_id\":8,\"entity_ids\":[\"08heatingactive|my custom name for heating active\",\"08tapwateractive\"]}]}";
|
|
||||||
|
|
||||||
StaticJsonDocument<500> doc;
|
StaticJsonDocument<500> doc;
|
||||||
deserializeJson(doc, json);
|
deserializeJson(doc, json);
|
||||||
@@ -222,7 +222,7 @@ void WebCustomizationService::device_entities(AsyncWebServerRequest * request, J
|
|||||||
// takes a list of updated entities with new masks from the web UI
|
// takes a list of updated entities with new masks from the web UI
|
||||||
// saves it in the customization service
|
// saves it in the customization service
|
||||||
// and updates the entity list real-time
|
// and updates the entity list real-time
|
||||||
void WebCustomizationService::masked_entities(AsyncWebServerRequest * request, JsonVariant & json) {
|
void WebCustomizationService::custom_entities(AsyncWebServerRequest * request, JsonVariant & json) {
|
||||||
if (json.is<JsonObject>()) {
|
if (json.is<JsonObject>()) {
|
||||||
// find the device using the unique_id
|
// find the device using the unique_id
|
||||||
for (const auto & emsdevice : EMSESP::emsdevices) {
|
for (const auto & emsdevice : EMSESP::emsdevices) {
|
||||||
@@ -232,10 +232,10 @@ void WebCustomizationService::masked_entities(AsyncWebServerRequest * request, J
|
|||||||
uint8_t product_id = emsdevice->product_id();
|
uint8_t product_id = emsdevice->product_id();
|
||||||
uint8_t device_id = emsdevice->device_id();
|
uint8_t device_id = emsdevice->device_id();
|
||||||
|
|
||||||
// and set the mask immediately for the changed entities
|
// and set the mask and custom names immediately for any listed entities
|
||||||
JsonArray entity_ids_json = json["entity_ids"];
|
JsonArray entity_ids_json = json["entity_ids"];
|
||||||
for (const JsonVariant id : entity_ids_json) {
|
for (const JsonVariant id : entity_ids_json) {
|
||||||
emsdevice->mask_entity(id.as<std::string>());
|
emsdevice->setCustomEntity(id.as<std::string>());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the list to the customization file
|
// Save the list to the customization file
|
||||||
@@ -260,9 +260,9 @@ void WebCustomizationService::masked_entities(AsyncWebServerRequest * request, J
|
|||||||
new_entry.product_id = product_id;
|
new_entry.product_id = product_id;
|
||||||
new_entry.device_id = device_id;
|
new_entry.device_id = device_id;
|
||||||
|
|
||||||
// get list of entities that have masks
|
// get list of entities that have masks set or a custom fullname
|
||||||
std::vector<std::string> entity_ids;
|
std::vector<std::string> entity_ids;
|
||||||
emsdevice->getMaskedEntities(entity_ids);
|
emsdevice->getCustomEntities(entity_ids);
|
||||||
new_entry.entity_ids = entity_ids;
|
new_entry.entity_ids = entity_ids;
|
||||||
|
|
||||||
// add the record and save
|
// add the record and save
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
// POST
|
// POST
|
||||||
#define DEVICE_ENTITIES_PATH "/rest/deviceEntities"
|
#define DEVICE_ENTITIES_PATH "/rest/deviceEntities"
|
||||||
#define MASKED_ENTITIES_PATH "/rest/maskedEntities"
|
#define CUSTOM_ENTITIES_PATH "/rest/customEntities"
|
||||||
#define RESET_CUSTOMIZATION_SERVICE_PATH "/rest/resetCustomizations"
|
#define RESET_CUSTOMIZATION_SERVICE_PATH "/rest/resetCustomizations"
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
@@ -63,7 +63,7 @@ class EntityCustomization {
|
|||||||
public:
|
public:
|
||||||
uint8_t product_id; // device's product id
|
uint8_t product_id; // device's product id
|
||||||
uint8_t device_id; // device's device id
|
uint8_t device_id; // device's device id
|
||||||
std::vector<std::string> entity_ids; // array of entity ids with masks
|
std::vector<std::string> entity_ids; // array of entity ids with masks and optional custom fullname
|
||||||
};
|
};
|
||||||
|
|
||||||
class WebCustomization {
|
class WebCustomization {
|
||||||
@@ -93,7 +93,7 @@ class WebCustomizationService : public StatefulService<WebCustomization> {
|
|||||||
void devices(AsyncWebServerRequest * request);
|
void devices(AsyncWebServerRequest * request);
|
||||||
|
|
||||||
// POST
|
// POST
|
||||||
void masked_entities(AsyncWebServerRequest * request, JsonVariant & json);
|
void custom_entities(AsyncWebServerRequest * request, JsonVariant & json);
|
||||||
void device_entities(AsyncWebServerRequest * request, JsonVariant & json);
|
void device_entities(AsyncWebServerRequest * request, JsonVariant & json);
|
||||||
void reset_customization(AsyncWebServerRequest * request);
|
void reset_customization(AsyncWebServerRequest * request);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user