HomeKit Framework
Carlos Raventos
Martial Lienert
Produits MFi
Station météo
Caméras : Welcome, Presence
+ HomeKit
Thermostat
Healthy Home Coach
Plan
Finalité
Technologies impliquées, spécificités
Configuration initiale d’un accessoire
Contrôle
Retour d’expérience
Finalité
Concerne les accessoires de contrôle de la maison : Thermostats, Prises,
Interrupteurs, Ampoules, Fenêtres, volets, sensors, etc.
Coordonner et contrôler des accessoires de différents fabricants, avec :
➔Apps tierces iOS, watchOS, tvOS : Framework Homekit
➔Siri
➔Apple Home : automations
Technologies impliquées
Base de données partagée : iCloud (structure de la maison, nommage)
Clés cryptographiques partagées à travers iCloud Keychain
HomeKit Accessory Protocol : entre un contrôleur (iPhone, Apple TV) et un
accessoire (BLE, IP)
Framework : Découverte, contrôle, monitoring accessoires
Spécificités
Pas de compte utilisateur à créer
Pas de serveur tiers
Securité end to end:
➔Clés stockées seulement dans iOS et l’accessoire
➔Un seul master
Accès distant avec Apple TV et iPad
Hiérarchie de données
HMHome
HMRoom
HMAccessory
HMService
HMCharacteristic
Configuration initiale
WiFi
Créer/choisir une maison
Appairage Homekit
Créer/choisir une pièce
Nommer les services contrôlables
WiFi avant iOS 10 : EAWiFiUnconfiguredAccessoryBrowser
let externalAccessoryBrowser = EAWiFiUnconfiguredAccessoryBrowser(delegate: self, queue: dispatch_get_main_queue())
externalAccessoryBrowser.startSearchingForUnconfiguredAccessoriesMatchingPredicate(nil)
// MARK: EAWiFiUnconfiguredAccessoryBrowserDelegate Methods
func accessoryBrowser(browser: EAWiFiUnconfiguredAccessoryBrowser, didFindUnconfiguredAccessories accessories:
Set<EAWiFiUnconfiguredAccessory>) {
}
func accessoryBrowser(browser: EAWiFiUnconfiguredAccessoryBrowser, didRemoveUnconfiguredAccessories accessories:
Set<EAWiFiUnconfiguredAccessory>) {
}
func accessoryBrowser(browser: EAWiFiUnconfiguredAccessoryBrowser, didUpdateState state:
EAWiFiUnconfiguredAccessoryBrowserState) {
}
func accessoryBrowser(browser: EAWiFiUnconfiguredAccessoryBrowser, didFinishConfiguringAccessory accessory:
EAWiFiUnconfiguredAccessory, withStatus status: EAWiFiUnconfiguredAccessoryConfigurationStatus) {
if status == .Success {
// store accessory name and proceed to add to HMHome
}
}
externalAccessoryBrowser.configureAccessory(accessory, withConfigurationUIOnViewController: self)
WiFi depuis iOS 10 : HMAccessoryBrowser
let accessoryBrowser = HMAccessoryBrowser()
accessoryBrowser.delegate = self
accessoryBrowser.startSearchingForNewAccessories()
// MARK: HMAccessoryBrowserDelegate Methods
func accessoryBrowser(browser: HMAccessoryBrowser, didFindNewAccessory accessory: HMAccessory) {
}
func accessoryBrowser(browser: HMAccessoryBrowser, didRemoveNewAccessory accessory: HMAccessory) {
}
var home: HMHome? = HMHomeManager().primaryHome
home?.addAccessory(accessory) { error in
if let error = error {
// handle error
} else {
// Once it's successfully added to the home, add it to the room that's selected.
}
}
Appairage HomeKit : HMAccessoryBrowser
Créer/choisir une pièce
//func home(home: HMHome, assignAccessory accessory: HMAccessory, toRoom room: HMRoom) {
home.assignAccessory(accessory, toRoom: room) { error in
if let error = error {
//displayError(error)
} else {
//update view
}
//}
Nommer les services
//func updateName(name: String, forAccessory accessory: HMAccessory) {
accessory.updateName(name) { error in
if let error = error {
//displayError(error)
} else {
//update view
}
//}
Observe Home Database updates
public protocol HMHomeManagerDelegate : NSObjectProtocol {
optional public func homeManagerDidUpdateHomes(_ manager: HMHomeManager)
optional public func homeManagerDidUpdatePrimaryHome(_ manager: HMHomeManager)
optional public func homeManager(_ manager: HMHomeManager, didAddHome: HMHome)
optional public func homeManager(_ manager: HMHomeManager, didRemoveHome: HMHome)
}
Observe Home Database updates
public protocol HMHomeDelegate : NSObjectProtocol {
optional public func homeDidUpdateName(_ home: HMHome)
optional public func home(_ home: HMHome, didAddAccessory: HMAccessory)
optional public func home(_ home: HMHome, didRemoveAccessory: HMAccessory)
optional public func home(_ home: HMHome, didUpdateRoom: HMRoom, forAccessory: HMAccessory)
optional public func home(_ home: HMHome, didAddRoom: HMRoom)
optional public func home(_ home: HMHome, didRemoveRoom: HMRoom)
// (... a lot more)
}
Observe Home Database updates
public protocol HMHomeDelegate : NSObjectProtocol {
optional public func homeDidUpdateName(_ home: HMHome)
optional public func home(_ home: HMHome, didAddAccessory: HMAccessory)
optional public func home(_ home: HMHome, didRemoveAccessory: HMAccessory)
optional public func home(_ home: HMHome, didUpdateRoom: HMRoom, forAccessory: HMAccessory)
optional public func home(_ home: HMHome, didAddRoom: HMRoom)
optional public func home(_ home: HMHome, didRemoveRoom: HMRoom)
// (... a lot more)
}
// Notifications are only received
// if the database is modified by
// another device/app !
Contrôle de l’accessoire
Actions possibles:
Lire une caractéristique
Ecrire une caractéristique
Ecouter les notifications
Créer des scènes (écritures groupées de caractéristiques)
Triggers (Réagir aux changements de valeur des caractéristiques)
Contrôle de l’accessoire
import HomeKit
var lightBulb: HMAccessory?
// Get the PowerState characteristic through the LightBulb service
let lightBulbOn = lightBulb?.services.first(where: { (service) -> Bool in
service.serviceType == HMServiceTypeLightbulb
})?.characteristics.first(where: { (characteristic) -> Bool in
characteristic.characteristicType == HMCharacteristicTypePowerState
})
Lecture d’une caractéristique
// func readValue(completionHandler completion: @escaping (Error?) -> Void)
// var value: Any? { get }
lightBulbOn?.readValue(completionHandler: { (error) in
if let error = error {
// Handle the error
} else if let isOn = lightBulbOn?.value as? Bool {
print("Light bulb is (isOn ? "ON" : "OFF")")
}
})
Ecriture d’une caractéristique
// func writeValue(_ value: Any?, completionHandler completion: @escaping (Error?) -> Void)
lightBulbOn?.writeValue(false, completionHandler: { (error) in
if let error = error {
// Handle the error
} else {
print("Light bulb is OFF")
}
})
Notifications
// func enableNotification(_ enable: Bool, completionHandler completion: @escaping (Error?) -> Void)
lightBulbOn?.enableNotification(true, completionHandler: { (error) in
if let error = error {
// Handle error
} else {
print("Notifications are enabled")
}
})
class AccDelegate : NSObject, HMAccessoryDelegate {
public func accessory(_ accessory: HMAccessory, service: HMService, didUpdateValueForCharacteristic: HMCharacteristic) {
if let isOn = characteristic.value as? Bool {
print("Light bulb is now (isOn ? "ON" : "OFF")")
}
}
}
let delegate = AccDelegate()
lightBulb?.delegate = delegate;

Présentation de HomeKit

  • 1.
  • 2.
    Produits MFi Station météo Caméras: Welcome, Presence + HomeKit Thermostat Healthy Home Coach
  • 3.
    Plan Finalité Technologies impliquées, spécificités Configurationinitiale d’un accessoire Contrôle Retour d’expérience
  • 4.
    Finalité Concerne les accessoiresde contrôle de la maison : Thermostats, Prises, Interrupteurs, Ampoules, Fenêtres, volets, sensors, etc. Coordonner et contrôler des accessoires de différents fabricants, avec : ➔Apps tierces iOS, watchOS, tvOS : Framework Homekit ➔Siri ➔Apple Home : automations
  • 5.
    Technologies impliquées Base dedonnées partagée : iCloud (structure de la maison, nommage) Clés cryptographiques partagées à travers iCloud Keychain HomeKit Accessory Protocol : entre un contrôleur (iPhone, Apple TV) et un accessoire (BLE, IP) Framework : Découverte, contrôle, monitoring accessoires
  • 6.
    Spécificités Pas de compteutilisateur à créer Pas de serveur tiers Securité end to end: ➔Clés stockées seulement dans iOS et l’accessoire ➔Un seul master Accès distant avec Apple TV et iPad
  • 7.
  • 8.
    Configuration initiale WiFi Créer/choisir unemaison Appairage Homekit Créer/choisir une pièce Nommer les services contrôlables
  • 9.
    WiFi avant iOS10 : EAWiFiUnconfiguredAccessoryBrowser let externalAccessoryBrowser = EAWiFiUnconfiguredAccessoryBrowser(delegate: self, queue: dispatch_get_main_queue()) externalAccessoryBrowser.startSearchingForUnconfiguredAccessoriesMatchingPredicate(nil) // MARK: EAWiFiUnconfiguredAccessoryBrowserDelegate Methods func accessoryBrowser(browser: EAWiFiUnconfiguredAccessoryBrowser, didFindUnconfiguredAccessories accessories: Set<EAWiFiUnconfiguredAccessory>) { } func accessoryBrowser(browser: EAWiFiUnconfiguredAccessoryBrowser, didRemoveUnconfiguredAccessories accessories: Set<EAWiFiUnconfiguredAccessory>) { } func accessoryBrowser(browser: EAWiFiUnconfiguredAccessoryBrowser, didUpdateState state: EAWiFiUnconfiguredAccessoryBrowserState) { } func accessoryBrowser(browser: EAWiFiUnconfiguredAccessoryBrowser, didFinishConfiguringAccessory accessory: EAWiFiUnconfiguredAccessory, withStatus status: EAWiFiUnconfiguredAccessoryConfigurationStatus) { if status == .Success { // store accessory name and proceed to add to HMHome } } externalAccessoryBrowser.configureAccessory(accessory, withConfigurationUIOnViewController: self)
  • 10.
    WiFi depuis iOS10 : HMAccessoryBrowser let accessoryBrowser = HMAccessoryBrowser() accessoryBrowser.delegate = self accessoryBrowser.startSearchingForNewAccessories() // MARK: HMAccessoryBrowserDelegate Methods func accessoryBrowser(browser: HMAccessoryBrowser, didFindNewAccessory accessory: HMAccessory) { } func accessoryBrowser(browser: HMAccessoryBrowser, didRemoveNewAccessory accessory: HMAccessory) { } var home: HMHome? = HMHomeManager().primaryHome home?.addAccessory(accessory) { error in if let error = error { // handle error } else { // Once it's successfully added to the home, add it to the room that's selected. } }
  • 11.
    Appairage HomeKit :HMAccessoryBrowser
  • 12.
    Créer/choisir une pièce //funchome(home: HMHome, assignAccessory accessory: HMAccessory, toRoom room: HMRoom) { home.assignAccessory(accessory, toRoom: room) { error in if let error = error { //displayError(error) } else { //update view } //}
  • 13.
    Nommer les services //funcupdateName(name: String, forAccessory accessory: HMAccessory) { accessory.updateName(name) { error in if let error = error { //displayError(error) } else { //update view } //}
  • 14.
    Observe Home Databaseupdates public protocol HMHomeManagerDelegate : NSObjectProtocol { optional public func homeManagerDidUpdateHomes(_ manager: HMHomeManager) optional public func homeManagerDidUpdatePrimaryHome(_ manager: HMHomeManager) optional public func homeManager(_ manager: HMHomeManager, didAddHome: HMHome) optional public func homeManager(_ manager: HMHomeManager, didRemoveHome: HMHome) }
  • 15.
    Observe Home Databaseupdates public protocol HMHomeDelegate : NSObjectProtocol { optional public func homeDidUpdateName(_ home: HMHome) optional public func home(_ home: HMHome, didAddAccessory: HMAccessory) optional public func home(_ home: HMHome, didRemoveAccessory: HMAccessory) optional public func home(_ home: HMHome, didUpdateRoom: HMRoom, forAccessory: HMAccessory) optional public func home(_ home: HMHome, didAddRoom: HMRoom) optional public func home(_ home: HMHome, didRemoveRoom: HMRoom) // (... a lot more) }
  • 16.
    Observe Home Databaseupdates public protocol HMHomeDelegate : NSObjectProtocol { optional public func homeDidUpdateName(_ home: HMHome) optional public func home(_ home: HMHome, didAddAccessory: HMAccessory) optional public func home(_ home: HMHome, didRemoveAccessory: HMAccessory) optional public func home(_ home: HMHome, didUpdateRoom: HMRoom, forAccessory: HMAccessory) optional public func home(_ home: HMHome, didAddRoom: HMRoom) optional public func home(_ home: HMHome, didRemoveRoom: HMRoom) // (... a lot more) } // Notifications are only received // if the database is modified by // another device/app !
  • 17.
    Contrôle de l’accessoire Actionspossibles: Lire une caractéristique Ecrire une caractéristique Ecouter les notifications Créer des scènes (écritures groupées de caractéristiques) Triggers (Réagir aux changements de valeur des caractéristiques)
  • 18.
    Contrôle de l’accessoire importHomeKit var lightBulb: HMAccessory? // Get the PowerState characteristic through the LightBulb service let lightBulbOn = lightBulb?.services.first(where: { (service) -> Bool in service.serviceType == HMServiceTypeLightbulb })?.characteristics.first(where: { (characteristic) -> Bool in characteristic.characteristicType == HMCharacteristicTypePowerState })
  • 19.
    Lecture d’une caractéristique //func readValue(completionHandler completion: @escaping (Error?) -> Void) // var value: Any? { get } lightBulbOn?.readValue(completionHandler: { (error) in if let error = error { // Handle the error } else if let isOn = lightBulbOn?.value as? Bool { print("Light bulb is (isOn ? "ON" : "OFF")") } })
  • 20.
    Ecriture d’une caractéristique //func writeValue(_ value: Any?, completionHandler completion: @escaping (Error?) -> Void) lightBulbOn?.writeValue(false, completionHandler: { (error) in if let error = error { // Handle the error } else { print("Light bulb is OFF") } })
  • 21.
    Notifications // func enableNotification(_enable: Bool, completionHandler completion: @escaping (Error?) -> Void) lightBulbOn?.enableNotification(true, completionHandler: { (error) in if let error = error { // Handle error } else { print("Notifications are enabled") } }) class AccDelegate : NSObject, HMAccessoryDelegate { public func accessory(_ accessory: HMAccessory, service: HMService, didUpdateValueForCharacteristic: HMCharacteristic) { if let isOn = characteristic.value as? Bool { print("Light bulb is now (isOn ? "ON" : "OFF")") } } } let delegate = AccDelegate() lightBulb?.delegate = delegate;