123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923 |
- # -*- coding: utf-8 -*-
- # !/usr/bin/env python
- import datetime
- import logging
- import time
- from decimal import Decimal
- from typing import TYPE_CHECKING
- from apilib.utils import is_number
- from apilib.monetary import RMB
- from apilib.utils_string import split_str
- from apps.web.constant import Const, DeviceCmdCode, ErrorCode, DeviceErrorCodeDesc, MQTT_TIMEOUT, CONSUMETYPE
- from apps.web.core.adapter.base import SmartBox, fill_2_hexByte, make_six_bytes_session_id
- from apps.web.core.exceptions import ServiceException, InvalidParameter
- from apps.web.core.networking import MessageSender
- from apps.web.device.models import Device, DeviceType
- from apps.web.south_intf.yuhuan_fire import YuhuanNorther
- logger = logging.getLogger(__name__)
- if TYPE_CHECKING:
- from apps.web.device.models import GroupDict
- class ChargingZHIXIA2Box(SmartBox):
- def __init__(self, device):
- super(ChargingZHIXIA2Box, self).__init__(device)
- def _start_device_for_card(self, needTime, portStr):
- """
- 刷卡启动
- :param needTime:
- :param portStr:
- :return:
- """
- hexTime = "{:04X}".format(int(needTime))
- hexPort = "{:02X}".format(int(portStr))
- 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
- )
- def _check_package(self, package):
- """
- 获取设备启动的发送数据 根据设备的当前模式以及套餐获取
- :param package:
- :return:
- """
- consumeModule = self._device.get("otherConf", dict()).get("consumeModule", 0)
- unit = package.get("unit", u"分钟")
- _time = float(package.get("time", 0))
- # 按时间计费
- if consumeModule == 0:
- 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'获取设备设置',
- '06': u'获取设备端口详情',
- '07': u'获取刷卡投币统计数据',
- '08': 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卡回收余额成功',
- }
- 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'])
- 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'])
- devInfo['rst'] = ErrorCode.SUCCESS
- 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,
- 'payInfo': list()
- }
- ctrInfo = Device.get_dev_control_cache(self._device.devNo)
- lastPortInfo = ctrInfo.get(str(usePort), {})
- 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 attachParas.get('redpackId'):
- if is_continus:
- redpackInfo = lastPortInfo.get("redpackInfo", list())
- if not redpackInfo:
- logger.warning("miss redpackInfo! {}-{}".format(self._device["devNo"], usePort))
- else:
- redpackInfo = list()
- redpackInfo.append({'redpackId': str(attachParas['redpackId'])})
- portDict['redpackInfo'] = redpackInfo
- else:
- if is_continus:
- portDict['redpackInfo'] = lastPortInfo.get("redpackInfo", list())
- else:
- portDict['redpackInfo'] = list()
- 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
- else:
- if is_continus:
- portDict['payInfo'] = lastPortInfo.get("payInfo", list())
- else:
- portDict['payInfo'] = list()
- 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
- # 玉环的对接,放这里吧
- YuhuanNorther.send_dev_status(self._device, attachParas['chargeIndex'], '1')
- 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]
- devType = DeviceType.objects(id=self.device['devType']['id']).first()
- finishedReasonDict = devType.finishedReasonDict
- if finishedReasonDict != {}:
- desc_map = finishedReasonDict
- else:
- desc_map = {
- '00': u'购买的充电时间或电量用完了。',
- '01': u'插头被拔或者松动,或者电瓶已经充满(系统判断为异常断电,电瓶车充电器种类繁多,可能存在误差)',
- '02': u'电池已经充满',
- '03': u'设备或者端口故障。建议您根据已经充电的时间评估是否需要到现场换到其他端口充电',
- '04': u'警告!您的电池功率超过本机最大限制。为了公共安全,不建议您在该充电桩充电',
- '05': u'刷卡退费结束',
- '06': u'可能是插头被拔掉或者未连接充电器。如果不是自己操作,建议您到现场检查是否有人误操作',
- '07': u'远程方式停止充电。如果不是自己操作,建议到现场尽快恢复充电'
- }
- desc = desc_map.get(reason, 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 = 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}
- elif cmdCode == "2C":
- # 中润易和独有 参数意义分别是卡号 端口号 刷卡次数
- return {"cmdCode": cmdCode, "cardNo": str(int(data[18:26], 16)), "portStr": str(int(data[26:28], 16)), "num": int(data[28:30], 16)}
- def get_dev_consume_count(self):
- 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):
- support_06 = self._device.get('otherConf', {}).get('support_06', True)
- if not support_06:
- return {'port': 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("consumeModule", 0):
- data.update({"leftTime": leftTime})
- else:
- data.update({"leftElec": leftTime / 100.0})
- if self.device.bill_as_service_feature.on:
- ctrInfo = Device.get_dev_control_cache(self._device['devNo'])
- needElec = ctrInfo[line]['needElec']
- usedElec = needElec - leftTime / 100.0
- elecCharge = self.device.bill_as_service_feature.elec_charge
- serviceCharge = self.device.bill_as_service_feature.service_charge
- elecFee = float(elecCharge * usedElec)
- serviceFee = float(serviceCharge * usedElec)
- consumeMoney = elecFee + serviceFee
- data.update({"elecFee": elecFee, "serviceFee" : serviceFee,'consumeMoney':consumeMoney})
- return data
- # 访问设备电流
- def get_port_elec_from_dev(self):
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': self._device['devNo'], "funCode": '21', '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'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})
- portData = devInfo['data'][18::]
- port1 = int(portData[2:4], 16)
- port2 = int(portData[4:6], 16)
- port3 = int(portData[6:8], 16)
- port4 = int(portData[8:10], 16)
- port5 = int(portData[10:12], 16)
- port6 = int(portData[12:14], 16)
- port7 = int(portData[14:16], 16)
- port8 = int(portData[16:18], 16)
- port9 = int(portData[18:20], 16)
- port10 = int(portData[20:22], 16)
- device = int(portData[22:24], 16)
- return {
- 'port1': port1,
- 'port2': port2,
- 'port3': port3,
- 'port4': port4,
- 'port5': port5,
- 'port6': port6,
- 'port7': port7,
- 'port8': port8,
- 'port9': port9,
- 'port10': port10,
- 'device': device,
- }
- # 访问设备
- def get_port_temperature_from_dev(self):
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': self._device['devNo'], "funCode": '22', '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'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})
- portData = devInfo['data'][18::]
- port1 = int(portData[2:4], 16)
- port2 = int(portData[4:6], 16)
- port3 = int(portData[6:8], 16)
- port4 = int(portData[8:10], 16)
- port5 = int(portData[10:12], 16)
- port6 = int(portData[12:14], 16)
- port7 = int(portData[14:16], 16)
- port8 = int(portData[16:18], 16)
- port9 = int(portData[18:20], 16)
- port10 = int(portData[20:22], 16)
- device = int(portData[22:24], 16)
- return {
- 'port1': port1,
- 'port2': port2,
- 'port3': port3,
- 'port4': port4,
- 'port5': port5,
- 'port6': port6,
- 'port7': port7,
- 'port8': port8,
- 'port9': port9,
- 'port10': port10,
- 'device': device,
- }
- # 访问设备,获取设备端口信息
- def get_port_status_from_dev(self):
- 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
- if self.device.devTypeCode == Const.DEVICE_TYPE_CODE_CHARGING_DIANCHUAN_HIGH:
- default_num = 2
- 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("consumeModule", 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
- # 获取IC卡、投币、最大功率设置
- def get_IC_coin_power_config(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
- return {'maxPower': maxPower, 'icMoney': icMoney, 'time1': time1,
- 'time2': time2, 'time3': time3}
- 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'充电桩忙,无响应,请您稍候再试'})
- otherConf = self.device.get("otherConf") or dict()
- otherConf.update(infoDict)
- Device.objects.filter(devNo=self.device.devNo).update(otherConf=otherConf)
- Device.invalid_device_cache(self.device.devNo)
- def get_coin_card_enable(self):
- devs = Device.get_collection().find({'devNo': self._device['devNo']})
- if devs.count == 0:
- raise ServiceException(
- {'result': 2, 'description': u'没有找到设备哦'})
- return {'putCoins': devs[0].get('otherConf', {}).get('putCoins', False),
- 'icCard': devs[0].get('otherConf', {}).get('icCard', False)}
- 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'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})
- try:
- conf = Device.objects.get(devNo = self._device['devNo']).otherConf
- conf.update({'putCoins': infoDict['putCoins'], 'icCard': infoDict['icCard']})
- Device.get_collection().update_one({'devNo': self._device['devNo']}, {'$set': {'otherConf': conf}})
- except Exception, e:
- logger.error('update dev=%s coin enable ic enable e=%s' % (self._device['devNo'], e))
- def get_dev_all_settings(self):
- """
- 电川PCB- DC_Crg_10L_C4.0及以上版本 支持全部参数一起查询 多参数消费流程 消费方式
- :return:
- """
- result = MessageSender.send(device = self.device, cmd = DeviceCmdCode.OPERATE_DEV_SYNC, payload = {
- "IMEI": self._device["devNo"],
- "data": "00",
- "funCode": "36"
- }, timeout = MQTT_TIMEOUT.SHORT)
- rst = result.get("rst")
- if rst == -1:
- raise ServiceException({'result': 2, 'description': u'充电桩正在玩命找网络,请您稍候再试'})
- elif rst == 1:
- raise ServiceException({'result': 2, 'description': u'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})
- elif rst == 0:
- data = split_str(result.get('data'), lens = "4444444242424224442222", startIndex = 18, toInt = True)
- resultDict = {
- "time1": data[0],
- "time2": data[1],
- "time3": data[2],
- "card1Time": data[3],
- "card2Time": data[4],
- "card3Time": data[5],
- "icMoney": data[6], # 前台单位为角
- "cardRefund": bool(data[7]),
- "power1": data[8],
- "power1ratio": data[9] * 10,
- "power2": data[10],
- "power2ratio": data[11] * 10,
- "power3": data[12],
- "power3ratio": data[13] * 10,
- "autoStop": bool(data[14]),
- "fuchongPower": data[15] * 0.1,
- "fuchongTime": data[16],
- "noPowerTime": data[17],
- "chargeFree": bool(data[18]),
- "volume": data[19],
- "consumeProcess": data[20],
- "consumeModule": data[21]
- }
- else:
- raise ServiceException({'result': 2, 'description': u"数据读取失败,请您稍后再试"})
- # TODO zjl 这个地方主板的读取所有参数对于icMoney这个字段读取的是错误的值,需要再使用旧的读取指令读取一遍,然后更新,等主板更正过来之后删除这一次的读取
- oldGetSettingsData = self.get_IC_coin_power_config()
- resultDict['icMoney'] = oldGetSettingsData.get("icMoney")
- resultDict['maxPower'] = oldGetSettingsData.get("maxPower")
- coinCardEnable = self.get_coin_card_enable()
- resultDict['putCoins'] = coinCardEnable['putCoins']
- resultDict['icCard'] = coinCardEnable['icCard']
- return resultDict
- # 获取设备配置参数
- def get_dev_setting(self):
- driverCode = self._device.get("devType", dict()).get("code", "")
- dev = Device.objects.get(devNo = self._device['devNo']) # type: Device
- if driverCode == Const.DEVICE_TYPE_CODE_CHARGING_DIANCHUAN_HIGH:
- resultDict = self.get_dev_all_settings()
- else:
- resultDict = self.get_IC_coin_power_config()
- tempDict = self.get_coin_card_enable()
- resultDict.update(tempDict)
- tempDict = self.get_gear_conf()
- resultDict.update(tempDict)
- tempDict = self.get_fullstop_cardrefund()
- resultDict.update(tempDict)
- # 兼容刷卡时间 2a指令
- try:
- tempDict = self.get_freemode_volume_andsoon_config()
- except Exception:
- tempDict = {
- 'volume': '',
- 'card1Time': '',
- 'card2Time': '',
- 'card3Time': '',
- 'fuchongPower': dev.otherConf.get('fuchongPower', ''),
- 'fuchongTime': dev.otherConf.get('fuchongTime', '')
- }
- finally:
- resultDict.update(tempDict)
- cardNoRangeStart = dev.otherConf.get('cardNoRangeStart', '')
- resultDict.update({'cardNoRangeStart': cardNoRangeStart})
- cardNoRangeEnd = dev.otherConf.get('cardNoRangeEnd', '')
- resultDict.update({'cardNoRangeEnd': cardNoRangeEnd})
- tempDict = self.get_temperature_voltage_threshold()
- resultDict.update(tempDict)
- return resultDict
- # 获取设备配置参数
- def set_dev_setting(self, setConf):
- keys = setConf.keys()
- if 'putCoins' in keys or 'icCard' in keys:
- self.set_coin_card_enable(setConf)
- if 'maxPower' in keys or 'icMoney' in keys or 'time1' in keys or 'time2' in keys or 'time3' in keys:
- self.set_IC_coin_power_config(setConf)
- def get_IC_card_password(self):
- devInfo = MessageSender.send(device = self.device, cmd = DeviceCmdCode.OPERATE_DEV_SYNC,
- payload = {'IMEI': self._device['devNo'], "funCode": '1A', '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::]
- result = confData[0:2]
- if result == '00':
- cardPassword = ''
- else:
- cardPassword = str(int(confData[2:12]))
- return {'cardPassword': cardPassword}
- 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
- return {'autoStop': True if confData[20:22] == u'01' else False,
- 'cardRefund': True if confData[18:20] == u'01' else False}
- 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'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})
- try:
- conf = Device.objects.get(devNo = self._device['devNo']).otherConf
- conf.update({'autoStop': infoDict['autoStop'], 'cardRefund': infoDict['cardRefund']})
- Device.get_collection().update({'devNo': self._device['devNo']}, {'$set': {'otherConf': conf}})
- except Exception, e:
- logger.error('update dev=%s coin enable ic enable e=%s' % (self._device['devNo'], e))
- 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) * 10
- power2 = int(confData[6:10], 16)
- power2ratio = int(confData[10:12], 16) * 10
- power3 = int(confData[12:16], 16)
- power3ratio = int(confData[16:18], 16) * 10
- result = {
- 'power1': power1, 'power1ratio': power1ratio, 'power2': power2,
- 'power2ratio': power2ratio, 'power3': power3, 'power3ratio': power3ratio
- }
- if self.device.devTypeCode == Const.DEVICE_TYPE_CODE_ZHANGRUNYIHE:
- power4 = int(confData[18:22], 16)
- power4ratio = int(confData[22:24], 16) * 10
- power5ratio = int(confData[24:26], 16) * 10
- result.update({'power4': power4, 'power4ratio': power4ratio,
- 'power5ratio': power5ratio})
- else:
- if len(confData) > 31:
- power4 = int(confData[18:22], 16)
- power4ratio = int(confData[22:24], 16) * 10
- power5 = int(confData[24:28], 16)
- power5ratio = int(confData[28:30], 16) * 10
- result.update({'power4': power4, 'power4ratio': power4ratio,
- 'power5': power5, 'power5ratio': power5ratio,
- 'support5PowerTi': True})
- return result
- def set_gear_conf(self, infoDict):
- data = ''
- data += fill_2_hexByte(hex(int(infoDict['power1'])), 4)
- data += fill_2_hexByte(hex(int(infoDict['power1ratio']) / 10), 2)
- data += fill_2_hexByte(hex(int(infoDict['power2'])), 4)
- data += fill_2_hexByte(hex(int(infoDict['power2ratio']) / 10), 2)
- data += fill_2_hexByte(hex(int(infoDict['power3'])), 4)
- data += fill_2_hexByte(hex(int(infoDict['power3ratio']) / 10), 2)
- if self.device.devTypeCode == Const.DEVICE_TYPE_CODE_ZHANGRUNYIHE:
- data += fill_2_hexByte(hex(int(infoDict['power4'])), 4)
- data += fill_2_hexByte(hex(int(infoDict['power4ratio']) / 10), 2)
- data += fill_2_hexByte(hex(int(infoDict['power5ratio']) / 10), 2)
- else:
- if 'power4' in infoDict:
- data += fill_2_hexByte(hex(int(infoDict['power4'])), 4)
- data += fill_2_hexByte(hex(int(infoDict['power4ratio']) / 10), 2)
- data += fill_2_hexByte(hex(int(infoDict['power5'])), 4)
- data += fill_2_hexByte(hex(int(infoDict['power5ratio']) / 10), 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):
- # type:(str,RMB)->(dict, RMB)
- 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
- # 获取IC卡、投币、最大功率设置
- def get_freemode_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)
- # chargeFree = True if confData[12:14] == '01' else False
- chargeFree = 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 {'card1Time': card1Time, 'card2Time': card2Time, 'card3Time': card3Time,
- 'chargeFree': chargeFree, 'volume': volume, 'fuchongPower': fuchongPower,
- 'fuchongTime': fuchongTime}
- def get_mcu_version(self):
- devInfo = MessageSender.send(device = self.device, cmd = DeviceCmdCode.OPERATE_DEV_SYNC,
- payload = {'IMEI': self._device['devNo'], "funCode": '25', '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::]
- mcuVersion = int(confData[0:4], 16)
- return {'mcuVersion': mcuVersion}
- def set_freemode_volume_config(self, infoDict):
- data = '01' if infoDict['chargeFree'] == '1' else '00'
- 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):
- 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'充电桩忙,无响应,请您稍候再试'})
- dev = Device.objects.get(devNo = self._device['devNo'])
- dev.otherConf.update({'fuchongPower': int(infoDict['fuchongPower'])})
- dev.otherConf.update({'fuchongTime': int(infoDict['fuchongTime'])})
- dev.save()
- 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_IC_card_password(self, infoDict):
- passwordStr = str(infoDict['cardPassword'])
- if len(passwordStr) < 6 or len(passwordStr) > 12:
- raise ServiceException({'result': 2, 'description': u'密码长度不合法, 请重新设置'})
- data = passwordStr.rjust(12, '0')
- devInfo = MessageSender.send(device = self.device, cmd = DeviceCmdCode.OPERATE_DEV_SYNC,
- payload = {'IMEI': self._device['devNo'], 'funCode': '18', 'data': data},
- timeout = MQTT_TIMEOUT.SHORT)
- def set_IC_card_range(self, infoDict):
- cardNoRangeStart = str(infoDict['cardNoRangeStart'])
- cardNoRangeEnd = str(infoDict['cardNoRangeEnd'])
- if int(cardNoRangeStart) > 4294967295 or int(cardNoRangeEnd) > 4294967295 or int(cardNoRangeStart) > int(
- cardNoRangeEnd):
- raise ServiceException({'result': 2, 'description': u'卡号设置不合法, 请重新设置'})
- cardNoRangeStart = cardNoRangeStart.rjust(10, '0')
- cardNoRangeEnd = cardNoRangeEnd.rjust(10, '0')
- data = cardNoRangeStart + cardNoRangeEnd
- devInfo = MessageSender.send(device = self.device, cmd = DeviceCmdCode.OPERATE_DEV_SYNC,
- payload = {'IMEI': self._device['devNo'], 'funCode': '19', 'data': data},
- timeout = MQTT_TIMEOUT.SHORT)
- dev = Device.objects.get(devNo = self._device['devNo'])
- dev.otherConf.update({'cardNoRangeStart': str(infoDict['cardNoRangeStart'])})
- dev.otherConf.update({'cardNoRangeEnd': str(infoDict['cardNoRangeEnd'])})
- dev.save()
- def set_no_power_time(self, infoDict):
- """
- 指令是0x37 可能是 双路大功率独有的 需要找主板厂家确认一下
- 设置充电器移除时间 相当于负载检测 5-999秒
- 设置浮充功率 进入浮充时间的最低功率 单位0.1w 0-99.9w
- 设置浮充时间 进入浮充之后 的充电时间 120-999秒
- :param infoDict:
- :return:
- """
- fuchongPower = infoDict["fuchongPower"]
- fuchongTime = infoDict["fuchongTime"]
- noPowerTime = infoDict["noPowerTime"]
- if fuchongPower > 99.9:
- raise ServiceException({"result": 2, "description": u"浮充功率设置范围为0-99.9w"})
- if fuchongTime > 999 or fuchongTime < 100:
- raise ServiceException({"result": 2, "description": u"浮充时间设置范围为120-999秒"})
- if noPowerTime > 999 or noPowerTime < 5:
- raise ServiceException({"result": 2, "decription": u"充电器移除时间设置范围为5-999秒"})
- result = MessageSender.send(
- device=self.device,
- cmd=DeviceCmdCode.OPERATE_DEV_SYNC,
- payload={
- "IMEI": self.device.devNo,
- "funCode": "37",
- "data": "{:0>4X}{:0>4X}{:0>4X}".format(int(fuchongPower*10), int(fuchongTime), int(noPowerTime))
- }
- )
- if result.get('rst') == -1:
- raise ServiceException({'result': 2, 'description': u'充电桩正在玩命找网络,请您稍候再试'})
- elif result.get('rst') == 1:
- raise ServiceException({'result': 2, 'description': u'充电桩忙,无响应,请您稍候再试'})
- else:
- if result["data"][18:20] != "01":
- raise ServiceException({"result": 2, "description": u"设置失败,请您稍后再试"})
- otherConf = self.device.get("otherConf", dict())
- otherConf.update({"fuchongPower": fuchongPower, "fuchongTime": fuchongTime, "noPowerTime": noPowerTime})
- Device.objects.filter(devNo=self.device.devNo).update(otherConf=otherConf)
- 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('chargeFree'):
- # chargeFree = True if request.POST.get('chargeFree') == 'true' else False
- chargeFree = request.POST.get("chargeFree", False)
- lastSetConf.update({'chargeFree': chargeFree})
- self.set_freemode_volume_config(lastSetConf)
- def set_elecCharge_function(self,elecCharge):
- data = fill_2_hexByte(hex(int(elecCharge * 100)), 4)
- devInfo = MessageSender.send(
- device=self.device,
- cmd=DeviceCmdCode.OPERATE_DEV_SYNC,
- payload={'IMEI': self._device['devNo'], "funCode": '50', 'data': data},
- timeout=MQTT_TIMEOUT.SHORT
- )
- if "rst" in devInfo and devInfo.get("rst") != 0:
- if devInfo.get("rst") == -1:
- raise ServiceException({"result": 2, "description": u"网络故障,请重新试试"})
- if devInfo.get("rst") == 1:
- raise ServiceException({"result": 2, "description": u"充电桩无响应,请稍后再试试"})
- return devInfo
- def get_elecCharge_function(self):
- time.sleep(15)
- data = 'EE0951{}'.format(make_six_bytes_session_id()) + '01'
- devInfo = MessageSender.send(
- device=self.device,
- cmd=DeviceCmdCode.PASSTHROUGH_OPERATE_DEV_SYNC,
- payload={'IMEI': self._device['devNo'], "funCode": '51', 'data': data},
- timeout=MQTT_TIMEOUT.SHORT
- )
- if "rst" in devInfo and devInfo.get("rst") != 0:
- if devInfo.get("rst") == -1:
- raise ServiceException({"result": 2, "description": u"网络故障,请重新试试"})
- if devInfo.get("rst") == 1:
- raise ServiceException({"result": 2, "description": u"充电桩无响应,请稍后再试试"})
- elecCharge = round(float(int(devInfo['data'][18:22],16)) / 100,2)
- return elecCharge
- def set_device_function_param(self, request, lastSetConf):
- # 和 主板厂家沟通 目前已经不会存在 有maxPower这个控制选项 maxPower 就是分档功率中的最高档功率
- if request.POST.has_key('icMoney'):
- lastSetConf.update({'icMoney': int(request.POST.get('icMoney', 0))})
- self.set_IC_coin_power_config(lastSetConf)
- if "noPowerTime" in request.POST:
- lastSetConf.update({
- "noPowerTime": int(request.POST["noPowerTime"]),
- "fuchongPower": int(request.POST["fuchongPower"]),
- "fuchongTime": int(request.POST["fuchongTime"]),
- })
- self.set_no_power_time(lastSetConf)
- if request.POST.has_key('time1') and request.POST.has_key('time2') and request.POST.has_key('time3'):
- 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 request.POST.has_key('power1') and request.POST.has_key('power1ratio'):
- 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 request.POST.has_key('card1Time') and request.POST.has_key('card2Time') and request.POST.has_key(
- 'card3Time'):
- 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 = 0 if request.POST.get('fuchongPower') == '' else int(request.POST.get('fuchongPower'))
- fuchongTime = 0 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 "consumeProcess" in request.POST and "consumeModule" in request.POST:
- lastSetConf.update({"consumeProcess": request.POST.get("consumeProcess")})
- lastSetConf.update({"consumeModule": request.POST.get("consumeModule")})
- self.set_consume_module(lastSetConf)
- if 'cardPassword' in request.POST:
- lastSetConf.update({'cardPassword': int(request.POST.get('cardPassword', 0))})
- self.set_IC_card_password(lastSetConf)
- if 'cardNoRangeStart' in request.POST and 'cardNoRangeEnd' in request.POST:
- lastSetConf.update({'cardNoRangeStart': int(request.POST.get('cardNoRangeStart', 0))})
- lastSetConf.update({'cardNoRangeEnd': int(request.POST.get('cardNoRangeEnd', 0))})
- self.set_IC_card_range(lastSetConf)
- if request.POST.has_key('voltageThre') and request.POST.has_key('temThre'):
- lastSetConf.update({'voltageThre': int(request.POST.get('voltageThre', 230))})
- lastSetConf.update({'temThre': int(request.POST.get('temThre', 60))})
- self.set_temperature_voltage_threshold(lastSetConf)
- 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 set_consume_module(self, infoDict):
- """
- 设置消费模式以及消费流程
- 包含两个参数 consumeProcess 消费流程 consumeModule 消费方式
- :param infoDict:
- :return:
- """
- consumeProcess = infoDict.get("consumeProcess", 0)
- consumeModule = infoDict.get("consumeModule", 0)
- consumeProcessHex = fill_2_hexByte(hex(int(consumeProcess)), 2)
- consumeModuleHex = fill_2_hexByte(hex(int(consumeModule)), 2)
- result = MessageSender.send(device = self.device, cmd = DeviceCmdCode.OPERATE_DEV_SYNC, payload = {
- "IMEI": self._device["devNo"],
- "funCode": "38",
- "data": consumeProcessHex + consumeModuleHex
- }, timeout = MQTT_TIMEOUT.SHORT)
- rst = result.get("rst")
- data = result.get("data")
- if rst == 0 and data[-4:-2] == "01":
- # OtherConf中也保留一份 方便启动的时候随时查询
- otherConf = self._device.get("otherConf", dict())
- otherConf.update({
- "consumeProcess": int(consumeProcess),
- "consumeModule": int(consumeModule)
- })
- Device.objects.filter(devNo = self._device["devNo"]).update(otherConf = otherConf)
- Device.invalid_device_cache(self._device["devNo"])
- return
- elif data[-4: -2] != "01":
- raise ServiceException({'result': 2, 'description': u'设置失败,请重新试试'})
- elif rst == -1:
- raise ServiceException({'result': 2, 'description': u'充电桩正在玩命找网络,请您稍候再试'})
- elif rst == 1:
- raise ServiceException({'result': 2, 'description': u'充电桩忙,无响应,请您稍候再试'})
- else:
- raise ServiceException({'result': 2, 'description': u'未知错误'})
- def get_temperature_voltage_threshold(self):
- devObj = Device.objects.get(devNo = self._device['devNo'])
- return {'temThre': devObj.otherConf.get('temThre', 230), 'voltageThre': devObj.otherConf.get('voltageThre', 60)}
- def set_temperature_voltage_threshold(self, infoDict):
- data = ''
- data += fill_2_hexByte(hex(int(infoDict['temThre'])), 2)
- data += fill_2_hexByte(hex(int(infoDict['voltageThre'])), 4)
- devInfo = MessageSender.send(device = self.device, cmd = DeviceCmdCode.OPERATE_DEV_SYNC,
- payload = {'IMEI': self._device['devNo'], "funCode": 'AA', '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'充电桩忙,无响应,请您稍候再试'})
- devObj = Device.objects.get(devNo = self._device['devNo'])
- devObj.otherConf['temThre'] = int(infoDict['temThre'])
- devObj.otherConf['voltageThre'] = int(infoDict['voltageThre'])
- devObj.save()
- def format_upload_power(self, power):
- return float(power / 10)
- ################ api相关接口
- def apiGetPortStatusFromDc(self, record):
- return self.get_port_status_from_dev()
- def apiGetDevSettingsFromDc(self, record):
- result = self.get_dev_setting()
- data = dict()
- data['power1'] = result['power1']
- data['power2'] = result['power2']
- data['power3'] = result['power3']
- data['power1ratio'] = result['power1ratio']
- data['power2ratio'] = result['power2ratio']
- data['power3ratio'] = result['power3ratio']
- data['fuchongTime'] = result['fuchongTime']
- data['fuchongPower'] = result['fuchongPower']
- data['maxPower'] = result['maxPower']
- data['icMoney'] = result['icMoney']
- data['time1'] = result['time1']
- data['time2'] = result['time2']
- data['time3'] = result['time3']
- return data
- def apisetDevSettingsFromDc(self, record):
- self.set_IC_coin_power_config(record)
- self.set_gear_conf(record)
- self.set_fuchong_config(record)
- return {}
- def apiGetPortInfoFromDc(self, record):
- return self.get_port_info(record['port'])
- def apiStartDeviceForDc(self, record):
- port = hex(int(record['port']))
- hexPort = fill_2_hexByte(port, 2)
- coins = float(record['price'])
- hexTime = fill_2_hexByte(hex(int(record['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(record['port'])
- 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:
- raise ServiceException(
- {'result': 2, 'description': u'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})
- else:
- raise ServiceException(
- {
- 'result': 2,
- 'description': u'启动设备失败,您的支付金额已经退回,请重新扫码设备({})'.format(devInfo['rst'])
- })
- portDict = {
- 'startTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
- 'status': Const.DEV_WORK_STATUS_WORKING,
- 'coins': coins,
- 'price': coins,
- 'isApi': True
- }
- Device.update_dev_control_cache(
- self._device['devNo'],
- {
- str(usePort): portDict
- })
- return devInfo
- def get_server_setting(self):
- if self.device.devTypeCode == Const.DEVICE_TYPE_CODE_CHARGING_DIANCHUAN_HIGH:
- default_refund_protection_time = 3
- else:
- default_refund_protection_time = 5
- return {
- 'refundProtectionTime': int(
- self.device.get_other_conf_item('refundProtectionTime', default_refund_protection_time)),
- }
- def set_server_setting(self, payload):
- refundProtectionTime = int(payload['refundProtectionTime'])
- self.device.update_other_conf(refundProtectionTime=refundProtectionTime)
- def set_service_fee_info(self, payload):
- elecCharge = round(float(payload['billAsService'].get('elecCharge', 0.5)), 2)
- serviceCharge = round(float(payload['billAsService'].get('serviceCharge', 0.5)), 2)
- total = elecCharge + serviceCharge
- result = self.set_elecCharge_function(total)
- if result['data'][18:20] != '01':
- raise InvalidParameter(u'电费参数设置失败')
- # 显示展示给用户信息部分
- if payload.get('displaySwitchs'):
- displaySwitchs = payload.get('displaySwitchs')
- else:
- displaySwitchs = {'displayCoinsSwitch': False,
- 'displayTimeSwitch': True,
- 'displayPriceSwitch': True,
- 'setPulseAble': False,
- 'setBasePriceAble': False}
- # 套餐部分
- packages = payload.get('packages')
- # 调整SN套餐顺序
- for i, item in enumerate(packages):
- item['sn'] = i
- # 套餐id 去重
- existIds = list(map(lambda _: _.get('id'), packages))
- washConfig = {}
- for rule in packages:
- if 'price' in rule:
- if not is_number(rule['price'] and is_number(rule.get('time', 0))):
- raise InvalidParameter(u'金币数目或者时间或者价格必须是数字')
- if RMB(rule['price']) >= self.device.owner.maxPackagePrice:
- raise InvalidParameter(u'套餐金额超限')
- if len(rule['name']) > 20:
- raise InvalidParameter(u'套餐名字只能取1-20位')
- if 'id' in rule:
- ruleId = rule['id']
- else:
- ruleId = list(set(range(1, 71)) - set([int(ruleId) for ruleId in washConfig.keys()]) - set(existIds))[0]
- washConfig[str(ruleId)] = {
- 'billingMethod': CONSUMETYPE.BILL_AS_SERVICE,
- 'name': rule['name'],
- 'coins': float(rule['price']),
- 'price': float(rule['price']),
- 'time': float(rule.get('time', 0)),
- 'description': rule.get('description', ''),
- 'imgList': rule.get('imgList', []),
- 'unit': rule.get('unit', u'分钟'),
- 'switch': rule.get('switch', True),
- 'sn': rule.get('sn')
- }
- total = elecCharge + serviceCharge
- self.device.update_device_obj(**{
- 'washConfig': washConfig,
- 'otherConf.displaySwitchs': displaySwitchs,
- 'otherConf.consumeModule': 1,
- 'otherConf.billingType': 'elec',
- 'otherConf.totalCharge': total,
- 'devType.features.billAsService.elecCharge': elecCharge,
- 'devType.features.billAsService.serviceCharge': serviceCharge
- })
- dealer = self.device.owner
- dealer.defaultWashConfig[self.device.devTypeId] = self.device['washConfig'].values()
- dealer.save()
- def get_service_fee_info(self):
- ruleList = []
- for packageId, rule in self.device['washConfig'].items():
- item = {
- 'id': packageId,
- 'name': rule['name'],
- 'coins': rule['coins'],
- 'price': rule.get('price', rule['coins']),
- 'time': rule.get('time', 20),
- 'description': rule.get('description', ''),
- 'imgList': rule.get('imgList', []),
- 'unit': rule.get('unit', u'分钟'),
- 'switch': rule.get('switch', True),
- }
- if 'sn' in rule:
- item['sn'] = rule['sn']
- ruleList.append(item)
- billAsService = self.device.bill_as_service_feature
- devData = {
- 'id': self.device.devNo,
- 'isManager': True,
- 'groupName': self.device.group['groupName'],
- 'groupNumber': self.device['groupNumber'],
- 'devNo': self.device.devNo,
- 'devTypeName': self.device.devTypeName,
- 'devTypeCode': self.device.devTypeCode
- }
- if "displaySwitchs" in self.device.my_obj.otherConf:
- displaySwitchs = self.device.my_obj.otherConf.get('displaySwitchs')
- else:
- displaySwitchs = {
- 'displayCoinsSwitch': True,
- 'displayTimeSwitch': True,
- 'displayPriceSwitch': True,
- "setPulseAble": False,
- "setBasePriceAble": False
- }
- ruleList = sorted(ruleList, key=lambda x: (x.get('sn'), x.get('id')))
- return {
- 'ruleList': ruleList,
- 'billAsService': billAsService,
- 'devData': devData,
- 'displaySwitchs': displaySwitchs,
- }
|