From 19a762d7e3e39c2e867247bb9c32001759656d6b Mon Sep 17 00:00:00 2001 From: gbrooker Date: Thu, 22 Feb 2018 22:18:04 +0800 Subject: [PATCH] Add onGetValue callback to GenericCharacteristic for lazy queries Separate functions to obtain the value of a characteristic for a HAP server and to just get a jason formatted value. --- Sources/HAP/Base/Characteristic.swift | 26 ++++++++++++++++--- Sources/HAP/Endpoints/characteristics().swift | 2 +- Sources/HAP/Utils/Event.swift | 2 +- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/Sources/HAP/Base/Characteristic.swift b/Sources/HAP/Base/Characteristic.swift index 82fe8f37..d4a220ad 100644 --- a/Sources/HAP/Base/Characteristic.swift +++ b/Sources/HAP/Base/Characteristic.swift @@ -1,5 +1,9 @@ import Foundation +#if os(Linux) + import Dispatch +#endif + public struct AnyCharacteristic { let wrapped: Characteristic @@ -17,7 +21,8 @@ protocol Characteristic: class, JSONSerializable { var iid: InstanceID { get set } var type: CharacteristicType { get } var permissions: [CharacteristicPermission] { get } - func getValue() -> JSONValueType? + func jsonValue() -> JSONValueType? + func getValue(fromConnection: Server.Connection?) -> JSONValueType? func setValue(_: Any?, fromConnection: Server.Connection?) throws var description: String? { get } var format: CharacteristicFormat? { get } @@ -38,7 +43,7 @@ extension Characteristic { if permissions.contains(.read) { // TODO: fixit - serialized["value"] = getValue() ?? 0 //NSNull() + serialized["value"] = jsonValue() ?? 0 //NSNull() } if let description = description { serialized["description"] = description } @@ -89,10 +94,20 @@ public class GenericCharacteristic: Characteristic, } } - func getValue() -> JSONValueType? { + func jsonValue() -> JSONValueType? { return value?.jsonValueType } + // Get Value for HAP controller + func getValue(fromConnection connection: Server.Connection?) -> JSONValueType? { + let currentValue = _value + DispatchQueue.global(qos: .userInitiated).async { [weak self] in + self?.onDidGetValue?(currentValue) + } + return jsonValue() + } + + // Set Value by HAP controller func setValue(_ newValue: Any?, fromConnection connection: Server.Connection?) throws { switch newValue { case let some?: @@ -106,6 +121,11 @@ public class GenericCharacteristic: Characteristic, service?.characteristic(self, didChangeValue: _value) } + // Subscribe a listener to value requests from (remote) HAP controllers. + // Called asynchronously on a global queue with the current value. + // Only a single listener is permitted. + public var onDidGetValue: ((T?) -> Void)? + public let permissions: [CharacteristicPermission] public var description: String? diff --git a/Sources/HAP/Endpoints/characteristics().swift b/Sources/HAP/Endpoints/characteristics().swift index d748ede5..6e11db7c 100644 --- a/Sources/HAP/Endpoints/characteristics().swift +++ b/Sources/HAP/Endpoints/characteristics().swift @@ -44,7 +44,7 @@ func characteristics(device: Device) -> Application { } var value: Protocol.Value? - switch characteristic.getValue() { + switch characteristic.getValue(fromConnection: connection) { case let _value as Double: value = .double(_value) case let _value as Float: value = .double(Double(_value)) case let _value as Int: value = .int(_value) diff --git a/Sources/HAP/Utils/Event.swift b/Sources/HAP/Utils/Event.swift index 80118e0b..4b1fa05d 100644 --- a/Sources/HAP/Utils/Event.swift +++ b/Sources/HAP/Utils/Event.swift @@ -62,7 +62,7 @@ struct Event { guard let aid = c.service?.accessory?.aid else { throw Error.characteristicWithoutAccessory } - payload.append(["aid": aid, "iid": c.iid, "value": c.getValue() ?? NSNull()]) + payload.append(["aid": aid, "iid": c.iid, "value": c.jsonValue() ?? NSNull()]) } let serialized = ["characteristics": payload] guard let body = try? JSONSerialization.data(withJSONObject: serialized, options: []) else {