Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New device: Sonoff B02 #269

Closed
tomlevels opened this issue Oct 30, 2020 · 37 comments
Closed

New device: Sonoff B02 #269

tomlevels opened this issue Oct 30, 2020 · 37 comments
Labels
enhancement New feature or request

Comments

@tomlevels
Copy link

tomlevels commented Oct 30, 2020

Here the dump for a new device (dump contains 2 instances): Sonoff B02. I can use it as a switch or light, but I cannot control the brightness or color.
[
{
"__v": 0,
"_id": "[hidden]",
"apikey": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"brandLogoUrl": "https://eu-ota.coolkit.cc/logo/q62PevoglDNmwUJ9oPE7kRrpt1nL1CoA.png",
"brandName": "SONOFF",
"createdAt": "xxxx-xx-xxxxx:xx:xx.xxx",
"devConfig": {},
"devGroups": [],
"deviceUrl": "",
"deviceid": "[hidden]",
"devicekey": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"extra": {
"id": "[hidden]",
"extra": {
"apmac": "xx:xx:xx:xx:xx:xx",
"brandId": "5c4c1aee3a7d24c7100be054",
"description": "20200806001",
"mac": "xx:xx:xx:xx:xx:xx",
"manufacturer": "\u6df1\u5733\u677e\u8bfa\u6280\u672f\u6709\u9650\u516c\u53f8",
"model": "WTW-SNL-02",
"modelInfo": "5e7a146548af4f7140874c8e",
"ui": "\u53cc\u8272\u51b7\u6696\u706f\u652f\u6301\u968f\u8c03\u53ca\u573a\u666f",
"uiid": 103
}
},
"family": {
"id": "5ea32db98011010008ceba36",
"index": 0
},
"group": "",
"groups": [],
"ip": "[hidden]",
"location": "",
"name": "[hidden]",,
"offlineTime": "xxxx-xx-xxxxx:xx:xx.xxx",
"online": true,
"onlineTime": "xxxx-xx-xxxxx:xx:xx.xxx",
"params": {
"OTA": "success",
"bindInfos": {
"gaction": [
"57727a4d-330d-4e21-8656-4b0328b42dfd_ewelinkGoogleHome"
]
},
"fwVersion": "1.3.1",
"ltype": "white",
"selfApikey": "",
"sequence": "123456789",
"switch": "on",
"version": 7,
"white": {
"br": 12,
"ct": 105
}
},
"productModel": "B02",
"settings": {
"alarmNotify": 1,
"appDoorbellNotify": 1,
"opsHistory": 1,
"opsNotify": 0,
"wxAlarmNotify": 0,
"wxDoorbellNotify": 0,
"wxOpsNotify": 0
},
"shareUsersInfo": [],
"sharedTo": [],
"showBrand": true,
"type": "10",
"uiid": 103
},
{
"__v": 0,
"_id": "[hidden]",
"apikey": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"brandLogoUrl": "https://eu-ota.coolkit.cc/logo/q62PevoglDNmwUJ9oPE7kRrpt1nL1CoA.png",
"brandName": "SONOFF",
"createdAt": "xxxx-xx-xxxxx:xx:xx.xxx",
"devConfig": {},
"devGroups": [],
"deviceUrl": "",
"deviceid": "[hidden]",
"devicekey": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"extra": {
"id": "[hidden]",
"extra": {
"apmac": "xx:xx:xx:xx:xx:xx",
"brandId": "5c4c1aee3a7d24c7100be054",
"description": "20200806001",
"mac": "xx:xx:xx:xx:xx:xx",
"manufacturer": "\u6df1\u5733\u677e\u8bfa\u6280\u672f\u6709\u9650\u516c\u53f8",
"model": "WTW-SNL-02",
"modelInfo": "5e7a146548af4f7140874c8e",
"ui": "\u53cc\u8272\u51b7\u6696\u706f\u652f\u6301\u968f\u8c03\u53ca\u573a\u666f",
"uiid": 103
}
},
"family": {
"id": "5ea32db98011010008ceba36",
"index": -1
},
"group": "",
"groups": [],
"ip": "[hidden]",
"location": "",
"name": "[hidden]",,
"offlineTime": "xxxx-xx-xxxxx:xx:xx.xxx",
"online": true,
"onlineTime": "xxxx-xx-xxxxx:xx:xx.xxx",
"params": {
"OTA": "success",
"bindInfos": {
"gaction": [
"57727a4d-330d-4e21-8656-4b0328b42dfd_ewelinkGoogleHome"
]
},
"fwVersion": "1.3.1",
"ltype": "white",
"selfApikey": "",
"sequence": "123456789",
"switch": "on",
"version": 7,
"white": {
"br": 34,
"ct": 85
}
},
"productModel": "B02",
"settings": {
"alarmNotify": 1,
"appDoorbellNotify": 1,
"opsHistory": 1,
"opsNotify": 0,
"wxAlarmNotify": 0,
"wxDoorbellNotify": 0,
"wxOpsNotify": 0
},
"shareUsersInfo": [],
"sharedTo": [],
"showBrand": true,
"type": "10",
"uiid": 103
}
]

@tomlevels
Copy link
Author

I already found out that I can control the device using the sonoff_sendcommand:
device: xxxxxxxx
white: { br: 30, ct: 100 }

I am now trying to hack this, but since I never programmed in Python, I did not succeed yet.
If you do this:
device: xxxxxxxx
white: { br: 30, ct: 100 }
switch: 'on'
It will always go off first and then go to the configured white setting. If it is off and you just send the white value, it goes on to the correct value. So the switch command does not have to be sent, only the white value.

@tomlevels
Copy link
Author

tomlevels commented Oct 30, 2020

I already fixed it myself (kind of). This code works for me now (first time Python for me, so it can be improved):

`
class Sonoff103(EWeLinkToggle):
_brightness = None
_temp = None

def _update_handler(self, state: dict, attrs: dict):
    self._attrs.update(attrs)

    if 'switch' in state:
        self._is_on = state['switch'] == 'on'

    if 'ltype' in state:
        state = state['white']

        if 'br' in state:
            # 1..100 => 1..255
            br = state['br']
            self._brightness = \
                round(1.0 + (br - 1.0) / (100.0 - 1.0) * 254.0)

        if 'ct' in state:
            # 0..255 => 500..153
            ct = state['ct']
            self._temp = round(500.0 - ct / 255.0 * (500.0 - 153.0))

    self.schedule_update_ha_state()

@property
def brightness(self):
    """Return the brightness of this light between 0..255."""
    return self._brightness

@property
def color_temp(self):
    """Return the CT color value in mireds."""
    return self._temp

@property
def supported_features(self):
    return SUPPORT_BRIGHTNESS | SUPPORT_COLOR_TEMP

@property
def capability_attributes(self):
    return {
        ATTR_MIN_MIREDS: 153,
        ATTR_MAX_MIREDS: 500
    }

@property
def state_attributes(self):
    return {
        **self._attrs,
        ATTR_BRIGHTNESS: self._brightness,
        ATTR_COLOR_TEMP: self._temp,
    }

async def async_turn_on(self, **kwargs) -> None:
    payload = { 'switch': 'on' }
    if (ATTR_BRIGHTNESS in kwargs or ATTR_COLOR_TEMP in kwargs):
        payload = {}
        br = kwargs.get(ATTR_BRIGHTNESS) or self._brightness or 1
        ct = kwargs.get(ATTR_COLOR_TEMP) or self._temp or 153
        payload['white'] = {
            'br': int(round((br - 1.0) * (100.0 - 1.0) / 254.0 + 1.0)),
            'ct': int(round((500.0 - ct) / (500.0 - 153.0) * 255.0))
        }

    await self.registry.send(self.deviceid, payload)

`

@tomlevels
Copy link
Author

Can this be added into the existing code at some point?

@AlexxIT
Copy link
Owner

AlexxIT commented Nov 5, 2020

Yes. Sorry. All my latest time on other project.

@thomasadelhardt
Copy link
Contributor

thomasadelhardt commented Nov 5, 2020

I have also been working at this, it looks like the FS-1 and the B02 bulb are actually the same bulb.
In my code the scenes are also included.
(Code removed, because newer code in the "Pull requests" section)

@tomlevels
Copy link
Author

I am not sure which device the FS-1 is (which brand)? But anyhow, your code seems to work fine (even better than my code) for my Sonoff B02, thanks a lot!

@thomasadelhardt
Copy link
Contributor

thomasadelhardt commented Nov 6, 2020

I think that the FortuneShip FS-1 is actually the same bulb as the Sonoff B02.
I purchased the FS-1, in febuary 2020.
I guess it make sense if Sonoff first wanted to test it on the market before putting there name on the box.

Here is the info from .sonoff.json file:
`

{
"1000b3e4d9": {
"settings": {
"opsNotify": 0,
"opsHistory": 1,
"alarmNotify": 1,
"wxAlarmNotify": 0,
"wxOpsNotify": 0,
"wxDoorbellNotify": 0,
"appDoorbellNotify": 1
},
"family": {
"room": {
"id": "5ea471f085bea80007006e1d"
},
"id": "5ea471f085bea80007006e1e",
"index": -1
},
"group": "",
"online": true,
"shareUsersInfo": [
{
"family": {
"id": "5f95928eb20c0a0007e60067",
"index": 0
},
"apikey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"permit": 15,
"shareDate": "2020-10-25T15:03:50.267Z",
"comment": ""
}
],
"groups": [],
"devGroups": [],
"_id": "5ea475659916be00081309b1",
"deviceid": "1000b3e4d9",
"name": "Udelys",
"type": "10",
"apikey": "1affa42f-64cf-4aaa-acc5-7e6a4fa5e9ed",
"extra": {
"extra": {
"uiid": 103,
"description": "",
"brandId": "5da282716cc4c3b59fa01a81",
"apmac": "d0:27:01:67:c7:03",
"mac": "d0:27:01:67:c7:02",
"ui": "双色冷暖灯_支持随调及场景",
"modelInfo": "5da686d0f8544da50466b402",
"model": "WTW-705-GL",
"manufacturer": "贵州财富之舟科技有限公司"
},
"_id": "5dae57358c903fbc50646333"
},
"params": {
"bindInfos": {
"gaction": [
"xxxxxx-xxxx-xxxx-xxxx-7e6a4fa5e9ed_ewelinkGoogleHome"
]
},
"version": 7,
"switch": "on",
"ltype": "white",
"white": {
"br": 76,
"ct": 130
},
"fwVersion": "1.4.8",
"sequence": "123456789",
"selfApikey": "",
"nightLight": {
"br": 5,
"ct": 0
},
"read": {
"br": 50,
"ct": 0
},
"bright": {
"br": 100,
"ct": 255
},
"computer": {
"br": 20,
"ct": 255
},
"effect": "white"
},
"createdAt": "2020-04-25T17:37:41.665Z",
"__v": 0,
"onlineTime": "2020-11-05T00:03:34.501Z",
"ip": "xx.xx.xx.xx",
"location": "",
"tags": {
"m_e9ed_thom": "off",
"m_3a1a_thom": "on"
},
"offlineTime": "2020-11-05T00:03:21.204Z",
"sharedBy": {
"email": "myemail@mail.com",
"apikey": "XXXXXXXXXXXXXXXXXXXX",
"permit": 15,
"shareTime": 1603638230190
},
"devicekey": "9260c9a8-dd4f-41d4-905a-8b6d5e52ac35",
"deviceUrl": "",
"brandName": "FortuneShip",
"showBrand": true,
"brandLogoUrl": "",
"productModel": "FS-1",
"devConfig": {},
"uiid": 103
}
}
`

@AlexxIT AlexxIT added the enhancement New feature or request label Nov 10, 2020
@thomasadelhardt
Copy link
Contributor

tomlevels
I have modified the code quite a bit, and have made a pull request.
Could you see how it works for you?
Now when a effect has been chosen and the brightness or the color temperature slides is changed, the effect is reset to Custom.

@tomlevels
Copy link
Author

I just tested, everything works except for the effects (if I select them nothing happens). Maybe that's because I do not know how to configure the effects. The effect does go to custom when I manually change something, so that works.

@MortenVinding
Copy link

MortenVinding commented Nov 19, 2020

Excelent work @thomasadelhardt!

Just got a "Smart Cloud QMS-2C-CW" bulb from Aliexpress. Looks to be the same as the Sonoff:
https://www.aliexpress.com/item/1005001340237235.html

I have added your modifications, and it comes up as a bulb in home assistant, but I got a few issues with it:

  1. Seems there is no status returned. I can turn it on and off in lovelace, but it jumps back to off right after (the bulb stays on)
  2. There is no adjustment for color temperature. But if I cut the power to the bulb, wait until it goes offline in HA, and power it up again, I get color control (working), until I turn it off in HA... it does not come back when turning it on again in HA.

Here is my .sonoff.json file:
homeassistant@openHABianPi:~/.homeassistant $ cat .sonoff.json | jq "."
{
"1000faaf73": {
"settings": {
"opsNotify": 0,
"opsHistory": 1,
"alarmNotify": 1,
"wxAlarmNotify": 0,
"wxOpsNotify": 0,
"wxDoorbellNotify": 0,
"appDoorbellNotify": 1
},
"family": {
"id": "5fb3dcf2bae33000085802eb",
"index": 0
},
"group": "",
"online": true,
"shareUsersInfo": [],
"groups": [],
"devGroups": [],
"_id": "5fb5a2f29abee80008ffb6c4",
"deviceid": "1000faaf73",
"name": "Devicefaaf73",
"type": "10",
"apikey": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"extra": {
"extra": {
"uiid": 103,
"description": "2020-09-16 王斌成 编号:202009161401000519262\n",
"brandId": "5e7a14d748af4f7140874c97",
"apmac": "d0:27:01:f5:5c:37",
"mac": "d0:27:01:f5:5c:36",
"ui": "双色冷暖灯_支持随调及场景",
"modelInfo": "5f606f23a2d4f5a009b429b0",
"model": "BOL-ZHI-DL",
"manufacturer": "深圳市启明智云科技有限公司"
},
"_id": "5f61ad6da2d4f5a009b432ff"
},
"createdAt": "2020-11-18T22:40:50.958Z",
"__v": 0,
"onlineTime": "2020-11-18T22:40:52.812Z",
"params": {
"version": 7,
"switch": "off",
"ltype": "white",
"white": {
"br": 10,
"ct": 77
},
"fwVersion": "1.0.1"
},
"ip": "109.198.138.133",
"location": "",
"sharedTo": [],
"devicekey": "13607c29-8dfd-4f73-9750-37b6fa35566f",
"deviceUrl": "",
"brandName": "QM Smart Cloud",
"showBrand": true,
"brandLogoUrl": "https://eu-ota.coolkit.cc/logo/Zcy2dJqOuqvpIJW4cGIwoE6k01YQyMwh.jpg",
"productModel": "QMS-2C-CW",
"devConfig": {},
"uiid": 103
}
}

@thomasadelhardt
Copy link
Contributor

I just tested, everything works except for the effects (if I select them nothing happens). Maybe that's because I do not know how to configure the effects. The effect does go to custom when I manually change something, so that works.

For some reason the effect settings are specified in my sonoff.json, my code read these and stores them, so they can be assigned to the bulb when a effect is selected.
Guess i have to hardcode them.

@thomasadelhardt
Copy link
Contributor

Excelent work @thomasadelhardt!

Just got a "Smart Cloud QMS-2C-CW" bulb from Aliexpress. Looks to be the same as the Sonoff:
https://www.aliexpress.com/item/1005001340237235.html

I have added your modifications, and it comes up as a bulb in home assistant, but I got a few issues with it:

  1. Seems there is no status returned. I can turn it on and off in lovelace, but it jumps back to off right after (the bulb stays on)
  2. There is no adjustment for color temperature. But if I cut the power to the bulb, wait until it goes offline in HA, and power it up again, I get color control (working), until I turn it off in HA... it does not come back when turning it on again in HA.

Thank you.
By adding "mode: local" to the configuration.yaml file, I am able to replicate your problem.
Because the bulb doesn't support local mode, the setting in lovelace aren't sent to the bulb.
And therefore Lovelace doesn't get a status update from the bulb, so the button in Lovelace jumps back...
So if you have mode:local in you configuration.yaml file, then try commenting it out.

@thomasadelhardt
Copy link
Contributor

thomasadelhardt commented Nov 19, 2020

I have tried to edit the code in my pull request, but not sure how it works, but here is the new code with hard coded values for the effects:

SONOFF103_EFFECTS = {
    'none': 'Custom',
    'nightLight': 'Night',
    'read': 'Reading',
    'computer': 'Work',
    'bright': 'Bright'
}

class Sonoff103(EWeLinkToggle):
# To Do:
#   Dont know how to get the "productModel", there are multiple bulbs models with uuid 103. They dont have the same color temperature range.
#   Model "FS-1" looks to be 2200-6500 Kelvin
#   Model "B02-F-A60"  is 2200K-6500K
#   Model "B02-F-ST64" is 1800K-5000K

    _ColorKelvinWarmest = 2200
    _ColorKelvinColdest = 6500
    _ColorMiredsWarmest = 1000000/_ColorKelvinWarmest
    _ColorMiredsColdest = 1000000/_ColorKelvinColdest
    
    _brightness = 0.0
    _colortemp = 0.0
    
    _effect = None


    def _update_handler(self, state: dict, attrs: dict):
        self._attrs.update(attrs)

        if 'switch' in state:
            self._is_on = state['switch'] == 'on'
        
        if 'effect' in state:
            if state['effect'] in SONOFF103_EFFECTS.keys(): 
                self._effect = state['effect']

        if 'white' in state:
            # only update brigthness-slider if brightness has changed, as the indicator might jump a bit because of round(). the bulb use percent HASS use 1...255 (1..100 => 1..255)
            if round(self._brightness) != round((state['white']['br']*2.55)):
                self._brightness = state['white']['br'] * 2.55

            # only update brigthness-slider if brightness has changed, as the indicator might jump a bit because of round(). the bulb use 0...255, HASS use Mireds (0..255 => Mireds)
            if round(self._colortemp) != round(self._ColorMiredsWarmest - state['white']['ct'] / 255.0 * (self._ColorMiredsWarmest - self._ColorMiredsColdest)):
                self._colortemp = self._ColorMiredsWarmest - state['white']['ct'] / 255.0 * (self._ColorMiredsWarmest - self._ColorMiredsColdest)


        self.schedule_update_ha_state()

    @property
    def brightness(self):
        """Return the brightness of this light between 0..255."""
        return self._brightness

    @property
    def color_temp(self):
        """Return the CT color value in mireds."""
        return self._colortemp

    @property
    def effect_list(self):
        """Return the list of supported effects."""
        return list(SONOFF103_EFFECTS.values())

    @property
    def effect(self):
        """Return the current effect."""
        return SONOFF103_EFFECTS[self._effect]

    @property
    def supported_features(self):
        return SUPPORT_BRIGHTNESS | SUPPORT_COLOR_TEMP | SUPPORT_EFFECT

    @property
    def capability_attributes(self):
        return {
            ATTR_EFFECT_LIST: self.effect_list,
            ATTR_MIN_MIREDS: round(self._ColorMiredsColdest), 
            ATTR_MAX_MIREDS: round(self._ColorMiredsWarmest)
        }

    @property
    def state_attributes(self):
        return {
            **self._attrs,
            ATTR_BRIGHTNESS: self.brightness,
            ATTR_COLOR_TEMP: self.color_temp,
            ATTR_EFFECT: self.effect
        }

    async def async_turn_on(self, **kwargs) -> None:
        payload = {'switch': 'on'}

        if ATTR_EFFECT in kwargs:
            _LOGGER.debug("Yes ATTR_EFFECT in kwargs: ATTR_EFFECT=" + str(kwargs[ATTR_EFFECT]) + " kwargs="+ str(kwargs) )
            payload = {}

            if kwargs[ATTR_EFFECT] in SONOFF103_EFFECTS.values(): 

                mode = payload['effect'] = next(k for k, v in SONOFF103_EFFECTS.items() if v == kwargs[ATTR_EFFECT])

                if mode == 'nightLight':
                    payload['white'] = {
                        'br': 5,
                        'ct': 0
                    }
                elif mode == 'read':
                    payload['white'] = {
                        'br': 50,
                        'ct': 0
                    }
                elif mode == 'computer':
                    payload['white'] = {
                        'br': 20,
                        'ct': 255
                    }
                elif mode == 'bright':
                    payload['white'] = {
                        'br': 100,
                        'ct': 255
                    }


        else:
            payload = {}
            payload['effect'] = 'none'

            br = kwargs.get(ATTR_BRIGHTNESS) or self._brightness or 1
            ct = kwargs.get(ATTR_COLOR_TEMP) or self._colortemp or self._ColorMiredsColdest

            payload['white'] = {
                'br': round(br/2.55),
                'ct': round((self._ColorMiredsWarmest - ct) / (self._ColorMiredsWarmest - self._ColorMiredsColdest) * 255.0)
            }


        await self.registry.send(self.deviceid, payload)

@MortenVinding
Copy link

Thank you.
By adding "mode: local" to the configuration.yaml file, I am able to replicate your problem.
Because the bulb doesn't support local mode, the setting in lovelace aren't sent to the bulb.
And therefore Lovelace doesn't get a status update from the bulb, so the button in Lovelace jumps back...
So if you have mode:local in you configuration.yaml file, then try commenting it out.

Sorry no my configuration.yaml file only has:
sonoff:
username: morten
password: xxxxx

I have just tried to add mode:cloud but that doesn’t change the behavior.

I have one more of these bulbs, new in the box.
Will try to add that and see if it’s the same.

@thomasadelhardt
Copy link
Contributor

Thank you.
By adding "mode: local" to the configuration.yaml file, I am able to replicate your problem.
Because the bulb doesn't support local mode, the setting in lovelace aren't sent to the bulb.
And therefore Lovelace doesn't get a status update from the bulb, so the button in Lovelace jumps back...
So if you have mode:local in you configuration.yaml file, then try commenting it out.

Sorry no my configuration.yaml file only has:
sonoff:
username: morten
password: xxxxx

I have just tried to add mode:cloud but that doesn’t change the behavior.

I have one more of these bulbs, new in the box.
Will try to add that and see if it’s the same.

Okay.
I'll recommend you also add debug:true
By the way, you should be aware that there are some problems if you use the same user/username in the app and i HASS.
You should register a new user at ewelink, and share the bulbs with that new user. Use the new username in HASS.


sonoff:
username: morten_NewUserNameForHass
password: xxxxx
mode: cloud
debug: true # Look at the notification section, a debug link will appear

@MortenVinding
Copy link

Okay.
I'll recommend you also add debug:true
By the way, you should be aware that there are some problems if you use the same user/username in the app and i HASS.
You should register a new user at ewelink, and share the bulbs with that new user. Use the new username in HASS.

adding debug...
Not sure what you mean with same user? Same as the user I login to HA with?

@MortenVinding
Copy link

Okay so I added debug. Very handy!

Also I added the other bulb, funny enough that worked with bluetooth, I couldn't get that working with the other bulb.

I created a new ewelink account using another email address, and shared the bulb's with that account.
Changed HASS to use that account, but unfortunately the problem remains the same.

Debug log from HASS start up, and turning the bulb on:
2020-11-19 22:06:28 DEBUG main SysInfo: {'version': '0.116.4', 'dev': False, 'hassio': False, 'virtualenv': True, 'python_version': '3.7.3', 'docker': False, 'arch': 'armv7l', 'os_name': 'Linux', 'os_version': '5.4.72-v7+'}
2020-11-19 22:06:28 DEBUG main AUTO mode start
2020-11-19 22:06:32 DEBUG sonoff_cloud 2 devices loaded from the Cloud Server
2020-11-19 22:06:32 DEBUG main 1000faaf73 == Init | {'uiid': 103, 'extra': {'manufacturer': 'QM Smart Cloud', 'model': 'QMS-2C-CW', 'sw_version': 'BOL-ZHI-DL v1.0.1'}, 'params': {'version': 7, 'switch': 'off', 'ltype': 'white', 'white': {'br': 41, 'ct': 26}, 'fwVersion': '1.0.1', 'cloud': 'online'}}
2020-11-19 22:06:32 DEBUG main 1000faaec4 == Init | {'uiid': 103, 'extra': {'manufacturer': 'QM Smart Cloud', 'model': 'QMS-2C-CW', 'sw_version': 'BOL-ZHI-DL v1.0.1'}, 'params': {'version': 7, 'switch': 'off', 'ltype': 'white', 'white': {'br': 41, 'ct': 77}, 'fwVersion': '1.0.1', 'cloud': 'online'}}
2020-11-19 22:06:35 DEBUG light ---------------------------------------------------------------------------------------
2020-11-19 22:06:35 DEBUG light round(self._temp):0!=424
2020-11-19 22:06:35 DEBUG light round(self._temp):0!=364
2020-11-19 22:06:35 DEBUG sonoff_cloud Cloud init: {'error': 0, 'apikey': '...', 'config': {'hb': 1, 'hbInterval': 145}, 'sequence': '1605819995793'}
2020-11-19 22:07:55 DEBUG light 363.74605786370495
2020-11-19 22:07:55 DEBUG sonoff_cloud 1000faaec4 => Cloud4 | {'ltype': 'white', 'white': {'br': 41, 'ct': 77}} | 1605820075104
2020-11-19 22:07:55 DEBUG sonoff_cloud 1000faaec4 <= Cloud3 | {'error': 0, 'deviceid': '1000faaec4', 'apikey': '...', 'sequence': '1605820075104'}
2020-11-19 22:07:55 DEBUG sonoff_cloud 1000faaec4 => Cloud5 | Force update sequence: 1605820075238
2020-11-19 22:07:55 DEBUG sonoff_cloud 1000faaec4 <= Cloud3 | {'error': 0, 'deviceid': '1000faaec4', 'apikey': '...', 'sequence': '1605820075238', 'params': {'version': 7, 'switch': 'off', 'ltype': 'white', 'white': {'br': 41, 'ct': 77}, 'fwVersion': '1.0.1'}}
2020-11-19 22:07:55 DEBUG light round(self._temp):364!=364

@thomasadelhardt
Copy link
Contributor

thomasadelhardt commented Nov 19, 2020

That looks like it is some of my old code, could you try the updated code at:
https://github.com/thomasadelhardt/SonoffLAN/tree/master/custom_components
Url updated

@thomasadelhardt
Copy link
Contributor

Okay.
I'll recommend you also add debug:true
By the way, you should be aware that there are some problems if you use the same user/username in the app and i HASS.
You should register a new user at ewelink, and share the bulbs with that new user. Use the new username in HASS.

adding debug...
Not sure what you mean with same user? Same as the user I login to HA with?

You have to have 2 different users/accounts registered at ewelink.
1 that you use in the app (Lets call this the main account)
And 1 that you use in the sonoff section in the configuration.yaml (Lets call this the secondary account)

In the app log out of your main account. (Profile -> Picture of gear -> Log out)
At the Log in screen make new account (Secondary account).
...Mayby some extra steps here, like verifying email
Log in with main account, choose to share bulbs with secondary account.
Edit configuration.yaml and use the secondary account in the sonoff section:

sonoff:
username: mortens_secondary_account_only_used_here_in_the_sonoff_section_of_HASS_configuration_:-)
password: xxxxx
mode: cloud
debug: true # Look at the notification section, a debug link will appear

@MortenVinding
Copy link

Okay.
I'll recommend you also add debug:true
By the way, you should be aware that there are some problems if you use the same user/username in the app and i HASS.
You should register a new user at ewelink, and share the bulbs with that new user. Use the new username in HASS.

adding debug...
Not sure what you mean with same user? Same as the user I login to HA with?

You have to have 2 different users/accounts registered at ewelink.
1 that you use in the app (Lets call this the main account)
And 1 that you use in the sonoff section in the configuration.yaml (Lets call this the secondary account)

In the app log out of your main account. (Profile -> Picture of gear -> Log out)
At the Log in screen make new account (Secondary account).
...Mayby some extra steps here, like verifying email
Log in with main account, choose to share bulbs with secondary account.
Edit configuration.yaml and use the secondary account in the sonoff section:

sonoff:
username: mortens_secondary_account_only_used_here_in_the_sonoff_section_of_HASS_configuration_:-)
password: xxxxx
mode: cloud
debug: true # Look at the notification section, a debug link will appear

That's exactly what I did.

Just realised my HASS is at 0.116.4, so working on upgrading that.
Also I'm not that strong in GitHub, so also will need some time to figure out how to download your newest version.

Thank you so much for all your help 👍 😊

@thomasadelhardt
Copy link
Contributor

@MortenVinding
Copy link

Here you go:
https://github.com/thomasadelhardt/SonoffLAN/archive/master.zip

Thanks a lot.

Unfortunately I can't get it to work, get this error in the log:

2020-11-20 00:48:36 ERROR (MainThread) [homeassistant.components.light] Error while setting up sonoff platform for light
Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.7/site-packages/homeassistant/helpers/entity_platform.py", line 207, in _async_setup_platform
    await asyncio.gather(*pending)
  File "/srv/homeassistant/lib/python3.7/site-packages/homeassistant/helpers/entity_platform.py", line 316, in async_add_entities
    await asyncio.gather(*tasks)
  File "/srv/homeassistant/lib/python3.7/site-packages/homeassistant/helpers/entity_platform.py", line 507, in _async_add_entity
    await entity.add_to_platform_finish()
  File "/srv/homeassistant/lib/python3.7/site-packages/homeassistant/helpers/entity.py", line 531, in add_to_platform_finish
    self.async_write_ha_state()
  File "/srv/homeassistant/lib/python3.7/site-packages/homeassistant/helpers/entity.py", line 296, in async_write_ha_state
    self._async_write_ha_state()
  File "/srv/homeassistant/lib/python3.7/site-packages/homeassistant/helpers/entity.py", line 322, in _async_write_ha_state
    attr.update(self.state_attributes or {})
  File "/home/homeassistant/.homeassistant/custom_components/sonoff/light.py", line 597, in state_attributes
    ATTR_EFFECT: self.effect
  File "/home/homeassistant/.homeassistant/custom_components/sonoff/light.py", line 577, in effect
    return SONOFF103_EFFECTS[self._effect]
KeyError: None

@thomasadelhardt
Copy link
Contributor

I have updated the code, hopefully it works now.
https://github.com/thomasadelhardt/SonoffLAN/archive/master.zip

@MortenVinding
Copy link

Thank you Thomas,

I updated with HACS, 43eecdd it says so I guess that is right.
Now it works again. Unfortunately it did not solve the update problem though.

All I ever see in the debug log is:
2020-11-20 11:26:40 DEBUG sonoff_cloud 1000faaf73 => Cloud4 | {'effect': 'none', 'white': {'br': 41, 'ct': 26}} | 1605868000598
2020-11-20 11:26:40 DEBUG sonoff_cloud 1000faaf73 <= Cloud3 | {'error': 0, 'deviceid': '1000faaf73', 'apikey': '...', 'sequence': '1605868000598'}
2020-11-20 11:26:40 DEBUG sonoff_cloud 1000faaf73 => Cloud5 | Force update sequence: 1605868000698
2020-11-20 11:26:40 DEBUG sonoff_cloud 1000faaf73 <= Cloud3 | {'error': 0, 'deviceid': '1000faaf73', 'apikey': '...', 'sequence': '1605868000698', 'params': {'version': 7, 'switch': 'off', 'ltype': 'white', 'white': {'br': 41, 'ct': 26}, 'fwVersion': '1.0.1', 'effect': 'none'}}

This is me turning the bulb on, so I guess the integration receives an "off" right after turning it on

@MortenVinding
Copy link

Just realised that turning the bulbs on in the eWeLink app is in fact correctly reflected in HASS.
When I turn them on that way I can control color temperature in HASS.

Here is the log lines when turning on in the eWe app:
2020-11-20 12:19:05 DEBUG sonoff_cloud 1000faaf73 <= Cloud3 | {'action': 'update', 'deviceid': '1000faaf73', 'apikey': '...', 'userAgent': 'app', 'sequence': '1605871145214', 'ts': 0, 'params': {'switch': 'on'}, 'tempRec': '1000faaf73'}
2020-11-20 12:19:06 DEBUG sonoff_cloud 1000faaf73 <= Cloud3 | {'action': 'update', 'deviceid': '1000faaf73', 'apikey': '...', 'userAgent': 'app', 'sequence': '1605871146357', 'ts': 0, 'params': {'switch': 'off'}, 'tempRec': '1000faaf73'}

@thomasadelhardt
Copy link
Contributor

thomasadelhardt commented Nov 20, 2020

I found out I wasn't sending scene/effects commands to the bulb as it where supposed to be done.
So started all over from scratch.
Hope that it fixed the issues you guys are having.
Anyway when a scene in the app is selected its reflected in Lovelace now.
https://github.com/thomasadelhardt/SonoffLAN/archive/master.zip

@MortenVinding
Copy link

Wheeee!!!
Just updated and everything works perfectly now!

Thank you so much. I owe you one! 👍

@thomasadelhardt
Copy link
Contributor

Nice to hear.
On my end it also works perfect now, I think the code is ready for merging.

@MortenVinding
Copy link

sounds god.
Only wish we could have local control, but I guess that's at limitation in the bulb's?

@MortenVinding
Copy link

MortenVinding commented Nov 26, 2020

sorry had to rollback your latest commit on my HASS @thomasadelhardt (47af237) since it broke my bulb's again.

@AlexxIT
Copy link
Owner

AlexxIT commented Nov 30, 2020

I will merge when I have time. Sorry

@thomasadelhardt
Copy link
Contributor

sounds god.
Only wish we could have local control, but I guess that's at limitation in the bulb's?

Yup it is a limit in the bulb.
But it looks like there actually is a workaround, a Ewelink server running locally, but I don't know if it works.
Private Sonoff server

sorry had to rollback your latest commit on my HASS @thomasadelhardt (47af237) since it broke my bulb's again.

Sorry to hear that, I thought I had nailed it!
Do you have any idea why/when it fails?

Could you try if this branch/patch works?
https://github.com/thomasadelhardt/SonoffLAN/archive/thomasadelhardt-if_off_the_send-on.zip

I will merge when I have time. Sorry
Doesn't look like it is ready just yet anyway.

@MortenVinding
Copy link

MortenVinding commented Dec 8, 2020

Ohh very interesting with local control!
Did not expect we should be able to configure the server, and I did not want to mess around with DNS spoofing.
Definably will look in to that once I get the time.

Unfortunately the newest version is stil problematic. First I ran in to a problem about "No module named 'asyncio.exceptions'", which I found (here: https://github.com/AlexxIT/XiaomiGateway3/issues/58 was related to me still running Python 3.7.
I fixed it in this way:

--- ../../../sonoff-new/sonoff_local.py	2020-12-07 22:04:13.000000000 +0100
+++ sonoff_local.py	2020-12-08 17:21:51.779745256 +0100
@@ -3,7 +3,6 @@
 import json
 import logging
 import time
-from asyncio.exceptions import CancelledError
 from base64 import b64encode, b64decode
 from typing import Callable, List

@@ -294,7 +293,7 @@
         except asyncio.TimeoutError:
             _LOGGER.debug(f"{log} !! Timeout {timeout}")
             return 'timeout'
-        except (ClientOSError, ServerDisconnectedError, CancelledError) as e:
+        except (ClientOSError, ServerDisconnectedError, asyncio.CancelledError) as e:
             _LOGGER.debug(f"{log} !! {e.args}")
             return 'E#COS'
         except:

So now it loads.
But the bulb still appears as OFF, even when it is on. I can control brightness, and tun it ON, but son after it goes back to OFF in HA.

@thomasadelhardt
Copy link
Contributor

So now it loads.
But the bulb still appears as OFF, even when it is on. I can control brightness, and tun it ON, but son after it goes back to OFF in HA.

Okay, so the right commands are sent to the bulb, but the bulbs state is not reported back to HA..
It is hard to guess why.

What does your log say?

@edu24x
Copy link

edu24x commented Dec 10, 2020

photo_2020-12-10_23-31-25

Nice work, it works perfectly.

@AlexxIT
Copy link
Owner

AlexxIT commented Mar 10, 2021

Is B02 works fine in latest release?

@AlexxIT
Copy link
Owner

AlexxIT commented Apr 24, 2022

You can reopen issue if it's still relevant

@AlexxIT AlexxIT closed this as completed Apr 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants