From a97f8ad31d8df4e85b78472a9fb59310d9d8519e Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 22 Mar 2023 20:48:37 +0100 Subject: [PATCH] add number & action for manual aircon. --- README.md | 3 ++ .../TrumaStausFrameResponseStorage.h | 2 +- .../TrumaiNetBoxAppAirconAuto.cpp | 14 +++++-- .../truma_inetbox/TrumaiNetBoxAppAirconAuto.h | 1 + .../TrumaiNetBoxAppAirconManual.cpp | 22 ++++++++++- .../TrumaiNetBoxAppAirconManual.h | 3 ++ .../truma_inetbox/TrumaiNetBoxAppHeater.cpp | 5 +++ .../truma_inetbox/TrumaiNetBoxAppHeater.h | 1 + components/truma_inetbox/__init__.py | 23 +++++++++++ components/truma_inetbox/automation.h | 9 +++++ components/truma_inetbox/binary_sensor/enum.h | 2 + components/truma_inetbox/helpers.cpp | 8 ++-- .../number/TrumaAirconManualNumber.cpp | 37 ++++++++++++++++++ .../number/TrumaAirconManualNumber.h | 26 +++++++++++++ .../number/TrumaHeaterNumber.cpp | 4 ++ .../truma_inetbox/number/TrumaHeaterNumber.h | 24 +----------- components/truma_inetbox/number/__init__.py | 12 ++++++ components/truma_inetbox/number/enum.h | 39 +++++++++++++++++++ components/truma_inetbox/sensor/TrumaSensor.h | 1 + tests/test.common.button.yaml | 10 +++++ tests/test.common.number.yaml | 5 +++ 21 files changed, 218 insertions(+), 33 deletions(-) create mode 100644 components/truma_inetbox/number/TrumaAirconManualNumber.cpp create mode 100644 components/truma_inetbox/number/TrumaAirconManualNumber.h create mode 100644 components/truma_inetbox/number/enum.h diff --git a/README.md b/README.md index 2fa51bd..24056af 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,7 @@ The following `type` values are available: - `TARGET_ROOM_TEMPERATURE` - `TARGET_WATER_TEMPERATURE` - `ELECTRIC_POWER_LEVEL` +- `AIRCON_MANUAL_TEMPERATURE` ### Sensor @@ -161,6 +162,8 @@ The following [ESP Home actions](https://esphome.io/guides/automations.html#acti - `truma_inetbox.heater.set_energy_mix` - `energy_mix` - Set energy mix to: `GAS`, `MIX`, `ELECTRICITY`. - `watt` - Optional: Set electricity level to `0`, `900`, `1800` +- `truma_inetbox.aircon.manual.set_target_temperature` + - `temperature` - Temperature between 16C and 31C. Below 16C will disable the Aircon. - `truma_inetbox.timer.disable` - Disable the timer configuration. - `truma_inetbox.timer.activate` - Set a new timer configuration. - `start` - Start time. diff --git a/components/truma_inetbox/TrumaStausFrameResponseStorage.h b/components/truma_inetbox/TrumaStausFrameResponseStorage.h index ba58024..09e9539 100644 --- a/components/truma_inetbox/TrumaStausFrameResponseStorage.h +++ b/components/truma_inetbox/TrumaStausFrameResponseStorage.h @@ -18,7 +18,7 @@ class TrumaStausFrameResponseStorage : public TrumaStausFrameStorage, public this->update_status_unsubmitted_ = false; this->update_status_stale_ = false; } - bool can_update() { return this->data_valid_; } + virtual bool can_update() { return this->data_valid_; } virtual TResponse *update_prepare() = 0; void update_submit() { this->update_status_unsubmitted_ = true; } const bool has_update() const { return this->update_status_unsubmitted_; } diff --git a/components/truma_inetbox/TrumaiNetBoxAppAirconAuto.cpp b/components/truma_inetbox/TrumaiNetBoxAppAirconAuto.cpp index 780c9a9..8f24f84 100644 --- a/components/truma_inetbox/TrumaiNetBoxAppAirconAuto.cpp +++ b/components/truma_inetbox/TrumaiNetBoxAppAirconAuto.cpp @@ -2,6 +2,7 @@ #include "TrumaStatusFrameBuilder.h" #include "esphome/core/log.h" #include "helpers.h" +#include "TrumaiNetBoxApp.h" namespace esphome { namespace truma_inetbox { @@ -25,8 +26,8 @@ StatusFrameAirconAutoResponse *TrumaiNetBoxAppAirconAuto::update_prepare() { return &this->update_status_; } -void TrumaiNetBoxAppAirconAuto::create_update_data(StatusFrame *response, u_int8_t *response_len, u_int8_t command_counter){ - +void TrumaiNetBoxAppAirconAuto::create_update_data(StatusFrame *response, u_int8_t *response_len, + u_int8_t command_counter) { status_frame_create_empty(response, STATUS_FRAME_AIRCON_AUTO_RESPONSE, sizeof(StatusFrameAirconAutoResponse), command_counter); @@ -38,10 +39,15 @@ void TrumaiNetBoxAppAirconAuto::create_update_data(StatusFrame *response, u_int8 status_frame_calculate_checksum(response); (*response_len) = sizeof(StatusFrameHeader) + sizeof(StatusFrameAirconAutoResponse); - TrumaStausFrameResponseStorage::update_submitted(); + TrumaStausFrameResponseStorage::update_submitted(); } - + void TrumaiNetBoxAppAirconAuto::dump_data() const {} +bool TrumaiNetBoxAppAirconAuto::can_update() { + return TrumaStausFrameResponseStorage::can_update() && + this->parent_->get_aircon_device() != TRUMA_DEVICE::UNKNOWN; +} + } // namespace truma_inetbox } // namespace esphome \ No newline at end of file diff --git a/components/truma_inetbox/TrumaiNetBoxAppAirconAuto.h b/components/truma_inetbox/TrumaiNetBoxAppAirconAuto.h index 9c1d1ff..f1945e7 100644 --- a/components/truma_inetbox/TrumaiNetBoxAppAirconAuto.h +++ b/components/truma_inetbox/TrumaiNetBoxAppAirconAuto.h @@ -12,6 +12,7 @@ class TrumaiNetBoxAppAirconAuto StatusFrameAirconAutoResponse *update_prepare() override; void create_update_data(StatusFrame *response, u_int8_t *response_len, u_int8_t command_counter) override; void dump_data() const override; + bool can_update() override; }; } // namespace truma_inetbox diff --git a/components/truma_inetbox/TrumaiNetBoxAppAirconManual.cpp b/components/truma_inetbox/TrumaiNetBoxAppAirconManual.cpp index d2a46ca..7dc191d 100644 --- a/components/truma_inetbox/TrumaiNetBoxAppAirconManual.cpp +++ b/components/truma_inetbox/TrumaiNetBoxAppAirconManual.cpp @@ -2,6 +2,7 @@ #include "TrumaStatusFrameBuilder.h" #include "esphome/core/log.h" #include "helpers.h" +#include "TrumaiNetBoxApp.h" namespace esphome { namespace truma_inetbox { @@ -26,7 +27,7 @@ StatusFrameAirconManualResponse *TrumaiNetBoxAppAirconManual::update_prepare() { } void TrumaiNetBoxAppAirconManual::create_update_data(StatusFrame *response, u_int8_t *response_len, - u_int8_t command_counter) { + u_int8_t command_counter) { status_frame_create_empty(response, STATUS_FRAME_AIRCON_MANUAL_RESPONSE, sizeof(StatusFrameAirconManualResponse), command_counter); @@ -44,5 +45,24 @@ void TrumaiNetBoxAppAirconManual::create_update_data(StatusFrame *response, u_in void TrumaiNetBoxAppAirconManual::dump_data() const {} +bool TrumaiNetBoxAppAirconManual::can_update() { + return TrumaStausFrameResponseStorage::can_update() && + this->parent_->get_aircon_device() != TRUMA_DEVICE::UNKNOWN; +} + +bool TrumaiNetBoxAppAirconManual::action_set_temp(u_int8_t temperature) { + if (!this->can_update()) { + ESP_LOGW(TAG, "Cannot update Truma."); + return false; + } + + auto update_data = this->update_prepare(); + + update_data->target_temp_aircon = decimal_to_aircon_temp(temperature); + + this->update_submit(); + return true; +} + } // namespace truma_inetbox } // namespace esphome \ No newline at end of file diff --git a/components/truma_inetbox/TrumaiNetBoxAppAirconManual.h b/components/truma_inetbox/TrumaiNetBoxAppAirconManual.h index 8a209cf..faad41c 100644 --- a/components/truma_inetbox/TrumaiNetBoxAppAirconManual.h +++ b/components/truma_inetbox/TrumaiNetBoxAppAirconManual.h @@ -12,6 +12,9 @@ class TrumaiNetBoxAppAirconManual StatusFrameAirconManualResponse *update_prepare() override; void create_update_data(StatusFrame *response, u_int8_t *response_len, u_int8_t command_counter) override; void dump_data() const override; + bool can_update() override; + + bool action_set_temp(u_int8_t temperature); }; } // namespace truma_inetbox diff --git a/components/truma_inetbox/TrumaiNetBoxAppHeater.cpp b/components/truma_inetbox/TrumaiNetBoxAppHeater.cpp index 52ea65a..305e219 100644 --- a/components/truma_inetbox/TrumaiNetBoxAppHeater.cpp +++ b/components/truma_inetbox/TrumaiNetBoxAppHeater.cpp @@ -49,6 +49,11 @@ void TrumaiNetBoxAppHeater::create_update_data(StatusFrame *response, u_int8_t * void TrumaiNetBoxAppHeater::dump_data() const {} +bool TrumaiNetBoxAppHeater::can_update() { + return TrumaStausFrameResponseStorage::can_update() && + this->parent_->get_heater_device() != TRUMA_DEVICE::UNKNOWN; +} + bool TrumaiNetBoxAppHeater::action_heater_room(u_int8_t temperature, HeatingMode mode) { if (!this->can_update()) { ESP_LOGW(TAG, "Cannot update Truma."); diff --git a/components/truma_inetbox/TrumaiNetBoxAppHeater.h b/components/truma_inetbox/TrumaiNetBoxAppHeater.h index 478ed01..d65d612 100644 --- a/components/truma_inetbox/TrumaiNetBoxAppHeater.h +++ b/components/truma_inetbox/TrumaiNetBoxAppHeater.h @@ -11,6 +11,7 @@ class TrumaiNetBoxAppHeater : public TrumaStausFrameResponseStorage class HeaterEnergyMixAction : public Action, pub } }; +template class AirconManualTempAction : public Action, public Parented { + public: + TEMPLATABLE_VALUE(u_int8_t, temperature) + + void play(Ts... x) override { + this->parent_->get_aircon_manual()->action_set_temp(this->temperature_.value_or(x..., 0)); + } +}; + template class TimerDisableAction : public Action, public Parented { public: void play(Ts... x) override { this->parent_->get_timer()->action_timer_disable(); } diff --git a/components/truma_inetbox/binary_sensor/enum.h b/components/truma_inetbox/binary_sensor/enum.h index a2bd2be..2aac3a0 100644 --- a/components/truma_inetbox/binary_sensor/enum.h +++ b/components/truma_inetbox/binary_sensor/enum.h @@ -4,6 +4,8 @@ namespace esphome { namespace truma_inetbox { enum class TRUMA_BINARY_SENSOR_TYPE { + UNKNOWN, + HEATER_ROOM, HEATER_WATER, HEATER_GAS, diff --git a/components/truma_inetbox/helpers.cpp b/components/truma_inetbox/helpers.cpp index da37b07..db82b66 100644 --- a/components/truma_inetbox/helpers.cpp +++ b/components/truma_inetbox/helpers.cpp @@ -38,7 +38,7 @@ TargetTemp decimal_to_room_temp(u_int8_t val) { return TargetTemp::TARGET_TEMP_OFF; } if (val <= 5) { - return TargetTemp::TARGET_TEMP_ROOM_MIN; + return TargetTemp::TARGET_TEMP_OFF; } if (val >= 30) { return TargetTemp::TARGET_TEMP_ROOM_MAX; @@ -51,7 +51,7 @@ TargetTemp decimal_to_room_temp(float val) { return TargetTemp::TARGET_TEMP_OFF; } if (val <= 5) { - return TargetTemp::TARGET_TEMP_ROOM_MIN; + return TargetTemp::TARGET_TEMP_OFF; } if (val >= 30) { return TargetTemp::TARGET_TEMP_ROOM_MAX; @@ -64,7 +64,7 @@ TargetTemp decimal_to_aircon_temp(u_int8_t val) { return TargetTemp::TARGET_TEMP_OFF; } if (val <= 16) { - return TargetTemp::TARGET_TEMP_AIRCON_MIN; + return TargetTemp::TARGET_TEMP_OFF; } if (val >= 31) { return TargetTemp::TARGET_TEMP_AIRCON_MAX; @@ -77,7 +77,7 @@ TargetTemp decimal_to_aircon_temp(float val) { return TargetTemp::TARGET_TEMP_OFF; } if (val <= 16) { - return TargetTemp::TARGET_TEMP_AIRCON_MIN; + return TargetTemp::TARGET_TEMP_OFF; } if (val >= 31) { return TargetTemp::TARGET_TEMP_AIRCON_MAX; diff --git a/components/truma_inetbox/number/TrumaAirconManualNumber.cpp b/components/truma_inetbox/number/TrumaAirconManualNumber.cpp new file mode 100644 index 0000000..e22c282 --- /dev/null +++ b/components/truma_inetbox/number/TrumaAirconManualNumber.cpp @@ -0,0 +1,37 @@ +#include "TrumaAirconManualNumber.h" +#include "esphome/core/log.h" +#include "esphome/components/truma_inetbox/helpers.h" + +namespace esphome { +namespace truma_inetbox { + +static const char *const TAG = "truma_inetbox.aircon_manual_number"; + +void TrumaAirconManualNumber::setup() { + this->parent_->get_aircon_manual()->add_on_message_callback([this](const StatusFrameAirconManual *status) { + switch (this->type_) { + case TRUMA_NUMBER_TYPE::AIRCON_MANUAL_TEMPERATURE: + this->publish_state(temp_code_to_decimal(status->target_temp_aircon, 0)); + break; + default: + break; + } + }); +} + +void TrumaAirconManualNumber::control(float value) { + switch (this->type_) { + case TRUMA_NUMBER_TYPE::AIRCON_MANUAL_TEMPERATURE: + this->parent_->get_aircon_manual()->action_set_temp(static_cast(value)); + break; + default: + break; + } +} + +void TrumaAirconManualNumber::dump_config() { + LOG_NUMBER("", "Truma Aircon Manual Number", this); + ESP_LOGCONFIG(TAG, " Type '%s'", enum_to_c_str(this->type_)); +} +} // namespace truma_inetbox +} // namespace esphome \ No newline at end of file diff --git a/components/truma_inetbox/number/TrumaAirconManualNumber.h b/components/truma_inetbox/number/TrumaAirconManualNumber.h new file mode 100644 index 0000000..a2b9ed4 --- /dev/null +++ b/components/truma_inetbox/number/TrumaAirconManualNumber.h @@ -0,0 +1,26 @@ +#pragma once + +#include "enum.h" +#include "esphome/components/number/number.h" +#include "esphome/components/truma_inetbox/TrumaiNetBoxApp.h" + +namespace esphome { +namespace truma_inetbox { + + +class TrumaAirconManualNumber : public Component, public number::Number, public Parented { + public: + void setup() override; + void dump_config() override; + + void set_type(TRUMA_NUMBER_TYPE val) { this->type_ = val; } + + protected: + TRUMA_NUMBER_TYPE type_; + + void control(float value) override; + + private: +}; +} // namespace truma_inetbox +} // namespace esphome \ No newline at end of file diff --git a/components/truma_inetbox/number/TrumaHeaterNumber.cpp b/components/truma_inetbox/number/TrumaHeaterNumber.cpp index a9098eb..8916414 100644 --- a/components/truma_inetbox/number/TrumaHeaterNumber.cpp +++ b/components/truma_inetbox/number/TrumaHeaterNumber.cpp @@ -19,6 +19,8 @@ void TrumaHeaterNumber::setup() { case TRUMA_NUMBER_TYPE::ELECTRIC_POWER_LEVEL: this->publish_state(static_cast(status_heater->el_power_level_a)); break; + default: + break; } }); } @@ -34,6 +36,8 @@ void TrumaHeaterNumber::control(float value) { case TRUMA_NUMBER_TYPE::ELECTRIC_POWER_LEVEL: this->parent_->get_heater()->action_heater_electric_power_level(static_cast(value)); break; + default: + break; } } diff --git a/components/truma_inetbox/number/TrumaHeaterNumber.h b/components/truma_inetbox/number/TrumaHeaterNumber.h index 883177b..a58836b 100644 --- a/components/truma_inetbox/number/TrumaHeaterNumber.h +++ b/components/truma_inetbox/number/TrumaHeaterNumber.h @@ -1,34 +1,12 @@ #pragma once +#include "enum.h" #include "esphome/components/number/number.h" #include "esphome/components/truma_inetbox/TrumaiNetBoxApp.h" namespace esphome { namespace truma_inetbox { -enum class TRUMA_NUMBER_TYPE { - TARGET_ROOM_TEMPERATURE, - TARGET_WATER_TEMPERATURE, - ELECTRIC_POWER_LEVEL, -}; - -static const char *enum_to_c_str(const TRUMA_NUMBER_TYPE val) { - switch (val) { - case TRUMA_NUMBER_TYPE::TARGET_ROOM_TEMPERATURE: - return "TARGET_ROOM_TEMPERATURE"; - break; - case TRUMA_NUMBER_TYPE::TARGET_WATER_TEMPERATURE: - return "TARGET_WATER_TEMPERATURE"; - break; - case TRUMA_NUMBER_TYPE::ELECTRIC_POWER_LEVEL: - return "ELECTRIC_POWER_LEVEL"; - break; - default: - return ""; - break; - } -} - class TrumaHeaterNumber : public Component, public number::Number, public Parented { public: void setup() override; diff --git a/components/truma_inetbox/number/__init__.py b/components/truma_inetbox/number/__init__.py index 734ce0e..3ed9ee6 100644 --- a/components/truma_inetbox/number/__init__.py +++ b/components/truma_inetbox/number/__init__.py @@ -62,6 +62,18 @@ CONF_SUPPORTED_TYPE = { CONF_MIN_VALUE: 0, CONF_STEP: 900, }, + + "AIRCON_MANUAL_TEMPERATURE": { + CONF_CLASS: truma_inetbox_ns.class_("TrumaAirconManualNumber", number.Number, cg.Component), + CONF_TYPE: TRUMA_NUMBER_TYPE_dummy_ns.AIRCON_MANUAL_TEMPERATURE, + CONF_UNIT_OF_MEASUREMENT: UNIT_CELSIUS, + CONF_ICON: ICON_THERMOMETER, + CONF_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE, + CONF_MAX_VALUE: 31, + # Values between 0 and 16 are handeld as off. + CONF_MIN_VALUE: 15, + CONF_STEP: 1, + }, } diff --git a/components/truma_inetbox/number/enum.h b/components/truma_inetbox/number/enum.h new file mode 100644 index 0000000..10f2672 --- /dev/null +++ b/components/truma_inetbox/number/enum.h @@ -0,0 +1,39 @@ +#pragma once + +namespace esphome { +namespace truma_inetbox { + +enum class TRUMA_NUMBER_TYPE { + UNKNOWN, + + TARGET_ROOM_TEMPERATURE, + TARGET_WATER_TEMPERATURE, + ELECTRIC_POWER_LEVEL, + + AIRCON_MANUAL_TEMPERATURE, +}; + +static const char *enum_to_c_str(const TRUMA_NUMBER_TYPE val) { + switch (val) { + case TRUMA_NUMBER_TYPE::TARGET_ROOM_TEMPERATURE: + return "TARGET_ROOM_TEMPERATURE"; + break; + case TRUMA_NUMBER_TYPE::TARGET_WATER_TEMPERATURE: + return "TARGET_WATER_TEMPERATURE"; + break; + case TRUMA_NUMBER_TYPE::ELECTRIC_POWER_LEVEL: + return "ELECTRIC_POWER_LEVEL"; + break; + + case TRUMA_NUMBER_TYPE::AIRCON_MANUAL_TEMPERATURE: + return "AIRCON_MANUAL_TEMPERATURE"; + break; + + default: + return ""; + break; + } +} + +} // namespace truma_inetbox +} // namespace esphome \ No newline at end of file diff --git a/components/truma_inetbox/sensor/TrumaSensor.h b/components/truma_inetbox/sensor/TrumaSensor.h index 41dca14..3e992a5 100644 --- a/components/truma_inetbox/sensor/TrumaSensor.h +++ b/components/truma_inetbox/sensor/TrumaSensor.h @@ -6,6 +6,7 @@ namespace esphome { namespace truma_inetbox { enum class TRUMA_SENSOR_TYPE { + UNKNOWN, CURRENT_ROOM_TEMPERATURE, CURRENT_WATER_TEMPERATURE, TARGET_ROOM_TEMPERATURE, diff --git a/tests/test.common.button.yaml b/tests/test.common.button.yaml index 1ae2d7f..01608af 100644 --- a/tests/test.common.button.yaml +++ b/tests/test.common.button.yaml @@ -35,3 +35,13 @@ name: "Set electric power level to 1800 Watt" on_press: - truma_inetbox.heater.set_electric_power_level: 1800 + - platform: template + name: "Switch Aircon off" + on_press: + - truma_inetbox.aircon.manual.set_target_temperature: 0 + - platform: template + name: "Set Aircon to fixed 21 C" + on_press: + - truma_inetbox.aircon.manual.set_target_temperature: 21 + + diff --git a/tests/test.common.number.yaml b/tests/test.common.number.yaml index 298fa66..265d202 100644 --- a/tests/test.common.number.yaml +++ b/tests/test.common.number.yaml @@ -7,3 +7,8 @@ - platform: truma_inetbox name: "electric power level" type: ELECTRIC_POWER_LEVEL + + - platform: truma_inetbox + name: "Aircon manual temp" + type: AIRCON_MANUAL_TEMPERATURE +