Remove dimmer polling#160
Conversation
|
I have question on this. How does it "flood" the network? From the code I am looking at there are only 2 requests that are sent to get the updated value.. 2 packets is hardly a flood. I would think that if there is something more then that taking place then the problem would be in the openzwave code and not in python-openzwave. I do see fault in it's use because there is no way to stop the timers if the locally stored value gets updated. and it appears that it will only run if the value being set is a 0. The idea is a good idea because polling is not necessarily the answer. say I have 50 dimmers would it not cause more network traffic if I have polling set for all 50 of those dimmers then to do a request to get an updated status for the one? |
|
Fair enough, flood is a strong word. Its 2 extra messages per device, so when I run my large scene scripts, it adds a lot of traffic causing the scene shifts to take a lot longer that necessary. I have a house full of HomeSeer HS-WD(1|2)00+ dimmers. Security makes it even worse. I think the correct solution is a single delayed poll (what I think you are calling "update status") of the device after triggering. I agree that continuous polling is almost always bad. In your 50 device example, I would program my hub to simply wait ~5 seconds and then query the device. |
|
Another particularly annoying consequence of this is with a single device. If the fade off is longer than it takes to process the additional two messages it frequently confuses the hub (home assistant in my case) and toggles the dimmer back on, sometimes getting "stuck" in a half-way off state. The SwitchMultiLevel can show up between the two updates. |
|
There appears to be more to this mystery. I still have two extra messages when turning off dimmers under certain circumstances: https://gist.github.com/loe/ed53109909c599d7bd930bb18572b812 |
|
hass does not have a refined implementation of zwave. to be completely honest it is pretty bad. It's extremely slow. partly because of the design of hass in it's self and also partly because of the implementation of zwave. hass it set up to do an update every 10 seconds. which would mean that at best you are going to get GUI updates for state changes once every 10 seconds. I do not know if this 10 second things applies only to the GUI portion of hass. I have a suspicion it does not. a lot can happen in 10 seconds. I give a really in depth explanation of what is happening with the z wave network in it's self. and the design flaws in it as well as the design flaws in hass it's self. You can read up on it here. home-assistant/architecture#81 From the name of your gist I am going to make an assumption here. you are trying toramp a dimmer over a period of time by setting the level every n seconds. and this is the result of doing that, you are getting a jumping of the dimmer level sometimes brighter and it will stop sometimes for what appears to be no reason. I am also going to assume you are trying to do this for a media room to give that theater experience right down to the ramping up and down of the lights. If the above is a correct assessment of what you are trying to do that I am going to tell you some bad news. it is not going to work. It may appear as tho you have managed to get it to run properly but it will glitch and have issues. once you read my posts in that link above it will make complete sense. and also why the problem occurs more often when the checking of the state of the light is still in the code. There is only one solution I have found, and it works perfectly. I explain it in that link above as well. |
|
as far as the "mystery logging output" are those diimmers z-wave plus? |
|
also if you check pr #134 in the command_classes.py file there is a class called SwitchMultilevel. there is an implementation of ramping up or down that i did that is i believe the best way to go about it. it produces the least amount of anomalies. We are hoping to get that PR into the next version of python-openzwave I need to do more documentation on the use of the various classes. |
|
I am not trying to do anything special, i.e. neither of your assumptions, that is the log I get when I just flip the toggle in the HA UI. My Z-Wave Plus dimmers have a configuration option where I can adjust the ramp time from 1 second to 10 seconds in 100ms increments. |
|
Also FYI the HomeSeer dimmer I think is using Jasco as OEM, they are nearly identical. Different firmware and LED layout, but otherwise same box. |
|
ok the reason I asked was because of thee name of the gist. which is HS-WD100+ Dimmer 3 second fade. which leads me to think that it is a ramp down over 3 seconds. and if one was to do that with command after command to decrease the light level over the 3 seconds it is not going to happen properly. my suggestion to you would be to run python openzwave on it's own and remove hass form the equation. and see if the issue with the light stopping it's level change goes away. If you have a PC running Windows that you can test from you can use EventGhost and the Z-Wave plugin for it. It has the best implementation of python-openzwave i have seen. I have 70+ switches and dimmers in my network not a single one of them are Z-Wave+ so polling is what happens. I have < 1sec status change notifications. |
I have no polling on my network, 100% of devices are Z-Wave+ |
|
hmmmm I wonder... I know that libopenzwave does a get after a set. I am wondering if it does this for zwave plus devices as well. I would think that it shouldn't or maybe set a timer to do a get if it hasn't received an update from the device within 2 seconds or so. I am thinking instead of removing those 2 timers you wrap them in an if statement that check if the node is zwave plus. the checking if a node is zwave plus should not cause any additional network traffic. it is something that gets reported a single time when the network starts up. def set_dimmer(self, value_id, value):
"""
The command 0x26 (COMMAND_CLASS_SWITCH_MULTILEVEL) of this node.
Set switch to value (using value value_id).
:param value_id: The value to retrieve state
:type value_id: int
:param value: The level : a value between 0-99 or 255. 255 set the level to the last value. \
0 turn the dimmer off
:type value: int
"""
logger.debug(u"set_dimmer Level:%s", value)
if value_id in self.get_dimmers():
if 99 < value < 255:
value = 99
elif value < 0:
value = 0
self.values[value_id].data = value
#Dimmers doesn't return the good level.
#Add a Timer to refresh the value
if value == 0 and not self.is_zwave_plus:
timer1 = Timer(1, self.values[value_id].refresh)
timer1.start()
timer2 = Timer(2, self.values[value_id].refresh)
timer2.start()
return True
return False
@property
def is_zwave_plus(self):
raise NotImplementedError |
|
If the device supports SwitchMultiLevel CC version 4, just use the “Target Value” ValueID reported (Dev branch). That tells you the final value the device is going to. If your using devices that don’t support version 4, just do a SetChangeVerified on the ValueID. OZW will automatically refresh the ValueID till 2 consecutive readings are the same. |
Looks like it does! https://products.z-wavealliance.org/products/2874/classes I will try out the dev branch of ozw. In the interim I'd still like to prevent this additional traffic on my network, it happens faster than my ramp time so it will never succeed. |
|
I've been running this patch for a while now (two weeks) and combined with HA's "refresh_value" (https://www.home-assistant.io/docs/z-wave/installation/) which polls my dimmers 5 seconds after an event my network behaves well. I haven't yet made time to take a stab at SwitchMultiLevel CC v4 yet. |
|
Anything missing? This is correctly solved at the application layer (home assistant in my case) with a timer that is aware of my configured ramp time. |
This is a hack that floods networks, if the device doesn't correctly report status the user should configure polling.