9 static const char *
const TAG =
"am43_cover";
14 LOG_COVER(
"",
"AM43 Cover",
this);
15 ESP_LOGCONFIG(TAG,
" Device Pin: %d", this->pin_);
16 ESP_LOGCONFIG(TAG,
" Invert Position: %d", (
int) this->invert_position_);
21 this->encoder_ = make_unique<Am43Encoder>();
22 this->decoder_ = make_unique<Am43Decoder>();
23 this->logged_in_ =
false;
27 if (this->node_state == espbt::ClientState::ESTABLISHED && !this->logged_in_) {
28 auto *packet = this->encoder_->get_send_pin_request(this->pin_);
30 esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_, packet->length,
31 packet->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
32 ESP_LOGI(TAG,
"[%s] Logging into AM43", this->get_name().c_str());
34 ESP_LOGW(TAG,
"[%s] Error writing set_pin to device, error = %d", this->get_name().c_str(), status);
36 this->logged_in_ =
true;
43 traits.set_supports_position(
true);
44 traits.set_supports_tilt(
false);
45 traits.set_is_assumed_state(
false);
50 if (this->node_state != espbt::ClientState::ESTABLISHED) {
51 ESP_LOGW(TAG,
"[%s] Cannot send cover control, not connected", this->get_name().c_str());
55 auto *packet = this->encoder_->get_stop_request();
57 esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_, packet->length,
58 packet->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
60 ESP_LOGW(TAG,
"[%s] Error writing stop command to device, error = %d", this->get_name().c_str(), status);
65 if (this->invert_position_)
67 auto *packet = this->encoder_->get_set_position_request(100 - (uint8_t)(pos * 100));
69 esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_, packet->length,
70 packet->data, ESP_GATT_WRITE_TYPE_NO_RSP, ESP_GATT_AUTH_REQ_NONE);
72 ESP_LOGW(TAG,
"[%s] Error writing set_position command to device, error = %d", this->get_name().c_str(), status);
77 esp_ble_gattc_cb_param_t *param) {
79 case ESP_GATTC_DISCONNECT_EVT: {
80 this->logged_in_ =
false;
83 case ESP_GATTC_SEARCH_CMPL_EVT: {
84 auto *chr = this->parent_->get_characteristic(AM43_SERVICE_UUID, AM43_CHARACTERISTIC_UUID);
86 if (this->parent_->get_characteristic(AM43_TUYA_SERVICE_UUID, AM43_TUYA_CHARACTERISTIC_UUID) !=
nullptr) {
87 ESP_LOGE(TAG,
"[%s] Detected a Tuya AM43 which is not supported, sorry.", this->get_name().c_str());
89 ESP_LOGE(TAG,
"[%s] No control service found at device, not an AM43..?", this->get_name().c_str());
93 this->char_handle_ = chr->handle;
95 auto status = esp_ble_gattc_register_for_notify(this->parent_->gattc_if, this->parent_->remote_bda, chr->handle);
97 ESP_LOGW(TAG,
"[%s] esp_ble_gattc_register_for_notify failed, status=%d", this->get_name().c_str(), status);
101 case ESP_GATTC_REG_FOR_NOTIFY_EVT: {
102 this->node_state = espbt::ClientState::ESTABLISHED;
105 case ESP_GATTC_NOTIFY_EVT: {
106 if (param->notify.handle != this->char_handle_)
108 this->decoder_->decode(param->notify.value, param->notify.value_len);
110 if (this->decoder_->has_position()) {
111 this->
position = ((float) this->decoder_->position_ / 100.0);
112 if (!this->invert_position_)
118 this->publish_state();
121 if (this->decoder_->has_pin_response()) {
122 if (this->decoder_->pin_ok_) {
123 ESP_LOGI(TAG,
"[%s] AM43 pin accepted.", this->get_name().c_str());
124 auto *packet = this->encoder_->get_position_request();
125 auto status = esp_ble_gattc_write_char(this->parent_->gattc_if, this->parent_->conn_id, this->char_handle_,
126 packet->length, packet->data, ESP_GATT_WRITE_TYPE_NO_RSP,
127 ESP_GATT_AUTH_REQ_NONE);
129 ESP_LOGW(TAG,
"[%s] Error writing set_position to device, error = %d", this->get_name().c_str(), status);
131 ESP_LOGW(TAG,
"[%s] AM43 pin rejected!", this->get_name().c_str());
135 if (this->decoder_->has_set_position_response() && !this->decoder_->set_position_ok_)
136 ESP_LOGW(TAG,
"[%s] Got nack after sending set_position. Bad pin?", this->get_name().c_str());
138 if (this->decoder_->has_set_state_response() && !this->decoder_->set_state_ok_)
139 ESP_LOGW(TAG,
"[%s] Got nack after sending set_state. Bad pin?", this->get_name().c_str());
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 dump_config() override
void control(const cover::CoverCall &call) override
cover::CoverTraits get_traits() override
const optional< float > & get_position() const