49 static const char *
const TAG =
"sonoff_d1";
53 for (
int i = 2; i < len - 1; i++) {
68 uint8_t value = this->
read();
69 ESP_LOGW(TAG,
"[%04d] Skip %02d: 0x%02x from the dimmer", this->
write_count_, garbage, value);
75 ESP_LOGW(TAG,
"[%04d] Skip %d bytes from the dimmer", this->
write_count_, garbage);
82 if (cmd ==
nullptr || len < 7) {
83 ESP_LOGW(TAG,
"[%04d] Too short command buffer (actual len is %d bytes, minimal is 7)", this->
write_count_, len);
89 ESP_LOGV(TAG,
"[%04d] Reading from dimmer:", this->
write_count_);
92 if (cmd[0] != 0xAA || cmd[1] != 0x55) {
93 ESP_LOGW(TAG,
"[%04d] RX: wrong header (%x%x, must be AA55)", this->
write_count_, cmd[0], cmd[1]);
97 if ((cmd[5] + 7 ) > len) {
98 ESP_LOGW(TAG,
"[%04d] RX: Payload length is unexpected (%d, max expected %d)", this->
write_count_, cmd[5],
108 if (valid_checksum != cmd[cmd[5] + 7 - 1]) {
109 ESP_LOGW(TAG,
"[%04d] RX: checksum mismatch (%d, expected %d)", this->
write_count_, cmd[cmd[5] + 7 - 1],
121 ESP_LOGW(TAG,
"[%04d] RX: feedback timeout", this->
write_count_);
129 uint8_t ref_buffer[7] = {0xAA, 0x55, cmd[2], cmd[3], 0x00, 0x00, 0x00};
130 uint8_t buffer[
sizeof(ref_buffer)] = {0};
131 uint32_t pos = 0, buf_len =
sizeof(ref_buffer);
140 while (pos <
sizeof(ref_buffer) && ref_buffer[pos] == buffer[pos]) {
143 if (pos ==
sizeof(ref_buffer)) {
144 ESP_LOGD(TAG,
"[%04d] Acknowledge received", this->
write_count_);
147 ESP_LOGW(TAG,
"[%04d] Unexpected acknowledge received (possible clash of RF/HA commands), expected ack was:",
157 ESP_LOGW(TAG,
"[%04d] Too short command (actual len is %d bytes, minimal is 7)", this->
write_count_, len);
160 if (cmd[0] != 0xAA || cmd[1] != 0x55) {
161 ESP_LOGW(TAG,
"[%04d] Wrong header (%x%x, must be AA55)", this->
write_count_, cmd[0], cmd[1]);
164 if ((cmd[5] + 7 ) != len) {
165 ESP_LOGW(TAG,
"[%04d] Payload length field does not match packet length (%d, expected %d)", this->
write_count_,
174 uint32_t retries = 10;
176 ESP_LOGV(TAG,
"[%04d] Writing to the dimmer:", this->
write_count_);
183 }
while (!this->
read_ack_(cmd, len) && retries > 0);
188 ESP_LOGE(TAG,
"[%04d] Unable to write to the dimmer", this->
write_count_);
196 uint8_t
cmd[17] = {0xAA, 0x55, 0x01, 0x04, 0x00, 0x0A, 0x00, 0x00, 0xFF,
198 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00};
202 ESP_LOGI(TAG,
"[%04d] Setting dimmer state to %s, raw brightness=%d", this->
write_count_, ONOFF(binary), cmd[7]);
207 if (cmd[2] == 0x01 && cmd[3] == 0x04 && cmd[4] == 0x00 && cmd[5] == 0x0A) {
208 uint8_t ack_buffer[7] = {0xAA, 0x55, cmd[2], cmd[3], 0x00, 0x00, 0x00};
211 ESP_LOGI(TAG,
"[%04d] RF sets dimmer state to %s, raw brightness=%d", this->
write_count_, ONOFF(cmd[6]), cmd[7]);
212 const uint8_t new_brightness = remap<uint8_t, uint8_t>(cmd[7], this->
min_value_, this->
max_value_, 0, 100);
213 const bool new_state = cmd[6];
223 ESP_LOGI(TAG,
"[%04d] Ghost command from RF detected, reverted", this->
write_count_);
229 ESP_LOGW(TAG,
"[%04d] Unexpected command received", this->
write_count_);
235 ESP_LOGV(TAG,
"Publishing new state: %s, brightness=%d", ONOFF(is_on), brightness);
237 call.set_state(is_on);
238 if (brightness != 0) {
244 call.set_brightness((
float) brightness / 100.0f);
266 const uint8_t calculated_brightness = (uint8_t) roundf(brightness * 100);
268 if (calculated_brightness == 0) {
281 ESP_LOGW(TAG,
"Failed to update the dimmer, publishing the previous state");
290 ESP_LOGCONFIG(TAG,
" Minimal brightness: %d", this->
min_value_);
291 ESP_LOGCONFIG(TAG,
" Maximal brightness: %d", this->
max_value_);
298 ESP_LOGV(TAG,
"Have some UART data in loop()");
299 uint8_t buffer[17] = {0};
300 size_t len =
sizeof(buffer);
bool control_dimmer_(bool binary, uint8_t brightness)
This class represents the communication layer between the front-end MQTT layer and the hardware outpu...
optional< std::array< uint8_t, N > > read_array()
std::string format_hex_pretty(const uint8_t *data, size_t length)
Format the byte array data of length len in pretty-printed, human-readable hex.
void write_array(const uint8_t *data, size_t len)
bool read_command_(uint8_t *cmd, size_t &len)
uint8_t calc_checksum_(const uint8_t *cmd, size_t len)
void publish_state_(bool is_on, uint8_t brightness)
void process_command_(const uint8_t *cmd, size_t len)
void current_values_as_binary(bool *binary)
The result of all the current_values_as_* methods have gamma correction applied.
bool write_command_(uint8_t *cmd, size_t len, bool needs_ack=true)
void dump_config() override
light::LightTraits get_traits() override
void current_values_as_brightness(float *brightness)
Master brightness of the light can be controlled.
constexpr const char * c_str() const
This class is used to represent the capabilities of a light.
bool read_ack_(const uint8_t *cmd, size_t len)
void populate_checksum_(uint8_t *cmd, size_t len)
light::LightState * light_state_
void write_state(light::LightState *state) override
const StringRef & get_name() const