// // IHClassControlManager.swift // Inhealth // // Created by weclouds on 2020/8/19. // Copyright © 2020 weclouds. All rights reserved. // import UIKit import SwiftyJSON import PKHUD let KNotifiGetAllDeviceInforFromGateway = "KNotifiGetAllDeviceInforFromGateway" class IHClassControlManager: NSObject { lazy var mainView : IHClassControlView = { let mainView = IHClassControlView.init(frame: CGRect.init(x: 0, y: 0, width: KSCREENWIDTH, height: self.vc!.viewH!)) mainView.backgroundColor = .white mainView.delegate = self return mainView }() private weak var vc : IHClassControlCtr? lazy var clientSocket: GCDAsyncUdpSocket? = { var mainQueue = DispatchQueue.main var clientSocket = GCDAsyncUdpSocket(delegate: self, delegateQueue: DispatchQueue.global()) return clientSocket }() var modelList = [gatewayInfor]() private var isReload = false func bindController(_ vc : UIViewController) { self.vc = vc as? IHClassControlCtr self.vc?.view.addSubview(mainView) //checksum(command: "12a15303011700") getAllDevice() } deinit { log.debug("IHClassControlManager销毁") clientSocket = nil } //viewWillAppear时执行 func getClassDevice(isReload : Bool) { self.isReload = isReload //发送命令 getAllDevice() } } extension IHClassControlManager{ func scanUnAddDevice() { // a.Byte 0-1: sequence number, when replying back, module will have to repeat the same SEQ number. // b.Byte 2: 0x01 // c.Byte 3: 0x00 // Byte 4: CheckSum. //扫描没有添加的设置 -- 固定的指令 //[0x12, 0xa1, 0x01, 0x00,0xb4] //返回 12 A1 01 05 01 (00 01 01 69) 25 - 面板灯 //"12a1 01 05 01 0001010c c8" -- 黑板灯 //添加设备 - 变化 //[0x12, 0xa1, 0x02, 0x05,0x01,0x00,0x01,0x01,0x69,0x26] //"12a1 02 0301170100000000d1" //删除设备 //[0x12, 0xa1, 0x03, 0x02,0x01,0x17,0xb7] //亮度(里面的值是变化的) --485灯 //[0x12, 0xa1, 0x52, 0x03,0x01,0x17,0x00,0x20] //色温(里面的值是变化的) -- 485灯 //[0x12, 0xa1, 0x53, 0x03,0x01,0x17,0x00,0x21] //情景开关 Switch Scenes Mode //[0x12, 0xa1, 0x57, 0x03,0x01,0x17,0x02,0x27] //亮度与色温 -- CW灯 -- 根据从网关里获取灯的类型 //[0x12, 0xa1, 0x5A,0x04, 0x01,0x17,0x1e,0x1e,0x65] //设置情景模式 //获取网关里的所有设备 - 固定 //[0x12, 0xa1, 0x04, 0x00,0xb7] } // //计算checksum // private func checksum(command : String) -> String{ // let str = command as NSString // let count = str.length / 2 // var sum = 0x0 // for i in 0.. 1{ // return hexStr.substring(with: NSRange.init(location: hexStr.length - 2, length: 2)) // }else{ // return "0\(hexStr)" // } // // } // // //16进制的字符串转换数字 // func hexStringToInt(from:String) -> Int { // let str = from.uppercased() // var sum = 0 // for i in str.utf8 { // sum = sum * 16 + Int(i) - 48 // 0-9 从48开始 // if i >= 65 { // A-Z 从65开始,但有初始值10,所以应该是减去55 // sum -= 7 // } // } // return sum // } //发送命令 private func getAllDevice(){ do{ // //不连接,直接发命令 try clientSocket?.enableBroadcast(true) // //let wifiIp = getLocalIPAddressForCurrentWiFi() // //第二次就不用了,直接使用这个 // try clientSocket?.bind(toPort: 37030) // //第一次要绑定interface,后面就不用了 // //try clientSocket?.bind(toPort: 37030, interface: wifiIp) try clientSocket?.beginReceiving() // 0117-设备地址 //[0x12, 0xa1, 0x52, 0x06,0x01,0x17,0x10,0x33] //"12a1 01 05 01 0001010c c8" //12a10203 011d 0400000000da // 用这个 let bytes: [UInt8] = [0x12, 0xa1, 0x5B, 0x00,0x0E] let command: Data = Data.init(bytes: bytes, count: bytes.count) //warn如果返回多个网关,这里只显示第一个 if self.vc?.gatewayList?.count ?? 0 > 0{ clientSocket?.send(command, toHost: self.vc!.gatewayList!.first!.ip!, port:UInt16(self.vc!.gatewayList!.first!.port!)! , withTimeout: -1, tag: 0) } }catch{ log.debug("绑定失败\(error)") } } // 获取当前wifi的IP地址 func getLocalIPAddressForCurrentWiFi() -> String? { var address: String? // get list of all interfaces on the local machine var ifaddr: UnsafeMutablePointer? = nil guard getifaddrs(&ifaddr) == 0 else { return nil } guard let firstAddr = ifaddr else { return nil } for ifptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) { let interface = ifptr.pointee // Check for IPV4 or IPV6 interface let addrFamily = interface.ifa_addr.pointee.sa_family if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) { // Check interface name let name = String(cString: interface.ifa_name) if name == "en0" { // Convert interface address to a human readable string var addr = interface.ifa_addr.pointee var hostName = [CChar](repeating: 0, count: Int(NI_MAXHOST)) getnameinfo(&addr, socklen_t(interface.ifa_addr.pointee.sa_len), &hostName, socklen_t(hostName.count), nil, socklen_t(0), NI_NUMERICHOST) address = String(cString: hostName) } } } freeifaddrs(ifaddr) return address } } extension IHClassControlManager: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?) { // //十进制数组 // let bytes: [UInt8]? = [UInt8](data) // var str : String = "" // for byte in bytes! { // //十进制转换成16进制字符串 // var s = String(byte,radix:16) // if s.count == 1{ // s = "0" + s // } // str = str + s // } //扫描未添加的设备 //foundDevice(respondStr: str) let str = dataConvertToHexString(data: data) //扫描网关返回的设备(带地址) getDeviceFromGateway(respondStr: str) //从网关中删除设备 //deleteDevieFromGateway(respondStr: str) //添加设备到网关 //addDeviceToGateway(respondStr: str) //调节CW灯的亮度与色温 // adjustLampBrightnessAndColor(respondStr: str) log.debug("didReceive获取所有的设备:\(str)") } //调节CW灯的亮度与色温 func adjustLampBrightnessAndColor(respondStr: String){ //"12a1 5a 03 0117 0028" let str = respondStr as NSString let componeStr = str.substring(with: NSRange.init(location: 12, length: 2)) if componeStr == "00" { //成功 log.debug("调节成功") }else{ //失败 log.debug("调节失败") } } //添加设备到网关 func addDeviceToGateway(respondStr: String){ //没有判断的条件 } //从网关中删除设备 func deleteDevieFromGateway(respondStr: String) { //"12a1 03 02 0117 d0" //如果 Address == 0117 相等的就成功 } //扫描网关返回的设备 func getDeviceFromGateway(respondStr : String) { let str = respondStr as NSString //"12a1 04 04 01 0117 01 d5" let componeStr = str.substring(with: NSRange.init(location: 8, length: 2)) let check = str.substring(with: NSRange.init(location: 4, length: 2)) //Found Device Count. var deviceArr = [(address : String ,type : String,location : String)]() if componeStr == "00" && check == "5b"{ log.debug("没有发现添加的设备") }else{ //如果 componeStr 是大于或等于01,里面可能是多个了 for i in 0.. 0 { IHClassControlService.share.setPanenlAndAllLight(panelAddress: panelAddress, lampLights: lampLights, classLights: classLights, scenes: scenes,keyId : keyId, ip: self.vc!.gatewayList![0].ip!, port: self.vc!.gatewayList![0].port!) //IHClassControlService.share.setSwitchScenesMode(address: address, scenes: scenes, ip: self.vc!.gatewayList![0].ip!, port: self.vc!.gatewayList![0].port!) } } //重新获取数据 func getDeviceData() { getAllDevice() } //设置设置的位置 func setDeviceLocation(device: (address: String, type: String, location: String)) { IHClassControlService.share.setAllDeviceLocation(device: device, ip: self.vc!.gatewayList![0].ip!, port: self.vc!.gatewayList![0].port!) } //面板情景id绑定按键id // func panelBindScenesAndKeyId(panel: (address: String, type: String, location: String), curtain: (address: String, type: String, location: String)?, scenes: String, keyId: String) { // IHClassControlService.share.setPanelBindSencesAndKeyId(panel: panel, curtain: curtain, scenes: scenes, keyId: keyId, ip: self.vc!.gatewayList![0].ip!, port: self.vc!.gatewayList![0].port!) // } //窗帘的开关 func controlCurtainTurnOn(panel : (address : String ,type : String,location : String),curtainDevice: (address: String, type: String, location: String), scenes: String) { //先绑定后再提示开关 IHClassControlService.share.setPanelBindSencesAndKeyId(panel: panel, curtain: curtainDevice, scenes: scenes, keyId: "5", ip: self.vc!.gatewayList![0].ip!, port: self.vc!.gatewayList![0].port!) } //操作模式 // func switchScenesMode(address: String, scenes: String) { // if self.vc!.gatewayList?.count ?? 0 > 0 { // IHClassControlService.share.setSwitchScenesMode(address: address, scenes: scenes, ip: self.vc!.gatewayList![0].ip!, port: self.vc!.gatewayList![0].port!) // } // // } func pushToLightCommandVC(ShoolDevice: (address: String, type: String, location: String)) { self.vc?.bottomView!.isHidden = true let lightVC = IHLightCommandCtr() //warn lightVC.gateway = self.vc?.gatewayList?[0] lightVC.schollDeviceInfor = ShoolDevice self.vc?.navigationController?.pushViewController(lightVC) } }