AllowedListDemo.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. # coding=utf-8
  2. import sys
  3. from PyQt5.QtWidgets import QMainWindow,QApplication, QTableWidgetItem, QMessageBox
  4. from PyQt5.QtCore import Qt
  5. from PyQt5.QtGui import QPixmap
  6. from PyQt5.QtCore import QThread,pyqtSignal
  7. from AllowedListUI import Ui_MainWindow
  8. from NetSDK.NetSDK import NetClient
  9. from NetSDK.SDK_Struct import *
  10. from NetSDK.SDK_Enum import *
  11. from NetSDK.SDK_Callback import *
  12. import datetime
  13. from queue import Queue
  14. class RecordInfo:
  15. def __init__(self):
  16. self.plate_number_str = ""
  17. self.vehicle_owner_str = ""
  18. self.start_time_str = ""
  19. self.end_time_str = ""
  20. self.auth_str = ""
  21. self.record_number_str = ""
  22. def get_alarm_info(self, info):
  23. self.plate_number_str = str(info.szPlateNumber.decode('gb2312'))
  24. self.vehicle_owner_str = str(info.szMasterOfCar.decode('gb2312'))
  25. self.start_time_str = '{}-{}-{} {}:{}:{}'.format(info.stBeginTime.dwYear, info.stBeginTime.dwMonth, info.stBeginTime.dwDay,
  26. info.stBeginTime.dwHour, info.stBeginTime.dwMinute, info.stBeginTime.dwSecond)
  27. self.end_time_str = '{}-{}-{} {}:{}:{}'.format(info.stCancelTime.dwYear, info.stCancelTime.dwMonth, info.stCancelTime.dwDay,
  28. info.stCancelTime.dwHour, info.stCancelTime.dwMinute, info.stCancelTime.dwSecond)
  29. self.auth_str = str(info.stAuthrityTypes[0].bAuthorityEnable)
  30. self.record_number_str = str(info.nRecordNo)
  31. class AllowedListWnd(QMainWindow, Ui_MainWindow):
  32. def __init__(self, parent=None):
  33. super(AllowedListWnd, self).__init__(parent)
  34. self.setupUi(self)
  35. # 界面初始化
  36. self._init_ui()
  37. # NetSDK用到的相关变量和回调
  38. self.loginID = C_LLONG()
  39. self.m_DisConnectCallBack = fDisConnect(self.DisConnectCallBack)
  40. self.m_ReConnectCallBack = fHaveReConnect(self.ReConnectCallBack)
  41. # 获取NetSDK对象并初始化
  42. self.sdk = NetClient()
  43. self.sdk.InitEx(self.m_DisConnectCallBack)
  44. self.sdk.SetAutoReconnect(self.m_ReConnectCallBack)
  45. # 初始化界面
  46. def _init_ui(self):
  47. self.row = 0
  48. self.column = 0
  49. self.Login_pushButton.setEnabled(True)
  50. self.Logout_pushButton.setEnabled(False)
  51. self.Query_pushButton.setEnabled(False)
  52. self.Add_pushButton.setEnabled(False)
  53. self.Modify_pushButton.setEnabled(False)
  54. self.Delete_pushButton.setEnabled(False)
  55. self.AllDelete_pushButton.setEnabled(False)
  56. self.RecordNo_lineEdit.setReadOnly(True)
  57. self.IP_lineEdit.setText('172.24.31.3')
  58. self.Port_lineEdit.setText('37777')
  59. self.User_lineEdit.setText('admin')
  60. self.Pwd_lineEdit.setText('admin123')
  61. self.setWindowFlag(Qt.WindowMinimizeButtonHint)
  62. self.setWindowFlag(Qt.WindowCloseButtonHint)
  63. self.setFixedSize(self.width(), self.height())
  64. self.Login_pushButton.clicked.connect(self.login_btn_onclick)
  65. self.Logout_pushButton.clicked.connect(self.logout_btn_onclick)
  66. self.Query_pushButton.clicked.connect(self.query_btn_onclick)
  67. self.Add_pushButton.clicked.connect(self.add_record_btn_onclick)
  68. self.Modify_pushButton.clicked.connect(self.modify_record_btn_onclick)
  69. self.Delete_pushButton.clicked.connect(self.delete_record_btn_onclick)
  70. self.AllDelete_pushButton.clicked.connect(self.delete_all_record_btn_onclick)
  71. self.Query_tableWidget.clicked.connect(self.detail_table_onclick)
  72. # 登录设备
  73. def login_btn_onclick(self):
  74. self.Query_tableWidget.setHorizontalHeaderLabels(['车牌号(Plate No.)', '车主(Vehicle Owner)', '开始时间(Start Time)', '结束时间(End Time)', '开闸授权(Switch Authorize)', '记录号(Record No.)'])
  75. ip = self.IP_lineEdit.text()
  76. port = int(self.Port_lineEdit.text())
  77. username = self.User_lineEdit.text()
  78. password = self.Pwd_lineEdit.text()
  79. stuInParam = NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY()
  80. stuInParam.dwSize = sizeof(NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY)
  81. stuInParam.szIP = ip.encode()
  82. stuInParam.nPort = port
  83. stuInParam.szUserName = username.encode()
  84. stuInParam.szPassword = password.encode()
  85. stuInParam.emSpecCap = EM_LOGIN_SPAC_CAP_TYPE.TCP
  86. stuInParam.pCapParam = None
  87. stuOutParam = NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY()
  88. stuOutParam.dwSize = sizeof(NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY)
  89. self.loginID, device_info, error_msg = self.sdk.LoginWithHighLevelSecurity(stuInParam, stuOutParam)
  90. if self.loginID:
  91. self.setWindowTitle('允许名单(AllowedList)-在线(OnLine)')
  92. self.Logout_pushButton.setEnabled(True)
  93. self.Login_pushButton.setEnabled(False)
  94. self.Query_pushButton.setEnabled(True)
  95. self.Add_pushButton.setEnabled(True)
  96. self.Modify_pushButton.setEnabled(True)
  97. self.Delete_pushButton.setEnabled(True)
  98. self.AllDelete_pushButton.setEnabled(True)
  99. else:
  100. QMessageBox.about(self, '提示(prompt)', error_msg)
  101. # 登出设备
  102. def logout_btn_onclick(self):
  103. # 登出
  104. result = self.sdk.Logout(self.loginID)
  105. self.Login_pushButton.setEnabled(True)
  106. self.Logout_pushButton.setEnabled(False)
  107. self.Query_pushButton.setEnabled(False)
  108. self.Add_pushButton.setEnabled(False)
  109. self.Modify_pushButton.setEnabled(False)
  110. self.Delete_pushButton.setEnabled(False)
  111. self.AllDelete_pushButton.setEnabled(False)
  112. self.clear_record_operate_detail()
  113. self.setWindowTitle("允许名单(AllowedList)-离线(OffLine)")
  114. self.loginID = C_LLONG(0)
  115. self.Query_tableWidget.clear()
  116. self.Query_tableWidget.setRowCount(0)
  117. self.row = 0
  118. self.column = 0
  119. self.Query_tableWidget.setHorizontalHeaderLabels(['车牌号(Plate No.)', '车主(Vehicle Owner)', '开始时间(Start Time)', '结束时间(End Time)', '开闸授权(Switch Authorize)', '记录号(Record No.)'])
  120. # 信息列表点击按钮
  121. # 鼠标点击信息列表后更新输入框
  122. # Update the input box after clicking the information list
  123. def detail_table_onclick(self):
  124. if self.Query_tableWidget.currentRow() >= 0:
  125. self.PlateNo_lineEdit.setText(self.Query_tableWidget.item(self.Query_tableWidget.currentRow(), 0).text())
  126. self.VehicleOwner_lineEdit.setText(self.Query_tableWidget.item(self.Query_tableWidget.currentRow(), 1).text())
  127. self.StartTime_lineEdit.setText(self.Query_tableWidget.item(self.Query_tableWidget.currentRow(), 2).text())
  128. self.EndTime_lineEdit.setText(self.Query_tableWidget.item(self.Query_tableWidget.currentRow(), 3).text())
  129. self.SwitchAuthorize_lineEdit.setText(self.Query_tableWidget.item(self.Query_tableWidget.currentRow(), 4).text())
  130. self.RecordNo_lineEdit.setText(self.Query_tableWidget.item(self.Query_tableWidget.currentRow(), 5).text())
  131. # 查询按钮
  132. # 允许名单模糊查询结果
  133. # Fuzzy Query Results of Allowed List
  134. def query_btn_onclick(self, no_prompt=False):
  135. self.row = 0
  136. self.column = 0
  137. self.Query_tableWidget.clear()
  138. self.Query_tableWidget.setRowCount(0)
  139. # self.Query_tableWidget.viewport().update()
  140. self.Query_tableWidget.setHorizontalHeaderLabels(['车牌号(Plate No.)', '车主(Vehicle Owner)', '开始时间(Start Time)', '结束时间(End Time)', '开闸授权(Switch Authorize)', '记录号(Record No.)'])
  141. inParam = NET_IN_FIND_RECORD_PARAM()
  142. inParam.dwSize = sizeof(NET_IN_FIND_RECORD_PARAM)
  143. inParam.emType = EM_NET_RECORD_TYPE.TRAFFICREDLIST
  144. in_condition = FIND_RECORD_TRAFFICREDLIST_CONDITION()
  145. in_condition.dwSize = sizeof(FIND_RECORD_TRAFFICREDLIST_CONDITION)
  146. text = str(self.Province_lineEdit.text()) + str(self.PlateNum_lineEdit.text())
  147. in_condition.szPlateNumberVague = text.encode('gb2312')
  148. inParam.pQueryCondition = cast(pointer(in_condition), c_void_p)
  149. outParam = NET_OUT_FIND_RECORD_PARAM()
  150. outParam.dwSize = sizeof(NET_OUT_FIND_RECORD_PARAM)
  151. # 按查询条件查询记录; by search filter search record
  152. result = self.sdk.FindRecord(self.loginID, inParam, outParam, 5000)
  153. if not result:
  154. print("FindRecord operate fail. " + self.sdk.GetLastErrorMessage())
  155. QMessageBox.about(self, '提示(prompt)', 'error:' + self.sdk.GetLastErrorMessage())
  156. else:
  157. print("FindRecord operate success! lFindeHandle:%s" % outParam.lFindeHandle)
  158. find_error = False
  159. while(True):
  160. count = 10
  161. inFindParam = NET_IN_FIND_NEXT_RECORD_PARAM()
  162. inFindParam.dwSize = sizeof(NET_IN_FIND_NEXT_RECORD_PARAM)
  163. inFindParam.lFindeHandle = outParam.lFindeHandle
  164. inFindParam.nFileCount = count
  165. outFindParam = NET_OUT_FIND_NEXT_RECORD_PARAM()
  166. outFindParam.dwSize = sizeof(NET_OUT_FIND_NEXT_RECORD_PARAM)
  167. outFindParam.nMaxRecordNum = count
  168. record_list = []
  169. for i in range(count):
  170. record = NET_TRAFFIC_LIST_RECORD()
  171. record.dwSize = sizeof(NET_TRAFFIC_LIST_RECORD)
  172. record.nAuthrityNum = 1
  173. record.stAuthrityTypes[0] = NET_AUTHORITY_TYPE()
  174. record.stAuthrityTypes[0].dwSize = sizeof(NET_AUTHORITY_TYPE)
  175. record_list.append(record)
  176. outFindParam.pRecordList = cast(
  177. (NET_TRAFFIC_LIST_RECORD * outFindParam.nMaxRecordNum)(*record_list), c_void_p)
  178. # 查找记录; search record
  179. result = self.sdk.FindNextRecord(inFindParam, outFindParam, 5000)
  180. if result:
  181. print("FindNextRecord operate number:%d" % outFindParam.nRetRecordNum)
  182. out_records = cast(outFindParam.pRecordList, POINTER(NET_TRAFFIC_LIST_RECORD * outFindParam.nRetRecordNum)).contents
  183. self.Query_tableWidget.setRowCount(self.row + outFindParam.nRetRecordNum)
  184. for i in range(outFindParam.nRetRecordNum):
  185. show_info = RecordInfo()
  186. show_info.get_alarm_info(out_records[i])
  187. item1 = QTableWidgetItem(show_info.plate_number_str)
  188. self.Query_tableWidget.setItem(self.row, self.column, item1)
  189. item2 = QTableWidgetItem(show_info.vehicle_owner_str)
  190. self.Query_tableWidget.setItem(self.row, self.column + 1, item2)
  191. item3 = QTableWidgetItem(show_info.start_time_str)
  192. self.Query_tableWidget.setItem(self.row, self.column + 2, item3)
  193. item4 = QTableWidgetItem(show_info.end_time_str)
  194. self.Query_tableWidget.setItem(self.row, self.column + 3, item4)
  195. item5 = QTableWidgetItem(show_info.auth_str)
  196. self.Query_tableWidget.setItem(self.row, self.column + 4, item5)
  197. item6 = QTableWidgetItem(show_info.record_number_str)
  198. self.Query_tableWidget.setItem(self.row, self.column + 5, item6)
  199. self.row += 1
  200. # find close
  201. if outFindParam.nRetRecordNum < count:
  202. break
  203. else:
  204. print("FindNextRecord operate fail. " + self.sdk.GetLastErrorMessage())
  205. find_error = True
  206. break
  207. self.clear_record_operate_detail()
  208. self.Query_tableWidget.viewport().update()
  209. self.sdk.FindRecordClose(outParam.lFindeHandle)
  210. if find_error:
  211. QMessageBox.about(self, '提示(prompt)', 'error:' + self.sdk.GetLastErrorMessage())
  212. else:
  213. if not no_prompt:
  214. QMessageBox.about(self, '提示(prompt)', "查询成功(Query Success)")
  215. # 获取允许名单输入框信息
  216. # Get the allowed list input box information
  217. def get_allowed_list_info(self):
  218. info = {}
  219. info['PlateNumber'] = self.PlateNo_lineEdit.text()
  220. info['VehicleOwner'] = self.VehicleOwner_lineEdit.text()
  221. info['StartTime'] = self.StartTime_lineEdit.text()
  222. info['EndTime'] = self.EndTime_lineEdit.text()
  223. info['Auth'] = self.SwitchAuthorize_lineEdit.text()
  224. info['RecordNo'] = self.RecordNo_lineEdit.text()
  225. if info['PlateNumber'] == '' or info['VehicleOwner'] == '' or \
  226. info['StartTime'] == '' or info['EndTime'] == '' or info['Auth'] == '':
  227. return False, info
  228. else:
  229. if len(info['PlateNumber'].encode('gb2312')) > 31 or \
  230. len(info['VehicleOwner'].encode('gb2312')) > 15:
  231. return False, info
  232. try:
  233. datetime.datetime.strptime(info['StartTime'], '%Y-%m-%d %H:%M:%S')
  234. datetime.datetime.strptime(info['EndTime'], '%Y-%m-%d %H:%M:%S')
  235. int(info['Auth'])
  236. except:
  237. return False, info
  238. return True, info
  239. # 信息格式化
  240. # info format
  241. def info_format(self, info):
  242. record = NET_TRAFFIC_LIST_RECORD()
  243. record.dwSize = sizeof(NET_TRAFFIC_LIST_RECORD)
  244. record.szPlateNumber = info['PlateNumber'].encode('gb2312')
  245. record.szMasterOfCar = info['VehicleOwner'].encode('gb2312')
  246. date = datetime.datetime.strptime(info['StartTime'], '%Y-%m-%d %H:%M:%S')
  247. record.stBeginTime = NET_TIME()
  248. record.stBeginTime.dwYear = date.year
  249. record.stBeginTime.dwMonth = date.month
  250. record.stBeginTime.dwDay = date.day
  251. record.stBeginTime.dwHour = date.hour
  252. record.stBeginTime.dwMinute = date.minute
  253. record.stBeginTime.dwSecond = date.second
  254. date = datetime.datetime.strptime(info['EndTime'], '%Y-%m-%d %H:%M:%S')
  255. record.stCancelTime = NET_TIME()
  256. record.stCancelTime.dwYear = date.year
  257. record.stCancelTime.dwMonth = date.month
  258. record.stCancelTime.dwDay = date.day
  259. record.stCancelTime.dwHour = date.hour
  260. record.stCancelTime.dwMinute = date.minute
  261. record.stCancelTime.dwSecond = date.second
  262. record.nAuthrityNum = 1
  263. record.stAuthrityTypes[0] = NET_AUTHORITY_TYPE()
  264. record.stAuthrityTypes[0].dwSize = sizeof(NET_AUTHORITY_TYPE)
  265. record.stAuthrityTypes[0].emAuthorityType = EM_NET_AUTHORITY_TYPE.NET_AUTHORITY_OPEN_GATE
  266. record.stAuthrityTypes[0].bAuthorityEnable = int(info['Auth'])
  267. return record
  268. # 允许名单操作
  269. # Allowed list operate
  270. def operate_record(self, type):
  271. verify, info = self.get_allowed_list_info()
  272. if not verify:
  273. QMessageBox.about(self, '提示(prompt)', "请输入有效数据(Please Enter Valid Data)")
  274. return -1
  275. else:
  276. inParam = NET_IN_OPERATE_TRAFFIC_LIST_RECORD()
  277. inParam.dwSize = sizeof(NET_IN_OPERATE_TRAFFIC_LIST_RECORD)
  278. inParam.emOperateType = type
  279. inParam.emRecordType = EM_NET_RECORD_TYPE.TRAFFICREDLIST
  280. if type == EM_RECORD_OPERATE_TYPE.NET_TRAFFIC_LIST_INSERT:
  281. operate_info = NET_INSERT_RECORD_INFO()
  282. operate_info.dwSize = sizeof(NET_INSERT_RECORD_INFO)
  283. record = self.info_format(info)
  284. operate_info.pRecordInfo = cast(pointer(record), POINTER(NET_TRAFFIC_LIST_RECORD))
  285. elif type == EM_RECORD_OPERATE_TYPE.NET_TRAFFIC_LIST_UPDATE:
  286. operate_info = NET_UPDATE_RECORD_INFO()
  287. operate_info.dwSize = sizeof(NET_UPDATE_RECORD_INFO)
  288. record = self.info_format(info)
  289. record.nRecordNo = int(info['RecordNo'])
  290. operate_info.pRecordInfo = cast(pointer(record), POINTER(NET_TRAFFIC_LIST_RECORD))
  291. else:
  292. operate_info = NET_REMOVE_RECORD_INFO()
  293. operate_info.dwSize = sizeof(NET_REMOVE_RECORD_INFO)
  294. operate_info.nRecordNo = int(info['RecordNo'])
  295. inParam.pstOpreateInfo = cast(pointer(operate_info), c_void_p)
  296. outParam = NET_OUT_OPERATE_TRAFFIC_LIST_RECORD()
  297. outParam.dwSize = sizeof(NET_OUT_OPERATE_TRAFFIC_LIST_RECORD)
  298. result = self.sdk.OperateTrafficList(self.loginID, inParam, outParam, 5000)
  299. if not result:
  300. print("OperateTrafficList operate fail. " + self.sdk.GetLastErrorMessage())
  301. return 0
  302. self.query_btn_onclick(no_prompt=True)
  303. self.clear_record_operate_detail()
  304. return 1
  305. # 增加按钮
  306. # Add button
  307. def add_record_btn_onclick(self):
  308. result = self.operate_record(EM_RECORD_OPERATE_TYPE.NET_TRAFFIC_LIST_INSERT)
  309. if result == 1:
  310. QMessageBox.about(self, '提示(prompt)', "添加成功(Add Success)")
  311. elif result == 0:
  312. QMessageBox.about(self, '提示(prompt)', "添加失败(Add Failed)")
  313. # 修改按钮
  314. # Modify button
  315. def modify_record_btn_onclick(self):
  316. if self.Query_tableWidget.currentRow() < 0:
  317. QMessageBox.about(self, '提示(prompt)', "请选择一条记录(Please Select A Record)")
  318. else:
  319. result = self.operate_record(EM_RECORD_OPERATE_TYPE.NET_TRAFFIC_LIST_UPDATE)
  320. if result == 1:
  321. QMessageBox.about(self, '提示(prompt)', "修改成功(Modify Success)")
  322. elif result == 0:
  323. QMessageBox.about(self, '提示(prompt)', "修改失败(Modify Failed)")
  324. # 删除按钮
  325. # Delete button
  326. def delete_record_btn_onclick(self):
  327. if self.Query_tableWidget.currentRow() < 0:
  328. QMessageBox.about(self, '提示(prompt)', "请选择一条记录(Please Select A Record)")
  329. else:
  330. result = self.operate_record(EM_RECORD_OPERATE_TYPE.NET_TRAFFIC_LIST_REMOVE)
  331. if result == 1:
  332. QMessageBox.about(self, '提示(prompt)', "删除成功(Modify Success)")
  333. elif result == 0:
  334. QMessageBox.about(self, '提示(prompt)', "删除失败(Modify Failed)")
  335. # 全部删除按钮
  336. # Delete all button
  337. def delete_all_record_btn_onclick(self):
  338. type = CtrlType.RECORDSET_CLEAR
  339. inParam = NET_CTRL_RECORDSET_PARAM()
  340. inParam.dwSize = sizeof(NET_CTRL_RECORDSET_PARAM)
  341. inParam.emType = EM_NET_RECORD_TYPE.TRAFFICREDLIST
  342. result = self.sdk.ControlDevice(self.loginID, type, inParam, 5000)
  343. if result:
  344. QMessageBox.about(self, '提示(prompt)', "全部删除成功(All Deleted Successfully)")
  345. else:
  346. print("ControlDevice operate fail. " + self.sdk.GetLastErrorMessage())
  347. QMessageBox.about(self, '提示(prompt)', "全部删除失败(All Delete Failed)")
  348. self.row = 0
  349. self.column = 0
  350. self.clear_record_operate_detail()
  351. self.Query_tableWidget.clear()
  352. self.Query_tableWidget.setRowCount(0)
  353. self.Query_tableWidget.viewport().update()
  354. self.Query_tableWidget.setHorizontalHeaderLabels(['车牌号(Plate No.)', '车主(Vehicle Owner)', '开始时间(Start Time)', '结束时间(End Time)', '开闸授权(Switch Authorize)', '记录号(Record No.)'])
  355. # 清除输入框
  356. def clear_record_operate_detail(self):
  357. self.PlateNo_lineEdit.setText('')
  358. self.VehicleOwner_lineEdit.setText('')
  359. self.StartTime_lineEdit.setText('')
  360. self.EndTime_lineEdit.setText('')
  361. self.SwitchAuthorize_lineEdit.setText('')
  362. self.RecordNo_lineEdit.setText('')
  363. # 实现断线回调函数功能
  364. def DisConnectCallBack(self, lLoginID, pchDVRIP, nDVRPort, dwUser):
  365. self.setWindowTitle("允许名单(AllowedList)-离线(OffLine)")
  366. # 实现断线重连回调函数功能
  367. def ReConnectCallBack(self, lLoginID, pchDVRIP, nDVRPort, dwUser):
  368. self.setWindowTitle('允许名单(AllowedList)-在线(OnLine)')
  369. # 关闭主窗口时清理资源
  370. def closeEvent(self, event):
  371. event.accept()
  372. if self.loginID:
  373. self.sdk.Logout(self.loginID)
  374. self.loginID = 0
  375. self.sdk.Cleanup()
  376. self.Query_tableWidget.clear()
  377. self.Query_tableWidget.setRowCount(0)
  378. if __name__ == '__main__':
  379. app = QApplication(sys.argv)
  380. my_wnd = AllowedListWnd()
  381. my_wnd.show()
  382. sys.exit(app.exec_())