1
0
mirror of https://github.com/esphome/esphome.git synced 2025-03-13 14:18:14 +00:00

Apply ci-custom fixes

This commit is contained in:
Mateusz Wójcik 2025-01-07 16:37:59 +01:00
parent 50999e6492
commit e7be621cf0
12 changed files with 383 additions and 403 deletions

View File

@ -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_(

View File

@ -13,9 +13,7 @@ class LevelUpButton : public button::Button, public Parented<DieselHeaterBLE> {
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<DieselHeaterBLE> {
@ -23,9 +21,7 @@ class LevelDownButton : public button::Button, public Parented<DieselHeaterBLE>
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<DieselHeaterBLE> {
@ -33,9 +29,7 @@ class TempUpButton : public button::Button, public Parented<DieselHeaterBLE> {
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<DieselHeaterBLE> {
@ -43,11 +37,8 @@ class TempDownButton : public button::Button, public Parented<DieselHeaterBLE> {
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
} // namespace diesel_heater_ble
} // namespace esphome

View File

@ -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)

View File

@ -9,121 +9,104 @@ namespace esphome {
namespace diesel_heater_ble {
class HeaterController {
public:
virtual std::vector<Request> gen_power_command(HeaterState state, bool power) = 0;
virtual std::vector<Request> gen_level_command(HeaterState state, uint8_t value) = 0;
virtual std::vector<Request> gen_level_up_command(HeaterState state) = 0;
virtual std::vector<Request> gen_level_down_command(HeaterState state) = 0;
virtual std::vector<Request> gen_temp_command(HeaterState state, uint8_t value) = 0;
virtual std::vector<Request> gen_temp_up_command(HeaterState state) = 0;
virtual std::vector<Request> gen_temp_down_command(HeaterState state) = 0;
virtual std::vector<Request> get_manual_mode_command(HeaterState state) = 0;
virtual std::vector<Request> get_auto_mode_command(HeaterState state) = 0;
public:
virtual std::vector<Request> gen_power_command(HeaterState state, bool power) = 0;
virtual std::vector<Request> gen_level_command(HeaterState state, uint8_t value) = 0;
virtual std::vector<Request> gen_level_up_command(HeaterState state) = 0;
virtual std::vector<Request> gen_level_down_command(HeaterState state) = 0;
virtual std::vector<Request> gen_temp_command(HeaterState state, uint8_t value) = 0;
virtual std::vector<Request> gen_temp_up_command(HeaterState state) = 0;
virtual std::vector<Request> gen_temp_down_command(HeaterState state) = 0;
virtual std::vector<Request> get_manual_mode_command(HeaterState state) = 0;
virtual std::vector<Request> get_auto_mode_command(HeaterState state) = 0;
};
class HeaterController_AA55_E : public HeaterController {
private:
std::vector<Request> change_mode_command(HeaterState state, uint8_t target_mode) {
std::vector<Request> requests;
if (state.runningmode != target_mode) {
requests.push_back(Request(0x02, target_mode, 0x00));
}
return requests;
class HeaterControllerAA55E : public HeaterController {
public:
std::vector<Request> change_mode_command(HeaterState state, uint8_t target_mode) {
std::vector<Request> requests;
if (state.runningmode != target_mode) {
requests.emplace_back(Request(0x02, target_mode, 0x00));
}
return requests;
}
void debug_request(std::vector<Request> requests) {
for (const auto &request : requests) {
ESP_LOGI("", "Request: %s", format_hex_pretty(request.toBytes()).c_str());
}
public:
std::vector<Request> gen_power_command(HeaterState state, bool power) override {
std::vector<Request> requests;
if (state.runningstate != power) {
requests.push_back(Request(0x03, power ? 0x01 : 0x00, 0x00));
}
return requests;
}
public:
std::vector<Request> gen_power_command(HeaterState state, bool power) override {
std::vector<Request> requests;
if (state.runningstate != power) {
requests.push_back(Request(0x03, power ? 0x01 : 0x00, 0x00));
}
this->debug_request(requests);
return requests;
std::vector<Request> 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<Request> 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<Request> 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<Request> 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<Request> 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<Request> 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<Request> 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<Request> 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<Request> 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<Request> 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<Request> 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<Request> 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<Request> get_manual_mode_command(HeaterState state) override { return change_mode_command(state, 0x01); }
std::vector<Request> get_manual_mode_command(HeaterState state) override {
return change_mode_command(state, 0x01);
}
std::vector<Request> get_auto_mode_command(HeaterState state) override {
return change_mode_command(state, 0x02);
}
std::vector<Request> 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

View File

@ -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<uint8_t> 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<uint8_t> &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

View File

@ -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<uint8_t> &data) {
std::vector<uint8_t> 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<Request> &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};

View File

@ -6,221 +6,212 @@
#include <stdexcept>
#include "state.h"
namespace esphome {
namespace diesel_heater_ble {
class ResponseParser {
public:
static std::vector<uint8_t> decrypt(const std::vector<uint8_t> &raw) {
// decrypt only if raw data starts with [0xDA, 0x07]
if (raw[0] == 0xAA) {
return raw;
}
std::vector<uint8_t> 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<uint8_t> decrypt(const std::vector<uint8_t> &raw) {
// decrypt only if raw data starts with [0xDA, 0x07]
if (raw[0] == 0xAA) {
return raw;
}
static HeaterClass detect_heater_class(const std::vector<uint8_t> &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<uint8_t> 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<uint8_t> &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<uint8_t> &raw, HeaterState &state) {
HeaterClass heater_class = detect_heater_class(raw);
if (heater_class == HeaterClass::HEATER_CLASS_UNKNOWN)
return false;
std::vector<uint8_t> 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<uint8_t> &raw, HeaterState &state) {
HeaterClass heater_class = detect_heater_class(raw);
if (heater_class == HeaterClass::HEATER_CLASS_UNKNOWN) return false;
std::vector<uint8_t> 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<uint8_t> toBytes() const {
return {header_1, header_2, password_1, password_2, command, data_1, data_2, checksum};
}
std::vector<uint8_t> 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
} // namespace diesel_heater_ble
} // namespace esphome

View File

@ -9,24 +9,20 @@ namespace esphome {
namespace diesel_heater_ble {
class PowerLevelNumber : public number::Number, public Parented<DieselHeaterBLE> {
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<DieselHeaterBLE> {
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
} // namespace esphome

View File

@ -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,

View File

@ -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<int>(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<int>(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 {

View File

@ -13,10 +13,8 @@ class PowerSwitch : public switch_::Switch, public Parented<DieselHeaterBLE> {
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
} // namespace diesel_heater_ble
} // namespace esphome

View File

@ -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"