mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 00:09:51 +03:00
Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev
This commit is contained in:
@@ -161,7 +161,7 @@ const SettingsCustomization: FC = () => {
|
||||
const saveCustomization = async () => {
|
||||
if (deviceEntities && selectedDevice) {
|
||||
const masked_entities = deviceEntities
|
||||
.filter((de) => de.m)
|
||||
// .filter((de) => de.m)
|
||||
.map((new_de) => new_de.m.toString(16).padStart(2, '0') + new_de.s);
|
||||
try {
|
||||
const response = await EMSESP.writeMaskedEntities({
|
||||
|
||||
@@ -131,10 +131,10 @@ export interface DeviceValue {
|
||||
n: string; // name
|
||||
c: string; // command
|
||||
l: string[]; // list
|
||||
h?: string; // help text
|
||||
s?: string; // steps for up/down
|
||||
m?: string; // min
|
||||
x?: string; // max
|
||||
h?: string; // help text, optional
|
||||
s?: string; // steps for up/down, optional
|
||||
m?: string; // min, optional
|
||||
x?: string; // max, optional
|
||||
}
|
||||
|
||||
export interface DeviceData {
|
||||
@@ -147,7 +147,7 @@ export interface DeviceEntity {
|
||||
n: string; // name
|
||||
s: string; // shortname
|
||||
m: number; // mask
|
||||
w?: boolean; // writeable
|
||||
w: boolean; // writeable
|
||||
}
|
||||
|
||||
export interface MaskedEntities {
|
||||
|
||||
@@ -634,14 +634,14 @@ const emsesp_deviceentities_2 = [
|
||||
{ v: 5, n: 'selected flow temperature', s: 'selflowtemp', m: 0 },
|
||||
{ v: 0, n: 'burner selected max power', s: 'selburnpow', m: 0 },
|
||||
{ v: 0, n: 'heating pump modulation', s: 'heatingpumpmod', m: 0 },
|
||||
{ n: 'heating pump 2 modulation', s: 'heatingpump2mod', m: 2 },
|
||||
{ n: 'outside temperature', s: 'outdoortemp', m: 2 },
|
||||
{ n: 'heating pump 2 modulation', s: 'heatingpump2mod', m: 0 },
|
||||
{ n: 'outside temperature', s: 'outdoortemp', m: 0 },
|
||||
{ v: 53, n: 'current flow temperature', s: 'curflowtemp', m: 0 },
|
||||
{ v: 51.8, n: 'return temperature', s: 'rettemp', m: 0 },
|
||||
{ n: 'mixing switch temperature', s: 'switchtemp', m: 2 },
|
||||
{ n: 'mixing switch temperature', s: 'switchtemp', m: 0 },
|
||||
{ v: 1.3, n: 'system pressure', s: 'syspress', m: 0 },
|
||||
{ v: 54.6, n: 'actual boiler temperature', s: 'boiltemp', m: 0 },
|
||||
{ n: 'exhaust temperature', s: 'exhausttemp', m: 2 },
|
||||
{ n: 'exhaust temperature', s: 'exhausttemp', m: 0 },
|
||||
{ v: false, n: 'gas', s: 'burngas', m: 0 },
|
||||
{ v: false, n: 'gas stage 2', s: 'burngas2', m: 0 },
|
||||
{ v: 0, n: 'flame current', s: 'flamecurr', m: 0 },
|
||||
@@ -923,22 +923,23 @@ rest_server.post(EMSESP_DEVICEENTITIES_ENDPOINT, (req, res) => {
|
||||
}
|
||||
})
|
||||
|
||||
function myF(entity, de, dd) {
|
||||
function updateMask(entity, de, dd) {
|
||||
const name = entity.slice(2)
|
||||
const mask = parseInt(entity.slice(0, 2), 16)
|
||||
const mask_hex = entity.slice(0, 2)
|
||||
const new_mask = parseInt(entity.slice(0, 2), 16)
|
||||
|
||||
objIndex = de.findIndex((obj) => obj.s == name)
|
||||
if (objIndex !== -1) {
|
||||
de[objIndex].m = mask
|
||||
de[objIndex].m = new_mask
|
||||
const fullname = de[objIndex].n
|
||||
objIndex = dd.data.findIndex((obj) => obj.n.slice(2) == fullname)
|
||||
if (objIndex !== -1) {
|
||||
// see if the mask has changed
|
||||
const old_mask = parseInt(dd.data[objIndex].n.slice(0, 2), 16)
|
||||
if (old_mask !== new_mask) {
|
||||
const mask_hex = entity.slice(0, 2)
|
||||
console.log('Updating ' + dd.data[objIndex].n + ' -> ' + mask_hex + fullname)
|
||||
dd.data[objIndex].n = mask_hex + fullname
|
||||
console.log('Updating: ')
|
||||
console.log(dd.data[objIndex])
|
||||
} else {
|
||||
console.log("can't locate record for " + fullname)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log("can't locate record for id " + id)
|
||||
@@ -949,11 +950,11 @@ rest_server.post(EMSESP_MASKED_ENTITIES_ENDPOINT, (req, res) => {
|
||||
const id = req.body.id
|
||||
for (const entity of req.body.entity_ids) {
|
||||
if (id === 1) {
|
||||
myF(entity, emsesp_deviceentities_1, emsesp_devicedata_1)
|
||||
updateMask(entity, emsesp_deviceentities_1, emsesp_devicedata_1)
|
||||
} else if (id === 2) {
|
||||
myF(entity, emsesp_deviceentities_2, emsesp_devicedata_2)
|
||||
updateMask(entity, emsesp_deviceentities_2, emsesp_devicedata_2)
|
||||
} else if (id === 4) {
|
||||
myF(entity, emsesp_deviceentities_4, emsesp_devicedata_4)
|
||||
updateMask(entity, emsesp_deviceentities_4, emsesp_devicedata_4)
|
||||
}
|
||||
}
|
||||
res.sendStatus(200)
|
||||
|
||||
@@ -404,9 +404,9 @@ void EMSdevice::register_device_value(uint8_t tag,
|
||||
if ((entityCustomization.product_id == product_id()) && (entityCustomization.device_id == device_id())) {
|
||||
std::string entity = tag < DeviceValueTAG::TAG_HC1 ? read_flash_string(short_name) : tag_to_string(tag) + "/" + read_flash_string(short_name);
|
||||
for (std::string entity_id : entityCustomization.entity_ids) {
|
||||
uint8_t flag = Helpers::hextoint(entity_id.substr(0, 2).c_str());
|
||||
if (entity_id.substr(2) == entity) {
|
||||
state = flag << 4; // set state high bits to flag, turn off active and ha flags
|
||||
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
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -759,7 +759,7 @@ void EMSdevice::generate_values_web(JsonObject & output) {
|
||||
// as generate_values_web() but stripped down to only show all entities and their state
|
||||
// this is used only for WebCustomizationService::device_entities()
|
||||
void EMSdevice::generate_values_web_all(JsonArray & output) {
|
||||
for (auto & dv : devicevalues_) {
|
||||
for (const auto & dv : devicevalues_) {
|
||||
// also show commands and entities that have an empty full name
|
||||
JsonObject obj = output.createNestedObject();
|
||||
|
||||
@@ -847,30 +847,24 @@ void EMSdevice::generate_values_web_all(JsonArray & output) {
|
||||
}
|
||||
}
|
||||
|
||||
// reset all entities to being visible
|
||||
// this is called before loading in the exclude entities list from the customization service
|
||||
void EMSdevice::reset_entity_masks() {
|
||||
for (auto & dv : devicevalues_) {
|
||||
dv.state &= 0x0F; // clear high nibble
|
||||
}
|
||||
}
|
||||
|
||||
// disable/exclude/mask_out a device entity based on the id
|
||||
void EMSdevice::mask_entity(const std::string & entity_id) {
|
||||
// first character contains mask flags
|
||||
uint8_t flag = (Helpers::hextoint(entity_id.substr(0, 2).c_str()) << 4);
|
||||
// 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
|
||||
bool EMSdevice::mask_entity(const std::string & entity_id) {
|
||||
for (auto & dv : devicevalues_) {
|
||||
std::string entity = dv.tag < DeviceValueTAG::TAG_HC1 ? read_flash_string(dv.short_name) : tag_to_string(dv.tag) + "/" + read_flash_string(dv.short_name);
|
||||
if (entity == entity_id.substr(2)) {
|
||||
uint8_t mask = Helpers::hextoint(entity_id.substr(0, 2).c_str()); // first character contains mask flags
|
||||
if (Mqtt::ha_enabled() && (((dv.state >> 4) ^ mask) & (DeviceValueState::DV_READONLY >> 4))) {
|
||||
// remove ha config on change of dv_readonly flag
|
||||
if (Mqtt::ha_enabled() && ((dv.state ^ flag) & DeviceValueState::DV_READONLY)) {
|
||||
dv.remove_state(DeviceValueState::DV_HA_CONFIG_CREATED);
|
||||
Mqtt::publish_ha_sensor_config(dv, "", "", true); // delete topic (remove = true)
|
||||
}
|
||||
dv.state = (dv.state & 0x0F) | flag; // set state high bits to flag
|
||||
return;
|
||||
dv.state = ((dv.state & 0x0F) | (mask << 4)); // set state high bits to flag
|
||||
return mask; // true if entity mask is not the deafult 0
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// builds json for a specific device value / entity
|
||||
|
||||
@@ -183,8 +183,7 @@ class EMSdevice {
|
||||
char * show_telegram_handlers(char * result, const size_t len, const uint8_t handlers);
|
||||
void show_mqtt_handlers(uuid::console::Shell & shell) const;
|
||||
void list_device_entries(JsonObject & output) const;
|
||||
void mask_entity(const std::string & entity_id);
|
||||
void reset_entity_masks();
|
||||
bool mask_entity(const std::string & entity_id);
|
||||
|
||||
using process_function_p = std::function<void(std::shared_ptr<const Telegram>)>;
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ size_t DeviceValue::tag_count = sizeof(DeviceValue::DeviceValueTAG_s) / sizeof(_
|
||||
// checks whether the device value has an actual value
|
||||
// returns true if its valid
|
||||
// state is stored in the dv object
|
||||
bool DeviceValue::hasValue() {
|
||||
bool DeviceValue::hasValue() const {
|
||||
bool has_value = false;
|
||||
switch (type) {
|
||||
case DeviceValueType::BOOL:
|
||||
|
||||
@@ -168,20 +168,20 @@ class DeviceValue {
|
||||
, state(state) {
|
||||
}
|
||||
|
||||
bool hasValue();
|
||||
bool hasValue() const;
|
||||
bool get_min_max(int16_t & dv_set_min, int16_t & dv_set_max);
|
||||
|
||||
// state flags
|
||||
inline void add_state(uint8_t s) {
|
||||
void add_state(uint8_t s) {
|
||||
state |= s;
|
||||
}
|
||||
inline bool has_state(uint8_t s) const {
|
||||
bool has_state(uint8_t s) const {
|
||||
return (state & s) == s;
|
||||
}
|
||||
inline void remove_state(uint8_t s) {
|
||||
void remove_state(uint8_t s) {
|
||||
state &= ~s;
|
||||
}
|
||||
inline uint8_t get_state() const {
|
||||
uint8_t get_state() const {
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
@@ -919,6 +919,10 @@ void Mqtt::publish_ha_sensor_config(DeviceValue & dv, const std::string & model,
|
||||
int16_t dv_set_min, dv_set_max;
|
||||
(void)dv.get_min_max(dv_set_min, dv_set_max);
|
||||
|
||||
// determine if we're creating the command topics which we use special HA configs
|
||||
// unless the entity has been marked as read-only and so it'll default to using the sensor/ type
|
||||
bool has_cmd = dv.has_cmd && !dv.has_state(DeviceValueState::DV_READONLY);
|
||||
|
||||
publish_ha_sensor_config(dv.type,
|
||||
dv.tag,
|
||||
dv.full_name,
|
||||
@@ -926,7 +930,7 @@ void Mqtt::publish_ha_sensor_config(DeviceValue & dv, const std::string & model,
|
||||
dv.short_name,
|
||||
dv.uom,
|
||||
remove,
|
||||
dv.has_cmd && !dv.has_state(DeviceValueState::DV_READONLY),
|
||||
has_cmd,
|
||||
dv.options,
|
||||
dv.options_size,
|
||||
dv_set_min,
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define EMSESP_APP_VERSION "3.4.0b10"
|
||||
#define EMSESP_APP_VERSION "3.4.0b11"
|
||||
|
||||
@@ -172,11 +172,10 @@ void WebCustomizationService::devices(AsyncWebServerRequest * request) {
|
||||
obj["i"] = emsdevice->unique_id(); // a unique id
|
||||
|
||||
/*
|
||||
// shortname - we prefix the count to make it unique
|
||||
uint8_t device_index = EMSESP::device_index(emsdevice->device_type(), emsdevice->unique_id());
|
||||
if (device_index) {
|
||||
char s[10];
|
||||
obj["s"] = emsdevice->device_type_name() + Helpers::smallitoa(s, device_index) + " (" + emsdevice->name() + ")";
|
||||
obj["s"] = emsdevice->device_type_name() + Helpers::smallitoa(s, device_index) + " (" + emsdevice->name() + ")"; // shortname - we prefix the count to make it unique
|
||||
} else {
|
||||
obj["s"] = emsdevice->device_type_name() + " (" + emsdevice->name() + ")";
|
||||
}
|
||||
@@ -221,17 +220,17 @@ void WebCustomizationService::masked_entities(AsyncWebServerRequest * request, J
|
||||
if (emsdevice) {
|
||||
uint8_t unique_device_id = json["id"];
|
||||
if (emsdevice->unique_id() == unique_device_id) {
|
||||
// first reset all the entity ids
|
||||
emsdevice->reset_entity_masks();
|
||||
|
||||
// build a list of entities
|
||||
JsonArray entity_ids_json = json["entity_ids"];
|
||||
std::vector<std::string> entity_ids;
|
||||
for (JsonVariant id : entity_ids_json) {
|
||||
for (const JsonVariant id : entity_ids_json) {
|
||||
std::string entity_id = id.as<std::string>();
|
||||
emsdevice->mask_entity(entity_id); // this will have immediate affect
|
||||
// handle the mask change and add to the list of customized entities
|
||||
// if the value is different from the default (mask == 0)
|
||||
if (emsdevice->mask_entity(entity_id)) {
|
||||
entity_ids.push_back(entity_id);
|
||||
}
|
||||
}
|
||||
|
||||
// Save the list to the customization file
|
||||
uint8_t product_id = emsdevice->product_id();
|
||||
|
||||
Reference in New Issue
Block a user