home-assistant / core

:house_with_garden: Open source home automation that puts local control and privacy first.
https://www.home-assistant.io
Apache License 2.0
71.68k stars 29.96k forks source link

New Tuya device not shown - due to brightness / color conflict #28602

Closed s3ta closed 4 years ago

s3ta commented 4 years ago

Home Assistant release with the issue:

0.101.3

Last working Home Assistant release (if known):

Operating environment (Hass.io/Docker/Windows/etc.):

manual install on raspberry-pi4/buster Integration:

https://www.home-assistant.io/integrations/tuya/

Description of problem:

Problem-relevant configuration.yaml entries and (fill out even if it seems unimportant):

tuya:
  username: xxxxxxx
  password: xxxxxxx
  country_code: 49
  platform: smart_life

Traceback (if applicable):

Additional information: OK, please be kind - I'm new to all this (HA, python, git,...), did a lot of coding (e.g. perl), but never considered myself a developper nor do I know a lot about collaboration - hoping to get this right: I have a new tuya device (LED controller Model AM-WIFI-002 is all it says) set up w/ Smart Life. I do already have fully functional tuya integrations running that way. That new device did not show up in the frontend - checking the logs gave errors like:

Nov  7 08:57:01 hom-e-server hass[17315]: 2019-11-07 08:57:01 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Nov  7 08:57:01 hom-e-server hass[17315]: Traceback (most recent call last):
Nov  7 08:57:01 hom-e-server hass[17315]:   File "/srv/homeassistant/lib/python3.7/site-packages/homeassistant/helpers/entity.py", line 275, in async_update_ha_state
Nov  7 08:57:01 hom-e-server hass[17315]:     self._async_write_ha_state()
Nov  7 08:57:01 hom-e-server hass[17315]:   File "/srv/homeassistant/lib/python3.7/site-packages/homeassistant/helpers/entity.py", line 316, in _async_write_ha_state
Nov  7 08:57:01 hom-e-server hass[17315]:     attr.update(self.state_attributes or {})
Nov  7 08:57:01 hom-e-server hass[17315]:   File "/srv/homeassistant/lib/python3.7/site-packages/homeassistant/components/light/__init__.py", line 477, in state_attributes
Nov  7 08:57:01 hom-e-server hass[17315]:     data[ATTR_BRIGHTNESS] = self.brightness
Nov  7 08:57:01 hom-e-server hass[17315]:   File "/srv/homeassistant/lib/python3.7/site-packages/homeassistant/components/tuya/light.py", line 43, in brightness
Nov  7 08:57:01 hom-e-server hass[17315]:     if self.tuya.brightness() is None:
Nov  7 08:57:01 hom-e-server hass[17315]:   File "/srv/homeassistant/lib/python3.7/site-packages/tuyaha/devices/light.py", line 16, in brightness
Nov  7 08:57:01 hom-e-server hass[17315]:     brightness = int(self.data.get('color').get('brightness') * 255 / 100)
Nov  7 08:57:01 hom-e-server hass[17315]: AttributeError: 'NoneType' object has no attribute 'get'

Checking the code in /srv/homeassistant/lib/python3.7/site-packages/tuyaha/devices/light.py gives:

 13     def brightness(self):
 14         work_mode = self.data.get('color_mode')
 15         if work_mode == 'colour':
 16             brightness = int(self.data.get('color').get('brightness') * 255 / 100)
 17         else:
 18             brightness = self.data.get('brightness')
 19         return brightness

I interpret this as - if we are in color_mode we get the brightness as a subproperty of color (and convert it) .

But on this new device color obviously is handled differently, since self.data.get('color') is None.

As a workaround I fixed this like:

 15         if work_mode == 'colour' and not (self.data.get('color') is None) :

Now at least the device shows up and I can control the brightness by the slider. However the color picker does not show up in lovelace, therefore I assumed above that this device needs different color handling than my other devices.

Could you kindly point me to how to dig further? e.g. How to find out which properties that device has? Maybe I can contribute more in "the right way"...

frankosborne commented 4 years ago

Hey @s3ta

New here as well but I have been very keen to get this working.

Getting my hands dirty with the API directly. It has been fun getting across python after a few of years of not using it. I can see the following responses from the API (two device examples):

{u'name': u'Downlight', u'dev_type': u'light', u'ha_type': u'light', u'data': {u'color_temp': 16671, u'state': u'false', u'color_mode': u'white', u'online': True, u'brightness': u'1000'}, u'id': u'#omittied', u'icon': u'https://images.tuyaeu.com/smart/icon/ay1538034526214P1Rco/15592670851fa19689437.jpg'}, {u'name': u'Downlight', u'dev_type': u'light', u'ha_type': u'light', u'data': {u'color_temp': 16671, u'state': u'true', u'color_mode': u'colour', u'online': True, u'brightness': u'1000'}, u'id': u'#omitted', u'icon': u'https://images.tuyaeu.com/smart/icon/ay1538034526214P1Rco/15592670851fa19689437.jpg'}

Now having a play... I can see the color_mode is set to either 'white' or 'colour'. This is either the current state or the last state the light was in when it was last on as far as I can tell. Regardless of the color_mode being set to 'white' or 'colour'. No property is returned for 'color' as you can see above.

I have been able to set the colour manually via the API or through home assistant by setting a state but we still do not get a property of color returned from the API.

I am guessing that you are right and our devices handle colour differently. Unfortunately I expect there actually has to be an update on the homeassistant API from Tuya to resolve this.

s3ta commented 4 years ago

Hi @frankosborne,

Thanks for the feedback.

Somehow this seems related to: https://github.com/home-assistant/home-assistant/pull/26534 as well as https://github.com/home-assistant/home-assistant/issues/25163

So I'm hoping this gets resolved anytime soon by Tuya

Being curious - could you tell me, how and where I can see/inspect that "response from the API".

frankosborne commented 4 years ago

Oh good good. I was gonna alter the code to work around it but unless I can get the current colour setting from the API there isn't much of a point.

I created a python script in the top directory running the following (from a pulled instance of the tuyaha component:

import tuyaha.tuyaapi

instance = tuyaha.TuyaApi()

devices = instance.init('username','password','countrycode','platform') - same as your ha config

print instance._request('Discovery', 'devices')

This was in Sypder on Unbuntu. The devices variable is now an array with all of your devices. You can call the functions in devices.base or the class for the actual type of device.

doctordarko commented 4 years ago

Possibly the same issue here where the brightness/colour error comes up with the set of bulbs that only started working few days ago. Initially those 3 globes were not recognised by HA at all.

In my instance, the lights still come on via HA control slider but the sliders goes back to off position after which I can't control lights through HA.

Workaround I found is to set mode to white in the Tuya app, after which lights work as intended in HA but white only mode.

skynet01 commented 4 years ago

Whats interesting is if you group the light bulb with another light that supports color change and change the color of the group the color updates on the tuya properly. But to change it again (as it works once) you first have to change the warmth of the tuya bulb. This leads me to believe that this issue can be fixed on our end and not on Tuya API's end.

At the very least maybe the error can be fixed, since right now this will halt any script that uses lights. For example all my scripts that use group.all_lights will no longer work.

frankosborne commented 4 years ago

I experienced the same. I believe this is because the set property works fine and ha api will accept it.

But once it’s set to a colour, that’s when all hell breaks loose with tuyaha on our end. Which we can resolve but we will have very limited colour functionality.

On 13 Nov 2019, at 3:47 am, skynet01 notifications@github.com wrote:

 Whats interesting is if you group the light bulb with another light that supports color change and change the color of the group the color updates on the tuya properly. But to change it again (as it works once) you first have to change the warmth of the tuya bulb. This leads me to believe that this issue can be fixed on our end and not on Tuya API's end.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

skynet01 commented 4 years ago

Any progress on this? Where can I donate money to get this fixed 😂

Unixman77 commented 4 years ago

Home Assistant release with the issue:

0.101.3

Last working Home Assistant release (if known):

Operating environment (Hass.io/Docker/Windows/etc.):

manual install on raspberry-pi4/buster Integration:

https://www.home-assistant.io/integrations/tuya/

Description of problem:

Problem-relevant configuration.yaml entries and (fill out even if it seems unimportant):

tuya:
  username: xxxxxxx
  password: xxxxxxx
  country_code: 49
  platform: smart_life

Traceback (if applicable):

Additional information: OK, please be kind - I'm new to all this (HA, python, git,...), did a lot of coding (e.g. perl), but never considered myself a developper nor do I know a lot about collaboration - hoping to get this right: I have a new tuya device (LED controller Model AM-WIFI-002 is all it says) set up w/ Smart Life. I do already have fully functional tuya integrations running that way. That new device did not show up in the frontend - checking the logs gave errors like:

Nov  7 08:57:01 hom-e-server hass[17315]: 2019-11-07 08:57:01 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Nov  7 08:57:01 hom-e-server hass[17315]: Traceback (most recent call last):
Nov  7 08:57:01 hom-e-server hass[17315]:   File "/srv/homeassistant/lib/python3.7/site-packages/homeassistant/helpers/entity.py", line 275, in async_update_ha_state
Nov  7 08:57:01 hom-e-server hass[17315]:     self._async_write_ha_state()
Nov  7 08:57:01 hom-e-server hass[17315]:   File "/srv/homeassistant/lib/python3.7/site-packages/homeassistant/helpers/entity.py", line 316, in _async_write_ha_state
Nov  7 08:57:01 hom-e-server hass[17315]:     attr.update(self.state_attributes or {})
Nov  7 08:57:01 hom-e-server hass[17315]:   File "/srv/homeassistant/lib/python3.7/site-packages/homeassistant/components/light/__init__.py", line 477, in state_attributes
Nov  7 08:57:01 hom-e-server hass[17315]:     data[ATTR_BRIGHTNESS] = self.brightness
Nov  7 08:57:01 hom-e-server hass[17315]:   File "/srv/homeassistant/lib/python3.7/site-packages/homeassistant/components/tuya/light.py", line 43, in brightness
Nov  7 08:57:01 hom-e-server hass[17315]:     if self.tuya.brightness() is None:
Nov  7 08:57:01 hom-e-server hass[17315]:   File "/srv/homeassistant/lib/python3.7/site-packages/tuyaha/devices/light.py", line 16, in brightness
Nov  7 08:57:01 hom-e-server hass[17315]:     brightness = int(self.data.get('color').get('brightness') * 255 / 100)
Nov  7 08:57:01 hom-e-server hass[17315]: AttributeError: 'NoneType' object has no attribute 'get'

Checking the code in /srv/homeassistant/lib/python3.7/site-packages/tuyaha/devices/light.py gives:

 13     def brightness(self):
 14         work_mode = self.data.get('color_mode')
 15         if work_mode == 'colour':
 16             brightness = int(self.data.get('color').get('brightness') * 255 / 100)
 17         else:
 18             brightness = self.data.get('brightness')
 19         return brightness

I interpret this as - if we are in color_mode we get the brightness as a subproperty of color (and convert it) .

But on this new device color obviously is handled differently, since self.data.get('color') is None.

As a workaround I fixed this like:

 15         if work_mode == 'colour' and not (self.data.get('color') is None) :

Now at least the device shows up and I can control the brightness by the slider. However the color picker does not show up in lovelace, therefore I assumed above that this device needs different color handling than my other devices.

Could you kindly point me to how to dig further? e.g. How to find out which properties that device has? Maybe I can contribute more in "the right way"...

Hi sir, I've had same issue, and I tried to modify line 15 like you did but I didn't find script : light.py in the location that is mentioned in log: /usr/local/lib/python3.7/site-packages/tuyaha/devices/light.py? if you have any idea how can I reach this path I appreciate it if you show me how. I'm using hassio image , I think is a docker but I don't get any clue to get to the hypervisor to update this light.py

s3ta commented 4 years ago

Hi sir, I've had same issue, and I tried to modify line 15 like you did but I didn't find script : light.py in the location that is mentioned in log: /usr/local/lib/python3.7/site-packages/tuyaha/devices/light.py? if you have any idea how can I reach this path I appreciate it if you show me how. I'm using hassio image , I think is a docker but I don't get any clue to get to the hypervisor to update this light.py

I'm not using hassio, but a manual installation, so the path is relative to your base directory (which I don't know for hassio) - to get started: if you're connected via ssh you can try installing locate and try to find the installation path by:

apt install locate
updatedb
locate tuyaha

If you already know the base directory you can cd there and try find tuyaha or directly find <yourbasedirectory> tuyaha (Hint: you might have to add sudo in front of every command, depending on the user you are connected to.) For editing via samba-shares, ... sorry, I don't know the layout, but I assume the installation (and that's what your looking for) is not shared there.

Unixman77 commented 4 years ago

Hi , after digging deeply on this issue, I found a way to find this script where it is located in hassio image. I first you have to install plugin ssh&webterminal, I used root as user but you can choose a regular user and run sudo after. after ssh to hassio using this plug, I run

docker container list

I tried locate image name something like: homeassistant/raspberryxxx-homeassistant- and get CONTAINER ID, where I used to connect to it using below command:

docker exec -it <CONTAINER ID> /bin/bash 

this aboce command intialise a seesion to this container , I then run:

find / -name light.py

it gives the location where this script located: /usr/local/lib/python3.7/site-packages/tuyaha/devices/light.py

-some users here advise me to not edit directly this py files as there is another way totally safety . read this link below for more detail.

https://developers.home-assistant.io/docs/en/creating_component_loading.html

hope you find what you want. here.

gadgetchnnel commented 4 years ago

This now appears to be happening with Teckin SB50 bulbs. Don't know if this is due to a firmware update or a change to the Tuya API. They will only show up in Home Assistant if they are in white mode. If I switch them to colour mode they will disappear from HA after a restart (they will reappear within a minute of switching them back to white mode).

Strangely, the light.turn_on service is able to set the colour of the bulb even though HA shows that they don't support colour options (but this doesn't help when trying to set it using the UI or the Alexa smart home skill).

skynet01 commented 4 years ago

Yeah any new tuya device you buy will do that. If you group the tuya lights with any other light that has color ui option you can change the color of the group and it will apply it to tuya as well.

gadgetchnnel commented 4 years ago

@skynet01 The Teckin bulbs were working fine for a few weeks (showing as supporting colour in HA) until they started acting like this a couple of days ago. Why would this suddenly happen?

skynet01 commented 4 years ago

Yeah no idea, I bought new bulbs and none of them are working. The one from 2 years ago is still fine. I think nothing new is working reliably on Tuya. The annoying part is that it looks like it would an easy fix, I am down to donate some beer money towards fixing this issue, just tell me where :)

ryanwinter commented 4 years ago

Who owns the Tuya homeassistant skill? Is it possible that there was an update to this that broke the client side?

Unixman77 commented 4 years ago

Hi , did you modify the line 15 like described above , in other world did you get the error log related to tuya platform ?

ryanwinter commented 4 years ago

Hi , did you modify the line 15 like described above , in other world did you get the error log related to tuya platform ?

I did something similar to get it working again, but there is currently no color options.

G33kDude commented 4 years ago

Copy of my notes from duplicate issue #30007, with a patched tuya api light file (light_patch.py) to re-enable color settings for tuya lights (though it force-shows color settings for all tuya lights whether they support color or not).

Best I can tell, the Tuya home-assistant API is not returning color information anymore, and HA gets confused by seeing a color capable bulb without color status information.

I was able to get most of the functionality back by patching /usr/local/lib/python3.7/site-packages/tuyaha/devices/light.py to handle missing color information more gracefully and override all bulbs to assume color capability (originally determined by presence of color information). However, it's not a perfect patch. The missing bulbs will become visible again, but all Tuya bulbs will show a color picker even if they're not colored bulbs.

Here's a diff of the original file vs my patched file (light_patch.py)

geek@homeserver:~/docker/homeassistant$ diff light.py light_patch.py
15c15
<         if work_mode == 'colour':
---
>         if work_mode == 'colour' and 'color' in self.data:
23c23
<         if work_mode == 'colour':
---
>         if work_mode == 'colour' and 'color' in self.data:
29,32c29,30
<         if self.data.get('color') is None:
<             return False
<         else:
<             return True
---
>         # Override color support
>         return True
41,43c39,42
<         if self.data.get('color') is None:
<             return None
<         else:
---
>         # Override color support
>         #if self.data.get('color') is None:
>         #    return None
>         #else:
45c44
<             if work_mode == 'colour':
---
>             if work_mode == 'colour' and 'color' in self.data:

I'm running HA through docker-compose, so I've applied this patch by specifying a new volume in the docker-compose.yml that overlays the patched file (light_patch.py) on top of the original library file.

version: '2'
services:
  ha:
    image: homeassistant/home-assistant:stable
    volumes:
      - ./config/:/config/
      - ./light_patch.py:/usr/local/lib/python3.7/site-packages/tuyaha/devices/light.py
    environment:
      - TZ=America/New_York
    restart: always
    network_mode: host

Once the change to docker-compose.yml was in place, I had to remove and recreate the container docker-compose rm --stop && docker-compose up -d (⚠️ If your config volume isn't configured correctly this could drop all your HA data). When the web interface came back up my lights were visible and controllable again.

Once the root cause is resolved you will need to remove the patch. It is a temporary stop-gap until something more permanent comes along. In my setup that will involve me removing the volume line I added to docker-compose.yml and then recreating the container again.

skynet01 commented 4 years ago

Welp, rather than bothering with patching, just replaced the light.py file with yours and things are honkey dory. Color changing works and they always show up too. Pretty good patch if you ask me :)

I am running Hassio through Hassbian, so you will just need to ssh into it, then get inside your homeassistant container: sudo docker exec -it homeassistant /bin/bash Then navigate to /usr/local/lib/python3.7/site-packages/tuyaha/devices/ backup the light.py that's there and replace the light.py with G33kDude's above. Restart HA and you are all set!

asyscom commented 4 years ago

for me the problem was a DNS issue, i used cloud9 DNS in my mikrotik, revert to google dns and problem is gone

asyscom commented 4 years ago

as not say, the problem is still present with google dns also..

gadgetchnnel commented 4 years ago

@G33kDude Thanks for that, that allowed me to to get it working without errors. The only issue being that Home Assistant can't keep track of what the colour is set to.

I worked around this (in a rather hacky way) by downloading the Tuya component and adding it to the custom_components folder with the following changes to light.py

Change from . import DATA_TUYA, TuyaDevice to from . import DATA_TUYA, TuyaDevice, DOMAIN

Change the hs_color property to this:

@property
    def hs_color(self):
        """Return the hs_color of the light."""
        if "entity_data" in self.hass.data[DOMAIN] and self.tuya.object_id() in self.hass.data[DOMAIN]["entity_data"]:
          return self.hass.data[DOMAIN]["entity_data"][self.tuya.object_id()]["color"]
        else:
          return tuple(map(int, self.tuya.hs_color()))

and in the turn_on method change this:

        if ATTR_HS_COLOR in kwargs:
            self.tuya.set_color(kwargs[ATTR_HS_COLOR])

to this:

        if ATTR_HS_COLOR in kwargs:
            self.tuya.set_color(kwargs[ATTR_HS_COLOR])
            if not "entity_data" in self.hass.data[DOMAIN]:
              self.hass.data[DOMAIN] = {"entity_data": {}}
            self.hass.data[DOMAIN]["entity_data"][self.tuya.object_id()] = {"color": kwargs[ATTR_HS_COLOR]}

This keeps track of the current colour in hass.data. This will obviously only work if you only control the lights through Home Assistant.

skynet01 commented 4 years ago

Nice! Hopefully, this will make it into an official fix soon. Can you post a link to your modified light.py file so we can just copy and paste it :) Also, can't we just update the original component file and then wait for the official fix to overwrite it?

ctrl50 commented 4 years ago

Nice! Hopefully, this will make it into an official fix soon. Can you post a link to your modified light.py file so we can just copy and paste it :) Also, can't we just update the original component file and then wait for the official fix to overwrite it?

im going to say yes= however if another release comes without a fix the issue will return.

gadgetchnnel commented 4 years ago

Here is my modified light.py from the Tuya component.

To use this, you will need to download the Tuya component from here and add the folder to your custom_components folder, replacing light.py with my modified version.

As a bonus, here is another version which also maps brightness levels if, like me, you have Tuya bulbs which only support brightness levels of 29-255 instead of the full range of 1-255 (setting the brightness to 28 or less turns the light off). This code maps brightness levels from to 0-255 range to the 29-255 range when setting brightness and vice versa when retrieving the brightness. The mapping isn't exact, and sometimes the retrieved brightness will not quite match what you set it to (which I think is due to the Tuya API actually using percentage brightness) but I find it is close enough.

johnjoemorgan commented 4 years ago

@gadgetchnnel

Running 103.4 with Hassio with Tuya custom component for lights (and local_tuya for switches)

Modified light.py not working for colour change either directly or in a group

djiesr commented 4 years ago

I want t patche "light.py" I'm on HassOS 3.7 I install SSH & Web Terminal I can see: addons backup bin config data dev etc... But find / -name light.py did't find it. I have the srv folder but is empty. Someone can give me some light to find my light.py? :)

StefanoGiu commented 4 years ago

Hello, I got this reply from tuya about the color issue…

Copy to clipboard Hello, that's because color_mode is based on work_mode ["white", "colour",] to get the value. The string of code I provided to you above is to get the color: { "header": { "name": "colorSet", "namespace": "control", "payloadVersion": 1 }, "payload": { "color": { "hue": 0, "saturation": 0, "brightness": 1 }, "accessToken": "token", "devId": "devId" } } Does it help to understand the issue?

I applied the fixes suggested here, but HA is not able to read the original status of the light and its color (it only stores the new color when changed from HA, but it’s not able to read it if changed from somewhere else…)

StefanoGiu commented 4 years ago

There is the Status API offered by tuya.

GET /v1.0/skills/devices/{device_identity}/status

I think this is the key to retrieve the current color value....

https://docs.tuya.com/en/iot/open-api/api-list/api/skill-service?id=K95zu0id1md0g

skynet01 commented 4 years ago

Any update on this or word when a patch might be available?

djiesr commented 4 years ago

If you just need the color or brightness parameter, in your customize section just add something like this:

light.8859gf59329894c: supported_features: 49 That will add color palette to your light, for other setting look this post: https://community.home-assistant.io/t/device-supported-features/168499

Le lun. 6 juill. 2020, à 13 h 12, skynet01 notifications@github.com a écrit :

Any update on this or word when a patch might be available?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/home-assistant/core/issues/28602#issuecomment-654361592, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHPIGULV2LEQM7FIKAPLYMLR2IAXFANCNFSM4JKDEQAA .

skynet01 commented 4 years ago

That worked! You can also just use the UI, open your light scroll down to supported_features and change it to 49. Thank you again for the tip. If you want the temperature control you can change it to 63

Adil-MohammedK commented 4 years ago

This worked for me. Its easy to install too. Colour changes are updated in the Lovelace. Give it a try. https://github.com/ollo69/ha_tuya_custom#integration-ha_tuya_custom My customize.yaml: light.4157153250029157c212: { support_color: true } Configuration.yaml: `tuya_custom: devices_config: