Sonoff /eWeLink component for original firmware

@peterbuga You’re the man!

Count me in as a guinea pig. :slight_smile:

1 Like

No problem. Count me in for testing :+1:
Least I can do.
I am not very technical and python is way over my head but happy to change files, switch things on/off, update yaml and send logs etc!

1 Like

Just an update. The power sensor is looking more predictable now :slight_smile:
The state goes to unknown for <60s then to a number which looks right. Then after switching off the switch it goes back to 0 within another 60s.
So looks like it’s behaving as expected :+1:

@peterbuga the fact is i’m running without proxy since my internet uses home cable so no proxy and my HA is running within hassio which is in docker running in Pi3 B+ and it’s exposed to internet so i can manage my HA from mobile phone, I’m still confused why I have to use proxy option anyway :slight_smile: .

You’re correct maybe this post a bit off topic, I’ll post somewhere else regarding how to install python addon properly within docker/hassio.

anyway, kudos for such a breakthrough :+1: , I hope this component will keep improving and included in HA next releases.

First of all, I have to say thank you @peterbuga ! I have 4 Sonoff S26 plugs at home and I had been managing them using IFTTT Webhooks so far. Worked OK, but this solution is far better, purely because the plugs states are synced in this case. Thank you, thank you, thank you.

My set up is Home Assistant is installed in a virtual environment in Debian 9.6.0, which is installed in QNAP as a VM. Home Assistant is accessed using HTTPS (with Let’s Encrypt). I first used the master branch, it didn’t work. I kept getting the async error some others mentioned above. Switching to websocket branch version fixed it and it works flawlessly. This is amazing!

When you have time, it would be great if you could integrate this into custom updater so it can update itself automatically when you have a new version, maybe with a support for different branches.

Can I donate you anything?

@peterbuga While my devices work perfectly, I am pasting the debug.json output below, in case it helps you with anything. I am not an expert developer like you so I don’t know if the below is helpful in any way but here it is just in case:

[
  {
    "__v": 0,
    "_id": "[hidden]",
    "apikey": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "brandName": "Sonoff",
    "createdAt": "xxxx-xx-xxxxx:xx:xx.xxx",
    "deviceStatus": "",
    "deviceUrl": "",
    "deviceid": "[hidden]",
    "devicekey": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "extra": {
      "_id": "[hidden]",
      "extra": {
        "apmac": "xx:xx:xx:xx:xx:xx",
        "brandId": "58e5f344baeb368720e25469",
        "description": "WO18237",
        "mac": "xx:xx:xx:xx:xx:xx",
        "manufacturer": "\u6df1\u5733\u677e\u8bfa\u6280\u672f\u6709\u9650\u516c\u53f8",
        "model": "PSA-B01-GL",
        "modelInfo": "5aca25ef85a15a8f032672f7",
        "ui": "\u5355\u901a\u9053\u63d2\u5ea7",
        "uiid": 1
      }
    },
    "group": "",
    "groups": [
      "5b33da93c7d29425c69488ba"
    ],
    "ip": "[hidden]",
    "location": "",
    "name": "[hidden]",,
    "offlineTime": "xxxx-xx-xxxxx:xx:xx.xxx",
    "online": true,
    "onlineTime": "xxxx-xx-xxxxx:xx:xx.xxx",
    "params": {
      "controlType": "7",
      "fwVersion": "2.6.0",
      "rssi": -74,
      "staMac": "xx:xx:xx:xx:xx:xx",
      "startup": "off",
      "switch": "off"
    },
    "productModel": "S26",
    "settings": {
      "alarmNotify": 1,
      "opsHistory": 1,
      "opsNotify": 1
    },
    "sharedTo": [],
    "showBrand": true,
    "type": "10",
    "uiid": 1
  },
  {
    "__v": 0,
    "_id": "[hidden]",
    "apikey": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "brandName": "Sonoff",
    "createdAt": "xxxx-xx-xxxxx:xx:xx.xxx",
    "deviceStatus": "",
    "deviceUrl": "",
    "deviceid": "[hidden]",
    "devicekey": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "extra": {
      "_id": "[hidden]",
      "extra": {
        "apmac": "xx:xx:xx:xx:xx:xx",
        "brandId": "58e5f344baeb368720e25469",
        "description": "WO18237",
        "mac": "xx:xx:xx:xx:xx:xx",
        "manufacturer": "\u6df1\u5733\u677e\u8bfa\u6280\u672f\u6709\u9650\u516c\u53f8",
        "model": "PSA-B01-GL",
        "modelInfo": "5aca25ef85a15a8f032672f7",
        "ui": "\u5355\u901a\u9053\u63d2\u5ea7",
        "uiid": 1
      }
    },
    "group": "",
    "groups": [
      "5b33da93c7d29425c69488ba"
    ],
    "ip": "[hidden]",
    "location": "",
    "name": "[hidden]",,
    "offlineTime": "xxxx-xx-xxxxx:xx:xx.xxx",
    "online": true,
    "onlineTime": "xxxx-xx-xxxxx:xx:xx.xxx",
    "params": {
      "controlType": "7",
      "fwVersion": "2.6.0",
      "rssi": -46,
      "staMac": "xx:xx:xx:xx:xx:xx",
      "startup": "off",
      "switch": "off"
    },
    "productModel": "S26",
    "settings": {
      "alarmNotify": 1,
      "opsHistory": 1,
      "opsNotify": 1
    },
    "sharedTo": [],
    "showBrand": true,
    "type": "10",
    "uiid": 1
  },
  {
    "__v": 0,
    "_id": "[hidden]",
    "apikey": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "brandName": "Sonoff",
    "createdAt": "xxxx-xx-xxxxx:xx:xx.xxx",
    "deviceStatus": "",
    "deviceUrl": "",
    "deviceid": "[hidden]",
    "devicekey": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "extra": {
      "_id": "[hidden]",
      "extra": {
        "apmac": "xx:xx:xx:xx:xx:xx",
        "brandId": "58e5f344baeb368720e25469",
        "description": "WO18237",
        "mac": "xx:xx:xx:xx:xx:xx",
        "manufacturer": "\u6df1\u5733\u677e\u8bfa\u6280\u672f\u6709\u9650\u516c\u53f8",
        "model": "PSA-B01-GL",
        "modelInfo": "5aca25ef85a15a8f032672f7",
        "ui": "\u5355\u901a\u9053\u63d2\u5ea7",
        "uiid": 1
      }
    },
    "group": "",
    "groups": [
      "5b33da93c7d29425c69488ba"
    ],
    "ip": "[hidden]",
    "location": "",
    "name": "[hidden]",,
    "offlineTime": "xxxx-xx-xxxxx:xx:xx.xxx",
    "online": true,
    "onlineTime": "xxxx-xx-xxxxx:xx:xx.xxx",
    "params": {
      "controlType": "7",
      "fwVersion": "2.6.1",
      "init": 1,
      "pulse": "off",
      "pulseWidth": 500,
      "rssi": -61,
      "sledOnline": "on",
      "staMac": "xx:xx:xx:xx:xx:xx",
      "startup": "off",
      "switch": "off",
      "timers": []
    },
    "productModel": "S26",
    "settings": {
      "alarmNotify": 1,
      "opsHistory": 1,
      "opsNotify": 1
    },
    "sharedTo": [],
    "showBrand": true,
    "type": "10",
    "uiid": 1
  },
  {
    "__v": 0,
    "_id": "[hidden]",
    "apikey": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "brandName": "Sonoff",
    "createdAt": "xxxx-xx-xxxxx:xx:xx.xxx",
    "deviceStatus": "",
    "deviceUrl": "",
    "deviceid": "[hidden]",
    "devicekey": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "extra": {
      "_id": "[hidden]",
      "extra": {
        "apmac": "xx:xx:xx:xx:xx:xx",
        "brandId": "58e5f344baeb368720e25469",
        "description": "WO18237",
        "mac": "xx:xx:xx:xx:xx:xx",
        "manufacturer": "\u6df1\u5733\u677e\u8bfa\u6280\u672f\u6709\u9650\u516c\u53f8",
        "model": "PSA-B01-GL",
        "modelInfo": "5aca25ef85a15a8f032672f7",
        "ui": "\u5355\u901a\u9053\u63d2\u5ea7",
        "uiid": 1
      }
    },
    "group": "",
    "groups": [
      "5b9ce2f48397cd2254ae1978"
    ],
    "ip": "[hidden]",
    "location": "",
    "name": "[hidden]",,
    "offlineTime": "xxxx-xx-xxxxx:xx:xx.xxx",
    "online": true,
    "onlineTime": "xxxx-xx-xxxxx:xx:xx.xxx",
    "params": {
      "controlType": "7",
      "fwVersion": "2.6.1",
      "init": 1,
      "pulse": "off",
      "pulseWidth": 500,
      "rssi": -66,
      "sledOnline": "on",
      "staMac": "xx:xx:xx:xx:xx:xx",
      "startup": "off",
      "switch": "off"
    },
    "productModel": "S26",
    "settings": {
      "alarmNotify": 1,
      "opsHistory": 1,
      "opsNotify": 1
    },
    "sharedTo": [],
    "showBrand": true,
    "type": "10",
    "uiid": 1
  }
]

@brightonguy glad that you find it useful & got it working eventually :+1:
i’ve been quite lazy lately in making the websocket implementation the default one, focusing mostly on adding support for new devices (which is somehow easier with old implementation :sweat_smile:) but i’m working on improvements nonetheless.

regarding the custom updater part, might not happen anytime soon (might actually be an easy thing to do, who knows) but being quite an active development and not being able to test most of the stuff on my side it would be easy to break flow/automations on people’s side and i kinda try to avoid that for now

you can donate some of your time and report back any of the bugs you might encounter instead of just magically waiting for them to be fixed :grin:

@forums2012 @Michaelrch
i’ve added the log capturing part :raised_hands: so anytime you have some free time please give it a go!
the instructions are like this:

  1. update the files from the new websocket-debug branch
  2. add a new option to the sonoff part in configuration.yaml -> debug: True
  3. (optional) change the scan_interval option to 10 or 20 sec
  4. (optional) it will be better if you could use a 2nd eWeLink account where’d you share only 1 device that you want to analyse (this way the log will be easier to read but i’ll take anything otherwise) + you will be able to change stuff from inside eWeLink app with the original account and send better data to the log (otherwise the “grace period” kicks in)
  5. restart HA to start generating the log (on every restart the log gets cleared)
  6. leave it like 5-10 minutes running, turn on/off the device be it from HA or eWelink app, in the case of plugs with power meters (and alike) connect some devices to it too
  7. a new file sonoff_debug.log will be created in the root of your config folder (where there is also configuration.yaml, custom_components folder etc) save it and post it somewhere, DM to me or anything else. but please do not post the outputs here as it might be quite big!
  8. set option debug: False or just remove it & restart HA to get back to normal usage

one important thing to mention: most of the important data is still obfuscated and I cannot trace (or control) anything form my side (feel free to double check it) and also the the deviceid is NOT hidden anymore BUT instead it’s an obfuscated-hash value because i need to know which-device-received-what if more of them are in the logs

1 Like

I’ve got a wifi diffuser (this one) which uses the eWeLink app.

I’ve added the component, and the diffusers show up as switches in Home Assistant. I can turn them on from HASS, but a few seconds later they show as off again in HASS, while they are actually on. In addition, these diffusers have RGB Leds in them that can be controlled separately from the diffuser component from eWeLink; would be good to be able to control them also from HASS.

@sdlafferty this is a very particular device, I didn’t even knew something like this existed :smile:!

the best you can do in this case would be to follow ALL (very important 4) the steps mentioned in the post above and open a new issue here. it’ll be easier for me to track the device like this and properly implementing it without spamming this thread.

looking forward for it! :wink:

1 Like

Finally installed uuid & websocket-client in docker.

but I got error during loading component :

2019-01-24 10:07:29 WARNING (MainThread) [homeassistant.loader] You are using a custom component for sonoff which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you do experience issues with Home Assistant.
2019-01-24 10:07:34 ERROR (MainThread) [homeassistant.setup] Error during setup of component sonoff
Traceback (most recent call last):
File “/usr/local/lib/python3.6/site-packages/urllib3/connection.py”, line 159, in _new_conn
(self._dns_host, self.port), self.timeout, **extra_kw)
File “/usr/local/lib/python3.6/site-packages/urllib3/util/connection.py”, line 57, in create_connection
for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
File “/usr/local/lib/python3.6/socket.py”, line 745, in getaddrinfo
for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -3] Try again

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py”, line 600, in urlopen
chunked=chunked)
File “/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py”, line 343, in _make_request
self._validate_conn(conn)
File “/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py”, line 839, in _validate_conn
conn.connect()
File “/usr/local/lib/python3.6/site-packages/urllib3/connection.py”, line 301, in connect
conn = self._new_conn()
File “/usr/local/lib/python3.6/site-packages/urllib3/connection.py”, line 168, in _new_conn
self, “Failed to establish a new connection: %s” % e)
urllib3.exceptions.NewConnectionError: <urllib3.connection.VerifiedHTTPSConnection object at 0x725414d0>: Failed to establish a new connection: [Errno -3] Try again

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/usr/local/lib/python3.6/site-packages/requests/adapters.py”, line 449, in send
timeout=timeout
File “/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py”, line 638, in urlopen
_stacktrace=sys.exc_info()[2])
File “/usr/local/lib/python3.6/site-packages/urllib3/util/retry.py”, line 398, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host=‘cn-api.coolkit.cc’, port=8080): Max retries exceeded with url: /api/user/login (Caused by NewConnectionError(‘<urllib3.connection.VerifiedHTTPSConnection object at 0x725414d0>: Failed to establish a new connection: [Errno -3] Try again’,))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/usr/local/lib/python3.6/site-packages/homeassistant/setup.py”, line 145, in _async_setup_component
hass, processed_config)
File “/config/custom_components/sonoff.py”, line 49, in async_setup
hass.data[DOMAIN] = Sonoff(hass, config)
File “/config/custom_components/sonoff.py”, line 88, in init
self.do_login()
File “/config/custom_components/sonoff.py”, line 129, in do_login
headers=self._headers, json=app_details)
File “/usr/local/lib/python3.6/site-packages/requests/api.py”, line 116, in post
return request(‘post’, url, data=data, json=json, **kwargs)
File “/usr/local/lib/python3.6/site-packages/requests/api.py”, line 60, in request
return session.request(method=method, url=url, **kwargs)
File “/usr/local/lib/python3.6/site-packages/requests/sessions.py”, line 533, in request
resp = self.send(prep, **send_kwargs)
File “/usr/local/lib/python3.6/site-packages/requests/sessions.py”, line 646, in send
r = adapter.send(request, **kwargs)
File “/usr/local/lib/python3.6/site-packages/requests/adapters.py”, line 516, in send
raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPSConnectionPool(host=‘cn-api.coolkit.cc’, port=8080): Max retries exceeded with url: /api/user/login (Caused by NewConnectionError(‘<urllib3.connection.VerifiedHTTPSConnection object at 0x725414d0>: Failed to establish a new connection: [Errno -3] Try again’,))

does anyone shed me some insight? does this connection need proxy again? how to setup?

Try changing your DNS settings of your router. Got similar errors for some other component. So worth a try.

@forums2012 Thanks, will try to change DNS from 8.8.8.8 to 1.1.1.1 for my router when I get home. Just curious, why only this component. I tried restart hassio, and restart my Pi remotely, changing api region to cn & us , still no luck (got the same error).

Was in a pretty similar situation with some other component. And this exact step worked.
Also was helpful that I didn’t try to connect to the component’s server for one whole day in order to avoid max retries excluded error.

i think you might’ve found a nice bug-improvement. i really don’t know what it’s going on with your HA setup of if you are passing thru some firewall/pi-hole or alike but your access to the internet looks a bit inconsistent, that’s why, judging from this error from logs above

urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host=‘cn-api.coolkit.cc’, port=8080): Max retries exceeded with url: /api/user/login (Caused by NewConnectionError(’<urllib3.connection.VerifiedHTTPSConnection object at 0x725414d0>: Failed to establish a new connection: [Errno -3] Try again’,))

it looks like this component it’s not able to connect to coolkit.cc servers.
i’ll push a quick change (soon-ish) and add the option to specify a (http) proxy server for this component connection (which is a bit redundant but it might just work in your case), i might say though that you might expect extra connection errors depending on how reliable or not is the proxy that you use.

i’ll let you know when you can retry it, help is on the way :wink:

yes, I did using Pi Hole as primary dns & 8.8.8.8 as secondary dns, and I’m using DuckDns with letsencrypt option.

FYI, I did tried to connect to cn-api.coolkit.cc:8080 and us-api.coolkit.cc:8080 via browser in my another laptop (all are routed through pi hole & 8.8.8.8) looks no problem (it displays “Welcome to OpenResty!” ), so I never suspect problem related to DNS.

Many thanks for the effort @peterbuga

So basically just need to change the main sonoff.py file right?
And add debug: true in config

@e-budianto might sound a bit weird but it’s unclear to me if you finally got it running or not :sweat_smile: can you please clarify it?

@forums2012 yes, just change the main sonoff.py from websocket-debug branch and you’re good to go :wink:

Peterbuga how can I update your component? I have sonoff basic pow r2 and 4ch pro

I just wanted to post my thanks @peterbuga . I added this and it worked perfectly for my Sonoff SV.

1 Like