123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- # -*- coding: utf-8 -*-
- # !/usr/bin/env python
- import logging
- from voluptuous import Schema, Range, Required, REMOVE_EXTRA
- from apps.web.constant import DeviceCmdCode, Const, MQTT_TIMEOUT
- 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
- logger = logging.getLogger(__name__)
- class ChargingZhongChuangBox(SmartBox):
- FIRST_INDEX = 1
- DATA_SIZE = 80
- DATA_OFFSET = 8
- SETTING_FIRST_INDEX = 41
- SETTING_LAST_INDEX = 43
- SETTING_SCHEMA = Schema({
- Required('unitPrice'): Range(min = 1, max = 250, msg = u'单次刷卡扣费参数错误'),
- Required('feeRate'): Range(min = 1, max = 99, msg = u'一元可充电度数参数错误'),
- Required('powerLimit'): Range(min = 100, max = 3000, msg = u'功耗极限设定参数错误'),
- }, extra = REMOVE_EXTRA)
-
- def __init__(self, device):
- super(ChargingZhongChuangBox, 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'][ChargingZhongChuangBox.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)
- def __parse_port_status(self, response_data):
- if len(response_data) < 44:#现网日志报错,有异常报文上报
- return {}
-
- forbidden_flag = int(response_data[40:44], 16)
- result = {}
- for ii in range(1, 11):
- response_status = response_data[(ii - 1) * 4: ii * 4]
- status = Const.DEV_WORK_STATUS_IDLE if forbidden_flag == 1 else Const.DEV_WORK_STATUS_FORBIDDEN
- if response_status == '0001':
- status = Const.DEV_WORK_STATUS_WORKING
- elif response_status == '0000':
- status = Const.DEV_WORK_STATUS_IDLE if forbidden_flag == 1 else Const.DEV_WORK_STATUS_FORBIDDEN
- elif response_status == '0002':
- status = Const.DEV_WORK_STATUS_FAULT
- result[str(ii)] = {'status': status}
- allPorts, usedPorts, usePorts = self.get_port_static_info(result)
- Device.update_dev_control_cache(self._device['devNo'],
- {'allPorts': allPorts,
- 'usedPorts': usedPorts,
- 'usePorts': usePorts,
- 'ports': result})
- return result
- def get_port_status(self, force=False):
- cacheValue = Device.get_dev_control_cache(self._device['devNo'])
- if 'ports' in cacheValue and force:
- return cacheValue['ports']
- else:
- return self.__parse_port_status(self.__read__(21, 11))
- def start_device(self, package, openId, attachParas):
- price = int(package['price'] * 10)
- if price < 1:
- raise ServiceException({'result': 2, 'description': u'请输入正确的支付费用'})
- logger.debug('charge index = %s; price = %s' % (attachParas['chargeIndex'], price))
- orderNo = attachParas.get('orderNo')
- devInfo = self.__write__(attachParas['chargeIndex'], price, timeout = MQTT_TIMEOUT.START_DEVICE,
- orderNo = orderNo)
- cacheValue = Device.get_dev_control_cache(self._device['devNo'])
- if not cacheValue:
- return
- cacheValue.update({'openId': openId, 'isStart': True})
- if 'ports' in cacheValue and str(attachParas['chargeIndex']) in cacheValue['ports']:
- cacheValue['ports'][str(attachParas['chargeIndex'])].update({'status': Const.DEV_WORK_STATUS_WORKING})
- Device.update_dev_control_cache(self._device['devNo'], cacheValue)
- return devInfo
-
- def get_dev_setting(self):
- device = Device.get_dev(self._device['devNo'])
- if device['otherConf']:
- return device['otherConf']
- else:
- response_data = self.__read__(ChargingZhongChuangBox.SETTING_FIRST_INDEX,
- ChargingZhongChuangBox.SETTING_LAST_INDEX)
- unitPrice = float(int(response_data[0:4], 16)) / 10
- feeRate = float(int(response_data[4:8], 16)) / 10
- powerLimit = int(response_data[8:12], 16)
- Device.update_field(
- dev_no = self._device['devNo'],
- otherConf = {
- 'unitPrice': unitPrice,
- 'feeRate': feeRate,
- 'powerLimit': powerLimit
- })
- return {'unitPrice': unitPrice, 'feeRate': feeRate, 'powerLimit': powerLimit}
- def set_dev_setting(self, configDict):
- settings = {
- 'unitPrice': int(10 * float(configDict.get('unitPrice'))),
- 'feeRate': int(10 * float(configDict.get('feeRate'))),
- 'powerLimit': int(configDict.get('powerLimit'))
- }
- settings = ChargingZhongChuangBox.SETTING_SCHEMA(settings)
- if settings['unitPrice'] != int(10 * float(self._device['otherConf']['unitPrice'])):
- self.__write__(ChargingZhongChuangBox.SETTING_FIRST_INDEX, settings['unitPrice'])
- if settings['feeRate'] != int(10 * float(self._device['otherConf']['feeRate'])):
- self.__write__(ChargingZhongChuangBox.SETTING_FIRST_INDEX + 1, settings['feeRate'])
- if settings['powerLimit'] != int(self._device['otherConf']['powerLimit']):
- self.__write__(ChargingZhongChuangBox.SETTING_FIRST_INDEX + 2, settings['powerLimit'])
- Device.update_field(
- dev_no = self._device['devNo'],
- otherConf = {
- 'unitPrice': float(configDict.get('unitPrice')),
- 'feeRate': float(configDict.get('feeRate')),
- 'powerLimit': configDict.get('powerLimit')
- })
- def analyze_event_data(self, data):
- self.__parse_port_status(data[ChargingZhongChuangBox.DATA_OFFSET:][20 * 4:31 * 4])
- def remote_charge_card(self, price, rechargeRecord=None):
- return self.__write__(50, 10 * int(price.amount))
-
- def set_device_function_param(self,request,lastSetConf):
- setting = {
- 'unitPrice': request.POST.get('unitPrice'),
- 'feeRate': request.POST.get('feeRate'),
- 'powerLimit': request.POST.get('powerLimit')
- }
- self.set_dev_setting(setting)
|