HubitatServer: Adds HubitatServer type and adds it to the multiplexer
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
//
|
||||
// HubitatServer.swift
|
||||
// XIONControlPanel
|
||||
//
|
||||
// Created by James Magahern on 3/14/20.
|
||||
// Copyright © 2020 XION. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Combine
|
||||
|
||||
class HubitatServer : Server
|
||||
{
|
||||
var connected: Bool = false
|
||||
|
||||
public fileprivate(set) var devices: [HubitatDevice] = []
|
||||
|
||||
private let baseURL: URL
|
||||
private let accessToken = "fa861583-71f0-466f-8add-f29b2278af6a"
|
||||
private var cancellable: AnyCancellable?
|
||||
|
||||
required init(_ url: URL)
|
||||
{
|
||||
self.baseURL = url
|
||||
}
|
||||
|
||||
func connect(_ completion: @escaping (Error?) -> Void)
|
||||
{
|
||||
// RESTful, assume we're connected unless we get an error
|
||||
self.connected = true
|
||||
completion(nil)
|
||||
}
|
||||
|
||||
func disconnect(_ completion: (Error?) -> Void)
|
||||
{
|
||||
self.connected = false
|
||||
}
|
||||
|
||||
func fetchDevices(_ fetchCompletion: @escaping (Result<[AnyDevice], Error>) -> Void)
|
||||
{
|
||||
let url = baseURL.appendingPathComponent("devices/all").authenticatedURLWithAccessToken(accessToken)
|
||||
|
||||
self.cancellable = URLSession.shared.dataTaskPublisher(for: url)
|
||||
.mapError { $0 as Error }
|
||||
.map { $0.data }
|
||||
.decode(type: [HubitatDevice].self, decoder: JSONDecoder())
|
||||
.eraseToAnyPublisher()
|
||||
.sink(receiveCompletion: { completion in
|
||||
if case let Subscribers.Completion.failure(error) = completion {
|
||||
fetchCompletion(.failure(error))
|
||||
}
|
||||
}) { (devices: [HubitatDevice]) in
|
||||
self.devices = devices
|
||||
fetchCompletion(.success(devices.map { AnyDevice($0) }))
|
||||
}
|
||||
}
|
||||
|
||||
func toggleDevice(_ device: AnyDevice, state: DeviceState, completion: @escaping (Error?) -> Void)
|
||||
{
|
||||
if let hubitatDevice = (self.devices.first { $0.serial == device.serial }) {
|
||||
print("HUBITAT: Toggle: ", hubitatDevice.id)
|
||||
|
||||
// TODO...
|
||||
}
|
||||
}
|
||||
|
||||
func responsibleForDevice(_ device: AnyDevice) -> Bool
|
||||
{
|
||||
return self.devices.contains { $0.serial == device.serial }
|
||||
}
|
||||
}
|
||||
|
||||
extension URL
|
||||
{
|
||||
func authenticatedURLWithAccessToken(_ token: String) -> URL
|
||||
{
|
||||
guard var components = URLComponents(url: self, resolvingAgainstBaseURL: false) else { fatalError() }
|
||||
components.queryItems = [ URLQueryItem(name: "access_token", value: token) ]
|
||||
|
||||
return components.url!
|
||||
}
|
||||
}
|
||||
@@ -102,14 +102,7 @@ extension ServerMultiplex
|
||||
private func handleDevicesChanged(_ devicesChanged: [AnyDevice])
|
||||
{
|
||||
let newDevicesSet = Set<AnyDevice>(devicesChanged)
|
||||
|
||||
let additions = newDevicesSet.subtracting(self.devices)
|
||||
if additions.count > 0 {
|
||||
DispatchQueue.main.async {
|
||||
self.delegate?.serverMultiplex(self, didAddDevices: Array(additions))
|
||||
}
|
||||
}
|
||||
|
||||
let changed = newDevicesSet.filter { (device: AnyDevice) in
|
||||
if let existing = (devices.first { $0.hashValue == device.hashValue }) {
|
||||
return existing.state != device.state
|
||||
@@ -118,13 +111,19 @@ extension ServerMultiplex
|
||||
return false
|
||||
}
|
||||
|
||||
self.devices = self.devices.union(newDevicesSet)
|
||||
|
||||
if additions.count > 0 {
|
||||
DispatchQueue.main.async {
|
||||
self.delegate?.serverMultiplex(self, didAddDevices: Array(additions))
|
||||
}
|
||||
}
|
||||
|
||||
if changed.count > 0 {
|
||||
DispatchQueue.main.async {
|
||||
self.delegate?.serverMultiplex(self, devicesStateChanged: Array(changed))
|
||||
}
|
||||
}
|
||||
|
||||
self.devices = self.devices.union(newDevicesSet)
|
||||
}
|
||||
|
||||
private func handleError(_ error: Error)
|
||||
|
||||
Reference in New Issue
Block a user