123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996 |
- # -*- coding: utf-8 -*-
- # !/usr/bin/env python
- import datetime
- from decimal import Decimal
- from apilib.monetary import RMB
- from apilib.utils_AES import EncryptDate
- from apps.web.constant import DeviceCmdCode, Const, ErrorCode
- from apps.web.core.adapter.policy_common import PolicyPackageInit
- from apps.web.core.adapter.weifuleCommon import PolicyBase
- from apps.web.core.exceptions import ServiceException
- from apps.web.core.networking import MessageSender
- from apps.web.device.models import Device, DeviceType
- from apps.web.user.models import Card, ServiceProgress, ConsumeRecord, UserVirtualCard
- cardKey = 'FR4e1OFCnDdrYA7u'
- class MyPackageInit(PolicyPackageInit):
- def get_reg_model(self, dealer, devTypeId, isTemp=False, **kw):
- policyTemp = self.INIT_POLICY
- displaySwitchs = self._get_displaySwitch(isTemp)
- ruleList = [
- {
- 'autoRefund': False,
- 'autoStop': True,
- 'billingMethod': 'prepaid',
- 'coins': 0.0,
- "name": "60分钟",
- 'price': 1.0,
- 'sn': 2,
- 'switch': True,
- 'time': 60.0,
- "unit": "分钟",
- },
- ]
- if devTypeId in dealer.defaultWashConfig:
- payload = dealer.defaultWashConfig[devTypeId]
- if not payload.get('policyTemp'):
- payload['policyTemp'] = policyTemp
- if not payload.get('displaySwitchs'):
- payload['displaySwitchs'] = displaySwitchs
- if not payload.get('ruleList'):
- payload['ruleList'] = ruleList
- else:
- payload = {'ruleList': ruleList, 'displaySwitchs': displaySwitchs, 'policyTemp': policyTemp}
- return payload
- def _formart_ruleList(self, isTemp=False):
- if not isTemp and not filter(lambda _: _.get('switch') == True, self.ruleList):
- raise ServiceException(
- {'result': 0, 'description': '没有可供用户选择的套餐, 请新增或启用 至少一个用户套餐',
- 'payload': {}})
- ids = [str(rule['id']) for rule in self.ruleList if 'id' in rule]
- for i, rule in enumerate(self.ruleList):
- ruleId = str(rule.get('id', ''))
- if not ruleId:
- ruleId = self._generate_id(ids)
- ids.append(ruleId)
- # 充满自停套餐
- if ruleId == 'autoPackage':
- rule['time'] = float(rule.get('time') or 0)
- # 自定义输入套餐
- if ruleId == 'customPackage':
- rule['time'] = float(rule.get('time') or 0)
- self.washConfig[ruleId] = {
- 'price': round(RMB(rule.get('price') or 0), 2),
- 'coins': round(RMB(rule.get('price') or 0), 2)
- }
- if 'switch' in rule:
- self.washConfig[ruleId].update({'switch': rule.get('switch', True)})
- if 'time' in rule:
- self.washConfig[ruleId].update({'time': round(float(rule.get('time') or 0), 2)})
- if 'name' in rule:
- self.washConfig[ruleId].update({'name': rule.get('name') or '套餐{}'.format(i + 1)})
- if 'unit' in rule:
- self.washConfig[ruleId].update({'unit': rule.get('unit')})
- if 'sn' in rule:
- self.washConfig[ruleId].update({'sn': rule['sn']})
- if 'autoStop' in rule:
- self.washConfig[ruleId]['autoStop'] = rule['autoStop']
- if 'autoRefund' in rule:
- self.washConfig[ruleId]['autoRefund'] = rule.get('autoRefund', False)
- # 此处有可能传入空字符串 加一个or判断为0
- if 'minAfterStartCoins' in rule:
- self.washConfig[ruleId]['minAfterStartCoins'] = round(RMB(rule['minAfterStartCoins'] or 0), 2)
- # 此处有可能传入空字符串 加一个or判断为0
- self.washConfig[ruleId]['billingMethod'] = 'prepaid'
- # 检验部分
- if RMB(rule.get('price') or 0) > self.dealer.maxPackagePrice:
- raise ServiceException({'result': 0, 'description': '套餐( {} )金额超限'.format(rule['name']), 'payload': {}})
- def _get_displaySwitch(self, isTemp=False):
- displaySwitchs = {
- "displayCoinsSwitch": False,
- "displayPriceSwitch": True,
- "displayTimeSwitch": True,
- "setBasePriceAble": False,
- "setPulseAble": False
- }
- return displaySwitchs
- class POLICYBox(PolicyBase, MyPackageInit):
- def __init__(self, device):
- super(POLICYBox, self).__init__(device)
- def translate_funcode(self, fun_code):
- fun_codeDict = {
- '01': u'查询所有端口状态',
- '02': u'查询端口详细信息',
- '03': u'上报投币充电事件',
- '04': u'上报刷卡事件',
- '05': u'上报充电结束事件',
- '06': u'远程停止充电',
- '07': u'远程启动充电',
- '08': u'查询投币总额',
- '09': u'清除投币总数',
- '0A': u'查询订单信息',
- }
- return fun_codeDict.get(fun_code, '')
- def translate_event_cmdcode(self, cmdCode):
- cmdDict = {
- }
- return cmdDict.get(cmdCode, '')
- def check_feedback_result(self, result):
- if 'rst' not in result:
- raise ServiceException({'result': 2, 'description': u'报文异常'})
- if result['rst'] == -1:
- raise ServiceException({'result': 2, 'description': u'充电桩正在玩命找网络,请您稍候再试'})
- if result['rst'] == 1:
- raise ServiceException({'result': 2, 'description': u'串口通讯失败,您稍候再试,或者联系客服'})
- if result['rst'] == 2:
- raise ServiceException({'result': 2, 'description': u'订单已满'})
- if result['rst'] == 3:
- raise ServiceException({'result': 2, 'description': u'端口已被禁用'})
- if result['rst'] == 4:
- raise ServiceException({'result': 2, 'description': u'检测插头未连接,请先插上插头后再使用'})
- if result['rst'] == 5:
- raise ServiceException({'result': 2, 'description': u'计费类型无效'})
- if result['rst'] == 7:
- raise ServiceException({'result': 2, 'description': u'端口计量故障'})
- # def get_port_info(self, port):
- # data = {'fun_code': 2, 'port': int(port)}
- # devInfo = self.send_mqtt(data)
- # portInfo = devInfo.get('data', {})
- # result = {'status': portInfo['status']}
- #
- # exec_orders = portInfo.get('exec_orders', [])
- # _wait = []
- # for exec_order in exec_orders:
- # if exec_order['status'] == 'running':
- # policy = exec_order.get('policy', {})
- # result['openId'] = policy['open_id']
- # result['billingMethod'] = policy['billingMethod']
- # result['policyType'] = policy['type']
- # result['voltage'] = round(portInfo.get('volt', 0), 2)
- # result['power'] = round(portInfo.get('watt', 0), 2)
- # result['ampere'] = round((portInfo.get('ampr', 0) * 0.001), 2)
- # result['usedTime'] = round(exec_order.get('time', 0) / 60.0, 1)
- # result['usedElec'] = round(exec_order.get('elec', 0) * 0.000001, 4)
- # result['startTime'] = datetime.datetime.fromtimestamp(int(exec_order['exec_time'])).strftime('%m-%d %H:%M:%S')
- # if 'card_no' in result:
- # result['cardNo'] = result['card_no']
- #
- # if exec_order['status'] == 'waiting':
- # _one = {}
- #
- # _wait.append(_one)
- #
- # if _wait:
- # result['waittingOrder'] = _wait
- #
- # return result
- 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'{} 参数错误(值为空).'.format(desc)})
- 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超出可选范围(值为: %s),可选最大值为%g' % (desc, params, 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超出可选范围(值为: %s),可选最小值为%g' % (desc, params, 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参数超出可选范围(值为: %s),可取范围为%g-%g' % (desc, params, minData, maxData)})
- def test(self, coins):
- data = {'fun_code': 0x07, 'order_id': '1111', 'coins': coins, 'port': 1, 'time': 60}
- devInfo = self.send_mqtt(data)
- return devInfo
- def get_port_status_from_dev(self):
- data = {'fun_code': 0x01, 'all': True}
- devInfo = self.send_mqtt(data)
- portData = devInfo['data']['port_stat']
- result = {}
- for k, v in portData.items():
- if v == 'idle':
- result[k] = {'status': Const.DEV_WORK_STATUS_IDLE}
- elif v == 'link':
- result[k] = {'status': Const.DEV_WORK_STATUS_CONNECTED}
- elif v == 'busy':
- result[k] = {'status': Const.DEV_WORK_STATUS_WORKING}
- elif v == 'fault':
- result[k] = {'status': Const.DEV_WORK_STATUS_FAULT}
- elif v == 'forbid':
- result[k] = {'status': Const.DEV_WORK_STATUS_FORBIDDEN}
- else:
- result[k] = {'status': Const.DEV_WORK_STATUS_FAULT}
- allPorts, usedPorts, usePorts = self.get_port_static_info(result)
- Device.update_dev_control_cache(self._device['devNo'],
- {'allPorts': allPorts, 'usedPorts': usedPorts, 'usePorts': usePorts})
- # 这里存在多线程更新缓存的场景,可能性比较低,但是必须先取出来,然后逐个更新状态,然后再记录缓存
- ctrInfo = Device.get_dev_control_cache(self._device['devNo'])
- for strPort, info in result.items():
- if strPort in ctrInfo:
- ctrInfo[strPort].update({'status': info['status']})
- else:
- ctrInfo[strPort] = info
- Device.update_dev_control_cache(self._device['devNo'], ctrInfo)
- return result
- def get_port_status(self, force=False):
- if force:
- return self.get_port_status_from_dev()
- ctrInfo = Device.get_dev_control_cache(self._device['devNo'])
- if 'allPorts' not in ctrInfo:
- self.get_port_status_from_dev()
- ctrInfo = Device.get_dev_control_cache(self._device['devNo'])
- allPorts = ctrInfo.get('allPorts', 2)
- statusDict = {}
- for ii in range(allPorts):
- tempDict = ctrInfo.get(str(ii + 1), {})
- if 'status' in tempDict:
- statusDict[str(ii + 1)] = {'status': tempDict.get('status')}
- elif 'isStart' in tempDict:
- if tempDict['isStart']:
- statusDict[str(ii + 1)] = {'status': Const.DEV_WORK_STATUS_WORKING}
- else:
- statusDict[str(ii + 1)] = {'status': Const.DEV_WORK_STATUS_IDLE}
- else:
- statusDict[str(ii + 1)] = {'status': Const.DEV_WORK_STATUS_IDLE}
- allPorts, usedPorts, usePorts = self.get_port_static_info(statusDict)
- Device.update_dev_control_cache(self._device['devNo'],
- {'allPorts': allPorts, 'usedPorts': usedPorts, 'usePorts': usePorts})
- return statusDict
- def active_deactive_port(self, port, active):
- if active:
- raise ServiceException({'result': 2, 'description': u'该设备不支持直接打开端口'})
- return self.stop_charging_port(port)
- # 停止该端口下的所有任务
- def stop_charging_port(self, port):
- data = {'fun_code': 0x06, 'port': port}
- devInfo = self.send_mqtt(data)
- if devInfo['rst'] == 0:
- Device.update_dev_control_cache(self._device['devNo'], {str(port): {'status': Const.DEV_WORK_STATUS_IDLE}})
- return True if devInfo['rst'] == 0 else False
- def analyze_event_data(self, data):
- if data['fun_code'] == '32': # 成功启动设备需要回复该事件
- return data['order']
- if data['fun_code'] == '34': # 如果是结束事件,需要把reason翻译出来
- descDict = {
- 'outofmoney': u'购买的充电时间或电量用完了',
- 'userstop': u'用户远程结束充电',
- 'adminstop': u'管理员远程结束充电',
- 'dealerstop': u'经销商远程结束充电',
- 'unplug': u'未检测到充电器, 结束充电',
- 'wattoverload': u'功率过载, 结束充电',
- 'voltoverload': u'电压过载, 结束充电',
- 'amproverload': u'电流过载, 结束充电',
- 'machoverload': u'整机功率过载, 结束充电',
- 'tempexcursion': u'温度过载, 结束充电',
- 'stopforfull': u'充满自停, 结束充电'
- }
- order = data['order']
- order['reasonDesc'] = descDict.get(str(order['cause_desc']), u'')
- data['order'] = order
- return data
- def ack_event(self, order_id, fun_code):
- data = {'order_id': order_id, 'fun_code': fun_code}
- self.send_mqtt(data)
- def get_card_pwd(self):
- devInfo = self.send_mqtt({'fun_code': 17})
- data = devInfo.get('data', {})
- card_cur_key = data.get('card_cur_key')
- enObj = EncryptDate(cardKey)
- card_cur_key = enObj.decrypt(card_cur_key)
- return {'card_pwd': card_cur_key}
- def set_device_function(self, request, lastSetConf):
- if 'clearSum' in request.POST:
- self.clear_dev_feecount()
- elif 'reboot' in request.POST:
- self.reboot_device()
- def set_device_function_param(self, request, lastSetConf):
- """
- 设置参数 对于计费模式做一下转换 顺便服务器保留一份
- :param request:
- :param lastSetConf:
- :return:
- """
- # 服务器侧的参数 先处理掉
- if request.POST.get('id_card_oncefee') is not None:
- id_card_oncefee = request.POST['id_card_oncefee']
- if not id_card_oncefee:
- raise ServiceException({'result': 2, 'description': u'在线卡单次刷卡金额不能为0'})
- Device.get_collection().update_one(filter={'devNo': self.device.devNo},
- update={'$set': {
- 'otherConf.id_card_oncefee': round(float(id_card_oncefee), 2),
- }})
- Device.invalid_device_cache(self.device.devNo)
- if request.POST.get('refundProtection') is not None:
- refundProtection = request.POST['refundProtection']
- Device.get_collection().update_one(filter={'devNo': self.device.devNo},
- update={'$set': {
- 'otherConf.refundProtection': round(float(refundProtection), 2),
- }})
- Device.invalid_device_cache(self.device.devNo)
- if request.POST.get('minAfterStartCoins') is not None:
- minAfterStartCoins = request.POST['minAfterStartCoins']
- Device.get_collection().update_one(filter={'devNo': self.device.devNo},
- update={'$set': {
- 'otherConf.minAfterStartCoins': round(float(minAfterStartCoins), 2),
- }})
- Device.invalid_device_cache(self.device.devNo)
- # 参数发向设备 11, 16指令
- setconfig1 = {'fun_code': 11}
- setconfig2 = {'fun_code': 16}
- # 音量适配
- if request.POST.get('volume_list'):
- volume_list = request.POST.get('volume_list')
- volumes = {}
- self.check_params_range(params=request.POST.get('volume'), minData=0.0, maxData=7.0, desc='语音音量参数')
- volumes.update({'default': int(request.POST.get('volume'))})
- for obj in volume_list:
- self.check_params_range(params=obj['volume'], minData=0.0, maxData=7.0, desc='音量参数')
- volumes.update({'{}-{}'.format(obj['start'], obj['end']): int(obj['volume'])})
- setconfig1.update({'volumes': volumes})
- if request.POST.get('float_time') or request.POST.get('float_watt') or request.POST.get('check_time'):
- float_charge = {}
- if request.POST.get('float_time'):
- float_charge['float_time'] = int(request.POST.get('float_time'))
- if request.POST.get('float_watt'):
- float_charge['float_watt'] = int(request.POST.get('float_watt'))
- if request.POST.get('check_time'):
- float_charge['check_time'] = int(request.POST.get('check_time'))
- setconfig1.update({'float_charge': float_charge})
- if request.POST.get('port_max_watt'):
- setconfig1.update({'port_max_watt': int(request.POST.get('port_max_watt'))})
- if request.POST.get('port_max_ampr'):
- setconfig1.update({'port_max_ampr': int(request.POST.get('port_max_ampr'))})
- if request.POST.get('mach_max_watt'):
- setconfig1.update({'mach_max_watt': int(request.POST.get('mach_max_watt'))})
- if request.POST.get('mach_max_temp'):
- setconfig1.update({'mach_max_temp': int(request.POST.get('mach_max_temp'))})
- if request.POST.get('mach_max_volt'):
- setconfig1.update({'mach_max_volt': int(request.POST.get('mach_max_volt'))})
- if request.POST.get('noload_check_watt') or request.POST.get('noload_check_time'):
- noload_check = {}
- if request.POST.get('noload_check_watt'):
- noload_check['watt'] = int(request.POST.get('noload_check_watt'))
- if request.POST.get('noload_check_time'):
- noload_check['time'] = int(request.POST.get('noload_check_time'))
- setconfig1.update({'noload_check': noload_check})
- # 离线卡配置
- if request.POST.get('policy'):
- policy = request.POST['policy']
- _type = policy['type']
- money = int(float(policy['money']) * 100) # 离线卡刷一次金额 单位: 分
- auto_stop = policy['auto_stop']
- rule = policy['rule']
- # 时间套餐格式化
- prices = rule.get('prices', [])
- # 单位准换
- for item in prices:
- item['price'] = int(float(item['price']) * 100)
- item['power'] = int(item['power'])
- # 排序
- prices = sorted(prices, key=lambda _: _['power'])
- # 电量部分格式化(电量的价格)
- price = int(float(policy.get('price', 1) * 100.0))
- setconfig1['policy'] = {
- 'type': _type,
- 'auto_stop': True if _type == 'elec' else auto_stop,
- 'over_money_stop': True,
- 'money': money,
- 'rule': {
- 'time': 'full_stop',
- 'prices': prices,
- 'elec': 'full_stop',
- 'price': price
- }
- }
- # 先不放出来: 按次的配置
- # if _type == 'count':
- # elec = rule.get('elec', 1) * 1000000 # 单位 3.6j
- # time = rule.get('time', 240) * 60 # 单位: 秒
- #
- # setconfig1['policy'] = {
- # 'type': 'elec',
- # 'auto_stop': auto_stop,
- # 'money': 100,
- # 'over_money_stop': False,
- # 'rule': {
- # 'elec': elec,
- # 'time': time,
- # 'price': 100
- # }
- # }
- self.send_mqtt(setconfig1)
- if request.POST.get('card_pwd'):
- card_pwd = request.POST.get('card_pwd')
- card_pwd2 = request.POST.get('card_pwd2')
- if card_pwd != card_pwd2:
- raise ServiceException({'result': 2, 'description': u'两次密码输入不一致'})
- self.check_pwd(card_pwd)
- enObj = EncryptDate(cardKey)
- setconfig2.update({'card_cur_key': enObj.encrypt(card_pwd)})
- if request.POST.get('card_refund', None) is not None:
- setconfig2.update({'card_refund': request.POST.get('card_refund')})
- if request.POST.get('card_disable', None) is not None:
- setconfig2.update({'card_disable': request.POST.get('card_disable')})
- if request.POST.get('card_timeout'):
- setconfig2.update({'card_timeout': int(request.POST.get('card_timeout'))})
- if request.POST.get('card_oncefee'):
- setconfig2.update({'card_oncefee': int(float(request.POST.get('card_oncefee')) * 100)})
- self.send_mqtt(setconfig2)
- def get_dev_setting(self):
- """
- 获取参数显示在前台
- :return:
- """
- # 获取主板侧的参数
- devInfo = self.send_mqtt({'fun_code': 12})
- # 参数整合
- data = dict()
- configs = devInfo['data']
- data['mach_max_watt'] = configs.get('mach_max_watt', 0)
- data['port_max_ampr'] = configs.get('port_max_ampr', 0)
- data['port_max_watt'] = configs.get('port_max_watt', 0)
- data['mach_max_volt'] = configs.get('mach_max_volt', 0)
- data['mach_max_temp'] = configs.get('mach_max_temp', 0)
- # 浮充参数的添加
- float_charge = configs.get('float_charge', {})
- data.update(float_charge)
- # 空载适配
- data.update({
- 'noload_check_watt': int(configs['noload_check'].get('watt', 0)),
- 'noload_check_time': int(configs['noload_check'].get('time', 0)),
- })
- # 音量适配
- volume_list = []
- for k, v in configs['volumes'].items():
- item = {}
- if k == 'default':
- continue
- if '-' in k:
- item['start'], item['end'] = k.split('-')
- item['volume'] = v
- volume_list.append(item)
- data.update({
- 'volume': configs['volumes']['default'],
- 'volume_list': volume_list
- })
- # 价格适配
- policy = configs['policy']
- policy['money'] = round(float(policy.get('money', 100)) * 0.01, 2)
- rule = policy.get('rule', {})
- # 功率计费部分
- prices = rule.get('prices', [])
- for item in prices:
- item['price'] = round(float(item['price']) * 0.01, 2)
- item['power'] = int(item['power'])
- prices = sorted(prices, key=lambda _: _['power'])
- # 电量计费部分
- price = round(float(rule.get('price', 100)) * 0.01, 2)
- rule.update({
- # 时间部分
- 'prices': prices,
- # 电量部分
- 'price': price
- })
- policy['rule'] = rule
- data.update({'policy': policy})
- # 17 指令
- devInfo = self.send_mqtt({'fun_code': 17})
- configs2 = devInfo.get('data')
- data['card_curmode'] = configs2['card_curmode']
- data['card_refund'] = configs2['card_refund']
- data['card_disable'] = configs2['card_disable']
- # data['card_token'] = configs2['card_token']
- data['card_timeout'] = configs2['card_timeout']
- state = self.get_dev_consume_count()
- data.update(state)
- return data
- def get_dev_consume_count(self):
- data = {'fun_code': 8}
- devInfo = self.send_mqtt(data)
- total_card = round(devInfo.get('data', {}).get('total_card', 0) * 0.01, 2)
- return {'total_card': total_card}
- def reset_total_card(self):
- data = {
- 'fun_code': 9
- }
- self.send_mqtt(data)
- def set_max_watt(self, max_watt):
- self.send_mqtt({'fun_code': 11, 'max_watt': int(max_watt)})
- def lock_unlock_port(self, port, lock=True):
- portInfo = self.get_port_info(port)
- if portInfo and portInfo['status'] == Const.DEV_WORK_STATUS_WORKING and lock:
- raise ServiceException({'result': 2, 'description': u'端口正忙,请先关闭端口后,再禁止端口'})
- typeStr = not lock
- self.send_mqtt({'port': int(port), 'enable': typeStr, 'fun_code': 13})
- @staticmethod
- def check_pwd(pwd):
- if len(pwd) != 6:
- raise ServiceException({'result': 2, 'description': u'密码必须是6位纯数字密码'})
- for char in pwd:
- if not (char >= '0' and char <= '9'):
- raise ServiceException({'result': 2, 'description': u'密码必须是6位纯数字密码'})
- return
- def get_card_mode(self):
- devInfo = self.send_mqtt({'fun_code': 17})
- MAP_MODE = {
- 'NORMAL': 0,
- 'ISSUE': 1,
- 'MODKEY': 2,
- }
- result = {}
- result['card_mode'] = MAP_MODE.get(devInfo['data']['card_curmode'])
- return result
- def set_card_mode(self, setConf):
- cardMode = int(setConf.get('card_mode'))
- data = {'fun_code': 16}
- if cardMode == 0:
- data.update({'card_curmode': {'mod': 'NORMAL'}})
- elif cardMode == 1: # 格式化为离线卡
- self.check_pwd(setConf['new_pwd'])
- newPwd = setConf['new_pwd']
- if not str(setConf['balance']).isdigit():
- raise ServiceException({'result': 2, 'description': u'余额必须是数字'})
- balance = int(setConf['balance'])
- if not (balance >= 0 and balance <= 5000):
- raise ServiceException({'result': 2, 'description': u'余额必须在0和5000元之间'})
- card_dft_val = balance * 100 # 硬件模块记录的单位是角
- enObj = EncryptDate(cardKey)
- data.update({'card_curmode': {'mod': 'ISSUE', 'cfg': {'card_new_key': enObj.encrypt(str(newPwd)),
- 'card_dft_val': card_dft_val}}})
- elif cardMode == 2:
- self.check_pwd(setConf['new_pwd'])
- oldPwd = setConf.get('old_pwd', '')
- newPwd = setConf.get('new_pwd', '')
- enObj = EncryptDate(cardKey)
- data.update({'card_curmode': {'mod': 'MODKEY', 'cfg': {'card_old_key': enObj.encrypt(str(oldPwd)),
- 'card_new_key': enObj.encrypt(str(newPwd))}}})
- self.send_mqtt(data)
- def response_card_charge_result(self, cardNo, result):
- self.send_mqtt({'fun_code': 36, 'card_no': cardNo, 'result': result})
- def recharge_card(self, cardNo, money, orderNo=None):
- self.send_mqtt(
- {'fun_code': 36, 'result': 1, 'card_no': cardNo, 'charge': int(money * 100), 'order_id': orderNo})
- card = Card.objects.filter(cardNo=cardNo, dealerId=self.device.ownerId).first()
- balance = card.balance + money
- return {
- 'result': ErrorCode.SUCCESS,
- 'description': ''
- }, balance
- def get_current_use(self, **kw):
- base_data = kw.get('base_data')
- spDict = kw.get('spDict')
- sp = ServiceProgress.objects.filter(device_imei=self.device.devNo, port=spDict['port']).first()
- data = {'fun_code': 2, 'port': spDict.get('port')}
- devInfo = self.send_mqtt(data)
- portInfo = devInfo.get('data', {})
- exec_orders = portInfo.get('exec_orders', [])
- running_order = None
- waiting_order = []
- for exec_order in exec_orders: # 第一层筛选
- if exec_order['id'] not in sp.consumes:
- if exec_order['id'] in sp.consumes:
- sp.consumes.remove(exec_order['id'])
- continue
- if exec_order['status'] == 'running':
- running_order = exec_order
- elif exec_order['status'] == 'waiting':
- waiting_order.append(exec_order)
- if len(sp.consumes) == 0: # 上一单没有正常结束 刷新此单的状态
- if running_order:
- sp.consumes.append(running_order['id'])
- sp.start_time = running_order['exec_time']
- sp.isFinished = False
- sp.finished_time = sp.start_time + 12 * 60 * 60
- if waiting_order:
- for wait_one in waiting_order:
- sp.consumes.append(wait_one['id'])
- sp.finished_time = sp.start_time + 12 * 60 * 60
- sp.save()
- pay_unit = self.show_pay_unit
- result_list = [] # 数据整理返回
- for exec_order in exec_orders:
- item = {}
- item.update(base_data)
- item['orderNo'] = exec_order['id']
- item['port'] = exec_order['port']
- order = ConsumeRecord.objects.filter(orderNo=exec_order['id']).first()
- if exec_order['status'] == 'running':
- item['voltage'] = round(portInfo.get('volt', 0), 2)
- item['power'] = round(portInfo.get('watt', 0), 2)
- item['ampere'] = round((portInfo.get('ampr', 0) * 0.001), 2)
- item['usedTime'] = round(exec_order.get('time', 0) / 60.0, 1)
- # item['elec'] = round(exec_order.get('elec', 0) * 0.000001, 4)
- if exec_order['order_type'] == 'apps_start':
- try:
- item['consumeMoney'] = '{}{}'.format(round(exec_order.get('money', 0) * 0.01, 2), pay_unit)
- item['leftMoney'] = '{}{}'.format(round(exec_order.get('left_money', 0) * 0.01, 2), pay_unit)
- item['order'] = {
- 'orderNo': exec_order['id'], # 停止按钮传订单停单用
- 'coin': '{}{}'.format(round(order.coin, 2), pay_unit),
- 'port': exec_order['port'],
- 'consumeType': 'mobile',
- }
- except:
- pass
- elif exec_order['order_type'] == 'card_start':
- try:
- item['cardNo'] = exec_order['card_no']
- item['cardConsumeMoney'] = '{}{}'.format(round(exec_order.get('money', 0) * 0.01, 2), pay_unit)
- item['cardLeftMoney'] = '{}{}'.format(round(exec_order.get('left_money', 0) * 0.01, 2),
- pay_unit)
- item['order'] = {
- 'orderNo': exec_order['id'], # 停止按钮传订单停单用
- 'coin': '{}{}'.format(round(exec_order.get('amount', 0) * 0.01, 2), pay_unit),
- 'port': exec_order['port'],
- 'consumeType': 'card',
- }
- except:
- pass
- else:
- pass
- elif exec_order['status'] == 'waiting':
- if exec_order['chrmt'] == 'TIME':
- item['needTime'] = '{}分钟'.format(round(exec_order.get('amount_time', 0) / 60.0, 1))
- item['leftTime'] = round(exec_order.get('left_time', 0) / 60.0, 1)
- elif exec_order['chrmt'] == 'ELEC':
- item['needElec'] = round(exec_order.get('amount_elec', 0) * 0.000001, 2)
- item['leftElec'] = round(exec_order.get('left_elec', 0) * 0.000001, 2)
- item['desc'] = '此订单已经下发到设备上,上一单运行完毕就会自动运行此订单'
- item['order'] = {
- 'orderNo': exec_order['id'], # 停止按钮传订单停单用
- 'coin': '{}币'.format(round(exec_order.get('amount', 0) * 0.01, 2)),
- 'port': exec_order['port'],
- 'consumeType': 'card' if 'cardNo' in exec_order else 'mobile',
- }
- if order.monthlyPackageId: # 包月卡抵扣
- item.pop('cardConsumeMoney', None)
- item.pop('cardLeftMoney', None)
- item.pop('needTime', None)
- # item.pop('usedTime', None)
- item.pop('leftTime', None)
- if 'cardNo' in exec_order:
- item['cardNo'] = exec_order['card_no']
- item.update(DeviceType.get_services_button(self.device['devType']['id']))
- result_list.append(item)
- return result_list
- def isHaveStopEvent(self):
- return True
- def stop_by_order(self, port, orderNo):
- data = {'fun_code': 4, 'order_id': orderNo, 'operator': 'user'}
- self.send_mqtt(data)
- def clear_dev_feecount(self):
- data = {'fun_code': 0x09, 'total_coin': True, 'total_card': True}
- self.send_mqtt(data)
- def reboot_device(self):
- # 重启单片机
- MessageSender.send(self.device, DeviceCmdCode.SET_DEVINFO, {'reset_mcu': True})
- # 重启模块
- MessageSender.send(self.device, DeviceCmdCode.SET_DEVINFO, {'restart': True})
- @property
- def show_pay_unit(self):
- """
- 前台显示付费的时候,目前有不同的客户希望 显示不同的单位 有的显示金币 有的显示元, 这个地方处理下
- :return:
- """
- return u'元'
- def get_port_using_detail(self, port, ctrInfo, isLazy=False):
- return self.get_port_info(port)
- def stop(self, port=None):
- return self.stop_charging_port(int(port))
- def __translate_status_from_str(self, status):
- dictConf = {
- 'idle': Const.DEV_WORK_STATUS_IDLE,
- 'busy': Const.DEV_WORK_STATUS_WORKING,
- 'forbid': Const.DEV_WORK_STATUS_FORBIDDEN,
- 'fault': Const.DEV_WORK_STATUS_FAULT,
- 'running': Const.DEV_WORK_STATUS_WORKING
- }
- return dictConf.get(status, Const.DEV_WORK_STATUS_IDLE)
- def update_show_pg(self, data):
- for k, v in data.items():
- v['showPG'] = True
- # @SmartBox.life_cycle(after=update_show_pg)
- def get_many_port_info(self, portList):
- data = {'fun_code': 1, 'all': True}
- devInfo = self.send_mqtt(data)
- portInfo = devInfo['data']
- portParam = portInfo.get('port_param', {})
- exec_queue = portInfo.get('exec_queue', {})
- pay_unit = self.show_pay_unit
- resultDict = {}
- for port, exec_orders in exec_queue.items():
- if port not in portList:
- continue
- result = {'index': port}
- onePortParam = portParam.get(port, {})
- _wait = []
- for exec_order in exec_orders:
- order = ConsumeRecord.objects.filter(orderNo=exec_order['id']).first() # type: ConsumeRecord
- if exec_order['status'] == 'running':
- result['voltage'] = round(onePortParam.get('volt', 0), 2)
- result['power'] = round(onePortParam.get('watt', 0), 2)
- result['ampere'] = round((onePortParam.get('ampr', 0) * 0.001), 2)
- result['devTemp'] = round((portInfo.get('mach_temp', 0)), 2)
- result['status'] = self.__translate_status_from_str(exec_order['status'])
- result['usedTime'] = round(exec_order.get('time', 0) / 60.0, 2)
- result['usedElec'] = round(exec_order.get('elec', 0) * 0.000001, 4)
- result['coins'] = order.coin if order else RMB(
- (exec_order.get('policy', {}).get('money', 0)) * 0.01)
- result['startTime'] = order.dateTimeAdded.strftime(
- '%m-%d %H:%M:%S') if order else datetime.datetime.fromtimestamp(
- exec_order['create_time']).strftime('%m-%d %H:%M:%S')
- if exec_order['order_type'] == 'apps_start':
- if not order:
- result['nickName'] = '经销商上分'
- else:
- result['nickName'] = order.user.nickname
- result['openId'] = order.openId
- result['consumeType'] = 'mobile'
- result['consumeMoney'] = '{}{}'.format(RMB.fen_to_yuan(exec_order['money']), pay_unit)
- policy = exec_order.get('policy', {})
- rule = exec_order.get('policy', {}).get('rule', {})
- if rule:
- if 'time' in rule:
- if order:
- result['needTime'] = order.servicedInfo['needTime']
- else:
- result['needTime'] = format(rule['time'] / 60.0, '.1f') + '分钟'
- else:
- if order:
- result['needElec'] = order.servicedInfo['needElec']
- else:
- result['needElec'] = format(rule['elec'] / 1000000.0, '.1f')
- if policy.get('billingMethod') == 'postpaid':
- result['consumeType'] = 'postpaid'
- if exec_order['order_type'] == 'card_start':
- result['consumeType'] = 'card'
- if order:
- result['nickName'] = order.user.nickname
- result['openId'] = order.openId
- result['cardNo'] = exec_order['card_no']
- result['cardConsumeMoney'] = '{}{}'.format(round(exec_order.get('money', 0) * 0.01, 2),
- pay_unit)
- result['cardBalance'] = '{}{}'.format(round(exec_order['balance'] * 0.01, 2), pay_unit)
- elif exec_order['status'] == 'waiting':
- _one = {}
- if 'amount_time' in exec_order:
- _one['needTime'] = '{}分钟'.format(round(exec_order['amount_time'] / 60.0, 1))
- if 'amount_elec' in exec_order:
- _one['needElec'] = '{}'.format(round(exec_order['amount_elec'] / 1000000.0, 2))
- if 'amount' in exec_order:
- _one['coins'] = '{}{}'.format(round(exec_order['amount'] / 100.0, 2), pay_unit)
- if 'create_time' in exec_order:
- _one['createTime'] = datetime.datetime.fromtimestamp(
- int(exec_order['create_time'])).strftime('%m-%d %H:%M:%S')
- if exec_order['order_type'] == 'apps_start':
- _one['consumeType'] = 'mobile'
- if not order:
- _one['nickName'] = '经销商上分'
- else:
- _one['nickName'] = order.user.nickname
- elif exec_order['order_type'] == 'card_start':
- _one['consumeType'] = 'card'
- _one['cardNo'] = exec_order['card_no']
- _one['cardBalance'] = '{}{}'.format(round(exec_order['balance'] * 0.01, 2), pay_unit)
- if order:
- _one['nickName'] = order.nickname
- _wait.append(_one)
- if _wait:
- result['waittingOrder'] = _wait
- resultDict[port] = result
- return resultDict
- @property
- def support_device_package(self):
- return True
|