// // IHClassControlService.swift // Inhealth // // Created by weclouds on 2020/8/27. // Copyright © 2020 weclouds. All rights reserved. // import UIKit import PKHUD let KNotifiSwitchScenseMode = "KNotifiSwitchScenseMode" let KNotifiSetLightLocation = "KNotifiSetLightLocation" class IHClassControlService: NSObject { static let share : IHClassControlService = IHClassControlService() private var scenes : String? private var panel : (address: String, type: String, location: String)? private var curtain : (address: String, type: String, location: String)? private var ip : String? private var port : String? private var isBind = false private var lampLights: [(address: String, type: String, location: String)]? private var classLights: [(address: String, type: String, location: String)]? private var totalCount = 0 private var isFinish = false private var isBindLight = false private var panelAddress : String? private var isTurnOn = false private var acceptCout = 0 private lazy var clientSocket: GCDAsyncUdpSocket? = { var mainQueue = DispatchQueue.main var clientSocket = GCDAsyncUdpSocket(delegate: self, delegateQueue: mainQueue) return clientSocket }() var isLocation : Bool = false //设置设备的位置 func setAllDeviceLocation(device : (address: String, type: String, location: String),ip : String, port : String ) { isLocation = true let addressArr = hexStringConvertToDecimal(hexString: device.address) // var bytes: [UInt8] = [18, 161, 89, 4,addressArr[0],addressArr[1]] var bytes: [UInt8] = [18, 161] if device.type == "40" { //窗帘 bytes.append(80) }else{ //其它灯 bytes.append(92) } bytes.append(3) bytes.append(addressArr[0]) bytes.append(addressArr[1]) let loction = hexStringToInt(from: device.location) bytes.append(UInt8(loction)) setCommand(bytesArr: bytes, ip: ip, port: port) } //面板情景id绑定按键id //绑定后再发送相应的操作情景 func setPanelBindSencesAndKeyId(panel: (address: String, type: String, location: String),curtain : (address: String, type: String, location: String)?, scenes: String, keyId: String,ip : String, port : String) { if curtain != nil{ self.curtain = curtain } isBind = true self.panel = panel self.scenes = scenes self.ip = ip self.port = port let addressArr = hexStringConvertToDecimal(hexString: panel.address) var bytes: [UInt8] = [18, 161, 89, 4,addressArr[0],addressArr[1]] let Scenes = hexStringToInt(from: scenes) bytes.append(UInt8(Scenes)) let key = hexStringToInt(from: keyId) bytes.append(UInt8(key)) setCommand(bytesArr: bytes, ip: ip, port: port) } //窗帘开关 func setCurtainTurnOn(device : (address: String, type: String, location: String), scenes: String,ip : String, port : String) { let addressArr = hexStringConvertToDecimal(hexString: device.address) var bytes: [UInt8] = [18, 161, 81, 4,addressArr[0],addressArr[1]] let Scenes = hexStringToInt(from: scenes) bytes.append(UInt8(Scenes)) let location = hexStringToInt(from: device.location) bytes.append(UInt8(location)) setCommand(bytesArr: bytes, ip: ip, port: port) } //1. 先绑定面板 //2. 再绑定所有的灯 //3. 全开/全关 func setPanenlAndAllLight(panelAddress: String, lampLights: [(address: String, type: String, location: String)], classLights: [(address: String, type: String, location: String)], scenes: String,keyId : String, ip : String, port : String) { //绑定面板 self.lampLights = lampLights self.classLights = classLights self.scenes = scenes //self.totalCount = lampLights.count + classLights.count self.ip = ip self.port = port self.panelAddress = panelAddress let addressArr = hexStringConvertToDecimal(hexString: panelAddress) var bytes: [UInt8] = [18, 161, 89, 4,addressArr[0],addressArr[1]] let Scenes = hexStringToInt(from: scenes) bytes.append(UInt8(Scenes)) let key = hexStringToInt(from: keyId) bytes.append(UInt8(key)) setCommand(bytesArr: bytes, ip: ip, port: port) } //绑定所有的灯 func bindLightToScence(device : (address: String, type: String, location: String)) { isBindLight = true if device.type == "31" { // 485的灯 let addressArr = hexStringConvertToDecimal(hexString: device.address) var bytes: [UInt8] = [18, 161, 86, 7,addressArr[0],addressArr[1]] let Scenes = hexStringToInt(from: self.scenes!) bytes.append(UInt8(Scenes)) if self.scenes! == "1" { //全开 bytes.append(10) bytes.append(50) bytes.append(1) bytes.append(1) }else{ //全关 bytes.append(0) bytes.append(0) bytes.append(0) bytes.append(0) } setCommand(bytesArr: bytes, ip: self.ip!, port: self.port!) }else{ //cw灯 let addressArr = hexStringConvertToDecimal(hexString: device.address) var bytes: [UInt8] = [18, 161, 84, 7,addressArr[0],addressArr[1]] let Scenes = hexStringToInt(from: self.scenes!) bytes.append(UInt8(Scenes)) if self.scenes! == "1" { //全开 bytes.append(255) bytes.append(255) bytes.append(1) bytes.append(1) }else{ //全关 bytes.append(0) bytes.append(0) bytes.append(0) bytes.append(0) } setCommand(bytesArr: bytes, ip: self.ip!, port: self.port!) } } // 开关情景模式的 func setSwitchScenesMode(address : String,scenes : String, ip : String, port : String){ //[0x12, 0xa1, 0x01, 0x00,0xb4] 0001010c let addressArr = hexStringConvertToDecimal(hexString: address) var bytes: [UInt8] = [18, 161, 87, 3,addressArr[0],addressArr[1]] let Scenes = hexStringToInt(from: scenes) bytes.append(UInt8(Scenes)) setCommand(bytesArr: bytes, ip: ip, port: port) // do{ // // //不连接,直接发命令 // try clientSocket?.enableBroadcast(true) // try clientSocket?.beginReceiving() // 0117-设备地址 // //[0x12, 0xa1, 0x52, 0x06,0x01,0x17,0x10,0x33] // //"12a1 01 05 01 0001010c c8" // //12a10203 011d 0400000000da // // let addressArr = hexStringConvertToDecimal(hexString: address) // var bytes: [UInt8] = [18, 161, 87, 3,addressArr[0],addressArr[1]] // let Scenes = hexStringToInt(from: scenes) // bytes.append(UInt8(Scenes)) // let totalStr = deciConvertHexStr(deciArr: bytes) // let sum = checksum(command: totalStr) // let dec = hexStringToInt(from: sum) // bytes.append(UInt8(dec)) // // let command: Data = Data.init(bytes: bytes, count: bytes.count) // // self.vc?.gateway?.ip! self.vc?.gateway?.port // clientSocket?.send(command, toHost: ip, port:UInt16(port)! , withTimeout: -1, tag: 0) // // }catch{ // log.debug("绑定失败\(error)") // } } private func setCommand(bytesArr : [UInt8], ip : String,port : String){ do{ //不连接,直接发命令 try clientSocket?.enableBroadcast(true) try clientSocket?.beginReceiving() // 0117-设备地址 //[0x12, 0xa1, 0x52, 0x06,0x01,0x17,0x10,0x33] //"12a1 01 05 01 0001010c c8" //12a10203 011d 0400000000da var bytes = [UInt8]() bytes = bytesArr let totalStr = deciConvertHexStr(deciArr: bytes) let sum = checksum(command: totalStr) let dec = hexStringToInt(from: sum) bytes.append(UInt8(dec)) let command: Data = Data.init(bytes: bytes, count: bytes.count) // self.vc?.gateway?.ip! self.vc?.gateway?.port clientSocket?.send(command, toHost: ip, port:UInt16(port)! , withTimeout: -1, tag: 0) }catch{ log.debug("绑定失败\(error)") } } } extension IHClassControlService : GCDAsyncUdpSocketDelegate{ func udpSocket(_ sock: GCDAsyncUdpSocket, didNotConnect error: Error?) { log.debug("didNotConnect") } func udpSocket(_ sock: GCDAsyncUdpSocket, didConnectToAddress address: Data) { log.debug("didConnectToAddress:\(String(data: address, encoding: String.Encoding.utf8))") } func udpSocket(_ sock: GCDAsyncUdpSocket, didReceive data: Data, fromAddress address: Data, withFilterContext filterContext: Any?) { // HUD.hide() //12 A1 04 01 00 B8 let hexStr = dataConvertToHexString(data: data) if isLocation == true { //设置灯的位置 lightLocationHavedSet(respondStr: hexStr) } if lampLights == nil && classLights == nil && isLocation == false && isBindLight == false{ adjustScenceMode(respondStr: hexStr) } if lampLights != nil && classLights != nil { //绑定面板 -- 全开/全关时 bindPanel(respondStr: hexStr) } if isBindLight == true{ //绑定所有的灯 -- 全开/全关时 bindAllLight(respondStr: hexStr) } if isTurnOn == true { //全开/全关 controlAllLights(respondStr: hexStr) } log.debug("didReceive") } func udpSocket(_ sock: GCDAsyncUdpSocket, didSendDataWithTag tag: Int) { log.debug("didSendDataWithTag") } func udpSocketDidClose(_ sock: GCDAsyncUdpSocket, withError error: Error?) { log.debug("withError") } func udpSocket(_ sock: GCDAsyncUdpSocket, didNotSendDataWithTag tag: Int, dueToError error: Error?) { log.debug("didNotSendDataWithTag") } } extension IHClassControlService{ //3. 全开/全关 fileprivate func controlAllLights(respondStr: String){ let str = respondStr as NSString let componeStr = str.substring(with: NSRange.init(location: 12, length: 2)) if componeStr == "00" { log.debug("全开/全关 - 成功") }else{ log.debug("全开/全关 - 失败") } } //2. 绑定完面板后,再绑定所有的灯,最后发命令 fileprivate func bindAllLight(respondStr: String){ let str = respondStr as NSString let componeStr = str.substring(with: NSRange.init(location: 12, length: 2)) acceptCout = acceptCout + 1 if componeStr == "00" { log.debug("绑定所有的灯 - 成功") if isFinish == true { //发送 - 全开/全关 isFinish = false isTurnOn = true if acceptCout == totalCount { setSwitchScenesMode(address: self.panelAddress!, scenes: self.scenes!, ip: self.ip!, port: self.port!) } } }else{ log.debug("绑定所有的灯 - 失败") } } //1.绑定完面板后,再绑定所有的灯,最后发命令 fileprivate func bindPanel(respondStr: String){ let str = respondStr as NSString let componeStr = str.substring(with: NSRange.init(location: 12, length: 2)) var i = 0 let tempLampLights = lampLights! let tempClassLights = classLights! lampLights = nil classLights = nil if componeStr == "00" { log.debug("面板的绑定情景--成功") //绑定所有的灯 for lamp in tempLampLights { //黑板灯 i = i + 1 DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { self.bindLightToScence(device: lamp) } } for light in tempClassLights { //面板灯 i = i + 1 DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { self.bindLightToScence(device: light) } } if i == tempLampLights.count + tempClassLights.count { isFinish = true totalCount = i } }else{ log.debug("灯的绑定情景--失败") } } //设置的位置 fileprivate func lightLocationHavedSet(respondStr: String){ let str = respondStr as NSString let componeStr = str.substring(with: NSRange.init(location: 12, length: 2)) if componeStr == "00" { //成功 log.debug("灯的位置成功") }else{ //失败 log.debug("灯的位置失败") } NotificationCenter.default.post(name: NSNotification.Name(KNotifiSetLightLocation), object: nil) } //调节CW灯的亮度与色温 fileprivate func adjustScenceMode(respondStr: String){ //"12a1 5a 03 0117 0028" let str = respondStr as NSString let componeStr = str.substring(with: NSRange.init(location: 12, length: 2)) var isfail = false if componeStr == "00" { //成功 log.debug("调节成功") isfail = true if isBind == false{ HUD.flash(.label("成功"), delay: 0.7) } if isBind == true { isBind = false //设置情景模式 - 除了窗帘 if self.curtain == nil{ setSwitchScenesMode(address: self.panel!.address, scenes: self.scenes!, ip: self.ip!, port: self.port!) }else{ setSwitchScenesMode(address: self.curtain!.address, scenes: self.scenes!, ip: self.ip!, port: self.port!) } }else{ NotificationCenter.default.post(name: NSNotification.Name(KNotifiSwitchScenseMode), object: nil, userInfo: ["isfail":isfail]) } }else{ //失败 log.debug("调节失败") isfail = true HUD.flash(.label("失败"), delay: 0.7) NotificationCenter.default.post(name: NSNotification.Name(KNotifiSwitchScenseMode), object: nil, userInfo: ["isfail":isfail]) } } }