weifule_car_home_doub.py 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. # -*- coding: utf-8 -*-
  2. # !/usr/bin/env python
  3. import datetime
  4. import json
  5. import logging
  6. import time
  7. from copy import deepcopy
  8. from typing import TYPE_CHECKING
  9. from apilib.monetary import RMB, VirtualCoin, Ratio
  10. from apilib.utils_string import make_title_from_dict
  11. from apilib.utils_sys import memcache_lock
  12. from apps.web.common.transaction import UserConsumeSubType
  13. from apps.web.constant import FAULT_LEVEL, DEALER_CONSUMPTION_AGG_KIND, Const
  14. from apps.web.device.models import DeviceUploadInfo, Group
  15. from apps.web.eventer import EventBuilder
  16. from apps.web.eventer.base import WorkEvent, FaultEvent
  17. from apps.web.eventer.weifuleCommon import WeiFuLeStatusEvent, WeiFuLeCarProcess
  18. from apps.web.user.models import CardRechargeOrder
  19. from apps.web.user.models import ConsumeRecord, CardConsumeRecord, Card, RechargeRecord, RefundMoneyRecord, \
  20. ServiceProgress
  21. from apps.web.utils import concat_user_login_entry_url
  22. if TYPE_CHECKING:
  23. pass
  24. logger = logging.getLogger(__name__)
  25. def log_obj(obj):
  26. obj = deepcopy(obj)
  27. if isinstance(obj, dict):
  28. for k, v in obj.items():
  29. if isinstance(v, object):
  30. obj[k] = str(v)
  31. if isinstance(obj, list) or isinstance(obj, tuple) or isinstance(obj, set):
  32. obj = map(lambda x: str(x) if isinstance(x, object) else x, obj)
  33. if isinstance(obj, unicode):
  34. obj = str(obj)
  35. # print('\33[33m' + json.dumps(obj,ensure_ascii=True,encoding='utf-8') + '\33[0m')
  36. return '\33[33m' + json.dumps(obj, ensure_ascii=False, encoding='utf-8') + '\33[0m'
  37. card_is_normal = 1
  38. card_not_in_db = 2
  39. card_is_forzen = 3
  40. card_has_not_order = 4 # IC卡适用
  41. card_less_balance = 5 # ID卡适用
  42. class builder(EventBuilder):
  43. def __getEvent__(self, device_event):
  44. logger.info('reve event, event_data:{}'.format(log_obj(device_event)))
  45. event_data = device_event.get('data')
  46. fun_code = event_data.get('fun_code')
  47. if not event_data:
  48. return
  49. if event_data['fun_code'] in [44]:
  50. return WeiFuLeStatusEvent(self.deviceAdapter, device_event)
  51. if fun_code in [40, 41, 42, 43]: # 40温度告警/41电流超限/42电压超限/43功率过载
  52. return ChargingWeiFuLeCarFaultEvent(self.deviceAdapter, event_data)
  53. else:
  54. return ChargingWeiFuLeCarWorkEvent(self.deviceAdapter, event_data)
  55. class Process(WeiFuLeCarProcess):
  56. def pre_pay(self, order):
  57. openId = order.openId
  58. used_time = round(self.order_info.get('time') / 60.0, 2)
  59. used_elec = self.order_info.get('elec') / 10.0 ** 6
  60. reason = self.desc_map.get(self.order_info.get('cause'))
  61. execTimeStamp = self.order_info.get('exec_time')
  62. finishedTimeStamp = self.order_info.get('over_time')
  63. finishedTime = datetime.datetime.fromtimestamp(finishedTimeStamp)
  64. if not execTimeStamp:
  65. startTime = finishedTime
  66. else:
  67. startTime = datetime.datetime.fromtimestamp(execTimeStamp)
  68. amount = RMB.fen_to_yuan(self.order_info.get('amount', 0))
  69. records = self.order_info.get('records', [])
  70. elecFee = round(sum(map(lambda _: _['elec_money'], records)) * 0.01, 2)
  71. serviceFee = round(sum(map(lambda _: _['serv_money'], records)) * 0.01, 2)
  72. extra = [
  73. {u'使用时长': u'{}(分钟)'.format(used_time)},
  74. {u'消费明细': u'电费{}元, 服务费{}元'.format(elecFee, serviceFee)},
  75. ]
  76. # for record in records:
  77. # sts = to_datetime(record['init']).strftime('%H:%M')
  78. # fts = to_datetime(record['last']).strftime('%H:%M')
  79. # extra.append({u'时段'.format(sts, fts): u'{}-{}'.format(sts, fts)})
  80. # extra.append({u'费用'.format(sts, fts): u'电费{}, 服务费{}'.format(round(record['elec_money'] * 0.01, 2),
  81. # round(record['serv_money'] * 0.01, 2))})
  82. usedMoney = min(RMB(elecFee + serviceFee), amount)
  83. leftMoney = amount - usedMoney
  84. status = self.order_info.get('status')
  85. consumeDict = {
  86. DEALER_CONSUMPTION_AGG_KIND.DURATION: '%d' % used_time,
  87. DEALER_CONSUMPTION_AGG_KIND.ELEC: '%.2f' % used_elec,
  88. DEALER_CONSUMPTION_AGG_KIND.COIN: amount.mongo_amount,
  89. 'reason': reason
  90. }
  91. order.status = status
  92. order.startTime = startTime
  93. order.finishedTime = finishedTime
  94. order.save()
  95. user = order.user
  96. self.smartbox.notify_user_service_complete(
  97. service_name='充电',
  98. openid=user.managerialOpenId if user else '',
  99. port='',
  100. address=self.dev.group['address'],
  101. reason=reason,
  102. finished_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
  103. extra=extra
  104. )
  105. if order.attachParas.get('is_auto_refund', False):
  106. recharge_record = None
  107. if order.rechargeRcdId:
  108. recharge_record = RechargeRecord.objects(
  109. id=order.rechargeRcdId, isQuickPay=True).first() # type: RechargeRecord
  110. if recharge_record:
  111. refundMoneyRecord = RefundMoneyRecord.objects.filter(openId=openId,
  112. rechargeObjId=recharge_record.id).first()
  113. if not refundMoneyRecord:
  114. self._do_refund_money(recharge_record, order, leftMoney, consumeDict)
  115. else:
  116. self._do_refund_coin(order, leftMoney, consumeDict)
  117. order.update_service_info(consumeDict)
  118. ServiceProgress.objects.filter(device_imei=self.devNo, weifuleOrderNo=order.orderNo).update(
  119. isFinished=True, finished_time=int(time.time())
  120. )
  121. self.adapter.async_update_portinfo_from_dev()
  122. def after_pay(self, order):
  123. """
  124. 只针对设备下发之后,没有回复的故障单为后付费
  125. :return:
  126. """
  127. used_time = round(self.order_info.get('time') / 60.0, 2)
  128. used_elec = self.order_info.get('elec') / 10.0 ** 6
  129. reason = self.desc_map.get(self.order_info.get('cause'))
  130. execTimeStamp = self.order_info.get('exec_time')
  131. finishedTimeStamp = self.order_info.get('over_time')
  132. port = self.order_info.get('port')
  133. finishedTime = datetime.datetime.fromtimestamp(finishedTimeStamp)
  134. if not execTimeStamp:
  135. startTime = finishedTime
  136. else:
  137. startTime = datetime.datetime.fromtimestamp(execTimeStamp)
  138. consumeDict = {
  139. DEALER_CONSUMPTION_AGG_KIND.DURATION: '%d' % used_time,
  140. DEALER_CONSUMPTION_AGG_KIND.ELEC: '%.2f' % used_elec,
  141. 'reason': reason,
  142. }
  143. amount = RMB.fen_to_yuan(self.order_info.get('amount', 0))
  144. records = self.order_info.get('records', [])
  145. elecFee = int(sum(map(lambda _: _['elec_money'], records))) * 0.01
  146. serviceFee = int(sum(map(lambda _: _['serv_money'], records))) * 0.01
  147. extra = [
  148. {u'使用时长': u'{}(分钟)'.format(used_time)},
  149. {u'消费明细': u'电费{}元, 服务费{}元'.format(elecFee, serviceFee)},
  150. ]
  151. usedMoney = min(RMB(elecFee + serviceFee), amount)
  152. order.startTime = startTime
  153. order.finishedTime = finishedTime
  154. coins = VirtualCoin(order.package.get('coins', 0))
  155. price = RMB(order.package.get('price'))
  156. ratio = Ratio(float(usedMoney) / float(amount))
  157. order.coin = coins * ratio
  158. order.money = price * ratio
  159. if order.money == RMB(0):
  160. order.coin = VirtualCoin(0)
  161. order.save()
  162. if order.money > RMB(0):
  163. self._pay_by_coins(order)
  164. else:
  165. order.update(status=self.FINISHED)
  166. order.reload()
  167. if order.status == self.FINISHED:
  168. extra.append({u'本单消费金额': '{}金币(已使用账户余额自动结算本次消费)'.format(order.coin.mongo_amount)})
  169. consumeDict.update({DEALER_CONSUMPTION_AGG_KIND.COIN: order.coin.mongo_amount})
  170. else:
  171. extra.append({u'本单消费金额': '{}元((您的账户余额不足以抵扣本次消费,请前往账单中心进行支付))'.format(order.money.mongo_amount)})
  172. consumeDict.update({DEALER_CONSUMPTION_AGG_KIND.SPEND_MONEY: order.money.mongo_amount})
  173. self.smartbox.notify_user_service_complete(
  174. service_name='充电结束',
  175. openid=order.user.managerialOpenId,
  176. port=str(port),
  177. address=self.dev.group['address'],
  178. reason=reason,
  179. finished_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
  180. extra=extra
  181. )
  182. order.update_service_info(consumeDict)
  183. ServiceProgress.objects.filter(device_imei=self.devNo, weifuleOrderNo=order.orderNo).update(
  184. isFinished=True, finished_time=int(time.time())
  185. )
  186. def _card_start_do_record_running_32(self):
  187. amount = RMB.fen_to_yuan(self.order_info.get('amount', 0))
  188. card_balance = RMB.fen_to_yuan(self.order_info.get('balance'))
  189. start_time_stamp = self.order_info.get('create_time')
  190. start_time = datetime.datetime.fromtimestamp(start_time_stamp)
  191. order_id = self.order_info.get('id')
  192. card_no = self.order_info.get('card_no')
  193. port = self.order_info.get('port')
  194. card = Card.objects.filter(cardNo=card_no, cardType='ID', dealerId=self.dev.ownerId).first()
  195. if not card:
  196. logger.info('no this card cardNo:{}'.format(card_no))
  197. return
  198. # 做一次订单号去重
  199. order = ConsumeRecord.objects.filter(sequanceNo=order_id, devNo=self.dev.devNo).first()
  200. if order:
  201. logger.info('order already exists cardNo:{}, order_id'.format(card_no, order_id))
  202. return
  203. servicedInfo = {
  204. 'cardNo': card_no,
  205. 'port': '1',
  206. }
  207. attachParas = {
  208. 'chargeIndex': '1',
  209. 'sequanceNo': order_id,
  210. 'is_auto_refund': self.dev.is_auto_refund
  211. }
  212. # 记录卡消费记录以及消费记录
  213. order, cardOrder = self.smartbox.record_consume_for_card(card, amount, servicedInfo=servicedInfo,
  214. attachParas=attachParas)
  215. card.freeze_balance(str(order.id), VirtualCoin(amount))
  216. consumeOrder = {
  217. 'orderNo': order.orderNo,
  218. 'cardOrderNo': cardOrder.orderNo,
  219. 'coin': str(amount),
  220. 'consumeType': 'card',
  221. }
  222. self._register_card_service_progress(card, port, consumeOrder, order_id)
  223. title = make_title_from_dict([
  224. {u'设备地址': u'{}'.format(self.dev.group.address)},
  225. {u'设备编号': u'{}'.format(self.dev['logicalCode'])},
  226. {u'实体卡': u'{}--No:{}'.format(card.cardName or card.nickName, card.cardNo)},
  227. # {u'本次消费': u'{} 元'.format(amount)},
  228. {u'卡余额': u'{} 元'.format(card_balance)},
  229. ])
  230. self.smartbox.notify_user(
  231. card.managerialOpenId,
  232. 'dev_start',
  233. **{
  234. 'title': title,
  235. 'things': u'刷卡消费',
  236. 'remark': u'感谢您的支持!',
  237. 'time': start_time.strftime(Const.DATETIME_FMT)
  238. }
  239. )
  240. def _card_start_do_record_finished_34(self):
  241. used_time = round(self.order_info.get('time') / 60.0, 2)
  242. finishedTimeStamp = self.order_info.get('over_time')
  243. finishedTime = datetime.datetime.fromtimestamp(finishedTimeStamp)
  244. execTimeStamp = self.order_info.get('exec_time')
  245. if not execTimeStamp:
  246. startTime = finishedTime
  247. else:
  248. startTime = datetime.datetime.fromtimestamp(execTimeStamp)
  249. reason = self.desc_map.get(self.order_info.get('cause'))
  250. card_no = self.order_info.get('card_no')
  251. used_elec = self.order_info.get('elec') / 10 ** 6
  252. order_id = self.order_info.get('id')
  253. amount = RMB.fen_to_yuan(self.order_info.get('amount', 0))
  254. records = self.order_info.get('records', [])
  255. elecFee = round(sum(map(lambda _: _['elec_money'], records)) * 0.01, 2)
  256. serviceFee = round(sum(map(lambda _: _['serv_money'], records)) * 0.01, 2)
  257. usedMoney = min(RMB(elecFee + serviceFee), amount)
  258. leftMoney = amount - usedMoney
  259. card = Card.objects.filter(cardNo=card_no, cardType='ID', dealerId=self.dev.ownerId).first()
  260. consumeOrder = ConsumeRecord.objects.filter(devNo=self.devNo, sequanceNo=order_id,
  261. status__ne=ConsumeRecord.Status.FINISHED).first()
  262. if not card or not consumeOrder:
  263. logger.info('do card finished --> no order found or repeated submit orderNo:{}'.format(order_id))
  264. return
  265. if not consumeOrder.attachParas.get('is_auto_refund', False):
  266. leftMoney = RMB(0)
  267. card.clear_frozen_balance(str(consumeOrder.id), VirtualCoin(leftMoney))
  268. card.reload()
  269. openId = consumeOrder.openId
  270. consumeOrder.servicedInfo.update({
  271. DEALER_CONSUMPTION_AGG_KIND.REFUND_CARD: leftMoney.mongo_amount,
  272. DEALER_CONSUMPTION_AGG_KIND.CONSUME_CARD: amount.mongo_amount,
  273. DEALER_CONSUMPTION_AGG_KIND.DURATION: '%d' % used_time,
  274. DEALER_CONSUMPTION_AGG_KIND.ELEC: '%.2f' % used_elec,
  275. 'reason': reason,
  276. 'cardNo': card_no
  277. })
  278. consumeOrder.status = self.FINISHED
  279. consumeOrder.startTime = startTime
  280. consumeOrder.finishedTime = finishedTime
  281. consumeOrder.save()
  282. ServiceProgress.update_progress_and_consume_rcd(
  283. self.dev['ownerId'],
  284. {
  285. 'open_id': openId,
  286. 'device_imei': self.devNo,
  287. 'isFinished': False,
  288. 'weifuleOrderNo': order_id,
  289. },
  290. consumeOrder.servicedInfo,
  291. progressDict={'isFinished': True, 'finished_time': finishedTimeStamp}
  292. )
  293. user = consumeOrder.user
  294. extra = [
  295. # {u'订单号': '{}'.format(consumeOrder.orderNo)},
  296. {u'本次使用时长': '{}(分钟)'.format(used_time)},
  297. {u'消费明细': u'电费{}元, 服务费{}元'.format(elecFee, serviceFee)},
  298. {u'卡片余额': '{}元'.format(card.balance)},
  299. ]
  300. self.smartbox.notify_user_service_complete(
  301. service_name='刷卡充电',
  302. openid=user.managerialOpenId if user else '',
  303. port='',
  304. address=self.dev.group.address,
  305. reason=reason,
  306. finished_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
  307. extra=extra
  308. )
  309. logger.info('card start event orderNo:{} is over'.format(order_id))
  310. self.adapter.async_update_portinfo_from_dev()
  311. class ChargingWeiFuLeCarWorkEvent(WorkEvent):
  312. def do(self, **args):
  313. fun_code = self.event_data.get('fun_code')
  314. order_id = self.event_data.get('order', {}).get('id')
  315. key = '{}.{}.event'.format(self.device.devNo, order_id)
  316. if fun_code == 37: # 处理卡充值
  317. self.deal_with_id_charge_event()
  318. elif fun_code == 44: # 上报结束后的状态
  319. pass
  320. elif fun_code == 45: # 上传要链接
  321. self.response_the_link()
  322. elif fun_code == 48:
  323. self.price_rule_change()
  324. else:
  325. with memcache_lock(key=key, value='1', expire=15) as acquired:
  326. if acquired:
  327. if fun_code == 32 or fun_code == 34 or fun_code == 33:
  328. self._do_order_change_event_32_33_34()
  329. self._do_ack_order_32_or_remove_order_from_device_34()
  330. else:
  331. logger.debug('fun_code<{}> is doing. cache_key:{}'.format(repr(fun_code), key))
  332. return
  333. def deal_with_id_charge_event(self):
  334. cardNo = self.event_data.get('card_no')
  335. card = self.update_card_dealer_and_type(cardNo) # type: Card
  336. logger.info(log_obj('Start card recharge operation'))
  337. if not card:
  338. logger.info(log_obj('Start card recharge operation --> no such card !!! '))
  339. return self.deviceAdapter.send_mqtt({
  340. 'fun_code': 37,
  341. 'card_no': cardNo,
  342. 'result': card_not_in_db,
  343. })
  344. elif card.frozen:
  345. logger.info(log_obj('Start card recharge operation --> card is frozen !!! '))
  346. return self.deviceAdapter.send_mqtt({
  347. 'fun_code': 37,
  348. 'card_no': cardNo,
  349. 'result': card_is_forzen,
  350. })
  351. elif not self.device.owner:
  352. return self.deviceAdapter.send_mqtt({
  353. 'fun_code': 37,
  354. 'card_no': cardNo,
  355. 'result': card_not_in_db,
  356. })
  357. # 是否存在没有到账的余额 进行充值
  358. card_recharge_order = CardRechargeOrder.get_last_to_do_one(str(card.id))
  359. self.recharge_id_card(
  360. card=card,
  361. rechargeType='append',
  362. order=card_recharge_order
  363. )
  364. card.reload()
  365. # {
  366. # "cmd": 100,
  367. # "IMEI": "863488058983340",
  368. # "time": 1664519145,
  369. # "data": {
  370. # "card_no": "3427873049",
  371. # "fun_code": 37,
  372. # "action": "query"
  373. # }
  374. # }
  375. action = self.event_data.get('action')
  376. if action == 'query':
  377. return self.deviceAdapter.send_mqtt({
  378. 'fun_code': 37,
  379. 'card_no': cardNo,
  380. 'result': card_is_normal,
  381. 'balance': RMB.yuan_to_fen(card.balance),
  382. "amount": RMB.yuan_to_fen(card.balance)
  383. })
  384. elif action == 'start':
  385. ongoingList = getattr(card, 'ongoingList', []) # 有冻结未结束的订单
  386. if card.balance <= RMB(0) or ongoingList:
  387. return self.deviceAdapter.send_mqtt({
  388. 'fun_code': 37,
  389. 'card_no': cardNo,
  390. 'result': card_less_balance,
  391. 'balance': RMB.yuan_to_fen(card.balance),
  392. "amount": RMB.yuan_to_fen(card.balance),
  393. })
  394. return self.deviceAdapter.send_mqtt({
  395. 'fun_code': 37,
  396. 'card_no': cardNo,
  397. 'result': card_is_normal,
  398. 'balance': RMB.yuan_to_fen(card.balance),
  399. "amount": RMB.yuan_to_fen(card.balance)
  400. })
  401. def _do_order_change_event_32_33_34(self):
  402. order_info = self.event_data.get('order')
  403. if not order_info:
  404. return logger.info(log_obj('no order info,do over!!'))
  405. else:
  406. order_processing = Process(self)
  407. order_type = order_info.get('order_type')
  408. self.save_upload_log()
  409. if hasattr(order_processing, order_type):
  410. event = getattr(order_processing, order_type)
  411. try:
  412. event()
  413. except Exception:
  414. import traceback
  415. logger.info(traceback.format_exc())
  416. else:
  417. logger.info(log_obj('no this order_type'))
  418. def _do_ack_order_32_or_remove_order_from_device_34(self):
  419. order_info = self.event_data.get('order')
  420. order_id = order_info.get('id')
  421. fun_code = self.event_data.get('fun_code')
  422. if (time.time() - order_info.get('create_time', 0)) < 300 and order_info.get('order_type') == 'apps_start':
  423. return
  424. if fun_code == 32:
  425. self.deviceAdapter.do_ack_order_32(order_id)
  426. elif fun_code == 34:
  427. self.deviceAdapter.do_ack_remove_order_from_device_34(order_id)
  428. else:
  429. pass
  430. def save_upload_log(self):
  431. order_info = self.event_data.get('order')
  432. order_info = deepcopy(order_info)
  433. order_info['order_id'] = order_info.pop('id')
  434. DeviceUploadInfo(**order_info).save()
  435. def response_the_link(self):
  436. qr_code_url = concat_user_login_entry_url(l=self.device['logicalCode'])
  437. data = {
  438. 'fun_code': 45,
  439. 'qrcode': qr_code_url
  440. }
  441. self.deviceAdapter.send_mqtt(data)
  442. def record_consume_for_card(self, card, money, desc=u'', servicedInfo=None, sid=None, attachParas=None):
  443. servicedInfo = {} if servicedInfo is None else servicedInfo
  444. attachParas = {} if attachParas is None else attachParas
  445. group = Group.get_group(self.device['groupId'])
  446. address = group['address']
  447. group_number = self.device['groupNumber']
  448. now = datetime.datetime.now()
  449. sequanceNo = attachParas.get('sequanceNo')
  450. new_record = {
  451. 'orderNo': ConsumeRecord.make_no(card.cardNo, UserConsumeSubType.CARD),
  452. 'time': now.strftime('%Y-%m-%d %H:%M:%S'),
  453. 'dateTimeAdded': now,
  454. 'openId': card.openId,
  455. 'ownerId': self.device['ownerId'],
  456. 'coin': money.mongo_amount,
  457. 'money': money.mongo_amount,
  458. 'devNo': self.device['devNo'],
  459. 'logicalCode': self.device['logicalCode'],
  460. 'groupId': self.device['groupId'],
  461. 'address': address,
  462. 'groupNumber': group_number,
  463. 'groupName': group['groupName'],
  464. 'devTypeCode': self.device.devTypeCode,
  465. 'devTypeName': self.device.devTypeName,
  466. 'isNormal': True,
  467. 'status': ConsumeRecord.Status.RUNNING,
  468. 'remarks': u'刷卡消费',
  469. 'errorDesc': '',
  470. 'sequanceNo': sequanceNo,
  471. 'desc': desc,
  472. 'attachParas': attachParas,
  473. 'servicedInfo': servicedInfo
  474. }
  475. order = ConsumeRecord.objects.create(**new_record)
  476. # 刷卡消费也记录一条数据
  477. new_card_record = {
  478. 'orderNo': new_record['orderNo'],
  479. 'openId': card.openId,
  480. 'cardId': str(card.id),
  481. 'money': money.mongo_amount,
  482. 'balance': card.balance.mongo_amount,
  483. 'devNo': self.device['devNo'],
  484. 'devType': self.device['devType']['name'],
  485. 'logicalCode': self.device['logicalCode'],
  486. 'groupId': self.device['groupId'],
  487. 'address': address,
  488. 'groupNumber': group_number,
  489. 'groupName': group['groupName'],
  490. 'result': 'success',
  491. 'remarks': u'刷卡消费',
  492. 'sequanceNo': '',
  493. 'dateTimeAdded': datetime.datetime.now(),
  494. 'desc': desc,
  495. 'servicedInfo': servicedInfo,
  496. 'linkedConsumeRcdOrderNo': str(new_record['orderNo'])
  497. }
  498. if sid is not None:
  499. new_card_record.update({'sid': sid})
  500. card_order = CardConsumeRecord.objects.create(**new_card_record)
  501. return order, card_order
  502. def price_rule_change(self):
  503. pass
  504. class ChargingWeiFuLeCarFaultEvent(FaultEvent):
  505. def do(self, **args):
  506. # 40温度告警/41电流超限/42电压超限/43功率过载
  507. group = Group.get_group(self.device['groupId'])
  508. fun_code = self.event_data.get('fun_code')
  509. if fun_code == 40:
  510. item = self.event_data.get('temp')
  511. faultName = r'设备火灾预警'
  512. desc = r'主板上报设备过热,设备温度超限(设备温度:{} 度)'.format(item)
  513. title = r'告警名称:\t\t{}\n\n地址名称:\t\t{}-{}\n'.format(faultName, group['address'], group['groupName'])
  514. elif fun_code == 41:
  515. item = self.event_data.get('ampr')
  516. faultName = r'设备电流超过最大限制'
  517. desc = r'主板上报电流超限,设备电流超限(设备电流:{} 安)'.format(item)
  518. title = r'告警名称:\t\t{}\n\n地址名称:\t\t{}-{}\n'.format(faultName, group['address'], group['groupName'])
  519. elif fun_code == 42:
  520. item = self.event_data.get('volt')
  521. faultName = r'设备电压超过最限制'
  522. desc = r'主板上报电压超限,设备电压超限(设备电压:{} 伏)'.format(item)
  523. title = r'告警名称:\t\t{}\n\n地址名称:\t\t{}-{}\n'.format(faultName, group['address'], group['groupName'])
  524. elif fun_code == 43:
  525. item = self.event_data.get('watt')
  526. faultName = r'设备功率超过最限制'
  527. desc = r'主板上报功率超限,设备功率超限(设备电压:{} 瓦)'.format(item)
  528. title = r'告警名称:\t\t{}\n\n地址名称:\t\t{}-{}\n'.format(faultName, group['address'], group['groupName'])
  529. else:
  530. return
  531. self.notify_dealer(
  532. templateName='device_fault',
  533. title=title,
  534. device=r'{}号设备({})\n'.format(self.device['groupNumber'], self.device['logicalCode']),
  535. location=r'设备告警\n',
  536. notifyTime=desc + r'\n',
  537. fault=r'%s\n' % datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  538. )
  539. self.record(
  540. faultCode=self.event_data.get('FaultCode'),
  541. description=desc,
  542. title=faultName,
  543. level=self.event_data.get('level', FAULT_LEVEL.NORMAL),
  544. # detail=self.event_data.get('statusInfo'),
  545. )