# coding=utf-8 import logging from typing import TYPE_CHECKING from apps.web.constant import Const from apps.web.core.adapter.base import SmartBox from apps.web.core.device_define.wxlz import DefaultParams from apps.web.core.exceptions import ServiceException from apps.web.core.networking import MessageSender from apps.web.device.models import Device if TYPE_CHECKING: from apps.web.user.models import ConsumeRecord logger = logging.getLogger(__name__) class ChargingBox(SmartBox): STATUS_MAP = { 0x01: Const.DEV_WORK_STATUS_IDLE, 0x02: Const.DEV_WORK_STATUS_WORKING, 0x03: Const.DEV_WORK_STATUS_FORBIDDEN, 0x04: Const.DEV_WORK_STATUS_FAULT, } @staticmethod def _check_package(package): if package["unit"] == u"分钟": chargeTime = int(package["time"]) elif package["unit"] == u"小时": chargeTime = int(package["time"]) * 60 else: chargeTime = 0 return chargeTime @staticmethod def _trans_status(status): return ChargingBox.STATUS_MAP.get(status, Const.DEV_WORK_STATUS_FAULT) def _clean_elec(self): result = MessageSender.send( device=self.device, cmd=210, payload={ "funCode": "clean_elec", } ) if result["rst"] == -1: raise ServiceException({"result": 2, "description": u"设备网络故障,清除电量失败"}) if result["rst"] == 1: raise ServiceException({"result": 2, "description": u"设备端口故障,停止电量失败"}) def _get_settings_from_device(self): """ 获取设备端的参数设置 包括存储在模块的参数 :return: """ result = MessageSender.send( device=self.device, cmd=210, payload={ "funCode": "get_settings" } ) if result["rst"] == -1: raise ServiceException({"result": 2, "description": u"设备网络故障,读取设备参数失败"}) if result["rst"] == 1: raise ServiceException({"result": 2, "description": u"设备端口故障,读取设备参数失败"}) powerPackage = list() powerDefaultPrice = int(result["data"]["power_default_price"]) / 100.0 for _item in result["data"]["power_step"]: powerPackage.append( {"min": int(_item["min"]), "max": int(_item["max"]), "price": int(_item["price"]) / 100.0} ) return { "powerPackage": powerPackage, "powerDefaultPrice": powerDefaultPrice, "usedElec": result["data"]["used_elec"] / 100.0, "temperature": result["data"]["temperature"] } def _set_settings_to_device(self, conf): powerDefaultPrice = int(float(conf["powerDefaultPrice"]) * 100) powerPackage = list() for _item in conf["powerPackage"]: powerPackage.append( {"min": int(_item["min"]), "max": int(_item["max"]), "price": int(float(_item["price"])*100)} ) data = { "power_step": powerPackage, "power_default_price": powerDefaultPrice } result = MessageSender.send( device=self.device, cmd=210, payload={ "funCode": "set_settings", "data": data } ) if result["rst"] == -1: raise ServiceException({"result": 2, "description": u"设备网络故障,设置设备参数失败"}) if result["rst"] == 1: raise ServiceException({"result": 2, "description": u"设备端口故障,设置设备参数失败"}) def _stop(self, port): result = MessageSender.send( device=self.device, cmd=210, payload={ "funCode": "stop", "data": {"port": int(port)} } ) if result["rst"] == -1: raise ServiceException({"result": 2, "description": u"设备网络故障,停止运行失败"}) if result["rst"] == 1: raise ServiceException({"result": 2, "description": u"设备端口故障,停止运行失败"}) def _get_all_status_from_device(self): result = MessageSender.send( device=self.device, cmd=210, payload={ "funCode": "all_status", } ) if result["rst"] == -1: raise ServiceException({"result": 2, "description": u"设备网络故障,获取端口运行状态失败"}) if result["rst"] == 1: raise ServiceException({"result": 2, "description": u"设备端口故障,获取端口运行状态失败"}) data = result["data"] allStatus = dict() for _port, _item in data.items(): allStatus[_port] = {"status": self._trans_status(_item["status"]), "power": _item["power"]} return allStatus def _async_settings(self): otherConf = self.device.get("otherConf", dict()) conf = { "powerPackage": otherConf.get("powerPackage", DefaultParams.DEFAULT_POWER_PACKAGE), "powerDefaultPrice": otherConf.get("powerDefaultPrice", DefaultParams.DEFAULT_POWER_PRICE) } self._set_settings_to_device(conf) def _get_port_detail(self, port): result = MessageSender.send( device=self.device, cmd=210, payload={ "funCode": "port_status", "data": { "port": int(port) } } ) if result["rst"] == -1: raise ServiceException({"result": 2, "description": u"设备网络故障,端口状态获取失败"}) if result["rst"] == 1: raise ServiceException({"result": 2, "description": u"设备端口故障,端口状态获取失败"}) data = result["data"] order = data.pop("order", None) if order: data["needTime"] = order["charge_time"] data["startTime"] = order["sts"] data["openId"] = order["open_id"] data["consumeMoney"] = order["money"] / 100.0 data["usedTime"] = order["duration"] / 60 data["status"] = self._trans_status(data["status"]) return data def get_dev_setting(self): deviceSettings = self._get_settings_from_device() deviceSettings["powerPackage"] = deviceSettings["powerPackage"] or [] serverSettings = self.device.get("otherConf") or dict() allSettings = { "usedElec": deviceSettings["usedElec"], "temperature": deviceSettings["temperature"], "minAfterStartCoins": serverSettings.get("minAfterStartCoins", DefaultParams.DEFAULT_MIN_COIN), "chargeType": "power", "elecPrice": 0, "powerPackage": deviceSettings["powerPackage"], "powerDefaultPrice": deviceSettings["powerDefaultPrice"], } return allSettings def set_device_function_param(self, request, lastSetConf): chargeType = request.POST.get("chargeType") if chargeType == "elec": raise ServiceException({"result": 2, "description": u"电量计费模式尚未开放,敬请期待"}) minAfterStartCoins = request.POST.get("minAfterStartCoins") powerPackage = request.POST.get("powerPackage") powerDefaultPrice = request.POST.get("powerDefaultPrice") otherConf = self.device.get("otherConf", dict()) otherConf["powerPackage"] = powerPackage otherConf["powerDefaultPrice"] = powerDefaultPrice otherConf["minAfterStartCoins"] = minAfterStartCoins Device.objects.filter(devNo=self.device.devNo).update(otherConf=otherConf) Device.invalid_device_cache(self.device.devNo) self._set_settings_to_device(otherConf) def set_device_function(self, request, lastSetConf): cleanElec = request.POST.get("cleanElec") if cleanElec: self._clean_elec() def start_device_realiable(self, order): # type:(ConsumeRecord)->dict port = order.used_port if port == -1: raise ServiceException({"result": 2, "description": u"请您选择合适的充电线路"}) chargeTime = self._check_package(order.package) if not chargeTime: raise ServiceException({"result": 2, "description": u"充电套餐单位错误,请联系设备老板进行处理"}) data = { "open_id": order.openId, "order_id": order.orderNo, "order_type": "com_start", "port": port, "charge_time": chargeTime } result = MessageSender.send( device=self.device, cmd=210, payload={ "funCode": "start", "data": data } ) return result def stop(self, port=None): if not port: raise ServiceException({"result": 2, "description": u"停止运行失败,无效的设备端口"}) self._stop(port) def get_port_status_from_dev(self): allStatus = self._get_all_status_from_device() status = {} devCache = Device.get_dev_control_cache(self.device.devNo) for _key, _value in allStatus.items(): _portCache = devCache.get(_key) or dict() _portCache.update(_value) status[_key] = _portCache Device.update_dev_control_cache(self.device.devNo, status) allPorts, usedPorts, usePorts = self.get_port_static_info(allStatus) Device.update_dev_control_cache( self._device["devNo"], { "allPorts": allPorts, "usedPorts": usedPorts, "usePorts": usePorts } ) return allStatus def get_port_status(self, force = False): if force: self.get_port_status_from_dev() devCache = Device.get_dev_control_cache(self.device.devNo) allPorts = devCache.get("allPorts", 10) status = dict() for _port in xrange(1, allPorts+1): status[str(_port)] = {"status": devCache.get(str(_port), dict()).get("status", Const.DEV_WORK_STATUS_IDLE)} return status def get_port_info(self, port): data = self._get_port_detail(port) return data def get_port_using_detail(self, port, ctrInfo, isLazy=False): portCache = ctrInfo.get(str(port), dict()) curInfo = self.get_port_info(port) curInfo.update(portCache) return curInfo def active_deactive_port(self, port, active): if not active: self.stop(port)