diff --git a/esphome/components/diesel_heater_ble/__init__.py b/esphome/components/diesel_heater_ble/__init__.py index 489e2b0093..1ae1844fb9 100644 --- a/esphome/components/diesel_heater_ble/__init__.py +++ b/esphome/components/diesel_heater_ble/__init__.py @@ -6,7 +6,7 @@ from esphome.const import CONF_ID CODEOWNERS = ["@warehog"] DEPENDENCIES = ["ble_client"] -CONF_HEATER_ID = "diesel_heater_ble" +CONF_DIESEL_HEATER_BLE = "diesel_heater_ble" diesel_heater_ble_ns = cg.esphome_ns.namespace("diesel_heater_ble") DieselHeaterBLE = diesel_heater_ble_ns.class_( diff --git a/esphome/components/diesel_heater_ble/button.h b/esphome/components/diesel_heater_ble/button.h index 51e8915067..aa20a4ad4e 100644 --- a/esphome/components/diesel_heater_ble/button.h +++ b/esphome/components/diesel_heater_ble/button.h @@ -13,9 +13,7 @@ class LevelUpButton : public button::Button, public Parented { LevelUpButton() = default; protected: - void press_action() override { - this->parent_->on_level_up_button_press(); - } + void press_action() override { this->parent_->on_level_up_button_press(); } }; class LevelDownButton : public button::Button, public Parented { @@ -23,9 +21,7 @@ class LevelDownButton : public button::Button, public Parented LevelDownButton() = default; protected: - void press_action() override { - this->parent_->on_level_down_button_press(); - } + void press_action() override { this->parent_->on_level_down_button_press(); } }; class TempUpButton : public button::Button, public Parented { @@ -33,9 +29,7 @@ class TempUpButton : public button::Button, public Parented { TempUpButton() = default; protected: - void press_action() override { - this->parent_->on_temp_up_button_press(); - } + void press_action() override { this->parent_->on_temp_up_button_press(); } }; class TempDownButton : public button::Button, public Parented { @@ -43,11 +37,8 @@ class TempDownButton : public button::Button, public Parented { TempDownButton() = default; protected: - void press_action() override { - this->parent_->on_temp_down_button_press(); - } + void press_action() override { this->parent_->on_temp_down_button_press(); } }; - -} // namespace diesel_heater -} // namespace esphome \ No newline at end of file +} // namespace diesel_heater_ble +} // namespace esphome diff --git a/esphome/components/diesel_heater_ble/button.py b/esphome/components/diesel_heater_ble/button.py index 7ac47af9ed..1af403ad0d 100644 --- a/esphome/components/diesel_heater_ble/button.py +++ b/esphome/components/diesel_heater_ble/button.py @@ -2,30 +2,30 @@ import esphome.codegen as cg from esphome.components import button import esphome.config_validation as cv -from . import CONF_HEATER_ID, DieselHeaterBLE, diesel_heater_ble_ns +from . import CONF_DIESEL_HEATER_BLE, DieselHeaterBLE, diesel_heater_ble_ns -CONF_LEVEL_UP_ID = "level_up" -CONF_LEVEL_DOWN_ID = "level_down" -CONF_TEMP_UP_ID = "temp_up" -CONF_TEMP_DOWN_ID = "temp_down" +CONF_LEVEL_UP = "level_up" +CONF_LEVEL_DOWN = "level_down" +CONF_TEMP_UP = "temp_up" +CONF_TEMP_DOWN = "temp_down" CONFIG_SCHEMA = cv.Schema( { - cv.GenerateID(CONF_HEATER_ID): cv.use_id(DieselHeaterBLE), - cv.Optional(CONF_LEVEL_UP_ID): button.button_schema( + cv.GenerateID(CONF_DIESEL_HEATER_BLE): cv.use_id(DieselHeaterBLE), + cv.Optional(CONF_LEVEL_UP): button.button_schema( diesel_heater_ble_ns.class_("LevelUpButton", button.Button), icon="mdi:arrow-up", ), - cv.Optional(CONF_LEVEL_DOWN_ID): button.button_schema( + cv.Optional(CONF_LEVEL_DOWN): button.button_schema( diesel_heater_ble_ns.class_("LevelDownButton", button.Button), icon="mdi:arrow-down", ), - cv.Optional(CONF_TEMP_UP_ID): button.button_schema( + cv.Optional(CONF_TEMP_UP): button.button_schema( diesel_heater_ble_ns.class_("TempUpButton", button.Button), icon="mdi:arrow-up", ), - cv.Optional(CONF_TEMP_DOWN_ID): button.button_schema( + cv.Optional(CONF_TEMP_DOWN): button.button_schema( diesel_heater_ble_ns.class_("TempDownButton", button.Button), icon="mdi:arrow-down", ), @@ -34,13 +34,13 @@ CONFIG_SCHEMA = cv.Schema( async def to_code(config): - parent = await cg.get_variable(config[CONF_HEATER_ID]) + parent = await cg.get_variable(config[CONF_DIESEL_HEATER_BLE]) for var in [ - CONF_LEVEL_UP_ID, - CONF_LEVEL_DOWN_ID, - CONF_TEMP_UP_ID, - CONF_TEMP_DOWN_ID, + CONF_LEVEL_UP, + CONF_LEVEL_DOWN, + CONF_TEMP_UP, + CONF_TEMP_DOWN, ]: if conf := config.get(var): sw_var = await button.new_button(conf) diff --git a/esphome/components/diesel_heater_ble/controllers.h b/esphome/components/diesel_heater_ble/controllers.h index 21ca63a9af..52d921a75e 100644 --- a/esphome/components/diesel_heater_ble/controllers.h +++ b/esphome/components/diesel_heater_ble/controllers.h @@ -9,121 +9,104 @@ namespace esphome { namespace diesel_heater_ble { class HeaterController { -public: - virtual std::vector gen_power_command(HeaterState state, bool power) = 0; - virtual std::vector gen_level_command(HeaterState state, uint8_t value) = 0; - virtual std::vector gen_level_up_command(HeaterState state) = 0; - virtual std::vector gen_level_down_command(HeaterState state) = 0; - virtual std::vector gen_temp_command(HeaterState state, uint8_t value) = 0; - virtual std::vector gen_temp_up_command(HeaterState state) = 0; - virtual std::vector gen_temp_down_command(HeaterState state) = 0; - virtual std::vector get_manual_mode_command(HeaterState state) = 0; - virtual std::vector get_auto_mode_command(HeaterState state) = 0; + public: + virtual std::vector gen_power_command(HeaterState state, bool power) = 0; + virtual std::vector gen_level_command(HeaterState state, uint8_t value) = 0; + virtual std::vector gen_level_up_command(HeaterState state) = 0; + virtual std::vector gen_level_down_command(HeaterState state) = 0; + virtual std::vector gen_temp_command(HeaterState state, uint8_t value) = 0; + virtual std::vector gen_temp_up_command(HeaterState state) = 0; + virtual std::vector gen_temp_down_command(HeaterState state) = 0; + virtual std::vector get_manual_mode_command(HeaterState state) = 0; + virtual std::vector get_auto_mode_command(HeaterState state) = 0; }; -class HeaterController_AA55_E : public HeaterController { -private: - std::vector change_mode_command(HeaterState state, uint8_t target_mode) { - std::vector requests; - if (state.runningmode != target_mode) { - requests.push_back(Request(0x02, target_mode, 0x00)); - } - return requests; +class HeaterControllerAA55E : public HeaterController { + public: + std::vector change_mode_command(HeaterState state, uint8_t target_mode) { + std::vector requests; + if (state.runningmode != target_mode) { + requests.emplace_back(Request(0x02, target_mode, 0x00)); } + return requests; + } - void debug_request(std::vector requests) { - for (const auto &request : requests) { - ESP_LOGI("", "Request: %s", format_hex_pretty(request.toBytes()).c_str()); - } + public: + std::vector gen_power_command(HeaterState state, bool power) override { + std::vector requests; + if (state.runningstate != power) { + requests.push_back(Request(0x03, power ? 0x01 : 0x00, 0x00)); } + return requests; + } -public: - std::vector gen_power_command(HeaterState state, bool power) override { - std::vector requests; - if (state.runningstate != power) { - requests.push_back(Request(0x03, power ? 0x01 : 0x00, 0x00)); - } - this->debug_request(requests); - return requests; + std::vector gen_level_command(HeaterState state, uint8_t value) override { + auto requests = get_manual_mode_command(state); + if (state.setlevel != value) { + requests.push_back(Request(0x04, value, 0x00)); } + return requests; + } - std::vector gen_level_command(HeaterState state, uint8_t value) override { - auto requests = get_manual_mode_command(state); - if (state.setlevel != value) { - requests.push_back(Request(0x04, value, 0x00)); - } - this->debug_request(requests); - return requests; + std::vector gen_level_up_command(HeaterState state) override { + auto requests = get_manual_mode_command(state); + if (state.setlevel <= 9) { + requests.push_back(Request(0x04, state.setlevel + 1, 0x00)); } + return requests; + } - std::vector gen_level_up_command(HeaterState state) override { - auto requests = get_manual_mode_command(state); - if (state.setlevel <= 9) { - requests.push_back(Request(0x04, state.setlevel + 1, 0x00)); - } - this->debug_request(requests); - return requests; + std::vector gen_level_down_command(HeaterState state) override { + auto requests = get_manual_mode_command(state); + if (state.setlevel > 1) { + requests.push_back(Request(0x04, state.setlevel - 1, 0x00)); } + return requests; + } - std::vector gen_level_down_command(HeaterState state) override { - auto requests = get_manual_mode_command(state); - if (state.setlevel > 1) { - requests.push_back(Request(0x04, state.setlevel - 1, 0x00)); - } - this->debug_request(requests); - return requests; + std::vector gen_temp_command(HeaterState state, uint8_t value) override { + auto requests = get_auto_mode_command(state); + if (state.settemp != value) { + requests.push_back(Request(0x04, value, 0x00)); } + return requests; + } - std::vector gen_temp_command(HeaterState state, uint8_t value) override { - auto requests = get_auto_mode_command(state); - if (state.settemp != value) { - requests.push_back(Request(0x04, value, 0x00)); - } - this->debug_request(requests); - return requests; + std::vector gen_temp_up_command(HeaterState state) override { + auto requests = get_auto_mode_command(state); + if (state.tempunit == 0x00 && state.settemp < 36) { + requests.push_back(Request(0x04, state.settemp + 1, 0x00)); + } else if (state.tempunit == 0x01 && state.settemp < 97) { + requests.push_back(Request(0x04, state.settemp + 1, 0x00)); } + return requests; + } - std::vector gen_temp_up_command(HeaterState state) override { - auto requests = get_auto_mode_command(state); - if (state.tempunit == 0x00 && state.settemp < 36) { - requests.push_back(Request(0x04, state.settemp + 1, 0x00)); - } else if (state.tempunit == 0x01 && state.settemp < 97) { - requests.push_back(Request(0x04, state.settemp + 1, 0x00)); - } - this->debug_request(requests); - return requests; + std::vector gen_temp_down_command(HeaterState state) override { + auto requests = get_auto_mode_command(state); + if (state.tempunit == 0x00 && state.settemp > 8) { + requests.push_back(Request(0x04, state.settemp - 1, 0x00)); + } else if (state.tempunit == 0x01 && state.settemp > 46) { + requests.push_back(Request(0x04, state.settemp - 1, 0x00)); } + return requests; + } - std::vector gen_temp_down_command(HeaterState state) override { - auto requests = get_auto_mode_command(state); - if (state.tempunit == 0x00 && state.settemp > 8) { - requests.push_back(Request(0x04, state.settemp - 1, 0x00)); - } else if (state.tempunit == 0x01 && state.settemp > 46) { - requests.push_back(Request(0x04, state.settemp - 1, 0x00)); - } - this->debug_request(requests); - return requests; - } + std::vector get_manual_mode_command(HeaterState state) override { return change_mode_command(state, 0x01); } - std::vector get_manual_mode_command(HeaterState state) override { - return change_mode_command(state, 0x01); - } - - std::vector get_auto_mode_command(HeaterState state) override { - return change_mode_command(state, 0x02); - } + std::vector get_auto_mode_command(HeaterState state) override { return change_mode_command(state, 0x02); } }; class ControllerSelector { -public: - static HeaterController *get_controller(HeaterClass heater_class) { - switch (heater_class) { - case HeaterClass::HEATER_AA_55_ENCRYPTED: - return new HeaterController_AA55_E(); - default: - return nullptr; - } + public: + static HeaterController *get_controller(HeaterClass heater_class) { + switch (heater_class) { + case HeaterClass::HEATER_AA_55_ENCRYPTED: + return new HeaterControllerAA55E(); + default: + return nullptr; } + } }; } // namespace diesel_heater_ble diff --git a/esphome/components/diesel_heater_ble/heater.cpp b/esphome/components/diesel_heater_ble/heater.cpp index 35aa392dbe..8e6bd06a41 100644 --- a/esphome/components/diesel_heater_ble/heater.cpp +++ b/esphome/components/diesel_heater_ble/heater.cpp @@ -12,13 +12,15 @@ void DieselHeaterBLE::loop() { if (this->last_request_ + 1000 < millis()) { this->last_request_ = millis(); uint8_t data[8] = {0xaa, 0x55, 0x0c, 0x22, 0x01, 0x00, 0x00, 0x2f}; - this->ble_write_chr(this->parent()->get_gattc_if(), this->parent()->get_remote_bda(), this->handle_, data, sizeof(data)); + this->ble_write_chr(this->parent()->get_gattc_if(), this->parent()->get_remote_bda(), this->handle_, data, + sizeof(data)); } this->update_sensors(this->state_); } } -void DieselHeaterBLE::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param) { +void DieselHeaterBLE::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, + esp_ble_gattc_cb_param_t *param) { switch (event) { case ESP_GATTC_OPEN_EVT: ESP_LOGD(TAG, "GATT client opened."); @@ -47,7 +49,8 @@ void DieselHeaterBLE::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_i break; case ESP_GATTC_NOTIFY_EVT: - if (param->notify.conn_id != this->parent()->get_conn_id()) break; + if (param->notify.conn_id != this->parent()->get_conn_id()) + break; if (param->notify.handle == this->handle_) { std::vector data(param->notify.value, param->notify.value + param->notify.value_len); this->on_notification_received(data); @@ -64,8 +67,10 @@ void DieselHeaterBLE::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_i } } -bool DieselHeaterBLE::ble_write_chr(esp_gatt_if_t gattc_if, esp_bd_addr_t remote_bda, uint16_t handle, uint8_t *data, uint16_t len) { - esp_err_t ret = esp_ble_gattc_write_char(gattc_if, 0, handle, len, data, ESP_GATT_WRITE_TYPE_RSP, ESP_GATT_AUTH_REQ_NONE); +bool DieselHeaterBLE::ble_write_chr(esp_gatt_if_t gattc_if, esp_bd_addr_t remote_bda, uint16_t handle, uint8_t *data, + uint16_t len) { + esp_err_t ret = + esp_ble_gattc_write_char(gattc_if, 0, handle, len, data, ESP_GATT_WRITE_TYPE_RSP, ESP_GATT_AUTH_REQ_NONE); if (ret != ESP_OK) { ESP_LOGD(TAG, "Write characteristic failed, status: %d", ret); return false; @@ -115,7 +120,6 @@ void DieselHeaterBLE::on_notification_received(const std::vector &data) } } - void DieselHeaterBLE::update_sensors(const HeaterState &new_state) { if (running_state_ != nullptr && running_state_->state != new_state.runningstate) { if (this->power_switch_ != nullptr) { @@ -221,45 +225,31 @@ void DieselHeaterBLE::update_sensors(const HeaterState &new_state) { } void DieselHeaterBLE::on_power_level_number(float value) { - this->sent_requests( - this->controller_->gen_level_command(this->state_, value) - ); + this->sent_requests(this->controller_->gen_level_command(this->state_, value)); } - + void DieselHeaterBLE::on_temp_number(float value) { - this->sent_requests( - this->controller_->gen_temp_command(this->state_, value) - ); + this->sent_requests(this->controller_->gen_temp_command(this->state_, value)); } void DieselHeaterBLE::on_power_switch(bool state) { - this->sent_requests( - this->controller_->gen_power_command(this->state_, state) - ); + this->sent_requests(this->controller_->gen_power_command(this->state_, state)); } void DieselHeaterBLE::on_level_up_button_press() { - this->sent_requests( - this->controller_->gen_level_up_command(this->state_) - ); + this->sent_requests(this->controller_->gen_level_up_command(this->state_)); } void DieselHeaterBLE::on_level_down_button_press() { - this->sent_requests( - this->controller_->gen_level_down_command(this->state_) - ); + this->sent_requests(this->controller_->gen_level_down_command(this->state_)); } void DieselHeaterBLE::on_temp_up_button_press() { - this->sent_requests( - this->controller_->gen_temp_up_command(this->state_) - ); + this->sent_requests(this->controller_->gen_temp_up_command(this->state_)); } void DieselHeaterBLE::on_temp_down_button_press() { - this->sent_requests( - this->controller_->gen_temp_down_command(this->state_) - ); + this->sent_requests(this->controller_->gen_temp_down_command(this->state_)); } } // namespace diesel_heater_ble diff --git a/esphome/components/diesel_heater_ble/heater.h b/esphome/components/diesel_heater_ble/heater.h index f08e293e26..2c027aafea 100644 --- a/esphome/components/diesel_heater_ble/heater.h +++ b/esphome/components/diesel_heater_ble/heater.h @@ -21,7 +21,6 @@ namespace esphome { namespace diesel_heater_ble { - class DieselHeaterBLE : public Component, public ble_client::BLEClientNode { public: DieselHeaterBLE() = default; @@ -32,7 +31,8 @@ class DieselHeaterBLE : public Component, public ble_client::BLEClientNode { void sent_request(const std::vector &data) { std::vector data_(data); - this->ble_write_chr(this->parent()->get_gattc_if(), this->parent()->get_remote_bda(), this->handle_, data_.data(), data.size()); + this->ble_write_chr(this->parent()->get_gattc_if(), this->parent()->get_remote_bda(), this->handle_, data_.data(), + data.size()); } void sent_requests(const std::vector &requests) { @@ -71,13 +71,13 @@ class DieselHeaterBLE : public Component, public ble_client::BLEClientNode { void set_temp_unit(sensor::Sensor *sensor) { temp_unit_ = sensor; } void set_altitude_unit(sensor::Sensor *sensor) { altitude_unit_ = sensor; } void set_automatic_heating(sensor::Sensor *sensor) { automatic_heating_ = sensor; } - + // Button setters void set_level_up_button(button::Button *button) { level_up_button_ = button; } void set_level_down_button(button::Button *button) { level_down_button_ = button; } void set_temp_up_button(button::Button *button) { temp_up_button_ = button; } void set_temp_down_button(button::Button *button) { temp_down_button_ = button; } - + void on_level_up_button_press(); void on_level_down_button_press(); void on_temp_up_button_press(); @@ -86,7 +86,7 @@ class DieselHeaterBLE : public Component, public ble_client::BLEClientNode { // Number setters void set_power_level_number(number::Number *number) { power_level_number_ = number; } void on_power_level_number(float value); - + void set_set_temp_number(number::Number *number) { set_temp_number_ = number; } void on_temp_number(float value); @@ -94,19 +94,18 @@ class DieselHeaterBLE : public Component, public ble_client::BLEClientNode { void set_power_switch(switch_::Switch *sw) { power_switch_ = sw; } void on_power_switch(bool state); - - HeaterState get_state() { - return this->state_; - } + HeaterState get_state() { return this->state_; } protected: uint16_t handle_{0}; - esp32_ble_tracker::ESPBTUUID service_uuid_ = esp32_ble_tracker::ESPBTUUID::from_raw("0000ffe0-0000-1000-8000-00805f9b34fb"); - esp32_ble_tracker::ESPBTUUID characteristic_uuid_ = esp32_ble_tracker::ESPBTUUID::from_raw("0000ffe1-0000-1000-8000-00805f9b34fb"); + esp32_ble_tracker::ESPBTUUID service_uuid_ = + esp32_ble_tracker::ESPBTUUID::from_raw("0000ffe0-0000-1000-8000-00805f9b34fb"); + esp32_ble_tracker::ESPBTUUID characteristic_uuid_ = + esp32_ble_tracker::ESPBTUUID::from_raw("0000ffe1-0000-1000-8000-00805f9b34fb"); HeaterState state_; HeaterController *controller_{}; - + bool response_received_{false}; uint32_t last_request_{0}; uint32_t last_update_{0}; diff --git a/esphome/components/diesel_heater_ble/messages.h b/esphome/components/diesel_heater_ble/messages.h index d3e04e3ad0..f5d71bd621 100644 --- a/esphome/components/diesel_heater_ble/messages.h +++ b/esphome/components/diesel_heater_ble/messages.h @@ -6,221 +6,212 @@ #include #include "state.h" - namespace esphome { namespace diesel_heater_ble { class ResponseParser { -public: - static std::vector decrypt(const std::vector &raw) { - // decrypt only if raw data starts with [0xDA, 0x07] - if (raw[0] == 0xAA) { - return raw; - } - - std::vector decrypted = raw; - for (size_t i = 0; i < 48; i += 8) { - decrypted[i] ^= 112; // "p" in ASCII - decrypted[i + 1] ^= 97; // "a" in ASCII - decrypted[i + 2] ^= 115; // "s" in ASCII - decrypted[i + 3] ^= 115; // "s" in ASCII - decrypted[i + 4] ^= 119; // "w" in ASCII - decrypted[i + 5] ^= 111; // "o" in ASCII - decrypted[i + 6] ^= 114; // "r" in ASCII - decrypted[i + 7] ^= 100; // "d" in ASCII - } - return decrypted; + public: + static std::vector decrypt(const std::vector &raw) { + // decrypt only if raw data starts with [0xDA, 0x07] + if (raw[0] == 0xAA) { + return raw; } - static HeaterClass detect_heater_class(const std::vector &raw) { - switch (raw[1]) { - case 0x55: - return HeaterClass::HEATER_AA_55; - case 0x66: - return HeaterClass::HEATER_AA_66; - case 0x07: - return HeaterClass::HEATER_AA_55_ENCRYPTED; - default: - return HeaterClass::HEATER_CLASS_UNKNOWN; - } + std::vector decrypted = raw; + for (size_t i = 0; i < 48; i += 8) { + decrypted[i] ^= 112; // "p" in ASCII + decrypted[i + 1] ^= 97; // "a" in ASCII + decrypted[i + 2] ^= 115; // "s" in ASCII + decrypted[i + 3] ^= 115; // "s" in ASCII + decrypted[i + 4] ^= 119; // "w" in ASCII + decrypted[i + 5] ^= 111; // "o" in ASCII + decrypted[i + 6] ^= 114; // "r" in ASCII + decrypted[i + 7] ^= 100; // "d" in ASCII + } + return decrypted; + } + + static HeaterClass detect_heater_class(const std::vector &raw) { + switch (raw[1]) { + case 0x55: + return HeaterClass::HEATER_AA_55; + case 0x66: + return HeaterClass::HEATER_AA_66; + case 0x07: + return HeaterClass::HEATER_AA_55_ENCRYPTED; + default: + return HeaterClass::HEATER_CLASS_UNKNOWN; + } + } + + static bool parse(const std::vector &raw, HeaterState &state) { + HeaterClass heater_class = detect_heater_class(raw); + if (heater_class == HeaterClass::HEATER_CLASS_UNKNOWN) + return false; + + std::vector decrypted = decrypt(raw); + + state.heater_class = heater_class; + state.rcv_cmd = decrypted[2]; + state.runningstate = decrypted[3]; + + if (heater_class == HeaterClass::HEATER_AA_55 || heater_class == HeaterClass::HEATER_AA_55_ENCRYPTED) { + state.errcode = decrypted[4]; + } else if (heater_class == HeaterClass::HEATER_AA_66) { + state.errcode = decrypted[17]; + } else if (heater_class == HeaterClass::HEATER_AA_66_ENCRYPTED) { + state.errcode = decrypted[35]; } - static bool parse(const std::vector &raw, HeaterState &state) { - HeaterClass heater_class = detect_heater_class(raw); - if (heater_class == HeaterClass::HEATER_CLASS_UNKNOWN) return false; - - std::vector decrypted = decrypt(raw); - - state.heater_class = heater_class; - state.rcv_cmd = decrypted[2]; - state.runningstate = decrypted[3]; - - if (heater_class == HeaterClass::HEATER_AA_55 || heater_class == HeaterClass::HEATER_AA_55_ENCRYPTED) { - state.errcode = decrypted[4]; - } else if (heater_class == HeaterClass::HEATER_AA_66) { - state.errcode = decrypted[17]; - } else if (heater_class == HeaterClass::HEATER_AA_66_ENCRYPTED) { - state.errcode = decrypted[35]; - } - - state.runningstep = decrypted[5]; - if (heater_class == HeaterClass::HEATER_AA_55 || heater_class == HeaterClass::HEATER_AA_66 ) { - state.altitude = decrypted[6] + (decrypted[7] << 8); - } else if (heater_class == HeaterClass::HEATER_AA_55_ENCRYPTED || heater_class == HeaterClass::HEATER_AA_66_ENCRYPTED) { - state.altitude = (decrypted[7] + (decrypted[6] << 8)) / 10; - } - - state.runningmode = decrypted[8]; - - if (heater_class == HeaterClass::HEATER_AA_55 || heater_class == HeaterClass::HEATER_AA_66 ) { - if (state.runningmode == 0x00) { - state.setlevel = decrypted[10] + 1; - } else if (state.runningmode == 0x01) { - state.setlevel = decrypted[9]; - } else if (state.runningmode == 0x02) { - state.settemp = decrypted[9]; - state.setlevel = decrypted[10] + 1; - } - } else if (heater_class == HeaterClass::HEATER_AA_55_ENCRYPTED || heater_class == HeaterClass::HEATER_AA_66_ENCRYPTED) { - state.setlevel = decrypted[10]; - state.settemp = decrypted[9]; - } - - if (heater_class == HeaterClass::HEATER_AA_55 || heater_class == HeaterClass::HEATER_AA_66 ) { - state.supplyvoltage = (decrypted[11] + (decrypted[12] << 8)) / 10; - } else if (heater_class == HeaterClass::HEATER_AA_55_ENCRYPTED || heater_class == HeaterClass::HEATER_AA_66_ENCRYPTED) { - state.supplyvoltage = (decrypted[12] + (decrypted[11] << 8)) / 10; - } - - if (heater_class == HeaterClass::HEATER_AA_55 || heater_class == HeaterClass::HEATER_AA_66 ) { - state.casetemp = (decrypted[13] + (decrypted[14] << 8)); - state.cabtemp = (decrypted[15] + (decrypted[16] << 8)); - } else if (heater_class == HeaterClass::HEATER_AA_55_ENCRYPTED || heater_class == HeaterClass::HEATER_AA_66_ENCRYPTED) { - state.casetemp = (decrypted[14] + (decrypted[13] << 8)); - state.cabtemp = (decrypted[33] + (decrypted[32] << 8)) / 10; - } - - // encrypted types only - if (heater_class == HeaterClass::HEATER_AA_55_ENCRYPTED || heater_class == HeaterClass::HEATER_AA_66_ENCRYPTED) { - state.sttime = decrypted[20] + (decrypted[19] << 8); - state.autotime = decrypted[22] + (decrypted[21] << 8); - state.runtime = decrypted[24] + (decrypted[23] << 8); - state.isauto = decrypted[25]; - state.language = decrypted[26]; - state.tempoffset = decrypted[34]; - state.tankvolume = decrypted[28]; - state.oilpumptype = decrypted[29]; - if (raw[29] == 20) { - state.rf433onoff = false; - } else if (raw[29] == 21) { - state.rf433onoff = true; - } - state.tempunit = decrypted[27]; - state.altiunit = decrypted[30]; - state.automaticheating = decrypted[31]; - } - - return true; + state.runningstep = decrypted[5]; + if (heater_class == HeaterClass::HEATER_AA_55 || heater_class == HeaterClass::HEATER_AA_66) { + state.altitude = decrypted[6] + (decrypted[7] << 8); + } else if (heater_class == HeaterClass::HEATER_AA_55_ENCRYPTED || + heater_class == HeaterClass::HEATER_AA_66_ENCRYPTED) { + state.altitude = (decrypted[7] + (decrypted[6] << 8)) / 10; } + + state.runningmode = decrypted[8]; + + if (heater_class == HeaterClass::HEATER_AA_55 || heater_class == HeaterClass::HEATER_AA_66) { + if (state.runningmode == 0x00) { + state.setlevel = decrypted[10] + 1; + } else if (state.runningmode == 0x01) { + state.setlevel = decrypted[9]; + } else if (state.runningmode == 0x02) { + state.settemp = decrypted[9]; + state.setlevel = decrypted[10] + 1; + } + } else if (heater_class == HeaterClass::HEATER_AA_55_ENCRYPTED || + heater_class == HeaterClass::HEATER_AA_66_ENCRYPTED) { + state.setlevel = decrypted[10]; + state.settemp = decrypted[9]; + } + + if (heater_class == HeaterClass::HEATER_AA_55 || heater_class == HeaterClass::HEATER_AA_66) { + state.supplyvoltage = (decrypted[11] + (decrypted[12] << 8)) / 10; + } else if (heater_class == HeaterClass::HEATER_AA_55_ENCRYPTED || + heater_class == HeaterClass::HEATER_AA_66_ENCRYPTED) { + state.supplyvoltage = (decrypted[12] + (decrypted[11] << 8)) / 10; + } + + if (heater_class == HeaterClass::HEATER_AA_55 || heater_class == HeaterClass::HEATER_AA_66) { + state.casetemp = (decrypted[13] + (decrypted[14] << 8)); + state.cabtemp = (decrypted[15] + (decrypted[16] << 8)); + } else if (heater_class == HeaterClass::HEATER_AA_55_ENCRYPTED || + heater_class == HeaterClass::HEATER_AA_66_ENCRYPTED) { + state.casetemp = (decrypted[14] + (decrypted[13] << 8)); + state.cabtemp = (decrypted[33] + (decrypted[32] << 8)) / 10; + } + + // encrypted types only + if (heater_class == HeaterClass::HEATER_AA_55_ENCRYPTED || heater_class == HeaterClass::HEATER_AA_66_ENCRYPTED) { + state.sttime = decrypted[20] + (decrypted[19] << 8); + state.autotime = decrypted[22] + (decrypted[21] << 8); + state.runtime = decrypted[24] + (decrypted[23] << 8); + state.isauto = decrypted[25]; + state.language = decrypted[26]; + state.tempoffset = decrypted[34]; + state.tankvolume = decrypted[28]; + state.oilpumptype = decrypted[29]; + if (raw[29] == 20) { + state.rf433onoff = false; + } else if (raw[29] == 21) { + state.rf433onoff = true; + } + state.tempunit = decrypted[27]; + state.altiunit = decrypted[30]; + state.automaticheating = decrypted[31]; + } + + return true; + } }; class Request { -public: - uint8_t header_1 = 0xAA; - uint8_t header_2 = 0x55; - uint8_t password_1 = 0x0C; - uint8_t password_2 = 0x22; - uint8_t command; - uint8_t data_1; - uint8_t data_2; - uint8_t checksum; + public: + uint8_t header_1 = 0xAA; + uint8_t header_2 = 0x55; + uint8_t password_1 = 0x0C; + uint8_t password_2 = 0x22; + uint8_t command; + uint8_t data_1; + uint8_t data_2; + uint8_t checksum; - Request(uint8_t command, uint8_t data1 = 0x00, uint8_t data2 = 0x00) - : command(command), data_1(data1), data_2(data2) { - calculateChecksum(); - } + Request(uint8_t command, uint8_t data1 = 0x00, uint8_t data2 = 0x00) + : command(command), data_1(data1), data_2(data2) { + calculateChecksum(); + } - void calculateChecksum() { - checksum = (password_1 + password_2 + command + data_1 + data_2) % 256; - } + void calculateChecksum() { checksum = (password_1 + password_2 + command + data_1 + data_2) % 256; } - std::vector toBytes() const { - return {header_1, header_2, password_1, password_2, command, data_1, data_2, checksum}; - } + std::vector toBytes() const { + return {header_1, header_2, password_1, password_2, command, data_1, data_2, checksum}; + } }; // Specific Requests class StatusRequest : public Request { -public: - StatusRequest() : Request(0x01) {} + public: + StatusRequest() : Request(0x01) {} }; class SetPowerRequest : public Request { -public: - SetPowerRequest(bool enable) - : Request(0x03, enable ? 0x01: 0x00, 0x00) {} + public: + SetPowerRequest(bool enable) : Request(0x03, enable ? 0x01 : 0x00, 0x00) {} }; class SetTemperatureRequest : public Request { -public: - SetTemperatureRequest(uint8_t temperature) - : Request(0x04, temperature, 0x00) {} + public: + SetTemperatureRequest(uint8_t temperature) : Request(0x04, temperature, 0x00) {} }; class SetLevelRequest : public Request { -public: - SetLevelRequest(uint8_t level) - : Request(0x04, level - 1, 0x00) {} + public: + SetLevelRequest(uint8_t level) : Request(0x04, level - 1, 0x00) {} }; class SetRunningModeRequest : public Request { -public: - SetRunningModeRequest(uint8_t mode) - : Request(0x02, mode, 0x00) {} + public: + SetRunningModeRequest(uint8_t mode) : Request(0x02, mode, 0x00) {} }; class SetAutomaticStartStopRequest : public Request { -public: - SetAutomaticStartStopRequest(bool enable) - : Request(0x13, enable ? 0x01 : 0x00, 0x00) {} + public: + SetAutomaticStartStopRequest(bool enable) : Request(0x13, enable ? 0x01 : 0x00, 0x00) {} }; class SetLanguageRequest : public Request { -public: - SetLanguageRequest(uint8_t languageCode) - : Request(0x14, languageCode, 0x00) {} + public: + SetLanguageRequest(uint8_t language_code) : Request(0x14, language_code, 0x00) {} }; class SetTemperatureUnitRequest : public Request { -public: - SetTemperatureUnitRequest(bool isCelsius) - : Request(0x15, isCelsius ? 0x01 : 0x00, 0x00) {} + public: + SetTemperatureUnitRequest(bool is_celsius) : Request(0x15, is_celsius ? 0x01 : 0x00, 0x00) {} }; class SetAltitudeUnitRequest : public Request { -public: - SetAltitudeUnitRequest(bool isMeters) - : Request(0x16, isMeters ? 0x01 : 0x00, 0x00) {} + public: + SetAltitudeUnitRequest(bool is_meters) : Request(0x16, is_meters ? 0x01 : 0x00, 0x00) {} }; class SetTankVolumeRequest : public Request { -public: - SetTankVolumeRequest(uint8_t volume) - : Request(0x17, volume, 0x00) {} + public: + SetTankVolumeRequest(uint8_t volume) : Request(0x17, volume, 0x00) {} }; class SetOilPumpTypeRequest : public Request { -public: - SetOilPumpTypeRequest(uint8_t type) - : Request(0x18, type, 0x00) {} + public: + SetOilPumpTypeRequest(uint8_t type) : Request(0x18, type, 0x00) {} }; class SetTemperatureOffsetRequest : public Request { -public: - SetTemperatureOffsetRequest(uint8_t offset) - : Request(0x20, offset, 0x00) {} + public: + SetTemperatureOffsetRequest(uint8_t offset) : Request(0x20, offset, 0x00) {} }; -} // namespace diesel_heater_ble -} // namespace esphome \ No newline at end of file +} // namespace diesel_heater_ble +} // namespace esphome diff --git a/esphome/components/diesel_heater_ble/number.h b/esphome/components/diesel_heater_ble/number.h index b43aff7618..a3e4c0ac5e 100644 --- a/esphome/components/diesel_heater_ble/number.h +++ b/esphome/components/diesel_heater_ble/number.h @@ -9,24 +9,20 @@ namespace esphome { namespace diesel_heater_ble { class PowerLevelNumber : public number::Number, public Parented { - public: + public: PowerLevelNumber() = default; - - protected: - void control(float value) override { - this->parent_->on_power_level_number(value); - } + + protected: + void control(float value) override { this->parent_->on_power_level_number(value); } }; class SetTempNumber : public number::Number, public Parented { - public: + public: SetTempNumber() = default; - - protected: - void control(float value) override { - this->parent_->on_temp_number(value); - } + + protected: + void control(float value) override { this->parent_->on_temp_number(value); } }; } // namespace diesel_heater_ble -} // namespace esphome \ No newline at end of file +} // namespace esphome diff --git a/esphome/components/diesel_heater_ble/sensor.py b/esphome/components/diesel_heater_ble/sensor.py index 94167355bd..71dbfae7c7 100644 --- a/esphome/components/diesel_heater_ble/sensor.py +++ b/esphome/components/diesel_heater_ble/sensor.py @@ -2,6 +2,8 @@ import esphome.codegen as cg from esphome.components import ble_client, sensor import esphome.config_validation as cv from esphome.const import ( + CONF_ALTITUDE, + CONF_SUPPLY_VOLTAGE, DEVICE_CLASS_EMPTY, DEVICE_CLASS_TEMPERATURE, STATE_CLASS_MEASUREMENT, @@ -12,7 +14,7 @@ from esphome.const import ( UNIT_VOLT, ) -from . import CONF_HEATER_ID, DieselHeaterBLE +from . import CONF_DIESEL_HEATER_BLE, DieselHeaterBLE CODEOWNERS = ["@warehog"] DEPENDENCIES = ["diesel_heater_ble"] @@ -22,11 +24,9 @@ AUTO_LOAD = ["sensor"] CONF_RUNNING_STATE = "running_state" CONF_ERROR_CODE = "error_code" CONF_RUNNING_STEP = "running_step" -CONF_ALTITUDE = "altitude" CONF_RUNNING_MODE = "running_mode" CONF_SET_LEVEL = "set_level" CONF_SET_TEMP = "set_temp" -CONF_SUPPLY_VOLTAGE = "supply_voltage" CONF_CASE_TEMP = "case_temp" CONF_CAB_TEMP = "cab_temp" CONF_START_TIME = "start_time" @@ -44,7 +44,7 @@ CONF_AUTOMATIC_HEATING = "automatic_heating" CONFIG_SCHEMA = cv.Schema( { - cv.GenerateID(CONF_HEATER_ID): cv.use_id(DieselHeaterBLE), + cv.GenerateID(CONF_DIESEL_HEATER_BLE): cv.use_id(DieselHeaterBLE), cv.Optional(CONF_RUNNING_STATE): sensor.sensor_schema( unit_of_measurement=UNIT_EMPTY, accuracy_decimals=1, @@ -182,7 +182,7 @@ CONFIG_SCHEMA = cv.Schema( async def to_code(config): - var = await cg.get_variable(config[CONF_HEATER_ID]) + var = await cg.get_variable(config[CONF_DIESEL_HEATER_BLE]) for sensor_name in [ CONF_RUNNING_STATE, diff --git a/esphome/components/diesel_heater_ble/state.h b/esphome/components/diesel_heater_ble/state.h index ce3591bdbc..2f269b7930 100644 --- a/esphome/components/diesel_heater_ble/state.h +++ b/esphome/components/diesel_heater_ble/state.h @@ -7,66 +7,97 @@ namespace esphome { namespace diesel_heater_ble { enum class HeaterClass { - HEATER_AA_55, // The one that sends responses with 0xAA 0x55 header - HEATER_AA_66, // The one that sends responses with 0xAA 0x66 header - HEATER_AA_55_ENCRYPTED, // The one that sends responses with 0xAA 0x55 header and encrypted data - HEATER_AA_66_ENCRYPTED, // The one that sends responses with 0xAA 0x66 header and encrypted data - HEATER_CLASS_UNKNOWN + HEATER_AA_55, // The one that sends responses with 0xAA 0x55 header + HEATER_AA_66, // The one that sends responses with 0xAA 0x66 header + HEATER_AA_55_ENCRYPTED, // The one that sends responses with 0xAA 0x55 header and encrypted data + HEATER_AA_66_ENCRYPTED, // The one that sends responses with 0xAA 0x66 header and encrypted data + HEATER_CLASS_UNKNOWN }; class HeaterState { - public: - HeaterClass heater_class; - uint8_t rcv_cmd; - uint8_t runningstate; - uint8_t errcode; - uint8_t runningstep; - uint16_t altitude; - uint8_t runningmode; - uint8_t setlevel; - uint8_t settemp; - uint16_t supplyvoltage; - uint16_t casetemp; - uint16_t cabtemp; + public: + HeaterClass heater_class; + uint8_t rcv_cmd; + uint8_t runningstate; + uint8_t errcode; + uint8_t runningstep; + uint16_t altitude; + uint8_t runningmode; + uint8_t setlevel; + uint8_t settemp; + uint16_t supplyvoltage; + uint16_t casetemp; + uint16_t cabtemp; - // encoded types only - uint16_t sttime; - uint16_t autotime; - uint16_t runtime; - uint8_t isauto; - uint8_t language; - uint8_t tempoffset; - uint8_t tankvolume; - uint8_t oilpumptype; - bool rf433onoff; - uint8_t tempunit; - uint8_t altiunit; - uint8_t automaticheating; - - // return table format of data with columnt names - std::string to_string() { - return "HeaterState: \n" - " heater_class: " + std::to_string(static_cast(heater_class)) + "\n" - " rcv_cmd: " + std::to_string(rcv_cmd) + "\n" - " runningstate: " + std::to_string(runningstate) + "\n" - " errcode: " + std::to_string(errcode) + "\n" - " runningstep: " + std::to_string(runningstep) + "\n" - " altitude: " + std::to_string(altitude) + "\n" - " runningmode: " + std::to_string(runningmode) + "\n" - " setlevel: " + std::to_string(setlevel) + "\n" - " settemp: " + std::to_string(settemp) + "\n" - " supplyvoltage: " + std::to_string(supplyvoltage) + "\n" - " casetemp: " + std::to_string(casetemp) + "\n" - " cabtemp: " + std::to_string(cabtemp) + "\n" - " sttime: " + std::to_string(sttime) + "\n" - " autotime: " + std::to_string(autotime) + "\n" - " runtime: " + std::to_string(runtime) + "\n" - " isauto: " + std::to_string(isauto) + "\n"; - } + // encoded types only + uint16_t sttime; + uint16_t autotime; + uint16_t runtime; + uint8_t isauto; + uint8_t language; + uint8_t tempoffset; + uint8_t tankvolume; + uint8_t oilpumptype; + bool rf433onoff; + uint8_t tempunit; + uint8_t altiunit; + uint8_t automaticheating; + + // return table format of data with columnt names + std::string to_string() { + return "HeaterState: \n" + " heater_class: " + + std::to_string(static_cast(heater_class)) + + "\n" + " rcv_cmd: " + + std::to_string(rcv_cmd) + + "\n" + " runningstate: " + + std::to_string(runningstate) + + "\n" + " errcode: " + + std::to_string(errcode) + + "\n" + " runningstep: " + + std::to_string(runningstep) + + "\n" + " altitude: " + + std::to_string(altitude) + + "\n" + " runningmode: " + + std::to_string(runningmode) + + "\n" + " setlevel: " + + std::to_string(setlevel) + + "\n" + " settemp: " + + std::to_string(settemp) + + "\n" + " supplyvoltage: " + + std::to_string(supplyvoltage) + + "\n" + " casetemp: " + + std::to_string(casetemp) + + "\n" + " cabtemp: " + + std::to_string(cabtemp) + + "\n" + " sttime: " + + std::to_string(sttime) + + "\n" + " autotime: " + + std::to_string(autotime) + + "\n" + " runtime: " + + std::to_string(runtime) + + "\n" + " isauto: " + + std::to_string(isauto) + "\n"; + } }; -} // namespace diesel_heater_ble -} // namespace esphome +} // namespace diesel_heater_ble +} // namespace esphome // // Represents the current system state // class HeaterState { diff --git a/esphome/components/diesel_heater_ble/switch.h b/esphome/components/diesel_heater_ble/switch.h index 7e0fd8c474..046636e7e0 100644 --- a/esphome/components/diesel_heater_ble/switch.h +++ b/esphome/components/diesel_heater_ble/switch.h @@ -13,10 +13,8 @@ class PowerSwitch : public switch_::Switch, public Parented { PowerSwitch() = default; protected: - void write_state(bool state) override { - this->parent_->on_power_switch(state); - } + void write_state(bool state) override { this->parent_->on_power_switch(state); } }; -} // namespace diesel_heater -} // namespace esphome \ No newline at end of file +} // namespace diesel_heater_ble +} // namespace esphome diff --git a/esphome/const.py b/esphome/const.py index bfb0167282..4abbd55d44 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -821,6 +821,7 @@ CONF_SUPPLEMENTAL_COOLING_ACTION = "supplemental_cooling_action" CONF_SUPPLEMENTAL_COOLING_DELTA = "supplemental_cooling_delta" CONF_SUPPLEMENTAL_HEATING_ACTION = "supplemental_heating_action" CONF_SUPPLEMENTAL_HEATING_DELTA = "supplemental_heating_delta" +CONF_SUPPLY_VOLTAGE = "supply_voltage" CONF_SUPPORTED_FAN_MODES = "supported_fan_modes" CONF_SUPPORTED_MODES = "supported_modes" CONF_SUPPORTED_PRESETS = "supported_presets"