diff --git a/components/maidsite_desk/button/__init__.py b/components/maidsite_desk/button/__init__.py index 09ed274..677707d 100644 --- a/components/maidsite_desk/button/__init__.py +++ b/components/maidsite_desk/button/__init__.py @@ -37,7 +37,7 @@ TYPES = [ CONF_SAVE_M4, ] -MaidsiteDeskButton = maidsite_desk_ns.class_("MaidsiteDeskButton", button.Button) +MaidsiteDeskButton = maidsite_desk_ns.class_("MaidsiteDeskButton", button.Button, cg.Component) CONFIG_SCHEMA = cv.Schema( { @@ -87,15 +87,14 @@ CONFIG_SCHEMA = cv.Schema( entity_category=ENTITY_CATEGORY_CONFIG, ), } -) +).extend(cv.COMPONENT_SCHEMA) async def to_code(config): hub = await cg.get_variable(config[CONF_MAIDSITE_DESK_ID]) - for key in TYPES: - await setup_conf(config, key, hub) - -async def setup_conf(parent_config, key, hub): - if child_config := parent_config.get(key): - var = await button.new_button(child_config) - await cg.register_parented(var, parent_config[CONF_MAIDSITE_DESK_ID]) - cg.add(getattr(hub, f"set_{key}_button")(var)) + for index, key in enumerate(TYPES): + if child_config := config.get(key): + var = await button.new_button(child_config) + await cg.register_component(var, child_config) + await cg.register_parented(var, config[CONF_MAIDSITE_DESK_ID]) + cg.add(getattr(hub, f"set_{key}_button")(var)) + cg.add(var.set_id(index)) diff --git a/components/maidsite_desk/button/maidsite_desk_button.cpp b/components/maidsite_desk/button/maidsite_desk_button.cpp index 2e51341..869ff62 100644 --- a/components/maidsite_desk/button/maidsite_desk_button.cpp +++ b/components/maidsite_desk/button/maidsite_desk_button.cpp @@ -1,10 +1,19 @@ #include "maidsite_desk_button.h" +#include "esphome/core/log.h" namespace esphome { namespace maidsite_desk { + static const char *const TAG = "maidsite_desk.button"; + + void MaidsiteDeskButton::dump_config() + { + LOG_BUTTON("", "Maidsite Desk Button", this); + delay(10); + } + void MaidsiteDeskButton::press_action() { this->parent_->button_press_action(this); diff --git a/components/maidsite_desk/button/maidsite_desk_button.h b/components/maidsite_desk/button/maidsite_desk_button.h index db96b6c..2c811be 100644 --- a/components/maidsite_desk/button/maidsite_desk_button.h +++ b/components/maidsite_desk/button/maidsite_desk_button.h @@ -1,5 +1,6 @@ #pragma once #include "esphome/components/button/button.h" +#include "esphome/core/component.h" #include "../maidsite_desk.h" @@ -7,13 +8,16 @@ namespace esphome { namespace maidsite_desk { - class MaidsiteDeskButton : public button::Button, public Parented + class MaidsiteDeskButton : public button::Button, public Component, public Parented { public: MaidsiteDeskButton() = default; + void dump_config() override; + void set_id(int id) { this->id_ = id; } protected: void press_action() override; + int id_; }; } // namespace maidsite_desk } // namespace esphome diff --git a/components/maidsite_desk/maidsite_desk.cpp b/components/maidsite_desk/maidsite_desk.cpp index 7b29dce..275f840 100644 --- a/components/maidsite_desk/maidsite_desk.cpp +++ b/components/maidsite_desk/maidsite_desk.cpp @@ -10,39 +10,7 @@ namespace esphome void MaidsiteDeskComponent::dump_config() { ESP_LOGCONFIG(TAG, "Maidsite Desk"); - -#ifdef USE_SENSOR - LOG_SENSOR("", "Maidsite Desk Sensor", this->unit_sensor_); - LOG_SENSOR("", "Maidsite Desk Sensor", this->height_abs_sensor_); - LOG_SENSOR("", "Maidsite Desk Sensor", this->height_pct_sensor_); - LOG_SENSOR("", "Maidsite Desk Sensor", this->height_min_sensor_); - LOG_SENSOR("", "Maidsite Desk Sensor", this->height_max_sensor_); - LOG_SENSOR("", "Maidsite Desk Sensor", this->position_m1_sensor_); - LOG_SENSOR("", "Maidsite Desk Sensor", this->position_m2_sensor_); - LOG_SENSOR("", "Maidsite Desk Sensor", this->position_m3_sensor_); - LOG_SENSOR("", "Maidsite Desk Sensor", this->position_m4_sensor_); -#endif -#ifdef USE_BUTTON - LOG_BUTTON("", "Maidsite Desk Button", this->unit_button_); - LOG_BUTTON("", "Maidsite Desk Button", this->step_up_button_); - LOG_BUTTON("", "Maidsite Desk Button", this->step_down_button_); - LOG_BUTTON("", "Maidsite Desk Button", this->stop_button_); - LOG_BUTTON("", "Maidsite Desk Button", this->goto_max_button_); - LOG_BUTTON("", "Maidsite Desk Button", this->goto_min_button_); - LOG_BUTTON("", "Maidsite Desk Button", this->goto_m1_button_); - LOG_BUTTON("", "Maidsite Desk Button", this->goto_m2_button_); - LOG_BUTTON("", "Maidsite Desk Button", this->goto_m3_button_); - LOG_BUTTON("", "Maidsite Desk Button", this->goto_m4_button_); - LOG_BUTTON("", "Maidsite Desk Button", this->save_m1_button_); - LOG_BUTTON("", "Maidsite Desk Button", this->save_m2_button_); - LOG_BUTTON("", "Maidsite Desk Button", this->save_m3_button_); - LOG_BUTTON("", "Maidsite Desk Button", this->save_m4_button_); - LOG_BUTTON("", "Maidsite Desk Button", this->save_m4_button_); -#endif -#ifdef USE_NUMBER - LOG_NUMBER("", "Maidsite Desk Number", this->height_abs_number_); - LOG_NUMBER("", "Maidsite Desk Number", this->height_pct_number_); -#endif + delay(10); } void MaidsiteDeskComponent::setup() @@ -115,7 +83,6 @@ namespace esphome std::string logStr; char buffer[5]; - size_t chunkSize = 90; for (size_t i = 0; i < bytes.size(); i++) { @@ -123,9 +90,9 @@ namespace esphome sprintf(buffer, "%02X", bytes[i]); logStr += buffer; } - for (size_t i = 0; i < logStr.length(); i += chunkSize) + for (size_t i = 0; i < logStr.length(); i += UART_LOG_CHUNK_SIZE) { - ESP_LOGI(TAG, "%s %s", prefix.c_str(), logStr.substr(i, chunkSize).c_str()); + ESP_LOGI(TAG, "%s %s", prefix.c_str(), logStr.substr(i, UART_LOG_CHUNK_SIZE).c_str()); delay(10); } } diff --git a/components/maidsite_desk/maidsite_desk.h b/components/maidsite_desk/maidsite_desk.h index a1777eb..d3647ce 100644 --- a/components/maidsite_desk/maidsite_desk.h +++ b/components/maidsite_desk/maidsite_desk.h @@ -15,6 +15,8 @@ #include #include +#define UART_LOG_CHUNK_SIZE 153 + namespace esphome { @@ -61,13 +63,14 @@ namespace esphome #endif MaidsiteDeskComponent() = default; + // base class functions float get_setup_priority() const override { return setup_priority::LATE; } void dump_config() override; void setup() override; void loop() override; - + // option functions void set_log_uart_msg(bool enable) { this->log_uart_msg_ = enable; } - + // functions to use in lambdas void request_physical_limits(); void request_limits(); void request_settings(); @@ -81,23 +84,26 @@ namespace esphome void goto_mem_position(int pos); void save_mem_position(int pos); + // variables to use in lambdas + std::vector response_message_; + protected: + // uart message functions void decode_response(std::vector message); void send_simple_command(unsigned char cmd); void send_2byte_command(unsigned char cmd, unsigned char high_byte, unsigned char low_byte); float byte2float(int high, int low); void log_uart_hex(std::string prefix, std::vector bytes, uint8_t separator); - private: - bool log_uart_msg_{false}; - - std::vector response_message_; + // options variables + bool log_uart_msg_ { false }; + // uart message variables std::vector request_message_; uint8_t response_payload_length_; uint8_t request_payload_length_; - bool response_receiving_{false}; - bool request_receiving_{false}; - + bool response_receiving_ { false }; + bool request_receiving_ { false }; + // sensor variables float current_height_ = 0; float limit_min_ = 0; float limit_max_ = 0; diff --git a/components/maidsite_desk/number/__init__.py b/components/maidsite_desk/number/__init__.py index e9926f3..1cde91b 100644 --- a/components/maidsite_desk/number/__init__.py +++ b/components/maidsite_desk/number/__init__.py @@ -21,7 +21,7 @@ CONF_NUMBERS = [ [ 0, 100, .1, ], ] -MaidsiteDeskNumber = maidsite_desk_ns.class_("MaidsiteDeskNumber", number.Number) +MaidsiteDeskNumber = maidsite_desk_ns.class_("MaidsiteDeskNumber", number.Number, cg.Component) CONFIG_SCHEMA = cv.Schema( { @@ -36,15 +36,19 @@ CONFIG_SCHEMA = cv.Schema( unit_of_measurement=UNIT_PERCENT, ), } -) +).extend(cv.COMPONENT_SCHEMA) async def to_code(config): hub = await cg.get_variable(config[CONF_MAIDSITE_DESK_ID]) for index, key in enumerate(TYPES): - await setup_conf(config, key, index, hub) - -async def setup_conf(parent_config, key, index, hub): - if child_config := parent_config.get(key): - var = await number.new_number(child_config, min_value=CONF_NUMBERS[index][0], max_value=CONF_NUMBERS[index][1], step=CONF_NUMBERS[index][2]) - await cg.register_parented(var, parent_config[CONF_MAIDSITE_DESK_ID]) - cg.add(getattr(hub, f"set_{key}_number")(var)) + if child_config := config.get(key): + var = await number.new_number( + child_config, + min_value=CONF_NUMBERS[index][0], + max_value=CONF_NUMBERS[index][1], + step=CONF_NUMBERS[index][2] + ) + await cg.register_component(var, child_config) + await cg.register_parented(var, config[CONF_MAIDSITE_DESK_ID]) + cg.add(getattr(hub, f"set_{key}_number")(var)) + cg.add(var.set_id(index)) diff --git a/components/maidsite_desk/number/maidsite_desk_number.cpp b/components/maidsite_desk/number/maidsite_desk_number.cpp index 1953909..31c0edd 100644 --- a/components/maidsite_desk/number/maidsite_desk_number.cpp +++ b/components/maidsite_desk/number/maidsite_desk_number.cpp @@ -1,10 +1,19 @@ #include "maidsite_desk_number.h" +#include "esphome/core/log.h" namespace esphome { namespace maidsite_desk { + static const char *const TAG = "maidsite_desk.number"; + + void MaidsiteDeskNumber::dump_config() + { + LOG_NUMBER("", "Maidsite Desk Number", this); + delay(10); + } + void MaidsiteDeskNumber::control(float value) { this->publish_state(value); diff --git a/components/maidsite_desk/number/maidsite_desk_number.h b/components/maidsite_desk/number/maidsite_desk_number.h index a586de3..76aca70 100644 --- a/components/maidsite_desk/number/maidsite_desk_number.h +++ b/components/maidsite_desk/number/maidsite_desk_number.h @@ -1,5 +1,6 @@ #pragma once #include "esphome/components/number/number.h" +#include "esphome/core/component.h" #include "../maidsite_desk.h" @@ -7,13 +8,16 @@ namespace esphome { namespace maidsite_desk { - class MaidsiteDeskNumber : public number::Number, public Parented + class MaidsiteDeskNumber : public number::Number, public Component, public Parented { public: MaidsiteDeskNumber() = default; + void dump_config() override; + void set_id(int id) { this->id_ = id; } protected: void control(float value) override; + int id_; }; } // namespace maidsite_desk } // namespace esphome diff --git a/components/maidsite_desk/sensor.py b/components/maidsite_desk/sensor.py deleted file mode 100644 index 4cf3b7d..0000000 --- a/components/maidsite_desk/sensor.py +++ /dev/null @@ -1,82 +0,0 @@ -import esphome.codegen as cg -import esphome.config_validation as cv -from esphome.components import sensor -from esphome.const import ( - UNIT_CENTIMETER, - UNIT_PERCENT, -) -from . import MaidsiteDeskComponent, CONF_MAIDSITE_DESK_ID - -CONF_UNIT = "unit" -CONF_HEIGHT_ABS = "height_abs" -CONF_HEIGHT_PCT = "height_pct" -CONF_HEIGHT_MIN = "height_min" -CONF_HEIGHT_MAX = "height_max" -CONF_POSITION_M1 = "position_m1" -CONF_POSITION_M2 = "position_m2" -CONF_POSITION_M3 = "position_m3" -CONF_POSITION_M4 = "position_m4" - -TYPES = [ - CONF_UNIT, - CONF_HEIGHT_ABS, - CONF_HEIGHT_PCT, - CONF_HEIGHT_MIN, - CONF_HEIGHT_MAX, - CONF_POSITION_M1, - CONF_POSITION_M2, - CONF_POSITION_M3, - CONF_POSITION_M4, -] - -CONFIG_SCHEMA = cv.All( - cv.Schema( - { - cv.GenerateID(CONF_MAIDSITE_DESK_ID): cv.use_id(MaidsiteDeskComponent), - - cv.Optional(CONF_UNIT): sensor.sensor_schema(), - cv.Optional(CONF_HEIGHT_ABS): sensor.sensor_schema( - accuracy_decimals=2, - unit_of_measurement=UNIT_CENTIMETER, - ), - cv.Optional(CONF_HEIGHT_PCT): sensor.sensor_schema( - accuracy_decimals=2, - unit_of_measurement=UNIT_PERCENT, - ), - cv.Optional(CONF_HEIGHT_MIN): sensor.sensor_schema( - accuracy_decimals=2, - unit_of_measurement=UNIT_CENTIMETER, - ), - cv.Optional(CONF_HEIGHT_MAX): sensor.sensor_schema( - accuracy_decimals=2, - unit_of_measurement=UNIT_CENTIMETER, - ), - cv.Optional(CONF_POSITION_M1): sensor.sensor_schema( - accuracy_decimals=2, - unit_of_measurement=UNIT_CENTIMETER, - ), - cv.Optional(CONF_POSITION_M2): sensor.sensor_schema( - accuracy_decimals=2, - unit_of_measurement=UNIT_CENTIMETER, - ), - cv.Optional(CONF_POSITION_M3): sensor.sensor_schema( - accuracy_decimals=2, - unit_of_measurement=UNIT_CENTIMETER, - ), - cv.Optional(CONF_POSITION_M4): sensor.sensor_schema( - accuracy_decimals=2, - unit_of_measurement=UNIT_CENTIMETER, - ), - } - ).extend(cv.COMPONENT_SCHEMA) -) - -async def to_code(config): - hub = await cg.get_variable(config[CONF_MAIDSITE_DESK_ID]) - for key in TYPES: - await setup_conf(config, key, hub) - -async def setup_conf(parent_config, key, hub): - if child_config := parent_config.get(key): - var = await sensor.new_sensor(child_config) - cg.add(getattr(hub, f"set_{key}_sensor")(var)) diff --git a/components/maidsite_desk/sensor/__init__.py b/components/maidsite_desk/sensor/__init__.py new file mode 100644 index 0000000..b4c4adc --- /dev/null +++ b/components/maidsite_desk/sensor/__init__.py @@ -0,0 +1,90 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import sensor +from esphome.const import ( + UNIT_CENTIMETER, + UNIT_PERCENT, +) +from .. import CONF_MAIDSITE_DESK_ID, MaidsiteDeskComponent, maidsite_desk_ns + +CONF_UNIT = "unit" +CONF_HEIGHT_ABS = "height_abs" +CONF_HEIGHT_PCT = "height_pct" +CONF_HEIGHT_MIN = "height_min" +CONF_HEIGHT_MAX = "height_max" +CONF_POSITION_M1 = "position_m1" +CONF_POSITION_M2 = "position_m2" +CONF_POSITION_M3 = "position_m3" +CONF_POSITION_M4 = "position_m4" + +TYPES = [ + CONF_UNIT, + CONF_HEIGHT_ABS, + CONF_HEIGHT_PCT, + CONF_HEIGHT_MIN, + CONF_HEIGHT_MAX, + CONF_POSITION_M1, + CONF_POSITION_M2, + CONF_POSITION_M3, + CONF_POSITION_M4, +] + +MaidsiteDeskSensor = maidsite_desk_ns.class_("MaidsiteDeskSensor", sensor.Sensor, cg.Component) + +CONFIG_SCHEMA = cv.Schema( + { + cv.GenerateID(CONF_MAIDSITE_DESK_ID): cv.use_id(MaidsiteDeskComponent), + + cv.Optional(CONF_UNIT): sensor.sensor_schema(), + + cv.Optional(CONF_HEIGHT_ABS): sensor.sensor_schema( + MaidsiteDeskSensor, + accuracy_decimals=2, + unit_of_measurement=UNIT_CENTIMETER, + ), + cv.Optional(CONF_HEIGHT_PCT): sensor.sensor_schema( + MaidsiteDeskSensor, + accuracy_decimals=2, + unit_of_measurement=UNIT_PERCENT, + ), + cv.Optional(CONF_HEIGHT_MIN): sensor.sensor_schema( + MaidsiteDeskSensor, + accuracy_decimals=2, + unit_of_measurement=UNIT_CENTIMETER, + ), + cv.Optional(CONF_HEIGHT_MAX): sensor.sensor_schema( + MaidsiteDeskSensor, + accuracy_decimals=2, + unit_of_measurement=UNIT_CENTIMETER, + ), + cv.Optional(CONF_POSITION_M1): sensor.sensor_schema( + MaidsiteDeskSensor, + accuracy_decimals=2, + unit_of_measurement=UNIT_CENTIMETER, + ), + cv.Optional(CONF_POSITION_M2): sensor.sensor_schema( + MaidsiteDeskSensor, + accuracy_decimals=2, + unit_of_measurement=UNIT_CENTIMETER, + ), + cv.Optional(CONF_POSITION_M3): sensor.sensor_schema( + MaidsiteDeskSensor, + accuracy_decimals=2, + unit_of_measurement=UNIT_CENTIMETER, + ), + cv.Optional(CONF_POSITION_M4): sensor.sensor_schema( + MaidsiteDeskSensor, + accuracy_decimals=2, + unit_of_measurement=UNIT_CENTIMETER, + ), + } +).extend(cv.COMPONENT_SCHEMA) + +async def to_code(config): + hub = await cg.get_variable(config[CONF_MAIDSITE_DESK_ID]) + for key in TYPES: + if child_config := config.get(key): + var = await sensor.new_sensor(child_config) + await cg.register_component(var, child_config) + await cg.register_parented(var, config[CONF_MAIDSITE_DESK_ID]) + cg.add(getattr(hub, f"set_{key}_sensor")(var)) diff --git a/components/maidsite_desk/sensor/maidsite_desk_sensor.cpp b/components/maidsite_desk/sensor/maidsite_desk_sensor.cpp new file mode 100644 index 0000000..87853a0 --- /dev/null +++ b/components/maidsite_desk/sensor/maidsite_desk_sensor.cpp @@ -0,0 +1,17 @@ +#include "maidsite_desk_sensor.h" +#include "esphome/core/log.h" + + +namespace esphome +{ + namespace maidsite_desk + { + static const char *const TAG = "maidsite_desk.sensor"; + + void MaidsiteDeskSensor::dump_config() + { + LOG_SENSOR("", "Maidsite Desk Sensor", this); + delay(10); + } + } // namespace maidsite_desk +} // namespace esphome diff --git a/components/maidsite_desk/sensor/maidsite_desk_sensor.h b/components/maidsite_desk/sensor/maidsite_desk_sensor.h new file mode 100644 index 0000000..fc63ff1 --- /dev/null +++ b/components/maidsite_desk/sensor/maidsite_desk_sensor.h @@ -0,0 +1,18 @@ +#pragma once +#include "esphome/components/sensor/sensor.h" +#include "esphome/core/component.h" +#include "../maidsite_desk.h" + + +namespace esphome +{ + namespace maidsite_desk + { + class MaidsiteDeskSensor : public sensor::Sensor, public Component, public Parented + { + public: + MaidsiteDeskSensor() = default; + void dump_config() override; + }; + } // namespace maidsite_desk +} // namespace esphome diff --git a/components/panasonic_heatpump/README.md b/components/panasonic_heatpump/README.md index 0d585a0..3581b93 100644 --- a/components/panasonic_heatpump/README.md +++ b/components/panasonic_heatpump/README.md @@ -107,7 +107,7 @@ switch: All sensors are optional and all default sensor variables can be applied. Here a list of all supported sensors: -``` +```yaml sensor: - platform: panasonic_heatpump top1: @@ -307,7 +307,7 @@ sensor: All binary sensors are optional and all default binary sensor variables can be applied. Here a list of all supported binary sensors: -``` +```yaml binary_sensor: - platform: panasonic_heatpump top0: @@ -363,7 +363,7 @@ binary_sensor: All text sensors are optional and all default text sensor variables can be applied. Here a list of all supported text sensors: -``` +```yaml text_sensor: - platform: panasonic_heatpump top4: @@ -415,7 +415,7 @@ text_sensor: All numbers are optional and all default number variables can be applied. Here a list of all supported numbers: -``` +```yaml number: - platform: panasonic_heatpump set5: @@ -491,7 +491,7 @@ number: All switches are optional and all default switch variables can be applied. Here a list of all supported switches: -``` +```yaml switch: - platform: panasonic_heatpump set1: @@ -527,7 +527,7 @@ switch: All selects are optional and all default select variables can be applied. Here a list of all supported selects: -``` +```yaml select: - platform: panasonic_heatpump set2: @@ -552,10 +552,14 @@ If you review the [ProtocolByteDecrypt.md](https://github.com/Egyras/HeishaMon/b They are usually marked as TOP (without a number). The nice part of ESPHome is that it is so highly customizeable. So if you want some additional TOP or SET entities you can easily create your own. -Under the hood the received uart message from the heatpump is stored in a vector. -Here are 2 examples how to create a sensor and a text_sensor: +Under the hood the received uart message from the heatpump is stored in a vector, +so you can decode each byte by yourself. +Here an example how to create a sensor and a text_sensor: + +```yaml +panasonic_heatpump: + id: my_heatpump -``` sensor: - platform: template name: "Dry concrete target temperature for actual stage" @@ -565,6 +569,8 @@ sensor: lambda: |- // get the requried byte int byte = my_heatpump->getResponseByte(46); + // a valid byte range is 0x00-0xFF + // do not update if the byte is invalid if (byte < 0) return {}; // convert the byte (see HeishaMon/ProtocolByteDecrypt.md) // in this case -128 @@ -577,6 +583,8 @@ text_sensor: lambda: |- // get the requried byte int byte = my_heatpump->getResponseByte(9); + // a valid byte range is 0x00-0xFF + // do not update if the byte is invalid if (byte < 0) return {}; // convert the byte (see HeishaMon/ProtocolByteDecrypt.md) // in this case 3rd and 4th bit (--> b0011 0000) @@ -584,13 +592,18 @@ text_sensor: // set text if (state == 0) return { "Standard" }; if (state == 1) return { "DHW" }; - // if state is unkown do not update text + // if state is unkown do not update return {}; ``` ## Known Issues -When the ESP controller is connected initially to the heatpump, the heatpump may not respond to any request messages. If the CZ-TAW1 is also connected to the ESP controller you will probably see some requests like 31 05 10 01 ... These are initial request messages. If the heatpump is not responding, it may help to turn off and on the power of the heatpump (switching the heatpump off is not enough). After a power on the heatpump should respond to the requests. +When the ESP controller is connected initially to the heatpump (and the heatpump is powered), +the heatpump may not respond to any request messages. +If the CZ-TAW1 is also connected to the ESP controller you will probably see some requests like 0x31 05 10 01 ... +These are initial request messages. +If the heatpump is not responding, it may help to turn off and on the power of the heatpump (switching the heatpump off is not enough). +After a power on the heatpump should respond to the requests. ## Sources