123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- # -*- coding: utf-8 -*-
- # !/usr/bin/env python
- import datetime
- import re
- from decimal import Decimal
- from apps.web.constant import DeviceCmdCode, Const
- from apps.web.core.adapter.base import SmartBox
- 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 ConsumeRecord
- class FastCharge(SmartBox):
- def __init__(self, device):
- super(FastCharge, self).__init__(device)
- def _check_package(self, package):
- """
- 获取设备启动的发送数据 根据设备的当前模式以及套餐获取
- :param package:
- :return:
- """
- devConf = self.get_device_configs()
- coinElec = devConf.get('coinElec', 10) # 单位是0.1度
- coinTime = devConf.get('coinMin', 240)
- maxTotalTime = devConf.get('maxTotalTime', 0) or 720
- coins = float(package.get('coins'))
- elec = coins * coinElec * 0.1
- _time = min(coins * coinTime, maxTotalTime)
- return _time, elec, coins
- def disable_app_device(self, switch=True):
- # type:(bool) -> None
- otherConf = self.device.get('otherConf', {})
- otherConf['disableDevice'] = switch
- Device.objects.filter(devNo=self.device['devNo']).update(otherConf=otherConf)
- Device.invalid_device_cache(self.device['devNo'])
- def reverse_hex(self, data):
- # type:(str) -> str
- if not isinstance(data, str):
- raise TypeError
- return ''.join(list(reversed(re.findall(r'.{2}', data))))
- def encode_str(self, data, length=2, ratio=1.0, base=16):
- # type:(any,int,float,int) -> str
- if not isinstance(data, Decimal):
- data = Decimal(data).quantize(Decimal('0.00'))
- if not isinstance(length, str):
- length = str(length)
- if not isinstance(ratio, Decimal):
- ratio = Decimal(ratio)
- end = 'X' if base == 16 else 'd'
- encodeStr = '%.' + length + end
- encodeStr = encodeStr % (data * ratio)
- return encodeStr
- def decode_str(self, data, ratio=1.0, base=16, reverse=False):
- # type:(str,float,int,bool) -> str
- """
- ratio:比率单位转换
- """
- if not isinstance(data, str):
- data = str(data)
- if reverse:
- data = ''.join(list(reversed(re.findall(r'.{2}', data))))
- return '%.10g' % (int(data, base) * ratio)
- def decode_long_hex_to_list(self, data, split=2, ratio=1.0, base=16):
- # type:(str,int,float,int) -> list
- """
- return: list
- """
- if len(data) % split != 0:
- raise Exception('Invalid data')
- pattern = r'.{%s}' % split
- hex_list = re.findall(pattern, data)
- hex_list = map(lambda x: self.decode_str(x, ratio=ratio, base=base), hex_list)
- return hex_list
- def check_params_range(self, params, minData=None, maxData=None, desc=''):
- # type:(str,float,float,str) -> str
- """
- 检查参数,返回字符串参数
- """
- if params is None:
- raise ServiceException({'result': 2, 'description': u'参数错误.'})
- if not isinstance(params, Decimal):
- params = Decimal(params)
- if not minData and maxData:
- if not isinstance(maxData, Decimal):
- maxData = Decimal(maxData)
- if params <= maxData:
- return '%g' % params
- else:
- raise ServiceException({'result': 2, 'description': u'%s超出可选范围,可选最大值为%g' % (desc, maxData)})
- if not maxData and minData:
- if not isinstance(minData, Decimal):
- minData = Decimal(minData)
- if minData <= params:
- return '%g' % params
- else:
- raise ServiceException({'result': 2, 'description': u'%s超出可选范围,可选最小值为%g' % (desc, minData)})
- if not minData and not maxData:
- return '%g' % params
- else:
- if not isinstance(minData, Decimal):
- minData = Decimal(minData)
- if not isinstance(maxData, Decimal):
- maxData = Decimal(maxData)
- if minData <= params <= maxData:
- return '%g' % params
- else:
- raise ServiceException(
- {'result': 2, 'description': u'%s参数超出可选范围,可取范围为%g-%g' % (desc, minData, maxData)})
- def send_mqtt(self, funCode, data, cmd=DeviceCmdCode.OPERATE_DEV_SYNC, order_id=None):
- """
- 发送mqtt 指令210 返回data
- """
- if not isinstance(funCode, str):
- funCode = str(funCode)
- if not isinstance(data, str):
- data = str(data)
- payload = {'IMEI': self.device['devNo'], 'funCode': funCode, 'data': data}
- if order_id:
- payload.update({'order_id': order_id})
- result = MessageSender.send(self.device, cmd, payload)
- if 'rst' in result and result['rst'] != 0:
- if result['rst'] == -1:
- raise ServiceException(
- {'result': 2, 'description': u'该设备正在玩命找网络,请您稍候再试', 'rst': -1})
- elif result['rst'] == 1:
- raise ServiceException(
- {'result': 2, 'description': u'该设备忙,无响应,请您稍候再试。也可能是您的设备版本过低,暂时不支持此功能', 'rst': 1})
- else:
- if cmd in [DeviceCmdCode.OPERATE_DEV_NO_RESPONSE, DeviceCmdCode.PASSTHROUGH_OPERATE_DEV_NO_RESPONSE]:
- return
- if 'order_id' in result or 'order_info' in result:
- return result
- else:
- return result.get('data', '')
- @staticmethod
- def port_is_busy(port_dict):
- if not port_dict:
- return False
- if 'billingType' not in port_dict:
- return False
- if 'status' not in port_dict:
- return False
- if 'coins' not in port_dict:
- return False
- if port_dict['billingType'] not in ['time', 'elec']:
- return False
- if port_dict['billingType'] == 'time':
- if 'needTime' not in port_dict:
- return False
- else:
- if 'needElec' not in port_dict:
- return False
- if port_dict['status'] == Const.DEV_WORK_STATUS_WORKING:
- return True
- else:
- return False
- def do_update_configs(self, updateDict):
- dev = Device.objects.get(devNo=self.device.devNo)
- deviceConfigs = dev.otherConf.get('deviceConfigs', {})
- deviceConfigs.update(updateDict)
- dev.otherConf['deviceConfigs'] = deviceConfigs
- dev.save()
- Device.invalid_device_cache(self.device.devNo)
- def get_device_configs(self):
- dev = Device.get_dev(self.device.devNo)
- deviceConfigs = dev.get('otherConf', {}).get('deviceConfigs', {})
- return deviceConfigs
- def start_device_realiable(self, order):
- # type:(ConsumeRecord)->dict
- package = order.package
- coins = package.get('coins', 0)
- deviceType = '03'
- port = order.used_port
- userType = '01'
- userNum = '{:0>16s}'.format(order.orderNo)
- sequanceNo = '{:0>16s}'.format(order.orderNo) + datetime.datetime.now().strftime('%Y%m%d%H%M%S')
- balance = self.encode_str(coins, length=8, ratio=100.0)
- chargeType = '00' # 00 为立即充电 01为 预约充电
- featureStr = 'FF'
- self.get_consumption_rules()
- return {}
- def get_dev_setting(self):
- deviceConfigs = self.get_device_configs()
- if not deviceConfigs:
- pass
- packages = [{'serviceFee': '2.5', 'parkingFee': '2.5', 'unitPrice': '2.5', 'startTime': '00:00'},
- {'serviceFee': '2.5', 'parkingFee': '2.5', 'unitPrice': '2.5', 'startTime': '03:00'},
- {'serviceFee': '2.5', 'parkingFee': '2.5', 'unitPrice': '2.5', 'startTime': '06:00'},
- {'serviceFee': '2.5', 'parkingFee': '2.5', 'unitPrice': '2.5', 'startTime': '09:00'},
- {'serviceFee': '2.5', 'parkingFee': '2.5', 'unitPrice': '2.5', 'startTime': '12:00'},
- {'serviceFee': '2.5', 'parkingFee': '2.5', 'unitPrice': '2.5', 'startTime': '15:00'},
- {'serviceFee': '2.5', 'parkingFee': '2.5', 'unitPrice': '2.5', 'startTime': '18:00'},
- {'serviceFee': '2.5', 'parkingFee': '2.5', 'unitPrice': '2.5', 'startTime': '21:00'}]
- return {'package': packages}
- def set_device_function_param(self, request, lastSetConf):
- print request, lastSetConf
- def get_consumption_rules(self):
- packages = [
- {'serviceFee': '2.5', 'parkingFee': '2.5', 'unitPrice': '2.5', 'startTime': '00:00'},
- {'serviceFee': '2.5', 'parkingFee': '2.5', 'unitPrice': '2.5', 'startTime': '03:00'},
- {'serviceFee': '2.5', 'parkingFee': '2.5', 'unitPrice': '2.5', 'startTime': '06:00'},
- {'serviceFee': '2.5', 'parkingFee': '2.5', 'unitPrice': '2.5', 'startTime': '09:00'},
- {'serviceFee': '2.5', 'parkingFee': '2.5', 'unitPrice': '2.5', 'startTime': '12:00'},
- {'serviceFee': '2.5', 'parkingFee': '2.5', 'unitPrice': '2.5', 'startTime': '15:00'},
- {'serviceFee': '2.5', 'parkingFee': '2.5', 'unitPrice': '2.5', 'startTime': '18:00'},
- {'serviceFee': '2.5', 'parkingFee': '2.5', 'unitPrice': '2.5', 'startTime': '21:00'},
- ]
- data = ''
- count = 0
- for item in packages:
- count += 1
- hour, min = item['startTime'].split(':')
- data += self.encode_str(hour)
- data += self.encode_str(min)
- if count % 2 == 0:
- data += self.encode_str(item['unitPrice'])
- data += self.encode_str(item['serviceFee'])
- data += self.encode_str(item['parkingFee'])
- return data
- def stop(self, port=None):
- data = {
- 'port': int(port),
- 'remote_type': 0,
- }
- result = MessageSender.send(self.device, DeviceCmdCode.OPERATE_DEV_SYNC,
- data)
|