mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 07:49:52 +03:00
@@ -4,6 +4,8 @@
|
||||
|
||||
## **IMPORTANT! BREAKING CHANGES**
|
||||
|
||||
Writeable Text entities have moved from type `sensor` to `text` in Home Assistant to make them also editable within an HA dashboard. Examples are `datetime`, `holidays`, `switchtime`, `vacations`, `maintenancedate`...). You will need to manually remove any old discovery topics from your MQTT broker using an application like MQTT Explorer.
|
||||
|
||||
## Added
|
||||
|
||||
- humidity for ventilation devices
|
||||
@@ -11,7 +13,8 @@
|
||||
- names for BC400, GB192i.2, read temperatures for low loss header and heatblock [#1317](https://github.com/emsesp/EMS-ESP32/discussions/1317)
|
||||
- option for `forceheatingoff` [#1262](https://github.com/emsesp/EMS-ESP32/issues/1262)
|
||||
- remote thermostat emulation RC100H for RC3xx [#1278](https://github.com/emsesp/EMS-ESP32/discussions/1278)
|
||||
- publish time for shower
|
||||
- shower_data MQTT payload contains the timestamp [#1329](https://github.com/emsesp/EMS-ESP32/issues/1329)
|
||||
- HA discovery for writeable text entities [#1337](https://github.com/emsesp/EMS-ESP32/pull/1377)
|
||||
- autodetect board_profile, store in nvs, add telnet command option, add E32V2
|
||||
- heatpump high res energy counters [#1348, #1349. #1350](https://github.com/emsesp/EMS-ESP32/issues/1348)
|
||||
- optional bssid in network settings
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
"@types/imagemin": "^8.0.3",
|
||||
"@types/lodash-es": "^4.17.10",
|
||||
"@types/node": "^20.8.10",
|
||||
"@types/react": "^18.2.34",
|
||||
"@types/react": "^18.2.35",
|
||||
"@types/react-dom": "^18.2.14",
|
||||
"@types/react-router-dom": "^5.3.3",
|
||||
"alova": "^2.13.1",
|
||||
@@ -54,7 +54,7 @@
|
||||
"@typescript-eslint/eslint-plugin": "^6.9.1",
|
||||
"@typescript-eslint/parser": "^6.9.1",
|
||||
"concurrently": "^8.2.2",
|
||||
"eslint": "^8.52.0",
|
||||
"eslint": "^8.53.0",
|
||||
"eslint-config-airbnb": "^19.0.4",
|
||||
"eslint-config-airbnb-typescript": "^17.1.0",
|
||||
"eslint-config-prettier": "^9.0.0",
|
||||
@@ -65,7 +65,7 @@
|
||||
"eslint-plugin-prettier": "alpha",
|
||||
"eslint-plugin-react": "^7.33.2",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"preact": "^10.18.1",
|
||||
"preact": "^10.18.2",
|
||||
"prettier": "^3.0.3",
|
||||
"rollup-plugin-visualizer": "^5.9.2",
|
||||
"terser": "^5.24.0",
|
||||
|
||||
@@ -641,9 +641,9 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@eslint/eslintrc@npm:^2.1.2":
|
||||
version: 2.1.2
|
||||
resolution: "@eslint/eslintrc@npm:2.1.2"
|
||||
"@eslint/eslintrc@npm:^2.1.3":
|
||||
version: 2.1.3
|
||||
resolution: "@eslint/eslintrc@npm:2.1.3"
|
||||
dependencies:
|
||||
ajv: "npm:^6.12.4"
|
||||
debug: "npm:^4.3.2"
|
||||
@@ -654,14 +654,14 @@ __metadata:
|
||||
js-yaml: "npm:^4.1.0"
|
||||
minimatch: "npm:^3.1.2"
|
||||
strip-json-comments: "npm:^3.1.1"
|
||||
checksum: fa25638f2666cac6810f98ee7d0f4b912f191806467c1b40d72bac759fffef0b3357f12a1869817286837b258e4de3517e0c7408520e156ca860fc53a1fbaed9
|
||||
checksum: 77b70a89232fe702c2f765b5b92970f5e4224b55363b923238b996c66fcd991504f40d3663c0543ae17d6c5049ab9b07ab90b65d7601e6f25e8bcd4caf69ac75
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@eslint/js@npm:8.52.0":
|
||||
version: 8.52.0
|
||||
resolution: "@eslint/js@npm:8.52.0"
|
||||
checksum: 86beff213d0ae4ced203a922b74e2cc4d767d109e7815f985bf648946ba072198977102e32afc9fa04f7825a6de83a831874f6b6675ba0c1d0743ade2dc2d53d
|
||||
"@eslint/js@npm:8.53.0":
|
||||
version: 8.53.0
|
||||
resolution: "@eslint/js@npm:8.53.0"
|
||||
checksum: a372d55aa2bbe0d9399acc8de3c892dcfe507fd914d29fde6826ae54a13452619be626aa7eb70b1ec4d4da5302b6ed8e8ac9bf1f830003f15c0ad56c30b4f520
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -1370,14 +1370,14 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/react@npm:^18.2.34":
|
||||
version: 18.2.34
|
||||
resolution: "@types/react@npm:18.2.34"
|
||||
"@types/react@npm:^18.2.35":
|
||||
version: 18.2.35
|
||||
resolution: "@types/react@npm:18.2.35"
|
||||
dependencies:
|
||||
"@types/prop-types": "npm:*"
|
||||
"@types/scheduler": "npm:*"
|
||||
csstype: "npm:^3.0.2"
|
||||
checksum: 6d16f86b384e829edc3710b1dd9ec4eb1d6b26bc079c5cf605bd0cbf77ae6224f15c76949afadb7f53df4544cfe4025c1111fbe36732cd7f660a320fbc2e5866
|
||||
checksum: 3c8c752d21856f74ddb96b9dd13cdd70c0ce1522808f20511f0220f392ea727fae9388db4da3ebe317d9bac98a0d930566d4277b22e92c1cad414429739e1d76
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -1558,7 +1558,7 @@ __metadata:
|
||||
"@types/imagemin": "npm:^8.0.3"
|
||||
"@types/lodash-es": "npm:^4.17.10"
|
||||
"@types/node": "npm:^20.8.10"
|
||||
"@types/react": "npm:^18.2.34"
|
||||
"@types/react": "npm:^18.2.35"
|
||||
"@types/react-dom": "npm:^18.2.14"
|
||||
"@types/react-router-dom": "npm:^5.3.3"
|
||||
"@typescript-eslint/eslint-plugin": "npm:^6.9.1"
|
||||
@@ -1566,7 +1566,7 @@ __metadata:
|
||||
alova: "npm:^2.13.1"
|
||||
async-validator: "npm:^4.2.5"
|
||||
concurrently: "npm:^8.2.2"
|
||||
eslint: "npm:^8.52.0"
|
||||
eslint: "npm:^8.53.0"
|
||||
eslint-config-airbnb: "npm:^19.0.4"
|
||||
eslint-config-airbnb-typescript: "npm:^17.1.0"
|
||||
eslint-config-prettier: "npm:^9.0.0"
|
||||
@@ -1581,7 +1581,7 @@ __metadata:
|
||||
jwt-decode: "npm:^4.0.0"
|
||||
lodash-es: "npm:^4.17.21"
|
||||
mime-types: "npm:^2.1.35"
|
||||
preact: "npm:^10.18.1"
|
||||
preact: "npm:^10.18.2"
|
||||
prettier: "npm:^3.0.3"
|
||||
react: "npm:latest"
|
||||
react-dom: "npm:latest"
|
||||
@@ -3654,14 +3654,14 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"eslint@npm:^8.52.0":
|
||||
version: 8.52.0
|
||||
resolution: "eslint@npm:8.52.0"
|
||||
"eslint@npm:^8.53.0":
|
||||
version: 8.53.0
|
||||
resolution: "eslint@npm:8.53.0"
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils": "npm:^4.2.0"
|
||||
"@eslint-community/regexpp": "npm:^4.6.1"
|
||||
"@eslint/eslintrc": "npm:^2.1.2"
|
||||
"@eslint/js": "npm:8.52.0"
|
||||
"@eslint/eslintrc": "npm:^2.1.3"
|
||||
"@eslint/js": "npm:8.53.0"
|
||||
"@humanwhocodes/config-array": "npm:^0.11.13"
|
||||
"@humanwhocodes/module-importer": "npm:^1.0.1"
|
||||
"@nodelib/fs.walk": "npm:^1.2.8"
|
||||
@@ -3698,7 +3698,7 @@ __metadata:
|
||||
text-table: "npm:^0.2.0"
|
||||
bin:
|
||||
eslint: bin/eslint.js
|
||||
checksum: 01784ab15351d749bc95446039ed7acd5124f7cc84acdbf98c7199272eae06212a8f3ea4a9b47e7cc54ab17ca094c3a664bbfc3002c7de27936220e278b5028a
|
||||
checksum: e305a71ce2b9a8631b293266fe53e346c76f28bc8d004af33f10e537cf133db1fb87af3599376e70ed6e0f89a78be10c4f08ddd0c1c9c0c497cd143b4a270420
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -6661,10 +6661,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"preact@npm:^10.18.1":
|
||||
version: 10.18.1
|
||||
resolution: "preact@npm:10.18.1"
|
||||
checksum: 587c4634b310efc306ef9315f849b8e4ff538435087a1dca626e1394b98570af1ecdc254b7f0bb3060fc7ab87456c5f891f9b8a167d5c34dbbcfcf60b6e993f4
|
||||
"preact@npm:^10.18.2":
|
||||
version: 10.18.2
|
||||
resolution: "preact@npm:10.18.2"
|
||||
checksum: c7dcd6ea812adb0bdc215366b14aadc44724b6dd6c4e9aadd986126d94abde62f3e02e18d6157a9984873be9877f206c0afa10a09346178c4c828a103a66a0e1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ REGISTER_FACTORY(Alert, EMSdevice::DeviceType::ALERT);
|
||||
|
||||
Alert::Alert(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand)
|
||||
: EMSdevice(device_type, device_id, product_id, version, name, flags, brand) {
|
||||
|
||||
// EM10, device-id 0x12, listens to error messages, measures voltage input and send 0x1A to the boiler.
|
||||
// values already shown in boiler
|
||||
// see https://github.com/emsesp/EMS-ESP32/issues/575
|
||||
@@ -32,7 +31,6 @@ Alert::Alert(uint8_t device_type, uint8_t device_id, uint8_t product_id, const c
|
||||
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &setFlowTemp_, DeviceValueType::UINT, FL_(setFlowTemp), DeviceValueUOM::DEGREES);
|
||||
register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &setBurnPow_, DeviceValueType::UINT, FL_(setBurnPow), DeviceValueUOM::PERCENT);
|
||||
|
||||
}
|
||||
// UBASetPoint 0x1A
|
||||
void Alert::process_UBASetPoints(std::shared_ptr<const Telegram> telegram) {
|
||||
|
||||
66
src/mqtt.cpp
66
src/mqtt.cpp
@@ -753,7 +753,8 @@ bool Mqtt::publish_ha_sensor_config(DeviceValue & dv, const char * model, const
|
||||
|
||||
// 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);
|
||||
// or we're dealing with Energy sensors that must have "diagnostic" as an entity category (e.g. negheat & nrgww)
|
||||
bool has_cmd = dv.has_cmd && !dv.has_state(DeviceValueState::DV_READONLY) && (dv.uom != DeviceValueUOM::KWH);
|
||||
|
||||
return publish_ha_sensor_config(dv.type,
|
||||
dv.tag,
|
||||
@@ -846,7 +847,7 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
||||
char config_topic[70];
|
||||
snprintf(config_topic, sizeof(config_topic), "%s/%s_%s/config", mqtt_basename_.c_str(), device_name, entity_with_tag);
|
||||
|
||||
bool set_ha_classes = false; // set to true if we want to set the state class and device class
|
||||
bool readonly_sensors = true;
|
||||
|
||||
// create the topic
|
||||
// depending on the type and whether the device entity is writable (a command)
|
||||
@@ -859,42 +860,41 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
||||
case DeviceValueType::UINT:
|
||||
case DeviceValueType::SHORT:
|
||||
case DeviceValueType::USHORT:
|
||||
if (discovery_type() == discoveryType::HOMEASSISTANT) {
|
||||
case DeviceValueType::ULONG:
|
||||
// number - https://www.home-assistant.io/integrations/number.mqtt
|
||||
snprintf(topic, sizeof(topic), "number/%s", config_topic);
|
||||
} else {
|
||||
// Domoticz does not support number, use sensor
|
||||
if (discovery_type() == discoveryType::HOMEASSISTANT) {
|
||||
snprintf(topic, sizeof(topic), "number/%s", config_topic);
|
||||
readonly_sensors = false;
|
||||
} else {
|
||||
snprintf(topic, sizeof(topic), "sensor/%s", config_topic);
|
||||
}
|
||||
break;
|
||||
case DeviceValueType::BOOL:
|
||||
// switch - https://www.home-assistant.io/integrations/switch.mqtt
|
||||
snprintf(topic, sizeof(topic), "switch/%s", config_topic);
|
||||
readonly_sensors = false;
|
||||
break;
|
||||
case DeviceValueType::ENUM:
|
||||
// select - https://www.home-assistant.io/integrations/select.mqtt
|
||||
snprintf(topic, sizeof(topic), "select/%s", config_topic);
|
||||
break;
|
||||
case DeviceValueType::ULONG:
|
||||
snprintf(topic, sizeof(topic), "sensor/%s", config_topic);
|
||||
set_ha_classes = true;
|
||||
readonly_sensors = false;
|
||||
break;
|
||||
case DeviceValueType::STRING:
|
||||
// text - https://www.home-assistant.io/integrations/text.mqtt
|
||||
snprintf(topic, sizeof(topic), "text/%s", config_topic); // e.g. set_datetime, set_holiday, set_wwswitchtime
|
||||
readonly_sensors = false;
|
||||
break;
|
||||
default:
|
||||
// plain old sensor
|
||||
snprintf(topic, sizeof(topic), "sensor/%s", config_topic);
|
||||
// plain old sensor, and make read-only
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
set_ha_classes = true; // these are Read only sensors. We can set the device class and state class
|
||||
// plain old read only device entity
|
||||
if (type == DeviceValueType::BOOL) {
|
||||
snprintf(topic, sizeof(topic), "binary_sensor/%s", config_topic); // binary sensor (for booleans)
|
||||
} else {
|
||||
snprintf(topic, sizeof(topic), "sensor/%s", config_topic); // normal HA sensor
|
||||
}
|
||||
|
||||
// For read-only sensors there are either sensor or binary_sensor
|
||||
// for both we also set the device class and state class
|
||||
if (readonly_sensors) {
|
||||
snprintf(topic, sizeof(topic), (type == DeviceValueType::BOOL) ? "binary_sensor/%s" : "sensor/%s", config_topic); // binary sensor (for booleans)
|
||||
}
|
||||
|
||||
// if we're asking to remove this topic, send an empty payload and exit
|
||||
@@ -910,13 +910,15 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
||||
doc["obj_id"] = uniq_id; // same as unique_id
|
||||
|
||||
const char * ic_ha = "ic"; // icon - only set this if there is no device class
|
||||
const char * sc_ha = "stat_cla"; // state class
|
||||
const char * uom_ha = "unit_of_meas"; // unit of measure
|
||||
|
||||
char sample_val[30] = "0"; // sample, correct(!) entity value, used only to prevent warning/error in HA if real value is not published yet
|
||||
|
||||
// we add the command topic parameter for commands
|
||||
if (has_cmd) {
|
||||
// add category
|
||||
doc["ent_cat"] = "config"; // for writeable entities, like switch, number, text, select
|
||||
|
||||
char command_topic[MQTT_TOPIC_MAX_SIZE];
|
||||
// add command topic
|
||||
if (tag >= DeviceValueTAG::TAG_HC1) {
|
||||
@@ -1038,12 +1040,16 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
||||
doc[uom_ha] = EMSdevice::uom_to_string(uom); // default
|
||||
}
|
||||
}
|
||||
|
||||
doc["val_tpl"] = (std::string) "{{" + val_obj + " if " + val_cond + " else " + sample_val + "}}";
|
||||
|
||||
// this next section is adding the state class, device class and sometimes the icon
|
||||
// used for Sensor and Binary Sensor Entities in HA
|
||||
if (set_ha_classes) {
|
||||
// Add the state class, device class and sometimes the icon. Used only for read-only sensors Sensor and Binary Sensor
|
||||
if (readonly_sensors) {
|
||||
// first set the catagory
|
||||
doc["ent_cat"] = "diagnostic";
|
||||
|
||||
const char * dc_ha = "dev_cla"; // device class
|
||||
const char * sc_ha = "stat_cla"; // state class
|
||||
|
||||
switch (uom) {
|
||||
case DeviceValueUOM::DEGREES:
|
||||
@@ -1079,11 +1085,11 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
||||
} else {
|
||||
doc[sc_ha] = F_(measurement);
|
||||
}
|
||||
doc[dc_ha] = "energy"; // no icon needed
|
||||
doc[dc_ha] = "energy";
|
||||
break;
|
||||
case DeviceValueUOM::KWH:
|
||||
doc[sc_ha] = F_(total_increasing);
|
||||
doc[dc_ha] = "energy"; // no icon needed
|
||||
doc[dc_ha] = "energy";
|
||||
break;
|
||||
case DeviceValueUOM::UA:
|
||||
doc[ic_ha] = F_(iconua);
|
||||
@@ -1127,15 +1133,8 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
||||
}
|
||||
}
|
||||
|
||||
// add category "diagnostic" for system entities
|
||||
// config for writeable entities, like switches. diagnostic for read only sensors.
|
||||
doc["ent_cat"] = (has_cmd && !set_ha_classes) ? "config" : "diagnostic";
|
||||
|
||||
// add the dev json object to the end
|
||||
doc["dev"] = dev_json;
|
||||
|
||||
// add "availability" section
|
||||
add_avty_to_doc(stat_t, doc.as<JsonObject>(), val_cond);
|
||||
doc["dev"] = dev_json; // add the dev json object to the end
|
||||
add_avty_to_doc(stat_t, doc.as<JsonObject>(), val_cond); // add "availability" section
|
||||
|
||||
return queue_ha(topic, doc.as<JsonObject>());
|
||||
}
|
||||
@@ -1309,5 +1308,4 @@ void Mqtt::add_avty_to_doc(const char * state_t, const JsonObject & doc, const c
|
||||
doc["avty_mode"] = "all";
|
||||
}
|
||||
|
||||
|
||||
} // namespace emsesp
|
||||
@@ -1 +1 @@
|
||||
#define EMSESP_APP_VERSION "3.6.3-dev.5b"
|
||||
#define EMSESP_APP_VERSION "3.6.3-test.6"
|
||||
|
||||
@@ -36,7 +36,9 @@ void WebStatusService::WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) {
|
||||
|
||||
switch (event) {
|
||||
case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
|
||||
EMSESP::logger().warning("WiFi disconnected. Reason: %s (%d)", disconnectReason(info.wifi_sta_disconnected.reason), info.wifi_sta_disconnected.reason); // IDF 4.0
|
||||
EMSESP::logger().warning("WiFi disconnected. Reason: %s (%d)",
|
||||
disconnectReason(info.wifi_sta_disconnected.reason),
|
||||
info.wifi_sta_disconnected.reason); // IDF 4.0
|
||||
EMSESP::system_.has_ipv6(false);
|
||||
break;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user