# -*- coding: utf-8 -*- # !/usr/bin/env python import datetime import logging from apps.web.constant import DeviceCmdCode, Const, MQTT_TIMEOUT from apps.web.core.adapter.base import SmartBox, fill_2_hexByte, hexbyte_2_bin from apps.web.core.exceptions import ServiceException from apps.web.core.networking import MessageSender from apps.web.device.models import Device logger = logging.getLogger(__name__) class ChargingDLYBox(SmartBox): def __init__(self, device): super(ChargingDLYBox, self).__init__(device) def start_device(self, package, openId, attachParas): if attachParas is None: raise ServiceException({'result': 2, 'description': u'请您选择合适的充电线路、电池类型信息'}) if not attachParas.has_key('chargeIndex'): raise ServiceException({'result': 2, 'description': u'请您选择合适的充电线路'}) port = hex(int(attachParas['chargeIndex'])) hexPort = fill_2_hexByte(port, 2) coins = int(package['coins']) hexCoins = fill_2_hexByte(hex(coins), 2) devInfo = MessageSender.send(device = self.device, cmd = DeviceCmdCode.OPERATE_DEV_SYNC, payload = { 'IMEI': self._device['devNo'], "funCode": '21', 'data': hexCoins + hexPort }, timeout = MQTT_TIMEOUT.START_DEVICE) if devInfo.has_key('rst') and devInfo['rst'] != 0: if devInfo['rst'] == -1: raise ServiceException({'result': 2, 'description': u'充电桩正在玩命找网络,您的金币还在,重试不需要重新付款,建议您试试旁边其他设备,或者稍后再试哦'}) elif devInfo['rst'] == 1: raise ServiceException({'result': 2, 'description': u'充电桩繁忙,无响应,您的金币还在,请试试其他线路,或者稍后再试哦'}) data = devInfo['data'][6::] if data[20:22] == '01': # 表示成功 pass else: raise ServiceException({'result': 2, 'description': u'启动充电失败,请重试看能否解决'}) power = int(data[0:4], 16) needTime = int(data[4:8], 16) port = int(data[18:20], 16) Device.update_dev_control_cache(self._device['devNo'], {str(port): {'startTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), 'power': power, 'coins': float(coins), 'needTime': needTime, 'isStart': True, 'openId': openId, 'refunded': False, 'vCardId': self._vcard_id}}) return devInfo def active_deactive_port(self, port, active): if not active: self.stop_port(port) devInfo = Device.get_dev_control_cache(self._device['devNo']) portCtrInfo = devInfo.get(str(port), {}) portCtrInfo.update({'isStart': False, 'status': Const.DEV_WORK_STATUS_IDLE, 'needTime': 0, 'leftTime': 0, 'endTime': datetime.datetime.now().strftime(Const.DATETIME_FMT)}) newValue = {str(port): portCtrInfo} Device.update_dev_control_cache(self._device['devNo'], newValue) else: raise ServiceException({'result': 2, 'description': u'此设备不支持直接启动端口'}) def stop_port(self, port): devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], "funCode": '22', 'data': fill_2_hexByte(hex(int(port)), 2)}) if devInfo.has_key('rst') and devInfo['rst'] != 0: if devInfo['rst'] == -1: raise ServiceException( {'result': 2, 'description': u'充电桩正在玩命找网络,请您稍候再试'}) elif devInfo['rst'] == 1: raise ServiceException( {'result': 2, 'description': u'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'}) data = devInfo['data'][6::] leftTime = int(data[0:4], 16) port = int(data[2:4], 16) return {'leftTime': leftTime, 'port': port} def get_port_status(self, force = False): devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], "funCode": '23', 'data': ''}) if devInfo.has_key('rst') and devInfo['rst'] != 0: if devInfo['rst'] == -1: raise ServiceException( {'result': 2, 'description': u'充电桩正在玩命找网络,请您稍候再试'}) elif devInfo['rst'] == 1: raise ServiceException( {'result': 2, 'description': u'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'}) data = devInfo['data'][6::] binStatus = hexbyte_2_bin(data[0:4]) result = {} for ii in range(10): status = Const.DEV_WORK_STATUS_IDLE if binStatus[ii] == '0' else Const.DEV_WORK_STATUS_WORKING result[str(ii)] = {'status': status} allPorts, usedPorts, usePorts = self.get_port_static_info(result) Device.update_dev_control_cache(self._device['devNo'], {'allPorts': allPorts, 'usedPorts': usedPorts, 'usePorts': usePorts}) return result def analyze_event_data(self, data): cmdCode = data[4:6] if cmdCode == '12': data = data[6::] leftTime = int(data[0:4], 16) port = int(data[4:6], 16) finishType = int(data[6:8], 16) reason = '' status = Const.DEV_WORK_STATUS_IDLE if finishType == 3: status = Const.DEV_WORK_STATUS_FAULT reason = u'异常结束' elif finishType == 2: reason = u'充满结束' elif finishType == 1: reason = u'正常结束' return {'status': status, 'statusInfo': reason, 'cmdCode': '12', 'leftTime': leftTime, 'port': port, 'reason': reason} return None