123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- # encoding=utf-8
- import logging
- import datetime
- from apilib.monetary import RMB
- from apps.web.constant import DeviceCmdCode
- from apps.web.core.adapter.base import SmartBox, MQTT_TIMEOUT
- from apps.web.core.device_define.huopo import HuopoCacheMgr, DefaultParams, Caculater
- from apps.web.core.exceptions import ServiceException
- from apps.web.core.networking import MessageSender
- from apps.web.user.models import MyUser
- from apps.web.device.models import Group, Device
- from taskmanager.mediator import task_caller
- logger = logging.getLogger(__name__)
- class HuoPoBox(SmartBox):
- def __init__(self, device):
- super(HuoPoBox, self).__init__(device)
- def _send_data(self, funCode, data, cmd=DeviceCmdCode.PASSTHROUGH_OPERATE_DEV_SYNC, timeout=MQTT_TIMEOUT.NORMAL):
- result = MessageSender.send(
- device=self.device,
- cmd=cmd,
- payload={
- "IMEI": self.device.devNo,
- "data": data,
- "funCode": funCode
- },
- timeout=timeout
- )
- if "rst" in result and result["rst"] != 0:
- if result['rst'] == -1:
- raise ServiceException({'result': 2, 'description': u'网络通信故障'})
- elif result['rst'] == 1:
- raise ServiceException({'result': 2, 'description': u'门禁主板连接故障'})
- else:
- raise ServiceException({'result': 2, 'description': u'系统错误'})
- return result
- def _open(self):
- otherConf = self.device.get("otherConf", dict())
- snNum = otherConf.get("snNum")
- try:
- snNum = int(snNum or "")
- except ValueError:
- raise ServiceException({"result": "", "description": u"道闸编号设置错误"})
- data = DefaultParams.INSTRUCT_FORMAT.format(
- snNum=snNum,
- dutou=DefaultParams.DUTOU_NUM,
- auth=DefaultParams.AUTH_NUM,
- stay=DefaultParams.STAY_NUM
- )
- return self._send_data("", data)
- def _get_card_wait(self):
- """
- 获取设备侧的参数
- :return:
- """
- result = self._send_data("GC", "", cmd=DeviceCmdCode.OPERATE_DEV_SYNC)
- return int(result.get("data")[:2], 16)
- def _set_card_wait(self, waitTime):
- if not self.device.driverVersion < "v2.0.0":
- data = "{:0>2X}".format(waitTime)
- self._send_data("CC", data, cmd=DeviceCmdCode.OPERATE_DEV_SYNC)
- def _get_server_config(self):
- """
- 获取设备侧的参数
- :return:
- """
- otherConf = self.device.get("otherConf", dict())
- parkInfo = self.get_parkingInfo()
- return {
- "maxParking": otherConf.get("maxParking", DefaultParams.DEFAULT_MAX_PARKING),
- "VIPMaxParking": otherConf.get("VIPMaxParking", DefaultParams.DEFAULT_VIP_MAX_PARKING),
- "snNum": otherConf.get("snNum", DefaultParams.DEFAULT_SN_NUM),
- "freeTime": otherConf.get("freeTime", DefaultParams.DEFAULT_FREE_TIME),
- "maxConsume": otherConf.get("maxConsume", DefaultParams.DEFAULT_FREE_TIME),
- "parkingNum": parkInfo.get("maxParking", 0),
- "VIPParkingNum": parkInfo.get("VIPMaxParking", 0)
- }
- def _get_device_config(self):
- """
- 获取服务器侧参数
- :return:
- """
- if self.device.driverVersion < "v2.0.0":
- return {
- "cardWait": u"驱动版本过低,暂不支持"
- }
- return {
- "cardWait": self._get_card_wait() # 刷卡等待时间
- }
- def calculate_consume(self, duration, package):
- """计算在给定的小时内要扣除的数量"""
- maxConsume = self.device.get("otherConf", dict()).get("maxConsume", DefaultParams.DEFAULT_MAX_CONSUME)
- freeTime = self.device.get("otherConf", dict()).get("freeTime", DefaultParams.DEFAULT_FREE_TIME)
- duration = duration - freeTime * 60
- c = Caculater(duration, package)
- money = c.caculate()
- if maxConsume == DefaultParams.DEFAULT_MAX_CONSUME:
- return money
- return min(money, RMB(maxConsume))
- def get_parkingInfo(self):
- serviceInfo = HuopoCacheMgr.get_parking_cache(self.device.groupId)
- parkingInfo = {}
- if serviceInfo is not None:
- parkingInfo = serviceInfo.get("parkingInfo", {})
- return parkingInfo
- def start_device(self, package, openId, attachParas):
- """启动
- 不把扣费逻辑做到这里面,是否决定扣费由外层service来决定
- """
- # 获取开闸信号 和 进入出门
- # TODO 标记用户的control不见了
- chargeIndex = attachParas.get("chargeIndex")
- control = "exit" if chargeIndex == "1" else "enter"
- # 开启道闸
- result = self._open()
-
- # 获取用户是否是VIP,使用了虚拟卡支付的都是VIP
- if self._vcard_id:
- _key = "VIPMaxParking"
- else:
- _key = "maxParking"
- # 在设备启动时候已经 加了锁 对于该设备当前
- parkingInfo = self.get_parkingInfo()
- parkingNum = parkingInfo.get(_key, 0)
- if control == "exit":
- if parkingNum > 0:
- parkingNum -= 1
- elif control == "enter":
- parkingNum += 1
- # 更新当前的最大人数 扫码的VIP不限制
- if openId and _key == "VIPMaxParking":
- parkingInfo.update({_key: parkingNum})
- HuopoCacheMgr.set_parking_cache(self._device.groupId, {"parkingInfo": parkingInfo})
- return result
- def notify_user(self, order, cardStart=False):
- """通知用户订单结束"""
- logger.info("start notify to user order finished")
- if order.isNormal and order.finishedTime:
- # 服务完成的订单需要通知用户
- openId = order.openId
- user = MyUser.objects.filter(openId=openId, groupId=self._device['groupId']).first()
- dealerId = self._device["ownerId"]
- group = Group.get_group(self._device["groupId"])
- address = group.get("address", "")
- startType = u"刷卡启动" if cardStart else u"扫码启动"
- # 通知的时候告诉用户是否使用虚拟卡支付了此次的费用 判断依据是 attachParas 里面有没有 vCardId
- if not order.attachParas.get("vCardId") and not order.attachParas.get("cardId"):
- payType = u"账户余额支付"
- elif not order.attachParas.get("vCardId") and order.attachParas.get("cardId"):
- payType = u"卡余额支付"
- else:
- payType = u"虚拟卡支付"
- consumeDict = {
- "title": u"\\n\\n设备编号:\\t\\t{logicalCode}\\n\\n服务地址:\\t\\t{group}\\n\\n起始时间:\\t\\t{st}\\n\\n结束时间:\\t\\t{et}\\n\\n启动方式:\\t\\t{startType}\\n\\n支付方式:\\t\\t{payType}".format(
- logicalCode=order.logicalCode,
- group=address,
- st=order.dateTimeAdded.strftime("%Y-%m-%d %H:%M:%S"),
- et=order.finishedTime.strftime("%Y-%m-%d %H:%M:%S"),
- startType=startType,
- payType=payType
- ),
- "service": u"停车服务已经结束",
- "finishTime": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
- "remark": u"谢谢您的支持"
- }
- task_caller(
- 'report_to_user_via_wechat',
- openId=user.managerialOpenId if user else "",
- dealerId=dealerId,
- templateName="service_complete",
- **consumeDict
- )
- def analyze_event_data(self, data):
- """
- 刷卡上报事件
- #2181113205,1,0010967430@
- #{sn号},{读头号(固定为1)},{刷卡卡号}@
- 返回数据 {"cmd":221,"IMEI":"866289037458447","funCode":"","data":"#2181113205,B1@"}
- """
- snNum, dutou, cardNoStr = data.replace("#", "").replace("@", "").split(",")
- cardNo = str(int(cardNoStr))
-
- return {"snNum": snNum, "cardNo": cardNo, "cardNoStr": cardNoStr, "dutou": dutou}
- def is_port_can_use(self, chargeIndex, canAdd=None):
- """这个地方不做判断 直接通过, 具体的停车人数在启动的时候对其进行判断,以免用户在扫码界面停留过久"""
- return True, u""
- def get_dev_setting(self):
- deviceConf = self._get_device_config()
- serverConf = self._get_server_config()
- conf = dict()
- conf.update(deviceConf)
- conf.update(serverConf)
- return conf
- def set_device_function_param(self, request, lastSetConf):
- """lastSetConf 缓存中的配置,更新的同时更新缓存"""
- maxConsume = int(request.POST.get("maxConsume"))
- cardWait = int(request.POST.get("cardWait"))
- freeTime = int(request.POST.get("freeTime"))
- maxParking = int(request.POST.get("maxParking"))
- vipMaxParking = int(request.POST.get("VIPMaxParking"))
- snNum = str(request.POST.get("snNum"))
- if snNum == DefaultParams.DEFAULT_SN_NUM:
- raise ServiceException({"result": "2", "description": u"保存失败,请配置主板编号"})
- # 配置驱动侧参数
- self._set_card_wait(cardWait)
- otherConf = self.device.get("otherConf", dict())
- otherConf.update({
- "maxConsume": maxConsume,
- "cardWait": cardWait,
- "freeTime": freeTime,
- "maxParking": maxParking,
- "VIPMaxParking": vipMaxParking,
- "snNum": snNum
- })
- Device.objects.filter(devNo=self.device.devNo).update(otherConf=otherConf)
- Device.invalid_device_cache(devNo=self.device.devNo)
|