From 503d0b5bc27bd30169349332f95cc5e9c9d8055e Mon Sep 17 00:00:00 2001 From: LiuYuancheng Date: Mon, 24 Jul 2023 22:45:14 +0800 Subject: [PATCH] update the code document and format the code of data manager module. --- src/metroEmuUI/dataMgr.py | 188 ++++++++++++++++++++------------------ 1 file changed, 99 insertions(+), 89 deletions(-) diff --git a/src/metroEmuUI/dataMgr.py b/src/metroEmuUI/dataMgr.py index 5d7f09b..f846e2a 100644 --- a/src/metroEmuUI/dataMgr.py +++ b/src/metroEmuUI/dataMgr.py @@ -2,21 +2,20 @@ #----------------------------------------------------------------------------- # Name: DataMgr.py # -# Purpose: Data manager module used to control all the other data processing +# Purpose: Data manager module is used to control all the other data processing # modules and store the interprocess/result data. # # Author: Yuancheng Liu # # Created: 2023/06/07 # Version: v_0.1.2 -# Copyright: n.a -# License: n.a +# Copyright: Copyright (c) 2023 LiuYuancheng +# License: MIT License #----------------------------------------------------------------------------- import time import json import threading -from datetime import datetime import metroEmuGobal as gv import Log @@ -40,16 +39,16 @@ def parseIncomeMsg(msg): #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- class DataManager(threading.Thread): - """ The data manager is a module running parallel with the main thread to - handle the data-IO with dataBase and the monitor hub's data fetching/ - change request. + """ The data manager is a module running parallel with the main App UI thread + to handle the data-IO such as input the current sensor state to PLC and + accept PLC's coil out request. """ def __init__(self, parent) -> None: threading.Thread.__init__(self) self.parent = parent self.terminate = False + # Init a udp server to accept all the other plc module's data fetch/set request. self.server = udpCom.udpServer(None, gv.UDP_PORT) - self.lastUpdate = datetime.now() self.daemon = True # init the local sensors data record dictionary self.sensorsDict = { @@ -58,6 +57,7 @@ def __init__(self, parent) -> None: 'ccline': None, 'mtline': None } + self.sensorPlcUpdateT = time.time() # init the local station data record dictionary self.stationsDict = { 'weline': None, @@ -65,6 +65,7 @@ def __init__(self, parent) -> None: 'ccline': None, 'mtline': None } + self.stationPlcUpdateT = time.time() # init the local train speed state dictionary self.trainsDict = { 'weline': None, @@ -72,48 +73,62 @@ def __init__(self, parent) -> None: 'ccline': None, 'mtline': None } + self.trainPlcUpdateT= time.time() gv.gDebugPrint("datamanager init finished.", logType=gv.LOG_INFO) #----------------------------------------------------------------------------- - def updateSensorsData(self): - if gv.iMapMgr: - for key in self.sensorsDict.keys(): - sensorAgent = gv.iMapMgr.getSensors(trackID=key) - self.sensorsDict[key] = sensorAgent.getSensorsState() - + # Define all the data fetching request here: + # the fetch function will handle the Plc components state fetch request by: convert + # the json string to dict, then fill the input reqDict with the data and return. + # return json.dumps({'result': 'failed'}) if process data error. + def fetchSensorInfo(self, reqJsonStr): + respStr = json.dumps({'result': 'failed'}) + try: + reqDict = json.loads(reqJsonStr) + self.sensorPlcUpdateT = time.time() + self.updateSensorsData() + for key in reqDict.keys(): + if key in self.sensorsDict.keys(): reqDict[key] = self.sensorsDict[key] + respStr = json.dumps(reqDict) + except Exception as err: + gv.gDebugPrint("fetchSensorInfo() Error: %s" %str(err), logType=gv.LOG_EXCEPT) + return respStr + #----------------------------------------------------------------------------- - def updateStationsData(self): - if gv.iMapMgr: - for key in self.stationsDict.keys(): - self.stationsDict[key] = [] - for stationAgent in gv.iMapMgr.getStations(trackID=key): - state = 1 if stationAgent.getDockState() else 0 - self.stationsDict[key].append(state) + def fetchStationInfo(self, reqJsonStr): + respStr = json.dumps({'result': 'failed'}) + try: + reqDict = json.loads(reqJsonStr) + self.stationPlcUpdateT = time.time() + self.updateStationsData() + for key in reqDict.keys(): + if key in self.stationsDict.keys(): reqDict[key] = self.stationsDict[key] + respStr = json.dumps(reqDict) + except Exception as err: + gv.gDebugPrint("fetchStationInfo() Error: %s" %str(err), logType=gv.LOG_EXCEPT) + return respStr #----------------------------------------------------------------------------- - def updateTrainsData(self): - if gv.iMapMgr: - for key in self.stationsDict.keys(): - self.trainsDict[key] = [] - for train in gv.iMapMgr.getTrains(trackID=key): - state = 0 if train.getTrainSpeed() == 0 else 1 - self.trainsDict[key].append(state) - - #----------------------------------------------------------------------------- - def run(self): - """ Thread run() function will be called by start(). """ - time.sleep(1) - gv.gDebugPrint("datamanager started.", logType=gv.LOG_INFO) - self.server.serverStart(handler=self.msgHandler) - gv.gDebugPrint("DataManager running finished.", logType=gv.LOG_INFO) + def fetchTrainInfo(self, reqJsonStr): + respStr = json.dumps({'result': 'failed'}) + try: + reqDict = json.loads(reqJsonStr) + self.trainPlcUpdateT = time.time() + self.updateTrainsData() + for key in reqDict.keys(): + if key in self.trainsDict.keys(): reqDict[key] = self.trainsDict[key] + respStr = json.dumps(reqDict) + except Exception as err: + gv.gDebugPrint("fetchTrainInfo() Error: %s" %str(err), logType=gv.LOG_EXCEPT) + return respStr #----------------------------------------------------------------------------- def msgHandler(self, msg): """ Function to handle the data-fetch/control request from the monitor-hub. Args: - msg (str/bytes): _description_ + msg (str/bytes): incoming data from PLC modules though UDP. Returns: - bytes: message bytes reply to the monitor hub side. + bytes: message bytes needs to reply to the PLC. """ gv.gDebugPrint("Incomming message: %s" % str(msg), logType=gv.LOG_INFO) if msg == b'': return None @@ -150,91 +165,86 @@ def msgHandler(self, msg): if isinstance(resp, str): resp = resp.encode('utf-8') #gv.gDebugPrint('reply: %s' %str(resp), logType=gv.LOG_INFO ) return resp - - #----------------------------------------------------------------------------- - def fetchSensorInfo(self, reqJsonStr): - reqDict = json.loads(reqJsonStr) - self.updateSensorsData() - respStr= json.dumps({'result': 'failed'}) - try: - for key in reqDict.keys(): - if key in self.sensorsDict.keys(): - reqDict[key] = self.sensorsDict[key] - respStr = json.dumps(reqDict) - except Exception as err: - gv.gDebugPrint("fetchSensorInfo() Error: %s" %str(err), logType=gv.LOG_EXCEPT) - return respStr #----------------------------------------------------------------------------- - def fetchStationInfo(self, reqJsonStr): - reqDict = json.loads(reqJsonStr) - self.updateStationsData() - respStr = json.dumps({'result': 'failed'}) - try: - for key in reqDict.keys(): - if key in self.stationsDict.keys(): - reqDict[key] = self.stationsDict[key] - respStr = json.dumps(reqDict) - except Exception as err: - gv.gDebugPrint("fetchStationInfo() Error: %s" %str(err), logType=gv.LOG_EXCEPT) - return respStr + def run(self): + """ Thread run() function will be called by start(). """ + time.sleep(1) + gv.gDebugPrint("datamanager subthread started.", logType=gv.LOG_INFO) + self.server.serverStart(handler=self.msgHandler) + gv.gDebugPrint("DataManager running finished.", logType=gv.LOG_INFO) #----------------------------------------------------------------------------- - def fetchTrainInfo(self, reqJsonStr): - reqDict = json.loads(reqJsonStr) - self.updateTrainsData() - respStr = json.dumps({'result': 'failed'}) - try: - for key in reqDict.keys(): - if key in self.trainsDict.keys(): - reqDict[key] = self.trainsDict[key] - respStr = json.dumps(reqDict) - except Exception as err: - gv.gDebugPrint("fetchTrainInfo() Error: %s" %str(err), logType=gv.LOG_EXCEPT) - return respStr + # define all the set() function here: + # set function will handle the Plc components state set request by: convert + # the json string to dict, the change the components state in map manager. - #----------------------------------------------------------------------------- def setSignals(self, reqJsonStr): - reqDict = json.loads(reqJsonStr) respStr = json.dumps({'result': 'failed'}) try: + reqDict = json.loads(reqJsonStr) if gv.iMapMgr: for key, val in reqDict.items(): gv.iMapMgr.setSingals(key, val) respStr = json.dumps({'result': 'success'}) - respStr = json.dumps(reqDict) except Exception as err: gv.gDebugPrint("setSignals() Error: %s" %str(err), logType=gv.LOG_EXCEPT) return respStr #----------------------------------------------------------------------------- - def setTrainsPower(self, reqJsonStr): - reqDict = json.loads(reqJsonStr) + def setStationSignals(self, reqJsonStr): respStr = json.dumps({'result': 'failed'}) try: + reqDict = json.loads(reqJsonStr) if gv.iMapMgr: for key, val in reqDict.items(): - gv.iMapMgr.setTainsPower(key, val) + gv.iMapMgr.setStationSignal(key, val) respStr = json.dumps({'result': 'success'}) - respStr = json.dumps(reqDict) except Exception as err: - gv.gDebugPrint("setTrainsPower() Error: %s" %str(err), logType=gv.LOG_EXCEPT) + gv.gDebugPrint("setStationSignals() Error: %s" %str(err), logType=gv.LOG_EXCEPT) return respStr #----------------------------------------------------------------------------- - def setStationSignals(self, reqJsonStr): - reqDict = json.loads(reqJsonStr) + def setTrainsPower(self, reqJsonStr): respStr = json.dumps({'result': 'failed'}) try: + reqDict = json.loads(reqJsonStr) if gv.iMapMgr: for key, val in reqDict.items(): - gv.iMapMgr.setStationSignal(key, val) + gv.iMapMgr.setTainsPower(key, val) respStr = json.dumps({'result': 'success'}) - respStr = json.dumps(reqDict) except Exception as err: - gv.gDebugPrint("setStationSignals() Error: %s" %str(err), logType=gv.LOG_EXCEPT) + gv.gDebugPrint("setTrainsPower() Error: %s" %str(err), logType=gv.LOG_EXCEPT) return respStr + #----------------------------------------------------------------------------- + # define() all the update function here, update function will update the local + # components record from the map manager. + + def updateSensorsData(self): + if gv.iMapMgr: + for key in self.sensorsDict.keys(): + sensorAgent = gv.iMapMgr.getSensors(trackID=key) + self.sensorsDict[key] = sensorAgent.getSensorsState() + + #----------------------------------------------------------------------------- + def updateStationsData(self): + if gv.iMapMgr: + for key in self.stationsDict.keys(): + self.stationsDict[key] = [] + for stationAgent in gv.iMapMgr.getStations(trackID=key): + state = 1 if stationAgent.getDockState() else 0 + self.stationsDict[key].append(state) + + #----------------------------------------------------------------------------- + def updateTrainsData(self): + if gv.iMapMgr: + for key in self.stationsDict.keys(): + self.trainsDict[key] = [] + for train in gv.iMapMgr.getTrains(trackID=key): + state = 0 if train.getTrainSpeed() == 0 else 1 + self.trainsDict[key].append(state) + #----------------------------------------------------------------------------- def stop(self): """ Stop the thread."""