node.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. import base64
  2. import datetime
  3. import sys
  4. from itertools import product
  5. import requests
  6. import message.message_pb2 as message
  7. from PyQt5.QtWidgets import QApplication, QSizePolicy, QLabel, QWidget, QListWidgetItem, QGridLayout
  8. import json
  9. import threading
  10. import time
  11. from functools import partial
  12. from PyQt5.QtCore import pyqtSignal, Qt, QTimer, QThread, QSize
  13. from PyQt5.QtGui import QCursor, QFont, QColor, QPixmap, QIcon, QImage
  14. from PyQt5.QtWidgets import QPushButton, QMainWindow, QMenu, QMessageBox
  15. import message.message_pb2 as message
  16. import google.protobuf.text_format as tf
  17. import re
  18. import ui.spaceUi as sui
  19. import db_helper.db_operation as spmng
  20. from config import MQ_CONFIG as mq_config
  21. import async_communication as cmt
  22. from config import PARKING_CONFIG as park_config
  23. class MainWindow(QMainWindow, sui.Ui_MainWindow):
  24. def __init__(self, parent=None):
  25. super(MainWindow, self).__init__(parent)
  26. self.setupUi(self)
  27. font = QFont()
  28. font.setFamily('宋体')
  29. font.setBold(False)
  30. font.setPointSize(17)
  31. self.parking_listWidget.setFont(font)
  32. self.pushButton_1480.setIcon(QIcon(QPixmap("./images/1480.png")))
  33. self.pushButton_1500.setIcon(QIcon(QPixmap("./images/1500.png")))
  34. self.pushButton_2050.setIcon(QIcon(QPixmap("./images/2050.png")))
  35. if park_config.unit == 11:
  36. self.unit_label.setText("A-1")
  37. elif park_config.unit == 12:
  38. self.unit_label.setText("A-2")
  39. elif park_config.unit == 13:
  40. self.unit_label.setText("A-3")
  41. elif park_config.unit == 14:
  42. self.unit_label.setText("A-4")
  43. elif park_config.unit == 21:
  44. self.unit_label.setText("B-1")
  45. elif park_config.unit == 22:
  46. self.unit_label.setText("B-2")
  47. elif park_config.unit == 23:
  48. self.unit_label.setText("B-3")
  49. elif park_config.unit == 24:
  50. self.unit_label.setText("B-4")
  51. elif park_config.unit == 25:
  52. self.unit_label.setText("B-5")
  53. elif park_config.unit == 31:
  54. self.unit_label.setText("C-1")
  55. elif park_config.unit == 32:
  56. self.unit_label.setText("C-2")
  57. self.btn_positions = [(i, j) for i in range(14, -1, -1) for j in range(6)]
  58. self.space_dict = {}
  59. self.space_is_init = False
  60. self.show_model = self.car_number_rbtn_2.isChecked()
  61. self.rmq_statu_dict = {}
  62. self.command_dict = {}
  63. self.timer = QTimer()
  64. self.timer.timeout.connect(self.Switch)
  65. self.timer.start(200)
  66. self.find_btn.clicked.connect(self.find_btn_click)
  67. def getBackGroundColor(self, color):
  68. if color == "red":
  69. return "background-color:rgb(255,70,70)"
  70. elif color == "gray":
  71. return "background-color:rgb(168,168,168)"
  72. elif color == "green":
  73. return "background-color:rgb(0,180,0)"
  74. elif color == "yellow":
  75. return "background-color:rgb(248,239,71)"
  76. elif color == "pastel":
  77. return "background-color:rgb(241,158,194)"
  78. def get_name(self,key):
  79. if key == 'id':
  80. return '下标'
  81. elif key == 'table_id':
  82. return '表编号'
  83. elif key == 'floor':
  84. return '楼层'
  85. elif key == 'height':
  86. return '限高'
  87. elif key == 'car_number':
  88. return '车牌号'
  89. elif key == 'statu':
  90. return '车位状态'
  91. elif key == 'plate_color':
  92. return '号牌颜色'
  93. elif key == 'plate_type':
  94. return '号牌类型'
  95. elif key == 'plate_confidence':
  96. return '号牌可信度'
  97. elif key == 'recognition_time':
  98. return '识别时间'
  99. elif key == 'primary_key':
  100. return '唯一码'
  101. else:
  102. return '未知'
  103. def show_parking_details(self,park_dict):
  104. self.parking_listWidget.clear()
  105. for poit in park_dict.items():
  106. item = QListWidgetItem()
  107. item.setSizeHint(QSize(50, 42))
  108. name = self.get_name(poit[0])
  109. if name == '未知':
  110. continue
  111. value = poit[1]
  112. if name == '楼层':
  113. value = value - 2
  114. item.setText(name + ":" + str(value))
  115. self.parking_listWidget.addItem(item)
  116. res = g_space.query_space_in_car_number(park_dict['car_number'])
  117. self.plate_full_image_label.setPixmap(QPixmap(""))
  118. self.plate_clip_image_label.setPixmap(QPixmap(""))
  119. if len(res) > 0:
  120. try:
  121. rep = requests.get(res[0]['plate_full_image'])
  122. pix = QPixmap()
  123. pix.loadFromData(rep.content)
  124. pix = pix.scaled(self.plate_full_image_label.size(), Qt.KeepAspectRatio)
  125. self.plate_full_image_label.setPixmap(pix)
  126. except Exception as e:
  127. print('全景图:'+str(e.args))
  128. try:
  129. rep = requests.get(res[0]['plate_clip_image'])
  130. pix = QPixmap()
  131. pix.loadFromData(rep.content)
  132. pix = pix.scaled(self.plate_clip_image_label.size(), Qt.KeepAspectRatio)
  133. self.plate_clip_image_label.setPixmap(pix)
  134. except Exception as e:
  135. print('特写图:'+str(e.args))
  136. def find_btn_click(self):
  137. text = self.find_lineEdit.text()
  138. if text == '':
  139. QMessageBox.question(None, "提示", "请输入要查询的内容",
  140. QMessageBox.Ok)
  141. return
  142. if self.car_number_rbtn.isChecked():
  143. park_dict = g_space.query_space_in_car_number(text)
  144. if len(park_dict) > 0:
  145. self.show_parking_details(park_dict[0])
  146. else:
  147. QMessageBox.question(None, "查询结果", "车牌号:" + text + " 未查询到数据!",
  148. QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
  149. elif self.key_rbtn.isChecked():
  150. park_dict = g_space.query_space_in_primary_key(text)
  151. if len(park_dict) > 0:
  152. self.show_parking_details(park_dict[0])
  153. else:
  154. QMessageBox.question(None, "查询结果", "唯一码:" + text + " 未查询到数据!",
  155. QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
  156. elif self.parking_rbtn.isChecked():
  157. park_dict = g_space.query_space_in_unit_and_table_id(park_config.unit,text)
  158. if len(park_dict) > 0:
  159. self.show_parking_details(park_dict[0])
  160. else:
  161. QMessageBox.question(None, "查询结果", "车位id:" + text + " 未查询到数据!",
  162. QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
  163. return
  164. def park_btn_left_click(self):
  165. sender = self.sender()
  166. tool_tip = sender.toolTip()
  167. dict = json.loads(tool_tip)
  168. self.show_parking_details(dict)
  169. def park_btn_right_click(self):
  170. menu = QMenu(self)
  171. sender = self.sender()
  172. tool_tip = sender.toolTip()
  173. dict = json.loads(tool_tip)
  174. action = menu.addAction('启用车位')
  175. action.triggered.connect(partial(self.btn_opeSpace, dict, 0))
  176. action = menu.addAction('停用车位')
  177. action.triggered.connect(partial(self.btn_disableSpace, dict, 10))
  178. action = menu.addAction('清除车位')
  179. action.triggered.connect(partial(self.btn_clearSpace, dict))
  180. action = menu.addAction('取出车辆')
  181. action.triggered.connect(partial(self.btn_pickUp, dict))
  182. menu.exec_(QCursor.pos())
  183. def btn_disableSpace(self, dict, statu):
  184. res = g_space.update_space_status(dict["id"], statu)
  185. if res == 0:
  186. QMessageBox.question(None, '提示', '更新车位失败!请检查是否点击错误!',
  187. QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
  188. def btn_opeSpace(self, dict, statu):
  189. res = g_space.update_space_status(dict["id"], statu)
  190. if res == 0:
  191. QMessageBox.question(None, '提示', '更新车位失败!请检查是否点击错误!',
  192. QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
  193. def btn_clearSpace(self, dict):
  194. res = g_space.clear_space_data(dict["id"])
  195. if res == 0:
  196. QMessageBox.question(None, '提示', '更新车位失败!请检查是否点击错误!',
  197. QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
  198. def btn_pickUp(self, dict):
  199. table = message.pick_table()
  200. table.primary_key = dict["primary_key"]
  201. g_rabbitmq.publish(mq_config.mq_command_exchange_name, "user_pick_command_request_port", tf.MessageToString(table, as_utf8=True))
  202. QMessageBox.question(None, '提示', '取车消息发送成功!',
  203. QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
  204. def get_btn_show(self, park):
  205. font = QFont()
  206. font.setFamily('宋体')
  207. font.setPointSize(21)
  208. if park["serial_id"] in park_config.channel_ex[park_config.unit]["入口"]:
  209. text_str = "入 口"
  210. font.setBold(True)
  211. elif park["serial_id"] in park_config.channel_ex[park_config.unit]["出口"]:
  212. text_str = "出 口"
  213. font.setBold(True)
  214. elif park["statu"] == 2 and park["car_number"] is not None and self.car_number_rbtn_2.isChecked():
  215. text_str = " "+park["car_number"]
  216. font.setPointSize(17)
  217. else:
  218. text_str = " 车位:%d\n 楼层:%d" % (park["table_id"], park["floor"] - 2)
  219. font.setPointSize(10)
  220. stylesheet = ""
  221. if park["statu"] == 10:
  222. stylesheet = "background-color:rgb(255,130,130);pressed{padding-top:2px;padding-left:2px;};text-align:left;"
  223. elif park["statu"] == 2 and park["car_number"] is not None:
  224. stylesheet = "background-color:rgb(248,239,71);pressed{padding-top:2px;padding-left:2px;};text-align:left;"
  225. elif park["statu"] == 6 or park["statu"] == 7:
  226. stylesheet = "background-color:rgb(0,162,232);pressed{padding-top:2px;padding-left:2px;};"
  227. elif park["statu"] == 0:
  228. stylesheet = "background-color:rgb(195,195,195);pressed{padding-top:2px;padding-left:2px;};text-align:left;"
  229. icon = QIcon() # 设置按钮图标
  230. if park["height"] == 1.48:
  231. icon = QIcon(QPixmap('./images/1480.png')) # 设置按钮图标
  232. elif park["height"] == 1.50:
  233. icon = QIcon(QPixmap('./images/1500.png')) # 设置按钮图标
  234. elif park["height"] == 2.05:
  235. icon = QIcon(QPixmap('./images/2050.png')) # 设置按钮图标
  236. tool_tip = '{"id":%d,\n"table_id":%d,\n"floor":%d, \n"height":%f,\n"car_number":"%s" , \n"statu":%d,\n"plate_color":"%s" ,\n"plate_type":"%s" ,\n"plate_confidence":"%s",\n"recognition_time":"%s",\n"primary_key":"%s"}' % (
  237. park["id"], (-1 if park["table_id"] is None else park["table_id"]),
  238. park["floor"], (0 if park["height"] is None else park["height"]),
  239. park["car_number"],park["statu"],park["plate_color"],
  240. park["plate_type"],park["plate_confidence"],park["recognition_time"],park["primary_key"])
  241. return font, text_str, stylesheet, tool_tip, icon
  242. def Switch(self):
  243. # 绘制车位按钮
  244. space_dict = g_space.query_space_in_unit(park_config.unit)
  245. if len(space_dict) < 0:
  246. return
  247. is_show_car_number = self.car_number_rbtn_2.isChecked()
  248. if self.space_dict != space_dict:
  249. if self.space_is_init == False:
  250. self.space_dict = space_dict
  251. self.space_is_init = True
  252. is_drawIn = False
  253. is_drawOut = False
  254. for park, position in zip(self.space_dict, self.btn_positions):
  255. btn = QPushButton()
  256. font, text_str, stylesheet, tool_tip, icon = self.get_btn_show(park)
  257. btn.setFont(font)
  258. btn.setLayout(QGridLayout())
  259. btn.setText(text_str)
  260. btn.setStyleSheet(stylesheet)
  261. btn.setToolTip(tool_tip)
  262. btn.setObjectName(str(park["table_id"]))
  263. btn.setIcon(icon)
  264. btn.setIconSize(QSize(30,30))
  265. if text_str == "入 口" and is_drawIn is False:
  266. self.unit_gridLayout.addWidget(btn, *position, 1, len(park_config.channel_ex[park_config.unit]["入口"]))
  267. is_drawIn = True
  268. elif text_str == "出 口" and is_drawOut is False:
  269. self.unit_gridLayout.addWidget(btn, *position, 1, len(park_config.channel_ex[park_config.unit]["出口"]))
  270. is_drawOut = True
  271. elif text_str != "出 口" and text_str != "入 口":
  272. btn.setContextMenuPolicy(Qt.CustomContextMenu)
  273. btn.customContextMenuRequested.connect(self.park_btn_right_click)
  274. btn.clicked.connect(self.park_btn_left_click)
  275. self.unit_gridLayout.addWidget(btn, *position)
  276. else:
  277. for park1, park2 in zip(self.space_dict, space_dict):
  278. if park1 != park2:
  279. font, text_str, stylesheet, tool_tip,icon = self.get_btn_show(park2)
  280. results = self.findChild(QPushButton, str(park2["table_id"]))
  281. results.setFont(font)
  282. results.setText(text_str)
  283. results.setStyleSheet(stylesheet)
  284. results.setToolTip(tool_tip)
  285. self.space_dict = space_dict
  286. if self.show_model != is_show_car_number:
  287. self.show_model = is_show_car_number
  288. for park in self.space_dict:
  289. if park["statu"] == 2:
  290. font, text_str, stylesheet, tool_tip,icon = self.get_btn_show(park)
  291. results = self.findChild(QPushButton, str(park["table_id"]))
  292. results.setFont(font)
  293. results.setText(text_str)
  294. results.setStyleSheet(stylesheet)
  295. results.setToolTip(tool_tip)
  296. def closeEvent(self, event):
  297. results = QMessageBox.question(self, '退出', '你确定要退出吗?', QMessageBox.Yes | QMessageBox.No,
  298. QMessageBox.No) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
  299. if results == QMessageBox.Yes:
  300. g_rabbitmq.close()
  301. event.accept() # 接受关闭事件
  302. else:
  303. event.ignore() # 忽略关闭事件
  304. if __name__ == '__main__':
  305. g_rabbitmq = cmt.RabbitAsyncCommunicator(mq_config.mq_ip, mq_config.mq_port, mq_config.mq_user, mq_config.mq_password)
  306. g_rabbitmq.Init(None, None)
  307. g_rabbitmq.start()
  308. g_space = spmng.DBOperation()
  309. app = QApplication(sys.argv)
  310. mainWindow = MainWindow()
  311. mainWindow.showMaximized()
  312. mainWindow.plate_full_image_label.setMaximumSize(mainWindow.plate_full_image_label.size())
  313. mainWindow.plate_clip_image_label.setMaximumSize(mainWindow.plate_clip_image_label.size())
  314. sys.exit(app.exec_())