123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- # -*- coding: utf-8 -*-
- # !/usr/bin/env python
- import logging
- import time
- from typing import TYPE_CHECKING
- from apilib.utils_string import split_str
- from apps.web.constant import DeviceCmdCode, MQTT_TIMEOUT, Const
- 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
- if TYPE_CHECKING:
- pass
- logger = logging.getLogger(__name__)
- class ChargingZhongChuangCarBox(SmartBox):
- DATA_OFFSET = 8
- ARRAY_INDEX_INCR = 10
- def __init__(self, device):
- super(ChargingZhongChuangCarBox, self).__init__(device)
-
- def translate_funcode(self,funCode):
- funCodeDict = {
- '03':u'从设备读数据',
- '06':u'向设备写数据',
- }
- return funCodeDict.get(funCode,'')
-
- def __read__(self, offset, size):
- request_data = fill_2_hexByte(hex(int(offset)), 4)
- request_data += (fill_2_hexByte(hex(int(size)), 4))
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': self._device['devNo'], "funCode": '03', 'data': request_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'充电桩忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能'})
- return devInfo['data'][ChargingZhongChuangCarBox.DATA_OFFSET:]
- def __write__(self, offset, value,timeout = MQTT_TIMEOUT.NORMAL,orderNo=None):
- request_data = fill_2_hexByte(hex(int(offset)), 4)
- request_data += fill_2_hexByte(hex(int(value)), 4)
- devInfo = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- {'IMEI': self._device['devNo'], 'funCode': '06', 'data': request_data},
- timeout = timeout)
- 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'][:-4] != ('0106' + request_data):
- raise ServiceException({'result': 2, 'description': u'写入充电桩数据错误'})
- return devInfo
- def get_port_info(self, line):
- return self.get_port_status().get(line)
- @staticmethod
- def __parse_port_status(response_data):
- def translate_status(status):
- if status in [0,1]:
- return Const.DEV_WORK_STATUS_IDLE
- elif status in [2]:
- return Const.DEV_WORK_STATUS_CONNECTED
- elif status in [3]:
- return Const.DEV_WORK_STATUS_WORKING
- elif status in [5,6,7,8]:
- return Const.DEV_WORK_STATUS_FAULT
- else:
- return Const.DEV_WORK_STATUS_FINISHED
- if len(response_data) < 80:#现网日志报错,有异常报文上报
- return {}
- descDict = {
- '0':u'空闲',
- '1':u'空闲',
- '2':u'枪已经连接',
- '3':u'正在充电',
- '4':u'充电完成',
- '5':u'电压偏高',
- '6':u'漏电保护',
- '7':u'电压偏低',
- '8':u'紧急停止'
- }
- result = split_str(response_data, lens="4"*21)
- devStatus = dict()
- # 定义多路之间数组下标增量
- portNum = int(result[0], 16)
- for port in xrange(portNum):
- portStr = str(port+1)
- devStatus[portStr] = {
- "power": int(result[1+port*ChargingZhongChuangCarBox.ARRAY_INDEX_INCR], 16),
- "voltage": int(result[2+port*ChargingZhongChuangCarBox.ARRAY_INDEX_INCR], 16),
- "elec": int(result[3+port*ChargingZhongChuangCarBox.ARRAY_INDEX_INCR], 16) / 1000.0,
- "orgStatus": int(result[4+port*ChargingZhongChuangCarBox.ARRAY_INDEX_INCR], 16),
- "balance": int(result[5+port*ChargingZhongChuangCarBox.ARRAY_INDEX_INCR], 16) / 10.0,
- "duration": int(result[6+port*ChargingZhongChuangCarBox.ARRAY_INDEX_INCR], 16),
- "status": translate_status(int(result[4+port*ChargingZhongChuangCarBox.ARRAY_INDEX_INCR], 16)),
- "desc": descDict.get(str(int(result[4+port*ChargingZhongChuangCarBox.ARRAY_INDEX_INCR])))
- }
- return devStatus
- def get_port_status(self, force=False):
- # 缓存中会有初始下发的金币信息
- devStatus = self.__parse_port_status(self.__read__(0, 21))
- # TODO 连接状态不要影响支付 这个地方暂时简单修改 后续需要将这个去掉 然后前台的状态为 连接状态的时候可以进行支付
- for value in devStatus.values():
- if isinstance(value, dict) and "status" in value and value["status"] == Const.DEV_WORK_STATUS_CONNECTED:
- value["status"] = Const.DEV_WORK_STATUS_IDLE
- Device.update_dev_control_cache(self._device["devNo"], devStatus)
- devCache = Device.get_dev_control_cache(self._device["devNo"])
- return devCache
- def start_device(self, package, openId, attachParas):
- price = int(package['price'] * 10)
- if price < 1:
- raise ServiceException({'result': 2, 'description': u'请输入正确的支付费用'})
-
- port = attachParas['chargeIndex']
- logger.debug('charge index = %s; price = %s' % (port, price))
- offset = 10 + (int(port) - 1) * self.ARRAY_INDEX_INCR
-
- orderNo = attachParas.get('orderNo')
- devInfo = self.__write__(offset, price, timeout = MQTT_TIMEOUT.START_DEVICE, orderNo = orderNo)
- cacheValue = Device.get_dev_control_cache(self._device['devNo'])
- if not cacheValue:
- return
-
- rechargeRcdId = attachParas.get("linkedRechargeRecordId")
- cacheValue.update({
- str(port):
- {
- 'openId': openId,
- "coins": package['coins'],
- "price": package['price'],
- "rechargeRcdId": str(rechargeRcdId) if rechargeRcdId else None,
- "vCardId": self._vcard_id,
- 'isStart': True,
- 'status': Const.DEV_WORK_STATUS_WORKING,
- 'finishedTime': int(time.time()) + 24 * 60 * 60
- }
- })
-
- Device.update_dev_control_cache(self._device['devNo'], cacheValue)
- return devInfo
-
- def get_port_status_from_dev(self):
- status = self.get_port_status()
- allPorts,usedPorts = len(status),0
- for portInfo in status.values():
- count = 0 if portInfo['status'] in [Const.DEV_WORK_STATUS_IDLE,Const.DEV_WORK_STATUS_FINISHED] else 1
- usedPorts += count
-
- status.update({'allPorts':allPorts,'usedPorts':usedPorts,'usePorts':allPorts - len(usedPorts)})
- Device.update_dev_control_cache(self._device['devNo'], status)
- return status
-
- def analyze_event_data(self, data):
- return self.__parse_port_status(data[ChargingZhongChuangCarBox.DATA_OFFSET:])
-
- def reply_left_balance(self,port,balance=0):
- offset = 5 + (int(port) - 1) * self.ARRAY_INDEX_INCR
- self.__write__(offset, int(balance), timeout=120)
|