123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849 |
- # -*- coding: utf-8 -*-
- #!/usr/bin/env python
- import copy
- import datetime
- import time
- from apps.web.constant import DeviceCmdCode, Const, FAULT_CODE, ErrorCode, MQTT_TIMEOUT
- from apps.web.core.adapter.base import SmartBox
- 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, MyUser, Card
- from apilib.utils_datetime import to_datetime
- from apilib.utils_AES import EncryptDate
- cardKey = 'FR4e1OFCnDdrYA7u'
- class ChargingWEIFULEBox(SmartBox):
- def __init__(self, device):
- super(ChargingWEIFULEBox, self).__init__(device)
- def translate_funcode(self, fun_code):
- fun_codeDict = {
- '01': u'查询所有端口状态',
- '02': u'查询端口详细信息',
- '03': u'上报投币充电事件',
- '04': u'上报刷卡事件',
- '05': u'上报充电结束事件',
- '06': u'远程停止充电',
- '07': u'远程启动充电',
- '08': u'查询投币总额',
- '09': u'清除投币总数',
- '0A': u'查询订单信息',
- }
- return fun_codeDict.get(fun_code, '')
- def translate_event_cmdcode(self, cmdCode):
- cmdDict = {
- }
- return cmdDict.get(cmdCode, '')
- def test(self, coins):
- data = {'fun_code':0x07,'order_id':'1111','coins':coins,'port':1,'time':60}
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': self._device['devNo'], 'data': data})
- return devInfo
-
- def check_feedback_result(self,devInfo):
- if not devInfo.has_key('rst'):
- raise ServiceException({'result': 2, 'description': u'报文异常'})
-
- if devInfo['rst'] == -1:
- raise ServiceException({'result': 2, 'description': u'充电桩正在玩命找网络,请您稍候再试'})
-
- if devInfo['rst'] == 1:
- raise ServiceException({'result': 2, 'description': u'串口通讯失败,您稍候再试,或者联系客服'})
-
- if devInfo['rst'] == 2:
- raise ServiceException({'result': 2, 'description': u'端口被禁用'})
-
- if devInfo['rst'] == 3:
- raise ServiceException({'result': 2, 'description': u'端口计量器故障'})
-
- if devInfo['rst'] == 4:
- raise ServiceException({'result': 2, 'description': u'设备订单已达上限'})
-
- if devInfo['rst'] == 5:
- raise ServiceException({'result': 2, 'description': u'设备正在自检'})
- # result = devInfo['data']['result']
- # if result == 0:
- # return
- # else:#等待设备的错误码进行细化
- # raise ServiceException({'result': 2, 'description': u'充电桩返回了错误,请您重试看看能否解决问题'})
-
- 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'请您选择合适的充电线路'})
- port = int(attachParas['chargeIndex'])
- unit = package.get('unit', u'分钟')
- needTime,power = None,None
- coins = int(float(package['coins'])*100)#单位为分
- onPoints = attachParas.get('onPoints')
- if onPoints: # 远程上分
- self.stop_charging_port(port)
- order_no = ConsumeRecord.make_no()
- else:
- order_no = str(attachParas.get("orderNo"))
- if unit == u'秒':
- if int(package['time']) < 60:
- raise ServiceException({'result': 2, 'description': u'套餐的最小时间不能小于60秒'})
- needTime = int(float(package['time']))
- data = {'fun_code':0x07,'order_id':order_no,'coins':coins,'port':port,'time':needTime}
- elif unit == u'分钟':
- needTime = int(package['time'])*60
- data = {'fun_code':0x07,'order_id':order_no,'coins':coins,'port':port,'time':needTime}
- elif unit == u'小时':
- needTime = int(float(package['time']) * 60 * 60)
- data = {'fun_code':0x07,'order_id':order_no,'coins':coins,'port':port,'time':needTime}
- elif unit == u'天':
- needTime = int(float(package['time']) * 60 * 60 * 24)
- data = {'fun_code':0x07,'order_id':order_no,'coins':coins,'port':port,'time':needTime}
- elif unit == u'度':
- power = int(float(package['time'])*1000000)#微度,需要乘于16个零
- data = {'fun_code':0x07,'order_id':order_no,'coins':coins,'port':port,'elec':power}
- else:
- needTime = int(package['time'])
- data = {'fun_code':0x07,'order_id':order_no,'coins':coins,'port':port,'time':needTime}
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': self._device['devNo'], 'data': data}, timeout = MQTT_TIMEOUT.START_DEVICE)
- self.check_feedback_result(devInfo)
-
- data = devInfo['data']
- if devInfo['rst'] == 0: # 成功
- devInfo['consumeOrderNo'] = data['order']['id']
- newValue = {
- str(port): {
- 'status': Const.DEV_WORK_STATUS_WORKING,
- 'startTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
- }
- }
- else:#TODO result的枚举列出原因
- raise ServiceException({'result': 2, 'description': u'充电桩响应异常,请您稍后再试哦'})
- if needTime:
- finishedTime = int(time.time()) + needTime
- devInfo['needTime'] = needTime/60
- if power:
- finishedTime = int(time.time()) + 60 * 60 * 10#设定10个小时,确实很难知道可以用多久结束
- devInfo['needElec'] = float(package['time'])
- newValue.update({'finishedTime': finishedTime})
- Device.update_dev_control_cache(self._device['devNo'], newValue)
- devInfo['finished_time'] = finishedTime
- devInfo['consumeOrderNo'] = order_no
- return devInfo
- def analyze_event_data(self, data):
- if data['fun_code'] == '34':#如果是结束事件,需要把reason翻译出来
- descDict = {
- '1':u'开始充电,但是没有接充电器',
- '2':u'充电过程中,插座脱落',
- '3':u'用户按下关闭按钮关闭',
- '4':u'用户刷卡结束充电',
- '5':u'远程结束充电',
- '6':u'充电端口故障,为了安全主动关闭',
- '7':u'订购的时间使用完毕',
- '8':u'订购的电量使用完毕',
- '9':u'本端口功率过载,主动关闭',
- '10':u'整机功率过载,主动关闭',
- '11':u'其他异常导致的关闭'
- }
- order = data['order']
- order['reason'] = descDict.get(str(order['closeType']),u'')
- data['order'] = order
- return data
- def get_dev_consume_count(self):
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': self._device['devNo'], 'data': {'fun_code': 0x08}})
-
- self.check_feedback_result(devInfo)
- data = devInfo['data']
- return {'cardFee': data['total_card']/100.0, 'coinFee': data['total_coin']/100.0}#单位为分
-
- def get_many_port_info(self,portList):
- devInfo = MessageSender.send(self.device, self.make_random_cmdcode(),
- {'IMEI': self._device['devNo'], 'data': {'fun_code': 0x12}})
-
- self.check_feedback_result(devInfo)
- resultDict = {}
- for port,data in devInfo['data']['details'].items():
- if port not in portList:
- continue
- result = {'index':port}
- result['status'] = self.__translate_status_from_str(data['status'])
- result['power'] = data.get('watt',0)
- result['ampere'] = data.get('ampr',0) / 1000.0
- result['voltage'] = data.get('volt')
-
- curOrder = None
- for order in data['orders']:
- if order['status'] == 'running':
- curOrder = order
- break
-
- if curOrder:
- result['elec'] = curOrder['elec']
- if curOrder['order_type'] == 'apps_start':
- result['consumeType'] = 'mobile'
- try:
- rcd = ConsumeRecord.objects.get(orderNo = curOrder['id'])
- if u'虚拟卡' in rcd.remarks:
- result['consumeType'] = 'mobile_vcard'
- except Exception,e:
- pass
- elif curOrder['order_type'] == 'coin_start':
- result['consumeType'] = 'coin'
- elif curOrder['order_type'] == 'card_start':
- result['consumeType'] = 'card'
-
- if curOrder.has_key('amount_time'):
- result['needTime'] = round(curOrder['amount_time']/60.0,1)
- if curOrder.has_key('time'):
- result['duration'] = round(curOrder['time']/60.0,1)
- result['usedTime'] = round(curOrder['time']/60.0,1)
- if curOrder.has_key('left_time'):
- result['leftTime'] = round(curOrder['left_time']/60.0,1)
- if curOrder.has_key('amount_elec'):
- result['needElec'] = curOrder['amount_elec']/1000000.0
- if curOrder.has_key('elec'):
- result['elec'] = curOrder.get('elec')/1000000.0
- if curOrder.has_key('execute_time'):
- result['startTime'] = datetime.datetime.fromtimestamp(int(curOrder['execute_time'])).strftime('%m-%d %H:%M:%S')
-
- if curOrder.has_key('id') and (curOrder['order_type'] not in ['coin_start','card_charge']) :#card_charge
- try:
- rcd = ConsumeRecord.objects.get(orderNo = curOrder['id'])
- result['openId'] = rcd['openId']
- result['coins'] = float(str(rcd['coin']))#都用coins
- result['money'] = float(str(rcd['money']))
- result['orderNo'] = str(curOrder['id'])
-
- user = MyUser.objects(openId=result['openId']).first()
- if user:
- result['nickName'] = user.nickname
-
- except Exception,e:#IC卡,如果没有绑定,不会有consumeRcd,应该直接从订单中拿数据
- result['coins'] = float(order['coins']/100.0)
- result['money'] = float(order['coins']/100.0)
- pass
-
- resultDict[port] = result
-
- return resultDict
-
- def get_port_info(self, line):
- devInfo = MessageSender.send(self.device, self.make_random_cmdcode(),
- {'IMEI': self._device['devNo'], 'data': {'fun_code': 0x02, 'port': int(line)}})
-
- self.check_feedback_result(devInfo)
-
- #找出当前正在执行的订单
- result = {}
- data = devInfo['data']
- result['status'] = self.__translate_status_from_str(data['status'])
- result['power'] = data.get('watt',0)
- result['ampere'] = data.get('ampr',0) / 1000.0
- result['voltage'] = data.get('volt')
-
- curOrder = None
- for order in data['orders']:
- if order['status'] == 'running':
- curOrder = order
- break
-
- if curOrder:
- result['elec'] = curOrder['elec']
- if curOrder['order_type'] == 'apps_start':
- result['consumeType'] = 'mobile'
- try:
- rcd = ConsumeRecord.objects.get(orderNo = curOrder['id'])
- if u'虚拟卡' in rcd.remarks:
- result['consumeType'] = 'mobile_vcard'
- except Exception,e:
- pass
- elif curOrder['order_type'] == 'coin_start':
- result['consumeType'] = 'coin'
- elif curOrder['order_type'] == 'card_start':
- result['consumeType'] = 'card'
-
- if curOrder.has_key('amount_time'):
- result['needTime'] = round(curOrder['amount_time']/60.0,1)
- if curOrder.has_key('time'):
- result['duration'] = round(curOrder['time']/60.0,1)
- result['usedTime'] = round(curOrder['time']/60.0,1)
- if curOrder.has_key('left_time'):
- result['leftTime'] = round(curOrder['left_time']/60.0,1)
- if curOrder.has_key('amount_elec'):
- result['needElec'] = curOrder['amount_elec']/1000000.0
- if curOrder.has_key('elec'):
- result['elec'] = curOrder.get('elec')/1000000.0
- if curOrder.has_key('execute_time'):
- result['startTime'] = datetime.datetime.fromtimestamp(int(curOrder['execute_time'])).strftime('%m-%d %H:%M:%S')
- if curOrder.has_key('card_no'):
- result['cardNo'] = str(int(curOrder['card_no'],16))
-
- if curOrder.has_key('id') and (curOrder['order_type'] not in ['coin_start','card_charge']) :#card_charge
- try:
- rcd = ConsumeRecord.objects.get(orderNo = curOrder['id'])
- result['openId'] = rcd['openId']
- result['coins'] = float(str(rcd['coin']))#都用coins
- result['money'] = float(str(rcd['money']))
- result['orderNo'] = str(curOrder['id'])
- except Exception,e:
- pass
-
- return result
-
- def __translate_status_from_str(self,status):
- dictConf = {
- 'idle':Const.DEV_WORK_STATUS_IDLE,
- 'busy':Const.DEV_WORK_STATUS_WORKING,
- 'forbid':Const.DEV_WORK_STATUS_FORBIDDEN,
- 'fault':Const.DEV_WORK_STATUS_FAULT,
- 'running':Const.DEV_WORK_STATUS_WORKING
- }
- return dictConf.get(status,Const.DEV_WORK_STATUS_IDLE)
-
- # 访问设备,获取设备端口信息
- def get_port_status_from_dev(self):
- devInfo = MessageSender.send(self.device, self.make_random_cmdcode(),
- {'IMEI': self._device['devNo'], 'data': {'fun_code': 0x01}})
-
- self.check_feedback_result(devInfo)
- data = devInfo['data']
- result = {}
- portNum = data.get('total',10)
- ii = 0
- while ii < portNum:
- ii += 1
- result[str(ii)] = {'status':self.__translate_status_from_str(data['status'].get(str(ii)))}
- allPorts, usedPorts, usePorts = self.get_port_static_info(result)
- Device.update_dev_control_cache(self._device['devNo'],
- {'allPorts': allPorts, 'usedPorts': usedPorts, 'usePorts': usePorts})
- # 这里存在多线程更新缓存的场景,可能性比较低,但是必须先取出来,然后逐个更新状态,然后再记录缓存
- ctrInfo = Device.get_dev_control_cache(self._device['devNo'])
- for strPort, info in result.items():
- if ctrInfo.has_key(strPort):
- ctrInfo[strPort].update({'status': info['status']})
- else:
- ctrInfo[strPort] = info
- Device.update_dev_control_cache(self._device['devNo'], ctrInfo)
- return result
- def get_port_status(self, force = False):
- if force:
- return self.get_port_status_from_dev()
- ctrInfo = Device.get_dev_control_cache(self._device['devNo'])
- if not ctrInfo.has_key('allPorts'):
- self.get_port_status_from_dev()
- ctrInfo = Device.get_dev_control_cache(self._device['devNo'])
- allPorts = ctrInfo.get('allPorts', 10)
- statusDict = {}
- for ii in range(allPorts):
- tempDict = ctrInfo.get(str(ii + 1), {})
- if tempDict.has_key('status'):
- statusDict[str(ii + 1)] = {'status': tempDict.get('status')}
- elif tempDict.has_key('isStart'):
- if tempDict['isStart']:
- statusDict[str(ii + 1)] = {'status': Const.DEV_WORK_STATUS_WORKING}
- else:
- statusDict[str(ii + 1)] = {'status': Const.DEV_WORK_STATUS_IDLE}
- else:
- statusDict[str(ii + 1)] = {'status': Const.DEV_WORK_STATUS_IDLE}
- allPorts, usedPorts, usePorts = self.get_port_static_info(statusDict)
- Device.update_dev_control_cache(self._device['devNo'],
- {'allPorts': allPorts, 'usedPorts': usedPorts, 'usePorts': usePorts})
- return statusDict
- def lock_unlock_port(self, port, lock = True):
- portInfo = self.get_port_info(port)
- if portInfo and portInfo['status'] == Const.DEV_WORK_STATUS_WORKING and lock:
- raise ServiceException({'result': 2, 'description': u'端口正忙,请先关闭端口后,再禁止端口'})
-
- typeStr = 'deactive' if lock else 'active'
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': self._device['devNo'], 'data': {'port':int(port),'type':typeStr,'fun_code':0x0D}})
-
- self.check_feedback_result(devInfo)
- if devInfo['rst'] == 0:
- if lock:
- Device.update_dev_control_cache(self._device['devNo'], {str(port): {'status': Const.DEV_WORK_STATUS_FORBIDDEN}})
- else:
- Device.update_dev_control_cache(self._device['devNo'], {str(port): {'status': Const.DEV_WORK_STATUS_IDLE}})
- else:
- Device.update_dev_control_cache(self._device['devNo'], {str(port): {'status': Const.DEV_WORK_STATUS_IDLE}})
- def active_deactive_port(self, port, active):
- if active:
- raise ServiceException({'result': 2, 'description': u'该设备不支持直接打开端口'})
- return self.stop_charging_port(port)
-
- #停止该端口下的所有任务
- def stop_charging_port(self, port):
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': self._device['devNo'], 'data': {'fun_code': 0x06, 'port': port}})
-
- self.check_feedback_result(devInfo)
-
- if devInfo['rst'] == 0:
- Device.update_dev_control_cache(self._device['devNo'], {str(port): {'status': Const.DEV_WORK_STATUS_IDLE}})
-
- return True if devInfo['rst'] == 0 else False
-
- def get_order(self,order_no):
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': self._device['devNo'], 'data': {'fun_code': 0x0A, 'order_id': order_no}})
-
- self.check_feedback_result(devInfo)
-
- curOrder = devInfo['data'].get('order',None)
- result = {}
- if not curOrder.has_key('order_type'):#有可能没有订单,应该返回空
- return result
-
- result['status'] = curOrder['status']
- result['elec'] = curOrder['elec']
- if curOrder['order_type'] == 'apps_start':
- result['consumeType'] = 'mobile'
- try:
- rcd = ConsumeRecord.objects.get(orderNo = curOrder['id'])
- if u'虚拟卡' in rcd.remarks:
- result['consumeType'] = 'mobile_vcard'
- except Exception,e:
- pass
- elif curOrder['order_type'] == 'coin_start':
- result['consumeType'] = 'coin'
- elif curOrder['order_type'] == 'card_start':
- result['consumeType'] = 'card'
-
- if curOrder.has_key('amount_time'):
- result['needTime'] = round(curOrder['amount_time']/60.0,1)
- if curOrder.has_key('time'):
- result['duration'] = round(curOrder['time']/60.0,1)
- result['usedTime'] = round(curOrder['time']/60.0,1)
- if curOrder.has_key('left_time'):
- result['leftTime'] = round(curOrder['left_time']/60.0,1)
- if curOrder.has_key('amount_elec'):
- result['needElec'] = curOrder['amount_elec']/1000000.0
- if curOrder.has_key('elec'):
- result['elec'] = curOrder.get('elec')/1000000.0
- if curOrder.has_key('execute_time'):
- result['startTime'] = datetime.datetime.fromtimestamp(int(curOrder['execute_time'])).strftime('%m-%d %H:%M:%S')
- if curOrder.has_key('card_no'):
- result['cardNo'] = str(int(curOrder['card_no'],16))
-
- if curOrder.has_key('id') and (curOrder['order_type'] not in ['coin_start','card_charge']) :#card_charge
- try:
- rcd = ConsumeRecord.objects.get(orderNo = curOrder['id'])
- result['openId'] = rcd['openId']
- result['coins'] = float(str(rcd['coin']))#都用coins
- result['money'] = float(str(rcd['money']))
- result['orderNo'] = str(curOrder['id'])
- except Exception,e:
- return None
-
- return result
-
- def response_card_balance(self, cardNo,balance,result):
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': self._device['devNo'], 'data': {'fun_code':35,'card_no':cardNo,'balance':int(100*float(balance)),'result':result}})
-
- self.check_feedback_result(devInfo)
-
- # 获取设备配置参数
- def get_dev_setting(self):
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': self._device['devNo'], 'data': {'fun_code': 0x0C}})
-
- self.check_feedback_result(devInfo)
-
- result = devInfo['data']
- result.update({
- 'fcharge_watt':result['fcharge']['watt'],
- 'fcharge_time':result['fcharge']['time'],
- 'fcharge_check':result['fcharge'].get('check',10),
- })
- packageElec,packageTime = [],[]
- for name,conf in result['package'].items():
- if name == 'TIME':
- for k,v in conf.items():
- packageTime.append({'price':int(k)/100,'time':v/60})#单位从秒转为分钟
- else:
- for k,v in conf.items():
- packageElec.append({'price':int(k)/100,'time':v/1000000})#单位从微度转为度
-
- result['package_elec'] = packageElec
- result['package_time'] = packageTime
-
- powerRate = []
- for k,v in result['power_rate'].items():
- powerRate.append(v)
- def cmp_power(x,y):
- if x['max'] < y['max']:
- return -1
- elif x['max'] > y['max']:
- return 1
- return 0
- powerRate = sorted(powerRate,cmp_power)
- result['power_rate'] = powerRate
-
- defaultVolume = 0
- volumeList = []
- for k,v in result['volume'].items():
- if k == 'default':
- defaultVolume = v
- else:
- tempList = k.split('-')
- volumeList.append({'start':tempList[0],'end':tempList[1],'volume':v})
- result.pop('volume')
- result['volume'] = defaultVolume
- result['volume_list'] = volumeList
- result['once_card'] = result['once_card'] / 100.0
- result['once_coin'] = result['once_coin'] / 100.0
- state = self.get_dev_consume_count()
- result.update(state)
-
- return result
- # 获取设备配置参数
- def set_dev_setting(self, setConf):
- #如果是卡密码,直接进行修改
- if setConf.has_key('card_pwd'):
- return self.set_card_pwd(setConf['card_pwd'])
-
- #时间套餐不能为空
- if setConf.has_key('package_time') and len(setConf['package_time']) == 0:
- raise ServiceException({'result': 2, 'description': u'按时间计费的套餐不能为空'})
-
- #检查数据
- if not (int(setConf['fcharge_time']) >= 1 and int(setConf['fcharge_time']) <= 300):
- raise ServiceException({'result': 2, 'description': u'浮充时间必须大于等于1分钟,小于等于300分钟'})
-
- if not (int(setConf['fcharge_check']) >= 2 and int(setConf['fcharge_check']) <= 30):
- raise ServiceException({'result': 2, 'description': u'浮充检测时间必须大于等于2分钟,小于等于30分钟'})
-
- if not (int(setConf['fcharge_watt']) >= 20 and int(setConf['fcharge_watt']) <= 100):
- raise ServiceException({'result': 2, 'description': u'浮充功率必须大于等于20瓦,小于等于100瓦'})
-
- if not (int(setConf['volume']) >= 0 and int(setConf['volume']) <= 7):
- raise ServiceException({'result': 2, 'description': u'音量必须大于等于0,小于等于7'})
-
- volumeDict = {'default':int(setConf['volume'])}
- for vl in setConf['volume_list']:
- startTime = to_datetime('2020-01-01 %s:00' % vl['start'])
- endTime = to_datetime('2020-01-01 %s:00' % vl['end'])
- if endTime <= startTime:
- raise ServiceException({'result': 2, 'description': u'结束时间一定要大于起始时间。比如起始时间为07:00,结束时间为23:59'})
- volumeDict['%s-%s' % (vl['start'],vl['end'])] = int(vl['volume'])
-
- setConf.pop('volume')
- setConf.pop('volume_list')
- setConf['volume'] = volumeDict
- setConf['once_card'] = int(float(setConf['once_card'])*100)
- setConf['once_coin'] = int(float(setConf['once_coin'])*100)
- setConf['max_watt'] = int(setConf['max_watt'])
- if not (int(setConf['max_watt']) >= 50 and int(setConf['max_watt']) <= 1000):
- raise ServiceException({'result': 2, 'description': u'最大功率必须大于等于100瓦,小于等于1000瓦'})
-
- setConf.update({'fun_code':0x0B})
- setConf['fcharge'] = {
- 'watt':int(setConf['fcharge_watt']),
- 'time':int(setConf['fcharge_time']),
- 'check':int(setConf['fcharge_check']),
- }
- setConf.pop('fcharge_watt')
- setConf.pop('fcharge_time')
- setConf.pop('fcharge_check')
-
- packageElec,packageTime = {},{}
- isHaveOneCoinForElec,isHaveOneCoinForTime = False,False
- for pConf in setConf['package_time']:
- if pConf['price'] == 1:
- isHaveOneCoinForTime = True
- packageTime[str(int(float(pConf['price'])*100))] = int(float(pConf['time'])*60)
-
- for pConf in setConf['package_elec']:
- if pConf['price'] == 1:
- isHaveOneCoinForElec = True
- packageElec[str(int(float(pConf['price'])*100))] = int(float(pConf['time'])*1000000)
-
- if (setConf['chrmt']=='ELEC' and not isHaveOneCoinForElec) or (setConf['chrmt']=='TIME' and not isHaveOneCoinForTime):
- raise ServiceException({'result': 2, 'description': u'刷卡投币收费模式中,至少需要包含1元的使用套餐'})
- if ( len(packageElec) != len(setConf['package_elec']) ) or ( len(packageTime) != len(setConf['package_time']) ):
- raise ServiceException({'result': 2, 'description': u'套餐价格不允许出现重复'})
-
- setConf.pop('package_time')
- setConf.pop('package_elec')
- setConf['package'] = {'ELEC':packageElec,'TIME':packageTime}
-
- powerRate = {}
- powerList = []
-
- for pConf in setConf['power_rate']:
- powerRate[str(pConf['max'])] = pConf
- powerList.append(int(pConf['max']))
- powerList = sorted(powerList)
-
- powerSetDict = {}
- ii = 0
- prePw = 0
- for pw in powerList:
- ii += 1
- if ii == 1:
- powerSetDict[str(ii)] = {'min':0,'max':pw,'rate':int(powerRate[str(pw)]['rate'])}
- else:
- if int(powerRate[str(pw)]['rate']) < int(powerRate[str(prePw)]['rate']):
- raise ServiceException({'result': 2, 'description': u'功率越大,比例应该越高,这样用户的时间才消耗快一些,您才不会亏哦'})
- powerSetDict[str(ii)] = {'min':prePw,'max':pw,'rate':int(powerRate[str(pw)]['rate'])}
- prePw = pw
-
- setConf.pop('power_rate')
- setConf['power_rate'] = powerSetDict
-
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': self._device['devNo'], 'data': setConf})
-
- self.check_feedback_result(devInfo)
- def ack_event(self,orderNo,funCode):
- devInfo = MessageSender.send(self.device, DeviceCmdCode.PASSTHROUGH_OPERATE_DEV_NO_RESPONSE,
- {'IMEI': self._device['devNo'], 'data': {'fun_code':funCode,'order_id':orderNo}})
-
- self.check_feedback_result(devInfo)
-
- def clear_dev_feecount(self):
-
- devInfo = MessageSender.send(self.device, self.make_random_cmdcode(),
- {'IMEI': self._device['devNo'], 'data': {'fun_code':0x09,'total_coin':True,'total_card':True}})
-
- self.check_feedback_result(devInfo)
-
- def response_card_charge_result(self,cardNo,result):
- MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SERVER_ASYNC,
- {'IMEI': self._device['devNo'], 'data': {'fun_code':37,'card_no':cardNo,'result':result}})
-
- def reboot_device(self):
- data = {'fun_code':0x0B,'reset_mcu':True}
- MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': self._device['devNo'], 'data': data})
-
- MessageSender.async_send(self.device, DeviceCmdCode.SET_DEVINFO,
- {'IMEI': self._device['devNo'], 'restart': True})
-
- def set_device_function(self, request, lastSetConf):
- if request.POST.has_key('clearSum'):
- self.clear_dev_feecount()
- elif request.POST.has_key('reboot'):
- self.reboot_device()
-
- def set_device_function_param(self, request, lastSetConf):
- newConf = copy.deepcopy(request.POST)
- newConf.pop('logicalCode', None)
- self.set_dev_setting(newConf)
-
- # if request.POST.has_key('maxPower') and request.POST.has_key('icMoney'):
- # lastSetConf.update({'maxPower': int(request.POST.get('maxPower', 0))})
- # lastSetConf.update({'icMoney': int(request.POST.get('icMoney', 0))})
- # self.set_IC_coin_power_config(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 request.POST.has_key('fuchongPower') and request.POST.has_key('fuChongTime'):
- # lastSetConf.update({'fuchongPower': int(request.POST.get('fuchongPower', 0))})
- # lastSetConf.update({'fuChongTime': int(request.POST.get('fuChongTime', 0))})
- # self.set_fuchong_config(lastSetConf)
- def get_card_pwd(self):
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': self._device['devNo'], 'data': {'fun_code': 0x11}})
-
- self.check_feedback_result(devInfo)
-
- result = devInfo['data']
- enObj = EncryptDate(cardKey)
- cardPwd = enObj.decrypt(result['card_pwd'])
- if not cardPwd:
- cardPwd = ''
-
- return {'card_pwd':cardPwd}
-
- def translante_card_no(self,hexCardNo):
- return int(hexCardNo,16)
-
- def check_pwd(self,pwd):
- if len(pwd) != 6:
- raise ServiceException({'result': 2, 'description': u'密码必须是6位纯数字密码'})
- for char in pwd:
- if not (char>='0' and char<='9'):
- raise ServiceException({'result': 2, 'description': u'密码必须是6位纯数字密码'})
- return
-
- def set_card_pwd(self,pwd):
- self.check_pwd(pwd)
- enObj = EncryptDate(cardKey)
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': self._device['devNo'], 'data': {'fun_code':0x0B,'card_pwd':enObj.encrypt(pwd)}})
-
- self.check_feedback_result(devInfo)
-
- def set_card_mode(self,setConf):
- cardMode = int(setConf.get('card_mode'))
- valueDict = {'fun_code':0x10}
- if cardMode == 0:
- valueDict.update({'mode':cardMode})
- elif cardMode == 1:#格式化为离线卡
- self.check_pwd(setConf['new_pwd'])
- newPwd = setConf['new_pwd']
- if not str(setConf['balance']).isdigit():
- raise ServiceException({'result': 2, 'description': u'余额必须是数字'})
- balance = int(setConf['balance'])
- if not (balance >=0 and balance <= 5000):
- raise ServiceException({'result': 2, 'description': u'余额必须在0和5000元之间'})
- balance = balance * 10#硬件模块记录的单位是角
- enObj = EncryptDate(cardKey)
- valueDict.update({'mode':1,'new_pwd':enObj.encrypt(str(newPwd)),'balance':balance})
- elif cardMode == 2:
- self.check_pwd(setConf['old_pwd'])
- self.check_pwd(setConf['new_pwd'])
- newPwd = setConf['new_pwd']
- oldPwd = setConf['old_pwd']
- enObj = EncryptDate(cardKey)
- valueDict.update({'mode':2,'old_pwd':enObj.encrypt(str(oldPwd)),'new_pwd':enObj.encrypt(str(newPwd))})
-
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': self._device['devNo'], 'data': valueDict})
-
- self.check_feedback_result(devInfo)
-
- def get_card_mode(self):
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': self._device['devNo'], 'data': {'fun_code': 0x11}})
- self.check_feedback_result(devInfo)
-
- cardMode = devInfo['data']['card_mode']
- return {'card_mode':cardMode}
-
- def check_alarm(self,alarm):
- if alarm.faultCode == FAULT_CODE.MCU_REBOOT:
- return u'此告警,建议您多观察,如果比较频繁不停上报单台设备的告警,可能会运行不稳定。需要您联系技术支持确认。'
- elif alarm.faultCode == FAULT_CODE.COUNTER_FAULT:
- portInfo = self.get_port_info(alarm.portNo)
- if portInfo['status'] == Const.DEV_WORK_STATUS_FAULT:
- return u'此端口目前已经为故障状态,继电器可能运行不稳定,建议您联系技术支持,以确认设备运行情况。'
- else:
- return u'端口状态检查正常,继电器或存偶尔无法获取数据。暂不影响使用。'
- elif alarm.faultCode == FAULT_CODE.RELAY_FAULT:
- return u'无法进行远程诊断,建议您到现场,直接插上插座,然后检查是否不用付款,就能够充电。如果是的,就属于继电器粘连。'
- elif alarm.faultCode == FAULT_CODE.DEV_OVERLOAD:
- return u'整机功率最大限定为7500瓦,接入的负载超过此负载,为了安全,将强行关闭所有充电端口。'
- elif alarm.faultCode == FAULT_CODE.COPY_CARD:
- return u'出现一模一样的卡,可能是用户复制了另外一张离线卡,然后使用,会给您造成经济上的损失,建议冻结。'
- return ''
-
- def get_part_info(self):
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': self._device['devNo'], 'data': {'fun_code': 0x05}})
- self.check_feedback_result(devInfo)
-
- partInfo = devInfo['data']
- result = {}
- nameDesc = {'networkBoard':u'网络板','chargeBoard':u'充电板','cardBoard':u'刷卡板'}
- for k,v in partInfo.items():
- if k not in nameDesc:
- continue
-
- result[nameDesc.get(k)] = {'SN':v}
-
- return result
- def recharge_card(self, cardNo, money, orderNo=None):
- hex_cardNo = hex(int(cardNo))[2::].replace('L', '').upper()
- result = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SERVER_ASYNC,
- {'IMEI': self.device['devNo'],
- 'data': {'fun_code': 37, 'result': 1, 'card_no': hex_cardNo,
- 'charge': int(money * 100),
- 'order_id': orderNo}})
- # 返回验证
- self.check_feedback_result(result)
- card = Card.objects.filter(cardNo=cardNo,dealerId=self.device.ownerId).first()
- balance = card.balance + money
- return {
- 'result': ErrorCode.SUCCESS,
- 'description': ''
- }, balance
-
- def get_customize_score_unit(self):
- return u'元'
-
- def get_customize_package_unit(self):
- chrmt = self.device['otherConf'].get('chrmt')
- if not chrmt:
- chrmt = self.get_dev_setting().get('chrmt')
-
- # 按时间计费
- if chrmt == 'TIME' or chrmt == 'POWER':
- return u'分钟'
- # 按电量计费
- elif chrmt == 'ELEC':
- return u'度'
-
- return u'元'
-
- def start_customize_point(self,pointNum,openId,port):
- unit = self.get_customize_package_unit()
- package = {'name':'customizePoint','price':pointNum,'coins':pointNum,'unit':unit,'time':999} # 如果是时间,就用时间作为兜底的控制,钱填大一些;
- attachParas = {'chargeIndex':port,'onPoints':True}
- return self.start_device(package, openId, attachParas)
|