123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343 |
- # -*- coding: utf-8 -*-
- # !/usr/bin/env python
- import datetime
- import logging
- from apilib.monetary import RMB
- from apilib.utils_sys import memcache_lock
- from apps.web.constant import FAULT_CODE, FAULT_LEVEL, ErrorCode
- from apps.web.device.models import Group
- from apps.web.eventer import EventBuilder
- from apps.web.eventer.base import WorkEvent, FaultEvent
- from apps.web.eventer.weifuleCommon import WeiFuLePolicyProcess
- from apps.web.user.models import WeifuleCardStamp, Card, CardRechargeOrder, CardRechargeRecord
- logger = logging.getLogger(__name__)
- created_order_32 = 32
- executing_order_33 = 33
- finished_order_34 = 34
- id_card_request_35 = 35
- card_recharge_order_37 = 37
- fault_event_overload_38 = 38 # 整机功率过载
- fault_event_relay_39 = 39 # 继电器故障
- fault_event_counter_40 = 40 # 计量芯片故障
- fault_event_mcu_36 = 36 # mcu重启
- power_event_41 = 999 # 待设备实现
- ic_consume_event_48 = 48 # ic卡花钱的时候,会上报此事件
- part_sn_event = 49 # 组件上报相关信息
- card_is_normal = 1
- card_not_in_db = 2
- card_is_forzen = 3
- card_has_not_order = 4 # IC卡适用
- card_less_balance = 5 # ID卡适用
- card_type_is_ic = 6 # IC卡不允许当做ID卡使用
- no_load_code = 7
- class builder(EventBuilder):
- def __getEvent__(self, device_event):
- event_data = self.deviceAdapter.analyze_event_data(device_event['data'])
- if event_data is None:
- return None
- if event_data['fun_code'] in [created_order_32, executing_order_33, finished_order_34, id_card_request_35,
- card_recharge_order_37]:
- return ChargingWEIFULEWorkEvent(self.deviceAdapter, event_data)
- if event_data['fun_code'] in [fault_event_mcu_36, fault_event_overload_38, fault_event_relay_39,
- fault_event_counter_40]:
- return WEIFULEFaultEvent(self.deviceAdapter, event_data)
- if event_data['fun_code'] in [ic_consume_event_48]:
- return WEIFULEICCardConsume(self.deviceAdapter, event_data)
- if event_data['fun_code'] in [power_event_41]:
- return WEIFULEPowerEvent(self.deviceAdapter, event_data)
- class WEIFULEPowerEvent(WorkEvent):
- def do(self, **args):
- power = int(self.event_data['power'])
- orderNo = str(self.event_data['orderNo'])
- # PowerInfoManager.instence().append_power(orderNo, power)
- class WEIFULEICCardConsume(FaultEvent):
- def do(self, **args):
- cardNo = str(int(self.event_data['card_no'], 16))
- stamp = self.event_data['stamp']
- isCopy = WeifuleCardStamp.is_copy_card(cardNo, self.device['ownerId'], stamp)
- if isCopy:
- self.event_data.update({
- 'faultName': u'复制卡告警',
- 'faultCode': FAULT_CODE.COPY_CARD,
- 'level': FAULT_LEVEL.CRITICAL,
- 'desc': u'卡号为:%s的卡,极可能是复制卡,建议冻结处理。' % cardNo
- })
- super(WEIFULEICCardConsume, self).do()
- newObj = WeifuleCardStamp(
- cardNo=cardNo,
- dealerId=self.device['ownerId'],
- stamp=str(stamp),
- dateTimeAdded=datetime.datetime.now()
- )
- newObj.save()
- class WEIFULEFaultEvent(FaultEvent):
- def do(self, **args):
- if self.event_data['fun_code'] == fault_event_mcu_36:
- self.event_data.update({
- 'faultName': u'单片机告警',
- 'faultCode': FAULT_CODE.MCU_REBOOT,
- 'level': FAULT_LEVEL.NORMAL,
- 'desc': u'充电主板上的单片机重启。'
- })
- elif self.event_data['fun_code'] == fault_event_relay_39:
- self.event_data.update({
- 'faultName': u'继电器告警',
- 'port': int(self.event_data['port']),
- 'faultCode': FAULT_CODE.RELAY_FAULT,
- 'level': FAULT_LEVEL.CRITICAL,
- 'desc': u'继电器发送粘连。'
- })
- elif self.event_data['fun_code'] == fault_event_counter_40:
- self.event_data.update({
- 'faultName': u'计量芯片告警',
- 'port': int(self.event_data['port']),
- 'faultCode': FAULT_CODE.COUNTER_FAULT,
- 'level': FAULT_LEVEL.CRITICAL,
- 'desc': u'计量芯片获取功率失败。'
- })
- elif self.event_data['fun_code'] == fault_event_overload_38:
- self.event_data.update({
- 'faultName': u'整机功率过载告警',
- 'faultCode': FAULT_CODE.DEV_OVERLOAD,
- 'level': FAULT_LEVEL.FATAL,
- 'desc': u'整机功率超过7500瓦。'
- })
- else:
- pass
- super(WEIFULEFaultEvent, self).do()
- class ChargingWEIFULEWorkEvent(WeiFuLePolicyProcess):
- # 微付乐的板子:根据设备上报上来的订单,创建正在服务的信息
- def translate_reason(self, order):
- cause = order.get('cause')
- if cause == 0:
- if self.duration < self.refundProtectionTime:
- return u'充电已结束,如有异常情况,请联系本台设备经销商。'
- else:
- return u'订购的套餐已用完。'
- elif cause == 1:
- return u'用户拔掉充电器,或者插座脱落。'
- elif cause == 2:
- return u'用户刷卡停止充电。'
- elif cause == 3:
- return u'远程停止。'
- elif cause == 4:
- return u'整机过载,系统为了安全,关闭掉所有充电端口。'
- elif cause == 5:
- return u'充电端口电流过载,系统为了安全,关闭此充电端口。'
- elif cause == 6:
- return u'端口功率过载,系统为了安全,关闭此充电端口。'
- elif cause == 7:
- return u'端口空载。可能是插座松动、充电端口故障、或者充电电池故障。'
- elif cause == 8:
- return u'恭喜您电池已经充满。'
- elif cause == 9:
- if self.duration < self.refundProtectionTime:
- return u'充电已结束,如有异常情况,请联系设备经销商。'
- else:
- return u'套餐金额已用完'
- elif cause == 12:
- if self.duration < self.refundProtectionTime:
- return u'充电已结束,如有异常情况,请联系本台设备经销商。'
- else:
- return u'订购的时间已用完'
- elif cause == 13:
- if self.duration < self.refundProtectionTime:
- return u'充电已结束,如有异常情况,请联系本台设备经销商。'
- else:
- return u'订购的电量已用完'
- return u'充电结束。'
- def deal_with_ic_charge_event(self, msgDict):
- cardNo = str(int(self.event_data['card_no'], 16))
- card = self.update_card_dealer_and_type(cardNo, 'IC')
- if not card:
- return self.deviceAdapter.response_card_charge_result(self.event_data['card_no'], card_not_in_db)
- elif card.frozen:
- return self.deviceAdapter.response_card_charge_result(self.event_data['card_no'], card_is_forzen)
- preBalance = RMB(self.event_data['balance'] / 100.0)
- self.update_balance_for_IC_card(card, preBalance)
- rechargeOrder = CardRechargeOrder.get_last_to_do_one(str(card.id))
- if rechargeOrder:
- self.recharge_ic_card(card=card,
- preBalance=preBalance,
- rechargeType='append',
- order=rechargeOrder,
- need_verify=False)
- else:
- return self.deviceAdapter.response_card_charge_result(self.event_data['card_no'], card_has_not_order)
- def analyse_need_from_package(self, order):
- needKind, needValue, unit = 'needElec', 0, u'度'
- if order['chrmt'] == 'TIME':
- needKind = 'needTime'
- needValue = order['amount_time'] / 60
- unit = u'分钟'
- else:
- needValue = order['amount_elec'] / 1000000.0
- return needKind, needValue, unit
- def do(self, **args):
- devNo = self.device['devNo']
- funCode = self.event_data['fun_code']
- if funCode == card_recharge_order_37: # 如果是卡充值,直接回复订单
- self.deal_with_ic_charge_event(self.event_data)
- elif funCode == id_card_request_35:
- self.response_id_card()
- else: # 处理任务事件
- order = self.event_data['order']
- logger.info('weifule charging event detected, devNo=%s' % (devNo,))
- with memcache_lock(key='%s-%s-%s-finished' % (devNo, order['id'], funCode), value='1',
- expire=120) as acquired:
- if acquired:
- self._do_ack_order(order)
- try:
- if funCode == created_order_32:
- self._do_created_order_32(order)
- elif funCode == executing_order_33:
- self._do_exec_order_33(order)
- elif funCode == finished_order_34 and order['order_type'] != 'card_charge':
- self._do_finished_order_34(order)
- elif funCode == finished_order_34 and order['order_type'] == 'card_charge':
- self.update_card_recharge_for_success_event(order['id'], RMB(order['balance'] / 100.0))
- except Exception:
- import traceback
- logger.warn(traceback.format_exc())
- logger.info('deal order is finished < funCode: {} order: {} >'.format(funCode, order.get('id')))
- else:
- logger.info('weifule charging event is doing !!!, devNo=%s' % (devNo,))
- def recharge_ic_card(self, card, preBalance, rechargeType, order, need_verify=True):
- # type:(Card, RMB, str, CardRechargeOrder, bool)->bool
- """
- # rechargeType有两种,一种是用直接覆写overwrite的方式,一种是append追加钱的方式。
- # 不同的的设备,充值的方式还不一样.注意:money是实际用户付的钱,coins是给用户充值的钱,比如付10块(money),充15(coins)。
- :param card:
- :param preBalance:
- :param rechargeType:
- :param order:
- :return:
- """
- if not order or order.coins == RMB(0):
- return False
- status = Card.get_card_status(str(card.id))
- if status == 'busy':
- return False
- Card.set_card_status(str(card.id), 'busy')
- try:
- # IC卡需要下发到设备,设备写卡,把余额打入卡中
- if rechargeType == 'overwrite':
- sendMoney = preBalance + order.coins
- else:
- sendMoney = order.coins
- # 先判断order最近一次充值是否OK. 满足三个条件在认为上次充值成功:
- # 1、操作时间已经超过三天
- # 2、操作结果是串口超时, 即result == 1
- # 3、当前余额大于最后一次充值操作的充值前余额
- if need_verify and len(order.operationLog) > 0:
- log = order.operationLog[-1]
- result = log['result']
- time_delta = (datetime.datetime.now() - log['time']).total_seconds()
- last_pre_balance = RMB(log['preBalance'])
- if (result == ErrorCode.DEVICE_CONN_FAIL or result == ErrorCode.BOARD_UART_TIMEOUT) \
- and (time_delta > 3 * 24 * 3600 or preBalance > last_pre_balance):
- logger.debug('{} recharge verify result is finished.'.format(repr(card)))
- order.update_after_recharge_ic_card(device=self.device,
- sendMoney=sendMoney,
- preBalance=preBalance,
- result=ErrorCode.SUCCESS,
- description=u'充值校验结束')
- # 现将订单状态改为待充值
- CardRechargeRecord.add_record(
- card=card,
- group=Group.get_group(order.groupId),
- order=order,
- device=self.device
- )
- return False
- if self.device.support_reliable: # 如果是新版本的,只管发,结果根据异步的事件进行处理
- self.deviceAdapter.recharge_card_async(card.cardNo, sendMoney, str(order.id))
- return False
- else:
- operation_result, balance = self.deviceAdapter.recharge_card(card.cardNo, sendMoney, str(order.id))
- order.update_after_recharge_ic_card(device=self.device,
- sendMoney=sendMoney,
- preBalance=preBalance,
- syncBalance=balance,
- result=operation_result['result'],
- description=operation_result['description'])
- if operation_result['result'] != ErrorCode.SUCCESS:
- return False
- if not balance:
- balance = preBalance + order.coins
- CardRechargeRecord.add_record(
- card=card,
- group=Group.get_group(order.groupId),
- order=order,
- device=self.device
- )
- # 刷新卡里面的余额
- card.balance = balance
- card.lastMaxBalance = balance
- card.save()
- return True
- except Exception as e:
- logger.exception(e)
- return False
- finally:
- Card.set_card_status(str(card.id), 'idle')
|