# -*- coding: utf-8 -*- #!/usr/bin/env python import time import logging from apilib.utils_datetime import timestamp_to_dt from apps.web.constant import Const, DeviceCmdCode, MQTT_TIMEOUT, DeviceErrorCodeDesc, ErrorCode from apps.web.core.adapter.base import SmartBox, fill_2_hexByte from apps.web.core.exceptions import ServiceException from apps.web.core.networking import MessageSender from apps.web.device.models import Device, GroupDict logger = logging.getLogger(__name__) class ChargingHaiNiaoSingleNewBox(SmartBox): def __init__(self, device): super(ChargingHaiNiaoSingleNewBox, self).__init__(device) def check_dev_status(self, attachParas = None): if attachParas is None: raise ServiceException({'result': 0, 'description': u'请您选择合适的充电端口、电池类型信息'}) if not attachParas.has_key('chargeIndex'): raise ServiceException({'result': 0, 'description': u'请您选择合适的充电端口'}) if not self.device.need_fetch_online: raise ServiceException( {'result': 2, 'description': DeviceErrorCodeDesc.get(ErrorCode.DEVICE_CONN_CHECK_FAIL)}) self.get_port_status_from_dev() group = self.device.group # type: GroupDict if group.is_free: logger.debug('{} is free. no need to check continue pay.'.format(repr(self.device))) return # 处理是否能够续充 portDict = self.get_port_status() port = str(attachParas['chargeIndex']) if port in portDict: isCanAdd = self.device['devType'].get('payableWhileBusy', False) if portDict[port]['status'] == Const.DEV_WORK_STATUS_IDLE: return elif portDict[port]['status'] == Const.DEV_WORK_STATUS_FAULT: raise ServiceException({'result': 0, 'description': u'该端口故障,暂时不能使用'}) elif portDict[port]['status'] == Const.DEV_WORK_STATUS_WORKING: if isCanAdd: return else: raise ServiceException({'result': 0, 'description': u'该端口正在工作不能使用,请您使用其他端口'}) elif portDict[port]['status'] == Const.DEV_WORK_STATUS_FORBIDDEN: raise ServiceException({'result': 0, 'description': u'该端口已被禁止使用,请您使用其他端口'}) elif portDict[port]['status'] == Const.DEV_WORK_STATUS_CONNECTED: return else: raise ServiceException({'result': 0, 'description': u'端口状态未知,暂时不能使用'}) else: raise ServiceException({'result': 0, 'description': u'未知端口,暂时不能使用'}) def get_port_status_from_dev(self): # 获取端口状态 devInfo = MessageSender.send(self.device, self.make_random_cmdcode(), {'IMEI': self._device['devNo'], "funCode": '01', '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'当前设备忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'}) result = {} binStr = str(bin(int(devInfo['data'][10:12], 16)))[2:] while len(binStr) < 8: binStr = '0' + binStr if len(binStr) >= 8: break portStatus = binStr[-1] if portStatus == '0': result['1'] = {'status': Const.DEV_WORK_STATUS_IDLE} elif portStatus == '1': result['1'] = {'status': Const.DEV_WORK_STATUS_WORKING} else: raise ServiceException({'result': 2, 'description': u'端口状态返回错误'}) portErrorStatus = devInfo['data'][20:22] if portErrorStatus != '00': raise ServiceException({'result': 2, 'description': u'端口故障(0x{})'.format(portErrorStatus)}) 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): # 获取端口状态(缓存) return self.get_port_status_from_dev() def get_dev_setting(self): devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'],"funCode":'02','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'当前设备忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'}) confData = devInfo['data'][8::] switchData = int(confData[0:2], 16) binStr = str(bin(switchData))[2:] while len(binStr) < 8: binStr = '0' + binStr if len(binStr) >= 8: break pauseModeData = int(binStr[5:8], 2) pauseModeMap = { '1': 'pause1MinutesClear', '2': 'pause2MinutesClear', '3': 'pause3MinutesClear', '4': 'pause5MinutesStart', '5': 'pause10MinutesStart', } pauseMode = pauseModeMap[str(pauseModeData)] billingMode = 'litre' if int(binStr[4]) else 'time' workingMode = 'multiple' if int(binStr[3]) else 'single' isPause = True if int(binStr[2]) else False isPowerOffMemory = True if int(binStr[1]) else False coinLaunchMode = 'button' if int(binStr[0]) else 'direct' power1Price = int(confData[10:12], 16) power1Matter = int(confData[12:16], 16) power2Price = int(confData[16:18], 16) power2Matter = int(confData[18:22], 16) power3Price = int(confData[22:24], 16) power3Matter = int(confData[24:28], 16) power4Price = int(confData[28:30], 16) power4Matter = int(confData[30:34], 16) power5Price = int(confData[34:36], 16) power5Matter = int(confData[36:40], 16) power6Price = int(confData[40:42], 16) power6Matter = int(confData[42:46], 16) usedCoinPackage = {"power1Price":power1Price,"power1Matter":power1Matter,\ "power2Price":power2Price,"power2Matter":power2Matter,\ "power3Price":power3Price,"power3Matter":power3Matter,\ "power4Price":power4Price,"power4Matter":power4Matter,\ "power5Price":power5Price,"power5Matter":power5Matter,\ "power6Price":power6Price,"power6Matter":power6Matter, } # 获取投币套餐 coinPackages = Device.get_dev(self.device.devNo).get("otherConf").get("coinPackages") if coinPackages:# type: list() name = coinPackages[0].get('name') usedCoinPackage.update({"name":name,"switch":True,"unit": coinPackages[0].get('unit')}) coinPackages = [usedCoinPackage] else: usedCoinPackage.update({"name": "未命名套餐", "switch": True, "unit": billingMode}) coinPackages = [usedCoinPackage] cardFee = int(confData[46:50], 16) cardMin = int(confData[50:54], 16) usedCardPackage = {"cardFee": cardFee, "cardMin": cardMin} cardPackages = Device.get_dev(self.device.devNo).get("otherConf").get("cardPackages") if cardPackages: usedCardPackage.update({"name": cardPackages[0].pop('name'), "switch": True,"unit": cardPackages[0]['unit']}) cardPackages = [usedCardPackage] else: usedCardPackage.update({"name": "未命名套餐", "switch": True, "unit": billingMode}) cardPackages = [usedCardPackage] otherSettingsData = int(confData[54:56], 16) binStr2 = str(bin(otherSettingsData))[2:] while len(binStr2) < 8: binStr2 = '0' + binStr2 if len(binStr2) >= 8: break remoteControl = True if int(binStr2[7]) else False voiceAnnouncements = True if int(binStr2[6]) else False unitPulse = int(confData[56:60], 16) device = Device.objects(devNo=self._device['devNo']).first() minConsumptionLimit = device.otherConf.get('minConsumptionLimit', 0) return { 'pauseMode': pauseMode, 'billingMode': billingMode, 'workingMode': workingMode, 'isPause': isPause, 'isPowerOffMemory': isPowerOffMemory, 'coinLaunchMode': coinLaunchMode, # 'power1Price': power1Price, # 'power1Matter': power1Matter, # 'power2Price': power2Price, # 'power2Matter': power2Matter, # 'power3Price': power3Price, # 'power3Matter': power3Matter, # 'power4Price': power4Price, # 'power4Matter': power4Matter, # 'power5Price': power5Price, # 'power5Matter': power5Matter, # 'power6Price': power6Price, # 'power6Matter': power6Matter, 'cardFee': cardFee, 'cardMin': cardMin, 'remoteControl': remoteControl, 'voiceAnnouncements': voiceAnnouncements, 'unitPulse': unitPulse, 'minConsumptionLimit': minConsumptionLimit, "coinPackages":coinPackages, "cardPackages":cardPackages, } 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'请您选择合适的充电线路'}) # 只有一个端口 hexPort = '0001' needTime = 0 needLitre = 0 needPrice = float(package['price']) hexNeedPrice = fill_2_hexByte(hex(int(needPrice * 100))) unit = package['unit'] if unit == u'升': needLitre = int(package['time']) hexLitre = fill_2_hexByte(hex(needLitre * 10)) data = hexPort + '01' + hexLitre + hexNeedPrice funCode = '08' elif unit == u'小时': needTime = int(package['time']) * 60 hexTime = fill_2_hexByte(hex(needTime)) data = hexPort + '01' + hexTime + hexNeedPrice funCode = '08' elif unit == u'秒': needTime = int(package['time']) hexTime = fill_2_hexByte(hex(needTime)) data = hexPort + '01' + hexTime + hexNeedPrice funCode = '0A' else: needTime = int(package['time']) hexTime = fill_2_hexByte(hex(needTime)) data = hexPort + '01' + hexTime + hexNeedPrice funCode = '08' billingMode = self.get_dev_setting()['billingMode'] if billingMode == 'litre' and unit == u'升': pass elif billingMode == 'time' and unit == u'分钟': pass elif billingMode == 'time' and unit == u'小时': pass elif billingMode == 'time' and unit == u'秒': pass else: raise ServiceException({'result': 2, 'description': u'套餐与主板的启动参数不匹配(时间/流量)'}) orderNo = attachParas.get('orderNo') portStatus = self.get_port_status_from_dev() if portStatus['1']['status'] == Const.DEV_WORK_STATUS_WORKING: if funCode == '08': funCode = '09' else: raise ServiceException({'result': 2, 'description': u'秒启动不支持续充'}) data = data[0:4] + data[6:10] devInfo = MessageSender.send( device = self.device, cmd = DeviceCmdCode.OPERATE_DEV_SYNC, payload = { 'IMEI': self._device['devNo'], "funCode": funCode, 'data': data }, 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'][8::] usePort = int(data[0:4], 16) result = data[4:8] if result == '0000': # 代表失败 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'充电站故障'}) start_timestamp = int(time.time()) finishedTime = start_timestamp + needTime * 60 portDict = { 'startTime': timestamp_to_dt(start_timestamp).strftime('%Y-%m-%d %H:%M:%S'), 'status': Const.DEV_WORK_STATUS_WORKING, 'finishedTime': finishedTime, 'needPrice': needPrice, # 个人中心断电需要用到 'coins': needPrice, 'isStart': True, 'needTime': needTime, 'needLitre': needLitre, 'openId': openId, 'refunded': False, 'vCardId': self._vcard_id } ctrInfo = Device.get_dev_control_cache(self._device['devNo']) lastPortInfo = ctrInfo.get(str(usePort), None) is_continue = False if lastPortInfo is not None and \ lastPortInfo.get('status', '') == Const.DEV_WORK_STATUS_WORKING and \ lastPortInfo.get('openId', '') == openId: is_continue = True if 'needPrice' in lastPortInfo: portDict['needPrice'] = float(needPrice) + lastPortInfo['needPrice'] if 'needTime' in lastPortInfo: portDict['needTime'] = needTime + lastPortInfo['needTime'] if 'needLitre' in lastPortInfo: portDict['needLitre'] = needLitre + lastPortInfo['needLitre'] finishedTime = int(time.time()) + portDict['needTime'] * 60 portDict.update({'finishedTime': finishedTime}) if 'linkedRechargeRecordId' in attachParas and attachParas.get('isQuickPay', False): item = { 'rechargeRcdId': str(attachParas['linkedRechargeRecordId']) } if is_continue: payInfo = lastPortInfo.get('payInfo', list()) else: payInfo = list() payInfo.append(item) portDict['payInfo'] = payInfo else: if unit == u'秒': data = data[0:4] + data[6:10] + data[10:14] devInfo = MessageSender.send( device = self.device, cmd = DeviceCmdCode.OPERATE_DEV_SYNC, payload = { 'IMEI': self._device['devNo'], "funCode": funCode, 'data': data }, 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'][8::] usePort = 1 result = data[4:8] if result == '0000': # 代表失败 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'充电站故障'}) if unit == u'秒': needTime = int(needTime / 60) start_timestamp = int(time.time()) finishedTime = start_timestamp + needTime * 60 portDict = { 'startTime': timestamp_to_dt(start_timestamp).strftime('%Y-%m-%d %H:%M:%S'), 'status': Const.DEV_WORK_STATUS_WORKING, 'finishedTime': finishedTime, 'needPrice': needPrice, # 个人中心断电需要用到 'coins': needPrice, 'isStart': True, 'needTime': needTime, 'needLitre': needLitre, 'openId': openId, 'refunded': False, 'vCardId': self._vcard_id } if 'linkedRechargeRecordId' in attachParas: item = { 'rechargeRcdId': str(attachParas['linkedRechargeRecordId']) } portDict['payInfo'] = [item] Device.update_dev_control_cache(self._device['devNo'], {str(usePort): portDict}) return devInfo @property def isHaveStopEvent(self): return True def get_port_info(self, line): devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], "funCode": '01', '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'当前设备忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'}) leftTimeSec = int(devInfo['data'][12:20], 16) leftTime = leftTimeSec / 60 return {'port': line, 'leftTime': leftTime} def stop(self, port = None): self.stop_charging_port(port) infoDict = dict() infoDict['remainder_time'] = 0 return infoDict def stop_charging_port(self, port): self.active_deactive_port(port, False) def active_deactive_port(self, port, active): if active: return else: data = '000100' devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], "funCode": '03', 'data': data + '0000'}) if devInfo.has_key('rst') and devInfo['rst'] != 0: if devInfo['rst'] == -1: raise ServiceException( {'result': 2, 'description': u'当前设备正在玩命找网络,请您稍候再试'}) elif devInfo['rst'] == 1: # 不处理 pass def analyze_event_data(self, data): cmdCode = data[6:8] if cmdCode == '86': channelChangeStatus = data[10:12] binChannelChangeStatus = str(bin(int(channelChangeStatus, 16)))[2:] while len(binChannelChangeStatus) < 8: binChannelChangeStatus = '0' + binChannelChangeStatus channelOperateStatus = data[14:16] binChannelOperateStatus = str(bin(int(channelOperateStatus, 16)))[2:] while len(binChannelOperateStatus) < 8: binChannelOperateStatus = '0' + binChannelOperateStatus channel1Status = False if binChannelChangeStatus[-1] == '0' else True channel1Oper = False if binChannelOperateStatus[-1] == '0' else True # 判断条件成立代表结束 if channel1Status is True and channel1Oper is False: reason = data[16:18] if reason == '00': desc = u'购买的充电时间或者电量用完了。' elif reason in ['04', '06', '07']: desc = u'管理人员可能远程断电了,或是插头被拔掉, 建议您根据已经充电的时间评估是否需要到现场换到其他端口充电。' elif reason == '05': desc = u'空载断电。' else: desc = u'' leftTime = int(data[36:44], 16) / 60 leftPrice = float(int(data[44:48], 16)) / 100 cardNo = int(data[48:56], 16) return { 'status': Const.DEV_WORK_STATUS_IDLE, 'leftPrice': leftPrice, 'leftTime': leftTime, 'cmdCode': cmdCode, 'reason': desc, 'cardNo': cardNo, 'port': '1' } else: return {} if cmdCode == '8B': cardNo = int(data[8:16], 16) return {'cmdCode': cmdCode, 'cardNo': str(cardNo)} if cmdCode == '8C': cardNo = int(data[8:16], 16) operFee = round(float(int(data[16:24], 16)) / 100, 2) return {'cmdCode': cmdCode, 'operFee': operFee, 'cardNo': str(cardNo)} if cmdCode == '8D': if 'debug' in self.device.otherConf: url = 'https://develop.5tao5ai.com/userLogin?l=' else: url = 'https://www.washpayer.com/userLogin?l=' hexUrl = ''.join([str(hex(ord(_)))[2:].upper() for _ in url]) return {'cmdCode': cmdCode, 'hexUrl': hexUrl} def pauseToUseDevice(self, port, oper): MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_NO_RESPONSE, {'IMEI': self._device['devNo'], "funCode": '03', 'data': '0001' + oper + '0000'}) if oper == '02': Device.update_dev_control_cache(self._device['devNo'], {'1': {'pausePort': True}}) elif oper == '01': Device.update_dev_control_cache(self._device['devNo'], {'1': {'pausePort': False}}) else: pass def send_setting_data(self, data): devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC, {'IMEI': self._device['devNo'], "funCode": '04', 'data': data}, timeout=30) 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'当前设备忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'}) if devInfo['data'][14:16] == '01': raise ServiceException( {'result': 2, 'description': u'设置失败'}) def set_pause_mode(self, isPause): data = '08' + ('0001' if isPause else '0000') self.send_setting_data(data) def set_power_off_memory(self, isPowerOffMemory): # data = '0C' + ('0001' if isPowerOffMemory else '0000') # self.send_setting_data(data) return def set_remote_control(self, remoteControl): data = '0E' + ('0001' if remoteControl else '0000') self.send_setting_data(data) def set_voice_announcements(self, voiceAnnouncements): data = '07' + ('0001' if voiceAnnouncements else '0000') self.send_setting_data(data) def ack_query_card_balance(self, cardNo, cardBalance): cardNo = str(hex(int(cardNo)))[2:].upper().rjust(8, '0') cardBalance = str(hex(int(float(cardBalance) * 100)))[2:].upper().rjust(8, '0') devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_NO_RESPONSE, {'IMEI': self._device['devNo'], "funCode": '0B', 'data': cardNo + cardBalance}) 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 ack_consume_card(self, cardNo, cardBalance, oper): cardNo = str(hex(int(cardNo)))[2:].upper().rjust(8, '0') cardBalance = str(hex(int(float(cardBalance) * 100)))[2:].upper().rjust(8, '0') data = cardNo + cardBalance + oper devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_NO_RESPONSE, {'IMEI': self._device['devNo'], "funCode": '0C', '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'当前设备忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'}) def init_device_QR_code(self, hexUrl): hexLogicalCode = ''.join([str(hex(ord(_)))[2:].upper() for _ in self.device['logicalCode']]) data = hexUrl + hexLogicalCode devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_NO_RESPONSE, {'IMEI': self._device['devNo'], "funCode": '0D', 'data': data.ljust(200, '0')}) 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_power_price(self, powerPriceDict): power1PriceData = '14' + fill_2_hexByte(hex(int(powerPriceDict['power1Price']))) self.send_setting_data(power1PriceData) power2PriceData = '16' + fill_2_hexByte(hex(int(powerPriceDict['power2Price']))) self.send_setting_data(power2PriceData) power3PriceData = '18' + fill_2_hexByte(hex(int(powerPriceDict['power3Price']))) self.send_setting_data(power3PriceData) power4PriceData = '1A' + fill_2_hexByte(hex(int(powerPriceDict['power4Price']))) self.send_setting_data(power4PriceData) power5PriceData = '1C' + fill_2_hexByte(hex(int(powerPriceDict['power5Price']))) self.send_setting_data(power5PriceData) power6PriceData = '1E' + fill_2_hexByte(hex(int(powerPriceDict['power6Price']))) self.send_setting_data(power6PriceData) def set_power_matter(self, powerMatterDict): power1MatterData = '15' + fill_2_hexByte(hex(int(powerMatterDict['power1Matter']))) self.send_setting_data(power1MatterData) power2MatterData = '17' + fill_2_hexByte(hex(int(powerMatterDict['power2Matter']))) self.send_setting_data(power2MatterData) power3MatterData = '19' + fill_2_hexByte(hex(int(powerMatterDict['power3Matter']))) self.send_setting_data(power3MatterData) power4MatterData = '1B' + fill_2_hexByte(hex(int(powerMatterDict['power4Matter']))) self.send_setting_data(power4MatterData) power5MatterData = '1D' + fill_2_hexByte(hex(int(powerMatterDict['power5Matter']))) self.send_setting_data(power5MatterData) power6MatterData = '1F' + fill_2_hexByte(hex(int(powerMatterDict['power6Matter']))) self.send_setting_data(power6MatterData) def set_base_settings(self, baseSettingsDict): billingModeData = '0B' + ('0001' if baseSettingsDict['billingMode'] == 'litre' else '0000') self.send_setting_data(billingModeData) workingModeData = '0A' + ('0001' if baseSettingsDict['workingMode'] == 'multiple' else '0000') self.send_setting_data(workingModeData) coinLaunchModeData = '09' + ('0001' if baseSettingsDict['coinLaunchMode'] == 'button' else '0000') self.send_setting_data(coinLaunchModeData) hexPauseModeMap = { 'pause1MinutesClear': '0001', 'pause2MinutesClear': '0002', 'pause3MinutesClear': '0003', 'pause5MinutesStart': '0004', 'pause10MinutesStart': '0005', } pauseModeData = hexPauseModeMap[baseSettingsDict['pauseMode']] self.send_setting_data('0D' + pauseModeData) # cardFeeData = str(hex(int(baseSettingsDict['cardFee'])))[2:].upper().rjust(4, '0') # self.send_setting_data('20' + cardFeeData) # # cardMinData = str(hex(int(baseSettingsDict['cardMin'])))[2:].upper().rjust(4, '0') # self.send_setting_data('21' + cardMinData) unitPulseData = str(hex(int(baseSettingsDict['unitPulse'])))[2:].upper().rjust(4, '0') unitPulseData = '01D6' if unitPulseData == '0000' else unitPulseData self.send_setting_data('22' + unitPulseData) device = Device.objects(devNo=self.device['devNo']).first() device.otherConf['minConsumptionLimit'] = baseSettingsDict['minConsumptionLimit'] device.save() Device.invalid_device_cache(self.device['devNo']) def set_device_function_param(self, request, lastSetConf): if 'billingMode' in request.POST \ and 'workingMode' in request.POST \ and 'minConsumptionLimit' in request.POST \ and 'pauseMode' in request.POST \ and 'unitPulse' in request.POST \ and 'coinLaunchMode' in request.POST: billingMode = request.POST['billingMode'] workingMode = request.POST['workingMode'] minConsumptionLimit = request.POST['minConsumptionLimit'] pauseMode = request.POST['pauseMode'] # cardFee = request.POST['cardFee'] # cardMin = request.POST['cardMin'] unitPulse = request.POST['unitPulse'] coinLaunchMode = request.POST['coinLaunchMode'] self.set_base_settings({ 'billingMode': billingMode, 'workingMode': workingMode, 'minConsumptionLimit': minConsumptionLimit, 'coinLaunchMode': coinLaunchMode, 'pauseMode': pauseMode, # 'cardFee': cardFee, # 'cardMin': cardMin, 'unitPulse': unitPulse }) if 'cardPackages' in request.POST and request.POST['cardPackages']: newCardPackages = [] for cardPackage in request.POST['cardPackages']: billingMode = request.POST['billingMode'] or lastSetConf.get('billingMode') if billingMode in [u'time', u'second']: billingMode = [u'time', u'second'] else: billingMode = [u'litre'] if cardPackage['unit'] not in billingMode: raise ServiceException( {'result': 2, 'description': u'套餐计费单位需与计费模式相同'}) cardFeeData = str(hex(int(cardPackage['cardFee'])))[2:].upper().rjust(4, '0') self.send_setting_data('20' + cardFeeData) cardMinData = str(hex(int(cardPackage['cardMin'])))[2:].upper().rjust(4, '0') self.send_setting_data('21' + cardMinData) newCardPackages.append({'name':cardPackage.get('name'),'unit':cardPackage['unit']}) device = Device.objects.get(logicalCode=self.device.logicalCode) device.otherConf['cardPackages'] = newCardPackages device.save() Device.invalid_device_cache(self.device.devNo) if 'coinPackages' in request.POST and request.POST['coinPackages']: newCoinPackages = [] for coinPackage in request.POST['coinPackages']: if len(request.POST['coinPackages']) == 1: request.POST['coinPackages'][0].update({'switch' : True}) power1Price = coinPackage['power1Price'] power1Price = 1 if power1Price == 0 else power1Price power2Price = coinPackage['power2Price'] power2Price = 2 if power2Price == 0 else power2Price power3Price = coinPackage['power3Price'] power3Price = 3 if power3Price == 0 else power3Price power4Price = coinPackage['power4Price'] power4Price = 4 if power4Price == 0 else power4Price power5Price = coinPackage['power5Price'] power5Price = 5 if power5Price == 0 else power5Price power6Price = coinPackage['power6Price'] power6Price = 6 if power6Price == 0 else power6Price power1Matter = coinPackage['power1Matter'] power1Matter = 5 if power1Matter == 0 else power1Matter power2Matter = coinPackage['power2Matter'] power2Matter = 25 if power2Matter == 0 else power2Matter power3Matter = coinPackage['power3Matter'] power3Matter = 40 if power3Matter == 0 else power3Matter power4Matter = coinPackage['power4Matter'] power4Matter = 60 if power4Matter == 0 else power4Matter power5Matter = coinPackage['power5Matter'] power5Matter = 80 if power5Matter == 0 else power5Matter power6Matter = coinPackage['power6Matter'] power6Matter = 100 if power6Matter == 0 else power6Matter if billingMode == u'time' or billingMode == [u'time', u'second']: billingMode = [u'time', u'second'] else: billingMode = [u'litre'] if coinPackage['unit'] not in billingMode: raise ServiceException( {'result': 2, 'description': u'套餐计费单位需与计费模式相同'}) self.set_power_price({ 'power1Price': power1Price, 'power2Price': power2Price, 'power3Price': power3Price, 'power4Price': power4Price, 'power5Price': power5Price, 'power6Price': power6Price }) self.set_power_matter({ 'power1Matter': power1Matter, 'power2Matter': power2Matter, 'power3Matter': power3Matter, 'power4Matter': power4Matter, 'power5Matter': power5Matter, 'power6Matter': power6Matter }) newCoinPackages.append({'name':coinPackage.get('name'),'unit':coinPackage.get('unit')}) device = Device.objects.get(logicalCode=self.device.logicalCode) device.otherConf['coinPackages'] = newCoinPackages device.save() Device.invalid_device_cache(self.device.devNo) def set_device_function(self, request, lastSetConf): if 'isPause' in request.POST: isPause = request.POST['isPause'] self.set_pause_mode(isPause) if 'isPowerOffMemory' in request.POST: isPowerOffMemory = request.POST['isPowerOffMemory'] self.set_power_off_memory(isPowerOffMemory) if 'remoteControl' in request.POST: remoteControl = request.POST['remoteControl'] self.set_remote_control(remoteControl) if 'voiceAnnouncements' in request.POST: voiceAnnouncements = request.POST['voiceAnnouncements'] self.set_voice_announcements(voiceAnnouncements)