13#ifdef USE_BINARY_SENSOR
19 if (this->
time_ !=
nullptr)
36 ESP_GATT_AUTH_REQ_NONE);
37 if (
status != ESP_GATT_OK) {
47 LOG_UPDATE_INTERVAL(
this);
49 ESP_LOGCONFIG(TAG,
" Clock sync: %s", YESNO(this->
time_ !=
nullptr));
57#ifdef USE_BINARY_SENSOR
67 esp_ble_gattc_cb_param_t *param) {
69 case ESP_GATTC_DISCONNECT_EVT: {
70 ESP_LOGD(TAG,
"[%s] Disconnected: reason=%d", this->
parent_->
address_str(), param->disconnect.reason);
82 case ESP_GATTC_SEARCH_CMPL_EVT: {
83 const auto service_uuid = espbt::ESPBTUUID::from_raw(
"f4b827c3-e660-4bc8-bdf6-3c8e9b845e0d");
84 const auto oper_uuid = espbt::ESPBTUUID::from_raw(
"b9d6f678-bc0d-4a73-90c8-60b0f07301f1");
85 const auto state_uuid = espbt::ESPBTUUID::from_raw(
"438d3433-7e5a-459a-a8e4-66343fad2bb0");
86 const auto info_uuid = espbt::ESPBTUUID::from_raw(
"f5f56229-dd4f-480f-a829-9189269d8b37");
87 const auto clock_uuid = espbt::ESPBTUUID::from_raw(
"82788997-49e4-4533-b949-7ed433678044");
91 if (oper ==
nullptr ||
state ==
nullptr) {
92 ESP_LOGW(TAG,
"[%s] C_OPER or C_STATE characteristic not found, disconnecting", this->
parent_->
address_str());
103 this->
node_state = espbt::ClientState::ESTABLISHED;
113 ESP_LOGW(TAG,
"[%s] BLE pair request failed, disconnecting", this->
parent_->
address_str());
118 ESP_LOGW(TAG,
"[%s] BLE authentication timed out, disconnecting", this->
parent_->
address_str());
123 case ESP_GATTC_READ_CHAR_EVT: {
124 if (param->read.conn_id != this->parent_->get_conn_id()) {
127 const uint16_t
handle = param->read.handle;
130 this->
on_oper_(param->read.value, param->read.value_len);
133 this->
on_state_(param->read.value, param->read.value_len);
136 this->
on_info_(param->read.value, param->read.value_len);
148 if (param->read.status == ESP_GATT_INSUF_ENCRYPTION || param->read.status == ESP_GATT_INSUF_AUTHENTICATION) {
154 if (param->read.status != ESP_GATT_OK) {
155 ESP_LOGW(TAG,
"[%s] Read of handle 0x%x failed, status=%d", this->
parent_->
address_str(), param->read.handle,
163 if (event != ESP_GAP_BLE_AUTH_CMPL_EVT || !this->
parent_->
check_addr(param->ble_security.auth_cmpl.bd_addr) ||
164 this->node_state != espbt::ClientState::ESTABLISHED) {
167 if (!param->ble_security.auth_cmpl.success) {
169 ESP_LOGW(TAG,
"[%s] BLE authentication failed, reason=%d, disconnecting", this->
parent_->
address_str(),
170 param->ble_security.auth_cmpl.fail_reason);
180 ESP_LOGI(TAG,
"[%s] Encryption confirmed, device ready", this->
parent_->
address_str());
183 if (this->
time_ !=
nullptr)
186#ifdef USE_TEXT_SENSOR
194#ifdef USE_BINARY_SENSOR
204 if (sensor !=
nullptr)
205 sensor->publish_state(NAN);
208#ifdef USE_BINARY_SENSOR
220 this->
mode_ = data[0];
222 ESP_LOGD(TAG,
"[%s] C_OPER: mode=0x%02x, speed=0x%02x", this->
parent_->
address_str(), this->mode_, this->speed_);
223#ifdef ECOCOMFORT2_CHILD_COUNT
239 const float humidity =
encode_uint16(data[5], data[6]) / 100.0f;
241 ESP_LOGD(TAG,
"[%s] C_STATE: mode=0x%02x, speed=0x%02x, %.2f °C, %.2f %%, %u ppb, direction=%u",
243#ifdef USE_BINARY_SENSOR
265 const uint16_t field =
encode_uint16(data[0] & 0x0F, data[1]);
267 snprintf(version,
sizeof(version),
"%u.%u.%u", data[0] >> 4, field >> 6, field & 0x3F);
269#ifdef USE_TEXT_SENSOR
288 ESP_LOGD(TAG,
"[%s] Syncing clock to %04u-%02u-%02u %02u:%02u:%02u", this->
parent_->
address_str(), now.
year,
291 esp_ble_gattc_write_char(this->
parent_->
get_gattc_if(), this->parent_->get_conn_id(), this->char_handle_clock_,
292 sizeof(data), data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
293 if (
status != ESP_GATT_OK) {
307 esp_ble_gattc_write_char(this->
parent_->
get_gattc_if(), this->parent_->get_conn_id(), this->char_handle_oper_,
308 sizeof(data), data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
309 if (
status != ESP_GATT_OK) {
316#ifdef ECOCOMFORT2_CHILD_COUNT
BedjetMode mode
BedJet operating mode.
void status_set_warning()
bool cancel_timeout(const char *name)
Cancel a timeout function.
void set_timeout(const char *name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a const char* name.
void status_clear_warning()
void set_parent(T *parent)
Set the parent of this object.
void invalidate_state()
Clear the state — sets has_state() to false and fires callbacks with nullopt.
void publish_state(bool new_state)
Publish a new state to the front-end.
void publish_initial_state(bool new_state)
Publish the initial state, this will not make the callback manager send callbacks and is meant only f...
espbt::ClientState node_state
uint16_t char_handle_state_
binary_sensor::BinarySensor * boost_binary_sensor_
static constexpr uint32_t READBACK_DELAY_MS
sensor::Sensor * voc_sensor_
void read_char_(uint16_t handle)
static constexpr uint32_t AUTH_TIMEOUT_ID
bool is_ready() const
True once the link is established and paired.
void on_state_(const uint8_t *data, uint16_t len)
text_sensor::TextSensor * firmware_text_sensor_
void on_info_(const uint8_t *data, uint16_t len)
uint16_t char_handle_oper_
sensor::Sensor * temperature_sensor_
StaticVector< Ecocomfort2Client *, ECOCOMFORT2_CHILD_COUNT > children_
binary_sensor::BinarySensor * connected_binary_sensor_
time::RealTimeClock * time_
static constexpr uint32_t READBACK_TIMEOUT_ID
sensor::Sensor * direction_sensor_
void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) override
uint16_t char_handle_info_
void register_child(Ecocomfort2Client *obj)
bool read_ok_(const esp_ble_gattc_cb_param_t *param)
uint16_t char_handle_clock_
void write_oper(uint8_t mode, uint8_t speed)
Write C_OPER (mode byte, speed/flags byte) and read it back shortly after.
sensor::Sensor * humidity_sensor_
void dump_config() override
void gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param) override
void set_connected_(bool connected)
void on_oper_(const uint8_t *data, uint16_t len)
static constexpr uint32_t AUTH_TIMEOUT_MS
const char * address_str() const
BLECharacteristic * get_characteristic(espbt::ESPBTUUID service, espbt::ESPBTUUID chr)
void disconnect() override
bool check_addr(esp_bd_addr_t &addr)
void publish_state(float state)
Publish a new state to the front-end.
void publish_state(const std::string &state)
ESPTime now()
Get the time in the currently defined timezone.
void add_on_time_sync_callback(F &&callback)
ESPHOME_LOG_TAG(TAG, "ecocomfort2.fan")
constexpr uint16_t encode_uint16(uint8_t msb, uint8_t lsb)
Encode a 16-bit value given the most and least significant byte.
A more user-friendly version of struct tm from time.h.
uint8_t minute
minutes after the hour [0-59]
uint8_t second
seconds after the minute [0-60]
uint8_t hour
hours since midnight [0-23]
bool is_valid(bool check_day_of_week=true, bool check_day_of_year=true) const
Check if this ESPTime is valid (year >= 2019 and the requested fields are in range).
uint8_t day_of_month
day of the month [1-31]
uint8_t month
month; january=1 [1-12]
uint8_t day_of_week
day of the week; sunday=1 [1-7]
spi_device_handle_t handle