ESPHome  2024.3.1
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  this->logged_in_ = false;
30  break;
31  }
32  case ESP_GATTC_DISCONNECT_EVT: {
33  this->logged_in_ = false;
35  if (this->battery_ != nullptr)
36  this->battery_->publish_state(NAN);
37  if (this->illuminance_ != nullptr)
38  this->illuminance_->publish_state(NAN);
39  break;
40  }
41  case ESP_GATTC_SEARCH_CMPL_EVT: {
42  auto *chr = this->parent_->get_characteristic(AM43_SERVICE_UUID, AM43_CHARACTERISTIC_UUID);
43  if (chr == nullptr) {
44  if (this->parent_->get_characteristic(AM43_TUYA_SERVICE_UUID, AM43_TUYA_CHARACTERISTIC_UUID) != nullptr) {
45  ESP_LOGE(TAG, "[%s] Detected a Tuya AM43 which is not supported, sorry.",
46  this->parent_->address_str().c_str());
47  } else {
48  ESP_LOGE(TAG, "[%s] No control service found at device, not an AM43..?",
49  this->parent_->address_str().c_str());
50  }
51  break;
52  }
53  this->char_handle_ = chr->handle;
54  break;
55  }
56  case ESP_GATTC_REG_FOR_NOTIFY_EVT: {
57  this->node_state = espbt::ClientState::ESTABLISHED;
58  this->update();
59  break;
60  }
61  case ESP_GATTC_NOTIFY_EVT: {
62  if (param->notify.handle != this->char_handle_)
63  break;
64  this->decoder_->decode(param->notify.value, param->notify.value_len);
65 
66  if (this->battery_ != nullptr && this->decoder_->has_battery_level() &&
67  millis() - this->last_battery_update_ > 10000) {
68  this->battery_->publish_state(this->decoder_->battery_level_);
69  this->last_battery_update_ = millis();
70  }
71 
72  if (this->illuminance_ != nullptr && this->decoder_->has_light_level()) {
73  this->illuminance_->publish_state(this->decoder_->light_level_);
74  }
75 
76  if (this->current_sensor_ > 0) {
77  if (this->illuminance_ != nullptr) {
78  auto *packet = this->encoder_->get_light_level_request();
79  auto status = esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(),
80  this->char_handle_, packet->length, packet->data,
81  ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
82  if (status) {
83  ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str().c_str(),
84  status);
85  }
86  }
87  this->current_sensor_ = 0;
88  }
89  break;
90  }
91  default:
92  break;
93  }
94 }
95 
96 void Am43::update() {
97  if (this->node_state != espbt::ClientState::ESTABLISHED) {
98  ESP_LOGW(TAG, "[%s] Cannot poll, not connected", this->parent_->address_str().c_str());
99  return;
100  }
101  if (this->current_sensor_ == 0) {
102  if (this->battery_ != nullptr) {
103  auto *packet = this->encoder_->get_battery_level_request();
104  auto status =
105  esp_ble_gattc_write_char(this->parent_->get_gattc_if(), this->parent_->get_conn_id(), this->char_handle_,
106  packet->length, packet->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
107  if (status) {
108  ESP_LOGW(TAG, "[%s] esp_ble_gattc_write_char failed, status=%d", this->parent_->address_str().c_str(), status);
109  }
110  }
111  this->current_sensor_++;
112  }
113 }
114 
115 } // namespace am43
116 } // namespace esphome
117 
118 #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:96
void dump_config() override
Definition: am43_sensor.cpp:12
uint8_t status
Definition: bl0942.h:23
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)
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
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