| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352 | # -*- coding: utf-8 -*-# !/usr/bin/env pythonimport datetimeimport loggingimport timefrom decimal import Decimalfrom apilib.monetary import RMBfrom apps.web.constant import DeviceCmdCode, Const, ErrorCode, MQTT_TIMEOUT, DeviceErrorCodeDescfrom apps.web.core.adapter.base import SmartBox, fill_2_hexByte, make_six_bytes_session_idfrom apps.web.core.exceptions import ServiceExceptionfrom apps.web.core.networking import MessageSenderfrom apps.web.device.models import Device, GroupDictlogger = logging.getLogger(__name__)class YuZe5Box(SmartBox):    def __init__(self, device):        super(YuZe5Box, self).__init__(device)    def _check_package(self, package):        """        获取设备启动的发送数据 根据设备的当前模式以及套餐获取        :param package:        :return:        """        consumeMode = self._device.get("otherConf", dict()).get("consumeMode")        if not consumeMode:            tempDict = self.get_all_dev_settings()            consumeMode = tempDict.get('consumeMode')            Device.get_collection().update_one({'devNo': self._device['devNo']}, {                '$set': {'otherConf.consumeMode': int(consumeMode)}})            Device.invalid_device_cache(self._device['devNo'])                unit = package.get("unit", u"分钟")        _time = float(package.get("time", 0))        # 按时间计费 或者线下免费模式        if consumeMode == 0 or consumeMode == 2:            billingType = "time"            if unit == u"小时":                _time = _time * 60            elif unit == u"天":                _time = _time * 24 * 60            elif unit == u"秒":                _time = _time / 60            elif unit == u"分钟":                _time = _time            else:                raise ServiceException({"result": 2, "description": u"套餐单位错误,请联系经销商"})        # 按电量计费        else:            billingType = "elec"            if unit != u"度":                raise ServiceException({"result": 2, "description": u"套餐单位错误,请联系经销商"})            else:                _time = _time * 100        return _time, unit, billingType    def translate_funcode(self, funCode):        funCodeDict = {            '01': u'获取端口数量',            '02': u'移动支付',            '0C': u'获取设备设置',            '08': u'设置设备参数',            '06': u'获取设备端口详情',            '07': u'获取刷卡投币统计数据',            '09': u'设置刷卡投币使能',            '0A': u'端口使能',            '0B': u'端口关闭',            '16': u'设置设备参数',            '20': u'设备重启',            '13': u'设置卡充满退费',            '15': u'获取功率费率配置',            '14': u'设置功率费率配置',            '12': u'充值',            '22': u'回复卡充值',        }        return funCodeDict.get(funCode, '')    def translate_event_cmdcode(self, cmdCode):        cmdDict = {            '03': u'投币上报',            '04': u'刷卡上报',            '05': u'充电结束',            '16': u'充电结束',            '10': u'刷卡上报',            '0D': u'故障',            '20': u'启动设备',            '11': u'刷卡使用',            '12': u'卡充值',            '22': u'ID卡扣费',            '23': u'ID卡扣费状态',            '17': u'IC卡回收余额成功',            '30': u'电流上报',            '31': u'温度上报',            '32': u'烟感上报',        }        return cmdDict.get(cmdCode, '')    def is_port_can_use(self, port, canAdd = False):        # 电川的在启动的时候去判断是否需要续充        return True, ''    def check_dev_status(self, attachParas = None):        """        如果超过两个心跳周期没有报心跳,并且最后一次更新时间在2个小时内,需要从设备获取状态        否则以缓存状态为准。        :param attachParas:        :return:        """        if attachParas is None:            raise ServiceException({'result': 0, 'description': u'请您选择合适的充电端口、电池类型信息'})        if not attachParas.has_key('chargeIndex'):            raise ServiceException({'result': 0, 'description': u'请您选择合适的充电端口'})        if not self.device.need_fetch_online:            raise ServiceException(                {'result': 2, 'description': DeviceErrorCodeDesc.get(ErrorCode.DEVICE_CONN_CHECK_FAIL)})        self.get_port_status_from_dev()        group = self.device.group  # type: GroupDict        if group.is_free:            logger.debug('{} is free. no need to check continue pay.'.format(repr(self.device)))            return        # 处理是否能够续充        portDict = self.get_port_status()        port = str(attachParas['chargeIndex'])        if port in portDict:            isCanAdd = self.device['devType'].get('payableWhileBusy', False)            if portDict[port]['status'] == Const.DEV_WORK_STATUS_IDLE:                return            elif portDict[port]['status'] == Const.DEV_WORK_STATUS_FAULT:                raise ServiceException({'result': 0, 'description': u'该端口故障,暂时不能使用'})            elif portDict[port]['status'] == Const.DEV_WORK_STATUS_WORKING:                if isCanAdd:                    return                else:                    raise ServiceException({'result': 0, 'description': u'该端口正在工作不能使用,请您使用其他端口'})            elif portDict[port]['status'] == Const.DEV_WORK_STATUS_FORBIDDEN:                raise ServiceException({'result': 0, 'description': u'该端口已被禁止使用,请您使用其他端口'})            elif portDict[port]['status'] == Const.DEV_WORK_STATUS_CONNECTED:                return            else:                raise ServiceException({'result': 0, 'description': u'端口状态未知,暂时不能使用'})        else:            raise ServiceException({'result': 0, 'description': u'未知端口,暂时不能使用'})    def test(self, coins):        hexPort = fill_2_hexByte(hex(int(1)), 2)        hexTime = fill_2_hexByte(hex(5))        devInfo = MessageSender.send(device = self.device,                                     cmd = DeviceCmdCode.OPERATE_DEV_SYNC,                                     payload = {                                         'IMEI': self._device['devNo'],                                         "funCode": '02',                                         'data': hexPort + '0000' + hexTime                                     },                                     timeout = MQTT_TIMEOUT.SHORT)        return devInfo    def port_is_busy(self, port_dict):        if not port_dict:            return False        if 'billingType' not in port_dict:            return False        if 'status' not in port_dict:            return False        if 'coins' not in port_dict:            return False        if 'price' not in port_dict:            return False        if port_dict['billingType'] not in ['time', 'elec']:            return False        if port_dict['billingType'] == 'time':            if 'needTime' not in port_dict:                return False        else:            if 'needElec' not in port_dict:                return False        if port_dict['status'] == Const.DEV_WORK_STATUS_WORKING:            return True        else:            return False    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'请您选择合适的充电线路'})        price = float(package['price'])        dev = Device.objects.get(devNo = self._device['devNo'])        refundProtection = dev.otherConf.get('refundProtection', 0)        refundProtectionTime = dev.otherConf.get('refundProtectionTime', 5)        port = hex(int(attachParas['chargeIndex']))        hexPort = fill_2_hexByte(port, 2)        _time, unit, billingType = self._check_package(package)        coins = float(package['coins'])        hexTime = fill_2_hexByte(hex(int(_time)))        devInfo = MessageSender.send(            device = self.device,            cmd = DeviceCmdCode.PASSTHROUGH_OPERATE_DEV_SYNC,            payload = {                'IMEI': self._device['devNo'],                "funCode": '02',                'data': 'EE0D02{}'.format(make_six_bytes_session_id()) + hexPort + '0000' + hexTime            }, timeout = MQTT_TIMEOUT.START_DEVICE)        usePort = int(attachParas['chargeIndex'])        if 'rst' not in devInfo:            raise ServiceException(                {                    'result': 2,                    'description': u'启动设备失败,您的支付金额已经退还,请重新扫码设备试试(1001)'                })        if devInfo['rst'] != 0:            if devInfo['rst'] == -1:                raise ServiceException(                    {                        'result': 2,                        'description': u'充电桩正在玩命找网络,您的金币还在,重试不需要重新付款,建议您试试旁边其他设备,或者稍后再试哦'                    })            elif devInfo['rst'] == 1:                self.check_serial_port_for_startcmd(attachParas['chargeIndex'])            else:                raise ServiceException(                    {                        'result': 2,                        'description': u'启动设备失败,您的支付金额已经退回,请重新扫码设备({})'.format(devInfo['rst'])                    })        else:            if 'data' not in devInfo:                logger.warning('no data in success response. result = {}'.format(str(devInfo)))                raise ServiceException(                    {                        'result': 2,                        'description': u'启动设备失败,您的支付金额已经退还,请重试'                    })            else:                data = devInfo['data'][18::]                result = data[2:4]                if result == '01':  # 成功                    pass                elif result == '02':                    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 == '03':                    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'该端口正在使用中'})                else:                    raise ServiceException({                        'result': 2,                        'description': u'启动设备失败({}),您的支付金额已经退回,请重新扫码设备'.format(result)                    })        portDict = {            'startTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),            'status': Const.DEV_WORK_STATUS_WORKING,            'coins': coins,            'price': price,            'billingType': billingType,            'isStart': True,            'openId': openId,            'refunded': False,            'vCardId': self._vcard_id,            'refundProtection': refundProtection,            'refundProtectionTime': refundProtectionTime        }        ctrInfo = Device.get_dev_control_cache(self._device.devNo)        lastPortInfo = ctrInfo.get(str(usePort), None)        if self.port_is_busy(lastPortInfo) and \                lastPortInfo.get('billingType') == billingType and \                lastPortInfo.get('openId') == openId:            is_continus = True            portDict['coins'] = float(coins) + lastPortInfo['coins']            portDict['price'] = float(price) + lastPortInfo['price']        else:            is_continus = False            portDict['coins'] = float(coins)            portDict['price'] = float(price)        if 'linkedRechargeRecordId' in attachParas and attachParas.get('isQuickPay', False):            if is_continus:                payInfo = lastPortInfo.get("payInfo", list())                if not payInfo:                    logger.warning("miss payInfo! {}-{}".format(self._device["devNo"], usePort))            else:                payInfo = list()            payInfo.append({'rechargeRcdId': str(attachParas['linkedRechargeRecordId'])})            portDict['payInfo'] = payInfo        if billingType == 'time':            if is_continus:                portDict['needTime'] = _time + lastPortInfo['needTime']            else:                portDict['needTime'] = _time            finishedTime = int(time.time()) + int(portDict['needTime'] * 60)        else:            if is_continus:                portDict['needElec'] = _time / 100.0 + lastPortInfo['needElec']            else:                portDict['needElec'] = _time / 100.0            finishedTime = int(time.time()) + 60 * 60 * 12        portDict.update({'finishedTime': finishedTime})        if 'orderNo' in attachParas:            portDict.update({'orderNo': attachParas['orderNo']})        Device.update_dev_control_cache(            self._device['devNo'],            {                str(usePort): portDict            })        devInfo['finishedTime'] = finishedTime        return devInfo    def analyze_event_data(self, data):        cmdCode = data[4:6]        if cmdCode == '05':            port = int(data[18:20], 16)            leftTime = int(data[20:24], 16)            reason = data[24:26]            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'刷卡退费结束'            elif reason == '06':                desc = u'可能是插头被拔掉或者未连接充电器。如果不是自己操作,建议您到现场检查是否有人误操作'            elif reason == '07':                desc = u'远程方式停止充电。如果不是自己操作,建议到现场尽快恢复充电'            else:                desc = u''            # 刷卡充电的结束            if len(data) > 34:                cardNo = str(int(data[26:34], 16))                backMoney = int(data[34:36], 16) / 10.0                cardType = 'ID' if data[36:40] == 'AA33' else 'IC'                if cardNo != str(0):                    return {'status': Const.DEV_WORK_STATUS_IDLE, 'cmdCode': cmdCode, 'port': port,                            'leftTime': leftTime, 'reason': desc, 'isStart': False, 'cardNo': cardNo,                            'backMoney': backMoney, 'cardType': cardType, 'endType': reason,                            'reasonCode': reason, 'uartData': data}                else:                    return {'status': Const.DEV_WORK_STATUS_IDLE, 'cmdCode': cmdCode, 'port': port,                            'leftTime': leftTime, 'reason': desc, 'isStart': False, 'endType': reason,                            'reasonCode': reason, 'uartData': data}            # 非刷卡充电的结束            else:                return {'status': Const.DEV_WORK_STATUS_IDLE, 'cmdCode': cmdCode, 'port': port,                        'leftTime': leftTime, 'reason': desc, 'isStart': False, 'endType': reason,                        'reasonCode': reason, 'uartData': data}        elif cmdCode == '0D':            port = int(data[16:18], 16)            errCode = data[18:20]            if errCode == '01':                return {'statusInfo': u'端口输出故障', 'cmdCode': cmdCode, 'port': port, 'FaultCode': errCode, "uart": data}            elif errCode == '02':                return {'statusInfo': u'机器整体充电功率过大', 'cmdCode': cmdCode, 'port': port, 'FaultCode': errCode,                        "uart": data}            elif errCode == '03':                return {'statusInfo': u'电源故障', 'cmdCode': cmdCode, 'port': port, 'FaultCode': errCode, "uart": data}        elif cmdCode == '03':  # 投币上报            coin = int(data[18:20], 16)            try:                port = int(data[20:22], 16)            except:                port = None            return {'cmdCode': cmdCode, 'coins': coin, 'port': port}        elif cmdCode == '11':  # 刷卡后,按下端口,上报的报文            # cardNo = str(int(''.join(re.findall(r'..', data[18:26])[::-1]), 16))            cardNo = int(data[18:26], 16)            cardNo = str(cardNo)            fee = int(data[26:28], 16) / 10.0            balance = int(data[28:32], 16) / 10.0            cardType = 'ID' if data[32:36] == 'AA33' else 'IC'            port = int(data[36:38], 16)            status = data[38:40]            return {'cardNo': cardNo, 'fee': fee, 'balance': balance, 'cardType': cardType, 'port': port,                    'status': status, 'cmdCode': cmdCode}        elif cmdCode == '12':            cardNo = data[18:26]            cardNo = str(int(cardNo, 16))            balance = int(data[26:30], 16) / 10.0            cardType = 'ID' if data[30:34] == 'AA33' else 'IC'            return {'cmdCode': cmdCode, 'balance': balance, 'cardType': cardType, 'cardNo': cardNo}        elif cmdCode == '04':  # 旧版本的刷卡报文            money = int(data[18:20], 16)            return {'cmdCode': cmdCode, 'money': money}        elif cmdCode == '30':  # 宇泽家的,主动上报电流            portData = data[18:48]            port1 = int(portData[2:4])            port2 = int(portData[4:6])            port3 = int(portData[6:8])            port4 = int(portData[8:10])            port5 = int(portData[10:12])            port6 = int(portData[12:14])            port7 = int(portData[14:16])            port8 = int(portData[16:18])            port9 = int(portData[18:20])            port10 = int(portData[20:22])            device = int(portData[22:24])            return {                'cmdCode': cmdCode,                'port1': port1,                'port2': port2,                'port3': port3,                'port4': port4,                'port5': port5,                'port6': port6,                'port7': port7,                'port8': port8,                'port9': port9,                'port10': port10,                'device': device,            }        elif cmdCode == '31':  # 宇泽家的,主动上报温度            portData = data[18:48]            port1 = int(portData[2:4])            port2 = int(portData[4:6])            port3 = int(portData[6:8])            port4 = int(portData[8:10])            port5 = int(portData[10:12])            port6 = int(portData[12:14])            port7 = int(portData[14:16])            port8 = int(portData[16:18])            port9 = int(portData[18:20])            port10 = int(portData[20:22])            device = int(portData[22:24])            return {                'cmdCode': cmdCode,                'port1': port1,                'port2': port2,                'port3': port3,                'port4': port4,                'port5': port5,                'port6': port6,                'port7': port7,                'port8': port8,                'port9': port9,                'port10': port10,                'device': device,            }        elif cmdCode == '32':  # 宇泽家的,主动上报温度            if data[18:20] == '01':                return {'isYangan': True, 'cmdCode': cmdCode}            else:                return {'isYangan': False, 'cmdCode': cmdCode}        elif cmdCode == '17':            """                IC卡回收余额成功,上报回收的数目                样例 660F170048614800052DDA5A0D000001DD            """            cardNo = int(data[18:26], 16)            cardNo = str(cardNo)            backMoney = int(data[26:30], 16) / 10.0            return {'cmdCode': cmdCode, 'cardNo': cardNo, 'backMoney': backMoney}        elif cmdCode == '22':  # ID卡,上报上来扣费            cardNo = int(data[18:26], 16)            cardNo = str(cardNo)            fee = int(data[26:28], 16) / 10.0            cardType = 'ID' if data[28:32] == 'AA33' else 'IC'            return {'cmdCode': cmdCode, 'cardNo': cardNo, 'fee': fee, 'cardType': cardType}        elif cmdCode == '23':  # ID卡,上报上来扣费            cardNo = int(data[18:26], 16)            cardNo = str(cardNo)            status = data[26:28]            return {'cmdCode': cmdCode, 'cardNo': cardNo, 'status': status}        elif cmdCode == '35':            temperature = int(data[18:20], 16)            smoke = int(data[20:22], 16)            voltage = int(data[22:26], 16)            return {'cmdCode': cmdCode, 'temperature': temperature, 'smokeWarning': (smoke == 0x01), 'voltage': voltage}        elif cmdCode == '41':            return {'cmdCode': cmdCode, 'smokeWarning': True}    def get_dev_consume_count(self):        """        crc校验错        :return:        """        devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,                                     {'IMEI': self._device['devNo'], "funCode": '07', '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'][16::]        cardFee = int(data[2:6], 16) / 10.0  # 以角为单位        coinFee = int(data[6:10], 16)  # 以元为单位        return {'cardFee': cardFee, 'coinFee': coinFee}    def get_port_info(self, line):        data = fill_2_hexByte(hex(int(line)), 2)        devInfo = MessageSender.send(self.device, self.make_random_cmdcode(),                                     {'IMEI': self._device['devNo'], "funCode": '06', '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'][16::]        leftTime = int(data[4:8], 16)        if data[8:12] == 'FFFF':            power = 0        else:            power = int(data[8:12], 16) / 10.0        data = {"port": line, "power": power}        # 电量计费模式        if not self._device.get("otherConf", dict()).get("consumeMode", 0):            data.update({"leftTime": leftTime})        else:            data.update({"leftElec": leftTime / 100.0})        return data    def get_port_status_from_dev(self):        """        访问设备,获取设备端口信息        :return:        """        devInfo = MessageSender.send(device = self.device,                                     cmd = DeviceCmdCode.PASSTHROUGH_OPERATE_DEV_SYNC,                                     payload = {                                         'IMEI': self._device['devNo'],                                         'funCode': '01',                                         'data': 'EE0901{}'.format(make_six_bytes_session_id()) + '00'                                     })        if devInfo.has_key('rst') and devInfo['rst'] != 0:            if devInfo['rst'] == -1:                raise ServiceException(                    {'result': 2, 'description': u'充电桩正在玩命找网络,请您稍候再试', 'rst': -1})            elif devInfo['rst'] == 1:                raise ServiceException(                    {'result': 2, 'description': u'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能', 'rst': 1})        data = devInfo['data'][16::]        result = {}        portNum = int(data[2:4], 16)        portData = data[4::]        ii = 0        while ii < portNum:            statusTemp = portData[ii * 2:ii * 2 + 2]            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(ii)] = status        allPorts, usedPorts, usePorts = self.get_port_static_info(result)        # 这里存在多线程更新缓存的场景,可能性比较低,但是必须先取出来,然后逐个更新状态,然后再记录缓存        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        ctrInfo.update({            'allPorts': allPorts, 'usedPorts': usedPorts, 'usePorts': usePorts        })        Device.update_dev_control_cache(self.device.devNo, ctrInfo)        return result    def get_default_port_nums(self):        default_num = 10        return default_num    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 'allPorts' in ctrInfo and ctrInfo['allPorts'] > 0:            allPorts = ctrInfo['allPorts']        else:            allPorts = self.get_default_port_nums()        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}        return statusDict    def lock_unlock_port(self, port, lock = True):        lockStr = '00' if lock else '01'        portStr = fill_2_hexByte(hex(int(port)), 2)        devInfo = MessageSender.send(device = self.device, cmd = DeviceCmdCode.OPERATE_DEV_SYNC,                                     payload = {'IMEI': self._device['devNo'], "funCode": '0A',                                                'data': portStr + lockStr}, timeout = MQTT_TIMEOUT.SHORT)        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'][18::]        if data[0:2] == '01':  # 表示成功            pass        else:            raise ServiceException({'result': 2, 'description': u'操作端口失败,请重试看能否解决'})        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}})    def active_deactive_port(self, port, active):        if active:            raise ServiceException({'result': 2, 'description': u'该设备不支持直接打开端口'})        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, '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)    def stop_charging_port(self, port):        portStr = fill_2_hexByte(hex(int(port)), 2)        devInfo = MessageSender.send(device = self.device, cmd = DeviceCmdCode.OPERATE_DEV_SYNC,                                     payload = {'IMEI': self._device['devNo'], "funCode": '0B', 'data': portStr},                                     timeout = MQTT_TIMEOUT.SHORT)        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'][16::]        port = int(data[2:4], 16)        leftTime = int(data[4:8], 16)        data = {"port": port}        # 电量计费模式        if not self._device.get("otherConf", dict()).get("consumeMode", 0):            data.update({"remainder_time": leftTime})        else:            data.update({"remainder_time": leftTime / 100.0})        return data    def stop(self, port = None):        return self.stop_charging_port(port)    @property    def isHaveStopEvent(self):        return True        def set_IC_coin_power_config(self, infoDict):        data = ''        data += fill_2_hexByte(hex(int(infoDict['maxPower'])), 4)        data += fill_2_hexByte(hex(int(infoDict['icMoney'])), 2)        data += fill_2_hexByte(hex(int(infoDict['time1'])), 4)        data += fill_2_hexByte(hex(int(infoDict['time2'])), 4)        data += fill_2_hexByte(hex(int(infoDict['time3'])), 4)        devInfo = MessageSender.send(device = self.device, cmd = DeviceCmdCode.OPERATE_DEV_SYNC,                                     payload = {'IMEI': self._device['devNo'], "funCode": '08', 'data': data},                                     timeout = MQTT_TIMEOUT.SHORT)        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'充电桩忙,无响应,请您稍候再试'})    def get_coin_card_enable(self):            putCoins = self.device['otherConf'].get('putCoins', False)        icCard = self.device['otherConf'].get('icCard', False)        return {'putCoins': putCoins, 'icCard': icCard}    def set_coin_card_enable(self, infoDict):        data = ''        if infoDict['putCoins']:            data += '01'        else:            data += '00'        if infoDict['icCard']:            data += '01'        else:            data += '00'        devInfo = MessageSender.send(device = self.device, cmd = DeviceCmdCode.OPERATE_DEV_SYNC,                                     payload = {'IMEI': self._device['devNo'], "funCode": '09', 'data': data},                                     timeout = MQTT_TIMEOUT.SHORT)        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'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})        else:            Device.get_collection().update_one({'devNo': self._device['devNo']},                                               {'$set': {                                                   'otherConf.putCoins': infoDict['putCoins'],                                                   'otherConf.icCard': infoDict['icCard'],                                               }})                        Device.invalid_device_cache(self.device.devNo)    def get_dev_setting(self):        # 发送指令查询        resultDict = {}                try:            tempDict = self.get_fullstop_cardrefund()            resultDict.update(tempDict)        except:            pass        # try:        #     tempDict = self.get_gear_conf()        #     resultDict.update(tempDict)        # except:        #     pass                        try:            tempDict = self.get_all_dev_settings()            resultDict.update(tempDict)        except:            pass                try:            tempDict = self.get_consume_mode_volume_andsoon_config()            resultDict.update(tempDict)        except:            pass                try:            # 设置后保存到设备的参数            tempDict = self.get_coin_card_enable()            resultDict.update(tempDict)        except:            pass        try:            tempDict = self.get_elec_rule()            resultDict.update(tempDict)        except:            pass                return resultDict    def get_fullstop_cardrefund(self):        devInfo = MessageSender.send(device = self.device, cmd = DeviceCmdCode.OPERATE_DEV_SYNC,                                     payload = {'IMEI': self._device['devNo'], "funCode": '0C', 'data': '00'},                                     timeout = MQTT_TIMEOUT.SHORT)        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'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})        confData = devInfo['data'][18::]        maxPower = int(confData[0:4], 16)        icMoney = int(confData[4:6], 16)        if len(confData) > 6:            time1 = int(confData[6:10], 16)            time2 = int(confData[10:14], 16)            time3 = int(confData[14:18], 16)        else:            time1, time2, time3 = 0, 0, 0        autoStop = True if confData[20:22] == u'01' else False        cardRefund = True if confData[18:20] == u'01' else False        return {'maxPower': maxPower}    def set_fullstop_cardrefund(self, infoDict):        data = ''        if infoDict['autoStop']:            data += '01'        else:            data += '00'        if infoDict['cardRefund']:            data += '01'        else:            data += '00'        devInfo = MessageSender.send(device = self.device, cmd = DeviceCmdCode.OPERATE_DEV_SYNC,                                     payload = {'IMEI': self._device['devNo'], "funCode": '13', 'data': data},                                     timeout = MQTT_TIMEOUT.SHORT)        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'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})                def get_gear_conf(self):        resultDict = {'power1': 0, 'power1ratio': 0, 'power2': 0,                      'power2ratio': 0, 'power3': 0, 'power3ratio': 0}        devInfo = MessageSender.send(device = self.device, cmd = DeviceCmdCode.OPERATE_DEV_SYNC,                                     payload = {'IMEI': self._device['devNo'], "funCode": '15', 'data': '00'},                                     timeout = MQTT_TIMEOUT.SHORT)        if devInfo.has_key('rst') and devInfo['rst'] != 0:            if devInfo['rst'] == -1:                raise ServiceException(                    {'result': 2, 'description': u'充电桩正在玩命找网络,请您稍候再试'})            elif devInfo['rst'] == 1:                return resultDict        confData = devInfo['data'][18::]        power1 = int(confData[0:4], 16)        power1ratio = int(confData[4:6], 16)        power2 = int(confData[6:10], 16)        power2ratio = int(confData[10:12], 16)        power3 = int(confData[12:16], 16)        power3ratio = int(confData[16:18], 16)        result = {            'power1': power1, 'power1ratio': power1ratio, 'power2': power2,            'power2ratio': power2ratio, 'power3': power3, 'power3ratio': power3ratio        }        if len(confData) > 31:            power4 = int(confData[18:22], 16)            power4ratio = int(confData[22:24], 16)            power5 = int(confData[24:28], 16)            power5ratio = int(confData[28:30], 16)            result.update({'power4': power4, 'power4ratio': power4ratio,                           'power5': power5, 'power5ratio': power5ratio})        return result    def set_gear_conf(self, infoDict):        data = ''        data += fill_2_hexByte(hex(infoDict['power1']), 4)        data += fill_2_hexByte(hex(infoDict['power1ratio']), 2)        data += fill_2_hexByte(hex(infoDict['power2']), 4)        data += fill_2_hexByte(hex(infoDict['power2ratio']), 2)        data += fill_2_hexByte(hex(infoDict['power3']), 4)        data += fill_2_hexByte(hex(infoDict['power3ratio']), 2)        if infoDict.has_key('power4'):            data += fill_2_hexByte(hex(int(infoDict['power4'])), 4)            data += fill_2_hexByte(hex(int(infoDict['power4ratio'])), 2)            data += fill_2_hexByte(hex(int(infoDict['power5'])), 4)            data += fill_2_hexByte(hex(int(infoDict['power5ratio'])), 2)        devInfo = MessageSender.send(device = self.device, cmd = DeviceCmdCode.OPERATE_DEV_SYNC,                                     payload = {'IMEI': self._device['devNo'], "funCode": '14', 'data': data},                                     timeout = MQTT_TIMEOUT.SHORT)        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'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})    def recharge_card(self, cardNo, money, orderNo = None):        try:            data = 'EE1012{}'.format(make_six_bytes_session_id())            cardNo = fill_2_hexByte(hex(int(cardNo)), 8)            data += cardNo + fill_2_hexByte(hex(int(money * 10)), 4) + '0001'            devInfo = MessageSender.send(device = self.device, cmd = DeviceCmdCode.PASSTHROUGH_OPERATE_DEV_SYNC,                                         payload = {'IMEI': self._device['devNo'], 'data': data, 'funCode': '12'},                                         timeout = MQTT_TIMEOUT.LONGEST)            if devInfo['rst'] != 0:                if devInfo['rst'] == ErrorCode.DEVICE_CONN_FAIL:                    # 离线无法判断是否成功, 认为充值成功, 走售后解决                    return {                               'result': ErrorCode.DEVICE_CONN_FAIL,                               'description': u'当前充电桩正在玩命找网络,请您稍候再试'                           }, None                elif devInfo['rst'] == ErrorCode.BOARD_UART_TIMEOUT:                    return {                               'result': ErrorCode.BOARD_UART_TIMEOUT,                               'description': u'当前充电桩忙,无响应,请您稍候再试'                           }, None                else:                    return {                               'result': devInfo['rst'],                               'description': u'系统异常'                           }, None            resultData = devInfo['data']            if resultData[4:6] != '16':                return {                           'result': ErrorCode.PARAMETER_ERROR_TO_BOX,                           'description': u'充值返回报文命令码不为16'                       }, None            balance = RMB(int(resultData[26:30], 16)) * Decimal('0.1')            result = True if resultData[34:36] == '01' else False            if result:                return {                           'result': ErrorCode.SUCCESS,                           'description': ''                       }, balance            else:                return {                           'result': ErrorCode.IC_RECHARGE_FAIL,                           'description': u'充值失败'                       }, balance        except Exception as e:            logger.exception(e)            return {                       'result': ErrorCode.EXCEPTION,                       'description': e.message                   }, None    def get_consume_mode_volume_andsoon_config(self):        devInfo = MessageSender.send(device = self.device, cmd = DeviceCmdCode.OPERATE_DEV_SYNC,                                     payload = {'IMEI': self._device['devNo'], "funCode": '2A', 'data': '00'},                                     timeout = MQTT_TIMEOUT.SHORT)        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'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})        confData = devInfo['data'][18::]        card1Time = int(confData[0:4], 16)        card2Time = int(confData[4:8], 16)        card3Time = int(confData[8:12], 16)        consumeMode = int(confData[12:14])        volume = int(confData[14:16], 16)        fuchongPower = int(confData[16:20], 16) * 0.1        fuchongTime = int(confData[20:24], 16)        return { 'volume': volume, }    def set_consume_mode_volume_config(self, infoDict):                data = fill_2_hexByte(hex(int(infoDict.get('consumeMode', 5))), 2)        data += fill_2_hexByte(hex(int(infoDict.get('volume', 5))), 2)        devInfo = MessageSender.send(device = self.device, cmd = self.make_random_cmdcode(),                                     payload = {'IMEI': self._device['devNo'], "funCode": '27', 'data': data},                                     timeout = MQTT_TIMEOUT.SHORT)        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'充电桩忙,无响应,请您稍候再试'})    def set_fuchong_config(self, infoDict):        """            已弃用  替代指令 37        :param infoDict:        :return:        """        data = fill_2_hexByte(hex(int(infoDict['fuchongPower']) * 10), 4)        data += fill_2_hexByte(hex(int(infoDict['fuchongTime'])), 4)        devInfo = MessageSender.send(device = self.device, cmd = DeviceCmdCode.OPERATE_DEV_SYNC,                                     payload = {'IMEI': self._device['devNo'], "funCode": '28', 'data': data},                                     timeout = MQTT_TIMEOUT.SHORT)        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'充电桩忙,无响应,请您稍候再试'})    def set_card_time_config(self, infoDict):        data = fill_2_hexByte(hex(int(infoDict['card1Time'])), 4)        data += fill_2_hexByte(hex(int(infoDict['card2Time'])), 4)        data += fill_2_hexByte(hex(int(infoDict['card3Time'])), 4)        devInfo = MessageSender.send(device = self.device, cmd = self.make_random_cmdcode(),                                     payload = {'IMEI': self._device['devNo'], "funCode": '29', 'data': data},                                     timeout = MQTT_TIMEOUT.SHORT)        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'充电桩忙,无响应,请您稍候再试'})    def set_fuchong_config_new(self, infoDict):        data = fill_2_hexByte(hex(int(infoDict['fuchongPower']) * 10), 4)        data += fill_2_hexByte(hex(int(infoDict['fuchongTime'])), 4)        data += fill_2_hexByte(hex(int(infoDict['noloadTime'])), 4)        devInfo = MessageSender.send(device=self.device, cmd=DeviceCmdCode.OPERATE_DEV_SYNC,                                     payload={'IMEI': self._device['devNo'], "funCode": '37', 'data': data},                                     timeout=MQTT_TIMEOUT.SHORT)        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'充电桩忙,无响应,请您稍候再试'})        else:            Device.get_collection().update_one({'devNo': self.device.devNo},                                               {'$set': {                                                   'otherConf.fuchongPower': int(infoDict['fuchongPower']),                                                   'otherConf.fuchongTime': int(infoDict['fuchongTime']),                                                   'otherConf.noloadTime': int(infoDict['noloadTime']),                                               }})            Device.invalid_device_cache(self.device.devNo)            def set_elec_rule(self, infoDict):        coinElec = int(infoDict['coinElec'])        cardElec = int(infoDict['cardElec'])        data = fill_2_hexByte(hex(coinElec), 4)        data += fill_2_hexByte(hex(cardElec), 4)                devInfo = MessageSender.send(device=self.device, cmd=DeviceCmdCode.OPERATE_DEV_SYNC,                                     payload={'IMEI': self._device['devNo'], "funCode": '42', 'data': data},                                     timeout=MQTT_TIMEOUT.SHORT)        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'充电桩忙,无响应,请您稍候再试'})        # else:        #     Device.get_collection().update_one({'devNo': self.device.devNo},        #                                        {'$set': {        #                                            'otherConf.coinElec': coinElec,        #                                            'otherConf.cardElec': cardElec        #                                        }})        #     Device.invalid_device_cache(self.device.devNo)                    def get_elec_rule(self):                # coinElec = self.device['otherConf'].get('coinElec', 0)        # cardElec = self.device['otherConf'].get('coinElec', 0)        devInfo = MessageSender.send(device=self.device, cmd=DeviceCmdCode.OPERATE_DEV_SYNC,                                     payload={'IMEI': self._device['devNo'], "funCode": '47', 'data': '00'},                                     timeout=MQTT_TIMEOUT.SHORT)        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'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})        confData = devInfo['data'][18::]        coinElec = int(confData[:4], 16)        cardElec = int(confData[4:8], 16)                        return {'coinElec': coinElec, 'cardElec': cardElec}        def set_device_function(self, request, lastSetConf):        if request.POST.has_key('putCoins'):            # putCoins = True if request.POST.get('putCoins') == 'true' else False            putCoins = request.POST.get("putCoins", False)            lastSetConf.update({'putCoins': putCoins})            self.set_coin_card_enable(lastSetConf)        if request.POST.has_key('icCard'):            # icCard = True if request.POST.get('icCard') == 'true' else False            icCard = request.POST.get("icCard", False)            lastSetConf.update({'icCard': icCard})            self.set_coin_card_enable(lastSetConf)        if request.POST.has_key('autoStop'):            # autoStop = True if request.POST.get('autoStop') == 'true' else False            autoStop = request.POST.get("autoStop", False)            lastSetConf.update({'autoStop': autoStop})            self.set_fullstop_cardrefund(lastSetConf)        if request.POST.has_key('cardRefund'):            # cardRefund = True if request.POST.get('cardRefund') == 'true' else False            cardRefund = request.POST.get("cardRefund", False)            lastSetConf.update({'cardRefund': cardRefund})            self.set_fullstop_cardrefund(lastSetConf)        if request.POST.has_key('consumeMode'):            consumeMode = request.POST.get("consumeMode", False)            lastSetConf.update({'consumeMode': consumeMode})            self.set_consume_mode_volume_config(lastSetConf)    def set_device_function_param(self, request, lastSetConf):        # 和 主板厂家沟通 目前已经不会存在 有maxPower这个控制选项 maxPower 就是分档功率中的最高档功率        if 'icMoney' in request.POST:            lastSetConf.update({'icMoney': int(request.POST.get('icMoney', 0))})            lastSetConf.update({'maxPower': int(request.POST.get('maxPower', 0))})            self.set_IC_coin_power_config(lastSetConf)        if 'time1' in request.POST and 'time2' in request.POST and 'time3' in request.POST:            lastSetConf.update({'time1': int(request.POST.get('time1', 0))})            lastSetConf.update({'time2': int(request.POST.get('time2', 0))})            lastSetConf.update({'time3': int(request.POST.get('time3', 0))})            self.set_IC_coin_power_config(lastSetConf)        if 'power1' in request.POST and 'power1ratio' in request.POST:            lastSetConf.update({'power1': int(request.POST.get('power1', 0))})            lastSetConf.update({'power1ratio': int(request.POST.get('power1ratio', 0))})            lastSetConf.update({'power2': int(request.POST.get('power2', 0))})            lastSetConf.update({'power2ratio': int(request.POST.get('power2ratio', 0))})            lastSetConf.update({'power3': int(request.POST.get('power3', 0))})            lastSetConf.update({'power3ratio': int(request.POST.get('power3ratio', 0))})            lastSetConf.update({'power4': int(request.POST.get('power4', 0))})            lastSetConf.update({'power4ratio': int(request.POST.get('power4ratio', 0))})            lastSetConf.update({'power5': int(request.POST.get('power5', 0))})            lastSetConf.update({'power5ratio': int(request.POST.get('power5ratio', 0))})            self.set_gear_conf(lastSetConf)        if 'card1Time' in request.POST and 'card2Time' in request.POST and 'card3Time' in request.POST:            lastSetConf.update({'card1Time': int(request.POST.get('card1Time', 0))})            lastSetConf.update({'card2Time': int(request.POST.get('card2Time', 0))})            lastSetConf.update({'card3Time': int(request.POST.get('card3Time', 0))})            self.set_card_time_config(lastSetConf)        if 'fuchongPower' in request.POST and 'fuchongTime' in request.POST:            fuchongPower = 5 if request.POST.get('fuchongPower') == '' else int(request.POST.get('fuchongPower'))            fuchongTime = 120 if request.POST.get('fuchongTime') == '' else int(request.POST.get('fuchongTime'))            lastSetConf.update({'fuchongPower': fuchongPower})            lastSetConf.update({'fuchongTime': fuchongTime})            self.set_fuchong_config(lastSetConf)        if 'refundProtectionTime' in request.POST:            lastSetConf.update({'refundProtectionTime': int(request.POST.get('refundProtectionTime', 5))})            dev = Device.objects.get(devNo = self._device['devNo'])            dev.otherConf.update({'refundProtectionTime': lastSetConf['refundProtectionTime']})            dev.save()                if 'coinElec' in request.POST and 'cardElec' in request.POST:            lastSetConf.update({'coinElec': request.POST['coinElec']})            lastSetConf.update({'cardElec': request.POST['cardElec']})            self.set_elec_rule(lastSetConf)                if 'consumeMode' in request.POST and 'volume' in request.POST:            lastSetConf.update({'consumeMode': request.POST['consumeMode']})            lastSetConf.update({'volume': request.POST['volume']})            self.set_consume_mode_volume_config(lastSetConf)            Device.get_collection().update_one({'devNo': self._device['devNo']}, {                '$set': {'otherConf.consumeMode': int(request.POST['consumeMode'])}})            Device.invalid_device_cache(self._device['devNo'])            def response_card_status(self, cardNo, balance, status):        data = 'EE1123{}'.format(make_six_bytes_session_id()) + fill_2_hexByte(hex(int(cardNo)), 4) + fill_2_hexByte(            hex(int(balance * 10)), 4) + 'AA33' + status        devInfo = MessageSender.send(self.device, DeviceCmdCode.PASSTHROUGH_OPERATE_DEV_SYNC,                                     {'IMEI': self._device['devNo'], "funCode": '22', '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:  # 等于1的时候,说明服务器和远程模块通讯OK,响应已经收到,不需要异常处理                raise ServiceException(                    {'result': 2, 'description': u'充电桩没有响应,可能是版本不对或者串口接线不良'})        resultData = devInfo['data']        if resultData[4:6] != '23':            return {'status': '00'}        backCardNo = int(resultData[18:26], 16)        if backCardNo != int(cardNo):            return {'status': '00'}        return {'status': resultData[26:28]}    def get_all_dev_settings(self):        devInfo = MessageSender.send(device=self.device, cmd=DeviceCmdCode.OPERATE_DEV_SYNC,                                     payload={'IMEI': self._device['devNo'], "funCode": '36', 'data': '00'},                                     timeout=MQTT_TIMEOUT.SHORT)        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'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})                    confData = devInfo['data'][18::]                time1 = int(confData[:4], 16)        time2 = int(confData[4:8], 16)        time3 = int(confData[8:12], 16)        card1Time = int(confData[12:16], 16)        card2Time = int(confData[16:20], 16)        card3Time = int(confData[20:24], 16)        icMoney = int(confData[24:28], 16)        cardRefund = True if confData[28:30] == u'01' else False                power1 = int(confData[30:34], 16)        power1ratio = int(confData[34:36], 16)        power2 = int(confData[36:40], 16)        power2ratio = int(confData[40:42], 16)        power3 = int(confData[42:46], 16)        power3ratio = int(confData[46:48], 16)        power4 = int(confData[48:52], 16)        power4ratio = int(confData[52:54], 16)        power5 = int(confData[54:58], 16)        power5ratio = int(confData[58:60], 16)                autoStop = True if confData[60:62] == u'01' else False                fuchongPower = int(confData[62:66], 16)        fuchongTime = int(confData[66:70], 16)        noloadTime = int(confData[70:74], 16)        freeMode = int(confData[74:76], 16)        consumeProcess = int(confData[76:78], 16)        # consumeMode = int(confData[78:80], 16) #无效        consumeMode = freeMode        return {            'time1': time1,            'time2': time2,            'time3': time3,            'card1Time': card1Time,            'card2Time': card2Time,            'card3Time': card3Time,            'icMoney': icMoney,            'cardRefund': cardRefund,            'power1': power1,            'power1ratio': power1ratio,            'power2': power2,            'power2ratio': power2ratio,            'power3': power3,            'power3ratio': power3ratio,            'power4': power4,            'power4ratio': power4ratio,            'power5': power5,            'power5ratio': power5ratio,            'autoStop': autoStop,            'fuchongPower': fuchongPower,            'fuchongTime': fuchongTime,            # 'noloadTime': noloadTime,            'consumeMode': consumeMode,            # 'consumeProcess': consumeProcess,            # 'consumeMode': consumeMode,        }    def format_upload_power(self, power):        return float(power / 10)    
 |