Cover update callback stops in some special case
mralessio opened this issue ยท 8 comments
Hello!
My intention is to use device_updated_cb
callback for Cover to process some logic during its movement etc..
I faced the problem when callback stops working in some special case, for example:
Pretend the blind initial position is 0% and we need to move it to 90%
- start moving the blind to some position
await cover.set_position(90)
- send Stop during movement
cover.stop()
- then continue to move it to the previously given position
await cover.set_position(90)
Here thedevice_updated_cb
stops - if then or instead to send the blind to any other position but except 90%, the callback gets back to work, for example, sending to any of 0-89 or 91-100% .
Not sure if I'm doing something not correctly.
Here is the reduced example:
async def cover_update_cb(cover: Cover):
print('Something inside cover update callback')
cover: Cover = None
async def test():
global cover
await asyncio.sleep(1)
await cover.set_position(90)
await asyncio.sleep(4)
print('STOP command')
await cover.stop()
await asyncio.sleep(2)
print(f'Continue to move to 90')
await cover.set_position(90)
"""here cover_update_cb stops. If instead set any different position from a position
that the blind started moving from at the beginning (in our case 90) then callback will work. """
async def main():
global cover
xknx = XKNX(daemon_mode=True)
cover = Cover(
xknx,
'Cover',
group_address_stop = "1/1/2",
group_address_position = "1/1/3",
group_address_position_state = "1/1/4",
device_updated_cb=cover_update_cb
)
loop = asyncio.get_running_loop()
loop.create_task(test())
await xknx.start()
await xknx.stop()
asyncio.run(main())
Hi ๐!
Thanks for reporting this issue!
Can you try to add always_callback=True
to this call and try again?
Line 363 in ada1d85
๐ If you want to provide a fix (and tests) feel free to submit a PR.
May I ask you for a help/advice in parallel?
I have the feedback position (DPT 5.001) of the blind.
Instead of sending a blind position cyclicly, I want to use the cover callback to update the current position each 1 sec by reading value from the group address, only when the blind moving.
Now I tried it like this:
async def cover_update_cb(self, cover: Cover):
await cover.sync()
self.position_fb = cover.position_current.value
or via read_group_value()
Is it a good practice/method to achieve it?
Sending a GroupValueRead to a state address of a xknx Device won't yield a response.
Calling device.sync() will send multiple reads.
Why don't you just write the calculated position out with write_group_value()
when moving?
I have RS485 digital motor connected over the KNX RS485 motor-controller which returns the precise blind position. I want to get advantage of it showing always precise position instead of calculated.
Then calling sync()
or even read_group_value()
in the callback will yield a loop over the bus - as a response will yield another callback.
You start an asyncio.Task in the callback when it is moving and cancel it again when it isn't anymore. In the Task call read_group_value()
(or sync()
if you only have that one state address) every 1 second or so.