52static constexpr size_t SONOFF_D1_ACK_SIZE = 7;
53static constexpr size_t SONOFF_D1_MAX_CMD_SIZE = 17;
66 uint8_t value = this->
read();
67 ESP_LOGW(TAG,
"[%04d] Skip %02d: 0x%02x from the dimmer", this->
write_count_, garbage, value);
73 ESP_LOGW(TAG,
"[%04d] Skip %d bytes from the dimmer", this->
write_count_, garbage);
80 if (cmd ==
nullptr ||
len < 7) {
81 ESP_LOGW(TAG,
"[%04d] Too short command buffer (actual len is %d bytes, minimal is 7)", this->
write_count_, len);
87 ESP_LOGV_HEX(TAG, cmd, 6, 6,
"[%04d] Reading from dimmer: %s", this->
write_count_);
89 if (cmd[0] != 0xAA || cmd[1] != 0x55) {
90 ESP_LOGW(TAG,
"[%04d] RX: wrong header (%x%x, must be AA55)", this->
write_count_, cmd[0], cmd[1]);
94 if ((cmd[5] + 7 ) >
len) {
95 ESP_LOGW(TAG,
"[%04d] RX: Payload length is unexpected (%d, max expected %d)", this->
write_count_, cmd[5],
101 ESP_LOGV_HEX(TAG, &cmd[6], cmd[5] + 1, SONOFF_D1_MAX_CMD_SIZE,
"[%04d] %s", this->
write_count_);
105 if (valid_checksum != cmd[cmd[5] + 7 - 1]) {
106 ESP_LOGW(TAG,
"[%04d] RX: checksum mismatch (%d, expected %d)", this->
write_count_, cmd[cmd[5] + 7 - 1],
118 ESP_LOGW(TAG,
"[%04d] RX: feedback timeout", this->
write_count_);
126 uint8_t ref_buffer[7] = {0xAA, 0x55, cmd[2], cmd[3], 0x00, 0x00, 0x00};
127 uint8_t
buffer[
sizeof(ref_buffer)] = {0};
129 size_t buf_len =
sizeof(ref_buffer);
141 if (
pos ==
sizeof(ref_buffer)) {
142 ESP_LOGD(TAG,
"[%04d] Acknowledge received", this->
write_count_);
146 ESP_LOGW(TAG,
"[%04d] Unexpected acknowledge received (possible clash of RF/HA commands), expected ack was:",
156 ESP_LOGW(TAG,
"[%04d] Too short command (actual len is %d bytes, minimal is 7)", this->
write_count_, len);
159 if (cmd[0] != 0xAA || cmd[1] != 0x55) {
160 ESP_LOGW(TAG,
"[%04d] Wrong header (%x%x, must be AA55)", this->
write_count_, cmd[0], cmd[1]);
163 if ((cmd[5] + 7 ) !=
len) {
164 ESP_LOGW(TAG,
"[%04d] Payload length field does not match packet length (%d, expected %d)", this->
write_count_,
175 ESP_LOGV_HEX(TAG, cmd,
len, SONOFF_D1_MAX_CMD_SIZE,
"[%04d] Writing to the dimmer: %s", this->
write_count_);
186 ESP_LOGE(TAG,
"[%04d] Unable to write to the dimmer", this->
write_count_);
194 uint8_t cmd[17] = {0xAA, 0x55, 0x01, 0x04, 0x00, 0x0A, 0x00, 0x00, 0xFF,
196 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00};
200 ESP_LOGI(TAG,
"[%04d] Setting dimmer state to %s, raw brightness=%d", this->
write_count_, ONOFF(binary), cmd[7]);
205 if (cmd[2] == 0x01 && cmd[3] == 0x04 && cmd[4] == 0x00 && cmd[5] == 0x0A) {
206 uint8_t ack_buffer[7] = {0xAA, 0x55, cmd[2], cmd[3], 0x00, 0x00, 0x00};
209 ESP_LOGI(TAG,
"[%04d] RF sets dimmer state to %s, raw brightness=%d", this->
write_count_, ONOFF(cmd[6]), cmd[7]);
211 const bool new_state = cmd[6];
221 ESP_LOGI(TAG,
"[%04d] Ghost command from RF detected, reverted", this->
write_count_);
227 ESP_LOGW(TAG,
"[%04d] Unexpected command received", this->
write_count_);
233 ESP_LOGV(TAG,
"Publishing new state: %s, brightness=%d", ONOFF(is_on), brightness);
236 if (brightness != 0) {
242 call.set_brightness((
float) brightness / 100.0f);
260 state->current_values_as_binary(&binary);
261 state->current_values_as_brightness(&brightness);
264 const uint8_t calculated_brightness = (uint8_t) roundf(brightness * 100);
266 if (calculated_brightness == 0) {
279 ESP_LOGW(TAG,
"Failed to update the dimmer, publishing the previous state");
287 "Sonoff D1 Dimmer: '%s'\n"
288 " Use RM433 Remote: %s\n"
289 " Minimal brightness: %d\n"
290 " Maximal brightness: %d",
299 ESP_LOGV(TAG,
"Have some UART data in loop()");
const LogString * get_log_name() const
Get the name for a "%s" log argument (LOG_STR_ARG).
LightCall & set_state(optional< bool > state)
Set the binary ON/OFF state of the light.
This class represents the communication layer between the front-end MQTT layer and the hardware outpu...
This class is used to represent the capabilities of a light.
bool read_command_(uint8_t *cmd, size_t &len)
void process_command_(const uint8_t *cmd, size_t len)
uint8_t calc_checksum_(const uint8_t *cmd, size_t len)
bool control_dimmer_(bool binary, uint8_t brightness)
void populate_checksum_(uint8_t *cmd, size_t len)
void dump_config() override
light::LightState * light_state_
void write_state(light::LightState *state) override
void publish_state_(bool is_on, uint8_t brightness)
bool read_ack_(const uint8_t *cmd, size_t len)
light::LightTraits get_traits() override
bool write_command_(uint8_t *cmd, size_t len, bool needs_ack=true)
optional< std::array< uint8_t, N > > read_array()
void write_array(const uint8_t *data, size_t len)
@ BRIGHTNESS
Dimmable light.
ESPHOME_LOG_TAG(TAG, "sonoff_d1")
constexpr uint8_t sum_bytes(const uint8_t *data, size_t len, uint8_t sum=0)
Add up the bytes of data with size len, truncated to 8 bits: the checksum many serial and IR protocol...
char * format_hex_pretty_to(char *buffer, size_t buffer_size, const uint8_t *data, size_t length, char separator)
Format byte array as uppercase hex to buffer (base implementation).
constexpr size_t format_hex_pretty_size(size_t byte_count)
Calculate buffer size needed for format_hex_pretty_to with separator: "XX:XX:...:XX\0".
T remap(U value, U min, U max, T min_out, T max_out)
Remap value from the range (min, max) to (min_out, max_out).