########################################################################### # Dispatcher System ########################################################################### import java from java.awt import Dimension from javax.swing import JButton, JFrame,JPanel,BoxLayout,Box from javax.swing import JLabel, JMenu, JMenuItem, JMenuBar from javax.swing import JFileChooser,JTextField, BorderFactory from javax.swing import SwingWorker, SwingUtilities from javax.swing import WindowConstants, JDialog, JTextArea from java.awt import Color, Font from java.awt.event import WindowEvent import jmri from xml.etree.ElementTree import ElementTree from xml.etree.ElementTree import Element from xml.etree.ElementTree import SubElement import xml.etree.ElementTree as ET import subprocess import sys my_path_to_jars = jmri.util.FileUtil.getExternalFilename('program:jython/DispatcherSystem/jars/jgrapht.jar') sys.path.append(my_path_to_jars) # add the jar to your path from org.jgrapht.graph import DefaultWeightedEdge from org.jgrapht.graph import DirectedWeightedMultigraph import threading import time import webbrowser import os def strip_end(text, suffix): if not text.endswith(suffix): return text return text[:len(text)-len(suffix)] def btnpanelLocation_action(event): global icons_file global run_file global start_file #print "clicked" chooser = jmri.configurexml.LoadStoreBaseAction.getUserFileChooser() returnVal = chooser.showOpenDialog(frame) current_file = str(chooser.getSelectedFile()) #print current_file filepath = os.path.dirname(current_file) root = os.path.splitext(os.path.basename(current_file)) old_filename = root[0] filetype = root[1] #print old_filename # if "run" not in old_filename and "icons" not in old_filename: # #print "run not in filepath" # start_file = current_file # icons_file = filepath + "/" + old_filename + "_icons" + filetype # run_file = filepath + "/" + old_filename + "_run" + filetype # else: # stripped_filename = strip_end(old_filename,"_icons") # stripped_filename = strip_end(stripped_filename,"_run") # start_file = filepath + "/" + stripped_filename + filetype # icons_file = filepath + "/" + stripped_filename + "_icons" + filetype # run_file = filepath + "/" + stripped_filename + "_run" + filetype start_file = current_file label_panel_location.text = start_file #row13b2.text = icons_file #row11b2.text = run_file #os.rename(r'filepath/old_filename.file type',r'file path/NEW file name.file type') def CreateIcons_action(event): global f1 initialPanelFilename = start_file finalPanelFilename = icons_file # print "save panel" saveOrigPanel() # print "process panels" result = processPanels() # result is "Success" or "Failure" # stage2 if str(result) == "Success": CreateTransits() else: title = "Error in Routine" msg = "Not creating Transits as failure in earlier routine" Query().displayMessage(msg,title) # print "Created Transits" def saveOrigPanel(): global backup_file global backup_filename get_backup_filename() store_panel(backup_file) def get_start_filename(): global start_filename global start_file chooser = jmri.configurexml.LoadStoreBaseAction.getUserFileChooser() #returnVal = chooser.showOpenDialog(frame) current_file = str(chooser.getSelectedFile()) #print current_file filepath = os.path.dirname(current_file) directory = filepath root = os.path.splitext(os.path.basename(current_file)) old_filename = root[0] filetype = root[1] #print old_filename # if "run" not in old_filename and "icons" not in old_filename: #print "run not in filepath" start_file = current_file icons_file = filepath + "/" + old_filename + "_icons" + filetype run_file = filepath + "/" + old_filename + "_run" + filetype start_filename = old_filename loaded_filename = old_filename def get_backup_filename(): global backup_file global backup_filename panel_name = start_file filepath = os.path.dirname(panel_name) root = os.path.splitext(os.path.basename(panel_name)) filename_root = root[0] filetype = root[1] orig_panel_path = filepath + "/" + filename_root + "_backup" + filetype orig_panel_name = filename_root + "_backup" i = 0 while os.path.exists(orig_panel_path): i+=1 orig_panel_path = filepath + "/" + filename_root + "_backup" + "_" + str(i) + filetype orig_panel_name = filename_root + "_backup" + "_" + str(i) #print "orig_panel_path", orig_panel_path backup_file = orig_panel_path backup_filename = orig_panel_name def store_panel(filename): #if self.logLevel > 1: print "storing orig file in " + filename file = java.io.File(filename) cm = jmri.InstanceManager.getNullableDefault(jmri.ConfigureManager) result = cm.storeUser(file) if result : msg = "store was successful" else: msg = "store failed" #if self.logLevel > 1: print(msg) def initialise_panel_location(stage1Button, stage3Button): global icons_file global run_file global start_file global directory global start_filename global loaded_filename global backup_file global backup_filename #print "clicked" chooser = jmri.configurexml.LoadStoreBaseAction.getUserFileChooser() robot = java.awt.Robot() #press the save tab KeyEvent = java.awt.event.KeyEvent #button.requestFocus(); #robot.delay(1000) # robot.keyPress(KeyEvent.VK_TAB) # robot.delay(10) # robot.keyRelease(KeyEvent.VK_TAB) # robot.delay(10) # robot.keyPress(KeyEvent.VK_SPACE) # robot.delay(10) # robot.keyRelease(KeyEvent.VK_SPACE) # robot.delay(10) # robot.keyPress(KeyEvent.VK_ENTER) # robot.delay(10) # robot.keyRelease(KeyEvent.VK_ENTER) # robot.delay(10) #returnVal = chooser.showOpenDialog(frame) current_file = str(chooser.getSelectedFile()) #print current_file filepath = os.path.dirname(current_file) directory = filepath root = os.path.splitext(os.path.basename(current_file)) old_filename = root[0] filetype = root[1] #print old_filename # if "run" not in old_filename and "icons" not in old_filename: #print "run not in filepath" start_file = current_file icons_file = filepath + "/" + old_filename + "_icons" + filetype run_file = filepath + "/" + old_filename + "_run" + filetype start_filename = old_filename loaded_filename = old_filename stage_to_run = "Stage 1" label_panel_location.text = start_file #msg = "Panel Directory: " + str(directory) #rowTitle_1_2.text = msg get_backup_filename() #rowStage1Title_2.text = "Modifies: " + start_filename + " Creates backup: " + backup_filename #row42b2.text = "Produces: " + start_filename + "_run" + filetype + " (from " + start_filename + "_icons" + filetype + ")" rowTitle_2_1.text = "You have " + loaded_filename + filetype + " loaded. You may run " + stage_to_run rowTitle_2_1.text = "Dispatcher System: Modifies current loaded panel to produce a running system" rowTitle_2_1.setFont(rowTitle_2_1.getFont().deriveFont(Font.BOLD, 13)); def CreateTransits_action(event): CreateTransits() def CreateTransits(): global g global le global logLevel global dpg #print "Setting up Graph" my_path_to_jars = jmri.util.FileUtil.getExternalFilename('program:jython/DispatcherSystem/jars/jgrapht.jar') import sys sys.path.append(my_path_to_jars) # add the jar to your path CreateGraph = jmri.util.FileUtil.getExternalFilename('program:jython/DispatcherSystem/CreateGraph.py') exec(open (CreateGraph).read()) le = LabelledEdge g = StationGraph() #print "Creating Transits" CreateTransits = jmri.util.FileUtil.getExternalFilename('program:jython/DispatcherSystem/CreateTransits.py') exec(open (CreateTransits).read()) global dpg dpg = DisplayProgress() #print "about to run CreateTransits" ct = CreateTransits() ct.run_transits() #print "ran CreateTransits" def show_options_message(msg): dialog = JDialog(None, 'Confirm Dispatcher Options', False) panel = JPanel(); panel.add(JTextArea(msg)) dialog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); dialog.getContentPane().add(panel); dialog.pack(); dialog.setVisible(True); def show_options_pane(): DispatcherFrame = jmri.jmrit.dispatcher.DispatcherFrame() OptionsMenu = jmri.jmrit.dispatcher.OptionsMenu(DispatcherFrame) robot = java.awt.Robot() #press the save tab KeyEvent = java.awt.event.KeyEvent #button.requestFocus(); #robot.delay(10) robot.keyPress(KeyEvent.VK_WINDOWS) robot.keyPress(KeyEvent.VK_F10) robot.delay(10) robot.keyRelease(KeyEvent.VK_F10) robot.delay(10) robot.keyRelease(KeyEvent.VK_WINDOWS) robot.delay(10) robot.keyPress(KeyEvent.VK_DOWN) robot.delay(10) robot.keyRelease(KeyEvent.VK_DOWN) robot.delay(10) robot.keyPress(KeyEvent.VK_DOWN) robot.delay(10) robot.keyRelease(KeyEvent.VK_DOWN) robot.delay(10) robot.keyPress(KeyEvent.VK_DOWN) robot.delay(10) robot.keyRelease(KeyEvent.VK_DOWN) robot.delay(10) robot.keyPress(KeyEvent.VK_SPACE) robot.delay(10) robot.keyRelease(KeyEvent.VK_SPACE) robot.delay(10) def ChangeOptions_action(event): y = threading.Timer(0.1, function = show_options_pane) y.start() msg = "You need to set the following: \n\n Use connectivity from Layout panels\n Trains from Roster\n Layout has block detection hardware\n Automatically allocate Sections to Active Trains\n Automatically set turnouts when a Section is allocated\n Apply Connections Turnout Delay\n\n The last option will set any turnouts sequentially with a delay between each to stop putting excessive demand on the controllers\n The default delay is 1000ms for most connections, 100ms for CAN connections\n This can be changed in Preferences > Connections > Connection Tab > Additional Connection Settings > Output Interval\n\n You also need to set SignalMasts/SML (top RH)\n and the Layout scale\n\n Save your Options in the Menu in the Dispatcher Frame after checking.\n ---------------------------------------------------------------------\n " + \ "\n IMPORTANT: After setting the options above you also need to set the Layout Scale in Preferences:Warrants \n to ensure the trains stop correctly\n" x = threading.Timer(2.0, function=show_options_message, args=(msg,)) x.start() def setAdvancedRouting(): jmri.InstanceManager.getDefault(jmri.jmrit.display.layoutEditor.LayoutBlockManager).enableAdvancedRouting(True) # def RunDispatcher_action(event): # global DispatchMaster # print "in RunDispatcher_action" # RunDispatch = jmri.util.FileUtil.getExternalFilename('program:jython/DispatcherSystem/RunDispatch.py') # DispatchMaster = DispatchMaster # exec(open (RunDispatch).read()) def leftJustify( panel ): b = Box.createHorizontalBox() b.add( panel ) b.add( Box.createHorizontalGlue() ) # (Note that you could throw a lot more components # and struts and glue in here.) return b ################################################################################################################ # main file ################################################################################################################ global start_filename global backup_filename start_file = "" run_file = "" directory = "" logLevel = 0 #***************** # Set Program locations, and include code #***************** CreateIcons = jmri.util.FileUtil.getExternalFilename('program:jython/DispatcherSystem/CreateIcons.py') execfile(CreateIcons) # delete previous Dispatch System Frames for frame1 in java.awt.Frame.getFrames(): # print "frame", frame1.getName() if frame1.getName() == "Dispatch System": # print "deleting frame", frame.getName() frame1.dispatchEvent(WindowEvent(frame, WindowEvent.WINDOW_CLOSING)) #***************** frame = jmri.util.JmriJFrame('Dispatch System'); frame.setName("Dispatch System") frame.addHelpMenu('html.scripthelp.DispatcherSystem.DispatcherSystem' , True) panel = JPanel() panel.setLayout(BoxLayout(panel, BoxLayout.Y_AXIS)) frame.add(panel) row0 = JPanel() row0.setLayout(BoxLayout(row0, BoxLayout.X_AXIS)) txt = JTextField(140) txt.setMaximumSize( txt.getPreferredSize() ); txt.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createLineBorder(Color.red), txt.getBorder())); label_panel_location = JLabel() btnpanelLocation = JButton("Set Panel Location", actionPerformed = btnpanelLocation_action) row0.add(Box.createVerticalGlue()) row0.add(Box.createRigidArea(Dimension(20, 0))) row0.add(btnpanelLocation) row0.add(Box.createRigidArea(Dimension(20, 0))) row0.add(label_panel_location) row0.add(Box.createRigidArea(Dimension(20, 0))) rowTitle_22 = JPanel() rowTitle_22.setLayout(BoxLayout(rowTitle_22, BoxLayout.X_AXIS)) rowTitle_23 = JPanel() rowTitle_23.setLayout(BoxLayout(rowTitle_23, BoxLayout.X_AXIS)) rowStage1Title_1 = JLabel("Stage1: ") get_start_filename() get_backup_filename() rowStage1Title_1 = JLabel(" Modifies: " + start_filename + " Creates backup: " + backup_filename) rowStage1Title_1.add(Box.createHorizontalGlue()); rowStage1Title_1.setAlignmentX(rowStage1Title_1.LEFT_ALIGNMENT) rowStage1Title_2 = JLabel("") rowStage1Title_3 = JLabel(" Read Help to see how system works") #start_filename + "_icons" rowTitle_22.add(Box.createVerticalGlue()) rowTitle_22.add(Box.createRigidArea(Dimension(20, 0))) rowTitle_22.add(rowStage1Title_1) rowTitle_22.add(Box.createRigidArea(Dimension(20, 0))) rowTitle_22.add(rowStage1Title_2) rowTitle_23.add(Box.createVerticalGlue()) rowTitle_23.add(Box.createRigidArea(Dimension(20, 0))) rowTitle_23.add(rowStage1Title_3) rowStage2Title = JPanel() rowStage2Title.setLayout(BoxLayout(rowStage2Title, BoxLayout.X_AXIS)) rowStage2Title_1 = JLabel("Stage2: Check the Dispatcher Options are set correctly (essential)") rowStage2Title_1.add(Box.createHorizontalGlue()); rowStage2Title_1.setAlignmentX(rowStage2Title_1.LEFT_ALIGNMENT) rowStage2Title_2 = JLabel("") #start_filename + "_icons" rowStage2Title.add(Box.createVerticalGlue()) rowStage2Title.add(Box.createRigidArea(Dimension(20, 0))) rowStage2Title.add(rowStage2Title_1) rowStage2Title.add(Box.createRigidArea(Dimension(20, 0))) rowStage2Title.add(rowStage2Title_2) rowTitle_2 = JPanel() rowTitle_2.setLayout(BoxLayout(rowTitle_2, BoxLayout.X_AXIS)) rowTitle_2_1 = JLabel("Stage3: Modify the Dispatcher Options so the trains move") rowTitle_2_1.add(Box.createHorizontalGlue()); rowTitle_2_1.setAlignmentX(rowTitle_2_1.LEFT_ALIGNMENT) rowTitle_2_2 = JLabel("") #start_filename + "_icons" rowTitle_2.add(Box.createVerticalGlue()) rowTitle_2.add(Box.createRigidArea(Dimension(20, 0))) rowTitle_2.add(rowTitle_2_1) rowTitle_2.add(Box.createRigidArea(Dimension(20, 0))) rowTitle_2.add(rowTitle_2_2) row_Title_3 = JPanel() row_Title_3.setLayout(BoxLayout(row_Title_3, BoxLayout.X_AXIS)) rowTitle_3_1 = JLabel("*******************************************************************") rowTitle_3_1.add(Box.createHorizontalGlue()); rowTitle_3_1.setAlignmentX(rowTitle_3_1.LEFT_ALIGNMENT) rowTitle_3_2 = JLabel("") row_Title_3.add(Box.createVerticalGlue()) row_Title_3.add(Box.createRigidArea(Dimension(20, 0))) row_Title_3.add(rowTitle_3_1) row_Title_3.add(Box.createRigidArea(Dimension(20, 0))) row_Title_3.add(rowTitle_3_2) rowStage2Separator = JPanel() rowStage2Separator.setLayout(BoxLayout(rowStage2Separator, BoxLayout.X_AXIS)) rowStage2Separator_1 = JLabel("*******************************************************************") rowStage2Separator_1.add(Box.createHorizontalGlue()); rowStage2Separator_1.setAlignmentX(rowStage2Separator_1.LEFT_ALIGNMENT) rowStage2Separator_2 = JLabel("") rowStage2Separator.add(Box.createVerticalGlue()) rowStage2Separator.add(Box.createRigidArea(Dimension(20, 0))) rowStage2Separator.add(rowStage2Separator_1) rowStage2Separator.add(Box.createRigidArea(Dimension(20, 0))) rowStage2Separator.add(rowStage2Separator_2) rowStage1Separator = JPanel() rowStage1Separator.setLayout(BoxLayout(rowStage1Separator, BoxLayout.X_AXIS)) rowStage1Separator_1 = JLabel("*******************************************************************") rowStage1Separator_1.add(Box.createHorizontalGlue()); rowStage1Separator_1.setAlignmentX(rowStage1Separator_1.LEFT_ALIGNMENT) rowStage1Separator_2 = JLabel("") rowStage1Separator.add(Box.createVerticalGlue()) rowStage1Separator.add(Box.createRigidArea(Dimension(20, 0))) rowStage1Separator.add(rowStage1Separator_1) rowStage1Separator.add(Box.createRigidArea(Dimension(20, 0))) rowStage1Separator.add(rowStage1Separator_2) rowStage1Button = JPanel() rowStage1Button.setLayout(BoxLayout(rowStage1Button, BoxLayout.X_AXIS)) rowrowStage1Button_2 = JLabel("Sets Up everything to run trains using Dispatcher") rowrowStage1Button_2.setFont(rowTitle_2_1.getFont().deriveFont(Font.BOLD, 13)); rowrowStage1Button_2.add(Box.createHorizontalGlue()); rowrowStage1Button_2.setAlignmentX(rowrowStage1Button_2.LEFT_ALIGNMENT) rowStage1Button_1 = JButton("Stage1", actionPerformed = CreateIcons_action) stage1Button = rowStage1Button_1 rowStage1Button.add(Box.createVerticalGlue()) rowStage1Button.add(Box.createRigidArea(Dimension(20, 0))) rowStage1Button.add(rowStage1Button_1) rowStage1Button.add(Box.createRigidArea(Dimension(20, 0))) rowStage1Button.add(rowrowStage1Button_2) #initialise_panel_location(stage1Button, stage2Button, stage3Button) robot = java.awt.Robot() KeyEvent = java.awt.event.KeyEvent setAdvancedRouting() rowStage2 = JPanel() rowStage2.setLayout(BoxLayout(rowStage2, BoxLayout.X_AXIS)) rowStage2_1 = JLabel("Check Dispatcher Options are set correctly enabling Trains to Run Automatically") rowStage2_1.setFont(rowTitle_2_1.getFont().deriveFont(Font.BOLD, 13)); rowStage2_1.add(Box.createHorizontalGlue()); rowStage2_1.setAlignmentX(rowStage2_1.LEFT_ALIGNMENT) rowStage2_2 = JButton("Stage2", actionPerformed = ChangeOptions_action) stage2Button = rowStage2_2 rowStage2.add(Box.createVerticalGlue()) rowStage2.add(Box.createRigidArea(Dimension(20, 0))) rowStage2.add(rowStage2_2) rowStage2.add(Box.createRigidArea(Dimension(20, 0))) rowStage2.add(rowStage2_1) initialise_panel_location(stage1Button, stage2Button) #rowStage1Title_1 = JLabel(" Modifies: " + start_filename + " Creates backup: " + backup_filename) #Title panel.add(leftJustify(rowTitle_2)) panel.add(leftJustify(rowTitle_22)) panel.add(leftJustify(rowTitle_23)) panel.add(leftJustify(row_Title_3)) #stage1 panel.add(leftJustify(rowStage1Button)) panel.add(leftJustify(rowStage1Separator)) #stage2 panel.add(leftJustify(rowStage2)) panel.add(leftJustify(rowStage2Separator)) frame.setPreferredSize(Dimension(700, 300)) frame.pack() frame.setVisible(True)