# -*- coding: utf-8 -*- from apps.web.core.adapter.base import * from apps.web.device.models import Device class ChargingKyxnBox(SmartBox): def __init__(self, device): super(ChargingKyxnBox, self).__init__(device) def analyze_event_data(self,data): cmdCode = data[6:8] backData = data[8::] if cmdCode == '04':#充电状态 voltage = int(backData[16:20],16)/10.0 electric = int(backData[20:24],16)/10.0 line = int(backData[24:26],16) + 1 costTime = int(backData[26:30],16) return {'voltage':voltage,'isStart':True,'electric':electric,'costTime':costTime,'port':line} elif cmdCode == '05':#结束状态 binTemp = hexbyte_2_bin(backData[16:18]) endReason = u'桩端结束' if binTemp[-1] == '0' else u'服务器结束' line = int(binTemp[0:-1],2) + 1 faultTemp = backData[18:20] faultCode = '' if faultTemp == '02': faultCode = Const.CHARGING_KYXN_DCGZ elif faultTemp == '04': faultCode = Const.CHARGING_KYXN_CDZGZ elif faultTemp == '06': faultCode = Const.CHARGING_KYXN_QTGZ return {'isStart':False,'reason':endReason,'faultCode':faultCode,'port':line} else: return None def check_dev_status(self,attachParas=None): if not attachParas.has_key('chargeIndex'): raise ServiceException({'result': 2, 'description': u'请您选择合适的充电线路'}) #查询是否已经接上了电池,如果没有接上电池,就要报错 #动作 lineBin = hexbyte_2_bin(hex(int(attachParas['chargeIndex'])-1)) temp1=lineBin[1::] + '0' cmd = '00000000' + decimal_2_hexByte(int(temp1,2)) devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], "funCode": "06", "data": cmd}) if 'rst' in devInfo 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'] devResult = data[16:18] binResult = hexbyte_2_bin(devResult) isNormal = True if binResult[-1] == '0' else False if not isNormal: raise ServiceException( {'result': 2, 'description': u'您未接电池,或者电池反接了,请您检查后再试哦'}) #凯源新能的可以往端口加钱,所以,端口即使被占用,可以仍然使用 def is_port_can_use(self,port): portDict = self.get_port_status() statusInfo = portDict.get(str(port)) if statusInfo.get('status','') != Const.DEV_WORK_STATUS_IDLE: return False,u'设备当前线路不是空闲状态,无法使用哦' return True,u'' def lock_unlock_port(self,port,lock): dev = Device.objects.get(devNo = self._device['devNo']) portKey = 'port%s' % port if lock: dev.otherConf.update({portKey:Const.DEV_WORK_STATUS_FORBIDDEN}) else: dev.otherConf.update({portKey:Const.DEV_WORK_STATUS_IDLE}) dev.save() if lock: self.active_deactive_port(port, False) 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 get_port_info(self,line): devCtrInfo = Device.get_dev_control_cache(self._device['devNo']) portInfo = devCtrInfo.get(line,None) if portInfo is None: return {'status':Const.DEV_WORK_STATUS_IDLE} return portInfo def get_port_status(self, force = False): resultDict = {} otherConf = Device.objects.get(devNo = self._device['devNo']).otherConf nowTime = datetime.datetime.now() devCtrInfo = Device.get_dev_control_cache(self._device['devNo']) for ii in range(8): resultDict[str(ii+1)] = {'status':Const.DEV_WORK_STATUS_FAULT} portInfo = devCtrInfo.get(str(ii+1),None) if portInfo is None: resultDict[str(ii+1)] = {'status':Const.DEV_WORK_STATUS_IDLE} continue if portInfo.get('isStart',False): startTime = to_datetime(portInfo['startTime']) usedTime = int((nowTime - startTime).total_seconds()/60.0) if usedTime > portInfo['needTime']: resultDict[str(ii+1)] = {'status':Const.DEV_WORK_STATUS_IDLE} else: resultDict[str(ii+1)] = {'status':Const.DEV_WORK_STATUS_WORKING} else: if portInfo.get('faultCode'): resultDict[str(ii+1)] = {'status':Const.DEV_WORK_STATUS_FAULT} else: resultDict[str(ii+1)] = {'status':Const.DEV_WORK_STATUS_IDLE} resultDict[str(ii+1)] = {'status':Const.DEV_WORK_STATUS_FAULT} portKey = 'port%s' % (ii + 1) confStatus = otherConf.get(portKey,None) if confStatus == Const.DEV_WORK_STATUS_FORBIDDEN: resultDict[str(ii + 1)] = {'status':Const.DEV_WORK_STATUS_FORBIDDEN} allPorts,usedPorts,usePorts = self.get_port_static_info(resultDict) Device.update_dev_control_cache(self._device['devNo'], {'allPorts':allPorts,'usedPorts':usedPorts,'usePorts':usePorts}) return resultDict 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'请您选择合适的充电线路'}) if not attachParas.has_key('batteryType'): raise ServiceException({'result': 2, 'description': u'请您选择合适的电池类型'}) if not attachParas.has_key('voltage'): raise ServiceException({'result': 2, 'description': u'请您选择合适的电池电压'}) #动作 lineBin = hexbyte_2_bin(hex(int(attachParas['chargeIndex'])-1)) temp1=lineBin[1::] + '0' cmd = '00000000' + decimal_2_hexByte(int(temp1,2)) #电池类型 if attachParas['batteryType'] == u'锂电池': cmd += '01' else: cmd += '02' #电压 vTemp = fill_2_hexByte(hex(int(attachParas['voltage'])*10)) cmd += vTemp #充电币 coins = int(package['coins']) cTemp = fill_2_hexByte(hex(int(coins))) cmd += cTemp devInfo = MessageSender.send(device = self.device, cmd = DeviceCmdCode.OPERATE_DEV_SYNC, payload = { 'IMEI': self._device['devNo'], "funCode": "0D", "data": cmd }, timeout = MQTT_TIMEOUT.START_DEVICE) 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'] devResult = data[16:18] binResult = hexbyte_2_bin(devResult) isStart = True if binResult[-1] == '0' else False lineNum = int(binResult[0:-1],2) + 1 if not isStart: raise ServiceException( {'result': 2, 'description': u'充电桩没有开始工作,请检查您的线路是否被占用,或者您的输入选择是否正确'}) #刷新状态 needTime = int(package['time']) newValue = {str(lineNum):{'startTime':datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), 'coins':float(coins),'isStart':isStart,'voltage':attachParas['voltage'],'refunded':False, 'batteryType':attachParas['batteryType'],'needTime':needTime,'openId':openId, 'vCardId':self._vcard_id}} Device.update_dev_control_cache(self._device['devNo'], newValue) unit = package.get('unit','') if unit == u'次': devInfo['finished_time'] = int(time.time()) + 24*60*60 return devInfo def active_deactive_port(self,port,active,duration=None): devCtrInfo = Device.get_dev_control_cache(self._device['devNo']) portInfo = devCtrInfo.get(str(port),{}) lineBin = hexbyte_2_bin(hex(int(port)-1)) temp1=lineBin[1::] + '0' if active else '1' cmd = '00000000' + decimal_2_hexByte(int(temp1,2)) #电池类型 if portInfo.get('batteryType','') == u'锂电池': cmd += '01' else: cmd += '02' #电压 vTemp = fill_2_hexByte(hex(int(portInfo.get('voltage',36))*10)) cmd += vTemp #充电币 coins = int(portInfo.get('coins',8)) cTemp = fill_2_hexByte(hex(int(coins))) cmd += cTemp devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], "funCode": "0D", "data": cmd}) 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'] devResult = data[16:18] binResult = hexbyte_2_bin(devResult) isStart = True if binResult[-1] == '0' else False lineNum = int(binResult[0:-1],2) + 1 if isStart: raise ServiceException( {'result': 2, 'description': u'充电桩端口没有成功停掉,请稍候再试哦'}) #刷新状态 portInfo.update({'endTime':datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),'isStart':False,'status':Const.DEV_WORK_STATUS_IDLE}) newValue = {str(lineNum):portInfo} Device.update_dev_control_cache(self._device['devNo'], newValue) if not active:#关闭充电桩的端口 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) return devInfo