123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- # -*- coding: utf-8 -*-
- # !/usr/bin/env python
- import datetime
- import logging
- import time
- import simplejson as json
- from apilib.utils_string import cn
- from apps.web.constant import DeviceErrorCodeDesc, ErrorCode, DeviceOnlineStatus, DeviceCmdCode, Const, FAULT_CODE, \
- MQTT_TIMEOUT
- from apps.web.core.adapter.base import SmartBox
- from apps.web.core.exceptions import ServiceException, DeviceNetworkTimeoutError
- from apps.web.core.networking import MessageSender
- from apps.web.device.models import Device
- from apps.web.core.device_define import PackageDict
- logger = logging.getLogger(__name__)
- class MySmartBox(SmartBox):
- def __init__(self, device):
- super(MySmartBox, self).__init__(device)
- def check_dev_status(self, attachParas = None):
- """
- 如果超过两个心跳周期没有报心跳,并且最后一次更新时间在2个小时内,需要从设备获取状态
- 否则以缓存状态为准。
- :param attachParas:
- :return:
- """
- if not self.device.need_fetch_online:
- raise ServiceException(
- {'result': 2, 'description': DeviceErrorCodeDesc.get(ErrorCode.DEVICE_CONN_FAIL)})
- if self.device.online == DeviceOnlineStatus.DEV_STATUS_ONLINE:
- retry = 3
- timeout = 12
- else:
- retry = 2
- timeout = 10
- operation_result = MessageSender.send(device = self.device, cmd = DeviceCmdCode.GET_DEVINFO, payload = {
- 'IMEI': self.device.devNo,
- 'fields': ['signal', 'pulse_open', 'board_volt', 'board_valid']
- }, timeout = timeout, retry = retry)
- if operation_result['rst'] != ErrorCode.DEVICE_SUCCESS:
- if operation_result['rst'] == ErrorCode.DEVICE_CONN_FAIL:
- raise ServiceException(
- {
- 'result': 2,
- 'description': DeviceErrorCodeDesc.get(ErrorCode.DEVICE_CONN_CHECK_FAIL)
- })
- else:
- raise ServiceException(
- {
- 'result': 2,
- 'description': u'检测设备状态失败({})'.format(operation_result['rst'])
- })
- else:
- if 'pulse_open' in operation_result and (not operation_result['pulse_open']):
- raise ServiceException(
- {
- 'result': 2,
- 'description': u'检测设备状态失败({})'.format(ErrorCode.PULSE_IS_CLOSE)
- })
- if 'board_valid' in operation_result and 'board_volt' in operation_result and operation_result[
- 'board_valid'] != 2:
- if operation_result['board_volt'] != operation_result['board_valid']:
- raise ServiceException(
- {
- 'result': 2,
- 'description': u'当前设备正在工作,请稍后再试'
- })
- def test(self, coins):
- now_time = datetime.datetime.now()
- return MessageSender.send(device = self.device, cmd = DeviceCmdCode.PAY_MONEY, payload = {
- 't': int(time.mktime(now_time.timetuple())),
- 'duration': coins * 60,
- 'app_pay': coins
- })
- def start_device(self, package, openId, attachParas):
- pay_count = int(package['coins'])
- result = MessageSender.net_pay(self.device, pay_count, timeout = MQTT_TIMEOUT.START_DEVICE)
- if result['rst'] == ErrorCode.DEVICE_CONN_FAIL:
- raise DeviceNetworkTimeoutError()
- elif result['rst'] != ErrorCode.DEVICE_SUCCESS:
- logger.debug('MySmartBox() failed to start, result was=%s' % (json.dumps(result),))
- raise ServiceException({'result': 2, 'description': DeviceErrorCodeDesc.get(result['rst'])})
- try:
- duration = self.get_duration(package)
- result['finishedTime'] = (int(time.time()) + duration)
- Device.update_dev_control_cache(self._device['devNo'],
- {
- 'status': Const.DEV_WORK_STATUS_WORKING,
- 'finishedTime': result['finishedTime']
- })
- except Exception as e:
- logger.exception('error = %s' % e)
- return result
- def start_device_realiable(self, order):
- try:
- now_time = datetime.datetime.now()
- result = MessageSender.send(device = self.device, cmd = DeviceCmdCode.PAY_MONEY, payload = {
- 't': int(time.mktime(now_time.timetuple())),
- 'duration': PackageDict(order.package).estimated_duraion,
- 'order_id': order.orderNo,
- 'order_type': 'pulse_start',
- 'app_pay': int(order.package['coins'])
- })
- if result['rst'] == ErrorCode.DEVICE_CONN_FAIL:
- result.update({
- 'fts': int(time.time()),
- 'order_type': 'com_start',
- 'order_id': order.orderNo
- })
- except ServiceException as e:
- logger.exception(e)
- return {
- 'rst': ErrorCode.EXCEPTION,
- 'fts': int(time.time()),
- 'errorDesc': cn(e.result.get('description')),
- 'order_type': 'com_start',
- 'order_id': order.orderNo
- }
- except Exception as e:
- logger.exception(e)
- return {
- 'rst': ErrorCode.EXCEPTION,
- 'fts': int(time.time()),
- 'order_type': 'com_start',
- 'order_id': order.orderNo
- }
- def get_total_coin(self):
- result = MessageSender.send(self.device, DeviceCmdCode.GET_DEVINFO,
- {'cmd': DeviceCmdCode.GET_DEVINFO, 'IMEI': self._device['devNo']})
- if result['rst'] != ErrorCode.DEVICE_SUCCESS:
- logger.debug('MySmartBox() failed to get total coin, result was=%s' % (json.dumps(result),))
- description = u'当前设备信号弱没有响应,请您稍后重试。'
- raise ServiceException({'result': 2, 'description': description})
- if not result.has_key('total_coin'):
- raise ServiceException({'result': 2, 'description': u'当前设备暂时不支持获取总的硬币数目,待版本自动升级后,会支持'})
- return result['total_coin']
- # 基类函数,检查告警状态,只能做一个简单的检查,设备是否在线
- def check_alarm(self, alarm):
- if alarm.faultCode == FAULT_CODE.OFFLINE:
- dev_info = MessageSender.send(device = self.device, cmd = DeviceCmdCode.GET_DEVINFO,
- payload = {'IMEI': self.device.devNo, 'fields': []},
- timeout = MQTT_TIMEOUT.SHORT)
- if dev_info['rst'] == 0:
- return u'设备状态检查在线,网络通畅,网络可能出现闪断'
- else:
- raise ServiceException({'result': 2, 'description': u'设备玩命也无法找到网络,设备可能不在线'})
- else:
- return u'无法检查该设备的告警状态,建议您用其他方式确认此告警是否正常'
- def set_device_function_param(self, request, lastSetConf):
- cardPrice = request.POST.get("cardPrice")
- eachCoin = request.POST.get("eachCoin")
- # 服务器参数
- if cardPrice and eachCoin:
- if not str(cardPrice).isdigit():
- raise ServiceException({"result": 2, "description": "刷卡单价必须为整数"})
- if not str(eachCoin).isdigit():
- raise ServiceException({"result": 2, "description": "脉冲次数必须为整数"})
- cardPrice = int(cardPrice)
- packages = self.device['washConfig']
- packages = sorted(packages.values(), key = lambda x: x["coins"])
- min_coin = int(packages[0].get("coins"))
- max_coin = int(packages[-1].get("coins"))
- eachCoin = int(eachCoin)
- if min_coin > eachCoin or max_coin < eachCoin:
- raise ServiceException({"result": 2, "description": "脉冲次数不能超过套餐投币数范围"})
- dic = {
- 'cardPrice': cardPrice,
- 'eachCoin': eachCoin
- }
- dev = Device.objects.get(devNo = self.device.devNo)
- dev.otherConf.update(dic)
- dev.save()
- dev.invalid_device_cache(dev.devNo)
- def get_dev_setting(self):
- data = {}
- # 服务器参数
- if self.device['otherConf'] and self.device['otherConf'].get('cardPrice') and self.device['otherConf'].get(
- 'eachCoin'):
- data['cardPrice'] = self.device['otherConf']['cardPrice']
- data['eachCoin'] = self.device['otherConf']['eachCoin']
- return data
|