check_command_XmSgj.py 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646
  1. import asyncio
  2. import datetime
  3. import hashlib
  4. import json
  5. import sys
  6. import threading
  7. import time
  8. from collections import namedtuple
  9. from concurrent.futures import ThreadPoolExecutor
  10. import requests
  11. sys.path.append("..")
  12. import pymysql
  13. import logging
  14. import uuid
  15. import chardet
  16. import message_pb2 as message
  17. import google.protobuf.text_format as tf
  18. import http_client
  19. import mytool.db_helper.db_operation as spmng
  20. MeasureStatu = {"ok": message.MeasureStatu.Value('Measure_OK'),
  21. "无数据": message.MeasureStatu.Value('Measure_Empty_Clouds'),
  22. "噪声": message.MeasureStatu.Value('Measure_Failture'),
  23. "PLC超界": message.MeasureStatu.Value('Measure_Border'),
  24. "终端超界": message.MeasureStatu.Value('Measure_Terminal_Border'),
  25. "失去连接": message.MeasureStatu.Value('Lidar_Disconnect')
  26. }
  27. Range_status = {"未超界": message.Range_status.Value('Range_correct'),
  28. "前超界": message.Range_status.Value('Range_front'),
  29. "后超界": message.Range_status.Value('Range_back'),
  30. "左超界": message.Range_status.Value('Range_left'),
  31. "右超界": message.Range_status.Value('Range_right'),
  32. "底盘超界": message.Range_status.Value('Range_bottom'),
  33. "车顶超界": message.Range_status.Value('Range_top'),
  34. "车宽超界": message.Range_status.Value('Range_car_width'),
  35. "轴距超界": message.Range_status.Value('Range_car_wheelbase'),
  36. "左旋转超界": message.Range_status.Value('Range_angle_anti_clock'),
  37. "右旋转超界": message.Range_status.Value('Range_angle_clock'),
  38. "方向盘未回正": message.Range_status.Value('Range_steering_wheel_nozero'),
  39. "车辆移动": message.Range_status.Value('Range_car_moving')
  40. }
  41. class CommandChecker:
  42. def __init__(self, db_config):
  43. self.db = spmng.DBOperation(db_config['db_ip'], db_config['db_port'], db_config['db_name'],
  44. db_config['db_user'], db_config['db_password'])
  45. self._dispatch_statu = {}
  46. self._measure_statu = {}
  47. self.push_pickqueue_thread = threading.Thread(target=self.push_pickqueue)
  48. # 入场推送地址
  49. self._in_url = 'http://szdy.xmsztc.cn/Api/CarInEntry'
  50. # 查询推送地址
  51. self._query_url = 'http://szdy.xmsztc.cn/Api/GetBill'
  52. # 出场推送地址
  53. self._out_url = 'http://szdy.xmsztc.cn/Api/CarOutEntry'
  54. # 手机端出场推送地址
  55. self._out_url_phone = 'https://sztc.xmsztc.cn/api/operateOutScene/sgjOutSceneRecord'
  56. # self._out_url_phone = 'https://sztc.smartcityxm.com/api/operateOutScene/sgjOutSceneRecord' #测试环境
  57. # 余位
  58. self._park_surplus_url = 'https://sztc.xmsztc.cn/api/basicPark/sgjParkSurplus'
  59. # self._park_surplus_url = 'https://sztc.smartcityxm.com/api/basicPark/sgjParkSurplus' # 测试环境
  60. # 公众号
  61. self._queue_url = 'https://sztc.xmsztc.cn/api/operateOutScene/sgjSendPickUpMsg'
  62. # self._queue_url = 'https://sztc.smartcityxm.com/api/operateOutScene/sgjSendPickUpMsg' # 测试环境
  63. # 手机端appid
  64. self._app_id_phone = '20230412151327035'
  65. # 手机端app秘钥
  66. self._appSecret_phone = 'Dl8gh4GGspOu9UU7YW00b55wE93ga6aF'
  67. # 云端秘钥
  68. self._secret_key = 'anzs74aph8ac8dy6tj48t05js6zpkgx5'
  69. # 车场ID
  70. self._parking_id = '2306041414159951342'
  71. # 云端appid
  72. self._app_id = 'blbc5zkpyymaicd3'
  73. # 云端主地址
  74. self._http = 'https://sztc.smartcityxm.com/wechath5/#/pagesA/parkingBill/inrecord_parking?inRecordId='
  75. self.chnnId_in = {11: '2307241522121721333', 12: '2306041439573931681', 13: '2307241531240571925',
  76. 14: '2307241534030091638'
  77. , 21: '2307241536315471441', 22: '2307211200055462502', 23: '2307241540369691638',
  78. 24: '2307241549404491178', 25: '2307211153450762758'
  79. , 31: '2307241552306981925', 32: '2307241554369581606'}
  80. self.chnnId_out = {11: '2307241523438171745', 12: '2306041441029631932', 13: '2307241532575281334',
  81. 14: '2307241534536081930'
  82. , 21: '2307241538324701014', 22: '2307211201229402651', 23: '2307241542527281313',
  83. 24: '2307241550388621477', 25: '2307211155130692935'
  84. , 31: '2307241553191751202', 32: '2307241555230551872'}
  85. self._plate_color = {'蓝色': '1', '黑色': '2', '黄色': '3', '白色': '4', '绿色': '5', '其他': '6'}
  86. self.push_pickqueue_thread.start()
  87. def get_in_url(self):
  88. return self._in_url
  89. def receive_dispatch_statu(self, statu, ex, key):
  90. self._dispatch_statu[key] = statu
  91. def receive_measure_info(self, statu, ex, key):
  92. self._measure_statu[key] = statu
  93. # 给收费系统推送请求
  94. def push_http_request(self, url, request, headers=None):
  95. results = ''
  96. statu = message.eError
  97. tm = time.time()
  98. # 若推送失败就重试最多2s
  99. while time.time() - tm < 2:
  100. try:
  101. print("请求地址:" + url)
  102. if url != self._in_url:
  103. print("请求内容:" + str(request))
  104. resp = requests.post(url, json=request, headers=headers, timeout=2).json()
  105. print("请求答复:" + str(resp) + '\n')
  106. if (('Tag' in resp.keys()) and resp['Tag'] == 1) or \
  107. (('code' in resp.keys()) and resp['code'] == 0):
  108. statu = message.eNormal
  109. results = resp
  110. break
  111. else:
  112. statu = message.eError
  113. results = '收费系统反馈错误!message:%s' % resp
  114. except Exception as e:
  115. statu = message.eError
  116. results = '向收费系统推送请求失败! ERROR:%s' % (str(e.args))
  117. time.sleep(0.2)
  118. return statu, results
  119. # 检查存车指令
  120. def entrance_isOK(self, park_body):
  121. # 停车表单
  122. park_table = message.park_table()
  123. try:
  124. tf.Parse(park_body, park_table)
  125. except Exception as e:
  126. park_table.statu.execute_statu = message.eError
  127. park_table.statu.statu_description = "设备故障,请联系管理员!" + "(停车表单错误)" + str(e.args)
  128. return park_table
  129. # 检查调度状态
  130. dispatch_key = "dispatch_%d_statu_port" % park_table.unit_id
  131. if (dispatch_key in self._dispatch_statu) is False or self._dispatch_statu[dispatch_key].timeout():
  132. park_table.statu.execute_statu = message.eError
  133. park_table.statu.statu_description = "设备故障,请联系管理员!" + "(调度)"
  134. return park_table
  135. # 获取车高信息
  136. dispatch_node_statu = message.dispatch_node_statu()
  137. try:
  138. tf.Parse(self._dispatch_statu[dispatch_key].statu, dispatch_node_statu)
  139. except Exception:
  140. park_table.statu.execute_statu = message.eError
  141. park_table.statu.statu_description = "设备故障,请联系管理员!" + "(调度状态消息错误)"
  142. return park_table
  143. # 判断搬运器状态
  144. if dispatch_node_statu.plc_carrier_status == 0:
  145. park_table.statu.execute_statu = message.eError
  146. park_table.statu.statu_description = "设备故障,请联系管理员!" + "(搬运器)"
  147. return park_table
  148. dispatch_plc_passway_status = dispatch_node_statu.dispatch_plc_passway_status_vector[park_table.import_id - 1]
  149. # 检查入口状态
  150. if dispatch_node_statu.plc_carrier_status == 4 or dispatch_plc_passway_status.plc_passway_enable == 2:
  151. park_table.statu.execute_statu = message.eWarning
  152. park_table.statu.statu_description = "该单元设备维护中!请前往其他入口!"
  153. return park_table
  154. if dispatch_plc_passway_status.car_height == 0:
  155. park_table.statu.execute_statu = message.eWarning
  156. park_table.statu.statu_description = "未检测到车辆!"
  157. return park_table
  158. elif dispatch_plc_passway_status.car_height == 4:
  159. park_table.statu.execute_statu = message.eWarning
  160. park_table.statu.statu_description = "车辆超高,请退出车库!"
  161. return park_table
  162. sensor_1 = dispatch_plc_passway_status.sensor_1
  163. sensor_2 = dispatch_plc_passway_status.sensor_2
  164. if park_table.unit_id != 31 and park_table.unit_id != 32:
  165. if (sensor_2 >> 3) & 0x01 != 1 or (sensor_2 >> 4) & 0x01 != 1:
  166. park_table.statu.execute_statu = message.eWarning
  167. park_table.statu.statu_description = "车辆未停到位,请根据库内指示灯挪车!"
  168. return park_table
  169. if (sensor_1 >> 2) & 0x01 != 1:
  170. park_table.statu.execute_statu = message.eWarning
  171. park_table.statu.statu_description = "车辆超限,请联系现场工作人员!"
  172. return park_table
  173. if (sensor_1 >> 3) & 0x01 != 1:
  174. park_table.statu.execute_statu = message.eWarning
  175. park_table.statu.statu_description = "车辆后超界,请往前!"
  176. return park_table
  177. if (sensor_1 >> 4) & 0x01 != 1:
  178. park_table.statu.execute_statu = message.eWarning
  179. park_table.statu.statu_description = "车辆前超界,请往后!"
  180. return park_table
  181. if (sensor_1 >> 5) & 0x01 != 1:
  182. park_table.statu.execute_statu = message.eWarning
  183. park_table.statu.statu_description = "车辆左超界,请往右!"
  184. return park_table
  185. if (sensor_1 >> 6) & 0x01 != 1:
  186. park_table.statu.execute_statu = message.eWarning
  187. park_table.statu.statu_description = "车辆右超界,请往左!"
  188. return park_table
  189. measure_buffer = message.measure_buffer()
  190. measure_info_to_terminal = message.measure_info()
  191. measure_info_to_plc_reverse = message.measure_info()
  192. measure_info_to_plc_forward = message.measure_info()
  193. if park_table.unit_id == 31 or park_table.unit_id == 32:
  194. measure_key = "measure_%d_statu_port" % park_table.terminal_id
  195. if (measure_key in self._measure_statu) is False or self._measure_statu[measure_key].timeout():
  196. park_table.statu.execute_statu = message.eError
  197. park_table.statu.statu_description = "设备故障,请联系管理员!" + "(雷达)"
  198. return park_table
  199. # 获取车高信息
  200. try:
  201. tf.Parse(self._measure_statu[measure_key].statu, measure_buffer)
  202. measure_info_to_terminal.CopyFrom(measure_buffer.measure_info_to_terminal)
  203. measure_info_to_plc_reverse.CopyFrom(measure_buffer.measure_info_to_plc_reverse)
  204. measure_info_to_plc_forward.CopyFrom(measure_buffer.measure_info_to_plc_forward)
  205. except Exception:
  206. park_table.statu.execute_statu = message.eError
  207. park_table.statu.statu_description = "设备故障,请联系管理员!" + "(雷达状态消息错误)"
  208. return park_table
  209. # 获取雷达信息
  210. tm = time.time()
  211. while time.time() - tm < 2:
  212. park_table.entrance_measure_info.CopyFrom(measure_buffer)
  213. # 没有超界。车为静止状态。
  214. # if measure_info.border_statu == MeasureStatu["ok"] and measure_info.ground_status == 0 and measure_info.motion_statu == 1:
  215. if measure_info_to_terminal.border_statu == Range_status["未超界"] and \
  216. measure_info_to_terminal.ground_status == MeasureStatu["ok"] and \
  217. measure_info_to_plc_reverse.border_statu == Range_status["未超界"] and \
  218. measure_info_to_plc_reverse.ground_status == MeasureStatu["ok"] and \
  219. measure_info_to_plc_forward.border_statu == Range_status["未超界"] and \
  220. measure_info_to_plc_forward.ground_status == MeasureStatu["ok"]:
  221. park_table.statu.execute_statu = message.eNormal
  222. break
  223. else:
  224. park_table.statu.execute_statu = message.eError
  225. if self._measure_statu[measure_key].statu is not None and self._measure_statu[
  226. measure_key].timeout() is False:
  227. try:
  228. measure_buffer = message.measure_buffer()
  229. measure_info_to_terminal = message.measure_info()
  230. tf.Parse(self._measure_statu[measure_key].statu, measure_buffer)
  231. measure_info_to_terminal.CopyFrom(measure_buffer.measure_info_to_terminal)
  232. measure_info_to_plc_reverse.CopyFrom(measure_buffer.measure_info_to_plc_reverse)
  233. measure_info_to_plc_forward.CopyFrom(measure_buffer.measure_info_to_plc_forward)
  234. # print("check measure info again:", measure_info)
  235. except:
  236. print("parse exception:\n" + self._measure_statu[measure_key].statu)
  237. time.sleep(0.1)
  238. if park_table.statu.execute_statu == message.eError:
  239. if measure_info_to_terminal.ground_status == MeasureStatu["ok"] or \
  240. measure_info_to_plc_reverse.ground_status == MeasureStatu["ok"] or \
  241. measure_info_to_plc_forward.ground_status == MeasureStatu["ok"]:
  242. park_table.statu.statu_description = "雷达状态异常!"
  243. elif measure_info_to_terminal.ground_status == MeasureStatu["终端超界"] or \
  244. measure_info_to_plc_reverse.ground_status == MeasureStatu["PLC超界"] or \
  245. measure_info_to_plc_forward.ground_status == MeasureStatu["PLC超界"]:
  246. park_table.statu.statu_description = "请按提示调整!"
  247. elif measure_info_to_terminal.ground_status == MeasureStatu["失去连接"] or \
  248. measure_info_to_plc_reverse.ground_status == MeasureStatu["失去连接"] or \
  249. measure_info_to_plc_forward.ground_status == MeasureStatu["失去连接"]:
  250. park_table.statu.statu_description = "设备故障,请联系管理员! (雷达)"
  251. else:
  252. park_table.statu.statu_description = "请检查库内是否有异物!"
  253. print(" MeasureInfo:\n " + tf.MessageToString(measure_info_to_terminal, as_utf8=True))
  254. return park_table
  255. # 填写车高信息
  256. height = dispatch_plc_passway_status.car_height
  257. # 赋值唯一码
  258. uid = str(uuid.uuid1())
  259. park_table.primary_key = uid
  260. # 查询黑名单
  261. print("----------------------------查询黑名单-----------------------------" + str(datetime.datetime.now()))
  262. blacklist_res = self.db.query_blacklist_in_car_number(park_table.car_number)
  263. blacklist_count = len(blacklist_res)
  264. if blacklist_count > 0:
  265. park_table.statu.execute_statu = message.eWarning
  266. park_table.statu.statu_description = "车辆 :%s 车辆超限,请退出!" % park_table.car_number
  267. return park_table
  268. # 查询车位表和指令表是否有该车
  269. print("----------------------------查询车位表-----------------------------" + str(datetime.datetime.now()))
  270. space_res = self.db.query_space_in_car_number(park_table.car_number)
  271. space_count = len(space_res)
  272. if space_count > 0:
  273. park_table.statu.execute_statu = message.eWarning
  274. park_table.statu.statu_description = "车辆 :%s 已在库内!" % park_table.car_number
  275. return park_table
  276. print("----------------------------查询指令表-----------------------------" + str(datetime.datetime.now()))
  277. command_res = self.db.query_command_in_car_number(park_table.car_number)
  278. command_count = len(command_res)
  279. if command_count > 0:
  280. park_table.statu.execute_statu = message.eWarning
  281. park_table.statu.statu_description = "指令正在执行中!请稍等!"
  282. return park_table
  283. # 车辆不在库内 查询是否有对应大小空车位
  284. print("----------------------------查询空车位-----------------------------" + str(datetime.datetime.now()))
  285. space_empty_res = self.db.query_space_in_height_level_wheel_base_unit_and_empty(height,
  286. measure_info_to_terminal.wheelbase,
  287. park_table.unit_id)
  288. space_empty_count = len(space_empty_res)
  289. if space_empty_count <= 0:
  290. park_table.statu.execute_statu = message.eWarning
  291. park_table.statu.statu_description = "没有空余的合适车位,车牌号:%s 高度等级:%d 轴距:%.3fm!" % (
  292. park_table.car_number, height, measure_info_to_terminal.wheelbase)
  293. else:
  294. # 查询是否在白名单
  295. print("----------------------------查询白名单-----------------------------" + str(datetime.datetime.now()))
  296. whitelist_res = self.db.query_whitelist_in_car_number(park_table.car_number)
  297. if len(whitelist_res) <= 0:
  298. # 向收费系统推送入场信息
  299. print(
  300. "----------------------------推送入场-----------------------------" + str(datetime.datetime.now()))
  301. in_dict = self.get_cloud_request_data(park_table, 'in')
  302. headers_dict, park_surplus_dict, pickup_queue_dict, phone_out_dict = self.get_phone_request_data(
  303. park_table.car_number, park_table.primary_key, park_table.unit_id, 'in')
  304. statu, response = self.push_http_request(self._in_url, in_dict)
  305. print(
  306. "----------------------------推送余位-----------------------------" + str(datetime.datetime.now()))
  307. self.push_http_request(self._park_surplus_url, park_surplus_dict, headers_dict)
  308. if statu != message.eNormal:
  309. park_table.statu.execute_statu = statu
  310. park_table.statu.statu_description = response
  311. else:
  312. if ('Data' in response.keys()) and ('InPicUrl' in response['Data'].keys()):
  313. park_table.car_number_info.plate_full_image = response['Data']['InPicUrl']
  314. park_table.car_number_info.plate_clip_image = response['Data']['InPlateUrl']
  315. else:
  316. park_table.statu.execute_statu = message.eError
  317. park_table.statu.statu_description = "收费系统答复错误!请联系管理员!"
  318. else:
  319. print("----------------------------白名单车辆-----------------------------" + str(
  320. datetime.datetime.now()))
  321. return park_table
  322. # 检查取车指令
  323. def exit_isOK(self, pick_body):
  324. pick_table = message.pick_table()
  325. try:
  326. tf.Parse(pick_body, pick_table)
  327. except Exception as e:
  328. pick_table.statu.execute_statu = message.eError
  329. pick_table.statu.statu_description = "设备故障,请联系管理员!" + "(取车表单错误)" + str(e.args)
  330. return pick_table
  331. if pick_table.primary_key is None or pick_table.primary_key == '':
  332. pick_table.statu.execute_statu = message.eWarning
  333. pick_table.statu.statu_description = " 唯一码不能为空!"
  334. else:
  335. # 查询车位表和指令表是否有该车
  336. print("****************************查询车位表****************************" + str(datetime.datetime.now()))
  337. space_res = self.db.query_space_in_primary_key(pick_table.primary_key)
  338. space_count = len(space_res)
  339. print(
  340. "****************************查询停车指令表****************************" + str(datetime.datetime.now()))
  341. command_res_park = self.db.query_park_command_in_primary_key(pick_table.primary_key)
  342. command_count_park = len(command_res_park)
  343. if space_count <= 0 and command_count_park <= 0:
  344. pick_table.statu.execute_statu = message.eWarning
  345. pick_table.statu.statu_description = "车辆信息不存在!"
  346. return pick_table
  347. print(
  348. "****************************查询取车指令表****************************" + str(datetime.datetime.now()))
  349. command_res = self.db.query_pick_command_in_primary_key(pick_table.primary_key)
  350. command_count = len(command_res)
  351. if command_count > 0:
  352. pick_table.unit_id = space_res[0]['unit']
  353. t_unit_str = self.get_unit_str(pick_table.unit_id)
  354. # 重复取车,提示成功,流程失败!
  355. pick_table.statu.execute_statu = message.eWarning
  356. pick_table.statu.statu_description = "取车成功!请前往 << %s >> 单元出口等待车辆,观看大屏幕提示取车!" % t_unit_str
  357. return pick_table
  358. pick_table.statu.execute_statu = message.eNormal
  359. pick_table.statu.statu_description = "取车成功,请观看大屏幕提示取车!"
  360. # 完善表单信息
  361. try:
  362. try:
  363. pick_table.car_number = space_res[0]['car_number']
  364. pick_table.unit_id = space_res[0]['unit']
  365. except Exception as e:
  366. pick_table.car_number = command_res_park[0]['car_number']
  367. pick_table.unit_id = command_res_park[0]['unit']
  368. print("车为表未找到,使用指令表结果")
  369. pick_table.car_number_info.plate_color = space_res[0]['plate_color']
  370. pick_table.car_number_info.plate_type = space_res[0]['plate_type']
  371. pick_table.car_number_info.plate_confidence = space_res[0]['plate_confidence']
  372. pick_table.car_number_info.recognition_time = space_res[0]['recognition_time']
  373. pick_table.car_number_info.plate_full_image = ''
  374. pick_table.car_number_info.plate_clip_image = ''
  375. except Exception as e:
  376. print("数据库信息不全,缺失号牌颜色等信息!")
  377. # 强制取车 或 虚拟取车
  378. if pick_table.statu.table_process_mod == message.PROCESS_ONLY_TO_DISPATCH or pick_table.statu.table_process_mod == message.PROCESS_ONLY_TO_PAY:
  379. # if pick_table.unit_id != 31 and pick_table.unit_id != 32:
  380. # 直接向收费系统发送出场
  381. print("****************************收费系统推送出场****************************" + str(
  382. datetime.datetime.now()))
  383. out_dict = self.get_cloud_request_data(pick_table, 'out')
  384. headers_dict, park_surplus_dict, pickup_queue_dict, phone_out_dict = self.get_phone_request_data(
  385. pick_table.car_number, pick_table.primary_key, pick_table.unit_id, 'out')
  386. self.push_http_request(self._out_url, out_dict)
  387. print("\n")
  388. print("****************************手机端推送出场****************************" + str(
  389. datetime.datetime.now()))
  390. self.push_http_request(self._out_url_phone, phone_out_dict, headers_dict)
  391. print("\n")
  392. print("****************************推送余位****************************" + str(datetime.datetime.now()))
  393. self.push_http_request(self._park_surplus_url, park_surplus_dict, headers_dict)
  394. print("\n")
  395. print("****************************推送排队****************************" + str(datetime.datetime.now()))
  396. self.push_http_request(self._queue_url, pickup_queue_dict, headers_dict)
  397. print("\n")
  398. print('强制取车')
  399. else:
  400. print(
  401. "****************************查询白名单****************************" + str(datetime.datetime.now()))
  402. whitelist_res = self.db.query_whitelist_in_car_number(pick_table.car_number)
  403. if len(whitelist_res) <= 0:
  404. # 向收费系统查询缴费情况
  405. print("****************************查询缴费情况****************************" + str(
  406. datetime.datetime.now()))
  407. request = self.get_cloud_request_data(pick_table, 'query')
  408. statu, response = self.push_http_request(self._query_url, request)
  409. if statu == message.eNormal:
  410. if ('Data' in response.keys()) and ('UnpaidMoney' in response['Data'].keys()):
  411. if response['Data']['UnpaidMoney'] == 0:
  412. # 向收费系统推送车辆离场
  413. print("****************************收费系统推送出场****************************" + str(
  414. datetime.datetime.now()))
  415. out_dict = self.get_cloud_request_data(pick_table, 'out')
  416. headers_dict, park_surplus_dict, pickup_queue_dict, phone_out_dict = self.get_phone_request_data(
  417. pick_table.car_number, pick_table.primary_key, pick_table.unit_id, 'out')
  418. self.push_http_request(self._out_url, out_dict)
  419. print("\n")
  420. print("****************************手机端推送出场****************************" + str(
  421. datetime.datetime.now()))
  422. self.push_http_request(self._out_url_phone, phone_out_dict, headers_dict)
  423. print("\n")
  424. print("****************************推送余位****************************" + str(
  425. datetime.datetime.now()))
  426. self.push_http_request(self._park_surplus_url, park_surplus_dict, headers_dict)
  427. print("\n")
  428. print("****************************推送排队****************************" + str(
  429. datetime.datetime.now()))
  430. self.push_http_request(self._queue_url, pickup_queue_dict, headers_dict)
  431. print("\n")
  432. if statu != message.eNormal:
  433. pick_table.statu.execute_statu = statu
  434. pick_table.statu.statu_description = response
  435. else:
  436. unit_str = self.get_unit_str(pick_table.unit_id)
  437. pick_table.statu.execute_statu = message.eNormal
  438. pick_table.statu.statu_description = "取车成功,请前往 << %s >> 单元出口等待车辆,观看大屏幕提示取车!" % unit_str
  439. else:
  440. pick_table.statu.execute_statu = message.eWarning
  441. pick_table.statu.statu_description = ("您有待缴费用,请您微信扫码缴费%.2f元;" % (
  442. response['Data']['UnpaidMoney'])) + self._http + pick_table.primary_key
  443. else:
  444. pick_table.statu.execute_statu = message.eError
  445. pick_table.statu.statu_description = "收费系统答复错误!请联系管理员!"
  446. else:
  447. pick_table.statu.execute_statu = statu
  448. pick_table.statu.statu_description = response
  449. else:
  450. unit_str = self.get_unit_str(pick_table.unit_id)
  451. pick_table.statu.execute_statu = message.eNormal
  452. pick_table.statu.statu_description = "取车成功,请前往 << %s >> 单元出口等待车辆,观看大屏幕提示取车!" % unit_str
  453. return pick_table
  454. def get_cloud_request_data(self, table, param):
  455. print(param + ":")
  456. # 创建请求
  457. msgId = str(uuid.uuid1()) + '@' + table.car_number
  458. AppId = self._app_id
  459. time = str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
  460. sign = msgId + AppId + time + self._secret_key
  461. hl = hashlib.md5()
  462. hl.update(sign.encode(encoding='utf-8'))
  463. sign = hl.hexdigest()
  464. color = self._plate_color[
  465. table.car_number_info.plate_color] if table.car_number_info.plate_color in self._plate_color.keys() else \
  466. self._plate_color['其他']
  467. # 入场请求
  468. if param == 'in':
  469. data = http_client.HttpRequest.InDate(self._parking_id, table.car_number,
  470. str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')),
  471. self.chnnId_in[table.unit_id],
  472. table.car_number_info.plate_type, color,
  473. table.car_number_info.plate_full_image,
  474. table.car_number_info.plate_clip_image, table.primary_key)
  475. # 查询请求
  476. elif param == 'query':
  477. data = http_client.HttpRequest.QueryData(table.primary_key, self._parking_id)
  478. # 出场请求
  479. elif param == 'out':
  480. data = http_client.HttpRequest.OutDate(self._parking_id, table.car_number,
  481. table.primary_key,
  482. str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')),
  483. self.chnnId_out[table.unit_id],
  484. table.car_number_info.plate_type, color,
  485. table.car_number_info.plate_full_image,
  486. table.car_number_info.plate_clip_image)
  487. request = http_client.HttpRequest(msgId, AppId, time, sign, data)
  488. return request.__dict__
  489. def get_phone_request_data(self, car_number, primary_key, unit_id, param):
  490. print(param + ":")
  491. # 创建请求
  492. appid_iphone = self._app_id_phone
  493. time_iphone = str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
  494. sign_iphone = appid_iphone + time_iphone + self._appSecret_phone
  495. hl_iphone = hashlib.md5()
  496. hl_iphone.update(sign_iphone.encode(encoding='utf-8'))
  497. sign_iphone = hl_iphone.hexdigest()
  498. headers_dict = {
  499. "Appid": appid_iphone,
  500. "Time": time_iphone,
  501. "Sign": sign_iphone
  502. }
  503. total = large = small = 0
  504. if param == 'queue 1':
  505. command_count = 1
  506. else:
  507. print("****************************查询余位*******************************" + str(datetime.datetime.now()))
  508. total = self.db.query_total_empty_space()[0]['count(*)']
  509. large = self.db.query_large_empty_space()[0]['count(*)']
  510. small = self.db.query_small_empty_space()[0]['count(*)']
  511. print("****************************查询排队信息****************************" + str(datetime.datetime.now()))
  512. command_count = self.db.query_command_queue_count_in_unit(unit_id)[0]['count(*)']
  513. park_surplus_dict = {
  514. "parkId": self._parking_id,
  515. "totalParkSurplus": total,
  516. "largeParkSurplus": large,
  517. "smallParkSurplus": small
  518. }
  519. pickup_queue_dict = {
  520. "licenesePlate": car_number,
  521. "inRecordId": primary_key,
  522. "garageNo": self.get_unit_str(unit_id),
  523. "waitNum": command_count,
  524. "remainingTime": command_count * 2
  525. }
  526. phone_out_dict = {
  527. "parkId": self._parking_id,
  528. "licenesePlate": car_number,
  529. "inRecordId": primary_key
  530. }
  531. return headers_dict, park_surplus_dict, pickup_queue_dict, phone_out_dict
  532. def push_pickqueue(self):
  533. while True:
  534. for unit in self.chnnId_in.keys():
  535. res = self.db.query_queue_condition_in_unit(unit)
  536. for dict in res:
  537. if dict['upload_statu'] is None and dict['row_number() over(order by queue_time)'] == 2:
  538. print("===============================排队为1 推送排队详情=========================" + str(datetime.datetime.now()))
  539. headers_dict, park_surplus_dict, pickup_queue_dict, phone_out_dict = self.get_phone_request_data(
  540. dict['car_number'], dict['primary_key'], dict['unit'], 'queue 1')
  541. self.push_http_request(self._queue_url, pickup_queue_dict, headers_dict)
  542. self.db.update_command_queue_upload_statu_in_car_number(dict['car_number'])
  543. print("\n")
  544. time.sleep(1)
  545. def get_unit_str(self, unit):
  546. if unit == 11:
  547. return 'A1'
  548. elif unit == 12:
  549. return 'A2'
  550. elif unit == 13:
  551. return 'A3'
  552. elif unit == 14:
  553. return 'A4'
  554. elif unit == 21:
  555. return 'B1'
  556. elif unit == 22:
  557. return 'B2'
  558. elif unit == 23:
  559. return 'B3'
  560. elif unit == 24:
  561. return 'B4'
  562. elif unit == 25:
  563. return 'B5'
  564. elif unit == 31:
  565. return 'C1'
  566. elif unit == 32:
  567. return 'C2'
  568. elif unit == 1:
  569. return 'A'
  570. elif unit == 2:
  571. return 'B'
  572. elif unit == 3:
  573. return 'C'
  574. return ''
  575. def get_unit_int(self, unit):
  576. if unit == 'A1':
  577. return 11
  578. elif unit == 'A2':
  579. return 12
  580. elif unit == 'A3':
  581. return 13
  582. elif unit == 'A4':
  583. return 14
  584. elif unit == 'B1':
  585. return 21
  586. elif unit == 'B2':
  587. return 22
  588. elif unit == 'B3':
  589. return 23
  590. elif unit == 'B4':
  591. return 24
  592. elif unit == 'B5':
  593. return 25
  594. elif unit == 'C1':
  595. return 31
  596. elif unit == 'C2':
  597. return 32
  598. return 0