# -*- coding: utf-8 -*- # !/usr/bin/env python import copy import datetime import time from decimal import Decimal from apilib.utils_AES import EncryptDate from apilib.utils_datetime import to_datetime from apps.web.constant import DeviceCmdCode, Const, FAULT_CODE, ErrorCode, CONSUMETYPE from apps.web.core.adapter.weifuleCommon import PolicyBase from apps.web.core.exceptions import ServiceException from apps.web.core.networking import MessageSender from apps.web.device.models import Device, DeviceType from apps.web.user.models import ConsumeRecord, Card, ServiceProgress cardKey = 'FR4e1OFCnDdrYA7u' class PolicyWEIFULEBox(PolicyBase): def __init__(self, device): super(PolicyWEIFULEBox, self).__init__(device) def translate_funcode(self, fun_code): fun_codeDict = { '01': u'查询所有端口状态', '02': u'查询端口详细信息', '03': u'上报投币充电事件', '04': u'上报刷卡事件', '05': u'上报充电结束事件', '06': u'远程停止充电', '07': u'远程启动充电', '08': u'查询投币总额', '09': u'清除投币总数', '0A': u'查询订单信息', } return fun_codeDict.get(fun_code, '') def translate_event_cmdcode(self, cmdCode): cmdDict = { } return cmdDict.get(cmdCode, '') def test(self, coins): data = {'fun_code': 0x07, 'order_id': '1111', 'coins': coins, 'port': 1, 'time': 60} devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], 'data': data}) return devInfo def check_feedback_result(self, devInfo): if not devInfo.has_key('rst'): raise ServiceException({'result': 2, 'description': u'报文异常'}) if devInfo['rst'] == -1: raise ServiceException({'result': 2, 'description': u'充电桩正在玩命找网络,请您稍候再试'}) if devInfo['rst'] == 1: raise ServiceException({'result': 2, 'description': u'串口通讯失败,您稍候再试,或者联系客服'}) if devInfo['rst'] == 2: raise ServiceException({'result': 2, 'description': u'端口被禁用'}) if devInfo['rst'] == 3: raise ServiceException({'result': 2, 'description': u'端口计量器故障'}) if devInfo['rst'] == 4: raise ServiceException({'result': 2, 'description': u'设备订单已达上限'}) if devInfo['rst'] == 5: raise ServiceException({'result': 2, 'description': u'设备正在自检'}) def analyze_event_data(self, data): if data['fun_code'] == '34': # 如果是结束事件,需要把reason翻译出来 descDict = { '1': u'开始充电,但是没有接充电器', '2': u'充电过程中,插座脱落', '3': u'用户按下关闭按钮关闭', '4': u'用户刷卡结束充电', '5': u'远程结束充电', '6': u'充电端口故障,为了安全主动关闭', '7': u'订购的时间使用完毕', '8': u'订购的电量使用完毕', '9': u'本端口功率过载,主动关闭', '10': u'整机功率过载,主动关闭', '11': u'其他异常导致的关闭' } order = data['order'] order['reason'] = descDict.get(str(order['closeType']), u'') data['order'] = order return data def get_dev_consume_count(self): devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], 'data': {'fun_code': 0x08}}) self.check_feedback_result(devInfo) data = devInfo['data'] return {'cardFee': round(data['total_card'] / 100.0,2), 'coinFee': data['total_coin'] / 100.0} # 单位为分 def get_many_port_info(self, portList): devInfo = MessageSender.send(self.device, self.make_random_cmdcode(), {'IMEI': self._device['devNo'], 'data': {'fun_code': 0x12}}) self.check_feedback_result(devInfo) resultDict = {} for port, data in devInfo['data']['details'].items(): if port not in portList: continue result = {'index': port} result['status'] = self.__translate_status_from_str(data['status']) result['power'] = round(data.get('watt', 0), 2) result['ampere'] = round(data.get('ampr', 0) / 1000.0, 2) result['voltage'] = round(data.get('volt'), 2) for exec_order in data['orders']: orderNo = exec_order.get('id') order = ConsumeRecord.objects.filter(orderNo=orderNo).first() if exec_order.get('status') == 'running': result['usedTime'] = round(exec_order.get('time', 0) / 60.0, 1) result['usedElec'] = round(exec_order.get('elec') / 1000000.0, 2) result['startTime'] = datetime.datetime.fromtimestamp(exec_order['exec_time']).strftime('%m-%d %H:%M:%S') result['nickName'] = order and order.nickname if 'card_no' in exec_order: result['cardNo'] = str(int(exec_order.get('card_no', 0), 16)) policy = exec_order.get('policy', {}) policyType = policy.get('type') billingMethod = policy.get('billingMethod') result['openId'] = policy.get('open_id') result['consumeMoney'] = '{}元'.format(round(exec_order.get('money') * 0.01, 2)) if billingMethod == 'prepaid': result['coins'] = round(policy.get('money') * 0.01, 2) if exec_order.get('order_type') == 'apps_start': result['consumeType'] = 'mobile' elif exec_order.get('order_type') == 'card_start': result['consumeType'] = 'card' result['cardBalance'] = '{}元'.format(round(exec_order.get('balance') * 0.01, 2)) elif billingMethod == 'postpaid': result['consumeType'] = 'postpaid' if exec_order.get('order_type') == 'apps_start': needFiled = 'need{}'.format(policyType.capitalize()) result[needFiled] = order and order.servicedInfo.get(needFiled) elif exec_order.get('order_type') == 'card_start': result['cardBalance'] = '{}元'.format(round(exec_order.get('balance') * 0.01, 2)) else: pass else: pass resultDict[port] = result return resultDict def __translate_status_from_str(self, status): dictConf = { 'idle': Const.DEV_WORK_STATUS_IDLE, 'busy': Const.DEV_WORK_STATUS_WORKING, 'forbid': Const.DEV_WORK_STATUS_FORBIDDEN, 'fault': Const.DEV_WORK_STATUS_FAULT, 'running': Const.DEV_WORK_STATUS_WORKING, 'link': Const.DEV_WORK_STATUS_CONNECTED } return dictConf.get(status, Const.DEV_WORK_STATUS_IDLE) # 访问设备,获取设备端口信息 def get_port_status_from_dev(self): devInfo = MessageSender.send(self.device, self.make_random_cmdcode(), {'IMEI': self._device['devNo'], 'data': {'fun_code': 0x01}}) self.check_feedback_result(devInfo) data = devInfo['data'] result = {} portNum = data.get('total', 10) ii = 0 while ii < portNum: ii += 1 result[str(ii)] = {'status': self.__translate_status_from_str(data['status'].get(str(ii)))} 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']) 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) statusDict = {} 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 lock_unlock_port(self, port, lock=True): portInfo = self.get_port_info(port) if portInfo and portInfo['status'] == Const.DEV_WORK_STATUS_WORKING and lock: raise ServiceException({'result': 2, 'description': u'端口正忙,请先关闭端口后,再禁止端口'}) typeStr = 'deactive' if lock else 'active' devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], 'data': {'port': int(port), 'type': typeStr, 'fun_code': 0x0D}}) self.check_feedback_result(devInfo) if devInfo['rst'] == 0: if lock: Device.update_dev_control_cache(self._device['devNo'], {str(port): {'status': Const.DEV_WORK_STATUS_FORBIDDEN}}) else: Device.update_dev_control_cache(self._device['devNo'], {str(port): {'status': Const.DEV_WORK_STATUS_IDLE}}) else: Device.update_dev_control_cache(self._device['devNo'], {str(port): {'status': Const.DEV_WORK_STATUS_IDLE}}) def active_deactive_port(self, port, active): if active: raise ServiceException({'result': 2, 'description': u'该设备不支持直接打开端口'}) return self.stop_charging_port(port) # 停止该端口下的所有任务 def stop_charging_port(self, port): devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], 'data': {'fun_code': 0x06, 'port': port}}) self.check_feedback_result(devInfo) if devInfo['rst'] == 0: Device.update_dev_control_cache(self._device['devNo'], {str(port): {'status': Const.DEV_WORK_STATUS_IDLE}}) return True if devInfo['rst'] == 0 else False def get_order(self, order_no): order = ConsumeRecord.objects.filter(orderNo=order_no).first() port = order.used_port devInfo = MessageSender.send(self.device, self.make_random_cmdcode(), {'IMEI': self._device['devNo'], 'data': {'fun_code': 0x02, 'port': int(port)}}) self.check_feedback_result(devInfo) data = devInfo.get('data', {}) exec_orders = data.get('orders', []) if not exec_orders: return {} result = {} for exec_order in exec_orders: if not exec_order.get('order_type'): # 有可能没有订单,应该返回空 return result if exec_order.get('status') != 'running': return {} result['power'] = round(data.get('watt', 0), 2) pay_unit = self.show_pay_unit # result['ampere'] = round(data.get('ampr', 0) / 1000.0, 2) # result['voltage'] = round(data.get('volt'), 2) result['status'] = exec_order.get('status', 0) orderNo = exec_order.get('id') order = ConsumeRecord.objects.filter(orderNo=orderNo).first() if order: result['coins'] = round(order.coin, 2) else: result['coins'] = round(exec_order.get('coins', 0) * 0.01, 2) result['usedTime'] = round(exec_order.get('time', 0) / 60.0, 1) result['usedElec'] = round(exec_order.get('elec') / 1000000.0, 2) if exec_order.get('status') == 'running': result['startTime'] = datetime.datetime.fromtimestamp(int(exec_order.get('execute_time', 0))).strftime( '%m-%d %H:%M:%S') if exec_order.get('chrmt') == 'TIME': result['needTime'] = round(exec_order.get('amount_time', 0) / 60.0, 1) result['leftTime'] = round(exec_order.get('left_time', 0) / 60.0, 1) leftMoney = round((result['coins'] * exec_order.get('left_time', 0) / exec_order.get('amount_time', 0)), 2) consumeMoney = round((result['coins'] - leftMoney), 2) if exec_order.get('order_type') == 'apps_start': result['consumeType'] = 'mobile' result['consumeMoney'] = '{}{}'.format(consumeMoney, pay_unit) result['leftMoney'] = '{}{}'.format(leftMoney, pay_unit) try: orderNo = exec_order.get('id', 0) order = ConsumeRecord.objects.get(orderNo=orderNo) result['nickName'] = order.user.nickname package = order.package if package.get('name') == '充满自停' and package.get('coins') == 0 and package.get( 'price') == 0: # 后付费 coins = round(exec_order.get('coins', 0) * 0.01, 2) consumeMoney = round( (coins * exec_order.get('time', 0) / exec_order.get( 'amount_time', 0)), 2) result['consumeMoney'] = '{}{}'.format(consumeMoney, pay_unit) result['consumeType'] = 'postpaid' result['needTime'] = '充满自停' result.pop('needElec', None) result.pop('leftMoney', None) result.pop('leftTime', None) result.pop('leftElec', None) except: pass if exec_order.get('order_type') == 'card_start': result['consumeType'] = 'card' result['cardNo'] = str(int(exec_order.get('card_no', 0), 16)) result['cardConsumeMoney'] = '{}{}'.format(consumeMoney, pay_unit) result['cardLeftMoney'] = '{}{}'.format(leftMoney, pay_unit) result['cardBalance'] = '{}{}'.format(round(exec_order.get('balance', 0) * 0.01, 2), pay_unit) try: card = Card.objects.get(cardNo=str(int(exec_order.get('card_no', 0), 16))) result['cardName'] = card.cardName or card.nickName if card.cardType == 'ID': # id卡 订单余额显示有问题 result['cardBalance'] = '{}{}'.format(round(exec_order.get('balance', 0) * 0.001, 2), pay_unit) except: pass elif exec_order.get('chrmt') == 'ELEC': result['needElec'] = round(exec_order.get('amount_elec', 0) * 0.000001, 2) result['leftElec'] = round(exec_order.get('left_elec', 0) * 0.000001, 4) leftMoney = round((result['coins'] * exec_order.get('left_elec', 0) / exec_order.get('amount_elec', 0)), 2) consumeMoney = round((result['coins'] - leftMoney), 2) if exec_order.get('order_type') == 'apps_start': result['consumeType'] = 'mobile' result['consumeMoney'] = '{}{}'.format(consumeMoney, pay_unit) result['leftMoney'] = '{}{}'.format(leftMoney, pay_unit) try: orderNo = exec_order.get('id', 0) order = ConsumeRecord.objects.get(orderNo=orderNo) result['nickName'] = order.user.nickname package = order.package if package.get('name') == '充满自停' and package.get('coins') == 0 and package.get( 'price') == 0: # 后付费 result['consumeType'] = 'postpaid' coins = round(exec_order.get('coins', 0) * 0.01, 2) consumeMoney = round( (coins * exec_order.get('elec', 0) / exec_order.get( 'amount_elec', 0)), 2) result['consumeMoney'] = '{}{}'.format(consumeMoney, pay_unit) result['needTime'] = '充满自停' result.pop('needElec', None) result.pop('leftMoney', None) result.pop('leftTime', None) result.pop('leftElec', None) if package.get('billingMethod') == CONSUMETYPE.BILL_AS_SERVICE: result.pop('consumeMoney', None) result['elecFee'] = self.device.bill_as_service_feature.current_elec_fee( consumeMoney).mongo_amount result['serviceFee'] = self.device.bill_as_service_feature.current_service_fee( consumeMoney).mongo_amount except: pass if exec_order.get('order_type') == 'card_start': result['consumeType'] = 'card' result['cardNo'] = str(int(exec_order.get('card_no', 0), 16)) result['cardConsumeMoney'] = '{}{}'.format(consumeMoney, pay_unit) result['cardLeftMoney'] = '{}{}'.format(leftMoney, pay_unit) result['cardBalance'] = '{}{}'.format(round(exec_order.get('balance', 0) * 0.01, 2), pay_unit) try: card = Card.objects.get(cardNo=str(int(exec_order.get('card_no', 0), 16))) result['cardName'] = card.cardName or card.nickName if card.cardType == 'ID': # id卡 订单余额显示有问题 result['cardBalance'] = '{}{}'.format(round(exec_order.get('balance', 0) * 0.001, 2), pay_unit) except: pass else: pass return result def response_card_balance(self, cardNo, balance, result): devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], 'data': {'fun_code': 35, 'card_no': cardNo, 'balance': int(100 * float(balance)), 'result': result}}) self.check_feedback_result(devInfo) # 获取设备配置参数 def get_dev_setting(self): devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], 'data': {'fun_code': 0x0C}}) self.check_feedback_result(devInfo) result = devInfo['data'] result.update({ 'fcharge_watt': result['fcharge']['watt'], 'fcharge_time': result['fcharge']['time'], 'fcharge_check': result['fcharge'].get('check', 10), }) # # 按功率分档收费 # TIME = result['price']['TIME'] # [{"max":"xxx","time":"xxx"}] # result['package_time'] = [] # for _ in TIME: # item = {} # item['power'] = _[0] # item['time'] = int(_[1]) / 60 # 时间未秒转换为分 # result['package_time'].append(item) # # # 按功率收费显示 # package_power = [] # for _item in TIME: # package_power.append({'power': _item[0], 'price': round(1.0 / (_item[1] / 60.0 / 60.0), 2)}) # result['package_power'] = package_power # # # 按电量收费 # result['package_elec'] = [] # elec = Decimal(result['price']['ELEC']) / 1000000 # 默认为毫度 # price = result['price'].get('price', 1) # 默认为一块钱 # result['package_elec'].append({'price': price, 'elec': elec}) noload_check = result.get('noload_check') if not noload_check: noload_check = { "time": 99, "watt": 99 }, result['emptyPower'] = noload_check['watt'] result['emptyTime'] = noload_check['time'] defaultVolume = 0 volumeList = [] for k, v in result['volume'].items(): if k == 'default': defaultVolume = v else: tempList = k.split('-') volumeList.append({'start': tempList[0], 'end': tempList[1], 'volume': v}) result.pop('volume') result['volume'] = defaultVolume result['volume_list'] = volumeList result['refundProtectionTime'] = self.device['otherConf'].get('refundProtectionTime', 5) return result # 获取设备配置参数 def set_dev_setting(self, setConf): # 检查数据 if not (int(setConf['fcharge_time']) >= 1 and int(setConf['fcharge_time']) <= 300): raise ServiceException({'result': 2, 'description': u'浮充时间必须大于等于1分钟,小于等于300分钟'}) if not (int(setConf['fcharge_check']) >= 2 and int(setConf['fcharge_check']) <= 30): raise ServiceException({'result': 2, 'description': u'浮充检测时间必须大于等于2分钟,小于等于30分钟'}) if not (int(setConf['fcharge_watt']) >= 20 and int(setConf['fcharge_watt']) <= 100): raise ServiceException({'result': 2, 'description': u'浮充功率必须大于等于20瓦,小于等于100瓦'}) if not (int(setConf['volume']) >= 0 and int(setConf['volume']) <= 7): raise ServiceException({'result': 2, 'description': u'音量必须大于等于0,小于等于7'}) volumeDict = {'default': int(setConf['volume'])} for vl in setConf['volume_list']: startTime = to_datetime('2020-01-01 %s:00' % vl['start']) endTime = to_datetime('2020-01-01 %s:00' % vl['end']) if endTime <= startTime: raise ServiceException({'result': 2, 'description': u'结束时间一定要大于起始时间。比如起始时间为07:00,结束时间为23:59'}) volumeDict['%s-%s' % (vl['start'], vl['end'])] = int(vl['volume']) setConf.pop('volume') setConf.pop('volume_list') setConf['volume'] = volumeDict # setConf['once_card'] = int(float(setConf['once_card']) * 100) # setConf['once_coin'] = int(float(setConf['once_coin']) * 100) setConf['max_watt'] = int(setConf['max_watt']) if not (int(setConf['max_watt']) >= 50 and int(setConf['max_watt']) <= 1000): raise ServiceException({'result': 2, 'description': u'最大功率必须大于等于100瓦,小于等于1000瓦'}) setConf.update({'fun_code': 0x0B}) setConf['fcharge'] = { 'watt': int(setConf['fcharge_watt']), 'time': int(setConf['fcharge_time']), 'check': int(setConf['fcharge_check']), } setConf.pop('fcharge_watt') setConf.pop('fcharge_time') setConf.pop('fcharge_check') # 空载检测 setConf['noload_check'] = {} setConf['noload_check']['watt'] = int(setConf.pop('emptyPower')) setConf['noload_check']['time'] = int(setConf.pop('emptyTime')) devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], 'data': setConf}) self.check_feedback_result(devInfo) def ack_event(self, orderNo, funCode): devInfo = MessageSender.send(self.device, DeviceCmdCode.PASSTHROUGH_OPERATE_DEV_NO_RESPONSE, {'IMEI': self._device['devNo'], 'data': {'fun_code': funCode, 'order_id': orderNo}}) self.check_feedback_result(devInfo) def clear_dev_feecount(self): devInfo = MessageSender.send(self.device, self.make_random_cmdcode(), {'IMEI': self._device['devNo'], 'data': {'fun_code': 0x09, 'total_coin': True, 'total_card': True}}) self.check_feedback_result(devInfo) def response_card_charge_result(self, cardNo, result): MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SERVER_ASYNC, {'IMEI': self._device['devNo'], 'data': {'fun_code': 37, 'card_no': cardNo, 'result': result}}) def reboot_device(self): data = {'fun_code':0x0B,'reset_mcu':True} MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], 'data': data}) MessageSender.async_send(self.device, DeviceCmdCode.SET_DEVINFO, {'IMEI': self._device['devNo'], 'restart': True}) def set_device_function(self, request, lastSetConf): if request.POST.has_key('clearSum'): self.clear_dev_feecount() elif request.POST.has_key('reboot'): self.reboot_device() def set_device_function_param(self, request, lastSetConf): newConf = copy.deepcopy(request.POST) newConf.pop('logicalCode', None) if 'refundProtectionTime' in newConf: refundProtectionTime = round(float(newConf.get('refundProtectionTime', 0.0)), 1) Device.get_collection().update_one(filter={'devNo': self.device.devNo}, update={'$set': {'otherConf.refundProtectionTime': refundProtectionTime}}) Device.invalid_device_cache(self.device.devNo) self.set_dev_setting(newConf) def get_card_pwd(self): devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], 'data': {'fun_code': 0x11}}) self.check_feedback_result(devInfo) result = devInfo['data'] enObj = EncryptDate(cardKey) cardPwd = enObj.decrypt(result['card_pwd']) if not cardPwd: cardPwd = '' return {'card_pwd': cardPwd} def translante_card_no(self, hexCardNo): return int(hexCardNo, 16) def check_pwd(self, pwd): if len(pwd) != 6: raise ServiceException({'result': 2, 'description': u'密码必须是6位纯数字密码'}) for char in pwd: if not (char >= '0' and char <= '9'): raise ServiceException({'result': 2, 'description': u'密码必须是6位纯数字密码'}) return def set_card_pwd(self, pwd): self.check_pwd(pwd) enObj = EncryptDate(cardKey) devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], 'data': {'fun_code': 0x0B, 'card_pwd': enObj.encrypt(pwd)}}) self.check_feedback_result(devInfo) def set_card_mode(self, setConf): cardMode = int(setConf.get('card_mode')) valueDict = {'fun_code': 0x10} if cardMode == 0: valueDict.update({'mode': cardMode}) elif cardMode == 1: # 格式化为离线卡 self.check_pwd(setConf['new_pwd']) newPwd = setConf['new_pwd'] if not str(setConf['balance']).isdigit(): raise ServiceException({'result': 2, 'description': u'余额必须是数字'}) balance = int(setConf['balance']) if not (balance >= 0 and balance <= 5000): raise ServiceException({'result': 2, 'description': u'余额必须在0和5000元之间'}) balance = balance * 10 # 硬件模块记录的单位是角 enObj = EncryptDate(cardKey) valueDict.update({'mode': 1, 'new_pwd': enObj.encrypt(str(newPwd)), 'balance': balance}) elif cardMode == 2: self.check_pwd(setConf['old_pwd']) self.check_pwd(setConf['new_pwd']) newPwd = setConf['new_pwd'] oldPwd = setConf['old_pwd'] enObj = EncryptDate(cardKey) valueDict.update({'mode': 2, 'old_pwd': enObj.encrypt(str(oldPwd)), 'new_pwd': enObj.encrypt(str(newPwd))}) devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], 'data': valueDict}) self.check_feedback_result(devInfo) def get_card_mode(self): devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], 'data': {'fun_code': 0x11}}) self.check_feedback_result(devInfo) cardMode = devInfo['data']['card_mode'] return {'card_mode': cardMode} def check_alarm(self, alarm): if alarm.faultCode == FAULT_CODE.MCU_REBOOT: return u'此告警,建议您多观察,如果比较频繁不停上报单台设备的告警,可能会运行不稳定。需要您联系技术支持确认。' elif alarm.faultCode == FAULT_CODE.COUNTER_FAULT: portInfo = self.get_port_info(alarm.portNo) if portInfo['status'] == Const.DEV_WORK_STATUS_FAULT: return u'此端口目前已经为故障状态,继电器可能运行不稳定,建议您联系技术支持,以确认设备运行情况。' else: return u'端口状态检查正常,继电器或存偶尔无法获取数据。暂不影响使用。' elif alarm.faultCode == FAULT_CODE.RELAY_FAULT: return u'无法进行远程诊断,建议您到现场,直接插上插座,然后检查是否不用付款,就能够充电。如果是的,就属于继电器粘连。' elif alarm.faultCode == FAULT_CODE.DEV_OVERLOAD: return u'整机功率最大限定为7500瓦,接入的负载超过此负载,为了安全,将强行关闭所有充电端口。' elif alarm.faultCode == FAULT_CODE.COPY_CARD: return u'出现一模一样的卡,可能是用户复制了另外一张离线卡,然后使用,会给您造成经济上的损失,建议冻结。' return '' # def get_part_info(self): # devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, # {'IMEI': self._device['devNo'], 'data': {'fun_code': 0x05}}) # self.check_feedback_result(devInfo) # # partInfo = devInfo['data'] # result = {} # nameDesc = {'networkBoard': u'网络板', 'chargeBoard': u'充电板', 'cardBoard': u'刷卡板'} # for k, v in partInfo.items(): # if k not in nameDesc: # continue # # result[nameDesc.get(k)] = {'SN': v} # # return result def recharge_card(self, cardNo, money, orderNo=None): hex_cardNo = hex(int(cardNo))[2::].replace('L', '').upper() result = MessageSender.send(self.device, self.make_random_cmdcode(), {'IMEI': self.device['devNo'], 'data': {'fun_code': 37, 'result': 1, 'card_no': hex_cardNo, 'charge': int(money * 100), 'order_id': orderNo}}) # 返回验证 self.check_feedback_result(result) card = Card.objects.filter(cardNo=cardNo,dealerId=self.device.ownerId).first() if not card: return { 'result': ErrorCode.EXCEPTION, 'description': '' }, None balance = card.balance + money return { 'result': ErrorCode.SUCCESS, 'description': '' }, balance def recharge_card_async(self, cardNo, money, orderNo): cardNo = hex(int(cardNo))[2::].replace('L', '').upper() MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SERVER_ASYNC, {'IMEI': self._device['devNo'], 'data': {'fun_code': 37, 'result': 1, 'card_no': cardNo, 'charge': int(money * 100), 'order_id': orderNo}}) @property def isHaveStopEvent(self): return True def stop(self, port = None): return self.stop_charging_port(port) def get_current_use(self, **kw): base_data = kw.get('base_data') spDict = kw.get('spDict') sp = ServiceProgress.objects.filter(id=spDict['_id']).first() data = {'fun_code': 2, 'port': spDict.get('port')} devInfo = self.send_mqtt(data) portInfo = devInfo.get('data', {}) exec_orders = portInfo.get('orders', []) if not exec_orders: sp.update(isFinished=True, status='finished', consumes=[]) return [] for exec_order in exec_orders: # 循环过来sp消费单同步 if exec_order['id'] not in sp.consumes: sp.consumes.append(exec_order['id']) sp.finished_time = int(time.time()) + 12 * 60 * 60 sp.isFinished = False if exec_order['status'] == 'running': sp.start_time = exec_order['exec_time'] pay_unit = self.show_pay_unit result_list = [] # 数据整理返回 for exec_order in exec_orders: item = {} item.update(base_data) item['orderNo'] = exec_order['id'] item['port'] = exec_order['port'] order = ConsumeRecord.objects.filter(orderNo=exec_order['id']).first() item['voltage'] = format(portInfo.get('volt', 0), '.2f') item['power'] = format(portInfo.get('watt', 0), '.2f') item['ampere'] = format((portInfo.get('ampr', 0) * 0.001), '.2f') item['usedTime'] = format(exec_order.get('time', 0) / 60.0, '.2f') # item['elec'] = format(exec_order.get('elec', 0) * 0.000001, '.4f') if exec_order['order_type'] == 'apps_start': try: item['consumeMoney'] = '{}{}'.format(round(exec_order.get('money', 0) * 0.01, 2), pay_unit) policy = exec_order['policy'] if policy.get('billingMethod', 'postpaid') == CONSUMETYPE.POSTPAID: item['order'] = { 'orderNo': exec_order['id'], # 停止按钮传订单停单用 # 'coin': '{}{}'.format(round(order.coin, 2), pay_unit), 'port': exec_order['port'], 'consumeType': 'postpaid', } else: item['order'] = { 'orderNo': exec_order['id'], # 停止按钮传订单停单用 'coin': '{}{}'.format(round(order.coin, 2), pay_unit), 'port': exec_order['port'], 'consumeType': 'mobile', } item['leftMoney'] = '{}{}'.format(round(exec_order.get('left_money', 0) * 0.01, 2), pay_unit) except: pass item.update(DeviceType.get_services_button(self.device['devType']['id'])) result_list.append(item) return result_list def check_dev_status(self, attachParas=None): port = int(attachParas['chargeIndex']) openId = attachParas['openId'] port_stat = self.get_port_info(port) status = port_stat.get('status') # if status not in ['busy', 'link']: # raise ServiceException({'result': 2, 'description': u'请先连接充电插座,再启动充电'}) last_openId = port_stat.get('openId') if status == 'busy': if openId and self.device.devType.get('payableWhileBusy'): if openId != last_openId: raise ServiceException({'result': 2, 'description': u'当前充电的设备不是您的设备哦!无法进行续充'}) else: if 'cardNo' in port_stat: raise ServiceException({'result': 2, 'description': u'刷卡启动的订单,无法扫码续充哦'}) else: raise ServiceException({'result': 2, 'description': u'当前端口处于充电状态, 请确认是否为您选择的充电端口哦!'})