From 914fd7a6af6718156d42939afc384e85f0306ea0 Mon Sep 17 00:00:00 2001 From: asmithie13 Date: Tue, 27 Feb 2024 23:17:54 -0500 Subject: [PATCH 01/10] Added new PLC example. --- PLC_Files/PLC2.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 PLC_Files/PLC2.txt diff --git a/PLC_Files/PLC2.txt b/PLC_Files/PLC2.txt new file mode 100644 index 00000000..15e65b68 --- /dev/null +++ b/PLC_Files/PLC2.txt @@ -0,0 +1,11 @@ +SwitchOcc or not SwitchRightOcc +SWITCH + +SwitchOcc or SwitchRightOcc +CurrentLIGHT + +SwitchOcc +LeftLIGHT + +not SwitchOcc or SwitchRightOcc +RightLIGHT \ No newline at end of file From 80156e3734e10515b34538b8ea1dba52cacf11b2 Mon Sep 17 00:00:00 2001 From: asmithie13 Date: Thu, 29 Feb 2024 15:03:35 -0500 Subject: [PATCH 02/10] Added that blocks can have multiple special attributes and added lights to the readTrackFile function. --- PLC_Files/__pycache__/Parser.cpython-311.pyc | Bin 4572 -> 4572 bytes Track_Resources/Block.py | 6 +- .../__pycache__/Block.cpython-311.pyc | Bin 834 -> 923 bytes Wayside SW/Red_Line.csv | 132 +++++++++--------- Wayside SW/app.py | 45 +++--- 5 files changed, 97 insertions(+), 86 deletions(-) diff --git a/PLC_Files/__pycache__/Parser.cpython-311.pyc b/PLC_Files/__pycache__/Parser.cpython-311.pyc index 676c996a05d7c92f604269a72c1146134631235c..3ffc87fd3147e9b18b5d134569df9122330c7cfb 100644 GIT binary patch delta 20 acmcbkd`FpkIWI340}%AM-rLB1Q4jz?SOy{h delta 20 acmcbkd`FpkIWI340}#w-y1SA4q96c2Mg{Qz diff --git a/Track_Resources/Block.py b/Track_Resources/Block.py index 20dbeedc..e73ffb61 100644 --- a/Track_Resources/Block.py +++ b/Track_Resources/Block.py @@ -1,10 +1,12 @@ # Define the Block class class Block: - def __init__(self, light, crossing, switch, state,occupied,id,speedLimit,authority): + def __init__(self, light, crossing, switch, lightState, crossingState, switchState, occupied,id,speedLimit,authority): self.LIGHT = light self.CROSSING = crossing self.SWITCH = switch - self.state = state + self.lightState = lightState + self.crossingState = crossingState + self.switchState = switchState self.occupied = occupied self.ID = id self.speedLimit = speedLimit diff --git a/Track_Resources/__pycache__/Block.cpython-311.pyc b/Track_Resources/__pycache__/Block.cpython-311.pyc index e01afb1bb06b03652d0c9d3e1d1b5983817178b3..760a9b10c39dc87f79f2a3a68ff3cf53e5cf9b56 100644 GIT binary patch delta 385 zcmX@aHk+MyIWI340}%W?{UG(S_Gd-guxFoS8^%ie( zQGRi8W?njk%UxWaS(2O)JlTX%i;;VBJfo(35y(|VAjjNd%1kNZ1@ZWRL@`K6L1FT2 z##%TZlX-=wLku;FY2*kzaK;i>4BO~Jn7H&qM Sv6#e1kk}U_30{~Qu*m?`^;Nt8 delta 318 zcmbQueu#~CIWI340}yb!-b}5V$XhPP3F1Kk6Od*G;?HFhXO*g^Fa$GbGWuz9++y|d zboU6k#o-*}9~|uI=YESVINUSD+2a;#@#I2AEk@4Ca~L&+Z!u-26mbK!7x4gzVvxa; zpD@-c*#Q|13^zojI#_zRZb&EqDc&1mGC+zODmZyElP|9@P}xd`A`u`}BsBRglTtkg ztMUg1Oah_= True if Light - #Index [1] of each Block => True if Crossing - #Index [2] of each Block => True if Switch - #Index [3] of each Block => Default - #Index [4] of each Block => True if Occupied + LIGHT_CONST = [True, False, False, False,None,None,False] + CROSSING_CONST = [False, True, False, None,True,None,False] + SWITCH_LIGHT_CONST = [True, False, True, False,None,True,False] + NORMAL_CONST = [False, False, False, None,None,None,False] #Switch Directions self.B5_Switch_Positions = ["B6","C11"] @@ -75,7 +84,7 @@ def __init__(self): A2 = Block(*NORMAL_CONST,"A2",50,None) A3 = Block(*CROSSING_CONST,"A3",50,None) A4 = Block(*NORMAL_CONST,"A4",50,None) - A5 = Block(*SWITCH_CONST,"A5",50,None) + A5 = Block(*SWITCH_LIGHT_CONST,"A5",50,None) B6 = Block(*LIGHT_CONST,"B6",50,None) B7 = Block(*NORMAL_CONST,"B7",50,None) B8 = Block(*NORMAL_CONST,"B8",50,None) From 65949d71adb3dd6cb36f7142ebe306ad655b42b2 Mon Sep 17 00:00:00 2001 From: asmithie13 Date: Thu, 29 Feb 2024 15:25:55 -0500 Subject: [PATCH 03/10] Updated prior hardcoded states to allow for more than one state ie a switch and a light. --- Wayside SW/app.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Wayside SW/app.py b/Wayside SW/app.py index ffe657ea..a48f55e2 100644 --- a/Wayside SW/app.py +++ b/Wayside SW/app.py @@ -107,7 +107,7 @@ def __init__(self): self.specialRedBlocks = [] for block in self.allRedBlocks: - if block.state == True: self.specialRedBlocks.append(block) + if block.LIGHT or block.CROSSING or block.SWITCH : self.specialRedBlocks.append(block) #Create Parser Object self.FileParser = Parser(None,self.AllBlocks) #Currently empty onject @@ -210,8 +210,8 @@ def blockActions(self): selectedBlock = self.BlockArray[selectedIndex] if selectedBlock.LIGHT and self.label_7.text(): - self.greenButton.setEnabled(not selectedBlock.state and self.label_7.text() == "MANUAL") - self.redButton.setEnabled(selectedBlock.state and self.label_7.text() == "MANUAL") + self.greenButton.setEnabled(not selectedBlock.lightState and self.label_7.text() == "MANUAL") + self.redButton.setEnabled(selectedBlock.lightState and self.label_7.text() == "MANUAL") self.upCrossingButton.setEnabled(False) self.downCrossingButton.setEnabled(False) self.switchButton.setEnabled(False) @@ -220,28 +220,28 @@ def blockActions(self): self.downCrossingButton.setStyleSheet("") self.label_11.setText("") - if selectedBlock.state: + if selectedBlock.lightState: self.greenButton.setStyleSheet('QPushButton {background-color: green; color: yellow;}') self.redButton.setStyleSheet("") - elif not selectedBlock.state: + elif not selectedBlock.lightState: self.greenButton.setStyleSheet("") self.redButton.setStyleSheet('QPushButton {background-color: red; color: yellow;}') elif selectedBlock.CROSSING and self.selectLine.isChecked(): self.greenButton.setEnabled(False) self.redButton.setEnabled(False) - self.upCrossingButton.setEnabled(not selectedBlock.state and self.label_7.text() == "MANUAL") - self.downCrossingButton.setEnabled(selectedBlock.state and self.label_7.text() == "MANUAL") + self.upCrossingButton.setEnabled(not selectedBlock.crossingState and self.label_7.text() == "MANUAL") + self.downCrossingButton.setEnabled(selectedBlock.crossingState and self.label_7.text() == "MANUAL") self.switchButton.setEnabled(False) self.greenButton.setStyleSheet("") self.redButton.setStyleSheet("") self.label_11.setText("") - if selectedBlock.state: + if selectedBlock.crossingState: self.upCrossingButton.setStyleSheet("background-color: yellow") self.downCrossingButton.setStyleSheet("") - elif not selectedBlock.state: + elif not selectedBlock.crossingState: self.upCrossingButton.setStyleSheet("") self.downCrossingButton.setStyleSheet("background-color: yellow") @@ -252,7 +252,7 @@ def blockActions(self): self.downCrossingButton.setEnabled(False) self.switchButton.setEnabled(True and self.label_7.text() == "MANUAL") - if selectedBlock.state == True: + if selectedBlock.switchState: self.label_11.setText(self.SwitchBlocks[1]) else: @@ -265,7 +265,7 @@ def blockActions(self): def greenButtonPushed(self): selectedIndex = self.blockMenu.currentIndex() - self.BlockArray[selectedIndex].state = True + self.BlockArray[selectedIndex].lightState = True self.greenButton.setEnabled(False) self.redButton.setEnabled(True) self.greenButton.setStyleSheet('QPushButton {background-color: green; color: yellow;}') @@ -274,7 +274,7 @@ def greenButtonPushed(self): def redButtonPushed(self): selectedIndex = self.blockMenu.currentIndex() - self.BlockArray[selectedIndex].state = False + self.BlockArray[selectedIndex].lightState = False self.greenButton.setEnabled(True) self.redButton.setEnabled(False) self.greenButton.setStyleSheet("") @@ -283,7 +283,7 @@ def redButtonPushed(self): def upButtonPushed(self): selectedIndex = self.blockMenu.currentIndex() - self.BlockArray[selectedIndex].state = True + self.BlockArray[selectedIndex].crossingState = True self.upCrossingButton.setEnabled(False) self.downCrossingButton.setEnabled(True) self.upCrossingButton.setStyleSheet("background-color: yellow") @@ -292,7 +292,7 @@ def upButtonPushed(self): def downButtonPushed(self): selectedIndex = self.blockMenu.currentIndex() - self.BlockArray[selectedIndex].state = False + self.BlockArray[selectedIndex].crossingState = False self.upCrossingButton.setEnabled(True) self.downCrossingButton.setEnabled(False) self.upCrossingButton.setStyleSheet("") @@ -301,7 +301,7 @@ def downButtonPushed(self): def switchButtonPushed(self): selectedIndex = self.blockMenu.currentIndex() - self.BlockArray[selectedIndex].state = not self.BlockArray[selectedIndex].state + self.BlockArray[selectedIndex].switchState = not self.BlockArray[selectedIndex].switchState current_text = self.label_11.text() if current_text == self.B5_Switch_Positions[0]: @@ -400,7 +400,7 @@ def updateBlockStates(self, arr): self.label_24.setText("") - if selectedBlock.state: + if selectedBlock.lightState: self.label_19.setText("Green") self.label_22.setText("") else: @@ -410,14 +410,14 @@ def updateBlockStates(self, arr): self.label_24.setText("") - if selectedBlock.state: + if selectedBlock.crossingState: self.label_19.setText("") self.label_22.setText("Up") else: self.label_19.setText("") self.label_22.setText("Down") elif selectedBlock.SWITCH: - if selectedBlock.state: + if selectedBlock.switchState: self.label_19.setText("") self.label_22.setText("") self.label_24.setText("B6") From b761bae478cc0186f16402a4760ae4d4061b01c5 Mon Sep 17 00:00:00 2001 From: asmithie13 Date: Thu, 29 Feb 2024 16:13:00 -0500 Subject: [PATCH 04/10] added crossingBlocks being accounted for in excel parser. --- Wayside SW/app.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Wayside SW/app.py b/Wayside SW/app.py index a48f55e2..c7c5a8e1 100644 --- a/Wayside SW/app.py +++ b/Wayside SW/app.py @@ -21,6 +21,7 @@ def sort_by_number(block): def readTrackFile(fileName): totalBlocks = [] lightBlocks = {} + crossingBlocks = [] fileName = "Wayside SW/" + fileName with open(fileName, "r") as fileObject: readObj = csv.reader(fileObject, delimiter=",") @@ -45,7 +46,9 @@ def readTrackFile(fileName): #numbers = [part for part in line[6].split('-') if part.isdigit()] numbers = re.findall(r'\b(\d+)-(\d+)\b', line[6]) - lightBlocks.update({num: False for pair in numbers for num in pair}) + current = {num: False for pair in numbers for num in pair} + crossingBlocks.append(list(current.keys())) + lightBlocks.update(current) tempBlock = Block(hasLightTemp,hasCrossingTemp,hasSwitchTemp,lightState,crossingState,switchState,False,blockId, line[5],None) totalBlocks.append(tempBlock) From c72fe4f22d0d7ea6109f8e5bb355bd7cbc902522 Mon Sep 17 00:00:00 2001 From: asmithie13 Date: Thu, 29 Feb 2024 20:31:10 -0500 Subject: [PATCH 05/10] Fixed red line csv and added more logic for triple pairs of blocks --- PLC_Files/Parser.py | 77 +++---------------- PLC_Files/__pycache__/Parser.cpython-311.pyc | Bin 4572 -> 2440 bytes Wayside SW/Red_Line.csv | 6 +- Wayside SW/app.py | 14 ++-- 4 files changed, 22 insertions(+), 75 deletions(-) diff --git a/PLC_Files/Parser.py b/PLC_Files/Parser.py index 6811b9aa..cbe9ad65 100644 --- a/PLC_Files/Parser.py +++ b/PLC_Files/Parser.py @@ -8,77 +8,24 @@ from Track_Resources.Block import Block class Parser(): - def __init__(self, inputPLC, outPuttedBlocks): + def __init__(self, inputPLC,CrossingTriplesIDS,outPuttedBlocks): self.inputPLC = inputPLC + self.CrossingTriplesIDS = CrossingTriplesIDS self.outPuttedBlocks = outPuttedBlocks - self.commandsToRun = [] - self.blockOccsByID = [False] * 26 #initially no blocks are occupied - - def blockState(self): #will break up inputPLC into what commands to run based off of conditions of occupancies - lines = self.inputPLC.split('\n') - index = 0 - alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' - - for char in alphabet: - occupied_blocks = [block for block in self.outPuttedBlocks if char in block.ID and block.occupied] - self.blockOccsByID[index] = True if occupied_blocks else False - index = index + 1 - - index = 0 - indexOcc = 0 - indexNotOcc = 0 - indexNextOcc = 0 - indexEnd = len(lines) - 1 - for length in range(2,25): #start with 2 for C - if (length + 1) >= 25 or not ("OCCUPIED " + alphabet[length]) in lines: break - - isOcc = False - - if (length + 1) < 25 and "OCCUPIED " + alphabet[length + 1] in lines : indexNextOcc = lines.index("OCCUPIED " + alphabet[length + 1]) - else: indexNextOcc = indexEnd - - indexOcc = lines.index("OCCUPIED " + alphabet[length]) - indexNotOcc = lines.index("OCCUPIED !" + alphabet[length]) - - if self.blockOccsByID[length]: - isOcc = True - - if isOcc: - indexLoopStart = indexOcc + 1 - indexLoopEnd = indexNotOcc - 1 - else: - indexLoopStart = indexNotOcc + 1 - if indexNextOcc != indexEnd : indexLoopEnd = indexNextOcc - 1 - else: indexLoopEnd = indexNextOcc + 1 - - for pos in range(indexLoopStart, indexLoopEnd): - self.commandsToRun.append(lines[pos]) - - def parsePLC(self): - self.blockState() - - for line in self.commandsToRun: - if line == '' : break - tokens = line.strip().split() - command = tokens[0] - parameters = tokens[1:] - block_id = parameters[0][1:] if parameters[0][0] == '!' else parameters[0] - match = [block for block in self.outPuttedBlocks if block.ID == block_id] - - if command == "LIGHT" or command == "CROSSING": - if parameters[0][0] != '!': - match[0].state = True - else: - match[0].state = False + lines = self.inputPLC.split('\n') + switchLogic, curLightLogic, leftLightLogic, rightLightLogic = lines[0], lines[3], lines[6], lines[9] - #CHANGE TO BE LIKE ABOVE JUST WITH DEFAULT STATES + CrossingTripleBlocks = [ + [block for row in self.CrossingTriplesIDS for element in row + for block in self.outPuttedBlocks if element == block.ID[1:]][i:i+3] + for i in range(0, len(self.CrossingTriplesIDS)*3, 3) + ] - elif command == "SWITCH": - if int(parameters[1][1:]) - 1 == int(parameters[0][1:]): match[0].state = True - else : match[0].state = False + - self.commandsToRun = [] + + diff --git a/PLC_Files/__pycache__/Parser.cpython-311.pyc b/PLC_Files/__pycache__/Parser.cpython-311.pyc index 3ffc87fd3147e9b18b5d134569df9122330c7cfb..10feb43359f24c00351d86c7a28492c3f5bcb841 100644 GIT binary patch literal 2440 zcma(SOKcNIbY^$`!HHw@2~a3WfU2n_>JkL4iXudb1C20FN}xrSqs8%Vl1(;VGrMU@ zWQ(Xug{dMHq#_V%)u@N`lS**RfkO^Gq&FL_RBKPIdP=2Ai;_wer@onuo!y2*->%=j zH}mHG-}t+5ID`QHivKPz^9cPxnK}eEiFH3l=mC zL6Knj2eL$$NzR=Z8Wv6E`f+x;h>J)B%7G#WTwOmZ^1wCHAR*9+Q!(BOD*3{cF_7%B zcJ&ZV*OmO}6`~YWS?@~>S`iKQrVK-tnCm+DA?UI?LTIrG%@^4LNT*J90K7=$PG_!y zn|j93Clw>ppO+Iv`B=^*WPQTW3YoW!v5rA`Qq~QbWV*Ue9?$gl^uEama6&w5T*j{Uo)9e=caanpxtE`Y3^Z@U2mCuMZMG1E(Z@5n@@Q@i0iBMffgla$w0X1xf){?_lZ$ z4iVY|YgByAPZ2GjCp&a?H~iLI~v=xw5XvMr?`G)Cak`T!1v=p?LX9;bw z7ol!d(T$uoSvWHjuQw(gMQGP}Hyq2V`WYbVLN2nEs*?cyGmC75!xym|-_=(J-TZQA z?LeD(Aa3(plC_;XZ21Q3fs=m^=Uf&6IaF59=|tvi~BlG%33S$NJu z-(a|QF}eD|>WyCpS5Iv~oR_i9H`GzZEQ&Q+$(WB_GL}y-s0vhwWb>o4#jA4Oi7v>Z zvV5wNmvyU2pH__ASW+8Ra#lDuMUu+snBlN3syt%2_y}QpTLOE$H=lFWS@;v3_ULum z3jnMetYBfY^o{$dzCbgtKXMXPi|+X{{A={+v*^)Sqp`BDcK+h(dq0m=2Ch~< z{Ky=*R!NJM>sd2BT#=N@_=G8`mGf#f*i&x0JG78`(r*i%%&@%w?MHhLKJ5BBxA2;I z5%_DMUKWTpF6Ru9XqsX9 zvxS13m#o$+B%7NMFUz_%MRKwpXGJ8m=N+GqQHqTSo9bY<6ZRSM4s6gnLjM*J%pS%y z6q;pE4egj^kL^d%UGvjl-1_|1L-N)1H^oQA@6Y{o;c@?u{mbuHkM)|zdRL5Ud(v!A zRwI|p$feol8sg`Iw{phLf*&WiW7g(!v`ZAZ`P+Qv&ZSPcIHlgKZN literal 4572 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 PO@C1Oe|*lU;=}&~z;Grz diff --git a/Wayside SW/Red_Line.csv b/Wayside SW/Red_Line.csv index db49fe91..ba224b01 100644 --- a/Wayside SW/Red_Line.csv +++ b/Wayside SW/Red_Line.csv @@ -13,7 +13,7 @@ Red,D,11,75,-0.5,40,RAILWAY CROSSING,,-0.38,3.75 Red,D,12,75,-1,40,,,-0.75,3 Red,E,13,70,-2,40,,,-1.4,1.6 Red,E,14,60,-1.25,40,,,-0.75,0.85 -Red,E,15,60,-1,40,SWITCH (15-16; 1-16),,-0.6,0.25 +Red,E,15,60,-1,40,SWITCH (15-16; 15-1),,-0.6,0.25 Red,F,16,50,-0.5,40,STATION: HERRON AVE,Left/Right,-0.25,0 Red,F,17,200,-0.5,55,,,-1,-1 Red,F,18,400,-0.06025,70,,,-0.24,-1.24 @@ -30,7 +30,7 @@ Red,H,28,50,0,70,UNDERGROUND,,0,-1.24 Red,H,29,60,0,70,UNDERGROUND,,0,-1.24 Red,H,30,60,0,70,UNDERGROUND,,0,-1.24 Red,H,31,50,0,70,UNDERGROUND,,0,-1.24 -Red,H,32,50,0,70,SWITCH (32-33; 33-72); UNDERGROUND,,0,-1.24 +Red,H,32,50,0,70,SWITCH (32-33; 32-72); UNDERGROUND,,0,-1.24 Red,H,33,50,0,70,UNDERGROUND,,0,-1.24 Red,H,34,50,0,70,UNDERGROUND,,0,-1.24 Red,H,35,50,0,70,STATION; STEEL PLAZA; UNDERGROUND,Left/Right,0,-1.24 @@ -41,7 +41,7 @@ Red,H,39,50,0,70,UNDERGROUND,,0,-1.24 Red,H,40,60,0,70,UNDERGROUND,,0,-1.24 Red,H,41,60,0,70,UNDERGROUND,,0,-1.24 Red,H,42,50,0,70,UNDERGROUND,,0,-1.24 -Red,H,43,50,0,70,SWITCH (43-44; 44-67); UNDERGROUND,,0,-1.24 +Red,H,43,50,0,70,SWITCH (43-44; 43-67); UNDERGROUND,,0,-1.24 Red,H,44,50,0,70,UNDERGROUND,,0,-1.24 Red,H,45,50,0,70,STATION; FIRST AVE; UNDERGROUND,Left/Right,0,-1.24 Red,I,46,75,0,70,,,0,-1.24 diff --git a/Wayside SW/app.py b/Wayside SW/app.py index c7c5a8e1..36a51f08 100644 --- a/Wayside SW/app.py +++ b/Wayside SW/app.py @@ -18,10 +18,9 @@ def sort_by_number(block): return int(block[1:]) # Convert the string to an integer, excluding the 'B' prefix #Function that reads all blocks from a *.csv file and assigns block attributes: -def readTrackFile(fileName): +def readTrackFile(fileName,crossingTriples): totalBlocks = [] lightBlocks = {} - crossingBlocks = [] fileName = "Wayside SW/" + fileName with open(fileName, "r") as fileObject: readObj = csv.reader(fileObject, delimiter=",") @@ -47,7 +46,7 @@ def readTrackFile(fileName): #numbers = [part for part in line[6].split('-') if part.isdigit()] numbers = re.findall(r'\b(\d+)-(\d+)\b', line[6]) current = {num: False for pair in numbers for num in pair} - crossingBlocks.append(list(current.keys())) + crossingTriples.append(list(current.keys())) lightBlocks.update(current) tempBlock = Block(hasLightTemp,hasCrossingTemp,hasSwitchTemp,lightState,crossingState,switchState,False,blockId, line[5],None) @@ -60,7 +59,6 @@ def readTrackFile(fileName): block.LIGHT = True block.lightState = False - return totalBlocks #Return a list of all blocks within the file class MyApp(QMainWindow): @@ -76,6 +74,7 @@ def __init__(self): # Global constants for LIGHT, CROSSING, and SWITCH LIGHT_CONST = [True, False, False, False,None,None,False] CROSSING_CONST = [False, True, False, None,True,None,False] + SWITCH_CONST = [False, False, True, None,None,True,False] SWITCH_LIGHT_CONST = [True, False, True, False,None,True,False] NORMAL_CONST = [False, False, False, None,None,None,False] @@ -87,7 +86,7 @@ def __init__(self): A2 = Block(*NORMAL_CONST,"A2",50,None) A3 = Block(*CROSSING_CONST,"A3",50,None) A4 = Block(*NORMAL_CONST,"A4",50,None) - A5 = Block(*SWITCH_LIGHT_CONST,"A5",50,None) + A5 = Block(*SWITCH_CONST,"A5",50,None) B6 = Block(*LIGHT_CONST,"B6",50,None) B7 = Block(*NORMAL_CONST,"B7",50,None) B8 = Block(*NORMAL_CONST,"B8",50,None) @@ -106,14 +105,15 @@ def __init__(self): self.SwitchBlocks = ["B5","B6","C11"] #Defines Red line blocks - self.allRedBlocks = readTrackFile("Red_Line.csv") + self.redCrossingTriplesIDS = [] #ids of red crossing blocks + self.allRedBlocks = readTrackFile("Red_Line.csv",self.redCrossingTriplesIDS) self.specialRedBlocks = [] for block in self.allRedBlocks: if block.LIGHT or block.CROSSING or block.SWITCH : self.specialRedBlocks.append(block) #Create Parser Object - self.FileParser = Parser(None,self.AllBlocks) #Currently empty onject + self.FileParser = Parser(None,self.redCrossingTriplesIDS,self.allRedBlocks) #Currently testing red object # Buttons self.fileButton.clicked.connect(self.on_file_button_clicked) From 29233cf8c8563700cea736a05d611a7b7845eeb1 Mon Sep 17 00:00:00 2001 From: asmithie13 Date: Fri, 1 Mar 2024 00:54:03 -0500 Subject: [PATCH 06/10] Parser handles lights and switches with boolean logic. --- PLC_Files/Parser.py | 15 +++++++++------ PLC_Files/__pycache__/Parser.cpython-311.pyc | Bin 2440 -> 3118 bytes 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/PLC_Files/Parser.py b/PLC_Files/Parser.py index cbe9ad65..82656a5f 100644 --- a/PLC_Files/Parser.py +++ b/PLC_Files/Parser.py @@ -23,9 +23,12 @@ def parsePLC(self): for i in range(0, len(self.CrossingTriplesIDS)*3, 3) ] - - - - - - + for data in CrossingTripleBlocks: + SwitchOcc = data[0].occupied + SwitchRightOcc = data[2].occupied + + data[0].switchState = eval(switchLogic) + data[0].lightState = eval(curLightLogic) + data[1].lightState = eval(leftLightLogic) + data[2].lightState = eval(rightLightLogic) + \ No newline at end of file diff --git a/PLC_Files/__pycache__/Parser.cpython-311.pyc b/PLC_Files/__pycache__/Parser.cpython-311.pyc index 10feb43359f24c00351d86c7a28492c3f5bcb841..5bee1b002261e482a2cfdd22f15bbab315c512be 100644 GIT binary patch delta 867 zcmeAWUMIn~oR^o20SMxA9;TjU-N<*4iK&2T@z_1#KA)uBEMV1*&mK!Qt4^~~nf+o#_qL~#})P!9(pT;j3oL3284SOWD3Lv89gn8IGmm%ez;CJ)BR%Is6>MKwP#@Nk-gi4K<=5;8La=dfRq(CF~IA*;ARaZdOZ zS=|o5ry>$Fq%Vr7UJ+64aJ>uU$X*mtzapXz;mBPS(YPX_0pZAB6w$mQqS@j4R7q_? z^+hG)D@w*4E)xWM+^_J+-&Isykb6P+PrfvPZx Ok07xxSR{%-SpWbWSG|@1 delta 204 zcmZ1{(IL#YoR^o20SMmeJxtxfypiu96Voe($rqWPaHX)D>9#4&0S|IzzEccNqhu}eZe9DHVOa*FEIiD From f94d184b46ea7928388e79cdbc425e18c6072388 Mon Sep 17 00:00:00 2001 From: asmithie13 Date: Fri, 1 Mar 2024 15:04:36 -0500 Subject: [PATCH 07/10] Fixed minor error in PLC file. --- PLC_Files/PLC2.txt | 2 +- PLC_Files/Parser.py | 9 ++++----- PLC_Files/__pycache__/Parser.cpython-311.pyc | Bin 3118 -> 3186 bytes Wayside SW/app.py | 5 ++++- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/PLC_Files/PLC2.txt b/PLC_Files/PLC2.txt index 15e65b68..be3ac3b4 100644 --- a/PLC_Files/PLC2.txt +++ b/PLC_Files/PLC2.txt @@ -7,5 +7,5 @@ CurrentLIGHT SwitchOcc LeftLIGHT -not SwitchOcc or SwitchRightOcc +not SwitchOcc and SwitchRightOcc RightLIGHT \ No newline at end of file diff --git a/PLC_Files/Parser.py b/PLC_Files/Parser.py index 82656a5f..26760d00 100644 --- a/PLC_Files/Parser.py +++ b/PLC_Files/Parser.py @@ -8,19 +8,19 @@ from Track_Resources.Block import Block class Parser(): - def __init__(self, inputPLC,CrossingTriplesIDS,outPuttedBlocks): + def __init__(self, inputPLC, CrossingTriplesIDS, outPuttedBlocks): self.inputPLC = inputPLC self.CrossingTriplesIDS = CrossingTriplesIDS self.outPuttedBlocks = outPuttedBlocks - + def parsePLC(self): lines = self.inputPLC.split('\n') switchLogic, curLightLogic, leftLightLogic, rightLightLogic = lines[0], lines[3], lines[6], lines[9] CrossingTripleBlocks = [ [block for row in self.CrossingTriplesIDS for element in row - for block in self.outPuttedBlocks if element == block.ID[1:]][i:i+3] - for i in range(0, len(self.CrossingTriplesIDS)*3, 3) + for block in self.outPuttedBlocks if str(element) == str(block.ID[1:])][i:i + 3] + for i in range(0, len(self.CrossingTriplesIDS) * 3, 3) ] for data in CrossingTripleBlocks: @@ -31,4 +31,3 @@ def parsePLC(self): data[0].lightState = eval(curLightLogic) data[1].lightState = eval(leftLightLogic) data[2].lightState = eval(rightLightLogic) - \ No newline at end of file diff --git a/PLC_Files/__pycache__/Parser.cpython-311.pyc b/PLC_Files/__pycache__/Parser.cpython-311.pyc index 5bee1b002261e482a2cfdd22f15bbab315c512be..81d358e12121b85fc637a90c68d9ceb8d4f77420 100644 GIT binary patch delta 597 zcmZ1{@kxSrIWI340}#A3dXzeCBkv(5#+=O;m~xmVJFreN1<42l@#h{OF_m#TLpnnZ zL##tBV-2GVL#%ZzQzuInPzC~kB8IihCCrnvS)}4hm|?;U3^mMIOfX&wLkeRnlO&AG zu#Ay`VKop#KsH$2di@&ai7Y)vJvKd#!3>&AFG2Etn#@I8MQaY@l+H@1@cA|UTa z1H%UfM&3|HWO73Bfna3*4)q&Sa#y7EJ}@Ix-VhYqs=Oh6qs|tcqsj+Tk7S%EJW+I_ z=t#~*r{F72!IzAJFBk=XU}oSGz5!+ec@R{@3$(UKfPq1cL6fnF1IPh7OakOE#>^s6 zcoloR6du4k9CM|CB{g)>sF$eBWzAHg2^0w!;ShFu7cxDXw4 zF+Ao%Xv`O&%i|{BV9#LWo9xKZB3E2uc#E|pwYbCxLK#CSlVU!goe7hla~LstPL|>< z;R(DbXLo?{qNvjqQK!kXI1h1skmTVs|G)qwCZ}>0h>NiTIhe%eH(b1orZS8`NlfA+ MNbCz132@K=0HWcWtN;K2 delta 566 zcmew)u}*?_IWI340}#aLJWM^ik@pZ2W5MPNOgT)g&|h4mZ_5^3n&8tKoRj;<{G9N<}Aj^x@;24*-Rjb^`bS*6IpsB zdX#$9gBdiLUNQm&{WO`1IDz!!YPOR46d>bA1H%UfMqY15WO73Bfna3*4)q&Sa#y7E zJ}@Ix-VhYqpuQt?PsD-514##x_QYH=^1NW=`GJ{%PxuCy3FJXg5iii9A^{+w$yfyP znkI9RI0J($!!5?lB2YjSGXn_)g@z(-AYCL4B&w7r?_pDp7XeA80ST}(SroWFFu(~m z20@_@tOy4oJ9tLQ6**Igz(=s}zJSRa-aaP+PZXXEK4JO==#`+!@*EkA{F6I4T9k4N z3~#ZPq~;bFK`3JgWpazLqL?4(fCPofTAW6V9+P7^OLz<~%GvBlyeR5$Mbu&PUCu+C r4|sSx7(sCIO0EKN30A%j44A}b18!bMQ#nSUBqs3@B=!Z11UT>j#2Ar2 diff --git a/Wayside SW/app.py b/Wayside SW/app.py index 36a51f08..a632138b 100644 --- a/Wayside SW/app.py +++ b/Wayside SW/app.py @@ -113,7 +113,10 @@ def __init__(self): if block.LIGHT or block.CROSSING or block.SWITCH : self.specialRedBlocks.append(block) #Create Parser Object - self.FileParser = Parser(None,self.redCrossingTriplesIDS,self.allRedBlocks) #Currently testing red object + self.SwitchBlocksNums = [['5','6','11']] + + #self.FileParser = Parser(None,self.redCrossingTriplesIDS,self.allRedBlocks) #Currently testing red object + self.FileParser = Parser(None,self.SwitchBlocksNums,self.AllBlocks) # Buttons self.fileButton.clicked.connect(self.on_file_button_clicked) From db6bcdc7dd493d36f6e773e4190fe9eda33d8c9f Mon Sep 17 00:00:00 2001 From: asmithie13 Date: Fri, 1 Mar 2024 15:47:17 -0500 Subject: [PATCH 08/10] Updated block class to match Lilly's. --- Track_Resources/Block.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Track_Resources/Block.py b/Track_Resources/Block.py index e73ffb61..93cf11c8 100644 --- a/Track_Resources/Block.py +++ b/Track_Resources/Block.py @@ -1,14 +1,17 @@ # Define the Block class class Block: - def __init__(self, light, crossing, switch, lightState, crossingState, switchState, occupied,id,speedLimit,authority): - self.LIGHT = light - self.CROSSING = crossing - self.SWITCH = switch + def __init__(self, lineColor, blockSection, blockNum, hasLight, hasCrossing, hasSwitch, lightState, crossingState, switchState,id,speedLimit): + self.lineColor = lineColor + self.blockSection = blockSection + self.blockNum = blockNum + self.LIGHT = hasLight + self.CROSSING = hasCrossing + self.SWITCH = hasSwitch self.lightState = lightState self.crossingState = crossingState self.switchState = switchState - self.occupied = occupied + self.occupied = False self.ID = id self.speedLimit = speedLimit - self.authority = authority + self.authority = None From 213a1da0559b1e37b19c4db086569a555512ae01 Mon Sep 17 00:00:00 2001 From: asmithie13 Date: Fri, 1 Mar 2024 22:57:35 -0500 Subject: [PATCH 09/10] Updated block functionality in ui. --- PLC_Files/__pycache__/Parser.cpython-311.pyc | Bin 3186 -> 2982 bytes .../__pycache__/Block.cpython-311.pyc | Bin 923 -> 1038 bytes Wayside SW/app.py | 42 +++++++++--------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/PLC_Files/__pycache__/Parser.cpython-311.pyc b/PLC_Files/__pycache__/Parser.cpython-311.pyc index 81d358e12121b85fc637a90c68d9ceb8d4f77420..66df538e396f3ef64af926c53750e7db6cc8614b 100644 GIT binary patch delta 218 zcmew)u}qwAIWI340}vcBd6fE|Wh37~CZ;cplP@y8WNewdn>lFmP8R;jQ&^TUwr;j& z^>k}z41Q;$(}axCXeHg-<)4-D*+|8UAq_T>s@=ZEr_bD1#ePrk!t zD=NqeRDe!Q*5fXhG6ot|#0w(0fy6Hko80`A(wtPgBD=}^x$8{D8G#xxiH{($FIXhN GMgai4u{uTo delta 369 zcmZ1`{z-ywIWI340}#A3dXzeibtB(FCZ-&w$rqVkG9H+`n>k3KmaBvpBo6^K%*z-V z7*+!@1k`d*j%1Nxs^yv73!-=@e`LPMcyRM!79VCtzR3a{4QjVoOHzwV3?Y;egffOu zCdGU}QxX(_VDdB$Jx0&TM>%GO@o<`dU;q*wE;l4(W(3Y*zapX0;dw(=ae?BT@GG*q z9ez(mBxXoo6j8k*qT1nl7s!#lD58EvL>f`C|5ps*eImkaa*wfGb7F%$*XNa@Mt;v3jzF|DKSc+3~(u!DtRu!>< z2zDTGiz6ek*e5eRqvRGhkmX#IUtFA-mwt;A$O$gbEJ@BN0=caSQ1GS)xdB=QmKQbhwp}rMhD9k4#^u53P3LJ4N+Mj#dSkM8O#%tpIpHt zD+Utdy&)t5q}XprsQ@Yd898RzhzRY=Vg`qz<^0Wlz;-+ zPm{3-L>I||2#8J~>lcSjZhlH>PO4pz9FWTh#Kq=7;sY}yBjX1aK1QIin8Zhr*cT)T JUYHuN$pAr8cMSjl delta 367 zcmeCg`$}0-gwvwSp3`iA;Oio}{s^?-={=k4qK$L*|<)_J51fq+i zKm Date: Fri, 1 Mar 2024 22:59:41 -0500 Subject: [PATCH 10/10] Updated outdated PLCs. --- PLC_Files/PLC1.txt | 16 ++++++++++------ PLC_Files/PLC2.txt | 11 ----------- PLC_Files/PLC_Red.txt | 41 ----------------------------------------- 3 files changed, 10 insertions(+), 58 deletions(-) delete mode 100644 PLC_Files/PLC2.txt delete mode 100644 PLC_Files/PLC_Red.txt diff --git a/PLC_Files/PLC1.txt b/PLC_Files/PLC1.txt index 71ee5d1f..be3ac3b4 100644 --- a/PLC_Files/PLC1.txt +++ b/PLC_Files/PLC1.txt @@ -1,7 +1,11 @@ -OCCUPIED C -SWITCH A5 B6 -LIGHT !C11 +SwitchOcc or not SwitchRightOcc +SWITCH -OCCUPIED !C -SWITCH A5 C11 -LIGHT C11 +SwitchOcc or SwitchRightOcc +CurrentLIGHT + +SwitchOcc +LeftLIGHT + +not SwitchOcc and SwitchRightOcc +RightLIGHT \ No newline at end of file diff --git a/PLC_Files/PLC2.txt b/PLC_Files/PLC2.txt deleted file mode 100644 index be3ac3b4..00000000 --- a/PLC_Files/PLC2.txt +++ /dev/null @@ -1,11 +0,0 @@ -SwitchOcc or not SwitchRightOcc -SWITCH - -SwitchOcc or SwitchRightOcc -CurrentLIGHT - -SwitchOcc -LeftLIGHT - -not SwitchOcc and SwitchRightOcc -RightLIGHT \ No newline at end of file diff --git a/PLC_Files/PLC_Red.txt b/PLC_Files/PLC_Red.txt deleted file mode 100644 index 8d57327d..00000000 --- a/PLC_Files/PLC_Red.txt +++ /dev/null @@ -1,41 +0,0 @@ -OCCUPIED A - -LIGHT !A1 - -OCCUPIED !A - -LIGHT A1 - -OCCUPIED B - -LIGHT !B5 - -OCCUPIED !B - -LIGHT B5 - -OCCUPIED C - -LIGHT !C8 - -OCCUPIED !C - -LIGHT C8 - -OCCUPIED D - -LIGHT !C8 -CROSSING !D11 -OCCUPIED !D - -LIGHT C8 -CROSSING D11 -OCCUPIED E -SWITCH #FINISH -LIGHT !E13 - -OCCUPIED !E - -LIGHT E13 - -OCCUPIED F