// // MeshifyFunctions.swift // pocloud // // Created by Patrick McDonagh on 5/29/18. // Copyright © 2018 patrickjmcd. All rights reserved. // import Foundation import RealmSwift import Alamofire import SwiftyJSON import PromiseKit func getDeviceTypes(baseURL : String, authToken : String) -> Promise { let realm = try! Realm() let url = "\(baseURL)/devicetypes" let headers : HTTPHeaders = [ "Authorization": authToken ] return Promise { seal in Alamofire.request(url, method: .get, headers: headers) .responseJSON { response in switch response.result { case .success: let deviceTypesJson : JSON = JSON(response.result.value!) for(_, json) : (String, JSON) in deviceTypesJson { do { try realm.write { let dt = DeviceType() dt.companyId = json["CompanyId"].intValue dt.id = json["id"].intValue dt.imgUrl = json["imgUrl"].stringValue dt.name = json["name"].stringValue dt.note = json["note"].stringValue dt.tenantId = json["tenantId"].intValue dt.vanityName = json["vanityName"].stringValue realm.add(dt, update: true) } } catch { seal.reject(error) } } seal.fulfill(true) case .failure(let error): seal.reject(error) } } } } func getAddresses(baseURL : String, authToken : String) ->Promise { let realm = try! Realm() let url = "\(baseURL)/addresses" let headers : HTTPHeaders = [ "Authorization": authToken ] return Promise { seal in Alamofire.request(url, method: .get, headers: headers) .validate() .responseJSON { response in switch response.result { case .success: let addressesJSON : JSON = JSON(response.result.value!) for(_, json) : (String, JSON) in addressesJSON { do { try realm.write { let addr = Address() addr.id = json["id"].intValue addr.apartment = json["id"].stringValue addr.city = json["city"].stringValue addr.country = json["country"].stringValue addr.lat = json["lat"].doubleValue addr.long = json["long"].doubleValue addr.state = json["state"].stringValue addr.street1 = json["street1"].stringValue addr.street2 = json["street2"].stringValue addr.zip = json["zip"].stringValue addr.zoneId = json["zoneid"].intValue realm.add(addr, update: true) } } catch { seal.reject(error) } } seal.fulfill(true) case .failure(let error): seal.reject(error) } } } } func getGateways(baseURL : String, authToken : String) -> Promise { let realm = try! Realm() let url = "\(baseURL)/gateways" let headers : HTTPHeaders = [ "Authorization": authToken ] return Promise { seal in Alamofire.request(url, method: .get, headers: headers) .responseJSON { response in switch response.result { case .success: let gatewaysJSON : JSON = JSON(response.result.value!) for(_, json) : (String, JSON) in gatewaysJSON { do { try realm.write { let gtw = Gateway() gtw.addressId = json["addressId"].intValue gtw.companyId = json["companyId"].intValue gtw.diaVersion = json["diaVersion"].stringValue gtw.gatewayConfigurationId = json["gatewayConfigurationId"].intValue gtw.gatewayTypeId = json["gatewayTypeId"].intValue gtw.id = json["id"].intValue gtw.macAddress = json["macAddress"].stringValue gtw.name = json["name"].stringValue gtw.panId = json["panId"].stringValue gtw.tenantId = json["tenantId"].intValue gtw.userId = json["userId"].intValue let associatedAddress = realm.objects(Address.self).filter("id == %d", gtw.addressId).first let parentCompany = realm.objects(Company.self).filter("id == %d", gtw.companyId).first gtw.address = associatedAddress realm.add(gtw, update: true) parentCompany?.gateways.append(gtw) } } catch { seal.reject(error) } } seal.fulfill(true) case .failure(let error): seal.reject(error) } } } } func getDevices(baseURL : String, authToken : String) ->Promise { let realm = try! Realm() let url = "\(baseURL)/devices" let headers : HTTPHeaders = [ "Authorization": authToken ] return Promise { seal in Alamofire.request(url, method: .get, headers: headers) .validate() .responseJSON { response in switch response.result { case .success: let devicesJSON : JSON = JSON(response.result.value!) for(_, json) : (String, JSON) in devicesJSON { do { try realm.write { let dev = Device() dev.companyId = json["companyId"].intValue dev.deviceTypeId = json["deviceTypeId"].intValue dev.gatewayId = json["gatewayId"].intValue dev.id = json["id"].intValue dev.macAddress = json["macAddress"].stringValue dev.techName = json["techname"].stringValue dev.tenantId = json["tenantId"].intValue dev.vanityName = json["vanityName"].stringValue let pGateway = realm.objects(Gateway.self).filter("id == %d", dev.gatewayId).first let pDeviceType = realm.objects(DeviceType.self).filter("id == %d", dev.deviceTypeId).first realm.add(dev, update: true) pGateway?.devices.append(dev) pDeviceType?.devices.append(dev) } } catch { seal.reject(error) } } seal.fulfill(true) case .failure(let error): seal.reject(error) } } } } func getChannels(deviceTypeId: Int, baseURL : String, authToken : String) -> Promise { let realm = try! Realm() let url = "\(baseURL)/devicetypes/\(deviceTypeId)/channels" let headers : HTTPHeaders = [ "Authorization": authToken ] return Promise { seal in Alamofire.request(url, method: .get, headers: headers) .responseJSON { response in switch response.result { case .success: let channelsJSON : JSON = JSON(response.result.value!) for(_, json) : (String, JSON) in channelsJSON { do { try realm.write { let ch = Channel() ch.channelType = json["channelType"].intValue ch.dataType = json["dataType"].intValue ch.defaultValue = json["defaultValue"].stringValue ch.deviceTypeId = json["deviceTypeId"].intValue ch.fromMe = json["fromMe"].boolValue ch.helpExplanation = json["helpExplanation"].stringValue ch.id = json["id"].intValue ch.io = json["io"].boolValue ch.name = json["name"].stringValue ch.regex = json["regex"].stringValue ch.regexErrMsg = json["regexErrMsg"].stringValue ch.subTitle = json["subTitle"].stringValue let pDeviceType = realm.objects(DeviceType.self).filter("id == %d", ch.deviceTypeId).first realm.add(ch, update: true) pDeviceType?.channels.append(ch) } } catch { seal.reject(error) } } seal.fulfill(true) case .failure(let error): seal.reject(error) } } } } func getChannelValues(deviceId: Int, baseURL : String, authToken : String) -> Promise<[String : MeshifyValue]> { let url = "\(baseURL)/devices/\(deviceId)/values" let headers : HTTPHeaders = [ "Authorization": authToken ] return Promise { prom in Alamofire.request(url, method: .get, headers: headers) .responseJSON { response in switch response.result { case .success: let channelValJSON : JSON = JSON(response.result.value!) var valueDict : [String : MeshifyValue] = [:] for(chName, json) : (String, JSON) in channelValJSON { let chv = MeshifyValue() chv.name = chName chv.value = json["value"].stringValue chv.timestamp = json["timestamp"].intValue valueDict[chv.name] = chv } prom.fulfill(valueDict) case .failure(let error): prom.reject(error) } } } } func getChannelHistory(deviceId: Int, channelId : Int, baseURL : String, authToken : String) -> Promise<[ChannelHistoryValue]> { let url = "\(baseURL)/devices/\(deviceId)/values/\(channelId)" let headers : HTTPHeaders = [ "Authorization": authToken ] return Promise { promise in Alamofire.request(url, method: .get, headers: headers) .responseJSON { response in switch response.result { case .success: let channelHistoryJSON : JSON = JSON(response.result.value!) var channelHistory = [ChannelHistoryValue]() for(_, json) : (String, JSON) in channelHistoryJSON { let chHistVal = ChannelHistoryValue() chHistVal.timestamp = Date(timeIntervalSince1970: Double(json["timestamp"].intValue)) chHistVal.value = json["value"].stringValue channelHistory.append(chHistVal) } channelHistory.reverse() promise.fulfill(channelHistory) case .failure(let error): promise.reject(error) } } } } func getCompanies(baseURL : String, authToken : String) -> Promise { let realm = try! Realm() let url = "\(baseURL)/companies" let headers : HTTPHeaders = [ "Authorization": authToken ] return Promise { seal in Alamofire.request(url, method: .get, headers: headers) .responseJSON { response in switch response.result { case .success: let gatewaysJSON : JSON = JSON(response.result.value!) for(_, json) : (String, JSON) in gatewaysJSON { do { try realm.write { let company = Company() company.id = json["id"].intValue company.name = json["name"].stringValue company.tenantId = json["tenantId"].intValue company.addressId = json["addressId"].intValue company.address = realm.objects(Address.self).filter("id == %d", company.addressId).first realm.add(company, update: true) } } catch { seal.reject(error) } } seal.fulfill(true) case .failure(let error): seal.reject(error) } } } } func getAllMeshifyData(baseURL : String, authToken : String) -> Promise{ return Promise { promise in firstly { getDeviceTypes(baseURL: baseURL, authToken: authToken) }.then { _ in getCompanies(baseURL: baseURL, authToken: authToken) }.then { _ in getAddresses(baseURL: baseURL, authToken: authToken) }.then { _ in getGateways(baseURL: baseURL, authToken: authToken) }.then { _ in getDevices(baseURL: baseURL, authToken: authToken) }.done{ _ in promise.fulfill(()) }.catch { error in promise.reject(error) } } } func writeChannelValue(deviceId: Int, channelName: String, value : String, baseURL : String, authToken : String) -> Promise { // let timestamp: Int = Int(Date().timeIntervalSince1970) var channelJson : JSON = JSON() channelJson["name"].string = channelName // channelJson["timestamp"].int = timestamp channelJson["value"].string = value var listJson = JSON() listJson.arrayObject = [channelJson] let url = "\(baseURL)/devices/\(deviceId)/values" let headers : HTTPHeaders = [ "Authorization": authToken ] return Promise { promise in Alamofire.request(url, method: .put, parameters: [:], encoding: listJson.rawString()!, headers: headers) .response { response in if response.response?.statusCode == 200 { promise.fulfill(true) } else { promise.reject(String(response.response!.statusCode) as! Error) } } } } func setChannelValue(deviceId: Int, channelName: String, value : String, baseURL : String, authToken : String) -> Promise { // let timestamp: Int = Int(Date().timeIntervalSince1970) var channelJson : JSON = JSON() channelJson["name"].string = channelName // channelJson["timestamp"].int = timestamp channelJson["value"].string = value var listJson = JSON() listJson.arrayObject = [channelJson] let url = "\(baseURL)/devices/\(deviceId)/sets?tries=2" let headers : HTTPHeaders = [ "Authorization": authToken ] return Promise { promise in Alamofire.request(url, method: .put, parameters: [:], encoding: listJson.rawString()!, headers: headers) .response { response in if response.response?.statusCode == 200 { promise.fulfill(true) } else { promise.reject(String(response.response!.statusCode) as! Error) } } } } extension String: ParameterEncoding { public func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest { var request = try urlRequest.asURLRequest() request.httpBody = data(using: .utf8, allowLossyConversion: false) return request } }