HAP-python
HAP-python copied to clipboard
Fake WindowCovering accessory / get the 'PositionState' value
Hello,
I am trying to implement a fake WindowCovering accessory (shutter) with HAP-python. I already have tested this with a copy of the busy_home.py file. You can check my shutter.py testing file.
I am getting "TargetPosition" value on the debug log. But on the iOS HomeKit app, when I change the target value.
Could you tell me how to get the 'PositionState' value on the HAP-python console?
$ python3 shutter.py
[accessory_driver] Loading Accessory state from `shutter.state`
[accessory_driver] Starting the event loop
[accessory_driver] Starting accessory Bridge on address 192.168.1.91, port 51800.
[hap_server] Got connection with ('192.168.1.5', 50943).
[hap_server] 192.168.1.5 - "POST /pair-verify HTTP/1.1" 200 -
[hap_server] 192.168.1.5 - "POST /pair-verify HTTP/1.1" 200 -
[hap_server] 192.168.1.5 - "GET /accessories HTTP/1.1" 200 -
[hap_server] 192.168.1.5 - "PUT /characteristics HTTP/1.1" 204 -
[hap_server] 192.168.1.5 - "PUT /characteristics HTTP/1.1" 204 -
[hap_server] 192.168.1.5 - "PUT /characteristics HTTP/1.1" 204 -
[hap_server] 192.168.1.5 - "PUT /characteristics HTTP/1.1" 204 -
[hap_server] 192.168.1.5 - "PUT /characteristics HTTP/1.1" 204 -
[hap_server] 192.168.1.5 - "PUT /characteristics HTTP/1.1" 204 -
[hap_server] 192.168.1.5 - "GET /characteristics?id=4.9,4.10,3.9,3.10,3.11,2.10,2.9,2.11 HTTP/1.1" 207 -
[shutter] WindowCovering TargetPosition value: 100
[hap_server] 192.168.1.5 - "PUT /characteristics HTTP/1.1" 204 -
[shutter] WindowCovering TargetPosition value: 0
[hap_server] 192.168.1.5 - "PUT /characteristics HTTP/1.1" 204 -
[shutter] WindowCovering TargetPosition value: 100
[hap_server] 192.168.1.5 - "PUT /characteristics HTTP/1.1" 204 -
[shutter] WindowCovering TargetPosition value: 0
[hap_server] 192.168.1.5 - "PUT /characteristics HTTP/1.1" 204 -
[shutter] WindowCovering TargetPosition value: 100
[hap_server] 192.168.1.5 - "PUT /characteristics HTTP/1.1" 204 -
[shutter] WindowCovering TargetPosition value: 0
[hap_server] 192.168.1.5 - "PUT /characteristics HTTP/1.1" 204 -
Here is my code from the file:
# Add the fan service. Also add optional characteristics to it.
serv_cover = self.add_preload_service(
'WindowCovering', chars=['CurrentPosition', 'TargetPosition', 'PositionState'])
self.char_rotation_speed = serv_cover.configure_char(
'TargetPosition', setter_callback=self.set_target_position)
self.char_state = serv_cover.configure_char(
'PositionState', setter_callback=self.set_position_state)
self.char_rotation_direction = serv_cover.configure_char(
'CurrentPosition', setter_callback=self.set_current_position)
'''
def change_state(self, value):
logging.info("WindowCovering CurrentPosition value: %s", value)
self.get_service('WindowCovering')\
.get_characteristic('CurrentPosition')\
.set_value(value)
'''
def set_target_position(self, value):
logging.info("WindowCovering TargetPosition value: %s", value)
self.get_service('WindowCovering')\
.get_characteristic('TargetPosition')\
.set_value(value)
# The value property of PositionState must be one of the following:
# Characteristic.PositionState.DECREASING = 0;
# Characteristic.PositionState.INCREASING = 1;
# Characteristic.PositionState.STOPPED = 2;
def set_position_state(self, value):
logging.info("WindowCovering PositionState value: %s", value)
self.get_service('PositionState')\
.get_characteristic('PositionState')\
.set_value(value)
I would appreciate some help. When it works I will make a PR to merge this in the main repo.
Regards, Ludovic
The way HomeKit handles this is a bit tricky. Maybe two examples help:
Case 1, Cover closed, want to open
- HomeKit will update
TargetPosition
to100
(start was 0) - The accessory needs to set
CurrentPosition
to100
(start was 0) - And
PositionState
to2
(for stopped)
Case 2, Cover open, want to close
- HomeKit will update
TargetPosition
to0
- The accessory needs to set
CurrentPosition
to0
- And
PositionState
to2
(for stopped)
To summarize, HomeKit will only update the TargetPosition
char, so that's the only one you need a setter for. Setting the CurrentPostion
attribute is required for the accessory, since HomeKit uses the difference to calculate if the cover is opening, closing or stopped. I mentioned PositionState
as well, but as far as I've noticed, it doesn't have any influence what so ever. Best to set it to stopped
during init and leave it there:
serv_cover.configure_char('PositionState', value=2)
Thanks, It seems to work with that code:
def set_target_position(self, value):
logging.info("WindowCovering TargetPosition value: %s", value)
self.get_service('WindowCovering')\
.get_characteristic('TargetPosition')\
.set_value(value)
time.sleep(2) # Delays for 2 seconds. You can also use a float value.
logging.info("WindowCovering CurrentPosition value: %s", value)
self.get_service('WindowCovering')\
.get_characteristic('CurrentPosition')\
.set_value(value)
When I set open at 0% (closed):
shutter] WindowCovering TargetPosition value: 0
[shutter] WindowCovering CurrentPosition value: 0
[hap_server] 192.168.1.5 - "PUT /characteristics HTTP/1.1" 204 -
When I set open at 20%:
[shutter] WindowCovering CurrentPosition value: 26
[hap_server] 192.168.1.5 - "PUT /characteristics HTTP/1.1" 204 -
[shutter] WindowCovering TargetPosition value: 24
[shutter] WindowCovering CurrentPosition value: 24
[hap_server] 192.168.1.5 - "PUT /characteristics HTTP/1.1" 204 -
[shutter] WindowCovering TargetPosition value: 22
[shutter] WindowCovering CurrentPosition value: 22
[hap_server] 192.168.1.5 - "PUT /characteristics HTTP/1.1" 204 -
[shutter] WindowCovering TargetPosition value: 21
[shutter] WindowCovering CurrentPosition value: 21
[hap_server] 192.168.1.5 - "PUT /characteristics HTTP/1.1" 204 -
[shutter] WindowCovering TargetPosition value: 20
[shutter] WindowCovering CurrentPosition value: 20
[hap_server] 192.168.1.5 - "PUT /characteristics HTTP/1.1" 204 -
When I set open at 100% (full open):
[shutter] WindowCovering TargetPosition value: 100
[shutter] WindowCovering CurrentPosition value: 100
[hap_server] 192.168.1.5 - "PUT /characteristics HTTP/1.1" 204 -
You can check the file new shutter.py file version. Can I make a PR to merge this in the main repo?
Regards, Ludovic