123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- # -*- coding: utf-8 -*-
- # !/usr/bin/env python
- import datetime
- import logging
- import time
- from mongoengine import DoesNotExist
- from apilib.monetary import RMB, VirtualCoin
- from apilib.utils_sys import memcache_lock
- from apps.web.agent.models import Agent
- from apps.web.constant import Const, DeviceCmdCode
- from apps.web.dealer.models import Dealer
- from apps.web.device.models import Group, Device
- from apps.web.eventer import EventBuilder
- from apps.web.eventer.base import WorkEvent, FaultEvent
- from apps.web.user.models import ServiceProgress, UserVirtualCard, VCardConsumeRecord, Card, MyUser
- from apps.web.user.transaction_deprecated import refund_money
- logger = logging.getLogger(__name__)
- class builder(EventBuilder):
- def __getEvent__(self, device_event):
- event_data = self.deviceAdapter.analyze_event_data(device_event['data'])
- if event_data is None or 'cmdCode' not in event_data:
- return None
- if event_data['cmdCode'] in ["08", "0C", "0E"]:
- if event_data['cmdCode'] == "08":
- event_data.update({{
- 'answer': device_event['data'][42:-4]
- }})
- return ChargingNanjiguangWorkEvent(self.deviceAdapter, event_data)
- if event_data["cmdCode"] in ["12"]:
- return ChargingNanjiguangFaultEvent(self.deviceAdapter, event_data)
- class ChargingNanjiguangWorkEvent(WorkEvent):
- def do(self, **args):
- cmdCode = self.event_data.get("cmdCode")
- devNo = self.device["devNo"]
- with memcache_lock(key = "{devNo}.{cmdCode}.event".format(devNo = devNo, cmdCode = cmdCode),
- value = '1') as acquired:
- if acquired:
- # 扫码结束充电
- if cmdCode == "08":
- sendData = self.event_data['answer']
- self.answer_device(funcCode="09", sendData=sendData)
- self.do_finish_charging()
- # 刷卡开始
- elif cmdCode == "0C":
- sendData = self.event_data.get("portHex") + self.event_data.get("timeStampHex")
- self.answer_device(funcCode="0D", sendData=sendData)
- self.do_start_card_charging()
- # 刷卡结束
- elif cmdCode == "0E":
- sendData = self.event_data.get("portHex") + self.event_data.get("timeStampHex")
- self.answer_device(funcCode="0F", sendData=sendData)
- self.do_finish_card_charging()
- else:
- logger.error("undefined cmd")
- def answer_device(self, funcCode, sendData):
- self.deviceAdapter._send_data(funcCode=funcCode, sendData=sendData, cmd=DeviceCmdCode.OPERATE_DEV_NO_RESPONSE)
- def do_finish_charging(self):
- """
- 扫码结束充电
- :return:
- """
- portStr = self.event_data.get("port")
- devCache = Device.get_dev_control_cache(self.device["devNo"])
- portCache = devCache.get(portStr)
- openId = portCache.get("openId")
- vCardId = portCache.get("vCardId")
- coins = portCache.get("coins")
- needTime = portCache.get("needTime")
- spendTime = self.event_data.get("spendTime")
- nowTime = datetime.datetime.now()
- group = Group.get_group(self.device["groupId"])
- dealer = Dealer.objects.filter(id=group["ownerId"]).first()
- if not openId:
- logger.error("open id is null")
- if not dealer:
- logger.error('dealer is not found, dealerId=%s' % group['ownerId'])
- return
- agent = Agent.objects(id=dealer.agentId).first()
- if not agent:
- logger.error('agent is not found, agentId=%s' % dealer.agentId)
- return
- user = MyUser.objects.filter(openId=openId, groupId=self.device["groupId"]).first()
- # 计算退费
- leftTime = needTime * 60 - spendTime if needTime * 60 > spendTime else 0
- refundCoins = VirtualCoin((leftTime / (needTime * 60)) * coins)
- self.notify_user(
- managerialOpenId=user.managerialOpenId,
- templateName="service_complete",
- title=u"\\n\\n结束原因:\\t\\t{reason}\\n\\n设备编号:\\t\\t{logicalCode}-{port}\\n\\n服务地址:\\t\\t{group}\\n\\n订购时间:\\t\\t{needTime}分钟\\n\\n剩余时间:\\t\\t{leftTime}分钟".format(
- reason=u"充电结束",
- logicalCode=self.device["logicalCode"],
- port=self.event_data["port"],
- group=group["address"],
- needTime=needTime,
- leftTime=int(leftTime / 60)
- ),
- service=u"充电桩充电服务",
- finishTime=datetime.datetime.strftime(nowTime, "%Y-%m-%d %H:%M:%S"),
- remark = u'谢谢您的支持'
- )
- consumeDict = {
- 'chargeIndex': portStr,
- 'reason': u"充电结束",
- 'actualNeedTime': needTime,
- 'duration': int(spendTime / 60),
- 'elec': round(self.event_data["spendElec"], 2),
- 'elecFee': self.calc_elec_fee(self.event_data["spendElec"]),
- 'leftTime': int(leftTime / 60),
- 'needTime': u'扫码订购%s分钟' % needTime
- }
- if int(refundCoins) > 0 and self.device.is_auto_refund:
- if vCardId is None:
- refund_money(self.device, refundCoins, openId)
- else:
- # 虚拟卡退费
- try:
- vCard = UserVirtualCard.objects.get(id=vCardId)
- except DoesNotExist:
- logger.info('can not find the vCard id = %s' % vCardId)
- return
- consumeRecordId = portCache.get("consumeRcdId")
- if consumeRecordId is None:
- logger.info('can not find consume rcd id')
- return
- try:
- vCardConsumeRcd = VCardConsumeRecord.objects.get(id=consumeRecordId)
- except DoesNotExist, e:
- logger.info('can not find the consume rcd id = %s' % consumeRecordId)
- return
- vCard.refund_quota(
- vCardConsumeRcd,
- int(spendTime/60),
- self.event_data["spendElec"],
- refundCoins.mongo_amount
- )
- consumeDict.update({"refundCoins": refundCoins.mongo_amount})
- refundTitle = u'您使用的%s号端口充电,共付款:%s元,充电预定时间为:%s分钟,剩余时间:%s分钟,给您退款:%s元' % (portStr, coins, int(needTime/60), int(leftTime/60), refundCoins)
- self.notify_user(user.managerialOpenId if user else '', 'refund_coins', **{
- 'title': refundTitle,
- 'backCount': u'金币:%s' % refundCoins,
- 'finishTime': datetime.datetime.strftime(nowTime, "%Y-%m-%d %H:%M:%S")
- })
- ServiceProgress.update_progress_and_consume_rcd(
- self.device["ownerId"],
- {
- "open_id": openId,
- "device_imei": self.device["devNo"],
- "port": int(portStr),
- "isFinished": False
- },
- consumeDict
- )
- # 事件结束之后清空端口的信息 更新设备的服务信息
- Device.clear_port_control_cache(self.device["devNo"], portStr)
- def do_start_card_charging(self):
- """
- 刷卡开始
- :return:
- """
- portStr = self.event_data.get("port")
- timeStamp = self.event_data.get("timeStamp")
- cardNo = self.event_data.get("cardNo")
- coins = self.event_data.get("coins")
- startTime = time.strftime("%Y-%m-%d %H:%M", time.localtime(timeStamp))
- card = self.update_card_dealer_and_type(cardNo, cardType="IC", isHaveBalance=False)
- if not card.openId:
- logger.error("card has not openId, cardNo is %s" % card.cardNo)
- return
- orderNo, cardOrderNo = self.record_consume_for_card(card, RMB(self.event_data["coins"]))
- # 记录当前的卡消费的 progress
- fee = RMB(coins)
- ServiceProgress.register_card_service(
- self.device,
- int(portStr),
- card,
- {
- "orderNo": orderNo,
- "money": fee.mongo_amount,
- "coin": fee.mongo_amount,
- "cardOrderNo": cardOrderNo
- }
- )
- # 通知卡消费成功
- self.notify_balance_has_consume_for_card(card, fee)
- # 更新一下端口缓存
- self.event_data.update({'cardId': str(card.id)})
- self.event_data.update({'openId': card.openId})
- self.event_data.update({'coins': int(fee)})
- self.event_data.update({'startTime': startTime})
- self.event_data.update({'isStart': True, 'status': Const.DEV_WORK_STATUS_WORKING})
- Device.update_dev_control_cache(self.device['devNo'], {portStr :self.event_data})
- def do_finish_card_charging(self):
- """
- # 刷卡结束上报
- :return:
- """
- portStr = self.event_data.get("port")
- spendTime = self.event_data.get("spendTime")
- spendElec = self.event_data.get("spendElec")
- devCache = Device.get_dev_control_cache(self.device["devNo"])
- portCache = devCache.get(portStr)
- if not portCache:
- logger.error("not port cache")
- return
- cardId = portCache.get("cardId")
- try:
- card = Card.objects.get(id=cardId)
- except DoesNotExist:
- logger.error("card don't exist")
- return
- openId = card.openId
- group = Group.get_group(self.device["groupId"])
- user = MyUser.objects.filter(openId=openId, groupId=self.device["groupId"]).first()
- consumeDict = {
- 'chargeIndex': portStr,
- 'reason': u"刷卡充电结束",
- 'duration': int(spendTime / 60),
- 'elec': round(spendElec, 2),
- 'elecFee': self.calc_elec_fee(self.event_data["spendElec"]),
- }
- nowTime = datetime.datetime.now()
- self.notify_user(
- managerialOpenId=user.managerialOpenId,
- templateName="service_complete",
- title=u"\\n\\n结束原因:\\t\\t{reason}\\n\\n设备编号:\\t\\t{logicalCode}-{port}\\n\\n服务地址:\\t\\t{group}\\n\\n订购金额:\\t\\t{coins}".format(
- reason=u"刷卡充电结束",
- logicalCode=self.device["logicalCode"],
- port=self.event_data["port"],
- group=group["address"],
- coins=portCache.get("coin")
- ),
- service=u"充电桩充电服务",
- finishTime=datetime.datetime.strftime(nowTime, "%Y-%m-%d %H:%M:%S"),
- remark = u'谢谢您的支持'
- )
- ServiceProgress.update_progress_and_consume_rcd(
- self.device["ownerId"],
- {
- "open_id": openId,
- "device_imei": self.device["devNo"],
- "port": int(portStr),
- "isFinished": False
- },
- consumeDict
- )
- # 事件结束之后清空端口的信息 更新设备的服务信息
- Device.clear_port_control_cache(self.device["devNo"], portStr)
- class ChargingNanjiguangFaultEvent(FaultEvent):
- def do(self, **args):
- """
- 烟感报警
- :param **args:
- :return:
- """
- # 首先发送确认消息
- self.deviceAdapter._send_data(funCode=13, sendData=self.event_data.get("timeStampHex"), cmd=DeviceCmdCode.OPERATE_DEV_NO_RESPONSE)
- group = Group.get_group(self.device["groupId"])
- eventTime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(self.event_data.get("timeStamp")))
- self.notify_dealer(
- templateName="device_fault",
- title="注意!设备烟感报警!",
- device=u"{groupNumber}组-{logicalCode}".format(groupNumber=self.device["groupNumber"], logicalCode=self.device["logicalCode"]),
- location=u"{address}-{groupName}".format(address=group["address"], groupName=group["groupName"]),
- fault=u"设备当前触发烟感,可能发生了火警!",
- notifyTime=eventTime
- )
|