123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304 |
- # -*- coding: utf-8 -*-
- # !/usr/bin/env python
- import datetime
- import json
- import logging
- import time
- from copy import deepcopy
- from typing import TYPE_CHECKING
- from apilib.monetary import RMB
- from apilib.utils_sys import memcache_lock
- from apps.web.constant import FAULT_LEVEL
- from apps.web.device.models import DeviceUploadInfo, Group
- from apps.web.eventer import EventBuilder
- from apps.web.eventer.base import WorkEvent, FaultEvent
- from apps.web.eventer.weifuleCommon import WeiFuLeStatusEvent, WeiFuLeCarProcess
- from apps.web.user.models import ConsumeRecord, CardConsumeRecord, Card
- from apps.web.user.models import CardRechargeOrder
- from apps.web.utils import concat_user_login_entry_url
- if TYPE_CHECKING:
- pass
- logger = logging.getLogger(__name__)
- def log_obj(obj):
- obj = deepcopy(obj)
- if isinstance(obj, dict):
- for k, v in obj.items():
- if isinstance(v, object):
- obj[k] = str(v)
- if isinstance(obj, list) or isinstance(obj, tuple) or isinstance(obj, set):
- obj = map(lambda x: str(x) if isinstance(x, object) else x, obj)
- if isinstance(obj, unicode):
- obj = str(obj)
- # print('\33[33m' + json.dumps(obj,ensure_ascii=True,encoding='utf-8') + '\33[0m')
- return '\33[33m' + json.dumps(obj, ensure_ascii=False, encoding='utf-8') + '\33[0m'
- card_is_normal = 1
- card_not_in_db = 2
- card_is_forzen = 3
- card_has_not_order = 4 # IC卡适用
- class builder(EventBuilder):
- def __getEvent__(self, device_event):
- logger.info('reve event, event_data:{}'.format(log_obj(device_event)))
- event_data = device_event.get('data')
- fun_code = event_data.get('fun_code')
- if not event_data:
- return
- if event_data['fun_code'] in [44]:
- return WeiFuLeStatusEvent(self.deviceAdapter, device_event)
- if fun_code in [40, 41, 42, 43]: # 40温度告警/41电流超限/42电压超限/43功率过载
- return ChargingWeiFuLeCarFaultEvent(self.deviceAdapter, event_data)
- else:
- return ChargingWeiFuLeCarWorkEvent(self.deviceAdapter, event_data)
- class ChargingWeiFuLeCarWorkEvent(WorkEvent):
- def do(self, **args):
- fun_code = self.event_data.get('fun_code')
- order_id = self.event_data.get('order', {}).get('id')
- key = '{}.{}.event'.format(self.device.devNo, order_id)
- if fun_code == 37: # 处理卡充值
- self.deal_with_ic_charge_event()
- elif fun_code == 44: # 上报结束后的状态
- pass
- elif fun_code == 45: # 上传要链接
- self.response_the_link()
- else:
- with memcache_lock(key=key, value='1', expire=15) as acquired:
- if acquired:
- if fun_code == 32 or fun_code == 34 or fun_code == 33:
- self._do_order_change_event_32_33_34()
- self._do_ack_order_32_or_remove_order_from_device_34()
- else:
- logger.debug('fun_code<{}> is doing. cache_key:{}'.format(repr(fun_code), key))
- return
- def deal_with_ic_charge_event(self):
- cardNo = self.event_data.get('card_no')
- card = Card.objects.filter(cardNo=cardNo, cardType='IC', dealerId=self.device.ownerId).first()
- logger.info(log_obj('Start card recharge operation'))
- if not card:
- logger.info(log_obj('Start card recharge operation --> no such card !!! '))
- return self.deviceAdapter.send_mqtt({
- 'fun_code': 37,
- 'card_no': cardNo,
- 'result': card_not_in_db,
- })
- elif card.frozen:
- logger.info(log_obj('Start card recharge operation --> card is frozen !!! '))
- return self.deviceAdapter.send_mqtt({
- 'fun_code': 37,
- 'card_no': cardNo,
- 'result': card_is_forzen,
- })
- rechargeOrder = CardRechargeOrder.get_last_to_do_one(str(card.id))
- if rechargeOrder:
- preBalance = RMB(self.event_data.get('balance', 0) / 100.0)
- logger.info(log_obj('Start card recharge operation --> to recharg rechargeAmount:{}'.format(preBalance)))
- self.recharge_ic_card(card=card,
- preBalance=preBalance,
- rechargeType='append',
- order=rechargeOrder,
- need_verify=False)
- else:
- logger.info(log_obj('Start card recharge operation --> no rechargeOrder !! '))
- self.deviceAdapter.send_mqtt({
- 'card_no': cardNo,
- 'fun_code': 37,
- 'result': card_has_not_order,
- })
- def _do_order_change_event_32_33_34(self):
- order_info = self.event_data.get('order')
- if not order_info:
- logger.info(log_obj('no order info,do over!!'))
- else:
- order_processing = WeiFuLeCarProcess(self)
- order_type = order_info.get('order_type')
- self.save_upload_log()
- if hasattr(order_processing, order_type):
- event = getattr(order_processing, order_type)
- try:
- event()
- except Exception:
- import traceback
- logger.info(traceback.format_exc())
- else:
- logger.info(log_obj('no this order_type'))
- def _do_ack_order_32_or_remove_order_from_device_34(self):
- order_info = self.event_data.get('order')
- order_id = order_info.get('id')
- fun_code = self.event_data.get('fun_code')
- if (time.time() - order_info.get('create_time', 0)) < 300 and order_info.get('order_type') == 'apps_start':
- return
- if fun_code == 32:
- self.deviceAdapter.do_ack_order_32(order_id)
- elif fun_code == 34:
- self.deviceAdapter.do_ack_remove_order_from_device_34(order_id)
- else:
- pass
- def save_upload_log(self):
- order_info = self.event_data.get('order')
- order_info = deepcopy(order_info)
- order_info['order_id'] = order_info.pop('id')
- DeviceUploadInfo(**order_info).save()
- def response_the_link(self):
- qr_code_url = concat_user_login_entry_url(l=self.device['logicalCode'])
- data = {
- 'fun_code': 45,
- 'qrcode': qr_code_url
- }
- self.deviceAdapter.send_mqtt(data)
- def record_consume_for_card(self, card, money, desc=u'', servicedInfo=None, sid=None, attachParas=None):
- servicedInfo = {} if servicedInfo is None else servicedInfo
- attachParas = {} if attachParas is None else attachParas
- group = Group.get_group(self.device['groupId'])
- address = group['address']
- group_number = self.device['groupNumber']
- now = datetime.datetime.now()
- orderNo = attachParas.get('orderNo')
- new_record = {
- 'orderNo': orderNo,
- 'time': now.strftime('%Y-%m-%d %H:%M:%S'),
- 'dateTimeAdded': now,
- 'openId': card.openId,
- 'ownerId': self.device['ownerId'],
- 'coin': money.mongo_amount,
- 'money': money.mongo_amount,
- 'devNo': self.device['devNo'],
- 'logicalCode': self.device['logicalCode'],
- 'groupId': self.device['groupId'],
- 'address': address,
- 'groupNumber': group_number,
- 'groupName': group['groupName'],
- 'devTypeCode': self.device.devTypeCode,
- 'devTypeName': self.device.devTypeName,
- 'isNormal': True,
- 'status': ConsumeRecord.Status.RUNNING,
- 'remarks': u'刷卡消费',
- 'errorDesc': '',
- 'sequanceNo': '',
- 'desc': desc,
- 'attachParas': attachParas,
- 'servicedInfo': servicedInfo
- }
- ConsumeRecord.get_collection().insert_one(new_record)
- # 刷卡消费也记录一条数据
- new_card_record = {
- 'orderNo': orderNo,
- 'openId': card.openId,
- 'cardId': str(card.id),
- 'money': money.mongo_amount,
- 'balance': card.balance.mongo_amount,
- 'devNo': self.device['devNo'],
- 'devType': self.device['devType']['name'],
- 'logicalCode': self.device['logicalCode'],
- 'groupId': self.device['groupId'],
- 'address': address,
- 'groupNumber': group_number,
- 'groupName': group['groupName'],
- 'result': 'success',
- 'remarks': u'刷卡消费',
- 'sequanceNo': '',
- 'dateTimeAdded': datetime.datetime.now(),
- 'desc': desc,
- 'servicedInfo': servicedInfo,
- 'linkedConsumeRcdOrderNo': str(new_record['orderNo'])
- }
- if sid is not None:
- new_card_record.update({'sid': sid})
- CardConsumeRecord.get_collection().insert(new_card_record)
- return new_record['orderNo'], new_card_record['orderNo']
- class ChargingWeiFuLeCarFaultEvent(FaultEvent):
- def do(self, **args):
- # 40温度告警/41电流超限/42电压超限/43功率过载
- group = Group.get_group(self.device['groupId'])
- fun_code = self.event_data.get('fun_code')
- if fun_code == 40:
- item = self.event_data.get('temp')
- faultName = r'设备火灾预警'
- desc = r'主板上报设备过热,设备温度超限(设备温度:{} 度)'.format(item)
- title = r'告警名称:\t\t{}\n\n地址名称:\t\t{}-{}\n'.format(faultName, group['address'], group['groupName'])
- elif fun_code == 41:
- item = self.event_data.get('ampr')
- faultName = r'设备电流超过最大限制'
- desc = r'主板上报电流超限,设备电流超限(设备电流:{} 安)'.format(item)
- title = r'告警名称:\t\t{}\n\n地址名称:\t\t{}-{}\n'.format(faultName, group['address'], group['groupName'])
- elif fun_code == 42:
- item = self.event_data.get('volt')
- faultName = r'设备电压超过最限制'
- desc = r'主板上报电压超限,设备电压超限(设备电压:{} 伏)'.format(item)
- title = r'告警名称:\t\t{}\n\n地址名称:\t\t{}-{}\n'.format(faultName, group['address'], group['groupName'])
- elif fun_code == 43:
- item = self.event_data.get('watt')
- faultName = r'设备功率超过最限制'
- desc = r'主板上报功率超限,设备功率超限(设备电压:{} 瓦)'.format(item)
- title = r'告警名称:\t\t{}\n\n地址名称:\t\t{}-{}\n'.format(faultName, group['address'], group['groupName'])
- else:
- return
- self.notify_dealer(
- templateName='device_fault',
- title=title,
- device=r'{}号设备({})\n'.format(self.device['groupNumber'], self.device['logicalCode']),
- location=r'设备告警\n',
- notifyTime=desc + r'\n',
- fault=r'%s\n' % datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
- )
- self.record(
- faultCode=self.event_data.get('FaultCode'),
- description=desc,
- title=faultName,
- level=self.event_data.get('level', FAULT_LEVEL.NORMAL),
- # detail=self.event_data.get('statusInfo'),
- )
|