PulseWithCard.py 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. # -*- coding: utf-8 -*-
  2. # !/usr/bin/env python
  3. import datetime
  4. import logging
  5. import time
  6. import simplejson as json
  7. from apilib.utils_string import cn
  8. from apps.web.constant import DeviceErrorCodeDesc, ErrorCode, DeviceOnlineStatus, DeviceCmdCode, Const, FAULT_CODE, \
  9. MQTT_TIMEOUT
  10. from apps.web.core.adapter.base import SmartBox
  11. from apps.web.core.exceptions import ServiceException, DeviceNetworkTimeoutError
  12. from apps.web.core.networking import MessageSender
  13. from apps.web.device.models import Device
  14. from apps.web.core.device_define import PackageDict
  15. logger = logging.getLogger(__name__)
  16. class MySmartBox(SmartBox):
  17. def __init__(self, device):
  18. super(MySmartBox, self).__init__(device)
  19. def check_dev_status(self, attachParas = None):
  20. """
  21. 如果超过两个心跳周期没有报心跳,并且最后一次更新时间在2个小时内,需要从设备获取状态
  22. 否则以缓存状态为准。
  23. :param attachParas:
  24. :return:
  25. """
  26. if not self.device.need_fetch_online:
  27. raise ServiceException(
  28. {'result': 2, 'description': DeviceErrorCodeDesc.get(ErrorCode.DEVICE_CONN_FAIL)})
  29. if self.device.online == DeviceOnlineStatus.DEV_STATUS_ONLINE:
  30. retry = 3
  31. timeout = 12
  32. else:
  33. retry = 2
  34. timeout = 10
  35. operation_result = MessageSender.send(device = self.device, cmd = DeviceCmdCode.GET_DEVINFO, payload = {
  36. 'IMEI': self.device.devNo,
  37. 'fields': ['signal', 'pulse_open', 'board_volt', 'board_valid']
  38. }, timeout = timeout, retry = retry)
  39. if operation_result['rst'] != ErrorCode.DEVICE_SUCCESS:
  40. if operation_result['rst'] == ErrorCode.DEVICE_CONN_FAIL:
  41. raise ServiceException(
  42. {
  43. 'result': 2,
  44. 'description': DeviceErrorCodeDesc.get(ErrorCode.DEVICE_CONN_CHECK_FAIL)
  45. })
  46. else:
  47. raise ServiceException(
  48. {
  49. 'result': 2,
  50. 'description': u'检测设备状态失败({})'.format(operation_result['rst'])
  51. })
  52. else:
  53. if 'pulse_open' in operation_result and (not operation_result['pulse_open']):
  54. raise ServiceException(
  55. {
  56. 'result': 2,
  57. 'description': u'检测设备状态失败({})'.format(ErrorCode.PULSE_IS_CLOSE)
  58. })
  59. if 'board_valid' in operation_result and 'board_volt' in operation_result and operation_result[
  60. 'board_valid'] != 2:
  61. if operation_result['board_volt'] != operation_result['board_valid']:
  62. raise ServiceException(
  63. {
  64. 'result': 2,
  65. 'description': u'当前设备正在工作,请稍后再试'
  66. })
  67. def test(self, coins):
  68. now_time = datetime.datetime.now()
  69. return MessageSender.send(device = self.device, cmd = DeviceCmdCode.PAY_MONEY, payload = {
  70. 't': int(time.mktime(now_time.timetuple())),
  71. 'duration': coins * 60,
  72. 'app_pay': coins
  73. })
  74. def start_device(self, package, openId, attachParas):
  75. pay_count = int(package['coins'])
  76. result = MessageSender.net_pay(self.device, pay_count, timeout = MQTT_TIMEOUT.START_DEVICE)
  77. if result['rst'] == ErrorCode.DEVICE_CONN_FAIL:
  78. raise DeviceNetworkTimeoutError()
  79. elif result['rst'] != ErrorCode.DEVICE_SUCCESS:
  80. logger.debug('MySmartBox() failed to start, result was=%s' % (json.dumps(result),))
  81. raise ServiceException({'result': 2, 'description': DeviceErrorCodeDesc.get(result['rst'])})
  82. try:
  83. duration = self.get_duration(package)
  84. result['finishedTime'] = (int(time.time()) + duration)
  85. Device.update_dev_control_cache(self._device['devNo'],
  86. {
  87. 'status': Const.DEV_WORK_STATUS_WORKING,
  88. 'finishedTime': result['finishedTime']
  89. })
  90. except Exception as e:
  91. logger.exception('error = %s' % e)
  92. return result
  93. def start_device_realiable(self, order):
  94. try:
  95. now_time = datetime.datetime.now()
  96. result = MessageSender.send(device = self.device, cmd = DeviceCmdCode.PAY_MONEY, payload = {
  97. 't': int(time.mktime(now_time.timetuple())),
  98. 'duration': PackageDict(order.package).estimated_duraion,
  99. 'order_id': order.orderNo,
  100. 'order_type': 'pulse_start',
  101. 'app_pay': int(order.package['coins'])
  102. })
  103. if result['rst'] == ErrorCode.DEVICE_CONN_FAIL:
  104. result.update({
  105. 'fts': int(time.time()),
  106. 'order_type': 'com_start',
  107. 'order_id': order.orderNo
  108. })
  109. except ServiceException as e:
  110. logger.exception(e)
  111. return {
  112. 'rst': ErrorCode.EXCEPTION,
  113. 'fts': int(time.time()),
  114. 'errorDesc': cn(e.result.get('description')),
  115. 'order_type': 'com_start',
  116. 'order_id': order.orderNo
  117. }
  118. except Exception as e:
  119. logger.exception(e)
  120. return {
  121. 'rst': ErrorCode.EXCEPTION,
  122. 'fts': int(time.time()),
  123. 'order_type': 'com_start',
  124. 'order_id': order.orderNo
  125. }
  126. def get_total_coin(self):
  127. result = MessageSender.send(self.device, DeviceCmdCode.GET_DEVINFO,
  128. {'cmd': DeviceCmdCode.GET_DEVINFO, 'IMEI': self._device['devNo']})
  129. if result['rst'] != ErrorCode.DEVICE_SUCCESS:
  130. logger.debug('MySmartBox() failed to get total coin, result was=%s' % (json.dumps(result),))
  131. description = u'当前设备信号弱没有响应,请您稍后重试。'
  132. raise ServiceException({'result': 2, 'description': description})
  133. if not result.has_key('total_coin'):
  134. raise ServiceException({'result': 2, 'description': u'当前设备暂时不支持获取总的硬币数目,待版本自动升级后,会支持'})
  135. return result['total_coin']
  136. # 基类函数,检查告警状态,只能做一个简单的检查,设备是否在线
  137. def check_alarm(self, alarm):
  138. if alarm.faultCode == FAULT_CODE.OFFLINE:
  139. dev_info = MessageSender.send(device = self.device, cmd = DeviceCmdCode.GET_DEVINFO,
  140. payload = {'IMEI': self.device.devNo, 'fields': []},
  141. timeout = MQTT_TIMEOUT.SHORT)
  142. if dev_info['rst'] == 0:
  143. return u'设备状态检查在线,网络通畅,网络可能出现闪断'
  144. else:
  145. raise ServiceException({'result': 2, 'description': u'设备玩命也无法找到网络,设备可能不在线'})
  146. else:
  147. return u'无法检查该设备的告警状态,建议您用其他方式确认此告警是否正常'
  148. def set_device_function_param(self, request, lastSetConf):
  149. cardPrice = request.POST.get("cardPrice")
  150. eachCoin = request.POST.get("eachCoin")
  151. # 服务器参数
  152. if cardPrice and eachCoin:
  153. if not str(cardPrice).isdigit():
  154. raise ServiceException({"result": 2, "description": "刷卡单价必须为整数"})
  155. if not str(eachCoin).isdigit():
  156. raise ServiceException({"result": 2, "description": "脉冲次数必须为整数"})
  157. cardPrice = int(cardPrice)
  158. packages = self.device['washConfig']
  159. packages = sorted(packages.values(), key = lambda x: x["coins"])
  160. min_coin = int(packages[0].get("coins"))
  161. max_coin = int(packages[-1].get("coins"))
  162. eachCoin = int(eachCoin)
  163. if min_coin > eachCoin or max_coin < eachCoin:
  164. raise ServiceException({"result": 2, "description": "脉冲次数不能超过套餐投币数范围"})
  165. dic = {
  166. 'cardPrice': cardPrice,
  167. 'eachCoin': eachCoin
  168. }
  169. dev = Device.objects.get(devNo = self.device.devNo)
  170. dev.otherConf.update(dic)
  171. dev.save()
  172. dev.invalid_device_cache(dev.devNo)
  173. def get_dev_setting(self):
  174. data = {}
  175. # 服务器参数
  176. if self.device['otherConf'] and self.device['otherConf'].get('cardPrice') and self.device['otherConf'].get(
  177. 'eachCoin'):
  178. data['cardPrice'] = self.device['otherConf']['cardPrice']
  179. data['eachCoin'] = self.device['otherConf']['eachCoin']
  180. return data