Merge branch 'main' into panasonic_dev

This commit is contained in:
ElVit
2025-02-27 17:20:58 +01:00
13 changed files with 217 additions and 159 deletions
+9 -10
View File
@@ -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))
@@ -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);
@@ -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<MaidsiteDeskComponent>
class MaidsiteDeskButton : public button::Button, public Component, public Parented<MaidsiteDeskComponent>
{
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
+3 -36
View File
@@ -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);
}
}
+15 -9
View File
@@ -15,6 +15,8 @@
#include <vector>
#include <string>
#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<uint8_t> response_message_;
protected:
// uart message functions
void decode_response(std::vector<uint8_t> 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<uint8_t> bytes, uint8_t separator);
private:
bool log_uart_msg_{false};
std::vector<uint8_t> response_message_;
// options variables
bool log_uart_msg_ { false };
// uart message variables
std::vector<uint8_t> 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;
+13 -9
View File
@@ -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))
@@ -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);
@@ -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<MaidsiteDeskComponent>
class MaidsiteDeskNumber : public number::Number, public Component, public Parented<MaidsiteDeskComponent>
{
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
-82
View File
@@ -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))
@@ -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))
@@ -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
@@ -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<MaidsiteDeskComponent>
{
public:
MaidsiteDeskSensor() = default;
void dump_config() override;
};
} // namespace maidsite_desk
} // namespace esphome
+24 -11
View File
@@ -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