node.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QSizePolicy, QLabel, QWidget
  3. import json
  4. import threading
  5. import time
  6. from functools import partial
  7. from PyQt5.QtCore import pyqtSignal, Qt
  8. from PyQt5.QtGui import QCursor
  9. from PyQt5.QtWidgets import QPushButton, QMainWindow, QMenu, QMessageBox
  10. import message.message_pb2 as message
  11. import google.protobuf.text_format as tf
  12. import re
  13. import ui.spaceUi as sui
  14. import spaceManage as spmng
  15. import async_communication as cmt
  16. from led import Led
  17. # db参数
  18. db_ip = "192.168.1.233"
  19. # db_ip = "127.0.0.1"
  20. db_port = 3306
  21. db_name = "ct_project"
  22. db_user = "zx"
  23. db_password = "zx123456"
  24. # db_user = "root"
  25. # db_password = "123456"
  26. # mq参数
  27. mq_ip = "192.168.1.233"
  28. # mq_ip = "127.0.0.1"
  29. mq_port = 5672
  30. mq_user = "zx"
  31. mq_password = "zx123456"
  32. # mq_user = "wk"
  33. # mq_password = "123456"
  34. statu_ex_keys = [
  35. ["statu_ex", "in_mcpu_1_statu_port"],
  36. ["statu_ex", "in_mcpu_2_statu_port"],
  37. ["statu_ex", "in_mcpu_3_statu_port"],
  38. ["statu_ex", "in_mcpu_4_statu_port"],
  39. ["statu_ex", "in_mcpu_5_statu_port"],
  40. ["statu_ex", "in_mcpu_6_statu_port"],
  41. ["statu_ex", "out_mcpu_1_statu_port"],
  42. ["statu_ex", "out_mcpu_2_statu_port"],
  43. ["statu_ex", "out_mcpu_3_statu_port"],
  44. ["statu_ex", "out_mcpu_4_statu_port"],
  45. ["statu_ex", "out_mcpu_5_statu_port"],
  46. ["statu_ex", "out_mcpu_6_statu_port"]
  47. ]
  48. class QPBtn(QPushButton):
  49. clickedSignal = pyqtSignal(bool) # 定义带参信号
  50. def __init__(self, parent=None):
  51. super(QPBtn, self).__init__(parent)
  52. def mousePressEvent(self, event): # 重定义该函数,对不同的操作释放不同的信号参数
  53. if event.buttons() == Qt.LeftButton:
  54. self.clickedSignal.emit(True)
  55. elif event.buttons() == Qt.RightButton:
  56. self.clickedSignal.emit(False)
  57. class MainWindow(QMainWindow, threading.Thread):
  58. drawSpaceBtnSignal = pyqtSignal(dict, int)
  59. drawMcpuBtnSignal = pyqtSignal(list)
  60. drawLedSignal = pyqtSignal()
  61. def __init__(self):
  62. threading.Thread.__init__(self)
  63. QMainWindow.__init__(self)
  64. self.mcpu_statu = {}
  65. self.mcpu_timeout = {}
  66. self.ui = sui.Ui_MainWindow()
  67. self.ui.setupUi(self)
  68. self.isClose = False
  69. self.drawSpaceBtnSignal.connect(self.drawSpaceBtn)
  70. self.drawMcpuBtnSignal.connect(self.drawMcpuBtn)
  71. self.drawLedSignal.connect(self.drawLed)
  72. self.btn_positions = [(i, j) for i in range(13, -1, -1) for j in range(6)]
  73. self.dispatch_mcpu_positions = [(i, j) for i in range(1) for j in range(3)]
  74. def getBackGroundColor(self, color):
  75. if color == "red":
  76. return "background-color:rgb(255,70,70)"
  77. elif color == "gray":
  78. return "background-color:rgb(168,168,168)"
  79. elif color == "green":
  80. return "background-color:rgb(0,180,0)"
  81. elif color == "yellow":
  82. return "background-color:rgb(248,239,71)"
  83. def drawLed(self):
  84. export_1 = True
  85. export_2 = True
  86. export_3 = True
  87. export_4 = True
  88. export_5 = True
  89. export_6 = True
  90. out_mcpu_1_statu = message.out_mcpu_statu()
  91. out_mcpu_2_statu = message.out_mcpu_statu()
  92. out_mcpu_3_statu = message.out_mcpu_statu()
  93. out_mcpu_4_statu = message.out_mcpu_statu()
  94. out_mcpu_5_statu = message.out_mcpu_statu()
  95. out_mcpu_6_statu = message.out_mcpu_statu()
  96. if self.ui.out_mcpu_1_statu_btn.toolTip() != "None":
  97. tf.Parse(self.ui.out_mcpu_1_statu_btn.toolTip(), out_mcpu_1_statu)
  98. if out_mcpu_1_statu.outside_safety == 2:
  99. export_1 = False
  100. if self.ui.out_mcpu_2_statu_btn.toolTip() != "None":
  101. tf.Parse(self.ui.out_mcpu_2_statu_btn.toolTip(), out_mcpu_2_statu)
  102. if out_mcpu_2_statu.outside_safety == 2:
  103. export_2 = False
  104. if self.ui.out_mcpu_3_statu_btn.toolTip() != "None":
  105. tf.Parse(self.ui.out_mcpu_3_statu_btn.toolTip(), out_mcpu_3_statu)
  106. if out_mcpu_3_statu.outside_safety == 2:
  107. export_3 = False
  108. if self.ui.out_mcpu_4_statu_btn.toolTip() != "None":
  109. tf.Parse(self.ui.out_mcpu_4_statu_btn.toolTip(), out_mcpu_4_statu)
  110. if out_mcpu_4_statu.outside_safety == 2:
  111. export_4 = False
  112. if self.ui.out_mcpu_5_statu_btn.toolTip() != "None":
  113. tf.Parse(self.ui.out_mcpu_5_statu_btn.toolTip(), out_mcpu_5_statu)
  114. if out_mcpu_5_statu.outside_safety == 2:
  115. export_5 = False
  116. if self.ui.out_mcpu_6_statu_btn.toolTip() != "None":
  117. tf.Parse(self.ui.out_mcpu_6_statu_btn.toolTip(), out_mcpu_6_statu)
  118. if out_mcpu_6_statu.outside_safety == 2:
  119. export_6 = False
  120. if g_space.command_queue_dict is not False and g_space.command_queue_dict is not None:
  121. for dict in g_space.command_queue_dict:
  122. if dict["export_id"] == 1:
  123. export_1 = False
  124. if dict["export_id"] == 2:
  125. export_2 = False
  126. if dict["export_id"] == 3:
  127. export_3 = False
  128. if dict["export_id"] == 4:
  129. export_4 = False
  130. if dict["export_id"] == 5:
  131. export_5 = False
  132. if dict["export_id"] == 6:
  133. export_6 = False
  134. if export_1 == export_2 == False:
  135. led = Led()
  136. led.setEnabled(False) # 设置为不使能状态,如果需要切换可以设置为True。则可以实现点击切换指示灯颜色的效果
  137. led.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
  138. led.setChecked(False) # 设置为选中状态
  139. else:
  140. led = Led()
  141. led.setEnabled(False) # 设置为不使能状态,如果需要切换可以设置为True。则可以实现点击切换指示灯颜色的效果
  142. led.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
  143. led.setChecked(True) # 设置为选中状态
  144. self.ui.led_process_Layout.addWidget(led, 0, 1)
  145. if export_3 == export_4 == False:
  146. led = Led()
  147. led.setEnabled(False) # 设置为不使能状态,如果需要切换可以设置为True。则可以实现点击切换指示灯颜色的效果
  148. led.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
  149. led.setChecked(False) # 设置为选中状态
  150. else:
  151. led = Led()
  152. led.setEnabled(False) # 设置为不使能状态,如果需要切换可以设置为True。则可以实现点击切换指示灯颜色的效果
  153. led.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
  154. led.setChecked(True) # 设置为选中状态
  155. self.ui.led_process_Layout.addWidget(led, 0, 2)
  156. if export_5 == export_6 == False:
  157. led = Led()
  158. led.setEnabled(False) # 设置为不使能状态,如果需要切换可以设置为True。则可以实现点击切换指示灯颜色的效果
  159. led.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
  160. led.setChecked(False) # 设置为选中状态
  161. else:
  162. led = Led()
  163. led.setEnabled(False) # 设置为不使能状态,如果需要切换可以设置为True。则可以实现点击切换指示灯颜色的效果
  164. led.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
  165. led.setChecked(True) # 设置为选中状态
  166. self.ui.led_process_Layout.addWidget(led, 0, 3)
  167. def drawMcpuBtn(self, list):
  168. ex_name = list[0]
  169. key = list[1]
  170. id = ex_name + ":" + key
  171. btn = self.findChild(QPushButton, key.replace("port", "btn"))
  172. if g_rabbitmq[id].statu is not None and g_rabbitmq[id].timeout() is False:
  173. btn.setToolTip(g_rabbitmq[id].statu)
  174. if key.find("in") >= 0:
  175. in_mcpu_statu = message.in_mcpu_statu()
  176. tf.Parse(g_rabbitmq[id].statu, in_mcpu_statu)
  177. if in_mcpu_statu.is_occupy == 1:
  178. btn.setStyleSheet(self.getBackGroundColor("green"))
  179. btn.setText(btn.text()[:9] + "空闲----"+btn.text()[15:])
  180. else:
  181. btn.setStyleSheet(self.getBackGroundColor("yellow"))
  182. btn.setText(btn.text()[:9] + "占用----"+btn.text()[15:])
  183. # print(btn.text())
  184. if in_mcpu_statu.door_statu == 2:
  185. btn.setText(btn.text()[:-3] + "开到位")
  186. elif in_mcpu_statu.door_statu == 3:
  187. btn.setText(btn.text()[:-3] + "关到位")
  188. elif in_mcpu_statu.door_statu == 4:
  189. btn.setText(btn.text()[:-3] + "开关中")
  190. elif in_mcpu_statu.door_statu == 5:
  191. btn.setText(btn.text()[:-3] + "门故障")
  192. # print(btn.text())
  193. # print(btn.text())
  194. elif btn.text().find("出口") >= 0:
  195. out_mcpu_statu = message.out_mcpu_statu()
  196. tf.Parse(g_rabbitmq[id].statu, out_mcpu_statu)
  197. if out_mcpu_statu.outside_safety == 1:
  198. btn.setStyleSheet(self.getBackGroundColor("green"))
  199. btn.setText(btn.text()[:9] + "空闲----" + btn.text()[15:])
  200. else:
  201. btn.setStyleSheet(self.getBackGroundColor("yellow"))
  202. btn.setText(btn.text()[:9] + "占用----" + btn.text()[15:])
  203. export_id = re.search('\d+', btn.objectName()).group()
  204. if g_space.command_queue_dict is not None:
  205. for dict in g_space.command_queue_dict:
  206. if dict["export_id"] == int(export_id):
  207. btn.setStyleSheet(self.getBackGroundColor("yellow"))
  208. btn.setText(btn.text()[:9] + "占用----" + btn.text()[15:])
  209. if out_mcpu_statu.door_statu == 2:
  210. btn.setText(btn.text()[:-3] + "开到位")
  211. elif out_mcpu_statu.door_statu == 3:
  212. btn.setText(btn.text()[:-3] + "关到位")
  213. elif out_mcpu_statu.door_statu == 4:
  214. btn.setText(btn.text()[:-3] + "开关中")
  215. elif out_mcpu_statu.door_statu == 5:
  216. btn.setText(btn.text()[:-3] + "门故障")
  217. else:
  218. btn.setToolTip("None")
  219. btn.setStyleSheet(self.getBackGroundColor("gray"))
  220. btn.setText(btn.text()[:9] + "断连")
  221. def drawSpaceBtn(self, parkspace_dict, unit):
  222. for park, position in zip(parkspace_dict.values(), self.btn_positions):
  223. btn = QPBtn()
  224. str = "车位:%d\n楼层:%d" % ((park["id"] - 1) % 78 + 1, park["floor"])
  225. if park["statu"] == 1:
  226. btn.setStyleSheet("background-color:rgb(255,130,130)")
  227. elif park["statu"] == 0 and park["car_number"] is not None:
  228. btn.setStyleSheet("background-color:rgb(248,239,71)")
  229. btn.setGeometry(0, 0, 50, 50)
  230. btn.setText(str)
  231. tool_tip = '{"id":%d,\n"floor":%d,\n "subID":%d, \n"height":%f, \n"car_number":"%s" ,\n "unit":%d, \n"statu":%d}' % (
  232. park["id"], park["floor"], park["subID"], park["height"], park["car_number"], park["unit"],
  233. park["statu"])
  234. btn.setToolTip(tool_tip)
  235. btn.clickedSignal.connect(self.btn_click)
  236. if unit == 1:
  237. self.ui.A_gridLayout.addWidget(btn, *position)
  238. if unit == 2:
  239. self.ui.B_gridLayout.addWidget(btn, *position)
  240. if unit == 3:
  241. self.ui.C_gridLayout.addWidget(btn, *position)
  242. def btn_click(self, flag):
  243. if flag is False:
  244. sender = self.sender()
  245. tool_tip = sender.toolTip()
  246. dict = json.loads(tool_tip)
  247. menu = QMenu(self)
  248. action = menu.addAction('启用车位')
  249. action.triggered.connect(partial(self.btn_opeSpace, dict, 0))
  250. action = menu.addAction('停用车位')
  251. action.triggered.connect(partial(self.btn_disableSpace, dict, 1))
  252. action = menu.addAction('清除车位')
  253. action.triggered.connect(partial(self.btn_clearSpace, dict))
  254. action = menu.addAction('取出车辆')
  255. action.triggered.connect(partial(self.btn_pickUp, dict))
  256. menu.exec_(QCursor.pos())
  257. def btn_disableSpace(self, dict, statu):
  258. if g_space.statu is False:
  259. QMessageBox.warning(self, '警告', '数据库连接错误,请检查网络状态!',
  260. QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
  261. else:
  262. g_space.updatePark(dict, statu)
  263. def btn_opeSpace(self, dict, statu):
  264. if g_space.statu is False:
  265. QMessageBox.warning(self, '错误', '数据库连接错误,请检查网络状态!',
  266. QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
  267. else:
  268. g_space.updatePark(dict, statu)
  269. def btn_clearSpace(self, dict):
  270. if g_space.statu is False:
  271. QMessageBox.warning(self, '错误', '数据库连接错误,请检查网络状态!',
  272. QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
  273. else:
  274. g_space.clearPark(dict)
  275. def btn_pickUp(self, dict):
  276. if g_space.statu is False:
  277. QMessageBox.warning(self, '错误', '数据库连接错误,请检查网络状态!',
  278. QMessageBox.Ok) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
  279. else:
  280. g_space.pickUpPark(dict)
  281. def run(self):
  282. while self.isClose is not True:
  283. if g_space.statu is False:
  284. self.setWindowTitle("MainWindow---连接错误!")
  285. self.setEnabled(False)
  286. else:
  287. self.setWindowTitle("MainWindow---连接正常!")
  288. self.setEnabled(True)
  289. if g_space.isUpdate_A is True:
  290. self.drawSpaceBtnSignal.emit(g_space.a_unit_park_dict, 1)
  291. g_space.isUpdate_A = False
  292. if g_space.isUpdate_B is True:
  293. self.drawSpaceBtnSignal.emit(g_space.b_unit_park_dict, 2)
  294. g_space.isUpdate_B = False
  295. if g_space.isUpdate_C is True:
  296. self.drawSpaceBtnSignal.emit(g_space.c_unit_park_dict, 3)
  297. g_space.isUpdate_C = False
  298. for list in statu_ex_keys:
  299. ex_name = list[0]
  300. key = list[1]
  301. id = ex_name + ":" + key
  302. if (id in self.mcpu_statu.keys()) is False or self.mcpu_statu[id].statu != g_rabbitmq[id].statu or \
  303. self.mcpu_timeout[id] != g_rabbitmq[id].timeout():
  304. self.mcpu_timeout[id] = g_rabbitmq[id].timeout()
  305. self.mcpu_statu[id] = g_rabbitmq[id]
  306. g_space.commandIsUpdate = True
  307. print("-----------------------------------------------")
  308. print("key = " + id + "" + " timeout=" + str(self.mcpu_timeout) + " statu=" + str(
  309. self.mcpu_statu[id].statu))
  310. self.drawMcpuBtnSignal.emit(list)
  311. time.sleep(0.01)
  312. if g_space.commandIsUpdate is True:
  313. self.drawLedSignal.emit()
  314. g_space.commandIsUpdate = False
  315. time.sleep(0.5)
  316. def closeEvent(self, event):
  317. results = QMessageBox.question(self, '退出', '你确定要退出吗?', QMessageBox.Yes | QMessageBox.No,
  318. QMessageBox.No) # "退出"代表的是弹出框的标题,"你确认退出.."表示弹出框的内容
  319. if results == QMessageBox.Yes:
  320. g_rabbitmq.close()
  321. g_space.isClose = True
  322. self.isClose = True
  323. event.accept() # 接受关闭事件
  324. else:
  325. event.ignore() # 忽略关闭事件
  326. g_rabbitmq = cmt.RabbitAsyncCommunicator(mq_ip, mq_port, mq_user, mq_password)
  327. g_space = spmng.ParkManage(db_ip, db_port, db_name, db_user, db_password, g_rabbitmq)
  328. if __name__ == '__main__':
  329. app = QApplication(sys.argv)
  330. g_space.start()
  331. g_rabbitmq.Init(None, statu_ex_keys)
  332. g_rabbitmq.start()
  333. mainWindow = MainWindow()
  334. mainWindow.start()
  335. mainWindow.showMaximized()
  336. time.sleep(0.5)
  337. mainWindow.show()
  338. sys.exit(app.exec_())
  339. # 进入程序的主循环,并通过exit函数确保主循环安全结束(该释放资源的一定要释放)