weifule_car_21kw.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  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
  10. from apilib.utils_sys import memcache_lock
  11. from apps.web.constant import FAULT_LEVEL
  12. from apps.web.device.models import DeviceUploadInfo, Group
  13. from apps.web.eventer import EventBuilder
  14. from apps.web.eventer.base import WorkEvent, FaultEvent
  15. from apps.web.eventer.weifuleCommon import WeiFuLeStatusEvent, WeiFuLeCarProcess
  16. from apps.web.user.models import ConsumeRecord, CardConsumeRecord, Card
  17. from apps.web.user.models import CardRechargeOrder
  18. from apps.web.utils import concat_user_login_entry_url
  19. if TYPE_CHECKING:
  20. pass
  21. logger = logging.getLogger(__name__)
  22. def log_obj(obj):
  23. obj = deepcopy(obj)
  24. if isinstance(obj, dict):
  25. for k, v in obj.items():
  26. if isinstance(v, object):
  27. obj[k] = str(v)
  28. if isinstance(obj, list) or isinstance(obj, tuple) or isinstance(obj, set):
  29. obj = map(lambda x: str(x) if isinstance(x, object) else x, obj)
  30. if isinstance(obj, unicode):
  31. obj = str(obj)
  32. # print('\33[33m' + json.dumps(obj,ensure_ascii=True,encoding='utf-8') + '\33[0m')
  33. return '\33[33m' + json.dumps(obj, ensure_ascii=False, encoding='utf-8') + '\33[0m'
  34. card_is_normal = 1
  35. card_not_in_db = 2
  36. card_is_forzen = 3
  37. card_has_not_order = 4 # IC卡适用
  38. class builder(EventBuilder):
  39. def __getEvent__(self, device_event):
  40. logger.info('reve event, event_data:{}'.format(log_obj(device_event)))
  41. event_data = device_event.get('data')
  42. fun_code = event_data.get('fun_code')
  43. if not event_data:
  44. return
  45. if event_data['fun_code'] in [44]:
  46. return WeiFuLeStatusEvent(self.deviceAdapter, device_event)
  47. if fun_code in [40, 41, 42, 43]: # 40温度告警/41电流超限/42电压超限/43功率过载
  48. return ChargingWeiFuLeCarFaultEvent(self.deviceAdapter, event_data)
  49. else:
  50. return ChargingWeiFuLeCarWorkEvent(self.deviceAdapter, event_data)
  51. class ChargingWeiFuLeCarWorkEvent(WorkEvent):
  52. def do(self, **args):
  53. fun_code = self.event_data.get('fun_code')
  54. order_id = self.event_data.get('order', {}).get('id')
  55. key = '{}.{}.event'.format(self.device.devNo, order_id)
  56. if fun_code == 37: # 处理卡充值
  57. self.deal_with_ic_charge_event()
  58. elif fun_code == 44: # 上报结束后的状态
  59. pass
  60. elif fun_code == 45: # 上传要链接
  61. self.response_the_link()
  62. else:
  63. with memcache_lock(key=key, value='1', expire=15) as acquired:
  64. if acquired:
  65. if fun_code == 32 or fun_code == 34 or fun_code == 33:
  66. self._do_order_change_event_32_33_34()
  67. self._do_ack_order_32_or_remove_order_from_device_34()
  68. else:
  69. logger.debug('fun_code<{}> is doing. cache_key:{}'.format(repr(fun_code), key))
  70. return
  71. def deal_with_ic_charge_event(self):
  72. cardNo = self.event_data.get('card_no')
  73. card = Card.objects.filter(cardNo=cardNo, cardType='IC', dealerId=self.device.ownerId).first()
  74. logger.info(log_obj('Start card recharge operation'))
  75. if not card:
  76. logger.info(log_obj('Start card recharge operation --> no such card !!! '))
  77. return self.deviceAdapter.send_mqtt({
  78. 'fun_code': 37,
  79. 'card_no': cardNo,
  80. 'result': card_not_in_db,
  81. })
  82. elif card.frozen:
  83. logger.info(log_obj('Start card recharge operation --> card is frozen !!! '))
  84. return self.deviceAdapter.send_mqtt({
  85. 'fun_code': 37,
  86. 'card_no': cardNo,
  87. 'result': card_is_forzen,
  88. })
  89. rechargeOrder = CardRechargeOrder.get_last_to_do_one(str(card.id))
  90. if rechargeOrder:
  91. preBalance = RMB(self.event_data.get('balance', 0) / 100.0)
  92. logger.info(log_obj('Start card recharge operation --> to recharg rechargeAmount:{}'.format(preBalance)))
  93. self.recharge_ic_card(card=card,
  94. preBalance=preBalance,
  95. rechargeType='append',
  96. order=rechargeOrder,
  97. need_verify=False)
  98. else:
  99. logger.info(log_obj('Start card recharge operation --> no rechargeOrder !! '))
  100. self.deviceAdapter.send_mqtt({
  101. 'card_no': cardNo,
  102. 'fun_code': 37,
  103. 'result': card_has_not_order,
  104. })
  105. def _do_order_change_event_32_33_34(self):
  106. order_info = self.event_data.get('order')
  107. if not order_info:
  108. logger.info(log_obj('no order info,do over!!'))
  109. else:
  110. order_processing = WeiFuLeCarProcess(self)
  111. order_type = order_info.get('order_type')
  112. self.save_upload_log()
  113. if hasattr(order_processing, order_type):
  114. event = getattr(order_processing, order_type)
  115. try:
  116. event()
  117. except Exception:
  118. import traceback
  119. logger.info(traceback.format_exc())
  120. else:
  121. logger.info(log_obj('no this order_type'))
  122. def _do_ack_order_32_or_remove_order_from_device_34(self):
  123. order_info = self.event_data.get('order')
  124. order_id = order_info.get('id')
  125. fun_code = self.event_data.get('fun_code')
  126. if (time.time() - order_info.get('create_time', 0)) < 300 and order_info.get('order_type') == 'apps_start':
  127. return
  128. if fun_code == 32:
  129. self.deviceAdapter.do_ack_order_32(order_id)
  130. elif fun_code == 34:
  131. self.deviceAdapter.do_ack_remove_order_from_device_34(order_id)
  132. else:
  133. pass
  134. def save_upload_log(self):
  135. order_info = self.event_data.get('order')
  136. order_info = deepcopy(order_info)
  137. order_info['order_id'] = order_info.pop('id')
  138. DeviceUploadInfo(**order_info).save()
  139. def response_the_link(self):
  140. qr_code_url = concat_user_login_entry_url(l=self.device['logicalCode'])
  141. data = {
  142. 'fun_code': 45,
  143. 'qrcode': qr_code_url
  144. }
  145. self.deviceAdapter.send_mqtt(data)
  146. def record_consume_for_card(self, card, money, desc=u'', servicedInfo=None, sid=None, attachParas=None):
  147. servicedInfo = {} if servicedInfo is None else servicedInfo
  148. attachParas = {} if attachParas is None else attachParas
  149. group = Group.get_group(self.device['groupId'])
  150. address = group['address']
  151. group_number = self.device['groupNumber']
  152. now = datetime.datetime.now()
  153. orderNo = attachParas.get('orderNo')
  154. new_record = {
  155. 'orderNo': orderNo,
  156. 'time': now.strftime('%Y-%m-%d %H:%M:%S'),
  157. 'dateTimeAdded': now,
  158. 'openId': card.openId,
  159. 'ownerId': self.device['ownerId'],
  160. 'coin': money.mongo_amount,
  161. 'money': money.mongo_amount,
  162. 'devNo': self.device['devNo'],
  163. 'logicalCode': self.device['logicalCode'],
  164. 'groupId': self.device['groupId'],
  165. 'address': address,
  166. 'groupNumber': group_number,
  167. 'groupName': group['groupName'],
  168. 'devTypeCode': self.device.devTypeCode,
  169. 'devTypeName': self.device.devTypeName,
  170. 'isNormal': True,
  171. 'status': ConsumeRecord.Status.RUNNING,
  172. 'remarks': u'刷卡消费',
  173. 'errorDesc': '',
  174. 'sequanceNo': '',
  175. 'desc': desc,
  176. 'attachParas': attachParas,
  177. 'servicedInfo': servicedInfo
  178. }
  179. ConsumeRecord.get_collection().insert_one(new_record)
  180. # 刷卡消费也记录一条数据
  181. new_card_record = {
  182. 'orderNo': orderNo,
  183. 'openId': card.openId,
  184. 'cardId': str(card.id),
  185. 'money': money.mongo_amount,
  186. 'balance': card.balance.mongo_amount,
  187. 'devNo': self.device['devNo'],
  188. 'devType': self.device['devType']['name'],
  189. 'logicalCode': self.device['logicalCode'],
  190. 'groupId': self.device['groupId'],
  191. 'address': address,
  192. 'groupNumber': group_number,
  193. 'groupName': group['groupName'],
  194. 'result': 'success',
  195. 'remarks': u'刷卡消费',
  196. 'sequanceNo': '',
  197. 'dateTimeAdded': datetime.datetime.now(),
  198. 'desc': desc,
  199. 'servicedInfo': servicedInfo,
  200. 'linkedConsumeRcdOrderNo': str(new_record['orderNo'])
  201. }
  202. if sid is not None:
  203. new_card_record.update({'sid': sid})
  204. CardConsumeRecord.get_collection().insert(new_card_record)
  205. return new_record['orderNo'], new_card_record['orderNo']
  206. class ChargingWeiFuLeCarFaultEvent(FaultEvent):
  207. def do(self, **args):
  208. # 40温度告警/41电流超限/42电压超限/43功率过载
  209. group = Group.get_group(self.device['groupId'])
  210. fun_code = self.event_data.get('fun_code')
  211. if fun_code == 40:
  212. item = self.event_data.get('temp')
  213. faultName = r'设备火灾预警'
  214. desc = r'主板上报设备过热,设备温度超限(设备温度:{} 度)'.format(item)
  215. title = r'告警名称:\t\t{}\n\n地址名称:\t\t{}-{}\n'.format(faultName, group['address'], group['groupName'])
  216. elif fun_code == 41:
  217. item = self.event_data.get('ampr')
  218. faultName = r'设备电流超过最大限制'
  219. desc = r'主板上报电流超限,设备电流超限(设备电流:{} 安)'.format(item)
  220. title = r'告警名称:\t\t{}\n\n地址名称:\t\t{}-{}\n'.format(faultName, group['address'], group['groupName'])
  221. elif fun_code == 42:
  222. item = self.event_data.get('volt')
  223. faultName = r'设备电压超过最限制'
  224. desc = r'主板上报电压超限,设备电压超限(设备电压:{} 伏)'.format(item)
  225. title = r'告警名称:\t\t{}\n\n地址名称:\t\t{}-{}\n'.format(faultName, group['address'], group['groupName'])
  226. elif fun_code == 43:
  227. item = self.event_data.get('watt')
  228. faultName = r'设备功率超过最限制'
  229. desc = r'主板上报功率超限,设备功率超限(设备电压:{} 瓦)'.format(item)
  230. title = r'告警名称:\t\t{}\n\n地址名称:\t\t{}-{}\n'.format(faultName, group['address'], group['groupName'])
  231. else:
  232. return
  233. self.notify_dealer(
  234. templateName='device_fault',
  235. title=title,
  236. device=r'{}号设备({})\n'.format(self.device['groupNumber'], self.device['logicalCode']),
  237. location=r'设备告警\n',
  238. notifyTime=desc + r'\n',
  239. fault=r'%s\n' % datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  240. )
  241. self.record(
  242. faultCode=self.event_data.get('FaultCode'),
  243. description=desc,
  244. title=faultName,
  245. level=self.event_data.get('level', FAULT_LEVEL.NORMAL),
  246. # detail=self.event_data.get('statusInfo'),
  247. )