12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898 |
- # -*- coding: utf-8 -*-
- # !/usr/bin/env python
- import datetime
- import logging
- import time
- from decimal import Decimal
- from typing import TYPE_CHECKING
- from apilib.monetary import RMB
- from apilib.utils_string import split_str
- from apps.web.south_intf.yuhuan_fire import YuhuanNorther
- from apps.web.constant import Const, DeviceCmdCode, ErrorCode, DeviceErrorCodeDesc, MQTT_TIMEOUT
- from apps.web.core.adapter.base import SmartBox, fill_2_hexByte, make_six_bytes_session_id
- from apps.web.core.exceptions import ServiceException
- from apps.web.core.networking import MessageSender
- from apps.web.device.models import Device
- from apps.web.user.models import ConsumeRecord
- logger = logging.getLogger(__name__)
- if TYPE_CHECKING:
- from apps.web.device.models import GroupDict
- class GaoBoRuiChargingBox(SmartBox):
- """ 高宝瑞电川版本 """
- def __init__(self, device):
- super(GaoBoRuiChargingBox, self).__init__(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'获取设备设置',
- '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卡回收余额成功',
- }
- 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_from_dev()
- 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)))
- write_data = 'EE0D02{}'.format(make_six_bytes_session_id()) + hexPort + '0000' + hexTime
- devInfo = MessageSender.send(
- device = self.device,
- cmd = DeviceCmdCode.PASSTHROUGH_OPERATE_DEV_SYNC,
- payload = {
- 'IMEI': self._device['devNo'],
- 'funCode': '02',
- 'data': write_data
- }, 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']})
- # 记一笔
- try:
- start_uart_data = {
- 'send': write_data,
- 'receive': devInfo
- }
- ConsumeRecord.objects.filter(orderNo=attachParas['orderNo']).update(
- servicedInfo__start_uart_data=start_uart_data)
- except:
- pass
- Device.update_dev_control_cache(
- self._device['devNo'],
- {
- str(usePort): portDict
- })
- devInfo['finishedTime'] = finishedTime
- # 玉环的对接,放这里吧
- YuhuanNorther.send_dev_status(self._device, int(attachParas['chargeIndex']), 1)
- return devInfo
- def start_device_realiable(self, order):
- attachParas = order.attachParas
- package = order.package
- if attachParas is None:
- raise ServiceException({'result': 2, 'description': u'请您选择合适的充电线路、电池类型信息'})
- if not attachParas.has_key('chargeIndex'):
- raise ServiceException({'result': 2, 'description': u'请您选择合适的充电线路'})
- dev = Device.objects.get(devNo = self._device.devNo)
- 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)))
- result = MessageSender.send(device = self.device,
- cmd = DeviceCmdCode.OPERATE_DEV_SYNC,
- payload = {
- 'IMEI': self._device.devNo,
- 'funCode': '02',
- 'order_id': order.orderNo,
- 'order_type': 'com_start',
- 'data': hexPort + '0000' + hexTime
- },
- timeout = 45,
- retry = 3)
- return result
- 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]
- # todo
- cardNo = str(int(data[26:34], 16))
- backMoney = int()
- 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 == '16': # 高版本的
- port = int(data[8:10], 16)
- leftTime = int(data[10:14], 16)
- elec = int(data[14:18], 16)
- reason = data[18:20]
- 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 == '0B':
- desc = u'设备或端口出现问题,为了安全起见,被迫停止工作。建议您根据已经充电的时间评估是否需要到现场换到其他端口充电。'
- else:
- desc = ''
- return {'status': Const.DEV_WORK_STATUS_IDLE, 'reason': desc, 'cmdCode': cmdCode, 'port': port,
- 'leftTime': leftTime, 'elec': elec, 'isStart': False, '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 == '10': # 用户刷卡上报的信息
- cardNo = data[8:16]
- cardNo = str(int(cardNo, 16))
- preFee = int(data[16:18], 16) / 10.0
- oper = data[18:20]
- return {'cardNo': cardNo, 'preFee': preFee, 'cmdCode': cmdCode, 'oper': oper}
- elif cmdCode == '20': # 启动设备
- port = int(data[8:10], 16)
- needTime = int(data[10:14], 16)
- elec = int(data[14:18], 16)
- consumeType = data[18:20]
- money = int(data[20:22], 16)
- return {'cmdCode': cmdCode, 'port': port, 'needTime': needTime, 'elec': elec, 'consumeType': consumeType,
- 'coins': money}
- elif cmdCode == '03': # 投币上报
- coin = int(data[18:20], 16)
- port = int(data[20:22], 16)
- 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}
- 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):
- 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})
- 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'
- }, timeout = MQTT_TIMEOUT.CHECK_DEVICE_STATUS)
- 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):
- consumeModule = infoDict['consumeModule']
- if consumeModule == 0:
- time1 = int(infoDict['time1'])
- time2 = int(infoDict['time2'])
- time3 = int(infoDict['time3'])
- else:
- time1 = int(infoDict['time1'] * 100)
- time2 = int(infoDict['time2'] * 100)
- time3 = int(infoDict['time3'] * 100)
- data = ''
- data += fill_2_hexByte(hex(int(infoDict['maxPower'])), 4)
- data += fill_2_hexByte(hex(int(infoDict['icMoney'])), 2)
- data += fill_2_hexByte(hex(time1), 4)
- data += fill_2_hexByte(hex(time2), 4)
- data += fill_2_hexByte(hex(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):
- 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:
- Device.get_collection().update_one({'devNo': self._device['devNo']}, {'$set': {'otherConf.putCoins': infoDict['putCoins'], 'otherConf.icCard': infoDict['icCard']}})
- 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)
- consumeModule = data[21]
- if consumeModule == 0:
- time1 = data[0]
- time2 = data[1]
- time3 = data[2]
- card1Time = data[3]
- card2Time = data[4]
- card3Time = data[4]
- else:
- time1 = round(int(data[0]) * 0.01,2)
- time2 = round(int(data[1]) * 0.01,2)
- time3 = round(int(data[2]) * 0.01,2)
- card1Time = round(int(data[3]) * 0.01,2)
- card2Time = round(int(data[4]) * 0.01,2)
- card3Time = round(int(data[5]) * 0.01,2)
- resultDict = {
- 'time1': time1,
- 'time2': time2,
- 'time3': time3,
- 'card1Time': card1Time,
- 'card2Time': card2Time,
- 'card3Time': card3Time,
- 'icMoney': data[6], # 前台单位为角
- 'cardRefund': bool(data[7]),
- # 'power1': data[8],
- # 'power1ratio': data[9],
- # 'power2': data[10],
- # 'power2ratio': data[11],
- # 'power3': data[12],
- 'NC': data[13],
- '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'数据读取失败,请您稍后再试'})
- oldGetSettingsData = self.get_IC_coin_power_config()
- resultDict['icMoney'] = oldGetSettingsData.get('icMoney')
- resultDict['maxPower'] = oldGetSettingsData.get('maxPower')
- coinCardEnable = self.get_coin_card_enable()
- resultDict.update(coinCardEnable)
- try:
- mcuVersion = self.get_mcu_version()
- resultDict.update(mcuVersion)
- except Exception:
- pass
- try:
- powers = self.get_gear_conf()
- resultDict.update(powers)
- except Exception:
- pass
- if resultDict.get('power5'):
- resultDict['maxPower'] = resultDict['power5']
- 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 == '100272':
- resultDict = self.get_dev_all_settings()
- else:
- resultDict = {}
- try:
- tempDict = self.get_IC_coin_power_config()
- resultDict.update(tempDict)
- except Exception:
- pass
- try:
- tempDict = self.get_coin_card_enable()
- resultDict.update(tempDict)
- except Exception:
- pass
- try:
- tempDict = self.get_gear_conf()
- resultDict.update(tempDict)
- except Exception:
- pass
- try:
- tempDict = self.get_fullstop_cardrefund()
- resultDict.update(tempDict)
- except Exception:
- pass
- try:
- mcuVersion = self.get_mcu_version()
- resultDict.update(mcuVersion)
- except Exception:
- pass
- # 兼容刷卡时间 2a指令
- try:
- tempDict = self.get_freemode_volume_andsoon_config()
- resultDict.update(tempDict)
- except Exception:
- pass
- refundProtection = dev.otherConf.get('refundProtection', 0)
- resultDict.update({'refundProtection': refundProtection})
- refundProtectionTime = dev.otherConf.get('refundProtectionTime', 5)
- resultDict.update({'refundProtectionTime': refundProtectionTime})
- 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)
- power2 = int(confData[6:10], 16)
- power2ratio = int(confData[10:12], 16)
- power3 = int(confData[12:16], 16)
- power3ratio = int(confData[16:18], 16)
- 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 = {
- 'power1': power1,
- 'power1ratio': power1ratio,
- 'power2': power2,
- 'power2ratio': power2ratio,
- 'power3': power3,
- 'power3ratio': power3ratio,
- 'power4': power4,
- 'power4ratio': power4ratio,
- 'power5': power5,
- 'power5ratio': power5ratio
- }
- 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'])), 2)
- data += fill_2_hexByte(hex(int(infoDict['power2'])), 4)
- data += fill_2_hexByte(hex(int(infoDict['power2ratio'])), 2)
- data += fill_2_hexByte(hex(int(infoDict['power3'])), 4)
- data += fill_2_hexByte(hex(int(infoDict['power3ratio'])), 2)
- 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_ic_card_realiable(self, cardNo, money, order_no):
- # type:(str,RMB,str)->dict
- 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'
- payload = {
- 'IMEI': self.device.devNo, 'data': data,
- 'funCode': '12', 'order_id': order_no, 'order_type': 'ic_recharge'
- }
- MessageSender.send_no_wait(device = self.device,
- cmd = DeviceCmdCode.PASSTHROUGH_OPERATE_DEV_SYNC,
- payload = payload)
- # 给实体卡充值
- 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
- 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'] 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):
- consumeModule = infoDict['consumeModule']
- if consumeModule == 0:
- card1Time = int(infoDict['card1Time'])
- card2Time = int(infoDict['card2Time'])
- card3Time = int(infoDict['card3Time'])
- else:
- card1Time = int(infoDict['card1Time'] * 100)
- card2Time = int(infoDict['card2Time'] * 100)
- card3Time = int(infoDict['card3Time'] * 100)
- data = fill_2_hexByte(hex(card1Time), 4)
- data += fill_2_hexByte(hex(card2Time), 4)
- data += fill_2_hexByte(hex(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'设置失败,请您稍后再试'})
- 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_device_function_param(self, request, lastSetConf):
- 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': float(request.POST.get('time1', 0))})
- lastSetConf.update({'time2': float(request.POST.get('time2', 0))})
- lastSetConf.update({'time3': float(request.POST.get('time3', 0))})
- self.set_IC_coin_power_config(lastSetConf)
- if request.POST.has_key('elec1') and request.POST.has_key('elec2') and request.POST.has_key('elec3'):
- lastSetConf.update({'elec1': int(float(request.POST.get('elec1', 0)) * 100 )})
- lastSetConf.update({'elec2': int(float(request.POST.get('elec2', 0)) * 100 )})
- lastSetConf.update({'elec3': int(float(request.POST.get('elec3', 0)) * 100 )})
- self.set_IC_coin_power_config(lastSetConf)
- if request.POST.has_key('power1'):
- lastSetConf.update({'power1': int(request.POST.get('power1', 0))})
- lastSetConf.update({'power2': int(request.POST.get('power2', 0))})
- lastSetConf.update({'power3': int(request.POST.get('power3', 0))})
- lastSetConf.update({'power4': int(request.POST.get('power4', 0))})
- lastSetConf.update({'power5': int(request.POST.get('power5', 0))})
- self.set_gear_conf(lastSetConf)
- if request.POST.has_key('power1ratio'):
- lastSetConf.update({'power1ratio': int(request.POST.get('power1ratio', 0))})
- lastSetConf.update({'power2ratio': int(request.POST.get('power2ratio', 0))})
- lastSetConf.update({'power3ratio': int(request.POST.get('power3ratio', 0))})
- lastSetConf.update({'power4ratio': int(request.POST.get('power4ratio', 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': float(request.POST.get('card1Time', 0))})
- lastSetConf.update({'card2Time': float(request.POST.get('card2Time', 0))})
- lastSetConf.update({'card3Time': float(request.POST.get('card3Time', 0))})
- self.set_card_time_config(lastSetConf)
- if 'fuchongPower' in request.POST and 'fuchongTime' in request.POST:
- lastSetConf.update({'fuchongPower': int(request.POST.get('fuchongPower', 0))})
- lastSetConf.update({'fuchongTime': int(request.POST.get('fuchongTime', 0))})
- self.set_fuchong_config(lastSetConf)
- if 'consumeProcess' in request.POST or 'consumeModule' in request.POST:
- lastSetConf.update({'consumeProcess': request.POST.get('consumeProcess', '0')})
- lastSetConf.update({'consumeModule': request.POST.get('consumeModule', '0')})
- self.set_consume_module(lastSetConf)
- if request.POST.has_key('refundProtectionTime'):
- 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 request.POST.has_key('volume'):
- if request.POST.get('volume') != lastSetConf['volume']:
- lastSetConf.update({'volume': int(request.POST.get('volume', 0))})
- self.set_freemode_volume_config(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中也保留一份 方便启动的时候随时查询
- Device.get_collection().update_one({'devNo': self.device.devNo}, {
- '$set': {'otherConf.consumeProcess': int(consumeProcess),
- 'otherConf.consumeModule': int(consumeModule), }})
- 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 get_dev_all_info_by_24(self):
- """
- 24指令
- 获取 总电流[2B]+箱体温度[1B]+输出回路继电器状态[2B]+输出回路功率[20B]+剩余充电时间[20B]
- """
- devInfo = MessageSender.send(device=self.device, cmd=DeviceCmdCode.OPERATE_DEV_SYNC,
- payload={'IMEI': self._device['devNo'], 'funCode': '24', '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'充电桩忙,无响应,请您稍候再试'})
- data = devInfo['data']
- data = data[18:]
- totalAmpere = round(int(data[0:4], 16) * 0.1, 2)
- boxTemperature = round(int(data[4:6], 16), 2)
- if data[4:6] == 'FF':
- boxTemperature = None
- relayStatus ='{:0<10b}'.format(int(data[6:10], 16))
- powers = [data[10 + item: 14 + item] for item in xrange(0, 40, 4)]
- leftTimes = [data[50 + item: 54 + item] for item in xrange(0, 40, 4)]
- portInfo = {}
- for i in xrange(0, 10):
- portInfo[str(i + 1)] = {
- 'status': round(int(relayStatus[i], 16), 2),
- 'power': round(int(powers[i], 16), 2),
- 'leftTime': round(int(leftTimes[i], 16), 2),
- }
- return {'totalAmpere': totalAmpere, 'boxTemperature': boxTemperature, 'portInfo': portInfo}
- def get_all_port_info_by_34(self, returnType='list'):
- """
- returnType : list dict
- """
- devInfo = MessageSender.send(self.device, self.make_random_cmdcode(),
- {'IMEI': self._device['devNo'], 'funCode': '34', 'data': '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'][18:]
- import re
- portStatus = map(lambda d: d, re.findall(r'..', data[:20]))
- portLeftTime = map(lambda d: int(d, 16), re.findall(r'....', data[20:60]))
- portPower = map(lambda d: int(d, 16) / 10.0, re.findall(r'....', data[60:100]))
- portUsedElec = map(lambda d: int(d, 16) / 100.0, re.findall(r'....', data[100:140]))
- ampere = map(lambda d: int(d, 16) / 10.0, re.findall(r'..', data[140:160]))
- if returnType == 'list':
- lis = []
- for i, x in enumerate(portStatus):
- item = {
- 'index': str(i + 1),
- 'portStatus': str(x),
- 'leftTime': str(portLeftTime[i]),
- 'power': str(portPower[i]),
- 'usedElec': str(portUsedElec[i]),
- 'ampere': str(ampere[i]),
- }
- lis.append(item)
- return lis
- if returnType == 'dict':
- lis = []
- for i, x in enumerate(portStatus):
- item = (str(i + 1), {
- 'index': str(i + 1),
- 'portStatus': str(x),
- 'leftTime': str(portLeftTime[i]),
- 'power': str(portPower[i]),
- 'usedElec': str(portUsedElec[i]),
- 'ampere': str(ampere[i]),
- })
- lis.append(item)
- result = dict(lis)
- return result
- def get_dev_all_info_by_42(self):
- """
- 42指令
- 获取 总电流[2B]+箱体温度[1B]+输出回路继电器状态[2B]+输出回路功率[20B]+剩余充电时间[20B]
- """
- devInfo = MessageSender.send(device=self.device, cmd=DeviceCmdCode.OPERATE_DEV_SYNC,
- payload={'IMEI': self._device['devNo'], 'funCode': '42', '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'充电桩忙,无响应,请您稍候再试'})
- data = devInfo['data']
- data = data[18:]
- totalAmpere = round(int(data[0:4], 16) * 0.1, 2)
- boxTemperature = round(int(data[4:6], 16), 2)
- if data[4:6] == 'FF':
- boxTemperature = None
- relayStatus = '{:0<10b}'.format(int(data[6:12], 16))
- powers = [data[12 + item: 16 + item] for item in xrange(0, 96, 4)]
- leftTimes = [data[108 + item: 112 + item] for item in xrange(0, 96, 4)]
- portInfo = {}
- for i in xrange(0, 24):
- portInfo[str(i + 1)] = {
- 'status': round(int(relayStatus[i], 16), 2),
- 'power': round(int(powers[i], 16), 2),
- 'leftTime': round(int(leftTimes[i], 16), 2),
- }
- return {'totalAmpere': totalAmpere, 'boxTemperature': boxTemperature, 'portInfo': portInfo}
- def get_device_function_code(self):
- devInfo = MessageSender.send(device=self.device, cmd=DeviceCmdCode.OPERATE_DEV_SYNC,
- payload={'IMEI': self._device['devNo'], 'funCode': '32', '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'充电桩忙,无响应,请您稍候再试'})
- data = devInfo['data']
- return '{:0>40b}'.format(int(data[18:-2], 16))
- def switch_bill_as_service(self, onOrOff):
- super(GaoBoRuiChargingBox, self).switch_bill_as_service(onOrOff)
- if onOrOff:
- infoDict = {"consumeProcess": self.device['otherConf'].get("consumeProcess", 0), "consumeModule": 1}
- self.set_consume_module(infoDict)
|