jinze.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. # -*- coding: utf-8 -*-
  2. from apps.web.core.adapter.base import *
  3. from apps.web.device.models import Cell, Device
  4. # 0A:修改从机地址;0B 回读从机状态 0C 按时间充电 0D 按电量充电 0E 停止充电
  5. class JinzeBox(SmartBox):
  6. def __init__(self, device):
  7. super(JinzeBox, self).__init__(device)
  8. def get_port_status_from_dev(self):
  9. return
  10. def test(self, coins):
  11. data = 'A500' +'0010050000000001' + '0001'
  12. devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_NO_RESPONSE,
  13. {'IMEI': self._device['devNo'], "funCode": '0C', 'data': data})
  14. return devInfo
  15. def analyze_event_data(self, data):
  16. port = int(data[2:4])
  17. voltage = int(data[10:12],16) + int(data[12:14],16)/10.0
  18. current = int(data[14:16],16) + int(data[16:18],16)/10.0
  19. duration = int(data[18:20],16)*60 + int(data[20:22],16)
  20. elec = round((int(data[22:24],16) + int(data[24:26],16)/10.0)/4.55,2)
  21. mode = data[26:28]
  22. battery = data[28:30]
  23. statusDesc = ''
  24. if mode == '00':
  25. statusDesc = u'待机'
  26. elif mode == '01':
  27. statusDesc = u'充电'
  28. elif mode == '02':
  29. statusDesc = u'识别'
  30. elif mode == '03':
  31. statusDesc = u'维护'
  32. elif mode == '04':
  33. statusDesc = u'浮充'
  34. elif mode == '05':
  35. statusDesc = u'完成'
  36. elif mode == '06':
  37. statusDesc = u'异常'
  38. elif mode == '90':
  39. statusDesc = u'额度用完结束'
  40. elif mode == '91':
  41. statusDesc = u'电池脱落'
  42. elif mode == '92':
  43. statusDesc = u'远程断电'
  44. elif mode == '93':
  45. statusDesc = u'无法充入'
  46. elif mode == '94':
  47. statusDesc = u'电池异常'
  48. return {'port':port,'voltage':voltage,'current':current,'duration':duration,'inputElec':elec,'mode':mode,'battery':battery,'statusDesc':statusDesc}
  49. #回读数据 A5 00 00 10 02 00 B7
  50. #回应A5 00 01 60 0B 1C 06 00 00 00 00 00 00 00 00 9E D1
  51. def read_port(self,port):
  52. hexPort = fill_2_hexByte(hex(int(port)), 2)
  53. data = 'A5' + hexPort + '00100200'
  54. devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
  55. {'IMEI': self._device['devNo'], "funCode": '0B', 'data': data})
  56. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  57. if devInfo['rst'] == -1:
  58. raise ServiceException({'result': 2, 'description': u'充电站正在玩命找网络,您的金币还在,重试不需要重新付款,建议您试试旁边其他设备,或者稍后再试哦'})
  59. elif devInfo['rst'] == 1:
  60. raise ServiceException({'result': 2, 'description': u'电池没有接上或者充电站从机无响应,建议您检查是否接上了电池,或者是否从机地址错误','flag':1})
  61. data = devInfo['data']
  62. portInfo = self.analyze_event_data(data)
  63. return portInfo
  64. def get_port_list(self):
  65. devObj = Device.objects.get(devNo = self._device['devNo'])
  66. portDict = devObj.otherConf.get('portDict',{})
  67. return portDict.keys()
  68. def add_address(self,new):
  69. hexNew = fill_2_hexByte(hex(int(new)), 2)
  70. try:
  71. self.read_port(new)
  72. raise ServiceException({'result': 2, 'description': u'您编辑的新从机地址已经被占用,请您换一个没有被使用的新从机地址'})
  73. except ServiceException,e:
  74. if not e.result.get('flag',0):
  75. raise e
  76. #A5 0A(旧地址) 00 10 B2 0B CD(新地址) 00
  77. data = 'A500' + '0010B20B' + hexNew + '00'
  78. devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_NO_RESPONSE,
  79. {'IMEI': self._device['devNo'], "funCode": '0A', 'data': data})
  80. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  81. if devInfo['rst'] == -1:
  82. raise ServiceException({'result': 2, 'description': u'充电站正在玩命找网络,您的金币还在,重试不需要重新付款,建议您试试旁边其他设备,或者稍后再试哦'})
  83. elif devInfo['rst'] == 1:
  84. raise ServiceException({'result': 2, 'description': u'充电站正在忙,无响应,您的金币还在,请试试其他线路,或者请稍后再试哦'})
  85. #再次检查修改后的从机地址是否能够回读上来
  86. try:
  87. self.read_port(new)
  88. except ServiceException,e:
  89. if e.result.get('flag',0):
  90. raise ServiceException({'result': 2, 'description': u'修改之后的地址,访问没有响应,可能设置失败了,请您再次检查设备'})
  91. else:
  92. raise e
  93. #登记记录到数据库中
  94. devObj = Device.objects.get(devNo = self._device['devNo'])
  95. portDict = devObj.otherConf.get('portDict',{})
  96. portDict.update({str(new):Const.DEV_WORK_STATUS_IDLE})
  97. devObj.otherConf['portDict'] = portDict
  98. devObj.save()
  99. return devObj
  100. def edit_address(self,old,new):
  101. hexOld = fill_2_hexByte(hex(int(old)), 2)
  102. hexNew = fill_2_hexByte(hex(int(new)), 2)
  103. # 首先回读,检查从机地址是正确。如果回读地址无响应,会报错
  104. self.read_port(old)
  105. # 检查新地址是否被占用
  106. try:
  107. self.read_port(new)
  108. raise ServiceException({'result': 2, 'description': u'您编辑的新从机地址已经被占用,请您换一个没有被使用的新从机地址'})
  109. except ServiceException,e:
  110. if not e.result.get('flag',0):
  111. raise e
  112. #A5 0A(旧地址) 00 10 B2 0B CD(新地址) 00
  113. data = 'A5' + hexOld + '0010B20B' + hexNew + '00'
  114. devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_NO_RESPONSE,
  115. {'IMEI': self._device['devNo'], "funCode": '0A', 'data': data})
  116. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  117. if devInfo['rst'] == -1:
  118. raise ServiceException({'result': 2, 'description': u'充电站正在玩命找网络,您的金币还在,重试不需要重新付款,建议您试试旁边其他设备,或者稍后再试哦'})
  119. elif devInfo['rst'] == 1:
  120. raise ServiceException({'result': 2, 'description': u'充电站正在忙,无响应,您的金币还在,请试试其他线路,或者请稍后再试哦'})
  121. #再次检查修改后的从机地址是否能够回读上来
  122. try:
  123. self.read_port(new)
  124. except ServiceException,e:
  125. if e.result.get('flag',0):
  126. raise ServiceException({'result': 2, 'description': u'修改之后的地址,访问没有响应,可能设置失败了,请您再次检查设备'})
  127. #登记记录到数据库中
  128. devObj = Device.objects.get(devNo = self._device['devNo'])
  129. portDict = devObj.otherConf.get('portDict',{})
  130. portDict.pop(str(old))
  131. portDict.update({str(new):Const.DEV_WORK_STATUS_IDLE})
  132. devObj.otherConf['portDict'] = portDict
  133. devObj.save()
  134. return devInfo
  135. def stop(self,port):
  136. # 首先回读,检查从机地址是正确。如果回读地址无响应,会报错
  137. self.read_port(port)
  138. hexPort = fill_2_hexByte(hex(int(port)),2)
  139. data = 'A5' + hexPort + '0010050000000001'
  140. devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_NO_RESPONSE,
  141. {'IMEI': self._device['devNo'], "funCode": '0E', 'data': data})
  142. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  143. if devInfo['rst'] == -1:
  144. raise ServiceException({'result': 2, 'description': u'充电站正在玩命找网络,您的金币还在,重试不需要重新付款,建议您试试旁边其他设备,或者稍后再试哦'})
  145. elif devInfo['rst'] == 1:
  146. raise ServiceException({'result': 2, 'description': u'充电站正在忙,无响应,您的金币还在,请试试其他线路,或者请稍后再试哦'})
  147. spendTime = devInfo['duration']/60
  148. ctrInfo = Device.get_dev_control_cache(self._device['devNo'])
  149. try:
  150. needTime = ctrInfo['needTime']
  151. devInfo['remainder_time'] = needTime - spendTime
  152. return devInfo
  153. except Exception,e:
  154. devInfo['remainder_time'] = 0
  155. return devInfo
  156. def get_port_info(self,line):
  157. try:
  158. portInfo = self.read_port(line)
  159. except Exception,e:
  160. portInfo = {'status':Const.DEV_WORK_STATUS_IDLE}
  161. return portInfo
  162. def get_port_status(self, force = False):
  163. devObj = Device.objects.get(devNo = self._device['devNo'])
  164. portDict = devObj.otherConf.get('portDict',{})
  165. ctrInfo = Device.get_dev_control_cache(self._device['devNo'])
  166. statusDict = {}
  167. for port,status in portDict.items():
  168. tempDict = ctrInfo.get(str(port),{})
  169. if tempDict.has_key('status'):
  170. statusDict[str(port)] = {'status':tempDict.get('status')}
  171. elif tempDict.has_key('isStart'):
  172. if tempDict['isStart']:
  173. statusDict[str(port)] = {'status':Const.DEV_WORK_STATUS_WORKING}
  174. else:
  175. statusDict[str(port)] = {'status':Const.DEV_WORK_STATUS_IDLE}
  176. elif status == Const.DEV_WORK_STATUS_FORBIDDEN:
  177. statusDict[str(port)] = {'status':Const.DEV_WORK_STATUS_FORBIDDEN}
  178. else:
  179. statusDict[str(port)] = {'status':Const.DEV_WORK_STATUS_IDLE}
  180. allPorts,usedPorts,usePorts = self.get_port_static_info(statusDict)
  181. Device.update_dev_control_cache(self._device['devNo'], {'allPorts':allPorts,'usedPorts':usedPorts,'usePorts':usePorts})
  182. return statusDict
  183. def lock_unlock_port(self,port,lock=True):
  184. devObj = Device.objects.get(devNo = self._device['devNo'])
  185. if lock:
  186. Device.update_dev_control_cache(self._device['devNo'], {str(port):{'status':Const.DEV_WORK_STATUS_FORBIDDEN}})
  187. devObj.otherConf['portDict'].update({str(port):Const.DEV_WORK_STATUS_FORBIDDEN})
  188. else:
  189. Device.update_dev_control_cache(self._device['devNo'], {str(port):{'status':Const.DEV_WORK_STATUS_IDLE}})
  190. devObj.otherConf['portDict'].update({str(port):Const.DEV_WORK_STATUS_IDLE})
  191. devObj.save()
  192. #只支持按时间充电
  193. #A5 00 00 10 05 00 00 00 00 01 BB 启动慢充
  194. def start_device(self, package, openId, attachParas):
  195. if attachParas is None:
  196. raise ServiceException({'result': 2, 'description': u'请您选择合适的充电线路、电池类型信息'})
  197. if not attachParas.has_key('chargeIndex'):
  198. raise ServiceException({'result': 2, 'description': u'请您选择合适的充电线路'})
  199. port = int(attachParas['chargeIndex'])
  200. # 首先回读,检查从机地址是正确。如果回读地址无响应,会报错
  201. self.read_port(port)
  202. hexPort = fill_2_hexByte(hex(port),2)
  203. needTime = int(package['time'])
  204. needCoins = int(package['coins'])
  205. unit = package.get('unit', u'分钟')
  206. if unit == u'小时':
  207. needTime = int(package['time']) * 60
  208. elif unit == u'天':
  209. needTime = int(package['time']) * 1440
  210. hexTime = fill_2_hexByte(hex(needTime))
  211. data = 'A5' + hexPort + '0010050100000001' + hexTime
  212. devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_NO_RESPONSE,
  213. {'IMEI': self._device['devNo'], "funCode": '0C', 'data': data},
  214. timeout = MQTT_TIMEOUT.START_DEVICE)
  215. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  216. if devInfo['rst'] == -1:
  217. raise ServiceException({'result': 2, 'description': u'充电站正在玩命找网络,您的金币还在,重试不需要重新付款,建议您试试旁边其他设备,或者稍后再试哦'})
  218. elif devInfo['rst'] == 1:
  219. raise ServiceException({'result': 2, 'description': u'充电站正在忙,无响应,您的金币还在,请试试其他线路,或者请稍后再试哦'})
  220. start_timestamp = int(time.time())
  221. devInfo['finishedTime'] = start_timestamp + needTime * 60
  222. portValue = {
  223. 'startTime': timestamp_to_dt(start_timestamp).strftime('%Y-%m-%d %H:%M:%S'),
  224. 'status': Const.DEV_WORK_STATUS_WORKING,
  225. 'finishedTime': devInfo['finishedTime'],
  226. 'needTime': needTime,
  227. 'isStart': True,
  228. 'openId': openId,
  229. 'refunded': False,
  230. 'coins': needCoins,
  231. 'vCardId': self._vcard_id
  232. }
  233. ctrInfo = Device.get_dev_control_cache(self._device['devNo'])
  234. if ctrInfo.has_key(str(port)) and ctrInfo.has_key('needTime'):
  235. portValue = ctrInfo[str(port)]
  236. portValue.update({'needTime':portValue['needTime']+needTime})
  237. Device.update_dev_control_cache(self._device['devNo'],{str(port): portValue})
  238. return devInfo
  239. #注意格子锁的状态,只用读取全部的这个命令,单个锁的不要用了。
  240. def get_board_lock_status(self,boardNo):
  241. hexBoardNo = fill_2_hexByte(hex(int(boardNo)), 2)
  242. devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
  243. {'IMEI': self._device['devNo'], "funCode": '80',
  244. 'data': '80' + hexBoardNo + '0033'})
  245. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  246. if devInfo['rst'] == -1:
  247. raise ServiceException({'result': 2, 'description': u'充电站正在玩命找网络,您的金币还在,重试不需要重新付款,建议您试试旁边其他设备,或者稍后再试哦'})
  248. elif devInfo['rst'] == 1:
  249. raise ServiceException({'result': 2, 'description': u'充电站正在忙,无响应,您的金币还在,请试试其他线路,或者请稍后再试哦'})
  250. #1:表示开。0:表示关。
  251. lockData = hexbyte_2_bin(devInfo['data'][4:6]) + hexbyte_2_bin(devInfo['data'][6:8]) + hexbyte_2_bin(devInfo['data'][8:10])
  252. result = {}
  253. ii = 1
  254. for data in lockData[::-1]:
  255. if data == '0':
  256. result[str(ii)] ='close'
  257. else:
  258. result[str(ii)] = 'open'
  259. ii += 1
  260. return result
  261. def get_all_lock_status(self):
  262. cells = Cell.objects.filter(logicalCode = self._device['logicalCode'])
  263. boardList = list(set([cell.boardNo for cell in cells]))
  264. devLockDict = {}
  265. for boardNo in boardList:
  266. lockDict = self.get_board_lock_status(boardNo)
  267. devLockDict[str(boardNo)] = lockDict
  268. resultDict = {}
  269. for cell in cells:
  270. resultDict[str(cell.cellNo)] = devLockDict[str(cell.boardNo)][str(cell.lockNo)]
  271. return resultDict
  272. def open_many_locks(self,boardNo,lockNos):
  273. lockNoDict = {'0':8,'1':7,'2':6,'3':5,'4':4,'5':3,'6':2,'7':1,'8':16,'9':15,'10':14,'11':13,'12':12,'13':11,'14':10,'15':9,
  274. '16':24,'17':23,'18':22,'19':21,'20':20,'21':19,'22':18,'23':17}
  275. binData = ""
  276. for ii in range(24):
  277. lockNo = lockNoDict.get(str(ii))
  278. if lockNo in lockNos:
  279. binData += '1'
  280. else:
  281. binData += '0'
  282. hexData1 = fill_2_hexByte(hex(int(binData[0:8],2)),2)
  283. hexData2 = fill_2_hexByte(hex(int(binData[8:16],2)),2)
  284. hexData3 = fill_2_hexByte(hex(int(binData[16:24],2)),2)
  285. hexBoardNo = fill_2_hexByte(hex(int(boardNo)), 2)
  286. devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_NO_RESPONSE,
  287. {'IMEI': self._device['devNo'], "funCode": '90',
  288. 'data': '90' + hexBoardNo + hexData1 + hexData2 + hexData3})
  289. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  290. if devInfo['rst'] == -1:
  291. raise ServiceException({'result': 2, 'description': u'充电站正在玩命找网络,您的金币还在,重试不需要重新付款,建议您试试旁边其他设备,或者稍后再试哦'})
  292. elif devInfo['rst'] == 1:
  293. raise ServiceException({'result': 2, 'description': u'充电站正在忙,无响应,您的金币还在,请试试其他线路,或者请稍后再试哦'})
  294. return devInfo
  295. @property
  296. def isHaveStopEvent(self):
  297. return True