simaier2.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. # -*- coding: utf-8 -*-
  2. # !/usr/bin/env python
  3. import time
  4. from apps.common.utils import int_to_hex
  5. from apps.web.constant import DeviceCmdCode, MQTT_TIMEOUT, Const
  6. from apps.web.core.adapter.base import SmartBox
  7. from apps.web.core.exceptions import ServiceException
  8. from apps.web.core.networking import MessageSender
  9. from apps.web.device.models import Device
  10. class WasherBox(SmartBox):
  11. WORK_MODE = {
  12. u"加强洗": "01", # 工作46分钟
  13. u"标准洗": "02", # 工作38分钟
  14. u"快速洗": "03", # 工作22分钟
  15. u"单脱水": "04", # 工作06分钟
  16. u"桶消毒": "05", # 工作04分钟
  17. u"自检": "06" # 工作30秒
  18. }
  19. STATUS_CODE_INFO = {
  20. '00': u'待机中',
  21. '01': u'预约中',
  22. '02': u'消毒清洁中',
  23. '03': u'洗衣工作中',
  24. '04': u'洗衣机洗涤结束',
  25. '05': u'洗衣机自检中',
  26. '06': u'进水超时',
  27. '07': u'排水超时',
  28. '08': u'脱水时撞桶',
  29. '09': u'脱水开盖',
  30. '0A': u'水位传感器异常',
  31. '0B': u'溢水报警',
  32. '0C': u'电机故障',
  33. '0D': u'通讯故障',
  34. 'FD': u'IMEI',
  35. 'FE': u'投币金额',
  36. }
  37. @staticmethod
  38. def _parse_status(status):
  39. return WasherBox.STATUS_CODE_INFO.get(status, u"未知状态")
  40. def _send_data(self, funCode, data, cmd=None, timeout=None):
  41. result = MessageSender.send(self.device, cmd or DeviceCmdCode.OPERATE_DEV_SYNC, {
  42. "IMEI": self.device.devNo,
  43. "data": data,
  44. "funCode": funCode
  45. }, timeout = timeout or MQTT_TIMEOUT.NORMAL)
  46. if result["rst"] != 0:
  47. if result['rst'] == -1:
  48. raise ServiceException({'result': 2, 'description': u'洗衣机正在玩命找网络,请稍候再试'})
  49. elif result['rst'] == 1:
  50. raise ServiceException({'result': 2, 'description': u'洗衣机主板连接故障'})
  51. else:
  52. raise ServiceException({'result': 2, 'description': u'系统错误'})
  53. return result
  54. def _start(self, workMode):
  55. result = self._send_data("02", workMode, timeout = MQTT_TIMEOUT.START_DEVICE)
  56. data = result.get("data", "")
  57. if data[8:10] != "03":
  58. status = WasherBox._parse_status(data[8:10])
  59. raise ServiceException({"result": 2, "description": u"启动失败, {}".format(status)})
  60. return result
  61. def _occupy(self, _time):
  62. """
  63. 预约洗衣机 时间不在8-20默认15分钟
  64. :param _time:
  65. :return:
  66. """
  67. if 8 < _time < 15:
  68. raise ServiceException({"result": 2, "description": u"预约时间范围在8-20分钟"})
  69. timeHex = int_to_hex(_time, lens=2)
  70. result = self._send_data("03", timeHex)
  71. data = result.get("data", "")
  72. if data[8:10] != "01":
  73. raise ServiceException({"result": 2, "description": u"预约失败"})
  74. def _cancel_occupy(self):
  75. """
  76. 取消预约
  77. :return:
  78. """
  79. self._send_data("05", "00")
  80. def _query_work_status(self):
  81. result = self._send_data("01", "00")
  82. data = result.get("data", "")
  83. status = WasherBox._parse_status(data[8:10])
  84. leftTime = int(data[10:12], 16)
  85. return {
  86. "status": status,
  87. "leftTime": leftTime,
  88. "statusCode": data[8:10]
  89. }
  90. def start_device(self, package, openId, attachParas):
  91. # 首先校验洗衣机状态
  92. statusInfo = self._query_work_status()
  93. if statusInfo.get("statusCode") != "00":
  94. raise ServiceException({"result": 2, "description": u"洗衣机当前正在工作,请稍后重试"})
  95. # 然后 找套餐
  96. packName = package.get("name")
  97. workMode = WasherBox.WORK_MODE.get(packName)
  98. if not workMode:
  99. raise ServiceException({"result": 2, "description": "当前洗衣机不支持该启动模式,请联系相应经销商解决"})
  100. # 发指令
  101. result = self._start(workMode)
  102. # 写缓存
  103. data = result.get("data", "")
  104. leftTime = int(data[10:12], 16)
  105. devCache = {
  106. "openId": openId,
  107. "washName": packName
  108. }
  109. Device.update_dev_control_cache(self.device.devNo, devCache)
  110. result["finishedTime"] = int(time.time()) + 60 * leftTime
  111. return result
  112. #获取设备的当前状态信息,用于控制面板按钮
  113. def get_device_function_by_key(self, keyName):
  114. if keyName == 'workingStatus':
  115. status_info = self._query_work_status()
  116. leftTime = status_info['leftTime']
  117. code = status_info['statusCode']
  118. if code not in ['03','02']:
  119. leftTime = None
  120. if leftTime > 47:
  121. leftTime = None
  122. return {"workingStatus": status_info['status'],'leftTime': leftTime}
  123. return None
  124. # 控制面板
  125. def press_down_key(self, keyName):
  126. '''
  127. 按钮控制面板
  128. '''
  129. cmd = 02
  130. #获取洗衣机状态
  131. status_info = self._query_work_status()
  132. # 自检
  133. if keyName == u'zjStart':
  134. if status_info['statusCode'] == '03' :
  135. raise ServiceException({"result": 2, "description": u"请停止洗衣机"})
  136. if status_info['statusCode'] == '02' :
  137. raise ServiceException({"result": 2, "description": u"请等待消毒完成"})
  138. mode = self.WORK_MODE[u'自检']
  139. return self._send_data(cmd, mode)
  140. #桶消毒过程点击停止后会进入一个假死的结束状态(04),需要从新发送两次才能正常操作(屏蔽掉,让他自己正常结束)
  141. if status_info['statusCode'] == '02':
  142. raise ServiceException({"result": 2, "description": u"桶消毒正在工作中,请稍等"})
  143. #仅仅用于停止
  144. if keyName == u'stop':
  145. if status_info['statusCode'] == '00':
  146. raise ServiceException({"result": 2, "description": u"洗衣机未启动"})
  147. mode = self.WORK_MODE[u'自检']
  148. return self._send_data(cmd, mode)
  149. #洗衣机不在待机状态
  150. if status_info['statusCode'] != '00':
  151. raise ServiceException({"result": 2, "description": u"洗衣机正在工作中"})
  152. if keyName == u'dtStart':
  153. mode = self.WORK_MODE[u'单脱水']
  154. elif keyName == u'ksStart':
  155. mode = self.WORK_MODE[u'快速洗']
  156. elif keyName == u'bzStart':
  157. mode = self.WORK_MODE[u'标准洗']
  158. elif keyName == u'jqStart':
  159. mode = self.WORK_MODE[u'加强洗']
  160. elif keyName == u'xdStart':
  161. mode = self.WORK_MODE[u'桶消毒']
  162. else:
  163. raise ServiceException({"result": 2, "description": u"参数错误"})
  164. result = self._send_data(cmd, mode)
  165. data = result.get("data", "")
  166. status = WasherBox._parse_status(data[8:10])
  167. if status == u"未知状态":
  168. raise ServiceException({'result': 2, 'description': u'洗衣机出现未知错误,请停止后重试'})
  169. if keyName == 'stop':
  170. Device.update_dev_control_cache(self._device['devNo'], {'status': Const.DEV_WORK_STATUS_IDLE})
  171. else:
  172. Device.update_dev_control_cache(self._device['devNo'], {'status': Const.DEV_WORK_STATUS_WORKING})
  173. return result