123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- # coding=utf-8
- import binascii
- import logging
- import time
- from apps.web.constant import DeviceCmdCode, MQTT_TIMEOUT, Const
- from apps.web.core.adapter.base import SmartBox
- from apps.web.core.device_define.hangzhoufulian import FaultMap
- 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 UniqueUser
- logger = logging.getLogger(__name__)
- class HZFLChargeBox(SmartBox):
- def _send_data(self, funCode, sendData, cmd=DeviceCmdCode.OPERATE_DEV_SYNC, timeout=MQTT_TIMEOUT.NORMAL):
- result = MessageSender.send(
- device=self.device,
- cmd=cmd,
- payload={
- "IMEI": self._device["devNo"],
- "funCode": funCode,
- "data": sendData
- },
- timeout=timeout
- )
- if "rst" in result:
- if result["rst"] == -1:
- raise ServiceException({'result': 2, 'description': u'充电桩正在玩命找网络,请稍候再试'})
- elif result["rst"] == 1:
- raise ServiceException({'result': 2, 'description': u'充电桩暂时无响应,请稍后再试'})
- elif result["rst"] == 0:
- return result
- else:
- raise ServiceException({'result': 2, 'description': u'系统错误'})
- else:
- raise ServiceException({'result': 2, 'description': u'系统错误'})
- @staticmethod
- def _to_ascii(s):
- """
- :param s: 原始字符串
- :return:
- """
- return binascii.hexlify(s)
- @staticmethod
- def _to_str(h):
- """
- :param h:
- :return:
- """
- return binascii.unhexlify(h)
- @staticmethod
- def _parse_0100(data):
- """
- 故障解析
- :param data:
- :return:
- """
- faultCode = data[18: 20]
- port = int(data[20: 22], 16)
- isStop = not bool(int(data[22: 24], 16))
- return {
- "faultCode": faultCode,
- "port": port,
- "isStop": isStop,
- "fault": FaultMap.get(faultCode, u"未知错误")
- }
- @staticmethod
- def _parse_0102(data):
- """端口功率上报"""
- # TODO zjl 看下是不是轮询的解析 以及流水号的作用
- serialNo = data[18: 28]
- power = int(data[28: 32], 16)
- port = int(data[32: 34], 16)
- return {
- "serilaNo": serialNo,
- "power": power,
- "port": port
- }
- @staticmethod
- def _parse_0105(data):
- """充电开始或者结束上报"""
- serialNo = data[18: 28]
- port = int(data[28: 30], 16)
- needTime = int(data[30: 34], 16)
- power = int(data[34: 38], 16)
- isStop = bool(int(data[38: 40], 16))
- return {
- "serialNo": serialNo,
- "port": port,
- "needTime": needTime,
- "power": power,
- "isStop": isStop
- }
- @staticmethod
- def _parse_000A(data):
- pass
- @staticmethod
- def _parse_0107(data):
- """使用电量上报"""
- serialNo = data[18: 28]
- totalElec = int(data[28: 34], 16)
- return {
- "serialNo": serialNo,
- "totalElec": totalElec
- }
- def _check_device(self):
- """检查设备状态"""
- self._send_data("FFFF", "")
- def _set_device_power(self, noPower, littlePower, largePower, noPowerTime):
- """设置设备功率阈值"""
- noPowerHex = "{:0>4X}".format(int(noPower))
- littlePowerHex = "{:0>4X}".format(int(littlePower))
- largePowerHex = "{:0>4X}".format(int(largePower))
- noPowerTimeHex = "{:0>2X}".format(int(noPowerTime))
- sendData = noPowerTimeHex + noPowerHex + littlePowerHex + largePowerHex
- result = self._send_data("0003", sendData)
- if result["data"][18:20] != "01":
- raise ServiceException({"result": "2", "description": u"参数设置失败,请重试再试!"})
- def _set_device_package(self, coins, powerType, chargeTime):
- """设置设备套餐"""
- coinsHex = "{:0>2X}".format(coins)
- powerTypeHex = "{:0>4X}".format(powerType)
- chargeTimeHex = "{:0>4X}".format(chargeTime)
- sendData = coinsHex + powerTypeHex + chargeTimeHex
- result = self._send_data("0101", sendData)
- if result["data"][18:20] != "01":
- raise ServiceException({"result": "2", "description": u"参数设置失败,请重试再试!"})
- def _start_device(self, orderNo, coins, userId, port):
- """启动设备"""
- orderNoHex = "{:0>64}".format(self._to_ascii(orderNo))
- coinsHex = "{:0>4X}".format(int(coins))
- userIdHex = "{:0>8X}".format(int(userId))
- portHex = "{:0>2X}".format(port)
- sendData = orderNoHex + coinsHex + userIdHex + portHex
- result = self._send_data("0004", sendData)
- return result
- def _get_server_conf(self):
- otherConf = self.device.get("otherConf", dict())
- return {
- "totalElec": otherConf.get("totalElec", 0)
- }
- def _get_device_conf(self):
- return {}
- def get_port_status_from_dev(self):
- maxPorts = 10
- resultDict = dict()
- devCache = Device.get_dev_control_cache(self.device.devNo)
- for _port in range(1, maxPorts+1):
- chargeIndex = str(_port)
- portCache = devCache.get(chargeIndex)
- if not portCache:
- portCache = {"status": Const.DEV_WORK_STATUS_IDLE}
- resultDict[chargeIndex] = portCache
- 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 get_port_status(self, force=False):
- return self.get_port_status_from_dev()
- def get_dev_setting(self):
- conf = dict()
- serverConf = self._get_server_conf()
- deviceConf = self._get_device_conf()
- conf.update(serverConf)
- conf.update(deviceConf)
- return conf
- def set_device_function_param(self, request, lastSetConf):
- if "noPower" in request.POST:
- pass
- elif "chargeType" in request.POST:
- pass
- else:
- raise ServiceException({"result": "2", "description": u"不支持的参数设置!"})
- def analyze_event_data(self, data):
- funCode = data[14:16]
- if funCode == "0100":
- event = self._parse_0100(data)
- elif funCode == "0102":
- event = self._parse_0102(data)
- elif funCode == "0105":
- event = self._parse_0105(data)
- elif funCode == "000A":
- event = self._parse_000A(data)
- elif funCode == "0107":
- event = self._parse_0107(data)
- else:
- logger.error("receice unanalyze event data, data is <{}>, device is <{}>".format(data, self.device.devNo))
- return
- event["cmdCode"] = funCode
- return event
- def start_device(self, package, openId, attachParas):
- chargeIndex = attachParas.get("chargeIndex")
- if not chargeIndex:
- raise ServiceException({"result": "2", "description": u"请选择合适的充电线路!"})
- port = int(chargeIndex)
- orderNo = attachParas["orderNo"]
- coins = package["time"]
- uniqueUser = UniqueUser.objects.filter(openId=openId).first() # type: UniqueUser
- userId = uniqueUser.userId if uniqueUser else 0
- result = self._start_device(orderNo=orderNo, coins=coins, userId=userId, port=port)
- startTime = int(time.time())
- portCache = {
- "status": Const.DEV_WORK_STATUS_WORKING,
- "isStart": True,
- "coins": coins,
- "openId": openId,
- "orderNo": orderNo,
- "startTime": startTime
- }
- Device.update_dev_control_cache(self.device.devNo, {str(port): portCache})
- result["finishedTime"] = (3600 * 12) + startTime
- result["startTIme"] = startTime
- return result
- def check_dev_status(self, attachParas=None):
- self._check_device()
|