From a054347f3227e49c7d037c842d8b3be9cac21725 Mon Sep 17 00:00:00 2001 From: James Magahern Date: Thu, 30 Apr 2020 19:00:08 -0700 Subject: [PATCH] HubitatServer: finishes ability to toggle hubitat switches --- XIONControlPanel/Servers/HubitatServer.swift | 35 ++++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/XIONControlPanel/Servers/HubitatServer.swift b/XIONControlPanel/Servers/HubitatServer.swift index 33fd94e..f593311 100644 --- a/XIONControlPanel/Servers/HubitatServer.swift +++ b/XIONControlPanel/Servers/HubitatServer.swift @@ -9,7 +9,12 @@ import Foundation import Combine -class HubitatServer : Server +public enum HubitatServerError : Error +{ + case apiError +} + +public class HubitatServer : Server { var connected: Bool = false @@ -17,7 +22,8 @@ class HubitatServer : Server private let baseURL: URL private let accessToken = "fa861583-71f0-466f-8add-f29b2278af6a" - private var cancellable: AnyCancellable? + private var fetchCancellable: AnyCancellable? + private var switchCancellable: AnyCancellable? required init(_ url: URL) { @@ -40,7 +46,7 @@ class HubitatServer : Server { let url = baseURL.appendingPathComponent("devices/all").authenticatedURLWithAccessToken(accessToken) - self.cancellable = URLSession.shared.dataTaskPublisher(for: url) + self.fetchCancellable = URLSession.shared.dataTaskPublisher(for: url) .mapError { $0 as Error } .map { $0.data } .decode(type: [HubitatDevice].self, decoder: JSONDecoder()) @@ -55,12 +61,29 @@ class HubitatServer : Server } } - func toggleDevice(_ device: AnyDevice, state: DeviceState, completion: @escaping (Error?) -> Void) + func toggleDevice(_ device: AnyDevice, state: DeviceState, completion toggleCompletion: @escaping (Error?) -> Void) { if let hubitatDevice = (self.devices.first { $0.serial == device.serial }) { - print("HUBITAT: Toggle: ", hubitatDevice.id) + let command = "devices/\(hubitatDevice.id)/\(state)" + let url = baseURL.appendingPathComponent(command).authenticatedURLWithAccessToken(accessToken) - // TODO... + self.switchCancellable = URLSession.shared.dataTaskPublisher(for: url) + .tryMap { data, response -> Data in + guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else { + throw HubitatServerError.apiError + } + + return data + } + .decode(type: HubitatDevice.self, decoder: JSONDecoder()) + .sink(receiveCompletion: { (completion: Subscribers.Completion) in + if case let Subscribers.Completion.failure(error) = completion { + toggleCompletion(error) + } + }, receiveValue: { (device: HubitatDevice) in + // don't need to do anything with this, but the server returns it to us. + toggleCompletion(nil) + }) } }