BazaJayGee66 / homeassistant_cololight

Custom component to support Cololight in Home-Assistant
MIT License
49 stars 6 forks source link

add polling of status(on or off and brightness) #22

Closed pim12345 closed 2 years ago

pim12345 commented 2 years ago

hey BazaJayGree66,

In this PR, I added polling of the status of the cololight (brightness and on/off). I found out by using wireshark and their razer integration. I have only tested with cololight firmware version of: 5.18.8.9 (I think the newest version) and I don't know if it will work with older versions.(hopefully you can test that). I hope you don't think my code quality is too bad.

Greetings Pim

BazaJayGee66 commented 2 years ago

Amazing find!

Will try and test and merge in this week.

pim12345 commented 2 years ago

I did some more testing. There is currently a bug that if you turn the light on or off from home assistant. It will directly after that ask a update from the lamp. But because the light has not got the time to turn off or on it will give the old state. Do you know how to skip the update function after the turn on or off function has been called? Or is there a way to delay that update?

BazaJayGee66 commented 2 years ago

Do you know how to skip the update function after the turn on or off function has been called? Or is there a way to delay that update?

I had noticed the same, but wasn't able to find if the update can be skipped. One solution could be to add a delay in the update, with something like

await asyncio.sleep(0.5)

Not the most elegant solution, and not sure how it would handle if the light was repeatably turn on/off quickly.

pim12345 commented 2 years ago

I now added a bool var that is set to false if you turn the light on or off. So that the update function is skipped when turning the light on or off. What do you think about that solution? What also a solution is https://github.com/home-assistant/core/blob/191230f535b053ec76ae1164035de8879dfc2750/homeassistant/components/influxdb/sensor.py#L283 adding a throttle to the update function(I have not tested that or implented that). What solution do you prefer?

BazaJayGee66 commented 2 years ago

I think having update as a boolean works.

Apologies, haven't had chance to test comprehensively yet.

BazaJayGee66 commented 2 years ago

When running in Home Assistant, the response data from the socket get delayed over time.

Doing some investigation, it looks like the data returned is not the latest state, but rather the last issued command in sequence.

I believe this might be due to how we're using the socket library.

Here's a simple example, where the output isn't the latest state (80 brightness), but what the brightness was in sequence for each command:

from cololight.light import (
    PyCololight,
    ColourException,
    ColourSchemeException,
    ModeExecption,
    CycleSpeedException,
)
import time

light = PyCololight("x.x.x.x")

def status():
    light._sock.sendto(
        bytes.fromhex(
            "535a303000000000001e000000000000000000000000000000000200000000000000000003020101"
        ),
        (light.host, light.port),
    )
    data = light._sock.recvfrom(4096)[0]
    print(data[41])
    time.sleep(0.5)

light.on = 10
time.sleep(0.5)
light.on = 20
time.sleep(0.5)
light.on = 30
time.sleep(0.5)
light.on = 40
time.sleep(0.5)
light.on = 30
time.sleep(0.5)
light.on = 60
time.sleep(0.5)
light.on = 70
time.sleep(0.5)
light.on = 80
time.sleep(0.5)

status()
status()
status()
status()
status()
status()
status()
status()

### Output
# 10
# 20
# 30
# 40
# 30
# 60
# 70
# 80
BazaJayGee66 commented 2 years ago

Have updated to close the socket connection after sending/receiving data.

pim12345 commented 2 years ago

The code works great. Only issue what I had was if the device was offline. Home assistant core crashes. Because it will infinity wait for the message of the light. (I had removed that timeout because I thought that home assistant handles that). I have set the timeout to 4 seconds.

BazaJayGee66 commented 2 years ago

Good find, have updated to make device unavailable if it times out.