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};
132 size_t buf_len =
sizeof(ref_buffer);
141 while (pos <
sizeof(ref_buffer) && ref_buffer[pos] == buffer[pos]) {
144 if (pos ==
sizeof(ref_buffer)) {
145 ESP_LOGD(TAG,
"[%04d] Acknowledge received", this->
write_count_);
148 ESP_LOGW(TAG,
"[%04d] Unexpected acknowledge received (possible clash of RF/HA commands), expected ack was:",
158 ESP_LOGW(TAG,
"[%04d] Too short command (actual len is %d bytes, minimal is 7)", this->
write_count_, len);
161 if (cmd[0] != 0xAA || cmd[1] != 0x55) {
162 ESP_LOGW(TAG,
"[%04d] Wrong header (%x%x, must be AA55)", this->
write_count_, cmd[0], cmd[1]);
165 if ((cmd[5] + 7 ) != len) {
166 ESP_LOGW(TAG,
"[%04d] Payload length field does not match packet length (%d, expected %d)", this->
write_count_,
175 uint32_t retries = 10;
177 ESP_LOGV(TAG,
"[%04d] Writing to the dimmer:", this->
write_count_);
184 }
while (!this->
read_ack_(cmd, len) && retries > 0);
189 ESP_LOGE(TAG,
"[%04d] Unable to write to the dimmer", this->
write_count_);
197 uint8_t
cmd[17] = {0xAA, 0x55, 0x01, 0x04, 0x00, 0x0A, 0x00, 0x00, 0xFF,
199 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00};
203 ESP_LOGI(TAG,
"[%04d] Setting dimmer state to %s, raw brightness=%d", this->
write_count_, ONOFF(binary), cmd[7]);
208 if (cmd[2] == 0x01 && cmd[3] == 0x04 && cmd[4] == 0x00 && cmd[5] == 0x0A) {
209 uint8_t ack_buffer[7] = {0xAA, 0x55, cmd[2], cmd[3], 0x00, 0x00, 0x00};
212 ESP_LOGI(TAG,
"[%04d] RF sets dimmer state to %s, raw brightness=%d", this->
write_count_, ONOFF(cmd[6]), cmd[7]);
213 const uint8_t new_brightness = remap<uint8_t, uint8_t>(cmd[7], this->
min_value_, this->
max_value_, 0, 100);
214 const bool new_state = cmd[6];
224 ESP_LOGI(TAG,
"[%04d] Ghost command from RF detected, reverted", this->
write_count_);
230 ESP_LOGW(TAG,
"[%04d] Unexpected command received", this->
write_count_);
236 ESP_LOGV(TAG,
"Publishing new state: %s, brightness=%d", ONOFF(is_on), brightness);
238 call.set_state(is_on);
239 if (brightness != 0) {
245 call.set_brightness((
float) brightness / 100.0f);
267 const uint8_t calculated_brightness = (uint8_t) roundf(brightness * 100);
269 if (calculated_brightness == 0) {
282 ESP_LOGW(TAG,
"Failed to update the dimmer, publishing the previous state");
291 ESP_LOGCONFIG(TAG,
" Minimal brightness: %d", this->
min_value_);
292 ESP_LOGCONFIG(TAG,
" Maximal brightness: %d", this->
max_value_);
299 ESP_LOGV(TAG,
"Have some UART data in loop()");
300 uint8_t buffer[17] = {0};
301 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)
Implementation of SPI Controller mode.
light::LightState * light_state_
void write_state(light::LightState *state) override
const StringRef & get_name() const