heshuichongdian.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. # -*- coding: utf-8 -*-
  2. # !/usr/bin/env python
  3. import datetime
  4. import logging
  5. import time
  6. from apilib.utils_datetime import to_datetime, timestamp_to_dt
  7. from apps.web.constant import Const, MQTT_TIMEOUT, DeviceCmdCode
  8. from apps.web.core.adapter.base import MqttSmartBox, fill_2_hexByte
  9. from apps.web.core.exceptions import ServiceException
  10. from apps.web.core.networking import MessageSender
  11. from apps.web.device.models import Device
  12. logger = logging.getLogger(__name__)
  13. class HeshuiChongdian(MqttSmartBox):
  14. def __init__(self, device):
  15. super(HeshuiChongdian, self).__init__(device)
  16. def analyze_event_data(self, data):
  17. if 'FB' == data[0:2]:
  18. return {'cmdCode': 'FB', 'port': 3}
  19. elif 'FD' in data[0:2]:
  20. if len(data) > 2:
  21. leftTime = int(data[2:6], 16)
  22. else:
  23. leftTime = -1
  24. return {'cmdCode': 'FD', 'port': 3, 'leftTime': leftTime}
  25. elif '01' in data[0:2]:
  26. return {'cmdCode': '01', 'usedTime': int(data[2:4], 16), 'port': 1}
  27. elif '02' in data[0:2]:
  28. return {'cmdCode': '02', 'usedTime': int(data[2:4], 16), 'port': 2}
  29. return None
  30. def get_port_info(self, line):
  31. if str(line) in ['1', '2']:
  32. ctrInfo = Device.get_dev_control_cache(self._device['devNo'])
  33. if ctrInfo is None or (not ctrInfo.has_key(str(line))):
  34. return {'port': line, 'leftTime': 0}
  35. portInfo = ctrInfo.get(str(line))
  36. if portInfo.has_key('startTime') and portInfo.has_key('needTime'):
  37. startTime = to_datetime(portInfo['startTime'])
  38. needTime = portInfo['needTime']
  39. leftTime = round((needTime - (datetime.datetime.now() - startTime).total_seconds()) / 60.0, 2)
  40. if leftTime <= 0:
  41. return {'port': line, 'leftTime': 0}
  42. return {'port': line, 'leftTime': leftTime}
  43. else:
  44. return {'port': line, 'leftTime': 0}
  45. leftTime = self.get_left_time_from_chargePort()
  46. return {'port': line, 'leftTime': leftTime}
  47. def get_port_status_from_dev(self):
  48. ctrInfo = Device.get_dev_control_cache(self._device['devNo'])
  49. device = Device.objects(devNo = self._device['devNo']).first()
  50. if device.otherConf.get('isMainboardDetection', False) is True:
  51. devInfo = MessageSender.send(self.device, 210,
  52. {'IMEI': self._device['devNo'], 'serialType': 'charger', 'funCode': 'FC',
  53. 'data': ''})
  54. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  55. if devInfo['rst'] == -1:
  56. raise ServiceException({'result': 2, 'description': u'设备正在玩命找网络,建议您试试旁边其他设备,或者稍后再试哦'})
  57. elif devInfo['rst'] == 1:
  58. raise ServiceException({'result': 2, 'description': u'设备忙,无响应,请您稍候再试。建议您试试旁边其他设备,或者稍后再试哦'})
  59. if devInfo['data'] != '0000':
  60. ctrInfo.update({'1': {'status': Const.DEV_WORK_STATUS_WORKING}})
  61. else:
  62. ctrInfo.update({'1': {'status': Const.DEV_WORK_STATUS_IDLE}})
  63. else:
  64. ctrInfo.update({'1': {'status': Const.DEV_WORK_STATUS_IDLE}})
  65. Device.update_dev_control_cache(self._device['devNo'], ctrInfo)
  66. def get_port_status(self, force = False):
  67. if force:
  68. return self.get_port_status_from_dev()
  69. portDict = {}
  70. ctrInfo = Device.get_dev_control_cache(self._device['devNo'])
  71. if ctrInfo.has_key('1') and ctrInfo['1'].has_key('startTime') and ctrInfo['1'].has_key('needTime'):
  72. portDict.update({'1': {'status': Const.DEV_WORK_STATUS_WORKING}})
  73. startTime = to_datetime(ctrInfo['1'].get('startTime'))
  74. if (datetime.datetime.now() - startTime).total_seconds() >= 60:
  75. portDict.update({'1': {'status': Const.DEV_WORK_STATUS_IDLE}})
  76. else:
  77. portDict.update({'1': {'status': Const.DEV_WORK_STATUS_WORKING}})
  78. else:
  79. portDict.update({'1': {'status': Const.DEV_WORK_STATUS_IDLE}})
  80. if ctrInfo.has_key('2') and ctrInfo['2'].has_key('startTime') and ctrInfo['2'].has_key('needTime'):
  81. portDict.update({'2': {'status': Const.DEV_WORK_STATUS_WORKING}})
  82. startTime = to_datetime(ctrInfo['2'].get('startTime'))
  83. if (datetime.datetime.now() - startTime).total_seconds() >= 60:
  84. portDict.update({'2': {'status': Const.DEV_WORK_STATUS_IDLE}})
  85. else:
  86. portDict.update({'2': {'status': Const.DEV_WORK_STATUS_WORKING}})
  87. else:
  88. portDict.update({'2': {'status': Const.DEV_WORK_STATUS_IDLE}})
  89. return portDict
  90. def start_device(self, package, openId, attachParas):
  91. #: 首先检查设备是否在线
  92. unit = package.get('unit', u'分钟')
  93. coins = package.get('price')
  94. port = int(attachParas.get('chargeIndex'))
  95. if unit == u'分钟': # 如果单位为分钟,就认为是充电
  96. needTimeInput = int(package['time'])
  97. needTime = needTimeInput * 60
  98. serialType = 'charger'
  99. funCode = '0A'
  100. data = fill_2_hexByte(hex(needTimeInput), 4)
  101. elif unit == u'秒': # 如果单位是秒,就认为是接水
  102. needTime = int(package['time'])
  103. serialType = 'water'
  104. if port == 1:
  105. funCode = '01'
  106. else:
  107. funCode = '02'
  108. data = ''
  109. else:
  110. raise ServiceException({'result': 2, 'description': u'套餐单位错误,无法启动哦'})
  111. devInfo = MessageSender.send(device = self.device, cmd = 220, payload = {
  112. 'IMEI': self._device['devNo'],
  113. 'serialType': serialType,
  114. "funCode": funCode,
  115. 'data': data
  116. }, timeout = MQTT_TIMEOUT.START_DEVICE)
  117. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  118. if devInfo['rst'] == -1:
  119. raise ServiceException({'result': 2, 'description': u'设备正在玩命找网络,您的金币还在,重试不需要重新付款,建议您试试旁边其他设备,或者稍后再试哦'})
  120. elif devInfo['rst'] == 1:
  121. raise ServiceException({'result': 2, 'description': u'设备正在忙,无响应,您的金币还在,重试不需要重新付款,请试试其他线路,或者请稍后再试哦'})
  122. start_timestamp = int(time.time())
  123. if serialType == 'charger':
  124. devInfo['finishedTime'] = (int(time.time()) + int(needTime))
  125. else:
  126. devInfo['finishedTime'] = (int(time.time()) + 60)
  127. value = {
  128. 'openId': openId,
  129. 'startTime': timestamp_to_dt(start_timestamp).strftime('%Y-%m-%d %H:%M:%S'),
  130. 'serialType': serialType,
  131. 'needTime': needTime,
  132. 'coins': coins,
  133. 'vCardId': self._vcard_id,
  134. 'status': Const.DEV_WORK_STATUS_WORKING,
  135. 'finishedTime': devInfo['finishedTime']
  136. }
  137. if 'linkedRechargeRecordId' in attachParas and attachParas.get('isQuickPay', False):
  138. item = {
  139. 'rechargeRcdId': str(attachParas['linkedRechargeRecordId'])
  140. }
  141. value['payInfo'] = [item]
  142. logger.info('port value is %s' % value)
  143. Device.update_dev_control_cache(self._device['devNo'], {str(port): value})
  144. return devInfo
  145. def get_left_time_from_chargePort(self):
  146. devInfo = MessageSender.send(self.device, 210, {'IMEI': self._device['devNo'], 'funCode': 'FC', 'data': ''})
  147. if devInfo.has_key('rst') and devInfo['rst'] != 0:
  148. raise ServiceException({'result': 2, 'description': u'当前设备正在玩命找网络,建议您试试旁边其他设备,或者试试投硬币,或者稍后再试哦'})
  149. leftTime = int(devInfo['data'], 16)
  150. return leftTime
  151. def set_standard_pulse(self, standardPulse):
  152. standardPulse = fill_2_hexByte(hex(int(standardPulse)))
  153. MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
  154. {'IMEI': self._device['devNo'], "funCode": '6b', 'data': standardPulse})
  155. def set_standard_count_and_time(self, standardCount, standardTime):
  156. standardCount = fill_2_hexByte(hex(int(standardCount)), num = 2)
  157. standardTime = fill_2_hexByte(hex(int(standardTime)), num = 2)
  158. MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
  159. {'IMEI': self._device['devNo'], "funCode": 'f5', 'data': standardCount + standardTime})
  160. def set_unit_pulse_detection(self):
  161. MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
  162. {'IMEI': self._device['devNo'], "funCode": 'b7', 'data': 'caca'})
  163. def set_device_function_param(self, request, lastSetConf):
  164. if 'standardPulse' in request.POST:
  165. standardPulse = request.POST['standardPulse']
  166. if standardPulse != '':
  167. self.set_standard_pulse(standardPulse)
  168. if 'standardCount' in request.POST and 'standardTime' in request.POST:
  169. standardCount = request.POST['standardCount']
  170. standardTime = request.POST['standardTime']
  171. if standardCount != '' and standardTime != '':
  172. self.set_standard_count_and_time(standardCount, standardTime)
  173. def get_dev_setting(self):
  174. device = Device.objects(devNo = self._device['devNo']).first()
  175. return {'isMainboardDetection': device.otherConf.get('isMainboardDetection', False)}
  176. def set_device_function(self, request, lastSetConf):
  177. if 'unitPulseDetection' in request.POST:
  178. self.set_unit_pulse_detection()
  179. if 'isMainboardDetection' in request.POST:
  180. isMainboardDetection = request.POST['isMainboardDetection']
  181. device = Device.objects(devNo = self._device['devNo']).first()
  182. device.otherConf['isMainboardDetection'] = isMainboardDetection
  183. device.save()