esphome / feature-requests

ESPHome Feature Request Tracker
https://esphome.io/
418 stars 26 forks source link

New Device Sonoff D1 Dimmer #611

Closed robbz23 closed 2 years ago

robbz23 commented 4 years ago

Describe the problem you have/What new integration you would like

Sonoff has released a new device called the D1 which is a mains dimmer using a ESP8285. With the help of others, we have been able to determine that the dimming functions are carried out by an MCU and this MCU talks to the ESP over the serial bus. By sending a command to the MCU over the serial bus I can control the dimmer functions, on, off, and set brightness have been sniffed out. Also in normal function from Sonoff, is a an optional 433mhz remote that communicates with the MCU directly. When changes are made with the remote, it is communicated over serial to the ESP chip.

Please describe your use case for this integration and alternatives you've tried:

To be able to use ESP home with this new device and to be able to control brightness of all lights connected to it.

Additional context

I have already flashed it with Tasmota and have used the console feature in Tasmota to send and receive commands over UART. Here is a sample of that

00:17:59 CMD: Baudrate 9600
00:17:59 SER: Set to 8N1 9600 bit/s
00:17:59 RSL: stat/tasmota_D9E56D/RESULT = {"Baudrate":9600}
00:25:32 CMD: SerialSend5 aa550104000a0122ffffffffffffffff29
00:25:32 RSL: stat/tasmota_D9E56D/RESULT = {"SerialSend":"Done"}
00:26:35 CMD: SerialSend5 aa550104000a0122ffffffffffffffff2a
00:26:35 RSL: stat/tasmota_D9E56D/RESULT = {"SerialSend":"Done"}
00:26:35 RSL: tele/tasmota_D9E56D/RESULT = {"SerialReceived":AA550104000005}
00:28:58 CMD:  SerialSend5 aa550104000a0101ffffffffffffffff09
00:28:58 RSL: stat/tasmota_D9E56D/RESULT = {"SerialSend":"Done"}
00:28:58 RSL: tele/tasmota_D9E56D/RESULT = {"SerialReceived":AA550104000005}
00:29:12 RSL: tele/tasmota_D9E56D/RESULT = {"SerialReceived":AA550104000A013CFFFFFFFFFFFFFFFF44}
00:29:43 RSL: tele/tasmota_D9E56D/RESULT = {"SerialReceived":AA550104000A0101FFFFFFFFFFFFFFFF09}
00:29:53 RSL: tele/tasmota_D9E56D/RESULT = {"SerialReceived":AA550104000A0164FFFFFFFFFFFFFFFF6C}
00:30:02 RSL: tele/tasmota_D9E56D/RESULT = {"SerialReceived":AA550104000AFF1EFFFFFFFFFFFFFFFF24}

Over at tasmota's issue have we determined the message format to tell the MCU to turn on and off the light.

The message aa550104000a0122ffffffffffffffff29 breaks down like this

aa550104000a -- header 01 -- on or 00 for off 22 -- on/off toggle flag ffffffffffffffff -- footer 29 -- checksum. It is a Checksum 8 Module 256 so you add up each byte and take the module with 256. However, you must add a byte of 01 to your sum before the module. This is verified with about 8 messages.

AA550104000A013CFFFFFFFFFFFFFFFF44 -- 60% AA550104000A0101FFFFFFFFFFFFFFFF09 -- 1% AA550104000A0164FFFFFFFFFFFFFFFF6C -- 100%

In the logs above you can see where I sent commands to the ESP using tasmota and serial send. Later you can see where I am adjusting the light with the remote and Tasmota is receiving the commands from the MCU.

epiniguin commented 4 years ago

There is a working Sonoff D1 Tasmota driver

Drew765 commented 4 years ago

Would be nice to get it into ESPHome but so it can be easier to integrate and more flexible.

h0jeZvgoxFepBQ2C commented 4 years ago

Anyone working on this? would be really nice..

craggyh commented 4 years ago

Any progress on this? Tasmota have had full control of this device for a while now with dimming and RF support but esphome is not catching up. I hate to say it but I'm considering going back to Tasmota because esphome can't support recent devices I've bought like this D1 and the Shelly i3.

Edit: I spoke too soon. Latest version of esphome just out has a bunch of new impressive features and updates. I’m not going anywhere 😁

craggyh commented 4 years ago

Ok, so I've done a bit of playing for a few hours and found a way to bypass the MCU and decode RF signals directly. You need to connect a wire from the top right corner pin on the 590R RF chip to solder pad 4 (gpio4).

$Sonoff D1

Then use the following code in esphome to receive the RF codes and map to buttons:

remote_receiver:
  pin: 4
  dump: rc_switch
#filter: 200us
  filter: 4us
  idle: 4ms
  tolerance: 50

binary_sensor:
  - platform: status
    name: "Sonoff D1 Status"

  - platform: remote_receiver
    name: "Sonoff Remote Button 1"
    rc_switch_raw:
      code: '100010101110101111101000'
      protocol: 1
    filters:
      delayed_off: 1s

  - platform: remote_receiver
    name: "Sonoff Remote Button 2"
    rc_switch_raw:
      code: '100010101110101111101100'
      protocol: 1
    filters:
      delayed_off: 1s

  - platform: remote_receiver
    name: "Sonoff Remote Button 3"
    rc_switch_raw:
      code: '100010101110101111100100'
      protocol: 1
    filters:
      delayed_off: 1s

  - platform: remote_receiver
    name: "Sonoff Remote Button 4"
    rc_switch_raw:
      code: '100010101110101111101001'
      protocol: 1
    filters:
      delayed_off: 1s

  - platform: remote_receiver
    name: "Sonoff Remote Button 5"
    rc_switch_raw:
      code: '100010101110101111100010'
      protocol: 1
    filters:
      delayed_off: 1s

  - platform: remote_receiver
    name: "Sonoff Remote Button 6"
    rc_switch_raw:
      code: '100010101110101111100101'
      protocol: 1
    filters:
      delayed_off: 1s

  - platform: remote_receiver
    name: "Sonoff Remote Button 7"
    rc_switch_raw:
      code: '100010101110101111100001'
      protocol: 1
    filters:
      delayed_off: 1s
  - platform: remote_receiver
    name: "Sonoff Remote Button 8"
    rc_switch_raw:
      code: '100010101110101111100011'
      protocol: 1
    filters:
      delayed_off: 1s

Now if only someone could tell me what I need to do to control the other MCU for dimming we would have full esphome control of this device and be able to double it up as a Sonoff RF Bridge and use all 8 buttons to control other devices in Homeassistant.

robbz23 commented 4 years ago

@craigueh That's amazing because it is the missing link that Tasmota can't do now. And it opens up the D1 to be so interesting as a dimmer with 8 controllable buttons.

Here is a link to the implementation in Tasmota that works perfectly. Basically the esp chip needs to talk to the RF chip via uart . The messages are formatted like I mentioned in my first comment here. I would like to help but I really have trouble understanding how to code this in Python.

It may be possible to do this without even creating a new component but by using the UART component.

https://esphome.io/components/uart.html

craggyh commented 4 years ago

Yeah it's pretty useful to be able to decode the RF stuff straight on the ESP. I tried out Tasmota and the delay of 1-2s after pressing a button was horrible. I found that button presses were sometimes missed altogether which was annoying. At least this way the response is instantaneous and the extra buttons can be used for other functions, or alternatively re-use the Sonoff remote elsewhere and use any RF remote for the dim up-down function. Of course, we'll probably need to cut the trace to the MCU from the 590R to stop the MCU picking up the remote button presses and trying to control the dimmer directly.

I'm tinkering with the serial to see if I can write to manually control the dimmer as a start:

`# Enable logging logger: baud_rate: 0

uart: baud_rate: 9600 tx_pin: GPIO1 rx_pin: GPIO3

switch:

I'm not sure how to convert the strings like AA550104000A013CFFFFFFFFFFFFFFFF44 to something like 0xA0, 0x01, 0x01, 0xA2 to write to the serial port. Any ideas?

I've also just stumbled across this post - https://community.home-assistant.io/t/esphome-custom-component-any-way-to-publish-a-light-state-manually/159757 This guy cleverly wrote a custom component to control another dimmer, perhaps we could modify his code on github to be used here for dimmer control?

craggyh commented 4 years ago

Ok so this works to write to the uart and turn on/off the dimmer:

switch:

I tried some other values to set the dimmer at 40% and 60% and it works. It should now be possible to set the buttons turn_on action to write to uart and set the dimmer at the desired level.

craggyh commented 4 years ago

Here we go, I un-paired the remote from the D1 and used the following uart.write on the binary sensors for button 1 and 2 on the remote :

binary_sensor:

This will now turn on and off the dimmer with button 1 and 2 as per the original Sonoff functionality. We can do the same with the other buttons for 1%, 40%, 60% and 100% or whatever increments we choose.

If I was clever enough I could probably write a lambda to present a slider or something that Homeassistant can use to increment the dimmer brightness to any custom value but we'll have to see if time permits. Ideally if someone had enough python skills they could write a custom light component to present the dimmer 1% to 100% as any other light with variable brightness. Maybe down the line we'll get lucky!!

robbz23 commented 4 years ago

My plan was to try to find another component that also uses UART as a basis for the code. I think the Tuya stuff does but I have trouble understanding the code. Sending codes out on UART is only half the battle. You also have to listen to the responses on the ESP chip when the other chip responds that it has a new state. IE if you pair the remote and use the remote buttons to update the dimming level you want to report this back to the ESP chip so it can update the state in HA.

craggyh commented 4 years ago

That’s the reason I bypassed the mcu and unpaired the remote. Now all states are controlled by esphome so regardless of whether a button is pressed on the remote or a switch is triggered in HA it’s esphome that controls and updates the state.

Esphome could have a template switch that updates it’s brightness depending on which button is pressed so HA is always aware.

craggyh commented 4 years ago

An alternative to the hardware modification is to go back to using the MCU with a paired remote and the custom UART Text sensor - https://esphome.io/components/text_sensor/uart.html

With this method I was able to get the following in the logs when I pressed the on button:

[16:14:37][VV][uart_esp8266:132]: Read 0b10101010 (0xAA) [16:14:37][VV][uart_esp8266:132]: Read 0b01010101 (0x55) [16:14:38][VV][uart_esp8266:132]: Read 0b00000001 (0x01) [16:14:38][VV][uart_esp8266:132]: Read 0b00000100 (0x04) [16:14:38][VV][uart_esp8266:132]: Read 0b00000000 (0x00) [16:14:38][VV][uart_esp8266:132]: Read 0b00001010 (0x0A) [16:14:38][VV][uart_esp8266:132]: Read 0b00000001 (0x01) [16:14:38][VV][uart_esp8266:132]: Read 0b01000110 (0x46) [16:14:38][VV][uart_esp8266:132]: Read 0b11111111 (0xFF) [16:14:38][VV][uart_esp8266:132]: Read 0b11111111 (0xFF) [16:14:38][VV][uart_esp8266:132]: Read 0b11111111 (0xFF) [16:14:38][VV][uart_esp8266:132]: Read 0b11111111 (0xFF) [16:14:38][VV][uart_esp8266:132]: Read 0b11111111 (0xFF) [16:14:38][VV][uart_esp8266:132]: Read 0b11111111 (0xFF) [16:14:38][VV][uart_esp8266:132]: Read 0b11111111 (0xFF) [16:14:38][VV][uart_esp8266:132]: Read 0b11111111 (0xFF) [16:14:38][VV][uart_esp8266:132]: Read 0b01001110 (0x4E)

You can use the custom UART Text sensor to update a template sensor or lambda based on the values sent back from the MCU over serial to the ESP after a button press. The disadvantage with this is that we're back to using the MCU to read the remote buttons and this introduces the 1-2s lag, restricts the control to fixed buttons/dim% and locks out the other buttons or third party RF remotes.

gytisgreitai commented 4 years ago

And what if I don't need the RF? Is there a working guide/config so I could just control the on/off/brightness via MQTT ? Thanks

JeffResc commented 4 years ago

@craigueh That's amazing because it is the missing link that Tasmota can't do now. And it opens up the D1 to be so interesting as a dimmer with 8 controllable buttons.

Here is a link to the implementation in Tasmota that works perfectly. Basically the esp chip needs to talk to the RF chip via uart . The messages are formatted like I mentioned in my first comment here. I would like to help but I really have trouble understanding how to code this in Python.

It may be possible to do this without even creating a new component but by using the UART component.

https://esphome.io/components/uart.html

@robbz23 Just wondering, what are you trying to implement here in Python? I played around with merging code from Tasmota’s implementation and used it in a custom ESPHome light component that supports dimming. I have to get a new bulb for my socket to verify everything is working as intended, but after that, I should be able to have working code for a light component that can control on/off/brightness.

And what if I don't need the RF? Is there a working guide/config so I could just control the on/off/brightness via MQTT ? Thanks

@gytisgreitai Like I said above, I have a mostly working implementation, give me a day to verify and I’d be happy to share the code here for those controls :)

JeffResc commented 4 years ago

Ok, so I've done a bit of playing for a few hours and found a way to bypass the MCU and decode RF signals directly. You need to connect a wire from the top right corner pin on the 590R RF chip to solder pad 4 (gpio4).

$Sonoff D1

Then use the following code in esphome to receive the RF codes and map to buttons:

 ...

Now if only someone could tell me what I need to do to control the other MCU for dimming we would have full esphome control of this device and be able to double it up as a Sonoff RF Bridge and use all 8 buttons to control other devices in Homeassistant.

@craigueh Could you share the original functionality of each button (1-8) so that I can merge them with the other code that I mentioned before to try to implement the default controls?

JeffResc commented 4 years ago

@craigueh Better yet, since you have access to the RF remote, where you able to decode the messages sent from the RF chip to the ESP?

In the Tasmota code linked below, they have a comment stating Received ack from Rf chip (aa 55 01 04 00 00 05) which I interpret as the ESP receiving this code via serial from the RF chip requesting a toggle of the dimmer to occur. Could you verify this or find the values for the other buttons?

Referenced Tasmota code

robbz23 commented 4 years ago

@JeffResc Yes the design of the D1 is that there are 3 chips. The esp handles wifi, one microcontroller handles RF and the other one handles dimming. When you press a button on the remote the RF chip tells the dimming chip the value. The dimming chip will then via UART update the status to ESP so that the app will show the correct state. You can also control the dimming chip by sending the appropriate commands via uart to the dimming chip. Check out the feature request issue on Tasmota. . In there you can see how to formulate the uart command to turn on/off and adjust brightness.

When the dimmer gets a new value it sends it back over uart to the ESP. Flash tasmota or esphome and set it up for listening on UART and you will see these messages coming back. If I remember correctly they are formed similar to how the commands are formulated to control dimming. The specific command you refer to I think is just an acknowledgment that you sent a command from esp to dimmer.

markbooth73 commented 4 years ago

I have one of these dimmers and have flashed it with the latest release of Tasmota. 8.5.0

My question relates to adjusting the dimmer output, I have looked for console commands but see nothing for the configuring the D1.

What I observe is that even as low as 1 % the output is way too bright, so is there a way to re-range, calibrate ?

I do not seem to have the well documented issue of ghost switching

JeffResc commented 4 years ago

@robbz23 Thanks for the reply, I've actually already got full control of the brightness and on/off working in ESPHome. I wanted to implement the RF remote though so we could have a fully working device, but I don't have an RF remote so I was looking if someone that did could provide me the RF codes so I could combine that with my working code in order to have a fully working ESPHome device.

markbooth73 commented 4 years ago

@robbz23 Thanks for the reply, I've actually already got full control of the brightness and on/off working in ESPHome. I wanted to implement the RF remote though so we could have a fully working device, but I don't have an RF remote so I was looking if someone that did could provide me the RF codes so I could combine that with my working code in order to have a fully working ESPHome device.

JeffResc, would you mind sharing your ESPHome config as is for now?

craggyh commented 4 years ago

Here's my config:

uart: baud_rate: 9600 # speed to STC15L101EW tx_pin: GPIO1 rx_pin: GPIO3

id: uart_bus

remote_receiver: pin: 4 dump: rc_switch filter: 4us idle: 4ms tolerance: 50

binary_sensor:

JeffResc commented 4 years ago

@craigueh Do you have the ESP directly connected to the RF receiver? I thought that there was another chip that the ESP had to communicate with via serial in order to receive RF commands

craggyh commented 4 years ago

Sorry I don't know how to insert the code without the formatting going crazy..

Yes, I have the esp chip connected directly to the rf receiver, I found the delay going through the other chip unbearable.

JeffResc commented 4 years ago

@craigueh You have them named as "Sonoff Remote Button 3," "Sonoff Remote Button 4," etc... What are the actual functions of these buttons? For example, which is on, off, brightness up, brightness down, etc?

craggyh commented 4 years ago

I’m not sure off hand what the actual original functions were but if you have a pic of the remote button 1 is top left, button 2 is top right and button 8 is bottom right so you should be able to work the rest out from that.

JeffResc commented 4 years ago

@craigueh Awesome, thanks. I'm making a full write-up on how to make this all work and it should be done shortly :)

JeffResc commented 4 years ago

@craigueh I have some code that I would like you to test. Would be be interesting and if so, do you have somewhere where I can instant message you like Discord?

craggyh commented 4 years ago

Yeah cool. I’d be happy to test. I’m on discord.

craggy#0561

JeffResc commented 4 years ago

@craigueh I sent you a friend request. I think you have to accept before I can send a DM.

JeffResc commented 4 years ago

I've posted a small write-up on my website on how to get it working. Please open an issue directly in the project's GitHub page, should you encounter one.

Drew765 commented 4 years ago

Thanks for the time you've spent on this Jeff. I'll be trialling this in the week or so.

markbooth73 commented 4 years ago

Jeff, many thanks for your efforts, I have compiled the binary and OTA uploaded to the D1. For now I see NO issues and will provide feedback thus needed, again thankyou. Regards,

robbz23 commented 4 years ago

@JeffResc Thanks so much. I didn't know about the custom light component. This is much easier than adding a new device, which I looked at and was a bit overwhelmed by.

I tried messing with it and it works well from HA to D1, but when I use the remote strange things happen. Where should I post more info? here or your github?

JeffResc commented 4 years ago

So as for ghost switching/dimming, it seems like that's coming from the RF chip. But good news is, it looks like the RF chip reports the ghost switch/dim over serial, so what I was planning on doing for users that don't need RF is when the ESP receives an RF signal, it will automatically just override it which I think could fix the issue.

robbz23 commented 4 years ago

@JeffR I just added an issue on your github after testing the RF file today. Also I don't think you can have it ignore rf chip just using software. AFAIK the RF chip talks to the dimming chip which in turn sends messages to the ESP. So when you push a button it would dim then inform the esp of the updated level. The best you could do is program the esp to set the brightness back to what it thinks it should be if it is changed by something else.

JeffResc commented 4 years ago

@robbz23 That's what I meant when I said override. I was planning on when the ESP receives a command from the RF chip, it would just override the change made by the RF chip and send the previous value again. This could fix the issues for those that don't have an RF remote.

robbz23 commented 4 years ago

I now have updated one of my two D1's to the rf hack that craig discovered and using the modified file I submitted as a PR to Jeff. The D1 still has its built in functions with the remote so you have to delay your commands a bit. I am triggering a scene with one button and a 2 sec delay is enough to let the sonoff set the level and then I change it with HA. My binary codes were different than Craigs but I was able to read them no problem in esphome.

  # Button 3 turns the light on to 100%
  - platform: remote_receiver
    name: "Sonoff Remote Button 3"
    rc_switch_raw:
      code: "100111100011000010110100"
      protocol: 1
    filters:
      delayed_off: 1s

I also tested changing the remotes hardcoded value in esphome. This only required a slight delay and is less noticeable.

  - platform: remote_receiver
    name: "Sonoff Remote Button 4"
    rc_switch_raw:
      code: "100111100011000010111001"
      protocol: 1
    filters:
      delayed_off: 1s
    on_state:
      then:
        - delay: 500ms
        - light.turn_on:
            id: main
            brightness: 5%

Also I needed to set the default transition to 0 sec in yaml otherwise I had problems with the on command.

craggyh commented 4 years ago

@ robbz23 So the codes are unique to each remote? That's interesting. I presumed they would be the same across remotes. That's actually good because using one D1 in my kitchen I can use multiple Sonoff remotes in my kitchen/living room/dining room and control things like ceiling speaker volume and media playback in each room with separate remotes.

robbz23 commented 4 years ago

@craigueh Im not sure they all were different, but I know some were.

craggyh commented 4 years ago

Most likely they are all different if any are.

Did you unpair your remote from the D1? I have mine unpaired so only the esp is receiving the rf codes and that makes things a lot simpler.

robbz23 commented 4 years ago

I was just going to ask you that. How do you unpair?

JeffResc commented 4 years ago

I don't have a remote so please excuse me if this is wrong, but I think you may be looking for this resource, @robbz23.

craggyh commented 4 years ago

Just hold the bottom left button on the remote for about 5-10s after you power up the d1 until you hear the beeps.

8osman commented 3 years ago

I'm looking for some help. I want to use the D1 as a replacement for a traditional dimmer switch (uk) and I'm trying to work out the gpio pins which would be best, ideally I'd like to use GPIO4 as per @craigueh suggestion of faster custom rf support.

I would like to connect a rotary encoder to some other gpio pins. I need to GPIO's I would really appreciate some suggestions as my electronics knowledge is limited.

GPIO 16 is currently connected to the OTA switch, I was thinking of just soldering off this for the on off.

I was trying to work out what GPIO14 was doing, it looks to be connected to a resistor / capacitor combination then to ground?

GPIO1 + 3 are on the rx / tx uart?

Thank you

craggyh commented 3 years ago

Gpio1/3 are needed for uart communication to the dimming chip/zero cross detection so that rules them out.

You could use gpio0 for the rotary encoder SW push button and gpio16 for DT. I can’t remember off hand what gpio14 is used for but if possible use it for CLK. Is there an led on the board that can be hijacked for a gpio? Mine is up in a ceiling so have no access to take a peek inside.

8osman commented 3 years ago

Thank you. I'll explore a bit more and see what i can do.

There is an led on the board so might use that.

marcospsn commented 3 years ago

@ robbz23 Obrigado pela resposta, na verdade já tenho controle total do brilho e liga / desliga trabalhando no ESPHome. Eu queria implementar o remoto RF para que pudéssemos ter um dispositivo totalmente funcional, mas eu não tenho um remoto RF, então eu estava procurando se alguém que tivesse poderia me fornecer os códigos RF para que eu pudesse combiná-los com meu código de trabalho em a fim de ter um dispositivo ESPHome totalmente funcional.

vc poderia compartilhar o seu compilado do esphome pra esse D1?

venkattetali commented 3 years ago

And what if I don't need the RF? Is there a working guide/config so I could just control the on/off/brightness via MQTT ? Thanks

Did it work for you I mean without remote

Eenoo commented 3 years ago

I have this working, so many thanks. Is there any progress on merging this into the release code? Or has this been done and just needs some documentation drafting?

Drew765 commented 3 years ago

@Eenoo have you flashed ESPhome or using Tasmota?