hap-rs
hap-rs copied to clipboard
Cannot pair with thermostat, ip_camera, light_sensor, or video_doorbell accessories
Pairing fails whenever a thermostat accessory is added.
To reproduce:
extern crate hap;
use hap::{
accessory::{bridge, thermostat, Category, Information},
transport::{IpTransport, Transport},
Config,
};
fn main() {
pretty_env_logger::init();
let bridge = bridge::new(Information {
name: "Bridge".into(),
..Default::default()
})
.unwrap();
let thermostat = thermostat::new(Information {
name: "Thermostat".into(),
..Default::default()
})
.unwrap();
let config = Config {
name: "Test".into(),
category: Category::Bridge,
..Default::default()
};
let mut ip_transport = IpTransport::new(config).unwrap();
ip_transport.add_accessory(bridge).unwrap();
ip_transport.add_accessory(thermostat).unwrap();
ip_transport.start().unwrap();
}
attempt to pair with code 11122333
fails with message "Home couldn't connect to this accessory". No errors are logged via the service.
changing the thermostat accessory to Outlet
or Valve
and pairing is successful.
Looks like this behavior is also present with ip_camera
, light_sensor
, and video_doorbell
. Uncommenting any of the add_accessory()
lines below will result in failure to pair.
extern crate hap;
use hap::{
accessory::{
air_purifier, air_quality_sensor, bridge, carbon_dioxide_sensor, carbon_monoxide_sensor,
contact_sensor, door, fan, fan_v2, garage_door_opener, heater_cooler,
humidifier_dehumidifier, humidity_sensor, ip_camera, leak_sensor, light_sensor, lightbulb,
lock, motion_sensor, occupancy_sensor, outlet, security_system, smoke_sensor,
stateless_programmable_switch, switch, temperature_sensor, thermostat, valve,
video_doorbell, window, window_covering, Category, Information,
},
transport::{IpTransport, Transport},
Config, Error,
};
fn main() -> Result<(), Error> {
let config = Config {
name: "Test".into(),
category: Category::Bridge,
..Default::default()
};
let mut ipt = IpTransport::new(config)?;
ipt.add_accessory(air_purifier::new(Information::default())?)?;
ipt.add_accessory(air_quality_sensor::new(Information::default())?)?;
ipt.add_accessory(bridge::new(Information::default())?)?;
ipt.add_accessory(carbon_dioxide_sensor::new(Information::default())?)?;
ipt.add_accessory(carbon_monoxide_sensor::new(Information::default())?)?;
ipt.add_accessory(contact_sensor::new(Information::default())?)?;
ipt.add_accessory(door::new(Information::default())?)?;
ipt.add_accessory(fan::new(Information::default())?)?;
ipt.add_accessory(fan_v2::new(Information::default())?)?;
ipt.add_accessory(garage_door_opener::new(Information::default())?)?;
ipt.add_accessory(heater_cooler::new(Information::default())?)?;
ipt.add_accessory(humidifier_dehumidifier::new(Information::default())?)?;
ipt.add_accessory(humidity_sensor::new(Information::default())?)?;
// ipt.add_accessory(ip_camera::new(Information::default())?)?;
ipt.add_accessory(leak_sensor::new(Information::default())?)?;
// ipt.add_accessory(light_sensor::new(Information::default())?)?;
ipt.add_accessory(lightbulb::new(Information::default())?)?;
ipt.add_accessory(lock::new(Information::default())?)?;
ipt.add_accessory(motion_sensor::new(Information::default())?)?;
ipt.add_accessory(occupancy_sensor::new(Information::default())?)?;
ipt.add_accessory(outlet::new(Information::default())?)?;
ipt.add_accessory(security_system::new(Information::default())?)?;
ipt.add_accessory(smoke_sensor::new(Information::default())?)?;
ipt.add_accessory(stateless_programmable_switch::new(Information::default())?)?;
ipt.add_accessory(switch::new(Information::default())?)?;
ipt.add_accessory(temperature_sensor::new(Information::default())?)?;
// ipt.add_accessory(thermostat::new(Information::default())?)?;
ipt.add_accessory(valve::new(Information::default())?)?;
// ipt.add_accessory(video_doorbell::new(Information::default())?)?;
ipt.add_accessory(window::new(Information::default())?)?;
ipt.add_accessory(window_covering::new(Information::default())?)?;
ipt.start()?;
Ok(())
}
So far I've found that the service is getting to the /pair-verify - M4: Sending Verify Finish Response
where it sends back the following response for the accessory w/ thermostat service:
{
"accessories":[
{
"aid":1,
"services":[
{
"iid":1,
"type":"3E",
"hidden":false,
"primary":false,
"characteristics":[
{
"iid":2,
"type":"14",
"format":"bool",
"perms":[
"pw"
]
},
{
"iid":3,
"type":"20",
"format":"string",
"perms":[
"pr"
],
"value":"undefined"
},
{
"iid":4,
"type":"21",
"format":"string",
"perms":[
"pr"
],
"value":"undefined"
},
{
"iid":5,
"type":"23",
"format":"string",
"perms":[
"pr"
],
"value":"undefined"
},
{
"iid":6,
"type":"30",
"format":"string",
"perms":[
"pr"
],
"value":"undefined",
"maxLen":64
},
{
"iid":7,
"type":"52",
"format":"string",
"perms":[
"pr"
],
"value":"undefined"
}
]
},
{
"iid":8,
"type":"4A",
"hidden":false,
"primary":true,
"characteristics":[
{
"iid":9,
"type":"F",
"format":"uint8",
"perms":[
"pr",
"ev"
],
"value":0,
"valid-values":[
0,
1,
2
]
},
{
"iid":10,
"type":"33",
"format":"uint8",
"perms":[
"pr",
"pw",
"ev"
],
"value":0,
"valid-values":[
0,
1,
2,
3
]
},
{
"iid":11,
"type":"11",
"format":"float",
"perms":[
"pr",
"ev"
],
"value":0.0,
"unit":"celsius",
"maxValue":100.0,
"minStep":0.1
},
{
"iid":12,
"type":"35",
"format":"float",
"perms":[
"pr",
"pw",
"ev"
],
"value":0.0,
"unit":"celsius",
"maxValue":38.0,
"minValue":10.0,
"minStep":0.1
},
{
"iid":13,
"type":"36",
"format":"uint8",
"perms":[
"pr",
"pw",
"ev"
],
"value":0,
"valid-values":[
0,
1
]
}
]
}
]
}
]
}
immediately thereafter an unpairing request comes through, whereas a working pairing next queries characteristics
Thanks a lot for testing & reporting! The unpairing request seems to be the the expected behaviour of an iOS controller getting an invalid accessories JSON, e.g. with required characteristics missing or forbidden characteristics included in an accessory. I will look into this.
So this is a weird one.
I discovered a bug causing zeroes as characteristic min_value
s not to be rendered into the auto-generated characteristics, but fixing it didn't change anything about the thermostat and light sensor accessories being invalid. The invalidity of the IP camera and video doorbell is obvious, as video streams aren't implemented in this crate yet.
Currently, I'm generating the accessories, services and characteristics from the HomeKit Accessory Simulator from the Additional Tools for Xcode 10.1 Beta 3.
I will publish the fix for the min_values as soon as the upcoming version of handlebars-rs it depends on is published and keep investigating the invalidity of the two accessories, but unfortunately I don't have much time for it at the moment.
Thanks for your patience and feel free to contribute if you find out anything about this issue in the meantime.
@ewilken Hey i was curious sine the above is over a year old, do you have video streams working yet? I see the use of CameraRTPStreamManagement
but it's auto generated type. Just cant tell.
In the example above, it at least looks like IID 12 should have a minimum value of 10.0 but has a value of 0.0 That doesn't look right
Perhaps we should compare values with the values that the simulator sets on a 'fresh' set up of these accessories and that the default values should mimic them to an extent that they seem to have some influence on the pairing process?