ESPHome  2024.12.2
am43_sensor.cpp
Go to the documentation of this file.
1 #include "am43_sensor.h"
2 #include "esphome/core/hal.h"
3 #include "esphome/core/log.h"
4 
5 #ifdef USE_ESP32
6 
7 namespace esphome {
8 namespace am43 {
9 
10 static const char *const TAG = "am43";
11 
13  ESP_LOGCONFIG(TAG, "AM43");
14  LOG_SENSOR(" ", "Battery", this->battery_);
15  LOG_SENSOR(" ", "Illuminance", this->illuminance_);
16 }
17 
18 void Am43::setup() {
19  this->encoder_ = make_unique<Am43Encoder>();
20  this->decoder_ = make_unique<Am43Decoder>();
21  this->logged_in_ = false;
22  this->last_battery_update_ = 0;
23  this->current_sensor_ = 0;
24 }
25 
26 void Am43::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param) {
27  switch (event) {
28  case ESP_GATTC_OPEN_EVT: {
29  if (param->open.status == ESP_GATT_OK) {
30  this->logged_in_ = false;
31  }
32  break;
33  }
34  case ESP_GATTC_DISCONNECT_EVT: {
35  this->logged_in_ = false;
37  if (this->battery_ != nullptr)
38  this->battery_->publish_state(NAN);
39  if (this->illuminance_ != nullptr)
40  this->illuminance_->publish_state(NAN);
41  break;
42  }
43  case ESP_GATTC_SEARCH_CMPL_EVT: {
44  auto *chr = this->parent_->get_characteristic(AM43_SERVICE_UUID, AM43_CHARACTERISTIC_UUID);
45  if (chr == nullptr) {
46  if (this->parent_->get_characteristic(AM43_TUYA_SERVICE_UUID, AM43_TUYA_CHARACTERISTIC_UUID) != nullptr) {
47  ESP_LOGE(TAG, "[%s] Detected a Tuya AM43 which is not supported, sorry.",
48  this->parent_->address_str().c_str());
49  } else {
50  ESP_LOGE(TAG, "[%s] No control service found at device, not an AM43..?",
51  this->parent_->address_str().c_str());
52  }
53  break;
54  }
55  this->char_handle_ = chr->handle;
56  break;
57  }
58  case ESP_GATTC_REG_FOR_NOTIFY_EVT: {
59  this->node_state = espbt::ClientState::ESTABLISHED;
60  this->update();
61  break;
62  }
63  case ESP_GATTC_NOTIFY_EVT: {
64  if (param->notify.handle != this->char_handle_)
65  break;
66  this->decoder_->decode(param->notify.value, param->notify.value_len);
67 
68  if (this->battery_ != nullptr && this->decoder_->has_battery_level() &&
69  millis() - this->last_battery_update_ > 10000) {
70  this->battery_->publish_state(this->decoder_->battery_level_);
71  this->last_battery_update_ = millis();
72  }
73 
74  if (this->illuminance_ != nullptr && this->decoder_->has_light_level()) {
75  this->illuminance_->publish_state(this->decoder_->light_level_);
76  }
77 
78  if (this->current_sensor_ > 0) {
79  if (this->illuminance_ != nullptr) {
80  auto *packet = this->encoder_->get_light_level_request();
81  auto status = esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(),
82  this->char_handle_, packet->length, packet->data,
83  ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
84  if (status) {
85  ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str().c_str(),
86  status);
87  }
88  }
89  this->current_sensor_ = 0;
90  }
91  break;
92  }
93  default:
94  break;
95  }
96 }
97 
98 void Am43::update() {
99  if (this->node_state != espbt::ClientState::ESTABLISHED) {
100  ESP_LOGW(TAG, "[%s] Cannot poll, not connected", this->parent_->address_str().c_str());
101  return;
102  }
103  if (this->current_sensor_ == 0) {
104  if (this->battery_ != nullptr) {
105  auto *packet = this->encoder_->get_battery_level_request();
106  auto status =
107  esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(), this->char_handle_,
108  packet->length, packet->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
109  if (status) {
110  ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str().c_str(), status);
111  }
112  }
113  this->current_sensor_++;
114  }
115 }
116 
117 } // namespace am43
118 } // namespace esphome
119 
120 #endif
std::unique_ptr< Am43Decoder > decoder_
Definition: am43_sensor.h:32
void gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param) override
Definition: am43_sensor.cpp:26
uint32_t IRAM_ATTR HOT millis()
Definition: core.cpp:25
void publish_state(float state)
Publish a new state to the front-end.
Definition: sensor.cpp:39
uint8_t current_sensor_
Definition: am43_sensor.h:36
uint8_t last_battery_update_
Definition: am43_sensor.h:39
void update() override
Definition: am43_sensor.cpp:98
void dump_config() override
Definition: am43_sensor.cpp:12
uint8_t status
Definition: bl0942.h:74
sensor::Sensor * battery_
Definition: am43_sensor.h:34
sensor::Sensor * illuminance_
Definition: am43_sensor.h:35
BLECharacteristic * get_characteristic(espbt::ESPBTUUID service, espbt::ESPBTUUID chr)
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
void setup() override
Definition: am43_sensor.cpp:18
std::unique_ptr< Am43Encoder > encoder_
Definition: am43_sensor.h:31
uint16_t char_handle_
Definition: am43_sensor.h:30
espbt::ClientState node_state
Definition: ble_client.h:38