123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- # -*- coding: utf-8 -*-
- # !/usr/bin/env python
- import time
- from apps.common.utils import int_to_hex
- from apps.web.constant import DeviceCmdCode, MQTT_TIMEOUT, Const
- from apps.web.core.adapter.base import SmartBox
- from apps.web.core.exceptions import ServiceException
- from apps.web.core.networking import MessageSender
- from apps.web.device.models import Device
- class WasherBox(SmartBox):
- WORK_MODE = {
- u"加强洗": "01", # 工作46分钟
- u"标准洗": "02", # 工作38分钟
- u"快速洗": "03", # 工作22分钟
- u"单脱水": "04", # 工作06分钟
- u"桶消毒": "05", # 工作04分钟
- u"自检": "06" # 工作30秒
- }
- STATUS_CODE_INFO = {
- '00': u'待机中',
- '01': u'预约中',
- '02': u'消毒清洁中',
- '03': u'洗衣工作中',
- '04': u'洗衣机洗涤结束',
- '05': u'洗衣机自检中',
- '06': u'进水超时',
- '07': u'排水超时',
- '08': u'脱水时撞桶',
- '09': u'脱水开盖',
- '0A': u'水位传感器异常',
- '0B': u'溢水报警',
- '0C': u'电机故障',
- '0D': u'通讯故障',
- 'FD': u'IMEI',
- 'FE': u'投币金额',
- }
- @staticmethod
- def _parse_status(status):
- return WasherBox.STATUS_CODE_INFO.get(status, u"未知状态")
- def _send_data(self, funCode, data, cmd=None, timeout=None):
- result = MessageSender.send(self.device, cmd or DeviceCmdCode.OPERATE_DEV_SYNC, {
- "IMEI": self.device.devNo,
- "data": data,
- "funCode": funCode
- }, timeout = timeout or MQTT_TIMEOUT.NORMAL)
- if result["rst"] != 0:
- if result['rst'] == -1:
- raise ServiceException({'result': 2, 'description': u'洗衣机正在玩命找网络,请稍候再试'})
- elif result['rst'] == 1:
- raise ServiceException({'result': 2, 'description': u'洗衣机主板连接故障'})
- else:
- raise ServiceException({'result': 2, 'description': u'系统错误'})
- return result
- def _start(self, workMode):
- result = self._send_data("02", workMode, timeout = MQTT_TIMEOUT.START_DEVICE)
- data = result.get("data", "")
- if data[8:10] != "03":
- status = WasherBox._parse_status(data[8:10])
- raise ServiceException({"result": 2, "description": u"启动失败, {}".format(status)})
- return result
- def _occupy(self, _time):
- """
- 预约洗衣机 时间不在8-20默认15分钟
- :param _time:
- :return:
- """
- if 8 < _time < 15:
- raise ServiceException({"result": 2, "description": u"预约时间范围在8-20分钟"})
- timeHex = int_to_hex(_time, lens=2)
- result = self._send_data("03", timeHex)
- data = result.get("data", "")
- if data[8:10] != "01":
- raise ServiceException({"result": 2, "description": u"预约失败"})
- def _cancel_occupy(self):
- """
- 取消预约
- :return:
- """
- self._send_data("05", "00")
- def _query_work_status(self):
- result = self._send_data("01", "00")
- data = result.get("data", "")
- status = WasherBox._parse_status(data[8:10])
- leftTime = int(data[10:12], 16)
- return {
- "status": status,
- "leftTime": leftTime,
- "statusCode": data[8:10]
- }
- def start_device(self, package, openId, attachParas):
- # 首先校验洗衣机状态
- statusInfo = self._query_work_status()
- if statusInfo.get("statusCode") != "00":
- raise ServiceException({"result": 2, "description": u"洗衣机当前正在工作,请稍后重试"})
- # 然后 找套餐
- packName = package.get("name")
- workMode = WasherBox.WORK_MODE.get(packName)
- if not workMode:
- raise ServiceException({"result": 2, "description": "当前洗衣机不支持该启动模式,请联系相应经销商解决"})
- # 发指令
- result = self._start(workMode)
- # 写缓存
- data = result.get("data", "")
- leftTime = int(data[10:12], 16)
- devCache = {
- "openId": openId,
- "washName": packName
- }
- Device.update_dev_control_cache(self.device.devNo, devCache)
- result["finishedTime"] = int(time.time()) + 60 * leftTime
- return result
- #获取设备的当前状态信息,用于控制面板按钮
- def get_device_function_by_key(self, keyName):
- if keyName == 'workingStatus':
- status_info = self._query_work_status()
- leftTime = status_info['leftTime']
- code = status_info['statusCode']
- if code not in ['03','02']:
- leftTime = None
- if leftTime > 47:
- leftTime = None
- return {"workingStatus": status_info['status'],'leftTime': leftTime}
- return None
- # 控制面板
- def press_down_key(self, keyName):
- '''
- 按钮控制面板
- '''
- cmd = 02
- #获取洗衣机状态
- status_info = self._query_work_status()
- # 自检
- if keyName == u'zjStart':
- if status_info['statusCode'] == '03' :
- raise ServiceException({"result": 2, "description": u"请停止洗衣机"})
- if status_info['statusCode'] == '02' :
- raise ServiceException({"result": 2, "description": u"请等待消毒完成"})
- mode = self.WORK_MODE[u'自检']
- return self._send_data(cmd, mode)
- #桶消毒过程点击停止后会进入一个假死的结束状态(04),需要从新发送两次才能正常操作(屏蔽掉,让他自己正常结束)
- if status_info['statusCode'] == '02':
- raise ServiceException({"result": 2, "description": u"桶消毒正在工作中,请稍等"})
- #仅仅用于停止
- if keyName == u'stop':
- if status_info['statusCode'] == '00':
- raise ServiceException({"result": 2, "description": u"洗衣机未启动"})
- mode = self.WORK_MODE[u'自检']
- return self._send_data(cmd, mode)
- #洗衣机不在待机状态
- if status_info['statusCode'] != '00':
- raise ServiceException({"result": 2, "description": u"洗衣机正在工作中"})
- if keyName == u'dtStart':
- mode = self.WORK_MODE[u'单脱水']
- elif keyName == u'ksStart':
- mode = self.WORK_MODE[u'快速洗']
- elif keyName == u'bzStart':
- mode = self.WORK_MODE[u'标准洗']
- elif keyName == u'jqStart':
- mode = self.WORK_MODE[u'加强洗']
- elif keyName == u'xdStart':
- mode = self.WORK_MODE[u'桶消毒']
- else:
- raise ServiceException({"result": 2, "description": u"参数错误"})
- result = self._send_data(cmd, mode)
- data = result.get("data", "")
- status = WasherBox._parse_status(data[8:10])
- if status == u"未知状态":
- raise ServiceException({'result': 2, 'description': u'洗衣机出现未知错误,请停止后重试'})
- if keyName == 'stop':
- Device.update_dev_control_cache(self._device['devNo'], {'status': Const.DEV_WORK_STATUS_IDLE})
- else:
- Device.update_dev_control_cache(self._device['devNo'], {'status': Const.DEV_WORK_STATUS_WORKING})
- return result
|