# -*- coding: utf-8 -*- # !/usr/bin/env python import binascii import datetime import logging import time from django.core.cache import caches from apilib.utils_datetime import timestamp_to_dt, to_datetime from apps.web.constant import Const, DeviceCmdCode, MQTT_TIMEOUT from apps.web.core.adapter.base import SmartBox, fill_2_hexByte, reverse_hex from apps.web.core.exceptions import ServiceException from apps.web.core.networking import MessageSender from apps.web.device.models import Device from apps.web.user.models import MyUser, Card from bson import ObjectId logger = logging.getLogger(__name__) class ChargingHongZhuoBox(SmartBox): TYPE_MAP = { "01": "投币扫码启动", "02": "刷卡启动", "03": "远程启动", "04": "其他启动方式" } def __init__(self, device): super(ChargingHongZhuoBox, self).__init__(device) def change_4_data(self, data): return data[2:4] + data[0:2] def get_port_status_from_dev(self): devInfo = MessageSender.send(self.device, self.make_random_cmdcode(), {'IMEI': self._device['devNo'], "funCode": '0F', 'data': '00'}) 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'][12::] if data[0:2] == '01': # 表示成功 pass else: raise ServiceException({'result': 2, 'description': u'获取统计数据失败,请重试看能否解决'}) result = {} portNum = int(data[2:4], 16) portData = data[4::] ii = 0 while ii < portNum: port = int(portData[ii * 4:ii * 4 + 2], 16) statusTemp = portData[ii * 4 + 2:ii * 4 + 4] if statusTemp == '01': status = {'status': Const.DEV_WORK_STATUS_IDLE} elif statusTemp == '02': status = {'status': Const.DEV_WORK_STATUS_WORKING} elif statusTemp == '03': status = {'status': Const.DEV_WORK_STATUS_FORBIDDEN} elif statusTemp == '04': status = {'status': Const.DEV_WORK_STATUS_FAULT} else: status = {'status': Const.DEV_WORK_STATUS_FAULT} ii += 1 result[str(port)] = status allPorts, usedPorts, usePorts = self.get_port_static_info(result) Device.update_dev_control_cache(self._device['devNo'], {'allPorts': allPorts, 'usedPorts': usedPorts, 'usePorts': usePorts}) # 这里存在多线程更新缓存的场景,可能性比较低,但是必须先取出来,然后逐个更新状态,然后再记录缓存 ctrInfo = Device.get_dev_control_cache(self._device['devNo']) for strPort, info in result.items(): if ctrInfo.has_key(strPort): ctrInfo[strPort].update({'status': info['status']}) else: ctrInfo[strPort] = info Device.update_dev_control_cache(self._device['devNo'], ctrInfo) return result def get_port_status(self, force = False): if force: return self.get_port_status_from_dev() ctrInfo = Device.get_dev_control_cache(self._device['devNo']) statusDict = {} if not ctrInfo.has_key('allPorts'): self.get_port_status_from_dev() ctrInfo = Device.get_dev_control_cache(self._device['devNo']) allPorts = ctrInfo.get('allPorts', 10) for ii in range(allPorts): tempDict = ctrInfo.get(str(ii + 1), {}) if tempDict.has_key('status'): statusDict[str(ii + 1)] = {'status': tempDict.get('status')} elif tempDict.has_key('isStart'): if tempDict['isStart']: statusDict[str(ii + 1)] = {'status': Const.DEV_WORK_STATUS_WORKING} else: statusDict[str(ii + 1)] = {'status': Const.DEV_WORK_STATUS_IDLE} else: statusDict[str(ii + 1)] = {'status': Const.DEV_WORK_STATUS_IDLE} allPorts, usedPorts, usePorts = self.get_port_static_info(statusDict) Device.update_dev_control_cache(self._device['devNo'], {'allPorts': allPorts, 'usedPorts': usedPorts, 'usePorts': usePorts}) return statusDict 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'请您选择合适的充电线路'}) dev = Device.objects.get(devNo=self._device['devNo']) mode = dev.otherConf.get('workMode', 'time') if mode == 'time': mode = '00' else: mode = '01' price = float(package['price']) port = hex(int(attachParas['chargeIndex'])) hexPort = fill_2_hexByte(port, 2) coins = int(package['coins']) hexCoins = fill_2_hexByte(hex(coins * 100)) # 注意单位是分 needElec = coins hexElec = fill_2_hexByte(hex(needElec * 100)) unit = package.get('unit', u'分钟') if unit in [u'分钟', u'小时', u'天']: billingType = 'time' needTime = int(package['time']) if unit == u'小时': needTime = int(package['time']) * 60 elif unit == u'天': needTime = int(package['time']) * 1440 hexTime = fill_2_hexByte(hex(needTime)) elif unit == u'度' or mode == '02': billingType = 'elec' devConf = caches['devmgr'].get('settingConf_%s' % (self._device['devNo'])) if devConf is None: conf = self.get_dev_setting() caches['devmgr'].set('settingConf_%s' % (self._device['devNo']), conf, 24 * 3600) elecFee = conf['elecFee'] else: elecFee = devConf['elecFee'] needElec = round((package['time']), 2) needElec = round(min(float(coins / elecFee), needElec), 2) hexElec = fill_2_hexByte(hex(int(needElec * 100)), 4) needTime = 12 * 60 hexTime = fill_2_hexByte(hex(needTime)) else: billingType = 'elec' devConf = caches['devmgr'].get('settingConf_%s' % (self._device['devNo'])) if devConf is None: conf = self.get_dev_setting() caches['devmgr'].set('settingConf_%s' % (self._device['devNo']), conf, 24 * 3600) elecFee = conf['elecFee'] else: elecFee = devConf['elecFee'] needElec = round((package['time']), 2) needElec = round(min(float(coins / elecFee), needElec), 2) hexElec = fill_2_hexByte(hex(int(needElec * 100)), 4) needTime = 12 * 60 hexTime = fill_2_hexByte(hex(needTime)) hexCoins = self.change_4_data(hexCoins) hexTime = self.change_4_data(hexTime) hexElec = self.change_4_data(hexElec) devInfo = MessageSender.send(device = self.device, cmd = DeviceCmdCode.OPERATE_DEV_SYNC, payload = { 'IMEI': self._device['devNo'], "funCode": '14', 'data': mode + hexPort + hexCoins + hexTime + hexElec }, 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'][12::] if data[0:2] == '01': # 表示成功 pass else: raise ServiceException({'result': 2, 'description': u'获取端口数据失败,请重试看能否解决'}) usePort = int(attachParas['chargeIndex']) result = data[4:6] if result == '01': # 成功 pass elif result == '0B': newValue = {str(usePort): {'status': Const.DEV_WORK_STATUS_FAULT, 'statusInfo': u'充电站故障'}} Device.update_dev_control_cache(self._device['devNo'], newValue) raise ServiceException({'result': 2, 'description': u'充电站故障'}) elif result == '0C': newValue = {str(usePort): {'status': Const.DEV_WORK_STATUS_WORKING, 'statusInfo': u''}} Device.update_dev_control_cache(self._device['devNo'], newValue) raise ServiceException({'result': 2, 'description': u'该端口正在使用中'}) start_timestamp = int(time.time()) devInfo['finishedTime'] = start_timestamp + needTime * 60 portDict = { 'startTime': timestamp_to_dt(start_timestamp).strftime('%Y-%m-%d %H:%M:%S'), 'status': Const.DEV_WORK_STATUS_WORKING, 'finishedTime': devInfo['finishedTime'], 'coins': float(coins), 'isStart': True, 'price': price, 'openId': openId, 'refunded': False, 'needTime': needTime, 'billingType': billingType, 'vCardId': self._vcard_id } if attachParas.has_key('orderNo'): portDict.update({'orderNo': attachParas['orderNo']}) Device.update_dev_control_cache(self._device['devNo'], {str(usePort): portDict}) return devInfo def get_port_info(self, line): # 20220225 新增版本 data = fill_2_hexByte(hex(int(line)), 2) devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], "funCode": '15', 'data': 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'][12::] if data[0:2] == '01': # 表示成功 pass else: raise ServiceException({'result': 2, 'description': u'获取统计数据失败,请重试看能否解决'}) mode = data[2:4] if mode == '01': usedTime = int(self.change_4_data(data[6:10]), 16) power = round(int(self.change_4_data(data[10:14]), 16) * 0.1 ,2) elec = str(round(int(self.change_4_data(data[14:18]), 16) * 0.01, 2)) leftMoney = round(int(self.change_4_data(data[18:22]), 16) * 0.01, 2) STA = '0' elif mode == '02': usedTime = int(self.change_4_data(data[6:10]), 16) power = str(round(int(binascii.hexlify(binascii.unhexlify(data[10:18])[::-1]), 16) * 0.1,2)) elec = str(round(int(self.change_4_data(data[18:22]), 16) * 0.01, 2)) leftMoney = round(int(self.change_4_data(data[22:26]), 16) * 0.01, 2) STA = str(int(binascii.hexlify(binascii.unhexlify(data[26:28])[::-1]), 16)) return {'port': line, 'usedTime': usedTime, 'power': power, 'usedElec': elec, 'leftMoney': leftMoney,'STA':STA} def active_deactive_port(self, port, active): if not active: self.stop_charging_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,'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(self, port = None): infoDict = self.stop_charging_port(port) infoDict['remainder_time'] = infoDict['leftTime'] return infoDict def stop_charging_port(self, port): portStr = fill_2_hexByte(hex(int(port)), 2) devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], "funCode": '0D', 'data': portStr + '00'}) 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'][12::] if data[0:2] == '01': # 表示成功 pass else: raise ServiceException({'result': 2, 'description': u'操作端口失败,请重试看能否解决'}) port = int(data[4:6], 16) money = int(self.change_4_data(data[6:10]), 16) leftTime = int(self.change_4_data(data[10:14]), 16) elec = int(self.change_4_data(data[14:18]), 16) return {'port': port, 'money': money, 'leftTime': leftTime, 'elec': elec} def set_dev_setting(self,setConf): data = '' data += self.change_4_data(fill_2_hexByte(hex(int(setConf['coinTime'])), 4)) data += self.change_4_data(fill_2_hexByte(hex(int(setConf['cardTime'])), 4)) data += self.change_4_data(fill_2_hexByte(hex(int(setConf['elecFee'])), 4)) data += self.change_4_data(fill_2_hexByte(hex(int(setConf['cardFee'])), 4)) data += self.change_4_data(fill_2_hexByte(hex(int(setConf['level1Power'])), 4)) data += self.change_4_data(fill_2_hexByte(hex(int(setConf['level2Power'])), 4)) data += self.change_4_data(fill_2_hexByte(hex(int(setConf['level3Power'])), 4)) data += self.change_4_data(fill_2_hexByte(hex(int(setConf['level4Power'])), 4)) data += self.change_4_data(fill_2_hexByte(hex(int(setConf['level1Time'])), 4)) data += self.change_4_data(fill_2_hexByte(hex(int(setConf['level2Time'])), 4)) data += self.change_4_data(fill_2_hexByte(hex(int(setConf['level3Time'])), 4)) data += self.change_4_data(fill_2_hexByte(hex(int(setConf['level4Time'])), 4)) data += fill_2_hexByte(hex(int(setConf['refundMoney'])), 2) data += fill_2_hexByte(hex(int(setConf['fullPowerStop'])), 2) data += self.change_4_data(fill_2_hexByte(hex(int(setConf['minPowerDetection'])), 4)) data += self.change_4_data(fill_2_hexByte(hex(int(setConf['fullDelayTime'])), 4)) data += fill_2_hexByte(hex(int(setConf['boardDisplay'])), 2) devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], "funCode": '18', 'data': 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'][12::] if data[0:2] == '01':#表示成功 otherConf = self._device.get("otherConf", dict()) otherConf.update( { "workMode": setConf['workMode'], "refundMoney": setConf['refundMoney'] } ) Device.objects.filter(devNo=self._device["devNo"]).update(otherConf=otherConf) Device.invalid_device_cache(self._device["devNo"]) # dev = Device.objects.get(devNo=self._device['devNo']) # dev.otherConf.update({'workMode': setConf['workMode']}) # dev.save() else: raise ServiceException({'result': 2, 'description': u'操作端口失败,请重试看能否解决'}) def get_dev_setting(self): devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], "funCode": '1E', 'data': '00'}) 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'][12::] if data[0:2] == '01': # 表示成功 pass else: raise ServiceException({'result': 2, 'description': u'操作端口失败,请重试看能否解决'}) confData = data[2:-2] coinTime = int(self.change_4_data(confData[0:4]), 16) cardTime = int(self.change_4_data(confData[4:8]), 16) elecFee = int(self.change_4_data(confData[8:12]), 16) cardFee = int(self.change_4_data(confData[12:16]), 16) level1Power = int(self.change_4_data(confData[16:20]), 16) level2Power = int(self.change_4_data(confData[20:24]), 16) level3Power = int(self.change_4_data(confData[24:28]), 16) level4Power = int(self.change_4_data(confData[28:32]), 16) level1Time = int(self.change_4_data(confData[32:36]), 16) level2Time = int(self.change_4_data(confData[36:40]), 16) level3Time = int(self.change_4_data(confData[40:44]), 16) level4Time = int(self.change_4_data(confData[44:48]), 16) refundMoney = int(confData[48:50], 16) fullPowerStop = int(confData[50:52], 16) minPowerDetection = int(self.change_4_data(confData[52:56]), 16) fullDelayTime = int(self.change_4_data(confData[56:60]), 16) boardDisplay = int(confData[60:62], 16) dev = Device.objects.get(devNo=self._device['devNo']) workMode = dev.otherConf.get('workMode', 'time') data={ 'coinTime': coinTime, 'cardTime': cardTime, 'elecFee': elecFee, 'cardFee': cardFee, 'level1Power': level1Power, 'level2Power': level2Power, 'level3Power': level3Power, 'level4Power': level4Power, 'level1Time': level1Time, 'level2Time': level2Time, 'level3Time': level3Time, 'level4Time': level4Time, 'refundMoney': refundMoney, 'fullPowerStop': fullPowerStop, 'minPowerDetection': minPowerDetection, 'fullDelayTime': fullDelayTime, 'boardDisplay': boardDisplay, 'workMode': workMode } try: elecNum = self.remote_meter_reading() data.update(elecNum) except: pass return data def set_device_function_param(self, request, lastSetConf): coinTime = request.POST.get('coinTime', None) cardTime = request.POST.get('cardTime', None) elecFee = request.POST.get('elecFee', None) cardFee = request.POST.get('cardFee', None) level1Power = request.POST.get('level1Power', None) level2Power = request.POST.get('level2Power', None) level3Power = request.POST.get('level3Power', None) level4Power = request.POST.get('level4Power', None) level1Time = request.POST.get('level1Time', None) level2Time = request.POST.get('level2Time', None) level3Time = request.POST.get('level3Time', None) level4Time = request.POST.get('level4Time', None) refundMoney = request.POST.get('refundMoney', None) fullPowerStop = request.POST.get('fullPowerStop', None) minPowerDetection = request.POST.get('minPowerDetection', None) fullDelayTime = request.POST.get('fullDelayTime', None) boardDisplay = request.POST.get('boardDisplay', None) workMode = request.POST.get('workMode', None) if coinTime: lastSetConf.update({'coinTime': int(coinTime)}) if cardTime: lastSetConf.update({'cardTime': int(cardTime)}) if elecFee: lastSetConf.update({'elecFee': int(elecFee)}) if cardFee: lastSetConf.update({'cardFee': int(cardFee)}) if level1Power: lastSetConf.update({'level1Power': int(level1Power)}) if level2Power: lastSetConf.update({'level2Power': int(level2Power)}) if level3Power: lastSetConf.update({'level3Power': int(level3Power)}) if level4Power: lastSetConf.update({'level4Power': int(level4Power)}) if level1Time: lastSetConf.update({'level1Time': int(level1Time)}) if level2Time: lastSetConf.update({'level2Time': int(level2Time)}) if level3Time: lastSetConf.update({'level3Time': int(level3Time)}) if level4Time: lastSetConf.update({'level4Time': int(level4Time)}) if refundMoney: lastSetConf.update({'refundMoney': int(refundMoney)}) if fullPowerStop: lastSetConf.update({'fullPowerStop': int(fullPowerStop)}) if minPowerDetection: lastSetConf.update({'minPowerDetection': int(minPowerDetection)}) if fullDelayTime: lastSetConf.update({'fullDelayTime': int(fullDelayTime)}) if boardDisplay: lastSetConf.update({'boardDisplay': int(boardDisplay)}) if workMode: lastSetConf.update({'workMode': workMode}) self.set_dev_setting(lastSetConf) def analyze_event_data(self, data): cmdCode = data[10:12] if cmdCode == '16': mode = int(data[14:16], 16) port = int(data[16:18], 16) reason = data[18:20] leftMoney = round(int(self.change_4_data(data[20:24]), 16) * 0.01, 2) duration = int(self.change_4_data(data[24:28]), 16) elec = round(int(self.change_4_data(data[28:32]), 16) * 0.01, 2) if reason == '00': desc = u'购买的充电时间用完了。' elif reason == '01': desc = u'可能是插头被拔掉,或者电瓶已经充满。系统判断为异常断电,由于电瓶车充电器种类繁多,可能存在误差。如有问题,请您及时联系商家协助解决问题并恢复充电。' elif reason == '02': desc = u'恭喜您!电池已经充满电!' elif reason == '03': desc = u'警告!您的电池超功率,已经停止充电,为了公共安全,不建议您在该充电桩充电!提醒您,为了安全大功率的电池不要放入楼道、室内等位置充电哦' elif reason == '04': desc = u'远程断电。' elif reason == '05': desc = u'设备或端口出现问题,为了安全起见,被迫停止工作。建议您根据已经充电的时间评估是否需要到现场换到其他端口充电。' else: desc = u'电池没有充满!原因未知。' return { 'status': Const.DEV_WORK_STATUS_IDLE, 'cmdCode': cmdCode, 'mode': mode, 'port': port, 'leftMoney': leftMoney, 'duration': duration, 'elec': elec, 'reason': desc } # ID卡刷卡指令上传 elif cmdCode == "10": result = data[12: 14] if result != "01": logger.info("card event result is {}".format(result)) return portStr = str(int(data[14: 16])) cardNo = str(int(reverse_hex(data[16: 24]), 16)) preFee = int(data[24: 26], 16) oper = data[26: 28] return { "cardNo": cardNo, "preFee": preFee, "oper": oper, "cmdCode": cmdCode, "portStr": portStr } elif cmdCode == "20": mode = data[14: 16] portStr = str(int(data[16: 18], 16)) money = str(int(reverse_hex(data[18: 22]), 16) / 100.0) # 单位是分 chargeTime = str(int(reverse_hex(data[22: 26]), 16)) # 单位是分钟 elec = str(int(reverse_hex(data[26: 30]), 16) / 100.0) # 单位是0.01kwh typeCode = data[30: 32] chargeType = self.TYPE_MAP.get(typeCode, "") return { "mode": mode, "portStr": portStr, "money": money, "chargeTime": chargeTime, "elec": elec, "chargeType": chargeType, "typeCode": typeCode, "cmdCode": cmdCode } else: logger.info("error cmd code! cmd is {}".format(cmdCode)) def response_use_card(self, res, port, balance): resHex = fill_2_hexByte(hex(int(res)), 2) portHex = fill_2_hexByte(hex(int(port)), 2) balanceHex = fill_2_hexByte(hex(int(balance)), 4, reverse=True) data = resHex + portHex + balanceHex MessageSender.send(device = self.device, cmd = DeviceCmdCode.OPERATE_DEV_NO_RESPONSE, payload = { "IMEI": self._device["devNo"], "funCode": "10", "data": data }) def get_device_function_by_key(self, keyName): devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], "funCode": '30', 'data': '00'}) 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'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'}) devInfo1 = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], "funCode": '32', 'data': '00'}) if devInfo1.has_key('rst') and devInfo['rst'] != 0: if devInfo1['rst'] == -1: raise ServiceException( {'result': 2, 'description': u'充电桩正在玩命找网络,请您稍候再试'}) elif devInfo1['rst'] == 1: raise ServiceException( {'result': 2, 'description': u'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'}) data = devInfo['data'][12::] data1 = devInfo1['data'][12::] if data[0:2] == '01' and data1[0:2] == '01': # 表示成功 pass else: raise ServiceException({'result': 2, 'description': u'操作端口失败,请重试看能否解决'}) fileNameStr = data[2:10] fileName = chr(int(fileNameStr[0:2], 16)) + chr(int(fileNameStr[2:4], 16)) + chr(int(fileNameStr[4:6], 16)) + chr(int(fileNameStr[6:8], 16)) boardVersion1 = int(data1[2:4]) boardVersion2 = int(data1[4:6]) boardVersion = str(boardVersion1) + '.' + str(boardVersion2) return {'fileName': fileName + '.bin' + '(当前主板版本为: v' + boardVersion + ')'} def set_device_function(self, request, lastSetConf): host_url = 'http://www.sdhongzhuo.com/down/bin_hz/' fileName = lastSetConf.get('fileName', '') if fileName == '': raise ServiceException({'result': 2, 'description': u'升级文件不存在, 请重新获取'}) fileNameStr = fileName[0:fileName.find('(')] mcu_url = host_url + fileNameStr devInfo = MessageSender.send(self.device, DeviceCmdCode.SET_DEVINFO, {'IMEI': self._device['devNo'], 'mcu_set': {'mcu_url': mcu_url}}) 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'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'}) @property def isHaveStopEvent(self): return True # 20220225新增,获取时间34,远程抄表35 def remote_meter_reading(self): devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], "funCode": '35', 'data': '01'}) if devInfo.has_key('rst') and devInfo['rst'] == -1: raise ServiceException( {'result': 2, 'description': u'充电桩正在玩命找网络,请您稍候再试'}) elif devInfo['rst'] == 1: raise ServiceException( {'result': 2, 'description': u'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'}) elif devInfo['rst'] == 102: return {'elecNum' : None} data = devInfo['data'][12::] if data[0:2] == '01': # 表示成功 pass else: raise ServiceException({'result': 2, 'description': u'获取统计数据失败,请重试看能否解决'}) elec = float(int(binascii.hexlify(binascii.unhexlify(data[2:10])[::-1]), 16)) * 0.01 return {'elecNum' : elec} def format_port_using_detail(self, detailDict): portData = {} usedTime = detailDict.get('usedTime',None) portData['usedTime'] = usedTime power = detailDict.get('power',None) portData['powerNow'] = power if detailDict.has_key('needTime'): detailDict.pop('needTime',None) if detailDict.has_key('openId'): user = MyUser.objects(openId=detailDict['openId'], groupId=self.device.groupId).first() if user: portData['nickName'] = user.nickname if detailDict.has_key('cardId'): if not detailDict.has_key('consumeType'): portData['consumeType'] = 'card' card = Card.objects.get(id=ObjectId(detailDict['cardId'])) if card.cardName: portData['cardName'] = card.cardName portData['cardNo'] = card.cardNo # 注意,如果是IC卡,不支持余额回收,这里也不要显示出来 if card.cardType == 'IC' and portData.has_key('leftMoney'): portData.pop('leftMoney') elif detailDict.has_key('openId') and (not detailDict.has_key('consumeType')): if detailDict.get('vCardId'): portData['consumeType'] = 'mobile_vcard' else: portData['consumeType'] = 'mobile' elif detailDict.has_key('consumeType') and detailDict['consumeType'] == 'coin': portData['consumeType'] = 'coin' # 硬币的都无法退费 if portData.has_key('leftMoney'): portData.pop('leftMoney') detailDict.update(portData) for k, v in detailDict.items(): if v < 0: detailDict.pop(k) # 因为前台显示的开始时间如果带年,就显示不下,这里做个切割 if detailDict.has_key('startTime') and detailDict['startTime'].count('-') == 2: detailDict['startTime'] = to_datetime(detailDict['startTime']).strftime('%m-%d %H:%M:%S') return detailDict