# -*- coding: utf-8 -*- # !/usr/bin/env python import datetime import logging import random, time from apps.web.constant import DeviceCmdCode, Const from apps.web.core.adapter.base import SmartBox, fill_2_hexByte, make_cartcp_order_no, reverse_hex, hexbyte_2_bin 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 ServiceProgress from apps.web.core.adapter.base import string_to_ascstring from apps.web.common.proxy import ClientConsumeModelProxy logger = logging.getLogger(__name__) class NengpaiBox(SmartBox): def __init__(self, device): super(NengpaiBox, self).__init__(device) def translate_funcode(self, fun_code): fun_codeDict = { '12': u'读取实时监测数据', '34': u'运营平台远程控制启机', '36': u'运营平台远程停机', '42': u'远程账户余额更新', '44': u'上报充电结束事件', '46': u'离线卡数据清除', '48': u'离线卡数据查询', '52': u'充电桩工作参数设置', '56': u'对时设置', '58': u'计费模型设置', } return fun_codeDict.get(fun_code, '') def translate_event_cmdcode(self, cmdCode): cmdDict = { } return cmdDict.get(cmdCode, '') @property def isHaveStopEvent(self): return True def get_port_from_ab(self, portAB): portConf = {'A':1, 'B':2, 'C':3} if portAB in portConf: return portConf[portAB] return int(portAB) def get_abport_from_index(self, port): portConf = {'1':'A', '2':'B', '3':'C'} return portConf.get(port) def test(self, coins): data = '6830007C0034%s012018061914444680%s01000000100000000000000000D14B0A54A0860100' % (self._device['devNo'], self._device['devNo']) sendMsg = {'IMEI':self._device['devNo'], 'cmd': 0x34, 'data': data, 'sqNo': '007C','reply':'device'} devInfo = MessageSender.send(self.device, '34', sendMsg) return devInfo def check_feedback_result(self, cmd, devInfo): if not devInfo.has_key('rst'): raise ServiceException({'result': 2, 'description': u'报文异常'}) if devInfo['rst'] == -1: raise ServiceException({'result': 2, 'description': u'充电桩正在玩命找网络,请您稍候再试'}) if not devInfo.has_key('data'): return data = devInfo['data'] if cmd == '36': errCode = data[-8:-6] if errCode == '01': return codeDesc = data[-6:-4] if codeDesc == '01': raise ServiceException({'result': 2, 'description': u'停止失败,设备编号不匹配'}) elif codeDesc == '02': raise ServiceException({'result': 2, 'description': u'停止失败,枪未处于充电状态'}) elif codeDesc == '03': raise ServiceException({'result': 2, 'description': u'停止失败,原因未知'}) elif cmd == '58': codeDesc = data[-6:-4] if codeDesc == '00': raise ServiceException({'result': 2, 'description': u'计费模型下发到设备失败,请您重新尝试'}) elif cmd == '34': codeDesc = data[-6:-4] if codeDesc == '01': raise ServiceException({'result': 2, 'description': u'设备编号不匹配'}) elif codeDesc == '02': raise ServiceException({'result': 2, 'description': u'枪已在充电'}) elif codeDesc == '03': raise ServiceException({'result': 2, 'description': u'设备故障'}) elif codeDesc == '04': raise ServiceException({'result': 2, 'description': u'设备离线'}) elif codeDesc == '05': raise ServiceException({'result': 2, 'description': u'未插枪'}) def check_dev_status(self, attachParas=None): if attachParas.get("isTempPackage") == True: washConfig = self.device.get("tempWashConfig", {}) else: washConfig = self.device.get("washConfig", {}) packageId = attachParas.get("packageId") if not packageId: # 快捷支付过来的 第一次拉起支付的时候已经校验通过了 return package = washConfig.get(packageId) # self._check_package(package) if package.get('name') == '充满自停' and package.get('coins') == 0 and package.get('price') == 0: port = int(attachParas['chargeIndex']) lineInfo = Device.get_dev_control_cache(self.device.devNo).get(str(port), {}) if lineInfo.get('status') == Const.DEV_WORK_STATUS_WORKING: raise ServiceException({'result': 2, 'description': u'当前端口已处于工作状态,无法使用充满自停套餐, 请换个端口进行充电'}) def make_sqNo(self): return fill_2_hexByte(hex(random.randint(0x0000, 0xFFFF))) def register_service_progress(self, openId, weifuleOrderNo, consumeOrder=None, attachParas=None): return ServiceProgress.objects.create( open_id=openId, device_imei=self.device.devNo, devTypeCode='300001', port=1, attachParas=attachParas if attachParas else {}, start_time=int(time.time()), finished_time=int(time.time() + 24 * 60 * 60), consumeOrder=consumeOrder if consumeOrder else {}, weifuleOrderNo=weifuleOrderNo, expireAt=datetime.datetime.now() + datetime.timedelta(days=91) ).id def _start(self, money, port, orderNo): amount = fill_2_hexByte(hex(int(float(money) * 100)), 8, True) sqNo = self.make_sqNo() data = '6830' + sqNo + '0034' + orderNo + self._device['devNo'] + fill_2_hexByte(hex(int(port)), 2) + '0000000000000000' + '0000000000000000' + amount payload = {'sqNo':sqNo, 'data':data, 'reply':'device'} return MessageSender.send(self.device, '34', payload) 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(self.get_port_from_ab(attachParas['chargeIndex'])) onPoints = attachParas.get('onPoints') if onPoints: # 远程上分 orderNo = make_cartcp_order_no(self._device['devNo'], port) logger.info('dealer onPoints package<{}> order<{}>'.format(package, orderNo)) else: orderNo = str(attachParas.get('orderNo')) coins = package.get('coins') result = self._start(coins, port, orderNo) self.check_feedback_result('34', result) data = result['data'] errCode = data[-6:-4] if errCode == '00': consumeOrder = { 'orderNo': orderNo, 'coin': package.get('coins'), 'consumeType': 'mobile', } self.register_service_progress(openId, orderNo, consumeOrder, attachParas) Device.update_dev_control_cache(self._device['devNo'], {str(port):{'coins':package.get('coins')}}) return {'rst':0} return {'rst':int(errCode)} def reply_authentication(self, payload): data = '680C' + payload['sqNo'] + '0002' + self._device['devNo'] + '00' msg = {'IMEI':self._device['devNo'], 'sqNo':payload['sqNo'], 'data':data, 'reply':'server'} devInfo = MessageSender.send(self._device, '02', msg) self.check_feedback_result('02', devInfo) def send_qrcode(self): sqNo = self.make_sqNo() data = '6832' + sqNo + '00F0' + self._device['devNo'] + '00' + '25' + '687474703A2F2F7777772E7761736870617965722E636F6D2F757365724C6F67696E3F6C3D' # data = '680E' + sqNo + '00F0' + self._device['devNo'] + '00' + '01' + '68' payload = {'IMEI':self._device['devNo'],'sqNo':sqNo, 'data':data, 'reply':'device'} return MessageSender.send(self.device, 'F0', payload) # 单独处理北科新能源的二维码下发(JC充电桩与服务平台交互协议V1.4) def send_qrcode2(self): sqNo = self.make_sqNo() str = self._device['devNo'] devNo = string_to_ascstring(str) if not self._device['ownerId']: # 用于注册设备 data = '683A' + sqNo + '009C' + '01' + '33' + '00' + '687474703A2F2F7777772E7761736870617965722E636F6D2F757365724C6F67696E3F6C3D' + devNo else: portNum = Device.get_dev_control_cache(self.device['devNo']).get('allPorts', 2) # 判断枪的数量,若为单枪则固定二维码后缀的枪号为01 if int(portNum) == 1: data = '683C' + sqNo + '009C' + '01' + '35' + '00' + '687474703A2F2F7777772E7761736870617965722E636F6D2F757365724C6F67696E3F6C3D' + devNo + '3031' else: data = '683A' + sqNo + '009C' + '01' + '33' + '00' + '687474703A2F2F7777772E7761736870617965722E636F6D2F757365724C6F67696E3F6C3D' + devNo def reply_feemode(self, payload): feeNo = payload['data'][-8:-4] serverFeeNo = self._device.otherConf.get('feeMode', {}).get('modeNo', '') check = '00' if feeNo == serverFeeNo else '01' data = '680E' + payload['sqNo'] + '0006' + self._device['devNo'] + feeNo + check msg = {'IMEI':self._device['devNo'], 'sqNo':payload['sqNo'], 'data':data, 'reply':'server'} devInfo = MessageSender.send(self._device, '06', msg) self.check_feedback_result('06', devInfo) """ 请参考如下格式feeMode的数据 {'modeNo':'0001','jianFee':2.00000,'jianServe':0.16540, 'fengFee':3.00000,'fengServe':0.16540, 'pingFee':4.00000,'pingServe':0.16540, 'guFee':5.00000,'guServe':0.16540, 'jishunScale':0, 'shiduan':'0000000000000000000000000000000000000000000000000' } """ def reply_new_feemode(self, payload): feeMode = self._device.otherConf.get('feeMode') if not feeMode: raise ServiceException({'result':2, 'description':u'设备没有初始化计费模型,请检查数据'}) feeData = feeMode['modeNo'] + fill_2_hexByte(hex(int(feeMode['jianFee'] * 100000)), 8, True) + fill_2_hexByte(hex(int(feeMode['jianServe'] * 100000)), 8, True) \ + fill_2_hexByte(hex(int(feeMode['fengFee'] * 100000)), 8, True) + fill_2_hexByte(hex(int(feeMode['fengServe'] * 100000)), 8, True)\ + fill_2_hexByte(hex(int(feeMode['pingFee'] * 100000)), 8, True) + fill_2_hexByte(hex(int(feeMode['pingServe'] * 100000)), 8, True)\ + fill_2_hexByte(hex(int(feeMode['guFee'] * 100000)), 8, True) + fill_2_hexByte(hex(int(feeMode['guServe'] * 100000)), 8, True)\ + fill_2_hexByte(hex(int(feeMode['jishunScale'])), 2, True) for ii in range(48): temp = '00' if feeMode['shiduan'][ii] == '0' else '01' feeData += temp data = '685E' + payload['sqNo'] + '000A' + self._device['devNo'] + feeData msg = {'IMEI':self._device['devNo'], 'sqNo':payload['sqNo'], 'data':data, 'reply':'server'} devInfo = MessageSender.send(self._device, '0A', msg) self.check_feedback_result('0A', devInfo) return devInfo def reply_heartbeat(self, payload): data = '680D' + payload['sqNo'] + '0004' + self._device['devNo'] + payload['data'][-8:-6] + '00' msg = {'IMEI':self._device['devNo'], 'sqNo':payload['sqNo'], 'data':data, 'reply':'server'} devInfo = MessageSender.send(self._device, '04', msg) self.check_feedback_result('04', devInfo) return devInfo def stop(self, port=None): port = self.get_port_from_ab(port) sqNo = self.make_sqNo() data = '680C' + sqNo + '0036' + self._device['devNo'] + fill_2_hexByte(hex(port), 2) msg = {'IMEI':self._device['devNo'], 'sqNo':sqNo, 'data':data, 'reply':'device'} devInfo = MessageSender.send(self._device, '36', msg) self.check_feedback_result('36', devInfo) return devInfo def reply_finished_order(self, payload, strResult): data = '6815' + payload['data'][4:8] + '0040' + payload['data'][12:44] + strResult msg = {'IMEI':self._device['devNo'], 'sqNo':payload['data'][4:8], 'data':data, 'reply':'server'} devInfo = MessageSender.send(self._device, '40', msg) self.check_feedback_result('40', devInfo) return devInfo def reply_card_start(self, sqNo, orderNo, port, cardNo, balance, success, replyResult): data = '682A' + sqNo + '0032' + orderNo + self._device['devNo'] + fill_2_hexByte(hex(port), 2) + fill_2_hexByte(hex(int(cardNo)), 16) + fill_2_hexByte(hex(int(balance)), 8) + success + replyResult msg = {'IMEI':self._device['devNo'], 'sqNo':sqNo, 'data':data, 'reply':'server'} devInfo = MessageSender.send(self._device, '32', msg) self.check_feedback_result('32', devInfo) return devInfo def send_current_time(self): nowTime = datetime.datetime.now() hexTime = reverse_hex(fill_2_hexByte(hex(nowTime.second*1000), 4)) + fill_2_hexByte(hex(nowTime.minute), 2) + fill_2_hexByte(hex(nowTime.hour), 2) \ + fill_2_hexByte(hex(nowTime.day), 2) + fill_2_hexByte(hex(nowTime.month), 2) + fill_2_hexByte(hex(nowTime.year - 2000), 2) sqNo = self.make_sqNo() data = '6812' + sqNo + '0056' + self._device['devNo'] + hexTime msg = {'IMEI':self._device['devNo'], 'sqNo':sqNo, 'data':data, 'reply':'device'} devInfo = MessageSender.send(self._device, '56', msg) self.check_feedback_result('56', devInfo) return devInfo def get_many_port_info(self, portList): resultDict = {} ctrInfo = Device.get_dev_control_cache(self._device['devNo']) for port in portList: portIndex = self.get_port_from_ab(port) valueDict = ctrInfo.get(str(portIndex)) valueDict.update({'index':port}) resultDict[port] = valueDict return resultDict def get_port_info(self, line): line = self.get_port_from_ab(line) return Device.get_dev_control_cache(self._device['devNo']).get(str(line), {}) def get_values_from_data(self, data): port = int(data[58:60]) valueDict = {} valueDict['index'] = port status = data[60:62] portStatus = Const.DEV_WORK_STATUS_IDLE if status == '00': # 端口离线是个什么鬼?先不处理吧 pass elif status == '01': portStatus = Const.DEV_WORK_STATUS_FAULT elif status == '02': portStatus = Const.DEV_WORK_STATUS_IDLE elif status == '03': portStatus = Const.DEV_WORK_STATUS_WORKING else: pass valueDict['status'] = portStatus qiangGuiwei = data[62:64] # 枪是否归位 if qiangGuiwei == '00': valueDict['qiangGuiwei'] = 'no' elif qiangGuiwei == '01': valueDict['qiangGuiwei'] = 'yes' else: valueDict['qiangGuiwei'] = 'unknow' if data[64:66] == '00': # //是否插枪 valueDict['isPlugin'] = 'no' else: valueDict['isPlugin'] = 'yes' valueDict['voltage'] = int(reverse_hex(data[66:70]), 16) / 10.0 valueDict['current'] = int(reverse_hex(data[70:74]), 16) / 10.0 # 电流,用什么显示呢? 还有电量,需要确认 valueDict['plugLineTemper'] = int(reverse_hex(data[74:76]), 16) / 10.0 valueDict['duration'] = int(reverse_hex(data[96:100]), 16) # valueDict['leftTime'] = int(reverse_hex(data[100:104]),16)/10.0 # 这个数据从测试看,貌似不准,就直接去掉吧 valueDict['elec'] = int(reverse_hex(data[104:112]), 16) / 10000.0 valueDict['jishunElec'] = int(reverse_hex(data[112:120]), 16) / 10000.0 valueDict['chargedMoney'] = int(reverse_hex(data[120:128]), 16) / 10000.0 binString = hexbyte_2_bin(data[128:130]) + hexbyte_2_bin(data[130:132]) binString = binString[::-1] faultDesc = '' if binString[0] == '1': faultDesc += u'急停按钮动作故障' if binString[1] == '1': faultDesc += u'无可用整流模块;' if binString[2] == '1': faultDesc += u'出风口温度过高;' if binString[3] == '1': faultDesc += u'交流防雷故障;' if binString[4] == '1': faultDesc += u'交直流模块 DC20 通信中断;' if binString[5] == '1': faultDesc += u'绝缘检测模块 FC08 通信中断;' if binString[6] == '1': faultDesc += u'电度表通信中断;' if binString[7] == '1': faultDesc += u'读卡器通信中断;' if binString[8] == '1': faultDesc += u'RC10 通信中断;' if binString[9] == '1': faultDesc += u'风扇调速板故障;' if binString[10] == '1': faultDesc += u'直流熔断器故障;' if binString[11] == '1': faultDesc += u'高压接触器故障;' if binString[12] == '1': faultDesc += u'门打开;' valueDict['faultDesc'] = faultDesc return valueDict # 访问设备,获取设备端口信息 。不支持从设备上获取信息,直接从缓存取 def get_port_status_from_dev(self): ctrInfo = Device.get_dev_control_cache(self._device['devNo']) result = {'1':ctrInfo.get('1', {}), '2':ctrInfo.get('2', {})} return result # result = {} # allPorts = ctrInfo.get('allPorts', 2) # for ii in range(allPorts): # sqNo = self.make_sqNo() # data = '680C' + sqNo + '0012' + self._device['devNo'] + '%02d' % (ii + 1) # msg = {'IMEI':self._device['devNo'],'sqNo':sqNo,'data':data,'reply':'device'} # devInfo = MessageSender.send(self._device, '12', msg) # self.check_feedback_result('12', devInfo) # valueDict = self.get_values_from_data(devInfo['data']) # Device.update_dev_control_cache(self.device['devNo'],{str(ii+1):valueDict}) # result[str(ii+1)] = valueDict # # return result def get_port_status(self, force=False): 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', 2) statusDict = {} abcDict = {'1':'A', '2':'B'} for ii in range(allPorts): tempDict = ctrInfo.get(str(ii + 1), {}) lock = self._device.otherConf.get(str(ii + 1), False) if tempDict.has_key('status'): statusDict[abcDict[str(ii + 1)]] = {'status': tempDict.get('status')} elif tempDict.has_key('isStart'): if tempDict['isStart']: statusDict[abcDict[str(ii + 1)]] = {'status': Const.DEV_WORK_STATUS_WORKING} else: statusDict[abcDict[str(ii + 1)]] = {'status': Const.DEV_WORK_STATUS_IDLE} else: statusDict[abcDict[str(ii + 1)]] = {'status': Const.DEV_WORK_STATUS_IDLE} if lock: statusDict[abcDict[str(ii + 1)]] = {'status':Const.DEV_WORK_STATUS_FORBIDDEN} 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): devObj = Device.objects.get(devNo = self.device['devNo']) port = self.get_port_from_ab(port) portInfo = self.get_port_info(port) if portInfo and portInfo['status'] == Const.DEV_WORK_STATUS_WORKING and lock: raise ServiceException({'result': 2, 'description': u'端口正忙,请先关闭端口后,再禁止端口'}) devObj.otherConf[str(port)] = lock devObj.save() 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 stop_charging_port(self, port): devInfo = self.stop(port) return True if devInfo['rst'] == 0 else False def get_policy_infos(self): feeMode = self._device.otherConf.get('feeMode', {}) timeRateList = [] shiduan = feeMode.get('shiduan', '000000000000000000000000000000000000000000000000') for ii in range(48): startHour = 0 + ii / 2 startMin = '00' if ii % 2 == 0 else '30' endHour = startHour if ii % 2 == 0 else startHour + 1 endMin = '30' if ii % 2 == 0 else '00' startTime = '%02d:%s' % (startHour, startMin) endTime = '%02d:%s' % (endHour, endMin) timeRateList.append({'startTime':startTime, 'endTime':endTime, 'rate':shiduan[ii]}) result = {'top_price_rate':feeMode.get('jianFee', 1.2), 'top_price_service_rate':feeMode.get('jianServe', 0), 'peak_price_rate':feeMode.get('fengFee', 1.2), 'peak_price_service_rate':feeMode.get('fengServe', 0), 'normal_price_rate':feeMode.get('pingFee', 1.2), 'normal_price_service_rate':feeMode.get('pingServe', 0), 'valley_price_rate':feeMode.get('guFee', 1.2), 'valley_price_service_rate':feeMode.get('guServe', 0), 'jishunScale':feeMode.get('jishunScale', 0), 'timeRateList':timeRateList} return result # 获取设备配置参数 def get_dev_setting(self): """ 从主板上读取数据显示在前台 :return: """ return self.get_policy_infos() # 获取设备配置参数 def set_dev_setting(self, setConf): """ :param setConf: :return: """ return 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): devObj = Device.objects.get(devNo = self.device['devNo']) feeMode = devObj.otherConf.get('feeMode', {}) feeMode['modeNo'] = '0001' feeMode['jianFee'] = float(request.POST.get('top_price_rate')) feeMode['jianServe'] = float(request.POST.get('top_price_service_rate')) feeMode['fengFee'] = float(request.POST.get('peak_price_rate')) feeMode['fengServe'] = float(request.POST.get('peak_price_service_rate')) feeMode['pingFee'] = float(request.POST.get('normal_price_rate')) feeMode['pingServe'] = float(request.POST.get('normal_price_service_rate')) feeMode['guFee'] = float(request.POST.get('valley_price_rate')) feeMode['guServe'] = float(request.POST.get('valley_price_service_rate')) feeMode['jishunScale'] = float(request.POST.get('jishunScale', 0)) shiduan = '' for ii in range(48): startHour = 0 + ii / 2 startMin = '00' if ii % 2 == 0 else '30' endHour = startHour if ii % 2 == 0 else startHour + 1 endMin = '30' if ii % 2 == 0 else '00' startTime = '%02d:%s' % (startHour, startMin) endTime = '%02d:%s' % (endHour, endMin) print startTime, endTime harfHourValue = '0' for conf in request.POST.get('timeRateList'): if startTime >= conf['startTime'] and endTime <= conf['endTime']: harfHourValue = conf['rate'] break else: continue shiduan += harfHourValue feeMode['shiduan'] = shiduan # 发送数据给设备 feeData = feeMode['modeNo'] + fill_2_hexByte(hex(int(feeMode['jianFee'] * 100000)), 8, True) + fill_2_hexByte(hex(int(feeMode['jianServe'] * 100000)), 8, True) \ + fill_2_hexByte(hex(int(feeMode['fengFee'] * 100000)), 8, True) + fill_2_hexByte(hex(int(feeMode['fengServe'] * 100000)), 8, True)\ + fill_2_hexByte(hex(int(feeMode['pingFee'] * 100000)), 8, True) + fill_2_hexByte(hex(int(feeMode['pingServe'] * 100000)), 8, True)\ + fill_2_hexByte(hex(int(feeMode['guFee'] * 100000)), 8, True) + fill_2_hexByte(hex(int(feeMode['guServe'] * 100000)), 8, True)\ + fill_2_hexByte(hex(int(feeMode['jishunScale'])), 2, True) for ii in range(48): temp = '00' if feeMode['shiduan'][ii] == '0' else '01' feeData += temp sqNo = self.make_sqNo() data = '685E' + sqNo + '0058' + self._device['devNo'] + feeData msg = {'IMEI':self._device['devNo'], 'sqNo':sqNo, 'data':data, 'reply':'device'} devInfo = MessageSender.send(self._device, '58', msg) self.check_feedback_result('58', devInfo) # 设备那边正确响应后,才能够存入数据库中 devObj.save() def get_signal(self): return {'rst':0, 'signal':self._device.signal} def active_deactive_port(self, port, active): if active == False: self.stop(port) def start_device_swap(self, portNo): consumeOrderNo = make_cartcp_order_no(self._device['devNo'], portNo) devInfo = self._start(100, portNo, consumeOrderNo) if not devInfo.has_key('rst'): return 1, 3, None # 错误3:设备报文异常 if devInfo['rst'] == -1: # return 0,2,'1234123412341234' return 1, 2, None # 错误2:离线 errCode = int(devInfo['data'][-6:-4]) if errCode == 0: return 0, 0, consumeOrderNo # 成功 return 1, errCode + 3, None def stop_device_swap(self, portNo): sqNo = self.make_sqNo() data = '680C' + sqNo + '0036' + self._device['devNo'] + fill_2_hexByte(hex(int(portNo)), 2) msg = {'IMEI':self._device['devNo'], 'sqNo':sqNo, 'data':data, 'reply':'device'} devInfo = MessageSender.send(self._device, '36', msg) if not devInfo.has_key('rst'): return 1, 4 # 错误4:设备报文异常 if devInfo['rst'] == -1: return 0, 2 # return 1,2,None # 错误2:离线 errCode = int(devInfo['data'][-6:-4]) if errCode == 0: return 0, 0 # 成功 return 1, errCode + 4 def get_charge_status_for_swap(self, portNo, connectorId): try: portDict = self.get_port_status_from_dev() except Exception, e: portDict = Device.get_dev_control_cache(self._device['devNo']) portInfo = portDict.get(str(portNo), {}) adapterDict = {str(Const.DEV_WORK_STATUS_IDLE):1, str(Const.DEV_WORK_STATUS_FAULT):255, str(Const.DEV_WORK_STATUS_WORKING):3} return { 'StartChargeSeqStat':4 if portInfo.get('status') == Const.DEV_WORK_STATUS_IDLE else 2, 'ConnectorID':connectorId, 'ConnectorStatus':adapterDict.get(portInfo.get('status'), 1), 'CurrentA':portInfo.get('current'), 'VoltageA':220.0, 'Soc':0, 'TotalPower':portInfo.get('elec'), 'TotalMoney':portInfo.get('chargedMoney'), } def get_cur_fee(self): feeMode = self._device.otherConf.get('feeMode', {}) shiduan = feeMode.get('shiduan', '000000000000000000000000000000000000000000000000') nowTime = datetime.datetime.now().strftime('%H:%M') curFeeIndex = 0 for ii in range(48): startHour = 0 + ii / 2 startMin = '00' if ii % 2 == 0 else '30' endHour = startHour if ii % 2 == 0 else startHour + 1 endMin = '30' if ii % 2 == 0 else '00' startTime = '%02d:%s' % (startHour, startMin) endTime = '%02d:%s' % (endHour, endMin) if nowTime >= startTime and nowTime <= endTime: curFeeIndex = shiduan[ii] break return { 'curElecFee':feeMode.get({'0':'jianFee', '1':'fengFee', '2':'pingFee', '3':'guFee'}.get(str(curFeeIndex)), 0), 'curServiceFee':feeMode.get({'0':'jianServe', '1':'fengServe', '2':'pingServe', '3':'guServe'}.get(str(curFeeIndex)), 0) } def update_charger(self,chargerType,power,server,port,username,pwd,filepath,mode,timeout): # 请参考协议内容 sqNo = self.make_sqNo() data = '6862' + sqNo + '0094' + self._device['devNo'] + fill_2_hexByte(hex(int(chargerType)), 2) + fill_2_hexByte(hex(int(power)), 4) data = data + string_to_ascstring(server,32) + reverse_hex(fill_2_hexByte(hex(int(port)), 4)) + string_to_ascstring(username,32) + string_to_ascstring(pwd,32) data = data + string_to_ascstring(filepath,64) + fill_2_hexByte(hex(int(mode)), 2) + fill_2_hexByte(hex(int(timeout)), 2) msg = {'IMEI':self._device['devNo'], 'sqNo':sqNo, 'data':data, 'reply':'device','cmd':'94','port':8768} # devInfo = MessageSender.send(self._device, '94', msg) devInfo = MessageSender.send_car_tcpip('211.159.224.10', 50000, msg) errCode = int(devInfo['data'][-6:-4]) if errCode == 0: return 0 return errCode def get_policy_for_user(self): feeMode = self._device.otherConf.get('feeMode',{}) shiduan = feeMode.get('shiduan','000000000000000000000000000000000000000000000000') elecFeeDict = {'0':feeMode.get('jianFee',0),'1':feeMode.get('fengFee',0),'2':feeMode.get('pingFee',0),'3':feeMode.get('guFee',0)} serveFeeDict = {'0':feeMode.get('jianServe',0),'1':feeMode.get('fengServe',0),'2':feeMode.get('pingServe',0),'3':feeMode.get('guServe',0)} policyInfos = [] for ii in range(48): startHour = 0 + ii/2 startMin = '00' if ii%2==0 else '30' startTime = '%02d:%s' % (startHour,startMin) if (ii == 0) or (ii > 0 and shiduan[ii] != shiduan[ii-1]): policyInfos.append({'startTime':startTime,'elecPrice':elecFeeDict.get(shiduan[ii]),'sevicePrice':serveFeeDict.get(shiduan[ii])}) return policyInfos def set_policy_infos(self,dataDict): devObj = Device.objects.get(devNo = self.device['devNo']) if 'feeMode' not in devObj.otherConf: devObj.otherConf.setdefault('feeMode',{}) feeMode = devObj.otherConf.get('feeMode', {}) feeMode['modeNo'] = '0001' feeMode['jianFee'] = float(dataDict.get('top_price_rate')) feeMode['jianServe'] = float(dataDict.get('top_price_service_rate')) feeMode['fengFee'] = float(dataDict.get('peak_price_rate')) feeMode['fengServe'] = float(dataDict.get('peak_price_service_rate')) feeMode['pingFee'] = float(dataDict.get('normal_price_rate')) feeMode['pingServe'] = float(dataDict.get('normal_price_service_rate')) feeMode['guFee'] = float(dataDict.get('valley_price_rate')) feeMode['guServe'] = float(dataDict.get('valley_price_service_rate')) feeMode['jishunScale'] = float(dataDict.get('jishunScale', 0)) shiduan = '' for ii in range(48): startHour = 0 + ii / 2 startMin = '00' if ii % 2 == 0 else '30' endHour = startHour if ii % 2 == 0 else startHour + 1 endMin = '30' if ii % 2 == 0 else '00' startTime = '%02d:%s' % (startHour, startMin) endTime = '%02d:%s' % (endHour, endMin) print startTime, endTime harfHourValue = '0' for conf in dataDict.get('timeRateList'): if startTime >= conf['startTime'] and endTime <= conf['endTime']: harfHourValue = conf['rate'] break else: continue shiduan += harfHourValue feeMode['shiduan'] = shiduan # 发送数据给设备 feeData = feeMode['modeNo'] + fill_2_hexByte(hex(int(feeMode['jianFee'] * 100000)), 8, True) + fill_2_hexByte(hex(int(feeMode['jianServe'] * 100000)), 8, True) \ + fill_2_hexByte(hex(int(feeMode['fengFee'] * 100000)), 8, True) + fill_2_hexByte(hex(int(feeMode['fengServe'] * 100000)), 8, True)\ + fill_2_hexByte(hex(int(feeMode['pingFee'] * 100000)), 8, True) + fill_2_hexByte(hex(int(feeMode['pingServe'] * 100000)), 8, True)\ + fill_2_hexByte(hex(int(feeMode['guFee'] * 100000)), 8, True) + fill_2_hexByte(hex(int(feeMode['guServe'] * 100000)), 8, True)\ + fill_2_hexByte(hex(int(feeMode['jishunScale'])), 2, True) for ii in range(48): temp = '00' if feeMode['shiduan'][ii] == '0' else '01' feeData += temp sqNo = self.make_sqNo() data = '685E' + sqNo + '0058' + self._device['devNo'] + feeData msg = {'IMEI':self._device['devNo'], 'sqNo':sqNo, 'data':data, 'reply':'device'} devInfo = MessageSender.send(self._device, '58', msg) self.check_feedback_result('58', devInfo) # 设备那边正确响应后,才能够存入数据库中 devObj.save() return devInfo def check_order_state(self, openId): dealerId = self.device.ownerId return ClientConsumeModelProxy.get_not_finished_record(ownerId=dealerId, openId=openId, devTypeCode=self._device['devType']['code']) def get_port_using_detail(self, port, ctrInfo, isLazy=False): """ 获取设备端口的详细信息 :param port: :param ctrInfo: :param isLazy: 是否延时加载设备信息 :return: """ detailDict = ctrInfo.get(str(port), {}) try: if isLazy: # 需要点击再次点击按钮加载 portInfo = {'isLazy': True} else: portInfo = self.get_port_info(str(port)) detailDict.update(portInfo) leftMoney = detailDict.get('coins') - detailDict.get('chargedMoney',0) detailDict.update({"leftMoney":u'%s元'%leftMoney }) detailDict.update({"chargedMoney":u'%s元'%detailDict.get('chargedMoney',0) }) except Exception, e: logger.exception('get port info from dev=%s err=%s' % (self.device.devNo, e)) return detailDict return self.format_port_using_detail(detailDict)