SecKatie / ha-wyzeapi

Home Assistant Integration for Wyze devices.
761 stars 116 forks source link

[Bug] color_temp does not match what is set #250

Closed reidprichard closed 3 years ago

reidprichard commented 3 years ago

Describe the bug Reported color_temp does not match what is set. If I run light.turn_on with a color_temp = 400, the light actually shows a color_temp of 499.

To Reproduce

  1. Go to Developer Tools
  2. Go to the services tab
  3. Choose the light.turn_on service
  4. Enter the entity_id of a Wyze tunable white bulb
  5. Enter a color_temp of your choice
  6. Click "call service"
  7. Click the states tab
  8. Observe that the device's color_temp in its attributes is greater than what was set.

Expected behavior The device's color_temp should be reasonably close to what was set (allowing for rounding and other imprecision).

System configuration System: HassOS on x86 HA Version: core-2021.9.5 WyzeApi Version: 2021.8.1 or possibly 2021.9.1 (it doesn't say an update is available, so 2021.9.1 I guess?)

home-assistant.log

2021-09-17 19:58:38 DEBUG (MainThread) [custom_components.wyzeapi.light] Setting color temp
2021-09-17 19:58:38 DEBUG (MainThread) [custom_components.wyzeapi.light] Turning on light
2021-09-17 19:58:38 DEBUG (MainThread) [custom_components.wyzeapi.light] Setting color temp
2021-09-17 19:58:38 DEBUG (MainThread) [custom_components.wyzeapi.light] Turning on light
2021-09-17 19:58:38 DEBUG (MainThread) [custom_components.wyzeapi.light] Setting color temp
2021-09-17 19:58:38 DEBUG (MainThread) [custom_components.wyzeapi.light] Turning on light
2021-09-17 19:58:38 DEBUG (MainThread) [custom_components.wyzeapi.light] Setting color temp
2021-09-17 19:58:38 DEBUG (MainThread) [custom_components.wyzeapi.light] Turning on light
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] Request:
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] url: https://api.wyzecam.com/app/v2/device/set_property_list
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] json: {'phone_system_type': '1', 'app_version': '2.18.43', 'app_ver': 'com.hualai.WyzeCam___2.18.43', 'sc': '9f275790cab94a72bd206c8876429f3c', 'ts': 1631923118, 'sv': '9d74946e652647e9b6c9d59326aef104', 'access_token': '', 'phone_id': '86173ed4-32ba-468c-ab8f-45a99f979fab', 'app_name': 'com.hualai.WyzeCam', 'property_list': [{'pid': 'P1502', 'pvalue': '5481'}], 'device_model': 'WLPA19', 'device_mac': '2CAA8E277130'}
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] headers: None
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] data: None
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] Request:
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] url: https://api.wyzecam.com/app/v2/device/set_property_list
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] json: {'phone_system_type': '1', 'app_version': '2.18.43', 'app_ver': 'com.hualai.WyzeCam___2.18.43', 'sc': '9f275790cab94a72bd206c8876429f3c', 'ts': 1631923118, 'sv': '9d74946e652647e9b6c9d59326aef104', 'access_token': '', 'phone_id': '86173ed4-32ba-468c-ab8f-45a99f979fab', 'app_name': 'com.hualai.WyzeCam', 'property_list': [{'pid': 'P3', 'pvalue': '1'}], 'device_model': 'WLPA19', 'device_mac': '2CAA8E277130'}
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] headers: None
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] data: None
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] Request:
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] url: https://api.wyzecam.com/app/v2/device/set_property_list
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] json: {'phone_system_type': '1', 'app_version': '2.18.43', 'app_ver': 'com.hualai.WyzeCam___2.18.43', 'sc': '9f275790cab94a72bd206c8876429f3c', 'ts': 1631923118, 'sv': '9d74946e652647e9b6c9d59326aef104', 'access_token': '', 'phone_id': '86173ed4-32ba-468c-ab8f-45a99f979fab', 'app_name': 'com.hualai.WyzeCam', 'property_list': [{'pid': 'P1502', 'pvalue': '5481'}], 'device_model': 'WLPA19', 'device_mac': '2CAA8E277A8C'}
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] headers: None
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] data: None
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] Request:
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] url: https://api.wyzecam.com/app/v2/device/set_property_list
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] json: {'phone_system_type': '1', 'app_version': '2.18.43', 'app_ver': 'com.hualai.WyzeCam___2.18.43', 'sc': '9f275790cab94a72bd206c8876429f3c', 'ts': 1631923118, 'sv': '9d74946e652647e9b6c9d59326aef104', 'access_token': '', 'app_name': 'com.hualai.WyzeCam', 'property_list': [{'pid': 'P3', 'pvalue': '1'}], 'device_model': 'WLPA19', 'device_mac': '2CAA8E277A8C'}
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] headers: None
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] data: None
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] Request:
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] url: https://api.wyzecam.com/app/v2/device/set_property_list
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] json: {'phone_system_type': '1', 'app_version': '2.18.43', 'app_ver': 'com.hualai.WyzeCam___2.18.43', 'sc': '9f275790cab94a72bd206c8876429f3c', 'ts': 1631923118, 'sv': '9d74946e652647e9b6c9d59326aef104', 'access_token': '', 'phone_id': '86173ed4-32ba-468c-ab8f-45a99f979fab', 'app_name': 'com.hualai.WyzeCam', 'property_list': [{'pid': 'P1502', 'pvalue': '5481'}], 'device_model': 'WLPA19', 'device_mac': '2CAA8E282460'}
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] headers: None
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] data: None
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] Request:
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] url: https://api.wyzecam.com/app/v2/device/set_property_list
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] json: {'phone_system_type': '1', 'app_version': '2.18.43', 'app_ver': 'com.hualai.WyzeCam___2.18.43', 'sc': '9f275790cab94a72bd206c8876429f3c', 'ts': 1631923118, 'sv': '9d74946e652647e9b6c9d59326aef104', 'access_token': '', 'phone_id': '86173ed4-32ba-468c-ab8f-45a99f979fab', 'app_name': 'com.hualai.WyzeCam', 'property_list': [{'pid': 'P3', 'pvalue': '1'}], 'device_model': 'WLPA19', 'device_mac': '2CAA8E282460'}
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] headers: None
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] data: None
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] Request:
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] url: https://api.wyzecam.com/app/v2/device/set_property_list
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] json: {'phone_system_type': '1', 'app_version': '2.18.43', 'app_ver': 'com.hualai.WyzeCam___2.18.43', 'sc': '9f275790cab94a72bd206c8876429f3c', 'ts': 1631923118, 'sv': '9d74946e652647e9b6c9d59326aef104', 'access_token': '', 'phone_id': '86173ed4-32ba-468c-ab8f-45a99f979fab', 'app_name': 'com.hualai.WyzeCam', 'property_list': [{'pid': 'P1502', 'pvalue': '5481'}], 'device_model': 'WLPA19', 'device_mac': '2CAA8E2650E5'}
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] headers: None
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] data: None
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] Request:
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] url: https://api.wyzecam.com/app/v2/device/set_property_list
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] json: {'phone_system_type': '1', 'app_version': '2.18.43', 'app_ver': 'com.hualai.WyzeCam___2.18.43', 'sc': '9f275790cab94a72bd206c8876429f3c', 'ts': 1631923118, 'sv': '9d74946e652647e9b6c9d59326aef104', 'access_token': '', 'phone_id': '86173ed4-32ba-468c-ab8f-45a99f979fab', 'app_name': 'com.hualai.WyzeCam', 'property_list': [{'pid': 'P3', 'pvalue': '1'}], 'device_model': 'WLPA19', 'device_mac': '2CAA8E2650E5'}
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] headers: None
2021-09-17 19:58:38 DEBUG (MainThread) [wyzeapy.wyze_auth_lib] data: None
reidprichard commented 3 years ago

I can work around this, as I've realized the error is linear, where color_temp = 1.24*commanded_color_temp - 34.235. Plot shown here: https://imgur.com/a/UCCzDVz

JoeSchubert commented 3 years ago

Edit

Sorry, I was a bit off in what I was originally thinking. Are you trying to pass the value as kelvin or mireds? Looking at the info for home assistant, the lightentity uses mireds, and that's what it looks like this integration works with.

There may be some loss in the math, I see that we're using ints, floats and converting that to a string to pass to wyze. Plus since it's being converted from mireds in ha to kelvin (I assume, since your log shows "5481") they may need to be floats throughout for higher accuracy.

reidprichard commented 3 years ago

I've been working in mireds. For some reason I was thinking that I couldn't use Kelvin, but I now see that works. It appears setting a Kelvin value has the same issue. I tried setting it to 2700K (= 370 mireds), and I got a temp of 424 mireds (~2400K) . This is exactly what my linear regression on the plot predicts.

Are you sure that 'pvalue' in the log is the requested color temp? When requesting 2700K, I saw 'pvalue': 3497, which is not the desired or achieved color temp, nor is it even between the two.

My inclination would be that there's a bad conversion somewhere rather than roundoff error. If it were roundoff, I'd expect a less predictable relationship between commanded and achieved color temp.

JoeSchubert commented 3 years ago

Sure? No. This is all reverse engineered by people since wyze doesn't have a public API. However, wyzeapy is what provides this project with an interface to their API. It lists p1502 as the PID for color temp. So the pvalue for that id should be the desired temperature in kelvin.

I'm looking at rewriting this function https://github.com/JoshuaMulliken/ha-wyzeapi/blob/e3292c2d68cdf464a465dc8e535395c68809bbac/custom_components/wyzeapi/light.py#L97 as I suspect that it's where the conversion is breaking down. HA provides a built-in to do the conversion we just need to constrain the values, I hope.

However, I don't have any bulbs to test with and it may be a few days before Josh can do testing. If you're comfortable modifying that block of code in your installation I can ping you when I push it (hopefully later today) to see if it fixes the big.

reidprichard commented 3 years ago

Yeah, you're definitely right (no surprise). I tested again:

I think there are two separate issues here - one with setting the color temp, and a second with reporting the color temp in the device's state.

I'd be happy to test the fix whenever ready, although I may need a little guidance on how to actually modify those files in my installation.

JoeSchubert commented 3 years ago

Yeah, both of the problems you mention stem from that one function. Because it needs to be converted both directions: going to wyzeapy and coming back. So I would've been surprised had your said your change was correct one direction but not the other :p

SecKatie commented 3 years ago

Yeah that is highly likely lol it is not actually a linear equation I guess

JoeSchubert commented 3 years ago

alright... so I'm kinda working completely blind on this since i don't have the device to test. If you'd be willing to test this (it might be WAY off... I'm using the 1,000,000/kelvin temp as what the mired values are supposed to be, which may be way off. You can see the values I'm guessing here:

Assuming that mireds follow the 1,000,000/kelvin temperature conversion, these values for min/max should work

@property
def min_mireds(self) -> int:
    if self._device_type is DeviceTypes.MESH_LIGHT:
        return 56
    return 37

@property
def max_mireds(self) -> int:
    return 153

To test this @reidprichard , you'll need to go into your home assistant configuration directory (I can't really say where that will be for your install usually it's in hidden directory in your HA user's home folder. However, on dietpi for instance (what I use) it's in a completely different location.

ok, so if you get into that directory... you can do: cd custom_components/wyzeapi cp light.py light.py.bak wget https://raw.githubusercontent.com/yoinx/ha-wyzeapi/54f1b371fea8722f35a338e5d73b4b7d548a92e1/custom_components/wyzeapi/light.py

then restart Home Assistant and test. If you want to go back to the norm just go back to your config directory and do: rm light.py mv light.py.bak light.py

and restart HA.

If you have a better idea of what the mireds min/max should be... by all means, let me know. I was trying to correlate to your graph... But I really don't understand mireds.

reidprichard commented 3 years ago

Thanks! That was pretty easy. One unrelated question - is there a way to paste into the in-browser SSH terminal? I tried ctrl+v, ctrl+shift+v, right-click menu, and nothing. My current method of getting links there has been putting them into a link shortener and manually typing the URL in. High-tech, right? Maybe I just need to figure out how to SSH in from a local terminal.

I got an error after restarting:

Logger: homeassistant.setup
Source: setup.py:317
First occurred: 9:24:54 PM (1 occurrences)
Last logged: 9:24:54 PM

Unable to prepare setup for platform wyzeapi.light: Platform not found (No module named 'custom_components.wyzeapi.token_manager').

The mired unit is defined as 1,000,000/[kelvin temp] like you said. Mireds stands for micro reciprocal degree; just a different way of representing a color temperature. I'm basically restating what you said, so maybe I'm missing your question.

Anyway, that being the case, the range would be 153.8 - 370. My other tunable bulbs (Sengled) report a range of 153 - 370 mireds, so perhaps rounding down is the ticket.

JoeSchubert commented 3 years ago

Ah, the error you got was because you're on an older release. When I voted the file, it was the latest stable (which supports 2fa among other things).

That's 153-370 for the color bulbs or white? They have different ranges.

I can try to give you another duke tomorrow afternoon or evening that would have the right values and won't error.

Note, if you want to edit that file, removing the

from .token_manager import token_exception_handler

Line at the top and both of the

@token_exception_handler

Lines in the file should make it load for you.

Also, no idea about the way to paste into the terminal in the browser... Never used it

Also, if you're feeling REALLY adventurous once that works, you could tweak the min max values toward the bottom of the file in the

min_mireds

And max_mireds function to see using the right values fixes it for you.

JoeSchubert commented 3 years ago

Actually, just edited the file a little online. Try the same steps with this file instead

https://raw.githubusercontent.com/yoinx/ha-wyzeapi/250-incorrect_color_temp/custom_components/wyzeapi/light.py

reidprichard commented 3 years ago

That range was for the tunable white bulbs. The color bulbs are advertised 1800K-6500K, so I'd expect their range to be 153-556.

Thanks for the file. Strike two I'm afraid. Now all my Wyze bulbs are showing "unavailable." Rolling back to light.py.bak fixed it.

JoeSchubert commented 3 years ago

Strange. I don't see anything in what I changed that should've made the devices go unavailable.

I'll have to look at it a bit more. What version of wyzeapi are you on? The latest is 2021.9.3 I believe

reidprichard commented 3 years ago

I'm on 2021.9.1. Should I update to 2021.9.3?

On Tue, Sep 21, 2021 at 2:24 PM Joe Schubert @.***> wrote:

Strange. I don't see anything in what I changed that should've made the devices go unavailable.

I'll have to look at it a bit more. What version of wyzeapi are you on?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/JoshuaMulliken/ha-wyzeapi/issues/250#issuecomment-924247410, or unsubscribe https://github.com/notifications/unsubscribe-auth/AP3GYYFP5B7T7SRU5MXCH7DUDDEXHANCNFSM5EIRV7IA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

bucketybuckbuck commented 3 years ago

Hi Guys, I'm also interested in this bug and happy to help out testing.

I'm on 2021.9.3 and tried your latest suggestion. It looks like just the import is missing for

import from .token_manager import token_exception_handler

If I add that in, the light state does show but when calling the light on service with

service: light.turn_on
data:
  brightness_pct: 100
  color_temp: 350
target:
  entity_id: light.kitchen1

I'll attach the log
wyzeapi.log

JoeSchubert commented 3 years ago

Hi Guys, I'm also interested in this bug and happy to help out testing.

I'm on 2021.9.3 and tried your latest suggestion. It looks like just the import is missing for

import from .token_manager import token_exception_handler

If I add that in, the light state does show but when calling the light on service with

service: light.turn_on
data:
  brightness_pct: 100
  color_temp: 350
target:
  entity_id: light.kitchen1

I'll attach the log wyzeapi.log

Thanks. That's helpful. I don't think that you should've been missing that import on 2021.9.3 though, that's a little odd to me.

return math.floor(1000000 / mired_temperature) TypeError: unsupported operand type(s) for /: 'int' and 'function'

Looks like either I messed up and it's trying to pass my variable as a function for some reason. Or home assistant's built in function is broken.

I'll try to post another test file that should work on 2021.9.3 tonight

bucketybuckbuck commented 3 years ago

Thanks. That's helpful. I don't think that you should've been missing that import on 2021.9.3 though, that's a little odd to me.

Sorry, I meant I am on 2021.9.3 but used the last version you posted https://raw.githubusercontent.com/yoinx/ha-wyzeapi/250-incorrect_color_temp/custom_components/wyzeapi/light.py

Interestingly, I'm unable to replicate that error today that I posted. I can successfully set the color_temp between 153-499.

Really appreciate you looking into this, thanks

SecKatie commented 3 years ago

THis has been resolved by #258

JoeSchubert commented 3 years ago

Pull Request has been submitted with the values being tested. If you want to test locally, feel free to grab the file from master here: https://raw.githubusercontent.com/JoshuaMulliken/ha-wyzeapi/master/custom_components/wyzeapi/light.py

this should be fixed in the next release.

SecKatie commented 3 years ago

@bucketybuckbuck @reidprichard it is in a full release!

reidprichard commented 3 years ago

Wow, you guys are lightning fast! Just updated and tested, and it works perfectly. Setting color_temp to 153 does not work, but 154 does work, so I was apparently wrong. Not a big deal, but I threw up a PR to correct it.

Thank you all!