# -*- coding: utf-8 -*- # !/usr/bin/env python import datetime import logging import time from apilib.monetary import RMB, VirtualCoin, Ratio from apps.web.constant import Const from apps.web.device.models import Group, Device from apps.web.eventer.base import WorkEvent from apps.web.eventer import EventBuilder from apps.web.user.models import ServiceProgress, 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']) return QiangLongEvent(self.deviceAdapter, event_data) class QiangLongEvent(WorkEvent): def do(self, **args): cmd = self.event_data.get("cmdCode") if cmd == "C0": portStr = self.event_data.get("portStr") devCache = Device.get_dev_control_cache(self.device.devNo) or dict() portCache = devCache.get(portStr) if not portCache: logger.error("<{}> has receive a finish event but no portCache exists!".format(self.device.devNo)) return openId = portCache.get("openId") coins = portCache.get("coins") needTime = portCache.get("needTime") startTimeStamp = portCache.get("startTimeStamp") cardId = portCache.get("cardId") nowTimeStamp = int(time.time()) duration = (nowTimeStamp - startTimeStamp) // 60 if duration < 0: duration = 0 elif duration > needTime: duration = needTime else: duration = duration user = MyUser.objects.filter(openId = openId, groupId = self.device.groupId).first() consumeDict = { "needTime": needTime, "duration": duration, "chargeIndex": portStr } if self.device.is_auto_refund: try: refundMoney = VirtualCoin(coins) * Ratio((needTime - duration) / needTime) except ZeroDivisionError: refundMoney = VirtualCoin(0) except Exception as e: refundMoney = VirtualCoin(0) logger.exception(e) if refundMoney > VirtualCoin(0): if cardId: self.record_refund_money_for_card(refundMoney, cardId) consumeDict.update({"cardId": cardId}) else: refund_money(self.device, refundMoney, openId) consumeDict.update({"refundedMoney": refundMoney.mongo_amount}) self.notify_user( user.managerialOpenId if user else '', 'refund_coins', **{ 'title': u"金币退款", 'backCount': u'%s' % refundMoney.amount, 'finishTime': datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") } ) group = Group.get_group(self.device.groupId) self.notify_user( managerialOpenId = user.managerialOpenId if user else "", templateName = "service_complete", title = u"设备编号:\\t\\t{logicalCode}-{port}\\n\\n服务地址:\\t\\t{group}\\n\\n订购时间:\\t\\t{needTime}分钟\\n\\n剩余时间:\\t\\t{leftTime}分钟".format( logicalCode = self.device["logicalCode"], port = portStr, group = group.get("address", ""), needTime = needTime, leftTime = needTime - duration ), service = u"充电服务", finishTime = datetime.datetime.now().strftime("%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 = consumeDict ) Device.clear_port_control_cache(self.device.devNo, portStr) elif cmd == "EE": self.do_card_start() def do_card_start(self): """ 刷卡启动设备 :return: """ cardNo = self.event_data.get("cardNo") portStr = self.event_data.get("portStr") otherConf = self.device.get("otherConf", dict()) cardCst = int(otherConf.get("cardCst", self.deviceAdapter.DEFAULT_CARD_CST)) cardTime = int(otherConf.get("cardTime", self.deviceAdapter.DEFAULT_CARD_TIME)) # if int(portStr) == 0: # logger.error("port 0 has been start!") # return self._smartBox._response_card(portStr, 0, 1) # 检查端口是否被占用 result = self.deviceAdapter._query_port_status(portStr) if result.get("status") != Const.DEV_WORK_STATUS_IDLE: logger.error("port <{}> is working!".format(portStr)) return self.deviceAdapter._response_card(portStr, 0, 1) # 是否是无效卡 card = self.update_card_dealer_and_type(cardNo) if not card or not card.openId or card.frozen: logger.error("card can not use, cardNo is <{}>".format(cardNo)) return self.deviceAdapter._response_card(portStr, 0, 5) # 端口号是 0 说明是查询余额 if int(portStr) == 0: logger.info("-------------------------------- find card") return self.deviceAdapter._response_card(portStr, int(float(card.balance*100)), 255) if float(card.balance) < cardCst: logger.error("card balance not enough, cardNo is <{}>".format(cardNo)) return self.deviceAdapter._response_card(portStr, int(float(card.balance * 100)), 3) # 都OK的话可以发送数据告诉主板准备启动了 self.deviceAdapter._response_card(portStr, int(float(card.balance * 100) - (cardCst * 100)), 255) # 发送启动 self.deviceAdapter._start(portStr, cardTime) # 卡扣费等等一系列操作 self.consume_money_for_card(card, RMB(cardCst)) orderNo, cardOrderNo = self.record_consume_for_card(card, RMB(cardCst)) portCache = { "cardId": str(card.id), "cardNo": card.cardNo, "status": Const.DEV_WORK_STATUS_WORKING, "coins": cardCst, "startTime": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "openId": card.openId, "isStart": True, "needTime": cardTime, "startTimeStamp": int(time.time()) } Device.update_dev_control_cache(self.device.devNo, {portStr: portCache}) ServiceProgress.register_card_service( self.device, int(portStr), card, consumeOrder = { "money": RMB(cardCst).mongo_amount, "needTime": cardTime, "unit": u"分钟", "consumeType": "card", "orderNo": orderNo, "cardOrderNo": cardOrderNo, } )