hainiaoSingle.py 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. # -*- coding: utf-8 -*-
  2. #!/usr/bin/env python
  3. import time
  4. import logging
  5. from apilib.utils_datetime import timestamp_to_dt
  6. from apps.web.constant import Const, DeviceCmdCode, MQTT_TIMEOUT, DeviceErrorCodeDesc, ErrorCode
  7. from apps.web.core.adapter.base import SmartBox, fill_2_hexByte
  8. from apps.web.core.exceptions import ServiceException
  9. from apps.web.core.networking import MessageSender
  10. from apps.web.device.models import Device, GroupDict
  11. logger = logging.getLogger(__name__)
  12. class ChargingHaiNiaoSingleBox(SmartBox):
  13. def __init__(self, device):
  14. super(ChargingHaiNiaoSingleBox, self).__init__(device)
  15. def translate_funcode(self, funCode):
  16. funCodeDict = {
  17. '01': u'获取端口状态',
  18. '02': u'获取设备参数',
  19. '03': u'操作端口',
  20. '04': u'设置参数',
  21. }
  22. return funCodeDict.get(funCode, '')
  23. def translate_event_cmdcode(self, cmdCode):
  24. cmdDict = {
  25. '86': u'设备上报信息',
  26. }
  27. return cmdDict.get(cmdCode, '')
  28. def check_dev_status(self, attachParas = None):
  29. """
  30. 如果超过两个心跳周期没有报心跳,并且最后一次更新时间在2个小时内,需要从设备获取状态
  31. 否则以缓存状态为准。
  32. :param attachParas:
  33. :return:
  34. """
  35. if attachParas is None:
  36. raise ServiceException({'result': 0, 'description': u'请您选择合适的充电端口、电池类型信息'})
  37. if not attachParas.has_key('chargeIndex'):
  38. raise ServiceException({'result': 0, 'description': u'请您选择合适的充电端口'})
  39. if not self.device.need_fetch_online:
  40. raise ServiceException(
  41. {'result': 2, 'description': DeviceErrorCodeDesc.get(ErrorCode.DEVICE_CONN_CHECK_FAIL)})
  42. self.get_port_status_from_dev()
  43. group = self.device.group # type: GroupDict
  44. if group.is_free:
  45. logger.debug('{} is free. no need to check continue pay.'.format(repr(self.device)))
  46. return
  47. # 处理是否能够续充
  48. portDict = self.get_port_status()
  49. port = str(attachParas['chargeIndex'])
  50. if port in portDict:
  51. isCanAdd = self.device['devType'].get('payableWhileBusy', False)
  52. if portDict[port]['status'] == Const.DEV_WORK_STATUS_IDLE:
  53. return
  54. elif portDict[port]['status'] == Const.DEV_WORK_STATUS_FAULT:
  55. raise ServiceException({'result': 0, 'description': u'该端口故障,暂时不能使用'})
  56. elif portDict[port]['status'] == Const.DEV_WORK_STATUS_WORKING:
  57. if isCanAdd:
  58. return
  59. else:
  60. raise ServiceException({'result': 0, 'description': u'该端口正在工作不能使用,请您使用其他端口'})
  61. elif portDict[port]['status'] == Const.DEV_WORK_STATUS_FORBIDDEN:
  62. raise ServiceException({'result': 0, 'description': u'该端口已被禁止使用,请您使用其他端口'})
  63. elif portDict[port]['status'] == Const.DEV_WORK_STATUS_CONNECTED:
  64. return
  65. else:
  66. raise ServiceException({'result': 0, 'description': u'端口状态未知,暂时不能使用'})
  67. else:
  68. raise ServiceException({'result': 0, 'description': u'未知端口,暂时不能使用'})
  69. def get_port_status_from_dev(self): # 获取端口状态
  70. devInfo = MessageSender.send(self.device, self.make_random_cmdcode(),
  71. {'IMEI': self._device['devNo'], "funCode": '01', 'data': '00'})
  72. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  73. if devInfo['rst'] == -1:
  74. raise ServiceException(
  75. {'result': 2, 'description': u'当前设备正在玩命找网络,请您稍候再试'})
  76. elif devInfo['rst'] == 1:
  77. raise ServiceException(
  78. {'result': 2, 'description': u'当前设备忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})
  79. result = {}
  80. binStr = str(bin(int(devInfo['data'][10:12], 16)))[2:]
  81. while len(binStr) < 8:
  82. binStr = '0' + binStr
  83. portStatus = binStr[-1]
  84. if portStatus == '0':
  85. result['1'] = {'status': Const.DEV_WORK_STATUS_IDLE}
  86. elif portStatus == '1':
  87. result['1'] = {'status': Const.DEV_WORK_STATUS_WORKING}
  88. else:
  89. raise ServiceException(
  90. {'result': 2, 'description': u'端口状态返回错误'})
  91. allPorts, usedPorts, usePorts = self.get_port_static_info(result)
  92. Device.update_dev_control_cache(self._device['devNo'],
  93. {'allPorts': allPorts, 'usedPorts': usedPorts, 'usePorts': usePorts})
  94. # 这里存在多线程更新缓存的场景,可能性比较低,但是必须先取出来,然后逐个更新状态,然后再记录缓存
  95. ctrInfo = Device.get_dev_control_cache(self._device['devNo'])
  96. for strPort, info in result.items():
  97. if ctrInfo.has_key(strPort):
  98. ctrInfo[strPort].update({'status': info['status']})
  99. else:
  100. ctrInfo[strPort] = info
  101. Device.update_dev_control_cache(self._device['devNo'], ctrInfo)
  102. return result
  103. def get_port_status(self, force = False): # 获取端口状态(缓存)
  104. if force:
  105. return self.get_port_status_from_dev()
  106. ctrInfo = Device.get_dev_control_cache(self._device['devNo'])
  107. statusDict = {}
  108. allPorts = ctrInfo.get('allPorts', 1)
  109. for ii in range(allPorts):
  110. tempDict = ctrInfo.get(str(ii + 1), {})
  111. if tempDict.has_key('status'):
  112. statusDict[str(ii + 1)] = {'status': tempDict.get('status')}
  113. elif tempDict.has_key('isStart'):
  114. if tempDict['isStart']:
  115. statusDict[str(ii + 1)] = {'status': Const.DEV_WORK_STATUS_WORKING}
  116. else:
  117. statusDict[str(ii + 1)] = {'status': Const.DEV_WORK_STATUS_IDLE}
  118. else:
  119. statusDict[str(ii + 1)] = {'status': Const.DEV_WORK_STATUS_IDLE}
  120. allPorts, usedPorts, usePorts = self.get_port_static_info(statusDict)
  121. Device.update_dev_control_cache(self._device['devNo'],
  122. {'allPorts': allPorts, 'usedPorts': usedPorts, 'usePorts': usePorts})
  123. return statusDict
  124. def start_device(self, package, openId, attachParas):
  125. if attachParas is None:
  126. raise ServiceException({'result': 2, 'description': u'请您选择合适的充电线路、电池类型信息'})
  127. if not attachParas.has_key('chargeIndex'):
  128. raise ServiceException({'result': 2, 'description': u'请您选择合适的充电线路'})
  129. # 只有一个端口
  130. hexPort = '0001'
  131. needTime = 0
  132. needLitre = 0
  133. needPrice = float(package['price'])
  134. hexNeedPrice = fill_2_hexByte(hex(int(needPrice * 100)))
  135. unit = package['unit']
  136. if unit == u'升':
  137. needLitre = int(package['time'])
  138. hexLitre = fill_2_hexByte(hex(needLitre * 10))
  139. data = hexPort + '01' + hexLitre + hexNeedPrice
  140. elif unit == u'小时':
  141. needTime = int(package['time']) * 60
  142. hexTime = fill_2_hexByte(hex(needTime))
  143. data = hexPort + '01' + hexTime + hexNeedPrice
  144. else:
  145. needTime = int(package['time'])
  146. hexTime = fill_2_hexByte(hex(needTime))
  147. data = hexPort + '01' + hexTime + hexNeedPrice
  148. billingMode = self.get_dev_setting()['billingMode']
  149. if billingMode == 'litre' and unit == u'升':
  150. pass
  151. elif billingMode == 'time' and unit == u'分钟':
  152. pass
  153. elif billingMode == 'time' and unit == u'小时':
  154. pass
  155. else:
  156. raise ServiceException({'result': 2, 'description': u'套餐与主板的启动参数不匹配(时间/流量)'})
  157. orderNo = attachParas.get('orderNo')
  158. portStatus = self.get_port_status_from_dev()
  159. if portStatus['1']['status'] == Const.DEV_WORK_STATUS_WORKING:
  160. data = data[0:4] + data[6:10]
  161. devInfo = MessageSender.send(
  162. device = self.device,
  163. cmd = DeviceCmdCode.OPERATE_DEV_SYNC,
  164. payload = {
  165. 'IMEI': self._device['devNo'],
  166. "funCode": '09',
  167. 'data': data
  168. }, timeout = MQTT_TIMEOUT.START_DEVICE)
  169. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  170. if devInfo['rst'] == -1:
  171. raise ServiceException(
  172. {'result': 2, 'description': u'当前设备正在玩命找网络,您的金币还在,重试不需要重新付款,建议您试试旁边其他设备,或者稍后再试哦'})
  173. elif devInfo['rst'] == 1:
  174. raise ServiceException({'result': 2, 'description': u'当前设备正在忙,无响应,您的金币还在,请试试其他线路,或者请稍后再试哦'})
  175. data = devInfo['data'][8::]
  176. usePort = int(data[0:4], 16)
  177. result = data[4:8]
  178. if result == '0000': # 代表失败
  179. newValue = {str(usePort): {'status': Const.DEV_WORK_STATUS_FAULT, 'statusInfo': u'充电站故障'}}
  180. Device.update_dev_control_cache(self._device['devNo'], newValue)
  181. raise ServiceException({'result': 2, 'description': u'充电站故障'})
  182. start_timestamp = int(time.time())
  183. finishedTime = start_timestamp + needTime * 60
  184. portDict = {
  185. 'startTime': timestamp_to_dt(start_timestamp).strftime('%Y-%m-%d %H:%M:%S'),
  186. 'status': Const.DEV_WORK_STATUS_WORKING,
  187. 'finishedTime': finishedTime,
  188. 'needPrice': needPrice,
  189. # 个人中心断电需要用到
  190. 'coins': needPrice,
  191. 'isStart': True,
  192. 'needTime': needTime,
  193. 'needLitre': needLitre,
  194. 'openId': openId,
  195. 'refunded': False,
  196. 'vCardId': self._vcard_id
  197. }
  198. ctrInfo = Device.get_dev_control_cache(self._device['devNo'])
  199. lastPortInfo = ctrInfo.get(str(usePort), None)
  200. is_continue = False
  201. if lastPortInfo is not None and \
  202. lastPortInfo.get('status', '') == Const.DEV_WORK_STATUS_WORKING and \
  203. lastPortInfo.get('openId', '') == openId:
  204. is_continue = True
  205. if 'needPrice' in lastPortInfo:
  206. portDict['needPrice'] = float(needPrice) + lastPortInfo['needPrice']
  207. if 'needTime' in lastPortInfo:
  208. portDict['needTime'] = needTime + lastPortInfo['needTime']
  209. if 'needLitre' in lastPortInfo:
  210. portDict['needLitre'] = needLitre + lastPortInfo['needLitre']
  211. finishedTime = int(time.time()) + portDict['needTime'] * 60
  212. portDict.update({'finishedTime': finishedTime})
  213. if 'linkedRechargeRecordId' in attachParas and attachParas.get('isQuickPay', False):
  214. item = {
  215. 'rechargeRcdId': str(attachParas['linkedRechargeRecordId'])
  216. }
  217. if is_continue:
  218. payInfo = lastPortInfo.get('payInfo', list())
  219. else:
  220. payInfo = list()
  221. payInfo.append(item)
  222. portDict['payInfo'] = payInfo
  223. else:
  224. devInfo = MessageSender.send(
  225. device = self.device,
  226. cmd = DeviceCmdCode.OPERATE_DEV_SYNC,
  227. payload = {
  228. 'IMEI': self._device['devNo'],
  229. "funCode": '08',
  230. 'data': data
  231. }, timeout = MQTT_TIMEOUT.START_DEVICE)
  232. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  233. if devInfo['rst'] == -1:
  234. raise ServiceException(
  235. {'result': 2, 'description': u'当前设备正在玩命找网络,您的金币还在,重试不需要重新付款,建议您试试旁边其他设备,或者稍后再试哦'})
  236. elif devInfo['rst'] == 1:
  237. raise ServiceException({'result': 2, 'description': u'当前设备正在忙,无响应,您的金币还在,请试试其他线路,或者请稍后再试哦'})
  238. data = devInfo['data'][8::]
  239. usePort = 1
  240. result = data[4:8]
  241. if result == '0000': # 代表失败
  242. newValue = {str(usePort): {'status': Const.DEV_WORK_STATUS_FAULT, 'statusInfo': u'充电站故障'}}
  243. Device.update_dev_control_cache(self._device['devNo'], newValue)
  244. raise ServiceException({'result': 2, 'description': u'充电站故障'})
  245. start_timestamp = int(time.time())
  246. finishedTime = start_timestamp + needTime * 60
  247. portDict = {
  248. 'startTime': timestamp_to_dt(start_timestamp).strftime('%Y-%m-%d %H:%M:%S'),
  249. 'status': Const.DEV_WORK_STATUS_WORKING,
  250. 'finishedTime': finishedTime,
  251. 'needPrice': needPrice,
  252. # 个人中心断电需要用到
  253. 'coins': needPrice,
  254. 'isStart': True,
  255. 'needTime': needTime,
  256. 'needLitre': needLitre,
  257. 'openId': openId,
  258. 'refunded': False,
  259. 'vCardId': self._vcard_id
  260. }
  261. if 'linkedRechargeRecordId' in attachParas:
  262. item = {
  263. 'rechargeRcdId': str(attachParas['linkedRechargeRecordId'])
  264. }
  265. portDict['payInfo'] = [item]
  266. Device.update_dev_control_cache(self._device['devNo'], {str(usePort): portDict})
  267. return devInfo
  268. def get_dev_setting(self):
  269. devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
  270. {'IMEI': self._device['devNo'],"funCode":'02','data':'00'})
  271. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  272. if devInfo['rst'] == -1:
  273. raise ServiceException(
  274. {'result': 2, 'description': u'当前设备正在玩命找网络,请您稍候再试'})
  275. elif devInfo['rst'] == 1:
  276. raise ServiceException(
  277. {'result': 2, 'description': u'当前设备忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})
  278. confData = devInfo['data'][8::]
  279. switchData = int(confData[0:2], 16)
  280. power1Price = int(confData[10:12], 16)
  281. power1Matter = int(confData[12:16], 16)
  282. power2Price = int(confData[16:18], 16)
  283. power2Matter = int(confData[18:22], 16)
  284. power3Price = int(confData[22:24], 16)
  285. power3Matter = int(confData[24:28], 16)
  286. power4Price = int(confData[28:30], 16)
  287. power4Matter = int(confData[30:34], 16)
  288. power5Price = int(confData[34:36], 16)
  289. power5Matter = int(confData[36:40], 16)
  290. power6Price = int(confData[40:42], 16)
  291. power6Matter = int(confData[42:46], 16)
  292. binStr = str(bin(switchData))[2:]
  293. while len(binStr) < 8:
  294. binStr = '0' + binStr
  295. billingMode = 'litre' if int(binStr[4]) else 'time'
  296. workingMode = 'multiple' if int(binStr[3]) else 'single'
  297. isPause = True if int(binStr[2]) else False
  298. isPowerOffMemory = True if int(binStr[1]) else False
  299. coinLaunchMode = 'button' if int(binStr[0]) else 'direct'
  300. device = Device.objects(devNo=self._device['devNo']).first()
  301. minConsumptionLimit = device.otherConf.get('minConsumptionLimit', 0)
  302. return {
  303. 'billingMode': billingMode,
  304. 'workingMode': workingMode,
  305. 'isPause': isPause,
  306. 'isPowerOffMemory': isPowerOffMemory,
  307. 'coinLaunchMode': coinLaunchMode,
  308. 'power1Price': power1Price,
  309. 'power1Matter': power1Matter,
  310. 'power2Price': power2Price,
  311. 'power2Matter': power2Matter,
  312. 'power3Price': power3Price,
  313. 'power3Matter': power3Matter,
  314. 'power4Price': power4Price,
  315. 'power4Matter': power4Matter,
  316. 'power5Price': power5Price,
  317. 'power5Matter': power5Matter,
  318. 'power6Price': power6Price,
  319. 'power6Matter': power6Matter,
  320. 'minConsumptionLimit': minConsumptionLimit
  321. }
  322. def send_setting_data(self, data):
  323. devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
  324. {'IMEI': self._device['devNo'], "funCode": '04', 'data': data})
  325. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  326. if devInfo['rst'] == -1:
  327. raise ServiceException(
  328. {'result': 2, 'description': u'当前设备正在玩命找网络,请您稍候再试'})
  329. elif devInfo['rst'] == 1:
  330. raise ServiceException(
  331. {'result': 2, 'description': u'当前设备忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})
  332. if devInfo['data'][14:16] == '01':
  333. raise ServiceException(
  334. {'result': 2, 'description': u'设置失败'})
  335. def set_pause_mode(self, isPause):
  336. data = '08' + ('0001' if isPause else '0000')
  337. self.send_setting_data(data)
  338. def set_power_off_memory(self, isPowerOffMemory):
  339. data = '0C' + ('0001' if isPowerOffMemory else '0000')
  340. self.send_setting_data(data)
  341. def set_base_settings(self, baseSettingsDict):
  342. billingModeData = '0B' + ('0001' if baseSettingsDict['billingMode'] == 'litre' else '0000')
  343. self.send_setting_data(billingModeData)
  344. workingModeData = '0A' + ('0001' if baseSettingsDict['workingMode'] == 'multiple' else '0000')
  345. self.send_setting_data(workingModeData)
  346. coinLaunchModeData = '09' + ('0001' if baseSettingsDict['coinLaunchMode'] == 'button' else '0000')
  347. self.send_setting_data(coinLaunchModeData)
  348. device = Device.objects(devNo=self._device['devNo']).first()
  349. device.otherConf['minConsumptionLimit'] = baseSettingsDict['minConsumptionLimit']
  350. device.save()
  351. def set_power_price(self, powerPriceDict):
  352. power1PriceData = '14' + fill_2_hexByte(hex(int(powerPriceDict['power1Price'])))
  353. self.send_setting_data(power1PriceData)
  354. power2PriceData = '16' + fill_2_hexByte(hex(int(powerPriceDict['power2Price'])))
  355. self.send_setting_data(power2PriceData)
  356. power3PriceData = '18' + fill_2_hexByte(hex(int(powerPriceDict['power3Price'])))
  357. self.send_setting_data(power3PriceData)
  358. power4PriceData = '1A' + fill_2_hexByte(hex(int(powerPriceDict['power4Price'])))
  359. self.send_setting_data(power4PriceData)
  360. power5PriceData = '1C' + fill_2_hexByte(hex(int(powerPriceDict['power5Price'])))
  361. self.send_setting_data(power5PriceData)
  362. power6PriceData = '1E' + fill_2_hexByte(hex(int(powerPriceDict['power6Price'])))
  363. self.send_setting_data(power6PriceData)
  364. def set_power_matter(self, powerMatterDict):
  365. power1MatterData = '15' + fill_2_hexByte(hex(int(powerMatterDict['power1Matter'])))
  366. self.send_setting_data(power1MatterData)
  367. power2MatterData = '17' + fill_2_hexByte(hex(int(powerMatterDict['power2Matter'])))
  368. self.send_setting_data(power2MatterData)
  369. power3MatterData = '19' + fill_2_hexByte(hex(int(powerMatterDict['power3Matter'])))
  370. self.send_setting_data(power3MatterData)
  371. power4MatterData = '1B' + fill_2_hexByte(hex(int(powerMatterDict['power4Matter'])))
  372. self.send_setting_data(power4MatterData)
  373. power5MatterData = '1D' + fill_2_hexByte(hex(int(powerMatterDict['power5Matter'])))
  374. self.send_setting_data(power5MatterData)
  375. power6MatterData = '1F' + fill_2_hexByte(hex(int(powerMatterDict['power6Matter'])))
  376. self.send_setting_data(power6MatterData)
  377. def set_device_function(self, request, lastSetConf):
  378. if 'isPause' in request.POST:
  379. isPause = request.POST['isPause']
  380. self.set_pause_mode(isPause)
  381. if 'isPowerOffMemory' in request.POST:
  382. isPowerOffMemory = request.POST['isPowerOffMemory']
  383. self.set_power_off_memory(isPowerOffMemory)
  384. def set_device_function_param(self, request, lastSetConf):
  385. if 'billingMode' in request.POST \
  386. and 'workingMode' in request.POST \
  387. and 'minConsumptionLimit' in request.POST \
  388. and 'coinLaunchMode' in request.POST:
  389. billingMode = request.POST['billingMode']
  390. workingMode = request.POST['workingMode']
  391. minConsumptionLimit = request.POST['minConsumptionLimit']
  392. coinLaunchMode = request.POST['coinLaunchMode']
  393. self.set_base_settings({
  394. 'billingMode': billingMode,
  395. 'workingMode': workingMode,
  396. 'minConsumptionLimit': minConsumptionLimit,
  397. 'coinLaunchMode': coinLaunchMode
  398. })
  399. if 'power1Price' in request.POST \
  400. and 'power2Price' in request.POST \
  401. and 'power3Price' in request.POST \
  402. and 'power4Price' in request.POST \
  403. and 'power5Price' in request.POST \
  404. and 'power6Price' in request.POST:
  405. power1Price = request.POST['power1Price']
  406. power2Price = request.POST['power2Price']
  407. power3Price = request.POST['power3Price']
  408. power4Price = request.POST['power4Price']
  409. power5Price = request.POST['power5Price']
  410. power6Price = request.POST['power6Price']
  411. self.set_power_price({
  412. 'power1Price': power1Price,
  413. 'power2Price': power2Price,
  414. 'power3Price': power3Price,
  415. 'power4Price': power4Price,
  416. 'power5Price': power5Price,
  417. 'power6Price': power6Price
  418. })
  419. if 'power1Matter' in request.POST \
  420. and 'power2Matter' in request.POST \
  421. and 'power3Matter' in request.POST \
  422. and 'power4Matter' in request.POST \
  423. and 'power5Matter' in request.POST \
  424. and 'power6Matter' in request.POST:
  425. power1Matter = request.POST['power1Matter']
  426. power2Matter = request.POST['power2Matter']
  427. power3Matter = request.POST['power3Matter']
  428. power4Matter = request.POST['power4Matter']
  429. power5Matter = request.POST['power5Matter']
  430. power6Matter = request.POST['power6Matter']
  431. self.set_power_matter({
  432. 'power1Matter': power1Matter,
  433. 'power2Matter': power2Matter,
  434. 'power3Matter': power3Matter,
  435. 'power4Matter': power4Matter,
  436. 'power5Matter': power5Matter,
  437. 'power6Matter': power6Matter
  438. })
  439. def get_port_info(self, line):
  440. devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
  441. {'IMEI': self._device['devNo'], "funCode": '01', 'data': '00'})
  442. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  443. if devInfo['rst'] == -1:
  444. raise ServiceException(
  445. {'result': 2, 'description': u'当前设备正在玩命找网络,请您稍候再试'})
  446. elif devInfo['rst'] == 1:
  447. raise ServiceException(
  448. {'result': 2, 'description': u'当前设备忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})
  449. leftTimeSec = int(devInfo['data'][12:20], 16)
  450. leftTime = leftTimeSec / 60
  451. return {'port': line, 'leftTime': leftTime}
  452. def stop(self, port = None):
  453. self.stop_charging_port(port)
  454. infoDict = dict()
  455. infoDict['remainder_time'] = 0
  456. return infoDict
  457. def stop_charging_port(self, port):
  458. self.active_deactive_port(port, False)
  459. def active_deactive_port(self, port, active):
  460. if active:
  461. return
  462. else:
  463. data = '000100'
  464. devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
  465. {'IMEI': self._device['devNo'], "funCode": '03', 'data': data + '0000'})
  466. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  467. if devInfo['rst'] == -1:
  468. raise ServiceException(
  469. {'result': 2, 'description': u'当前设备正在玩命找网络,请您稍候再试'})
  470. elif devInfo['rst'] == 1:
  471. # 不处理
  472. pass
  473. def analyze_event_data(self, data):
  474. cmdCode = data[6:8]
  475. if cmdCode == '86':
  476. channelChangeStatus = data[10:12]
  477. binChannelChangeStatus = str(bin(int(channelChangeStatus, 16)))[2:]
  478. while len(binChannelChangeStatus) < 8:
  479. binChannelChangeStatus = '0' + binChannelChangeStatus
  480. channelOperateStatus = data[14:16]
  481. binChannelOperateStatus = str(bin(int(channelOperateStatus, 16)))[2:]
  482. while len(binChannelOperateStatus) < 8:
  483. binChannelOperateStatus = '0' + binChannelOperateStatus
  484. channel1Status = False if binChannelChangeStatus[-1] == '0' else True
  485. channel1Oper = False if binChannelOperateStatus[-1] == '0' else True
  486. # 判断条件成立代表结束
  487. if channel1Status is True and channel1Oper is False:
  488. reason = data[16:18]
  489. if reason == '00':
  490. desc = u'购买的充电时间或者电量用完了。'
  491. elif reason in ['04', '06', '07']:
  492. desc = u'管理人员可能远程断电了,或是插头被拔掉, 建议您根据已经充电的时间评估是否需要到现场换到其他端口充电。'
  493. elif reason == '05':
  494. desc = u'空载断电。'
  495. else:
  496. desc = u''
  497. leftTime = int(data[36:44], 16) / 60
  498. leftPrice = float(int(data[44:48], 16)) / 100
  499. return {
  500. 'status': Const.DEV_WORK_STATUS_IDLE,
  501. 'leftPrice': leftPrice,
  502. 'leftTime': leftTime,
  503. 'cmdCode': cmdCode,
  504. 'reason': desc,
  505. 'port': '1'
  506. }
  507. else:
  508. return {}
  509. def pauseToUseDevice(self, port, oper):
  510. MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_NO_RESPONSE,
  511. {'IMEI': self._device['devNo'], "funCode": '03', 'data': '0001' + oper + '0000'})
  512. if oper == '02':
  513. Device.update_dev_control_cache(self._device['devNo'], {'1': {'pausePort': True}})
  514. elif oper == '01':
  515. Device.update_dev_control_cache(self._device['devNo'], {'1': {'pausePort': False}})
  516. else:
  517. pass
  518. @property
  519. def isHaveStopEvent(self):
  520. return True