Skip to content

Commit

Permalink
Merge pull request emsesp#1391 from proddy/dev2
Browse files Browse the repository at this point in the history
sync with latest dev
  • Loading branch information
proddy authored Nov 5, 2023
2 parents 2afe50f + af1292c commit 06f5e12
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 73 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG_LATEST.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@

## **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
- telegrams for RC100H, hc2, etc. (seen on discord, not tested)
- 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
Expand Down
6 changes: 3 additions & 3 deletions interface/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand All @@ -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",
Expand Down
50 changes: 25 additions & 25 deletions interface/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -1558,15 +1558,15 @@ __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"
"@typescript-eslint/parser": "npm:^6.9.1"
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"
Expand All @@ -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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -3698,7 +3698,7 @@ __metadata:
text-table: "npm:^0.2.0"
bin:
eslint: bin/eslint.js
checksum: 01784ab15351d749bc95446039ed7acd5124f7cc84acdbf98c7199272eae06212a8f3ea4a9b47e7cc54ab17ca094c3a664bbfc3002c7de27936220e278b5028a
checksum: e305a71ce2b9a8631b293266fe53e346c76f28bc8d004af33f10e537cf133db1fb87af3599376e70ed6e0f89a78be10c4f08ddd0c1c9c0c497cd143b4a270420
languageName: node
linkType: hard

Expand Down Expand Up @@ -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

Expand Down
6 changes: 2 additions & 4 deletions src/devices/alert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,17 @@ 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
register_telegram_type(0x1A, "UBASetPoints", false, MAKE_PF_CB(process_UBASetPoints));

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) {
has_update(telegram, setFlowTemp_, 0); // boiler set temp from thermostat
has_update(telegram, setBurnPow_, 1); // max burner power in %
has_update(telegram, setFlowTemp_, 0); // boiler set temp from thermostat
has_update(telegram, setBurnPow_, 1); // max burner power in %
}
} // namespace emsesp
2 changes: 1 addition & 1 deletion src/devices/boiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1269,7 +1269,7 @@ void Boiler::process_UBAMonitorFastPlus(std::shared_ptr<const Telegram> telegram
has_update(telegram, heatblock_, 23); // see #1317
has_update(telegram, headertemp_, 25); // see #1317
//has_update(telegram, temperatur_, 27); // unknown temperature
telegram->read_value(exhaustTemp1_ , 31);
telegram->read_value(exhaustTemp1_, 31);
if (Helpers::hasValue(exhaustTemp1_)) {
has_update(exhaustTemp_, exhaustTemp1_);
}
Expand Down
70 changes: 34 additions & 36 deletions src/mqtt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand All @@ -859,42 +860,41 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
case DeviceValueType::UINT:
case DeviceValueType::SHORT:
case DeviceValueType::USHORT:
case DeviceValueType::ULONG:
// number - https://www.home-assistant.io/integrations/number.mqtt
// Domoticz does not support number, use sensor
if (discovery_type() == discoveryType::HOMEASSISTANT) {
// number - https://www.home-assistant.io/integrations/number.mqtt
snprintf(topic, sizeof(topic), "number/%s", config_topic);
readonly_sensors = false;
} else {
// Domoticz does not support number, use sensor
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
Expand All @@ -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) {
Expand Down Expand Up @@ -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) {
const char * dc_ha = "dev_cla"; // device class
// 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:
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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>());
}
Expand Down Expand Up @@ -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
} // namespace emsesp
2 changes: 1 addition & 1 deletion src/roomcontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ void Roomctrl::send(const uint8_t addr) {
} else if (type_ == FB10) {
rc_time_[hc] = uuid::get_uptime();
temperature(addr, 0x10, hc); // send to master-thermostat (https://github.com/emsesp/EMS-ESP32/issues/336)
} else { // type==RC20
} else { // type==RC20
rc_time_[hc] = uuid::get_uptime();
temperature(addr, 0x00, hc); // send to all
}
Expand Down
2 changes: 1 addition & 1 deletion src/version.h
Original file line number Diff line number Diff line change
@@ -1 +1 @@
#define EMSESP_APP_VERSION "3.6.3-dev.5b"
#define EMSESP_APP_VERSION "3.6.3-test.6"
4 changes: 3 additions & 1 deletion src/web/WebStatusService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down

0 comments on commit 06f5e12

Please sign in to comment.