# -*- coding: utf-8 -*- # !/usr/bin/env python import datetime import random import logging import binascii import time from typing import TYPE_CHECKING from apps.web.core.adapter.base import SmartBox, fill_2_hexByte, reverse_hex from apps.web.core.networking import MessageSender from apps.web.core.exceptions import ServiceException from apps.web.constant import Const, DeviceCmdCode, MQTT_TIMEOUT from apps.web.device.models import Device from apps.web.user.models import ConsumeRecord from apilib.monetary import VirtualCoin logger = logging.getLogger(__name__) if TYPE_CHECKING: pass class ChargeModeMap(object): TIME_QUOTA = 1 POWER_QUOTA = 2 ELEC_QUOTA = 3 FREE_QUOTA = 4 INTERVAL_QUOTA = 5 class PortStatusCode(object): DEV_WORK_STATUS_IDLE = 0 DEV_WORK_STATUS_IDLE_POWER_NORMAL_FAULT_RELAY_CONNECT = 1 DEV_WORK_STATUS_IDLE_FAULT_OVERLOAD_RELAY_CONNECT_NORMAL = 2 DEV_WORK_STATUS_IDLE_FAULT_OVERLOAD_FAULT_RELAY_CONNECT = 3 DEV_WORK_STATUS_WORKING = 4 DEV_WORK_STATUS_WORKING_POWER_NORMAL_FAULT_RELAY_CONNECT = 5 DEV_WORK_STATUS_WORKING_FAULT_OVERLOAD_RELAY_CONNECT_NORMAL = 6 DEV_WORK_STATUS_WORKING_FAULT_OVERLOAD_FAULT_RELAY_CONNECT = 7 DEV_WORK_STATUS_WORKING_COIN = 8 DEV_WORK_STATUS_WORKING_COIN_POWER_NORMAL_FAULT_RELAY_CONNECT = 9 DEV_WORK_STATUS_WORKING_COIN_FAULT_OVERLOAD_RELAY_CONNECT_NORMAL = 10 DEV_WORK_STATUS_WORKING_COIN_FAULT_OVERLOAD_FAULT_RELAY_CONNECT = 11 class BILLING_TYPE(object): """ 充电方式 """ TIME = "time" ELEC = "elec" POWER = "power" FREE = "free" INTERVAL_QUOTA = "interval_quota" class ChargingBeiSiYunBox(SmartBox): def _encrypt_func(self, bArray, kArray, r, en=True): """ :param bArray: 加密的字节数组 :param kArray: 加密的字节数组 参与加密 :param r: 加密的随机字符 0-255 单字节 :param en: 是否为加密 True = 加密 False = 解密 """ kenLen = 10 result = bytearray() for i in range(len(bArray)): temp_char = bArray[i] s = i % kenLen + 1 if s == kenLen: s = 0 else: s = s k = kArray[s] if en: rc = (temp_char + k + r) % 256 else: rc = (temp_char - k - r) % 256 result.insert(i, rc) # print("[encrypt_func] result = {}, hex result = {}".format(result, binascii.hexlify(result))) return result def _send_mqtt(self, funCode, data=None, cmd=None, timeout=MQTT_TIMEOUT.NORMAL): """ 发送数据到mqtt服务器 :param funCode: :param data: :param cmd: :param timeout: :return: """ if cmd is None: cmd = DeviceCmdCode.OPERATE_DEV_SYNC if data is None: data = "00" result = MessageSender.send(device=self.device, cmd=cmd, payload={ "IMEI": self.device.devNo, "funCode": funCode, "data": data }, timeout=timeout) if "rst" in result and result.get("rst") != 0: if result.get("rst") == -1: raise ServiceException({"result": 2, "description": u"网络故障,请重新试试"}) if result.get("rst") == 1: raise ServiceException({"result": 2, "description": u"充电桩无响应,请稍后再试试"}) return result def _start_remote(self, port, method, orderType, balance, orderNo, maxTime=0, spendMoney=0, other=0): portHex = fill_2_hexByte(hex(int(port)), 2) methodHex = fill_2_hexByte(hex(int(method)), 2) orderTypeHex = fill_2_hexByte(hex(int(orderType)), 2) balanceHex = fill_2_hexByte(hex(int(balance)), 4) orderNoHex = fill_2_hexByte(hex(int(orderNo)), 10) maxTimeHex = fill_2_hexByte(hex(int(maxTime)), 2) spendMoneyHex = fill_2_hexByte(hex(int(spendMoney)), 4) otherHex = fill_2_hexByte(hex(int(other)), 4) data = portHex + methodHex + orderTypeHex + balanceHex + orderNoHex + maxTimeHex + spendMoneyHex + otherHex result = self._send_mqtt("A2", data=data) # deviceVersion = int(result["data"][2:8], 16) # port = int(result["data"][8:10], 16) # orderNo = int(result["data"][10:20], 16) # infoDict = { # "deviceVersion": deviceVersion, # "port": port, # "orderNo": orderNo # } return result def _update_charge_balance(self, port, balance, other=0): portHex = fill_2_hexByte(hex(int(port)), 2) balanceHex = fill_2_hexByte(hex(int(balance)), 4) otherHex = fill_2_hexByte(hex(int(other), 4)) data = portHex + balanceHex + otherHex result = self._send_mqtt("A3", data=data) deviceVersion = int(result["data"][2:8], 16) port = int(result["data"][8:10], 16) orderNo = int(result["data"][10:20], 16) newBalance = int(result["data"][20:24], 16) / 100 infoDict = { "deviceVersion": deviceVersion, "port": port, "orderNo": orderNo, "newBalance": newBalance, } return infoDict def _stop_remote(self, port, other=0): portHex = fill_2_hexByte(hex(int(port)), 2) otherHex = fill_2_hexByte(hex(int(other)), 4) data = portHex + otherHex result = self._send_mqtt("A4", data=data) deviceVersion = int(result["data"][2:8], 16) port = int(result["data"][8:10], 16) orderNo = int(result["data"][10:20], 16) chargeStatus = int(result["data"][20:22], 16) usedElec = int(result["data"][22:28], 16) / 1000 usedMoney = int(result["data"][28:32], 16) / 100 self._ack(port) infoDict = { "deviceVersion": deviceVersion, "port": port, "orderNo": orderNo, "chargeStatus": chargeStatus, "usedElec": usedElec, "usedMoney": usedMoney, } return infoDict def _ack(self, port): portHex = fill_2_hexByte(hex(int(port)), 2) data = portHex + "01" self._send_mqtt("AA", data=data, cmd=DeviceCmdCode.OPERATE_DEV_NO_RESPONSE) def _check_MCU_code(self): result = self._send_mqtt("B0", data="00") deviceVersion = int(result["data"][2:8], 16) deviceCode = int(result["data"][8:], 16) infoDict = { "deviceVersion": deviceVersion, "deviceCode": deviceCode } return infoDict def _check_MCU_temperature(self): result = self._send_mqtt("B1", data="00") deviceVersion = int(result["data"][2:8], 16) temperature = int(result["data"][8:], 16) infoDict = { "deviceVersion": deviceVersion, "temperature": temperature } return infoDict def _relay_control(self, relay, control): relayHex = fill_2_hexByte(hex(int(relay)), 2) controlHex = fill_2_hexByte(hex(int(control)), 2) data = relayHex + controlHex self._send_mqtt("B2", data=data, cmd=DeviceCmdCode.OPERATE_DEV_NO_RESPONSE) def _update_device(self, typeCode, code): typeCodeHex = fill_2_hexByte(hex(int(typeCode)), 2) codeHex = fill_2_hexByte(hex(int(code)), 6) data = typeCodeHex + codeHex self._send_mqtt("B3", data=data, cmd=DeviceCmdCode.OPERATE_DEV_NO_RESPONSE) def _restart_device(self): self._send_mqtt("B4", data="00", cmd=DeviceCmdCode.OPERATE_DEV_NO_RESPONSE) def _set_sound(self, sound): self._send_mqtt("B5", data=sound, cmd=DeviceCmdCode.OPERATE_DEV_NO_RESPONSE) def _remote_set_device_function_parameter(self, infoDic): minPowerHex = fill_2_hexByte(hex(int(float(infoDic.get("minPower")) / 0.2)), 2) checkTimeHex = fill_2_hexByte(hex(int(infoDic.get("checkTime"))), 2) powerFailureTimeHex = fill_2_hexByte(hex(int(infoDic.get("powerFailureTime")) / 5), 2) checkAutoStopHex = fill_2_hexByte(hex(int(infoDic.get("checkAutoStop"))), 2) floatTimeHex = fill_2_hexByte(hex(int(infoDic.get("floatTime"))), 2) price = fill_2_hexByte(hex(int(float(infoDic.get("price")) * 100)), 4) overloadPowerHex = fill_2_hexByte(hex(int(infoDic.get("overloadPower"))), 4) onceChargeTimeHex = fill_2_hexByte(hex(int(float(infoDic.get("onceChargeTime")) / 5)), 2) temperatureTresholdHex = fill_2_hexByte(hex(int(infoDic.get("checkTime"))), 2) powerPrice = infoDic.get("powerPrice") if len(powerPrice) < 10: i = len(powerPrice) while i < 10: powerPrice.update({str(i): {u'max': 0xffff, u'price': 655.35}}) i += 1 powerPriceHex = "" for i in range(10): max = powerPrice[str(i)]["max"] sectionPrice = int(powerPrice[str(i)]["price"] * 100) powerPriceHex = powerPriceHex + fill_2_hexByte(hex(int(max))) + fill_2_hexByte(hex(sectionPrice)) data = minPowerHex + checkTimeHex + powerFailureTimeHex + checkAutoStopHex + floatTimeHex + \ price + overloadPowerHex + onceChargeTimeHex + temperatureTresholdHex + powerPriceHex self._send_mqtt("B6", data=data, cmd=DeviceCmdCode.OPERATE_DEV_NO_RESPONSE) def _remote_get_dev_setting(self): result = self._send_mqtt("B7", data="00") data = result.get("data")[10:] minPower = int(data[0:2], 16) * 0.2 checkTime = int(data[2:4], 16) powerFailureTime = int(data[4:6], 16) * 5 checkAutoStop = int(data[6:8], 16) floatTime = int(data[8:10], 16) price = float(int(data[10:14], 16)) / 100 overloadPower = int(data[14:18], 16) onceChargeTime = int(data[18:20], 16) * 5 temperatureTreshold = int(data[20:22], 16) powerPriceHex = data[22:] packages = [] for i in range(10): max = int(powerPriceHex[i * 8:i * 8 + 8][:4], 16) sectionPrice = float(int(powerPriceHex[i * 8:i * 8 + 8][4:], 16)) / 100 if max != 65535 and sectionPrice != 6553.55: packages.append({"max": max, "price": sectionPrice}) sound = self.device.otherConf.get('sound') billingType = self.device.otherConf.get('billingType') infoDict = { "minPower": minPower, "checkTime": checkTime, "powerFailureTime": powerFailureTime, "checkAutoStop": checkAutoStop, "floatTime": floatTime, "price": price, "overloadPower": overloadPower, "onceChargeTime": onceChargeTime, "temperatureTreshold": temperatureTreshold, "packages": packages, "sound": sound, "billingType": billingType } return infoDict def _get_device_status_info(self): result = self._send_mqtt("A6", "00") deviceVersion = int(result["data"][2:8], 16) typeOfDevice = int(result["data"][8:10], 16) other = int(result["data"][10:12], 16) portStatus = result["data"][12:] if typeOfDevice == 1: portNum = 2 elif typeOfDevice == 2: portNum = 10 elif typeOfDevice == 3: portNum = 16 ii = 0 portNo = 0 portStatusDict = {} while ii < portNum: statusTemp = portStatus[ii * 2:ii * 2 + 2] if statusTemp == "00": status = {'status': Const.DEV_WORK_STATUS_IDLE, "statusCode": PortStatusCode.DEV_WORK_STATUS_IDLE} elif statusTemp == "01": status = {'status': Const.DEV_WORK_STATUS_FAULT_RELAY_CONNECT, "statusCode": PortStatusCode.DEV_WORK_STATUS_IDLE_POWER_NORMAL_FAULT_RELAY_CONNECT} elif statusTemp == "02": status = {'status': Const.DEV_WORK_STATUS_FAULT_OVERLOAD, "statusCode": PortStatusCode.DEV_WORK_STATUS_IDLE_FAULT_OVERLOAD_RELAY_CONNECT_NORMAL} elif statusTemp == "03": status = {'status': Const.DEV_WORK_STATUS_FAULT_OVERLOAD, "statusCode": PortStatusCode.DEV_WORK_STATUS_IDLE_FAULT_OVERLOAD_FAULT_RELAY_CONNECT} elif statusTemp == "04": status = {'status': Const.DEV_WORK_STATUS_WORKING, "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING} elif statusTemp == "05": status = {'status': Const.DEV_WORK_STATUS_FAULT_RELAY_CONNECT, "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_POWER_NORMAL_FAULT_RELAY_CONNECT} elif statusTemp == "06": status = {'status': Const.DEV_WORK_STATUS_FAULT_OVERLOAD, "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_FAULT_OVERLOAD_RELAY_CONNECT_NORMAL} elif statusTemp == "07": status = {'status': Const.DEV_WORK_STATUS_FAULT_OVERLOAD, "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_FAULT_OVERLOAD_FAULT_RELAY_CONNECT} elif statusTemp == "08": status = {'status': Const.DEV_WORK_STATUS_APPOINTMENT, "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_COIN} elif statusTemp == "09": status = {'status': Const.DEV_WORK_STATUS_FAULT_RELAY_CONNECT, "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_COIN_POWER_NORMAL_FAULT_RELAY_CONNECT} elif statusTemp == "10": status = {'status': Const.DEV_WORK_STATUS_FAULT_OVERLOAD, "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_COIN_FAULT_OVERLOAD_RELAY_CONNECT_NORMAL} elif statusTemp == "11": status = {'status': Const.DEV_WORK_STATUS_FAULT_OVERLOAD, "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_COIN_FAULT_OVERLOAD_FAULT_RELAY_CONNECT} else: status = {'status': Const.DEV_WORK_STATUS_FAULT} ii += 1 portNo += 1 portStatusDict[str(portNo)] = status infoDict = { "deviceVersion": deviceVersion, "typeOfDevice": typeOfDevice, "other": other, "portStatusDict": portStatusDict } return infoDict def analyze_event_data(self, data): cmdCode = data[0:2] if cmdCode == "A4": deviceVersion = int(reverse_hex(data[2:8]), 16) port = int(data[8:10], 16) orderNo = data[10:20], reasonCode = int(data[20:22], 16) usedElec = int(reverse_hex(data[22:28]), 16) / 1000 usedMoney = int(reverse_hex(data[28:32]), 16) / 100 if reasonCode == 1: reason = u"浮充开始" elif reasonCode == 2: reason = u"主动关闭" elif reasonCode == 3: reason = u"插头拔出" elif reasonCode == 4: reason = u"充电完成" elif reasonCode == 5: reason = u"充满自停" elif reasonCode == 6: reason = u"功率过载" elif reasonCode == 7: reason = u"电流过载" elif reasonCode == 8: reason = u"充电失败,检测功率过低" elif reasonCode == 9: reason = u"温度异常" elif reasonCode == 10: reason = u"消费用完" return { "cmdCode": cmdCode, "deviceVersion": deviceVersion, "port": port, "orderNo": orderNo, "reasonCode": reasonCode, "reason": reason, "usedElec": usedElec, "usedMoney": usedMoney } elif cmdCode == "A5": deviceCode = int(data[2:8], 16) port = int(data[8:10], 16) orderNo = int(data[10:20], 16) outputVoltage = int(reverse_hex(data[20:24]), 16) / 100 outputElec = int(reverse_hex(data[24:28]), 16) / 1000 power = int(reverse_hex(data[28:34]), 16) / 1000 usedElec = int(reverse_hex(data[34:40]), 16) / 1000 usedMoney = int(reverse_hex(data[40:44])), 16 / 100 return { "cmdCode": cmdCode, "deviceCode": deviceCode, "port": port, "orderNo": orderNo, "outputVoltage": outputVoltage, "outputElec": outputElec, "power": power, "usedElec": usedElec, "usedMoney": usedMoney } elif cmdCode == "A6": deviceVersion = int(data[2:8], 16) typeOfDevice = int(data[8:10], 16) other = int(data[10:12], 16) portStatus = data[12:] if typeOfDevice == 1: portNum = 2 elif typeOfDevice == 2: portNum = 10 elif typeOfDevice == 3: portNum = 16 ii = 0 portNo = 1 portStatusDict = {} while ii < portNum: statusTemp = portStatus[ii * 2:ii * 2 + 2] if statusTemp == "00": status = {'status': Const.DEV_WORK_STATUS_IDLE, "statusCode": PortStatusCode.DEV_WORK_STATUS_IDLE} elif statusTemp == "01": status = {'status': Const.DEV_WORK_STATUS_FAULT_RELAY_CONNECT, "statusCode": PortStatusCode.DEV_WORK_STATUS_IDLE_POWER_NORMAL_FAULT_RELAY_CONNECT} elif statusTemp == "02": status = {'status': Const.DEV_WORK_STATUS_FAULT_OVERLOAD, "statusCode": PortStatusCode.DEV_WORK_STATUS_IDLE_FAULT_OVERLOAD_RELAY_CONNECT_NORMAL} elif statusTemp == "03": status = {'status': Const.DEV_WORK_STATUS_FAULT_OVERLOAD, "statusCode": PortStatusCode.DEV_WORK_STATUS_IDLE_FAULT_OVERLOAD_FAULT_RELAY_CONNECT} elif statusTemp == "04": status = {'status': Const.DEV_WORK_STATUS_WORKING, "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING} elif statusTemp == "05": status = {'status': Const.DEV_WORK_STATUS_FAULT_RELAY_CONNECT, "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_POWER_NORMAL_FAULT_RELAY_CONNECT} elif statusTemp == "06": status = {'status': Const.DEV_WORK_STATUS_FAULT_OVERLOAD, "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_FAULT_OVERLOAD_RELAY_CONNECT_NORMAL} elif statusTemp == "07": status = {'status': Const.DEV_WORK_STATUS_FAULT_OVERLOAD, "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_FAULT_OVERLOAD_FAULT_RELAY_CONNECT} elif statusTemp == "08": status = {'status': Const.DEV_WORK_STATUS_WORKING, "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_COIN} elif statusTemp == "09": status = {'status': Const.DEV_WORK_STATUS_FAULT_RELAY_CONNECT, "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_COIN_POWER_NORMAL_FAULT_RELAY_CONNECT} elif statusTemp == "10": status = {'status': Const.DEV_WORK_STATUS_FAULT_OVERLOAD, "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_COIN_FAULT_OVERLOAD_RELAY_CONNECT_NORMAL} elif statusTemp == "11": status = {'status': Const.DEV_WORK_STATUS_FAULT_OVERLOAD, "statusCode": PortStatusCode.DEV_WORK_STATUS_WORKING_COIN_FAULT_OVERLOAD_FAULT_RELAY_CONNECT} else: status = {'status': Const.DEV_WORK_STATUS_FAULT} ii += 1 portNo += 1 portStatusDict[str(portNo)] = status return { "deviceVersion": deviceVersion, "typeOfDevice": typeOfDevice, "other": other, "portStatusDict": portStatusDict } elif cmdCode == "A7": deviceCode = int(data[2:8], 16) cardNo = int(data[8:16], 16) mode = int(data[16:18], 16) port = int(data[18:20], 16) return { "deviceCode": deviceCode, "cardNo": cardNo, "mode": mode, "port": port } elif cmdCode == "A8": deviceCode = int(data[2:8], 16) cardNo = int(data[8:16], 16) return { "deviceCode": deviceCode, "cardNo": cardNo } elif cmdCode == "AB": deviceCode = int(data[2:8], 16) port = int(data[8:10], 16) coins = int(data[10:14], 16) return { "deviceCode": deviceCode, "port": port, "coins": coins } elif cmdCode == "B8": deviceCode = int(data[2:8], 16) return { "deviceCode": deviceCode } def _check_package(self, package): billingType = self.device.otherConf.get('billingType','time') nowTime = int(time.time()) unit = self.device.otherConf.get('price') onceChargeTime = self.device.otherConf.get('onceChargeTime') or self._remote_get_dev_setting()['onceChargeTime'] onceChargeTime = int(onceChargeTime) if unit != 0: if billingType == BILLING_TYPE.TIME: method = '01' needTime = float(package['price']) / float(unit) * 60 elif billingType == BILLING_TYPE.POWER: method = '02' needTime = 0 elif billingType == BILLING_TYPE.ELEC: method = '03' needTime = package['price'] / float(unit) elif billingType == BILLING_TYPE.FREE: method = '04' needTime = 0 elif billingType == BILLING_TYPE.INTERVAL_QUOTA: method = '05' needTime = 0 else: method = '04' needTime = 0 if needTime > onceChargeTime: needTime = onceChargeTime finishedTime = nowTime + needTime * 60 * 60 return method, billingType, needTime, finishedTime def start_device(self, package, openId, attachParas): chargeIndex = attachParas.get("chargeIndex") port = int(chargeIndex) - 1 coins = float(package['price']) balance = int(coins * 100) if not chargeIndex: raise ServiceException({'result': 2, 'description': u'请您选择合适的充电线路'}) if not openId: raise ServiceException({"result": 2, "description": u"本设备暂不支持上分"}) devStatus = self._get_device_status_info() if devStatus["portStatusDict"][chargeIndex]['status'] == Const.DEV_WORK_STATUS_IDLE: method, billingType, needTime, finishedTime = self._check_package(package) orderType = '01' orderNo = attachParas['orderNo'][-10:] result = self._start_remote(port, method, orderType, balance, orderNo) portDict = { 'startTime': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), 'status': Const.DEV_WORK_STATUS_WORKING, 'finishedTime': finishedTime, 'coins': coins, 'isStart': True, 'orderNo': attachParas['orderNo'], 'useType': 'mobile', 'orderType': orderType, 'openId': openId, 'refunded': False, 'billingType': billingType, } if billingType == 'time': portDict.update({'needTime': needTime}) elif billingType == 'elec': portDict.update({'needElec': needTime}) elif billingType == "power": portDict.update({'leftMoney': coins}) Device.update_dev_control_cache(self._device['devNo'], {str(chargeIndex): portDict}) result["finishedTime"] = finishedTime return result elif devStatus["portStatusDict"][chargeIndex]['status'] == Const.DEV_WORK_STATUS_WORKING: result = self._update_charge_balance(port, balance) portDict = { "coins": result.get("newBalance") } Device.update_dev_control_cache(self._device['devNo'], {str(chargeIndex): portDict}) return result else: raise ServiceException( {'result': 2, 'description': u'车辆未连接,请先连接车辆!'}) def get_port_status_from_dev(self): result = self._get_device_status_info() portDict = result["portStatusDict"] allPorts, usedPorts, usePorts = self.get_port_static_info(portDict) 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 portDict.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 set_device_function_param(self, request, lastSetConf): minPower = request.POST.get("minPower") checkTime = request.POST.get("checkTime") powerFailureTime = request.POST.get("powerFailureTime") checkAutoStop = request.POST.get("checkAutoStop") floatTime = request.POST.get("floatTime") price = request.POST.get("price") overloadPower = request.POST.get("overloadPower") onceChargeTime = request.POST.get("onceChargeTime") temperatureTreshold = request.POST.get("temperatureTreshold") packages = request.POST.get('packages') powerPrice = {} for i in range(len(packages)): powerPrice[str(i)] = packages[i] lastSetConf.update( { "minPower": minPower, "checkTime": checkTime, "powerFailureTime": powerFailureTime, "checkAutoStop": checkAutoStop, "floatTime": floatTime, "price": price, "overloadPower": overloadPower, "onceChargeTime": onceChargeTime, "temperatureTreshold": temperatureTreshold, "powerPrice": powerPrice, } ) self._remote_set_device_function_parameter(lastSetConf) billingType = request.POST.get("billingType") sound = request.POST.get('sound') self.device.update_device_obj(**{ 'otherConf.billingType': billingType, 'otherConf.sound': sound, 'otherConf.onceChargeTime': onceChargeTime, 'otherConf.price': price }) if sound == '0': soundData = 'EO' elif sound == '1': soundData = 'E1' elif sound == '2': soundData = 'E2' elif sound == '3': soundData = 'E3' elif sound == '4': soundData = 'E4' elif sound == '5': soundData = 'E5' elif sound == '6': soundData = 'E6' elif sound == '7': soundData = 'E7' self._set_sound(soundData) def get_dev_setting(self): result = self._remote_get_dev_setting() return result def stop_charging_port(self, port=None): if not port: raise ServiceException({"result": 2, "description": u"请选择需要结束的充电端口"}) return self._stop_remote(port) def _response_data(self, cmd, data): self._send_mqtt(cmd, data) def get_port_status(self, force=False): if force: return self.get_port_status_from_dev()["portStatusDict"] ctrInfo = Device.get_dev_control_cache(self.device.devNo) if 'allPorts' in ctrInfo and ctrInfo['allPorts'] > 0: allPorts = ctrInfo['allPorts'] else: 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} return statusDict def active_deactive_port(self, chargeIndex, active): if active: raise ServiceException({'result': 2, 'description': u'该设备不支持直接打开端口'}) port = int(chargeIndex) - 1 self.stop_charging_port(str(port)) devInfo = Device.get_dev_control_cache(self._device['devNo']) portCtrInfo = devInfo.get(str(chargeIndex), {}) portCtrInfo.update({'isStart': False, 'status': Const.DEV_WORK_STATUS_IDLE, 'needTime': 0, 'leftTime': 0, 'endTime': datetime.datetime.now().strftime(Const.DATETIME_FMT)}) newValue = {str(chargeIndex): portCtrInfo} Device.update_dev_control_cache(self._device['devNo'], newValue) def get_port_info(self, chargeIndex): port = int(chargeIndex) - 1 portHex = fill_2_hexByte(hex(int(port)), 2) result = self._send_mqtt('A5', data=portHex) data = result['data'] deviceCode = int(reverse_hex(data[2:8]), 16) port = int(data[8:10], 16) orderNo = int(reverse_hex(data[10:20]), 16) outputVoltage = float(int(reverse_hex(data[20:24]), 16)) / 100 outputElec = float(int(reverse_hex(data[24:28]), 16)) / 1000 power = float(int(reverse_hex(data[28:34]), 16)) / 1000 usedElec = float(int(reverse_hex(data[34:40]), 16)) / 1000 usedMoney = float(int(reverse_hex(data[40:42]), 16)) / 100 cacheInfo = Device.get_dev_control_cache(self.device.devNo) lineInfo = cacheInfo[chargeIndex] startTime = datetime.datetime.strptime(lineInfo['startTime'], '%Y-%m-%d %H:%M:%S') startTime = int(time.mktime(startTime.timetuple())) nowTime = time.time() data = {"port": chargeIndex, "power": power, 'elec': usedElec, 'consumeMoney': usedMoney, \ 'outputVoltage': outputVoltage, 'outputElec': outputElec} if "needTime" in lineInfo: needTime = lineInfo['needTime'] leftTime = int(needTime - (nowTime - startTime) / 60) data.update({"needTime":needTime,"leftTime":leftTime}) elif "needElec" in lineInfo: needElec = lineInfo['needElec'] leftElec = float(needElec) - usedElec data.update({"needElec": needElec, "leftElec": leftElec}) elif "leftMoney" in lineInfo: leftMoney = float(lineInfo['leftMoney']) - usedMoney data.update({"leftMoney": leftMoney}) return data