From 2f9be9e5ef7c5d8bb5cecdb0da724e6965d98f13 Mon Sep 17 00:00:00 2001 From: ICHeavy <102187487+ICHeavy@users.noreply.github.com> Date: Thu, 4 Aug 2022 17:13:02 -0400 Subject: [PATCH] TCHW_WIndows_Final lol whoops pt. 2 --- .../TrainControllerHW_WIN64/TestEnv/GPIO.py | 20 + .../TrainControllerHW_WIN64/TestEnv/PSv2_1.py | 13 + .../TestEnv/TrainController.py | 472 +++++++++++ .../TestEnv/TrainControllerV2.py | 163 ++++ .../TrainControllerHW_WIN64/TestEnv/engine.py | 9 + .../TestEnv/enginet.py | 206 +++++ .../TrainControllerHW_WIN64/TestEnv/index.js | 65 ++ .../TrainControllerHW_WIN64/TestEnv/main.py | 1 + .../TestEnv/package-lock.json | 779 ++++++++++++++++++ .../TestEnv/package.json | 15 + .../TrainControllerHW_WIN64/TestEnv/pubsub.py | 81 ++ .../TrainControllerHW_WIN64/TestEnv/pubsub.ts | 50 ++ .../TestEnv/pubsubV2.py | 82 ++ .../TestEnv/pubsubt.py | 81 ++ .../TrainControllerHW_WIN64/src/testTM.py | 353 ++++++++ 15 files changed, 2390 insertions(+) create mode 100644 src/modules/TrainControllerHW_WIN64/TestEnv/GPIO.py create mode 100644 src/modules/TrainControllerHW_WIN64/TestEnv/PSv2_1.py create mode 100644 src/modules/TrainControllerHW_WIN64/TestEnv/TrainController.py create mode 100644 src/modules/TrainControllerHW_WIN64/TestEnv/TrainControllerV2.py create mode 100644 src/modules/TrainControllerHW_WIN64/TestEnv/engine.py create mode 100644 src/modules/TrainControllerHW_WIN64/TestEnv/enginet.py create mode 100644 src/modules/TrainControllerHW_WIN64/TestEnv/index.js create mode 100644 src/modules/TrainControllerHW_WIN64/TestEnv/main.py create mode 100644 src/modules/TrainControllerHW_WIN64/TestEnv/package-lock.json create mode 100644 src/modules/TrainControllerHW_WIN64/TestEnv/package.json create mode 100644 src/modules/TrainControllerHW_WIN64/TestEnv/pubsub.py create mode 100644 src/modules/TrainControllerHW_WIN64/TestEnv/pubsub.ts create mode 100644 src/modules/TrainControllerHW_WIN64/TestEnv/pubsubV2.py create mode 100644 src/modules/TrainControllerHW_WIN64/TestEnv/pubsubt.py create mode 100644 src/modules/TrainControllerHW_WIN64/src/testTM.py diff --git a/src/modules/TrainControllerHW_WIN64/TestEnv/GPIO.py b/src/modules/TrainControllerHW_WIN64/TestEnv/GPIO.py new file mode 100644 index 00000000..3da32209 --- /dev/null +++ b/src/modules/TrainControllerHW_WIN64/TestEnv/GPIO.py @@ -0,0 +1,20 @@ +from gpiozero import LED +#imports LED functions from gpiozero library +from gpiozero import Button +#imports Button functions from gpiozero library + +led = LED(4) +#declare the GPIO pin 4 for LED output and store it in led variable +button = Button(17) +#declare the GPIO pin 17 for Button output and store it in button variable + +while True: +#initiated an infinite while loop + button.wait_for_press() +#use the built-in function of the button to wait till press + led.on() +#turn on the led + button.wait_for_release() +#use the built-in function of button to wait till release + led.off() +#turn off the led \ No newline at end of file diff --git a/src/modules/TrainControllerHW_WIN64/TestEnv/PSv2_1.py b/src/modules/TrainControllerHW_WIN64/TestEnv/PSv2_1.py new file mode 100644 index 00000000..8ef1d7da --- /dev/null +++ b/src/modules/TrainControllerHW_WIN64/TestEnv/PSv2_1.py @@ -0,0 +1,13 @@ +import paho.mqtt.client as mqtt +broker = "broker.hivemq.com" +port = 8000 + +def on_publish(client,userdata,result): #create function for callback + print("data published \n") + pass + + +client1= mqtt.Client("control1") #create client object +client1.on_publish = on_publish #assign function to callback +client1.connect(broker,port) #establish connection +ret = client1.publish("trains/vitals","bf1") #publish \ No newline at end of file diff --git a/src/modules/TrainControllerHW_WIN64/TestEnv/TrainController.py b/src/modules/TrainControllerHW_WIN64/TestEnv/TrainController.py new file mode 100644 index 00000000..e5d404d7 --- /dev/null +++ b/src/modules/TrainControllerHW_WIN64/TestEnv/TrainController.py @@ -0,0 +1,472 @@ +from simple_pid import PID +import sys +import time +#import TrainModel somehow +from subprocess import check_output + + +class TrainController(): + def __init__(self, + #TrainModel + cmdV = 0.0, + currV = 0, + auth = 0, + IDnum = 0): + + ######################## train info #################### + self.IDnum = IDnum + self.auto = True + # TODO self.TrainModel = TrainModel + + ######################## station info ################## + self.comingUp = False + self.arrived = False + self.stationDL = False + self.stationDR = False + self.stationName = "" + + + ######################## fail states ################### + self.FAILURE = False + self.Fengine = False + self.Fbrake = False + self.Fsig = False + self.passengerPanic = False #ebrake from train model + + ######################## nonvitals ##################### + self.doorsL = False + self.doorsR = False + self.inLights = False + self.exLights = False + self.announce = "" + self.temp = 68 + + ######################## vitals ######################## + self.engine = Engine(self, cmdV, currV, auth, self.IDnum) + self.engine.cmdV = cmdV + self.engine.setpoint_speed = 0.0 + self.engine.currV = currV + self.engine.auth = auth + + self.engine.brake = False + self.engine.EBrake = False + + ##### to and from train model + #from software -> update speedlimit + # brakes(both), failures, cmdV, and auth, error check if feeling fancy + # use a check sum failure detection or find other + # + + self.stationList =("Shadyside", + "Herron Ave", + "Swissville", + "Penn Station", + "Steel Plaza", + "First Ave", + "Station Square", + "South Hills Junction", + "Pioneer", + "Edgebrook", + "Whited", + "South Bank", + "Central", + "Inglewood", + "Overbrook", + "Glenburry", + "Dormont", + "Mt Lebanon", + "Poplar", + "Castle Shannon") + #need to sort which is called in fucnntions call + + + ############################################################## + ######################### functions ######################## + ############################################################## + + + ######################## speed controls ###################### + #todo + def setV(self, currV): + self.engine.PILoop() + + self.engine.AnteayerV = self.engine.prevV + self.engine.prevV = self.engine.currV + self.engine.currV = currV + + # TODO + # self.engine.DetectEngineFailure(currV) + # self.engine.DetectBrakeFailure() + + self.stationHanfler() + + + + def stationHandler(self): + #stopped at new station + if(self.comingUp and self.engine.currV == 0): + + # if train arrived at station + if(self.engine.auth == 0): + self.atStation = True + + # Opening Left Doors in auto mode + if(self.stationDR and self.auto): + if(self.doorsR): + pass + else: + self.doorsR = True + # TODO + # set lights + #update TM + + + #Opening Right Doors in auto mode + if(self.stationDL and self.auto): + if(self.doorsL): + pass + else: + self.doorsR = True + # TODO + # set lights + #update TM + + #when departing + self.comingUp = False #reset flag + if(self.engine.auth != 0): + self.SetBrake(False) #turn off brakes + + def setCmdV(self, cmdV): + self.engine.cmdV = cmdV + #updateOLED + + + def setAuth(self, auth): + if(auth == 0): + self.setBrakes(True) + # TODO send to TM and update displays + print("Brakes: ON, Stop upcoming") + + self.engine.auth = auth + + + def setSetptV(self, setPtV): + self.engine.setPtV = setPtV + + + def setKp(self, kp): + self.engine.kp = kp + #TODO + #update LED and Train model + + + def setKi(self,ki): + self.engine.ki = ki + #TODO + #update LED and Train model + + ######################## Brakes ######################## + def setBrake(self, brake): + self.engine.setBrake(brake) + #TODO + #update LED and Train model + + def setEBrake(self, Ebrake): + self.engine.EBrake = Ebrake + #TODO + #update LED and Train model + + + ######################### nonvitals ######################## + def toggleAuto(self, togguy): + self.auto = togguy + #update LEDs (and trian model?) + # TODO + + def togDoorsL(self, boolman): + self.left_doors = boolman + #update LEDs and train model + # if(self.left_doors): + # self.TrainModel.open_left_doors() + # else: + # self.TrainModel.close_left_doors() + + def togDoorsR(self, boolman): + self.right_doors = boolman + #update LEDs and train model + # if(self.right_doors): + # self.TrainModel.open_right_doors() + # else: + # self.TrainModel.close_right_doors() + + #toggle_interior_lights: function for toggling interior lights based of checkmarks + def togInLights(self): + self.interior_lights = not(self.inLights) + print("Interior Lights: " + str(self.inLights)) + + #UPDATE LED and trian model + # if(self.inLights): + # self.TrainModel.TURN in LIGHTS ON() + # else: + # self.TrainModel.TURN in LIGHTS OFF() + + + def togExLights(self): + self.exterior_lights = not(self.exterior_lights) + print("Exterior Lights: " + str(self.exterior_lights)) + if(self.exterior_lights): + self.TrainModel.t_lights_on() + else: + self.TrainModel.t_lights_off() + + def ExLightsON(self): + self.exLights = True + #update lights and train model + #self.TrainModel.t_lights_on() + #self.HandleExteriorLights() + + def ExLightsOFF(self): + self.exLights = False + #update lights and trian model + #self.TrainModel.t_lights_off() + #self.HandleExteriorLights() + + + def on_TempChange(self): + #self.temp = poll from UI input + #update TM and LEDs + pass + + + def BuildAnnouncement(self): + if(self.upcomingStation): + self.announce = str("Arriving at " + self.station + " Station.") + + if(self.doorsL and self.doorsR): + self.announce += " The doors will open on the left and right.\n" + elif(self.doorsL): + self.announce += " The doors will open on the left.\n" + elif(self.doorsR): + self.announce += " The doors will open on the right.\n" + else: + self.announce += "" + + #SendAnnouncement: used to send announcement to train model and UI + def SendAnnouncement(self): + #self.TrainModel.set_announcements(self.announce) + #send to OLED + #todo + pass + +############################################################################################################################ +############################################################################################################################ + + # Engine of TC + +############################################################################################################################ +############################################################################################################################ + + +class Engine(): + def __init__( + self, + TrainController, + cmdV = 0, + currV = 0, + auth = 0, + trainID = 0 + ): + +######################## Train Info ##################### + self.trainID = trainID + self.TC = TrainController + +######################## Vitals ##################### + self.AnteayerV = 0.0 # T-2 + self.prevV = 0.0 # T-1 + self.currV = currV # T + self.manCmdV = 0 + self.cmdV = cmdV + self.setptV = 0.0 + self.auth = auth + self.brake = False + self.EBrake = False + self.allowedError = 5 + +######################## Power Info ##################### + self.kp = 3000 + self.ki = 1000 + self.limits = (0,120000) #120kW + + self.prevPower0 = 0.0 + self.Power0 = 0.0 + self.PI0 = PID(self.kp, self.ki, 0) + self.tooFast0 = False + + self.prevPower1 = 0.0 + self.Power1 = 0.0 + self.PI1 = PID(self.kp, self.ki, 0) + self.tooFast1 = False + + self.prevPower2 = 0.0 + self.Power2 = 0.0 + self.PI2 = PID(self.kp, self.ki, 0) + self.tooFast2 = False + + self.powers = {self.power0, self.power1, self.power2} + + def checkPriorConditions(self): + + # when in auto + if (self.TC.auto): + # leaving from a stop + if (self.TC.atStation and not (self.cmdV == 0 or self.auth == 0)): + self.TC.togDoorsL(False) + self.TC.togDoorsR(False) + self.turnBrakeOff() + self.TC.atStation = False + print("Brake: OFF") + + + # recovered from too fast + if (self.tooFast0 and not(self.auth == 0) and (self.currV < self.cmdV)): + self.turnBrakeOff() + self.tooFast0 = False + print("Brake: OFF") + + # setting too fast + if (self.currV > (self.cmdV + self.AllowedError)): + print("Brake: ON") + self.tooFast0 = True + self.PILoop(0,0) + self.turnBakeOn() + + # normal auto use case, use commanded V + elif (not(self.brake or self.EBrake)): + self.prevPower = self.power + self.PILoop(self.cmdV, self.currV) + + # fail + else: + self.PILoop(0,0) + + # in manual, use manual Commanded V + else: + if (not (self.manCmdV == 0 or self.brake or self.EBrake)): + self.PILoop(self.manCmdV, self.currV) + + ##update dispalays TODO + + + + def PILoop(self, setguy, inguy): + self.PI0.setpoint = setguy + self.power0 = self.PI0(inguy, dt = 1) #timetep set to 1 + + self.PI1.setpoint = setguy + self.power1 = self.PI1(inguy, dt = 1) + + self.PI2.setpoint = setguy + self.power2 = self.PI2(inguy, dt = 1) + + + #error check with timeout + counter = 0 + while True: + if (max(self.powers) - min(self.powers) > self.allowedError and counter < 3): + + print("Error: Invalid Power Calculation") + print("Trying again") + # send a null power command in hopes it stabilizes + self.PILoop(setguy, 0) + self.checkPriorConditions() + counter += 1 + # if couunter exceeds 3 tries it begins an error alert + elif (counter > 3): + pass + #TODO begin error alert + # if counter < 3 and range < allowedError continue + else: + break + + + def getPower(self): + return self.power0 + + + ## TODO + + # abstract message sending and decoding + # set up better main loop + # test and get working PID reliably + # make most gpio set up + # merge these 2. finish completing them + # set up full test class + + ###################### ON CLICK/CALL ACTIONS ACTIONS ###################### + + def setBrake(self, mode): + self.brake = mode + if (mode): + self.TrainController.SendServiceBrakeOn() + else: + self.TrainController.SendServiceBrakeOff() + + self.BrakeFailureTest() + + # self.TrainController.DisplayUpdate() + # TODO + #update TM and LED + + def OnEBrakeOn(self): + self.emergency_brake = True + self.TrainController.SendEmergencyBrakeOn() + self.TrainController.DisplayUpdate() + + def IncreaseSetpoint(self): + if(self.setPtV +1 <= self.commanded_speed): + self.setpoint_speed = self.setpoint_speed + 1 + self.TrainController.DisplayUpdate() + + def DecreaseSetpoint(self): + if(self.setpoint_speed > 0): + self.setpoint_speed = self.setpoint_speed - 1 + self.TrainController.DisplayUpdate() + + ###################### FAILURE DETECTION ###################### + def DetectEngineFailure(self, current): + if(current == 666): + self.engine_failure = True + self.TrainController.UI.ui.textBrowser_13.setStyleSheet(u"background-color: rgb(255, 0, 0);") + self.VitalFault() + self.TrainController.TrainModel.train_detected_engine_failure() + + def DetectBrakeFailure(self): + if(self.service_brake and (self.current_speed >= (self.previous_speed+.5)) and not(self.current_speed == 0)): + self.brake_failure = True + self.TrainController.UI.ui.textBrowser_14.setStyleSheet(u"background-color: rgb(255, 0, 0);") + self.VitalFault() + self.TrainController.TrainModel.train_detected_brake_failure() + + print("Service brake: " + str(self.service_brake)) + print("Current Speed: " + str(self.current_speed)) + print("Previous speed: " + str(self.previous_speed)) + + + #testing brake failure + def BrakeFailureTest(self): + if(self.TrainController.TrainModel.train.brakeFailure): + self.brake_failure = True + self.TrainController.UI.ui.textBrowser_14.setStyleSheet(u"background-color: rgb(255, 0, 0);") + self.VitalFault() + self.TrainController.TrainModel.train_detected_brake_failure() + # print("Service brake: " + str(self.service_brake)) + # print("Current Speed: " + str(self.current_speed)) + # print("Previous speed: " + str(self.previous_speed)) + + def VitalFault(self): + self.TC.any_failure = True + print("##*!!!!!!*## VITAL FAULT DETECTED ##*!!!!!!*##") + if(not(self.TrainController.passenger_brake_detected)): + self.OnEBrakeOn() + diff --git a/src/modules/TrainControllerHW_WIN64/TestEnv/TrainControllerV2.py b/src/modules/TrainControllerHW_WIN64/TestEnv/TrainControllerV2.py new file mode 100644 index 00000000..de0fe20c --- /dev/null +++ b/src/modules/TrainControllerHW_WIN64/TestEnv/TrainControllerV2.py @@ -0,0 +1,163 @@ +from simple_pid import PID +import sys +import time +#import TrainModel somehow +from subprocess import check_output + +class TrainController(): + def __init__(self, + #TrainModel + cmdV = 0.0, + currV = 0, + auth = 0, + IDnum = 0): + + ######################## train info #################### + self.IDnum = IDnum + self.auto = True + # TODO self.TrainModel = TrainModel + + ######################## station info ################## + self.comingUp = False + self.arrived = False + self.stationDL = False + self.stationDR = False + self.stationName = "" + + + ######################## fail states ################### + self.FAILURE = False + self.Fengine = False + self.Fbrake = False + self.Fsig = False + self.passengerPanic = False #ebrake from train model + + ######################## nonvitals ##################### + self.doorsL = False + self.doorsR = False + self.inLights = False + self.exLights = False + self.announce = "" + self.temp = 68 + + ######################## vitals ######################## + self.engine = Engine(self, cmdV, currV, auth, self.IDnum) + self.engine.cmdV = cmdV + self.engine.setpoint_speed = 0.0 + self.engine.currV = currV + self.engine.auth = auth + + self.engine.brake = False + self.engine.EBrake = False + + ##### to and from train model + #from software -> update speedlimit + # brakes(both), failures, cmdV, and auth, error check if feeling fancy + # use a check sum failure detection or find other + # + + self.stationList =("Shadyside", + "Herron Ave", + "Swissville", + "Penn Station", + "Steel Plaza", + "First Ave", + "Station Square", + "South Hills Junction", + "Pioneer", + "Edgebrook", + "Whited", + "South Bank", + "Central", + "Inglewood", + "Overbrook", + "Glenburry", + "Dormont", + "Mt Lebanon", + "Poplar", + "Castle Shannon") + #need to sort which is called in fucnntions call + + + ############################################################## + ######################### functions ######################## + ############################################################## + + + ######################## Brakes ######################## + def setBrake(self, brake): + self.engine.setBrake(brake) + #TODO + #update LED and Train model + +############################################################################################################################ +############################################################################################################################ + + # Engine of TC + +############################################################################################################################ +############################################################################################################################ + +class Engine(): + def __init__( + self, + TrainController, + cmdV = 0, + currV = 0, + auth = 0, + trainID = 0 + ): + +######################## Train Info ##################### + self.trainID = trainID + self.TC = TrainController + +######################## Vitals ##################### + self.AnteayerV = 0.0 # T-2 + self.prevV = 0.0 # T-1 + self.currV = currV # T + self.manCmdV = 0 + self.cmdV = cmdV + self.auth = auth + self.brake = False + self.EBrake = False + self.allowedError = 5 + +######################## Power Info ##################### + self.kp = 3000 + self.ki = 1000 + self.limits = (0,120000) #120kW + + self.prevPower0 = 0.0 + self.Power0 = 0.0 + self.PI0 = PID(self.kp, self.ki, 0) + self.tooFast0 = False + + self.prevPower1 = 0.0 + self.Power1 = 0.0 + self.PI1 = PID(self.kp, self.ki, 0) + self.tooFast1 = False + + self.prevPower2 = 0.0 + self.Power2 = 0.0 + self.PI2 = PID(self.kp, self.ki, 0) + self.tooFast2 = False + + self.powers = {self.power0, self.power1, self.power2} + + +###################### update Displays ###################### + + + def setBrake(self, mode): + self.brake = mode + if (mode): + self.TrainController.SendServiceBrakeOn() + else: + self.TrainController.SendServiceBrakeOff() + + self.BrakeFailureTest() + + # self.TrainController.DisplayUpdate() + # TODO + #update TM and LED \ No newline at end of file diff --git a/src/modules/TrainControllerHW_WIN64/TestEnv/engine.py b/src/modules/TrainControllerHW_WIN64/TestEnv/engine.py new file mode 100644 index 00000000..ab3ab409 --- /dev/null +++ b/src/modules/TrainControllerHW_WIN64/TestEnv/engine.py @@ -0,0 +1,9 @@ +from simple_pid import PID +import sys +import time +#import TrainModel somehow +from subprocess import check_output +from simple_pid import PID +import TrainController + + diff --git a/src/modules/TrainControllerHW_WIN64/TestEnv/enginet.py b/src/modules/TrainControllerHW_WIN64/TestEnv/enginet.py new file mode 100644 index 00000000..35a6527b --- /dev/null +++ b/src/modules/TrainControllerHW_WIN64/TestEnv/enginet.py @@ -0,0 +1,206 @@ +from subprocess import check_output +from simple_pid import PID +import TrainController + +class Engine(): + def __init__( + self, + TrainController, + cmdV = 0, + currV = 0, + auth = 0, + trainID = 0 + ): + +######################## Train Info ##################### + self.trainID = trainID + self.TC = TrainController + +######################## Vitals ##################### + self.AnteayerV = 0.0 # T-2 + self.prevV = 0.0 # T-1 + self.currV = currV # T + self.manCmdV = 0 + self.cmdV = cmdV + self.auth = auth + self.brake = False + self.EBrake = False + self.allowedError = 5 + +######################## Power Info ##################### + self.kp = 3000 + self.ki = 1000 + self.limits = (0,120000) #120kW + + self.prevPower0 = 0.0 + self.Power0 = 0.0 + self.PI0 = PID(self.kp, self.ki, 0) + self.tooFast0 = False + + self.prevPower1 = 0.0 + self.Power1 = 0.0 + self.PI1 = PID(self.kp, self.ki, 0) + self.tooFast1 = False + + self.prevPower2 = 0.0 + self.Power2 = 0.0 + self.PI2 = PID(self.kp, self.ki, 0) + self.tooFast2 = False + + self.powers = {self.power0, self.power1, self.power2} + + def checkPriorConditions(self): + + # when in auto + if (self.TC.auto): + # leaving from a stop + if (self.TC.atStation and not (self.cmdV == 0 or self.auth == 0)): + self.TC.togDoorsL(False) + self.TC.togDoorsR(False) + self.turnBrakeOff() + self.TC.atStation = False + print("Brake: OFF") + + + # recovered from too fast + if (self.tooFast0 and not(self.auth == 0) and (self.currV < self.cmdV)): + self.turnBrakeOff() + self.tooFast0 = False + print("Brake: OFF") + + # setting too fast + if (self.currV > (self.cmdV + self.AllowedError)): + print("Brake: ON") + self.tooFast0 = True + self.PILoop(0,0) + self.turnBakeOn() + + # normal auto use case, use commanded V + elif (not(self.brake or self.EBrake)): + self.prevPower = self.power + self.PILoop(self.cmdV, self.currV) + + # fail + else: + self.PILoop(0,0) + + # in manual, use manual Commanded V + else: + if (not (self.manCmdV == 0 or self.brake or self.EBrake)): + self.PILoop(self.manCmdV, self.currV) + + ##update dispalays TODO + + + + def PILoop(self, setguy, inguy): + self.PI0.setpoint = setguy + self.power0 = self.PI0(inguy, dt = 1) #timetep set to 1 + + self.PI1.setpoint = setguy + self.power1 = self.PI1(inguy, dt = 1) + + self.PI2.setpoint = setguy + self.power2 = self.PI2(inguy, dt = 1) + + + #error check with timeout + counter = 0 + while True: + if (max(self.powers) - min(self.powers) > self.allowedError and counter < 3): + + print("Error: Invalid Power Calculation") + print("Trying again") + # send a null power command in hopes it stabilizes + self.PILoop(setguy, 0) + self.checkPriorConditions() + counter += 1 + # if couunter exceeds 3 tries it begins an error alert + elif (counter > 3): + pass + #TODO begin error alert + # if counter < 3 and range < allowedError continue + else: + break + + + def getPower(self): + return self.power0 + + + ## TODO + # merge these 2 + + # finish parsing pubsub + # make simple comm test for pub subs + + # add gpio command + # test and get working PID reliably + # make most gpio set up + # set up full test class + + ###################### ON CLICK/CALL ACTIONS ACTIONS ###################### + def turnBrakeON(self): + self.brake = True + self.TrainController.SendServiceBrakeOn() + self.BrakeFailureTest() + self.TrainController.DisplayUpdate() + + def OnSBrakeOff(self): + self.service_brake = False + self.TrainController.SendServiceBrakeOff() + self.TrainController.DisplayUpdate() + + def OnEBrakeOn(self): + self.emergency_brake = True + self.TrainController.SendEmergencyBrakeOn() + self.TrainController.DisplayUpdate() + + def IncreaseSetpoint(self): + if(self.setpoint_speed+1 <= self.commanded_speed): + self.setpoint_speed = self.setpoint_speed + 1 + self.TrainController.DisplayUpdate() + + def DecreaseSetpoint(self): + if(self.setpoint_speed > 0): + self.setpoint_speed = self.setpoint_speed - 1 + self.TrainController.DisplayUpdate() + + ###################### FAILURE DETECTION ###################### + def DetectEngineFailure(self, current): + if(current == 666): + self.engine_failure = True + self.TrainController.UI.ui.textBrowser_13.setStyleSheet(u"background-color: rgb(255, 0, 0);") + self.VitalFault() + self.TrainController.TrainModel.train_detected_engine_failure() + + def DetectBrakeFailure(self): + if(self.service_brake and (self.current_speed >= (self.previous_speed+.5)) and not(self.current_speed == 0)): + self.brake_failure = True + self.TrainController.UI.ui.textBrowser_14.setStyleSheet(u"background-color: rgb(255, 0, 0);") + self.VitalFault() + self.TrainController.TrainModel.train_detected_brake_failure() + + print("Service brake: " + str(self.service_brake)) + print("Current Speed: " + str(self.current_speed)) + print("Previous speed: " + str(self.previous_speed)) + + + #testing brake failure + def BrakeFailureTest(self): + if(self.TrainController.TrainModel.train.brakeFailure): + self.brake_failure = True + self.TrainController.UI.ui.textBrowser_14.setStyleSheet(u"background-color: rgb(255, 0, 0);") + self.VitalFault() + self.TrainController.TrainModel.train_detected_brake_failure() + # print("Service brake: " + str(self.service_brake)) + # print("Current Speed: " + str(self.current_speed)) + # print("Previous speed: " + str(self.previous_speed)) + + def VitalFault(self): + self.TC.any_failure = True + print("##*!!!!!!*## VITAL FAULT DETECTED ##*!!!!!!*##") + if(not(self.TrainController.passenger_brake_detected)): + self.OnEBrakeOn() + + diff --git a/src/modules/TrainControllerHW_WIN64/TestEnv/index.js b/src/modules/TrainControllerHW_WIN64/TestEnv/index.js new file mode 100644 index 00000000..2704579f --- /dev/null +++ b/src/modules/TrainControllerHW_WIN64/TestEnv/index.js @@ -0,0 +1,65 @@ +const mqtt = require('mqtt'); +//must init npm prior +//all code is in the index File +//this will prolly need added to his json file + +//get publilshing working + +//get PID PIDing w/ curr and setPT + //needs to constantly be calculating + //model off prem and auris + +//test to feed inputs + + +//for msg handling +// inQ = new Array(); +// outQ = new Array(); + +//for connection purposes +const websocketUrl = "mqtt://broker.hivemq.com"; +const topic = 'trains/vitals' +const host = 'broker.hivemq.com'; + + +const client = mqtt.connect(websocketUrl); + +//sub to topic +client.subscribe(topic); //not including power + + +client.on('connect', () => { + console.log('Connected') + client.subscribe([topic], () => { + console.log(`Subscribe to topic '${topic}'`) + }) + client.publish(topic, 'nodejs mqtt test', { qos: 0, retain: false }, (error) => { + if (error) { + console.error(error) + } + }) +}) + + +client.on('message', (topic, payload) => { + console.log('Received Message:', topic, payload.toString()) +}) + +// function on_connect(client) { + +// //client.subscribe(//power); +// //client.subscribe(//externals); + +// } + +// function on_message(client) { +// client.on("message", (topic,message,packet) => { +// console.log(new TextDecoder("utf-8").decode(message)); +// } + + + +// // client.on("message", (topic, message, packet) => { +// // callBack(JSON.parse(new TextDecoder("utf-8").decode(message))); +// // }); +// } \ No newline at end of file diff --git a/src/modules/TrainControllerHW_WIN64/TestEnv/main.py b/src/modules/TrainControllerHW_WIN64/TestEnv/main.py new file mode 100644 index 00000000..3628dd45 --- /dev/null +++ b/src/modules/TrainControllerHW_WIN64/TestEnv/main.py @@ -0,0 +1 @@ +import pub \ No newline at end of file diff --git a/src/modules/TrainControllerHW_WIN64/TestEnv/package-lock.json b/src/modules/TrainControllerHW_WIN64/TestEnv/package-lock.json new file mode 100644 index 00000000..45f05f78 --- /dev/null +++ b/src/modules/TrainControllerHW_WIN64/TestEnv/package-lock.json @@ -0,0 +1,779 @@ +{ + "name": "trains", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "trains", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "mqtt": "^4.3.7" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/commist": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/commist/-/commist-1.1.0.tgz", + "integrity": "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==", + "dependencies": { + "leven": "^2.1.0", + "minimist": "^1.1.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "engines": [ + "node >= 6.0" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/duplexify": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/help-me": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-3.0.0.tgz", + "integrity": "sha512-hx73jClhyk910sidBB7ERlnhMlFsJJIBqSVMFDwPN8o2v9nmp5KgLq1Xz1Bf1fCMMZ6mPrX159iG0VLy/fPMtQ==", + "dependencies": { + "glob": "^7.1.6", + "readable-stream": "^3.6.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/js-sdsl": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-2.1.4.tgz", + "integrity": "sha512-/Ew+CJWHNddr7sjwgxaVeIORIH4AMVC9dy0hPf540ZGMVgS9d3ajwuVdyhDt6/QUvT8ATjR3yuYBKsS79F+H4A==" + }, + "node_modules/leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + }, + "node_modules/mqtt": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-4.3.7.tgz", + "integrity": "sha512-ew3qwG/TJRorTz47eW46vZ5oBw5MEYbQZVaEji44j5lAUSQSqIEoul7Kua/BatBW0H0kKQcC9kwUHa1qzaWHSw==", + "dependencies": { + "commist": "^1.0.0", + "concat-stream": "^2.0.0", + "debug": "^4.1.1", + "duplexify": "^4.1.1", + "help-me": "^3.0.0", + "inherits": "^2.0.3", + "lru-cache": "^6.0.0", + "minimist": "^1.2.5", + "mqtt-packet": "^6.8.0", + "number-allocator": "^1.0.9", + "pump": "^3.0.0", + "readable-stream": "^3.6.0", + "reinterval": "^1.1.0", + "rfdc": "^1.3.0", + "split2": "^3.1.0", + "ws": "^7.5.5", + "xtend": "^4.0.2" + }, + "bin": { + "mqtt": "bin/mqtt.js", + "mqtt_pub": "bin/pub.js", + "mqtt_sub": "bin/sub.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/mqtt-packet": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.10.0.tgz", + "integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==", + "dependencies": { + "bl": "^4.0.2", + "debug": "^4.1.1", + "process-nextick-args": "^2.0.1" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/number-allocator": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.10.tgz", + "integrity": "sha512-K4AvNGKo9lP6HqsZyfSr9KDaqnwFzW203inhQEOwFrmFaYevpdX4VNwdOLk197aHujzbT//z6pCBrCOUYSM5iw==", + "dependencies": { + "debug": "^4.3.1", + "js-sdsl": "^2.1.2" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/reinterval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz", + "integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==" + }, + "node_modules/rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + }, + "dependencies": { + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "commist": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/commist/-/commist-1.1.0.tgz", + "integrity": "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==", + "requires": { + "leven": "^2.1.0", + "minimist": "^1.1.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "duplexify": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "requires": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "help-me": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/help-me/-/help-me-3.0.0.tgz", + "integrity": "sha512-hx73jClhyk910sidBB7ERlnhMlFsJJIBqSVMFDwPN8o2v9nmp5KgLq1Xz1Bf1fCMMZ6mPrX159iG0VLy/fPMtQ==", + "requires": { + "glob": "^7.1.6", + "readable-stream": "^3.6.0" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "js-sdsl": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-2.1.4.tgz", + "integrity": "sha512-/Ew+CJWHNddr7sjwgxaVeIORIH4AMVC9dy0hPf540ZGMVgS9d3ajwuVdyhDt6/QUvT8ATjR3yuYBKsS79F+H4A==" + }, + "leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==" + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + }, + "mqtt": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-4.3.7.tgz", + "integrity": "sha512-ew3qwG/TJRorTz47eW46vZ5oBw5MEYbQZVaEji44j5lAUSQSqIEoul7Kua/BatBW0H0kKQcC9kwUHa1qzaWHSw==", + "requires": { + "commist": "^1.0.0", + "concat-stream": "^2.0.0", + "debug": "^4.1.1", + "duplexify": "^4.1.1", + "help-me": "^3.0.0", + "inherits": "^2.0.3", + "lru-cache": "^6.0.0", + "minimist": "^1.2.5", + "mqtt-packet": "^6.8.0", + "number-allocator": "^1.0.9", + "pump": "^3.0.0", + "readable-stream": "^3.6.0", + "reinterval": "^1.1.0", + "rfdc": "^1.3.0", + "split2": "^3.1.0", + "ws": "^7.5.5", + "xtend": "^4.0.2" + } + }, + "mqtt-packet": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.10.0.tgz", + "integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==", + "requires": { + "bl": "^4.0.2", + "debug": "^4.1.1", + "process-nextick-args": "^2.0.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "number-allocator": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.10.tgz", + "integrity": "sha512-K4AvNGKo9lP6HqsZyfSr9KDaqnwFzW203inhQEOwFrmFaYevpdX4VNwdOLk197aHujzbT//z6pCBrCOUYSM5iw==", + "requires": { + "debug": "^4.3.1", + "js-sdsl": "^2.1.2" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "reinterval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz", + "integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==" + }, + "rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "requires": { + "readable-stream": "^3.0.0" + } + }, + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "requires": {} + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } +} diff --git a/src/modules/TrainControllerHW_WIN64/TestEnv/package.json b/src/modules/TrainControllerHW_WIN64/TestEnv/package.json new file mode 100644 index 00000000..22d724b2 --- /dev/null +++ b/src/modules/TrainControllerHW_WIN64/TestEnv/package.json @@ -0,0 +1,15 @@ +{ + "name": "trains", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "start": "node index.js" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "mqtt": "^4.3.7" + } +} diff --git a/src/modules/TrainControllerHW_WIN64/TestEnv/pubsub.py b/src/modules/TrainControllerHW_WIN64/TestEnv/pubsub.py new file mode 100644 index 00000000..02ed0ce5 --- /dev/null +++ b/src/modules/TrainControllerHW_WIN64/TestEnv/pubsub.py @@ -0,0 +1,81 @@ +# subscriber.py +import paho.mqtt.client as mqtt + +import time + +########## +# connect to server +# subscribe to topics +# +# make into a class +# add decode fucntion +# add IO +# incorporate PID + +class pubsub: + + def __init__(self): + self.topic = "xxx" + def connect() -> mqtt: + def on_connect(client, userdata, flags, rc): + if rc == 0: + print("Connected to Broker!") + else: + print("Failed to connect, returned code %d\n", rc) + + client = mqtt.Client() + client.on_connect = on_connect + client.connect("broker.hivemq.com", 8000) + self.subscibe = subscribe + + return client + + + def subscribe(self, client: mqtt, topic): + def on_message(client, userdata, msg): + print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic") + self.topic = topic + client.subscribe(self.topic) + client.on_message = on_message + + + + def publish(self, topic, msg2send): + while True: + time.sleep(1) + result = self.client.publish(topic, msg2send) + # result: [0, 1] + status = result[0] + if status == 0: + print(f"Send `{self.msg2send}` to topic `{topic}`") + else: + print(f"Failed to send message to topic {topic}") + + + + def decode(self, msg): + if (msg.topic == "trains/power"): + if "power" in msg.topic: + #updateSpeed(msg.payload) + #call power + #todo + pass + + elif (msg.topic == "trains/lights"): + if "lights" in msg.topic: + #call lights + #todo + pass + #the rest + #todo + # + + + def run(self): + client = self.connect() + client.loop_start() + self.publish(client) + + + + diff --git a/src/modules/TrainControllerHW_WIN64/TestEnv/pubsub.ts b/src/modules/TrainControllerHW_WIN64/TestEnv/pubsub.ts new file mode 100644 index 00000000..04686a32 --- /dev/null +++ b/src/modules/TrainControllerHW_WIN64/TestEnv/pubsub.ts @@ -0,0 +1,50 @@ +import mqtt from "mqtt"; + +//for msg handling +// inQ = new Array(); +// outQ = new Array(); + +//for connection purposes +const websocketUrl = "ws://broker.hivemq.com"; +const client = mqtt.connect(websocketUrl); +const topic = 'train/vitals' + +//sub to topic +client.subscribe(topic); //not including power + + +client.on('connect', () => { + console.log('Connected') + client.subscribe([topic], () => { + console.log(`Subscribe to topic '${topic}'`) + }) + client.publish(topic, 'nodejs mqtt test', { qos: 0, retain: false }, (error) => { + if (error) { + console.error(error) + } + }) +}) + + +client.on('message', (topic, payload) => { + console.log('Received Message:', topic, payload.toString()) +}) + +// function on_connect(client) { + +// //client.subscribe(//power); +// //client.subscribe(//externals); + +// } + +// function on_message(client) { +// client.on("message", (topic,message,packet) => { +// console.log(new TextDecoder("utf-8").decode(message)); +// } + + + +// // client.on("message", (topic, message, packet) => { +// // callBack(JSON.parse(new TextDecoder("utf-8").decode(message))); +// // }); +// } \ No newline at end of file diff --git a/src/modules/TrainControllerHW_WIN64/TestEnv/pubsubV2.py b/src/modules/TrainControllerHW_WIN64/TestEnv/pubsubV2.py new file mode 100644 index 00000000..248831ef --- /dev/null +++ b/src/modules/TrainControllerHW_WIN64/TestEnv/pubsubV2.py @@ -0,0 +1,82 @@ +# subscriber.py +import paho.mqtt.client as mqtt +import paho.mqtt.publish as publish +import paho.mqtt.subscribe as subscribe + +import time + +class mqttHW(mqtt.Client): + def __init__(self): + super().__init__() + self.recieve_data = "" + self.recieve_time = "" + self.lasttime = "" + self.broker = "broker.hivemq.com" + self.channel = 8000 + self.on_connect() + + def on_connect(self, mqttc, obj, flags, rc): + # print("rc: "+str(rc)) + client = mqtt.Client() + client.on_connect = self.on_connect + client.connect(self.broker, self.channel) + self.subscibe = subscribe("trains/brake") + + + def on_message(self, mqttc, obj, msg): + print(msg.topic + " " + str(msg.payload)) + self.recieve_time = time.time() + self.recieve_data = (msg.payload).decode() + + + def run(self, topic): + self.connect(self.broker, 1883, 60) + self.subscribe(topic, 0) + + self.loop_start() + + rc = 0 + + return rc + + + def publish_message(self, topic, msg): + publish.single(topic, msg, self.broker) + + + def isNew(self): + flag = False + if self.lasttime == self.recieve_time: flag = False + else: flag = True + self.lasttime = self.recieve_time + return flag + + def getRdata(self): + return self.recieve_data + + + + +# If you want to use a specific client id, use +# mqttc = MyMQTTClass("client-id") +# but note that the client id must be unique on the broker. Leaving the client +# id parameter empty will generate a random id for you. +mqttc = MyMQTTClass("Trains") +rc = mqttc.run("localhost","testTopic1") + +print("rc: "+str(rc)) + +i=0 +while(1): + i+=1 + print(i) + mqttc.publish_message("localhost", "testTopic2",i) + + if mqttc.isNew(): print(mqttc.recieve_data) + + + def run(self): + client.on_connect = self.on_connect + client.on_message = self.on_message + client.on_publish = self.on_publish + client.on_subscribe = self.on_subscribe \ No newline at end of file diff --git a/src/modules/TrainControllerHW_WIN64/TestEnv/pubsubt.py b/src/modules/TrainControllerHW_WIN64/TestEnv/pubsubt.py new file mode 100644 index 00000000..02ed0ce5 --- /dev/null +++ b/src/modules/TrainControllerHW_WIN64/TestEnv/pubsubt.py @@ -0,0 +1,81 @@ +# subscriber.py +import paho.mqtt.client as mqtt + +import time + +########## +# connect to server +# subscribe to topics +# +# make into a class +# add decode fucntion +# add IO +# incorporate PID + +class pubsub: + + def __init__(self): + self.topic = "xxx" + def connect() -> mqtt: + def on_connect(client, userdata, flags, rc): + if rc == 0: + print("Connected to Broker!") + else: + print("Failed to connect, returned code %d\n", rc) + + client = mqtt.Client() + client.on_connect = on_connect + client.connect("broker.hivemq.com", 8000) + self.subscibe = subscribe + + return client + + + def subscribe(self, client: mqtt, topic): + def on_message(client, userdata, msg): + print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic") + self.topic = topic + client.subscribe(self.topic) + client.on_message = on_message + + + + def publish(self, topic, msg2send): + while True: + time.sleep(1) + result = self.client.publish(topic, msg2send) + # result: [0, 1] + status = result[0] + if status == 0: + print(f"Send `{self.msg2send}` to topic `{topic}`") + else: + print(f"Failed to send message to topic {topic}") + + + + def decode(self, msg): + if (msg.topic == "trains/power"): + if "power" in msg.topic: + #updateSpeed(msg.payload) + #call power + #todo + pass + + elif (msg.topic == "trains/lights"): + if "lights" in msg.topic: + #call lights + #todo + pass + #the rest + #todo + # + + + def run(self): + client = self.connect() + client.loop_start() + self.publish(client) + + + + diff --git a/src/modules/TrainControllerHW_WIN64/src/testTM.py b/src/modules/TrainControllerHW_WIN64/src/testTM.py new file mode 100644 index 00000000..8007237a --- /dev/null +++ b/src/modules/TrainControllerHW_WIN64/src/testTM.py @@ -0,0 +1,353 @@ +from asyncio import open_connection +from pydoc_data.topics import topics +import time +import paho.mqtt.client as mqtt +broker = "broker.hivemq.com" +port = 8000 + + + +class testInOut(): + def __init__(self): + self.prevmsgIn = "" + self.prevmsgOut = "" + self.msgOut = "" + self.prevTopic = "" + self.topicOut = "" + self.IDnum = "TCHW TESTER" + + self.client = mqtt.Client() + self.client.on_publish = self.on_publish + self.client.on_connect = self.on_connect + self.client.on_message = self.on_message + + + print("CONNECTING...") + self.client.connect("broker.hivemq.com", 1883, 8000) + self.topicList = ["trains/PID","trains/nonvitals","trains/vitals", "trains/updates"] + self.client.loop_start() + self.testguy() + + + def on_publish(self, client, userdata, result): #create function for callback + if (result > 0): + print("SEND SUCCESS") + else: + print(f"FAILED TO SEND w/ CODE: {client.rc}") + + + def on_connect(self, client, userdata, flags, rc): + print("CONNECTED W/ CODE: ", {rc} ) + self.client.subscribe("trains/vitals") + self.client.subscribe("trains/PISystem") + self.client.subscribe("trains/nonvitals") + self.client.subscribe("trains/updates") + temp = f"{self.IDnum} joined!" + self.client.publish("trains/updates", temp) + + + # def publish_handler(self, topic = "trains/updates", txt = "empty update"): + # tempresult = self.client.publish(topic,txt) + # print("message sent status: ") + # print(tempresult) + + + def on_message(self, client, userdata, msg): + if ((msg.topic in self.topicList) and (msg.payload != self.prevmsgIn)): + #TODO + self.decodeguy(msg) + + + elif(self.prevmsgIn == msg.payload): + print("ERROR! REPEATED MSG: ") + print(f"{msg.payload}") + print("PREV MSG: ") + print(f"{self.prevmsgIn}") + + else: + print("ERROR! INVALID ENTRY: ") + print(f"{msg.payload}") + + self.prevmsgIn = msg.payload + + + # update TC info + # if GPIO + # access GPIO + + + def publishHandler(self, topic = "trains/updates",msg= "blank msg"): + # temp = f"MSG: {msg} SENT TO {topic}" + # self.client.publish(topic, msg) + + + ################################ IMPORTANT ###################### + #ex) in JS + # within given function + #[using inc CMDV as example] + # + # if (this->isAuto()): + #this->publishHandler("trains/vitals", "icmdV") + # else: + #TrainCOntroller SW module + + + pass + + def decodeguy(self,msg): + pass + + def testguy(self): + #self.client.loop_write() + temp = "###############BEGIN TEST LOOP: POWER INPUTS FIRST ###############" + print(temp) + self.client.publish("trains/vitals", temp) + + + print("testing PID, SPEED TOO HIGH") + self.client.publish("trains/vitals", "scv 100") + time.sleep(1) + + print("GET POWER 1") + self.client.publish("trains/vitals", "GPOW") + time.sleep(1) + + print("SET CMD VEL") + self.client.publish("trains/vitals", "ScmdV 30") + time.sleep(1) + + print("GET CURRV VEL 1") + self.client.publish("trains/vitals", "GcurrV") + time.sleep(1) + + print("GET POWER 1") + self.client.publish("trains/vitals", "GPOW") + time.sleep(1) + + + + print("testing PID 2") + self.client.publish("trains/vitals", "scv 25") + time.sleep(1) + + print("GET POWER 2") + self.client.publish("trains/vitals", "GPOW") + time.sleep(1) + + print("GET CMD VEL") + self.client.publish("trains/vitals", "GcmdV") + time.sleep(1) + + print("GET CURRV VEL 2") + self.client.publish("trains/vitals", "GcurrV") + time.sleep(1) + + print("SET CURRV VEL") + self.client.publish("trains/vitals", "ScurrV 250") + time.sleep(1) + + print("GET POWER 3") + self.client.publish("trains/vitals", "GPOW") + time.sleep(1) + + print("testing PID 3") + self.client.publish("trains/vitals", "scv 25") + time.sleep(1) + + print("GET CURRV VEL 3") + self.client.publish("trains/vitals", "GcurrV") + time.sleep(1) + + print("GET POWER 4") + self.client.publish("trains/vitals", "GPOW") + time.sleep(1) + + print("SET AUTH VEL") + self.client.publish("trains/vitals", "Sauth 155") + time.sleep(1) + + print("GET AUTH VEL") + self.client.publish("trains/vitals", "Gauth") + time.sleep(1) + + print("INC CMD VEL") + self.client.publish("trains/vitals", "icmdV") + time.sleep(1) + + print("DEC CMD VEL") + self.client.publish("trains/vitals", "dcmdV") + time.sleep(1) + + print("GET KP") + self.client.publish("trains/vitals", "gkp") + time.sleep(1) + + print("SET KP") + self.client.publish("trains/vitals", "skp 8000") + time.sleep(1) + + print("INCREASE KP") + self.client.publish("trains/vitals", "ikp") + time.sleep(1) + + print("DECREASE KP") + self.client.publish("trains/vitals", "dkp") + time.sleep(1) + + print("GET KI") + self.client.publish("trains/vitals", "gki") + time.sleep(1) + + print("SET KI") + self.client.publish("trains/vitals", "ski 4200") + time.sleep(1) + + print("INCREASE KI") + self.client.publish("trains/vitals", "iki") + time.sleep(1) + + print("DECREASE KI") + self.client.publish("trains/vitals", "dki") + time.sleep(1) + + + temp = "############### VITALS NEXT ###############" + time.sleep(2) + print(temp) + self.client.publish("trains/vitals", temp) + + + # EBRAKE ON + print("e. emergency brake ON") + self.client.publish("trains/vitals", "eb1") + time.sleep(1) + + #GET EBRAKE + print("e. GET EBRAKE") + self.client.publish("trains/vitals", "geb") + time.sleep(1) + + #BRAKE ON + print("f. service brake ON") + self.client.publish("trains/vitals", "sb1") + time.sleep(1) + + # GET BRAKE + print("e. get brake") + self.client.publish("trains/vitals", "gsb") + time.sleep(1) + + + #AUTO ON + print("f.1. AUTO ON") + self.client.publish("trains/vitals", "auto1") + + #SIGNAL FAIL + print("g. testing signal fail") + self.client.publish("trains/vitals", "sf1") + time.sleep(1) + + #ENGINE FAIL + print("h. testing engine failS") + self.client.publish("trains/vitals", "ef1") + time.sleep(1) + + #BRAKE FAIL + print("i. testing brake fail") + self.client.publish("trains/vitals", "bf1") + + #GET AUTO + print("i.1. get AUTO") + self.client.publish("trains/vitals", "Gauto") + + + + temp = "j.############### NONVITALS TURN ON ###############" + time.sleep(2) + print(temp) + self.client.publish("trains/nonvitals", temp) + self.client.publish("trains/updates", temp) + #LEFT DOOR OPEN + print("k. testing L door ON") + self.client.publish("trains/nonvitals", "ld1") + time.sleep(1) + + #RIGHT DOOR OPEN + print("l. testing R door ON") + self.client.publish("trains/nonvitals", "rd1") + time.sleep(1) + + #EXT LIGHTS ON + print("m. EXT LIGHT ON") + self.client.publish("trains/nonvitals", "el1") + time.sleep(1) + + #IN LIGHTS ON + print("n. INT LIGHT ON") + self.client.publish("trains/nonvitals", "il1") + time.sleep(1) + + #GET TEMP + print("n. GET TEMP") + self.client.publish("trains/nonvitals", "Gtemp") + time.sleep(1) + + #INCREASE TEMP + print("n. INC TEMP") + self.client.publish("trains/nonvitals", "Itemp") + time.sleep(1) + + #DECREASAE TEMP + print("n. DEC TEMP") + self.client.publish("trains/nonvitals", "Dtemp") + time.sleep(1) + + + temp = "p. ############### TURNING OFF: VITALS ###############" + print(temp) + self.client.publish("trains/updates", temp) + time.sleep(2) + + #EBRAKE OFF + print("q. emergency brake OFF") + self.client.publish("trains/vitals", "eb0") + time.sleep(1) + + #BRAKE OFF + print("r. service brake OFF") + self.client.publish("trains/vitals", "sb0") + time.sleep(1) + + #RESET FAILS + print("s. testing reset fails") + self.client.publish("trains/vitals", "ref") + time.sleep(1) + + #LEFT DOOR CLOSE + print("t. testing L door OFF") + self.client.publish("trains/nonvitals", "ld0") + time.sleep(1) + + #RIGHT DOOR CLOSE + print("u. testing R door OFF") + self.client.publish("trains/nonvitals", "rd0") + time.sleep(1) + + #EXT LIGHT OFF + print("v. EXT LIGHT OFF") + self.client.publish("trains/nonvitals", "el0") + time.sleep(1) + + #INT lIGHT OFF + print("w. INT LIGHT OFF") + self.client.publish("trains/nonvitals", "il0") + time.sleep(1) + + #TURN AUTO OFF + print("x. AUTO OFF") + self.client.publish("trains/vitals", "auto0") + time.sleep(1) + + +tester = testInOut() +