IHClassControlService.swift 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. //
  2. // IHClassControlService.swift
  3. // Inhealth
  4. //
  5. // Created by weclouds on 2020/8/27.
  6. // Copyright © 2020 weclouds. All rights reserved.
  7. //
  8. import UIKit
  9. import PKHUD
  10. let KNotifiSwitchScenseMode = "KNotifiSwitchScenseMode"
  11. let KNotifiSetLightLocation = "KNotifiSetLightLocation"
  12. class IHClassControlService: NSObject {
  13. static let share : IHClassControlService = IHClassControlService()
  14. private var scenes : String?
  15. private var panel : (address: String, type: String, location: String)?
  16. private var curtain : (address: String, type: String, location: String)?
  17. private var ip : String?
  18. private var port : String?
  19. private var isBind = false
  20. private var lampLights: [(address: String, type: String, location: String)]?
  21. private var classLights: [(address: String, type: String, location: String)]?
  22. private var totalCount = 0
  23. private var isFinish = false
  24. private var isBindLight = false
  25. private var panelAddress : String?
  26. private var isTurnOn = false
  27. private var acceptCout = 0
  28. private lazy var clientSocket: GCDAsyncUdpSocket? = {
  29. var mainQueue = DispatchQueue.main
  30. var clientSocket = GCDAsyncUdpSocket(delegate: self, delegateQueue: mainQueue)
  31. return clientSocket
  32. }()
  33. var isLocation : Bool = false
  34. //设置设备的位置
  35. func setAllDeviceLocation(device : (address: String, type: String, location: String),ip : String, port : String ) {
  36. isLocation = true
  37. let addressArr = hexStringConvertToDecimal(hexString: device.address)
  38. // var bytes: [UInt8] = [18, 161, 89, 4,addressArr[0],addressArr[1]]
  39. var bytes: [UInt8] = [18, 161]
  40. if device.type == "40" {
  41. //窗帘
  42. bytes.append(80)
  43. }else{
  44. //其它灯
  45. bytes.append(92)
  46. }
  47. bytes.append(3)
  48. bytes.append(addressArr[0])
  49. bytes.append(addressArr[1])
  50. let loction = hexStringToInt(from: device.location)
  51. bytes.append(UInt8(loction))
  52. setCommand(bytesArr: bytes, ip: ip, port: port)
  53. }
  54. //面板情景id绑定按键id
  55. //绑定后再发送相应的操作情景
  56. func setPanelBindSencesAndKeyId(panel: (address: String, type: String, location: String),curtain : (address: String, type: String, location: String)?, scenes: String, keyId: String,ip : String, port : String) {
  57. if curtain != nil{
  58. self.curtain = curtain
  59. }
  60. isBind = true
  61. self.panel = panel
  62. self.scenes = scenes
  63. self.ip = ip
  64. self.port = port
  65. let addressArr = hexStringConvertToDecimal(hexString: panel.address)
  66. var bytes: [UInt8] = [18, 161, 89, 4,addressArr[0],addressArr[1]]
  67. let Scenes = hexStringToInt(from: scenes)
  68. bytes.append(UInt8(Scenes))
  69. let key = hexStringToInt(from: keyId)
  70. bytes.append(UInt8(key))
  71. setCommand(bytesArr: bytes, ip: ip, port: port)
  72. }
  73. //窗帘开关
  74. func setCurtainTurnOn(device : (address: String, type: String, location: String), scenes: String,ip : String, port : String) {
  75. let addressArr = hexStringConvertToDecimal(hexString: device.address)
  76. var bytes: [UInt8] = [18, 161, 81, 4,addressArr[0],addressArr[1]]
  77. let Scenes = hexStringToInt(from: scenes)
  78. bytes.append(UInt8(Scenes))
  79. let location = hexStringToInt(from: device.location)
  80. bytes.append(UInt8(location))
  81. setCommand(bytesArr: bytes, ip: ip, port: port)
  82. }
  83. //1. 先绑定面板
  84. //2. 再绑定所有的灯
  85. //3. 全开/全关
  86. 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) {
  87. //绑定面板
  88. self.lampLights = lampLights
  89. self.classLights = classLights
  90. self.scenes = scenes
  91. //self.totalCount = lampLights.count + classLights.count
  92. self.ip = ip
  93. self.port = port
  94. self.panelAddress = panelAddress
  95. let addressArr = hexStringConvertToDecimal(hexString: panelAddress)
  96. var bytes: [UInt8] = [18, 161, 89, 4,addressArr[0],addressArr[1]]
  97. let Scenes = hexStringToInt(from: scenes)
  98. bytes.append(UInt8(Scenes))
  99. let key = hexStringToInt(from: keyId)
  100. bytes.append(UInt8(key))
  101. setCommand(bytesArr: bytes, ip: ip, port: port)
  102. }
  103. //绑定所有的灯
  104. func bindLightToScence(device : (address: String, type: String, location: String)) {
  105. isBindLight = true
  106. if device.type == "31" {
  107. // 485的灯
  108. let addressArr = hexStringConvertToDecimal(hexString: device.address)
  109. var bytes: [UInt8] = [18, 161, 86, 7,addressArr[0],addressArr[1]]
  110. let Scenes = hexStringToInt(from: self.scenes!)
  111. bytes.append(UInt8(Scenes))
  112. if self.scenes! == "1" {
  113. //全开
  114. bytes.append(10)
  115. bytes.append(50)
  116. bytes.append(1)
  117. bytes.append(1)
  118. }else{
  119. //全关
  120. bytes.append(0)
  121. bytes.append(0)
  122. bytes.append(0)
  123. bytes.append(0)
  124. }
  125. setCommand(bytesArr: bytes, ip: self.ip!, port: self.port!)
  126. }else{
  127. //cw灯
  128. let addressArr = hexStringConvertToDecimal(hexString: device.address)
  129. var bytes: [UInt8] = [18, 161, 84, 7,addressArr[0],addressArr[1]]
  130. let Scenes = hexStringToInt(from: self.scenes!)
  131. bytes.append(UInt8(Scenes))
  132. if self.scenes! == "1" {
  133. //全开
  134. bytes.append(255)
  135. bytes.append(255)
  136. bytes.append(1)
  137. bytes.append(1)
  138. }else{
  139. //全关
  140. bytes.append(0)
  141. bytes.append(0)
  142. bytes.append(0)
  143. bytes.append(0)
  144. }
  145. setCommand(bytesArr: bytes, ip: self.ip!, port: self.port!)
  146. }
  147. }
  148. // 开关情景模式的
  149. func setSwitchScenesMode(address : String,scenes : String, ip : String, port : String){
  150. //[0x12, 0xa1, 0x01, 0x00,0xb4] 0001010c
  151. let addressArr = hexStringConvertToDecimal(hexString: address)
  152. var bytes: [UInt8] = [18, 161, 87, 3,addressArr[0],addressArr[1]]
  153. let Scenes = hexStringToInt(from: scenes)
  154. bytes.append(UInt8(Scenes))
  155. setCommand(bytesArr: bytes, ip: ip, port: port)
  156. // do{
  157. //
  158. // //不连接,直接发命令
  159. // try clientSocket?.enableBroadcast(true)
  160. // try clientSocket?.beginReceiving() // 0117-设备地址
  161. // //[0x12, 0xa1, 0x52, 0x06,0x01,0x17,0x10,0x33]
  162. // //"12a1 01 05 01 0001010c c8"
  163. // //12a10203 011d 0400000000da
  164. //
  165. // let addressArr = hexStringConvertToDecimal(hexString: address)
  166. // var bytes: [UInt8] = [18, 161, 87, 3,addressArr[0],addressArr[1]]
  167. // let Scenes = hexStringToInt(from: scenes)
  168. // bytes.append(UInt8(Scenes))
  169. // let totalStr = deciConvertHexStr(deciArr: bytes)
  170. // let sum = checksum(command: totalStr)
  171. // let dec = hexStringToInt(from: sum)
  172. // bytes.append(UInt8(dec))
  173. //
  174. // let command: Data = Data.init(bytes: bytes, count: bytes.count)
  175. // // self.vc?.gateway?.ip! self.vc?.gateway?.port
  176. // clientSocket?.send(command, toHost: ip, port:UInt16(port)! , withTimeout: -1, tag: 0)
  177. //
  178. // }catch{
  179. // log.debug("绑定失败\(error)")
  180. // }
  181. }
  182. private func setCommand(bytesArr : [UInt8], ip : String,port : String){
  183. do{
  184. //不连接,直接发命令
  185. try clientSocket?.enableBroadcast(true)
  186. try clientSocket?.beginReceiving() // 0117-设备地址
  187. //[0x12, 0xa1, 0x52, 0x06,0x01,0x17,0x10,0x33]
  188. //"12a1 01 05 01 0001010c c8"
  189. //12a10203 011d 0400000000da
  190. var bytes = [UInt8]()
  191. bytes = bytesArr
  192. let totalStr = deciConvertHexStr(deciArr: bytes)
  193. let sum = checksum(command: totalStr)
  194. let dec = hexStringToInt(from: sum)
  195. bytes.append(UInt8(dec))
  196. let command: Data = Data.init(bytes: bytes, count: bytes.count)
  197. // self.vc?.gateway?.ip! self.vc?.gateway?.port
  198. clientSocket?.send(command, toHost: ip, port:UInt16(port)! , withTimeout: -1, tag: 0)
  199. }catch{
  200. log.debug("绑定失败\(error)")
  201. }
  202. }
  203. }
  204. extension IHClassControlService : GCDAsyncUdpSocketDelegate{
  205. func udpSocket(_ sock: GCDAsyncUdpSocket, didNotConnect error: Error?) {
  206. log.debug("didNotConnect")
  207. }
  208. func udpSocket(_ sock: GCDAsyncUdpSocket, didConnectToAddress address: Data) {
  209. log.debug("didConnectToAddress:\(String(data: address, encoding: String.Encoding.utf8))")
  210. }
  211. func udpSocket(_ sock: GCDAsyncUdpSocket, didReceive data: Data, fromAddress address: Data, withFilterContext filterContext: Any?) {
  212. // HUD.hide()
  213. //12 A1 04 01 00 B8
  214. let hexStr = dataConvertToHexString(data: data)
  215. if isLocation == true {
  216. //设置灯的位置
  217. lightLocationHavedSet(respondStr: hexStr)
  218. }
  219. if lampLights == nil && classLights == nil && isLocation == false && isBindLight == false{
  220. adjustScenceMode(respondStr: hexStr)
  221. }
  222. if lampLights != nil && classLights != nil {
  223. //绑定面板 -- 全开/全关时
  224. bindPanel(respondStr: hexStr)
  225. }
  226. if isBindLight == true{
  227. //绑定所有的灯 -- 全开/全关时
  228. bindAllLight(respondStr: hexStr)
  229. }
  230. if isTurnOn == true {
  231. //全开/全关
  232. controlAllLights(respondStr: hexStr)
  233. }
  234. log.debug("didReceive")
  235. }
  236. func udpSocket(_ sock: GCDAsyncUdpSocket, didSendDataWithTag tag: Int) {
  237. log.debug("didSendDataWithTag")
  238. }
  239. func udpSocketDidClose(_ sock: GCDAsyncUdpSocket, withError error: Error?) {
  240. log.debug("withError")
  241. }
  242. func udpSocket(_ sock: GCDAsyncUdpSocket, didNotSendDataWithTag tag: Int, dueToError error: Error?) {
  243. log.debug("didNotSendDataWithTag")
  244. }
  245. }
  246. extension IHClassControlService{
  247. //3. 全开/全关
  248. fileprivate func controlAllLights(respondStr: String){
  249. let str = respondStr as NSString
  250. let componeStr = str.substring(with: NSRange.init(location: 12, length: 2))
  251. if componeStr == "00" {
  252. log.debug("全开/全关 - 成功")
  253. }else{
  254. log.debug("全开/全关 - 失败")
  255. }
  256. }
  257. //2. 绑定完面板后,再绑定所有的灯,最后发命令
  258. fileprivate func bindAllLight(respondStr: String){
  259. let str = respondStr as NSString
  260. let componeStr = str.substring(with: NSRange.init(location: 12, length: 2))
  261. acceptCout = acceptCout + 1
  262. if componeStr == "00" {
  263. log.debug("绑定所有的灯 - 成功")
  264. if isFinish == true {
  265. //发送 - 全开/全关
  266. isFinish = false
  267. isTurnOn = true
  268. if acceptCout == totalCount {
  269. setSwitchScenesMode(address: self.panelAddress!, scenes: self.scenes!, ip: self.ip!, port: self.port!)
  270. }
  271. }
  272. }else{
  273. log.debug("绑定所有的灯 - 失败")
  274. }
  275. }
  276. //1.绑定完面板后,再绑定所有的灯,最后发命令
  277. fileprivate func bindPanel(respondStr: String){
  278. let str = respondStr as NSString
  279. let componeStr = str.substring(with: NSRange.init(location: 12, length: 2))
  280. var i = 0
  281. let tempLampLights = lampLights!
  282. let tempClassLights = classLights!
  283. lampLights = nil
  284. classLights = nil
  285. if componeStr == "00" {
  286. log.debug("面板的绑定情景--成功")
  287. //绑定所有的灯
  288. for lamp in tempLampLights {
  289. //黑板灯
  290. i = i + 1
  291. DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
  292. self.bindLightToScence(device: lamp)
  293. }
  294. }
  295. for light in tempClassLights {
  296. //面板灯
  297. i = i + 1
  298. DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
  299. self.bindLightToScence(device: light)
  300. }
  301. }
  302. if i == tempLampLights.count + tempClassLights.count {
  303. isFinish = true
  304. totalCount = i
  305. }
  306. }else{
  307. log.debug("灯的绑定情景--失败")
  308. }
  309. }
  310. //设置的位置
  311. fileprivate func lightLocationHavedSet(respondStr: String){
  312. let str = respondStr as NSString
  313. let componeStr = str.substring(with: NSRange.init(location: 12, length: 2))
  314. if componeStr == "00" {
  315. //成功
  316. log.debug("灯的位置成功")
  317. }else{
  318. //失败
  319. log.debug("灯的位置失败")
  320. }
  321. NotificationCenter.default.post(name: NSNotification.Name(KNotifiSetLightLocation), object: nil)
  322. }
  323. //调节CW灯的亮度与色温
  324. fileprivate func adjustScenceMode(respondStr: String){
  325. //"12a1 5a 03 0117 0028"
  326. let str = respondStr as NSString
  327. let componeStr = str.substring(with: NSRange.init(location: 12, length: 2))
  328. var isfail = false
  329. if componeStr == "00" {
  330. //成功
  331. log.debug("调节成功")
  332. isfail = true
  333. if isBind == false{
  334. HUD.flash(.label("成功"), delay: 0.7)
  335. }
  336. if isBind == true {
  337. isBind = false
  338. //设置情景模式 - 除了窗帘
  339. if self.curtain == nil{
  340. setSwitchScenesMode(address: self.panel!.address, scenes: self.scenes!, ip: self.ip!, port: self.port!)
  341. }else{
  342. setSwitchScenesMode(address: self.curtain!.address, scenes: self.scenes!, ip: self.ip!, port: self.port!)
  343. }
  344. }else{
  345. NotificationCenter.default.post(name: NSNotification.Name(KNotifiSwitchScenseMode), object: nil, userInfo: ["isfail":isfail])
  346. }
  347. }else{
  348. //失败
  349. log.debug("调节失败")
  350. isfail = true
  351. HUD.flash(.label("失败"), delay: 0.7)
  352. NotificationCenter.default.post(name: NSNotification.Name(KNotifiSwitchScenseMode), object: nil, userInfo: ["isfail":isfail])
  353. }
  354. }
  355. }