// // IHConfigGatewayDetailService.swift // Inhealth // // Created by weclouds on 2020/8/26. // Copyright © 2020 weclouds. All rights reserved. // import UIKit import PKHUD let KNotifiAddDeviceToGateway = "KNotifiAddDeviceToGateway" let KNotifiDeleteDeviceFromGateway = "KNotifiDeleteDeviceFromGateway" let KNotifiTurnOnLightFalse = "KNotifiTurnOnLightFalse" class IHConfigGatewayDetailService: NSObject { static let share : IHConfigGatewayDetailService = IHConfigGatewayDetailService() private lazy var clientSocket: GCDAsyncUdpSocket? = { var mainQueue = DispatchQueue.main var clientSocket = GCDAsyncUdpSocket(delegate: self, delegateQueue: DispatchQueue.global()) return clientSocket }() var isDelete : Bool = false //删除设备 var isAdd : Bool = false //添加设备 var deleteAddress : String? var isTurnOn : Bool = false //开关灯 var isCwLight : Bool = false //是什么类型的灯 var operationLightState : Bool = false //关/开灯 var light : (address: String, type: String)? var isModel : Bool = false deinit { log.debug("IHConfigGatewayDetailService销毁") } //485灯的传感器工作模式 func setLightWorkModel(device : (address: String, type: String),dodgeEnable: String, bodyEnable: String, ip : String, port : String) { isModel = true light = device let addressArr = hexStringConvertToDecimal(hexString: device.address) var bytes: [UInt8] = [18, 161, 85, 4,addressArr[0],addressArr[1]] bytes.append(UInt8(dodgeEnable)!) bytes.append(UInt8(bodyEnable)!) setCommand( device: device, byteArr: bytes, ip: ip, port: port) } //开关灯(485/cw) func setCWOrOtherLightTurnOn(isTurnOn : Bool, device : (address: String, type: String), ip : String, port : String) { operationLightState = isTurnOn light = device if device.type == "31" { //485 //[0x12, 0xa1, 0x52, 0x03,0x01,0x17,0x00,0x20] isDelete = false isAdd = false self.isTurnOn = true isCwLight = false let addressArr = hexStringConvertToDecimal(hexString: device.address) var bytes: [UInt8] = [18, 161, 82, 3,addressArr[0],addressArr[1]] if isTurnOn == false { //关 bytes.append(0) }else{ bytes.append(80) } setCommand( device: device, byteArr: bytes, ip: ip, port: port) }else{ //cw //[0x12, 0xa1, 0x5A,0x04, 0x01,0x17,0x1e,0x1e,0x65] isDelete = false isAdd = false self.isTurnOn = true isCwLight = true let addressArr = hexStringConvertToDecimal(hexString: device.address) var bytes: [UInt8] = [18, 161, 90, 4,addressArr[0],addressArr[1]] if isTurnOn == false { //关 bytes.append(0) bytes.append(0) }else{ bytes.append(255) bytes.append(255) } setCommand( device: device, byteArr: bytes, ip: ip, port: port) } } private func setCommand( device : (address: String, type: String),byteArr : [UInt8], ip : String, port : String){ do{ //不连接,直接发命令 try clientSocket?.enableBroadcast(true) try clientSocket?.beginReceiving() // 0117-设备地址 // let addressArr = hexStringConvertToDecimal(hexString: device.address) // var bytes: [UInt8] = [18, 161, 82, 3,addressArr[0],addressArr[1]] // if isTurnOn == false { // //关 // bytes.append(0) // }else{ // bytes.append(80) // } var bytes = [UInt8]() bytes = byteArr 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)") } } //删除设备 func deleteDeviceFromGateway(deviceAddress : String, ip : String, port : String) { //[0x12, 0xa1, 0x01, 0x00,0xb4] 0001010c do{ isDelete = true isAdd = false deleteAddress = deviceAddress //不连接,直接发命令 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: deviceAddress) var bytes: [UInt8] = [18, 161, 3, 2,addressArr[0],addressArr[1]] 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)") } } //添加设备到网关 func addDeviceToGateway(deviceUUid : String,ip : String, port : String){ //[0x12, 0xa1, 0x01, 0x00,0xb4] 0001010c do{ isDelete = false isAdd = true //不连接,直接发命令 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 //[0x12, 0xa1, 0x02, 0x05,0x01,0x00,0x01,0x01,0x69,0x26] let uuidArr = hexStringConvertToDecimal(hexString: deviceUUid) var bytes: [UInt8] = [18, 161, 2, 5,1,uuidArr[0],uuidArr[1],uuidArr[2],uuidArr[3]] 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 IHConfigGatewayDetailService : 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?) { //12 A1 04 01 00 B8 let hexStr = dataConvertToHexString(data: data) if isAdd == true { //添加设备到网关 addDeviceToGateway(respondStr: hexStr) } if isDelete == true { //删除设备 deleteDevieFromGateway(respondStr : hexStr) } if self.isTurnOn == true{ //开关灯 turnOffLight(respondStr : hexStr) } if self.isModel == true { //485灯的传感器工作模式 lightWorkModel(respondStr : hexStr) } log.debug("didReceive:\(hexStr)") } 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 IHConfigGatewayDetailService{ //485灯传感器工作模式 fileprivate func lightWorkModel(respondStr : String){ isModel = false let respone = respondStr as NSString let subStr = respone.substring(with: NSRange.init(location: 12, length: 2)) if subStr == "00"{ //保存此灯 deviceWorkModel let defaults = UserDefaults.standard let deviceArr = defaults.object(forKey: "deviceWorkModel") as? [[String : String]] if deviceArr == nil { defaults.set([["address" : light!.address,"type" : light!.type]], forKey: "deviceWorkModel") }else{ var newDeviceArr = [[String : String]]() newDeviceArr = deviceArr! newDeviceArr.append(["address" : light!.address,"type" : light!.type]) } defaults.synchronize() } } //开关灯 fileprivate func turnOffLight(respondStr : String){ log.debug() //"12a15203011f0028" isTurnOn = false isCwLight = false let respone = respondStr as NSString let subStr = respone.substring(with: NSRange.init(location: 12, length: 2)) var isfail = false if subStr == "00"{ isfail = true DispatchQueue.main.async { HUD.flash(.label("成功"), delay: 0.6) } }else{ isfail = false DispatchQueue.main.async { HUD.flash(.label("失败"), delay: 0.6) } } NotificationCenter.default.post(name: NSNotification.Name(KNotifiTurnOnLightFalse), object: nil, userInfo: ["turnOn" : (address : self.light?.address,type : self.light?.type,turnOn : isfail == true ? operationLightState : !operationLightState)]) // NotificationCenter.default.post(name: NSNotification.Name(KNotifiTurnOnLightFalse), object: nil) } //添加设备到网关 fileprivate func addDeviceToGateway(respondStr: String){ // a.Byte 0-1: sequence number, when replying back, module will have to repeat the same SEQ number. // b.Byte 2: 0x02. // c.Byte 3: 2 // d.Byte 4-5: Device Address. // e.Byte 6: Device Type // f.Byte 7-8: System Version. // g.Byte 9-10: Hardware Version. // h.Byte 11: CheckSum if respondStr.count == 24 { // DispatchQueue.main.async { // HUD.flash(.label("成功"), delay: 0.6) // } DispatchQueue.main.async { NotificationCenter.default.post(name: NSNotification.Name(KNotifiAddDeviceToGateway), object: nil) } }else{ DispatchQueue.main.async { HUD.flash(.label("绑定失败"), delay: 0.6) } } } //删除设备 fileprivate func deleteDevieFromGateway(respondStr : String){ // deleteAddress let respone = respondStr as NSString let subStr = respone.substring(with: NSRange.init(location: 8, length: 4)) if let deleteAddress = deleteAddress{ if subStr == deleteAddress { NotificationCenter.default.post(name: NSNotification.Name(KNotifiDeleteDeviceFromGateway), object: nil) } } } }