650 lines
28 KiB
Python
650 lines
28 KiB
Python
## Version 2023-04-19:
|
||
# Essentially rewritten with augmented comments
|
||
# Avoid potential cross-thread contamination and resulting crashes
|
||
# by minimizing Table windows that get updated as Sensors are
|
||
# created and Blocks are edited.
|
||
# Cope with Blocks exported from unnamed AnyRail Sections.
|
||
# Cope with Blocks exported with Section names containing one or more
|
||
# LowLineChars AKA the "_" character. Turned out to be troublesome.
|
||
# Challenge Blocks exported with Section names containing only WhiteSpace
|
||
# characters.
|
||
# Extensive print output to the PanelPro Script Output window.
|
||
# Tested with AnyRail Version 6.51.0
|
||
|
||
|
||
## Version 2023-04-04: Original upload.
|
||
# Developed with PanelPro version 5.3.4+Raae2040ea3
|
||
# under Java 11.0.13
|
||
# on Windows 10 amd64 v10.0
|
||
# Tested with AnyRail Version 6.50.2
|
||
|
||
|
||
# The AnyRail program, Copyright © 2023 DRail Software, can export a track plan
|
||
# to a JMRI PanelPro XML file with a Layout Editor formatted Panel.
|
||
|
||
# See the discussion at https://www.jmri.org/community/connections/AnyRail/index.shtml
|
||
|
||
# Fair disclosure:
|
||
# MOST OF WHAT FOLLOWS is dependent upon the English (EN) language choice from
|
||
# within the AnyRail menu:
|
||
# FILE >> Options >> Languages item.
|
||
# NO OTHER LANGUAGE CHOICE HAS BEEN
|
||
# TESTED AS OF THIS TIME
|
||
# AnyRail Version 6.51.0 (Apr 6, 2023)
|
||
|
||
# If the track plan has defined "Sections," then there is a one-to-one
|
||
# translation to "Blocks" in the exported Panel file.
|
||
|
||
# The first exported PanelPro Block systemName is always "IB1"
|
||
# and the rest of the systemName values are numbered sequentially.
|
||
|
||
# An exported Block systemName might be "IB123" for some iteration, but have a
|
||
# different "IB" number the next time the plan is exported.
|
||
|
||
# The exported PanelPro Blocks do not have any assigned occupancy Sensors.
|
||
|
||
# In fact, no Sensors are defined in the exported file.
|
||
|
||
# Each PanelPro user has many options as to how to best define their own
|
||
# occupancy Sensors, but this script implements a simplistic rule.
|
||
|
||
# The derived exported PanelPro Block will have a userName that is constructed
|
||
# by concatenating several strings that are separated with LowLineChars.
|
||
# 1) A slight variation on the artificially constructed systemName,
|
||
# 2) The specific AnyRail section name, if actually defined,
|
||
# 3) The pull-down choice for the "Usage" value.
|
||
|
||
# If the AnyRail Section name were something like "West Station," and the
|
||
# selected Usage is "Detection," then the exported Block userName might look
|
||
# like "B_123_West Station_Detection" but only if the exported Block systemName
|
||
# were "IB123."
|
||
|
||
# To augment the exported PanelPro file, for each named Section and hence each
|
||
# exported Block with systemName "IBxxx", this script will create a new occupancy
|
||
# Sensor with a systemName "ISxxx" with matching digits "xxx."
|
||
|
||
# Usually, the Sensor assigned to the exported Block will be set to
|
||
# the Sensor userName, but some contingency is built in for AnyRail
|
||
# Sections with names that are either not unique or even left blank.
|
||
|
||
# If the option is set to rename the exported Block, then it's userName
|
||
# and it's comment field will match those of the created occupancy Sensor.
|
||
|
||
# The choices described above might not meet your needs.
|
||
|
||
# Each time it becomes necessary to modify the AnyRail track plan and export a
|
||
# new version of the PanelPro file, the user is forced to rebuild the list of
|
||
# Sensors that define the related Occupancy status for each Block. After
|
||
# many such revisions and the resultant efforts on a large club layout, the
|
||
# painful need for a script has led to what you are reading now.
|
||
#
|
||
# This script automates what would be a tedious and error prone process when
|
||
# done manually. It does however, require careful attention to the AnyRail
|
||
# track plan details.
|
||
#
|
||
# Be sure to investigate the lines marked with IMPORTANT OPTIONS DEFINITIONS
|
||
|
||
# This script is intended be executed EXACTLY ONCE on each NEWLY EXPORTED
|
||
# PanelPro XML file.
|
||
|
||
# ##### Begin CAUTION notification:
|
||
# AnyRail allows duplicated Section names. It also allows duplicate Label
|
||
# names for Turnouts, but that is not addressed here.
|
||
#
|
||
# Due to the script’s method of providing a userName for each Block that
|
||
# is derived from, but NOT directly copied from the AnyRail Section names,
|
||
# the exported file provides unique Block userNames that this script cannot
|
||
# always use.
|
||
#
|
||
# This script parses the original Section Name and tries to use
|
||
# it for the provided Sensor userName
|
||
# but PanelPro does not allow Sensors to have duplicated userNames.
|
||
#
|
||
# If the AnyRail track plan contains Sections with duplicated names, only
|
||
# the Block with the lowest numbered Block userName will be assigned an
|
||
# occupancy Sensor with that userName.
|
||
#
|
||
# If the script discovers a Section name that was previously used to provide
|
||
# an occupancy Sensor userName, the subsequent Sensors that would have
|
||
# duplicated that name will not be assigned a userName, and the exported
|
||
# Block userName will be used for the new Sensor’s Comment field.
|
||
# For each such case, an ERROR message is provided in the JMRI System Console
|
||
# and the log files.
|
||
# ##### End of CAUTION notification
|
||
#
|
||
# Author: Cliff Anderson, Copyright 2023, Part of the JMRI distribution
|
||
|
||
import jmri
|
||
import java
|
||
import org.slf4j.Logger
|
||
import org.slf4j.LoggerFactory
|
||
|
||
############# IMPORTANT OPTIONS DEFINITIONS:
|
||
# Define the Sensor Prefix for a DCC address (not for a LCC address) or else
|
||
# default to a temporary internal address.
|
||
defaultSensorPrefix = "IS" # Can be user modified now or at some later time
|
||
# with more control over the hardware address
|
||
# from within the
|
||
# Tools >> Tables >> Sensors window
|
||
# using the "Edit" pull-down menu
|
||
# to "move" the userNames to newly defined Sensors
|
||
|
||
## ONLY if the Block "hardware" addresses match the layout hardware Sensor addresses:
|
||
# defaultSensorPrefix = "LS" # for LocoNet
|
||
# defaultSensorPrefix = "L2S" # for a second LocoNet
|
||
# defaultSensorPrefix = "NS" # for NCE
|
||
|
||
|
||
# Decide to make the Block userName match the Sensor userName
|
||
isRenameBlocks = True # Match Block userNames with non-empty Sensor userNames
|
||
# isRenameBlocks = False # Retain AnyRail assigned Block userNames
|
||
|
||
# Not really an option, but AnyRail might choose to use some other character as a
|
||
# separator character in a future AnyRail version.
|
||
fragmentSeparator = "_" # The Low Line character
|
||
# recognized by reverse engineering, not from any documentation.
|
||
|
||
############# IMPORTANT OPTIONS DEFINITIONS ENDS
|
||
|
||
|
||
# The AnyRailBuildSensorList class controls the action of looping through
|
||
# the list of AnyRail exported Blocks and creating the Occupancy Sensors.
|
||
# In spite of an early choice to derive this class from AbstractAutomaton,
|
||
# other than the utilization of a separate thread and the labeling on the log
|
||
# file, little or no features from the parent class now come into play.
|
||
class AnyRailBuildSensorList(jmri.jmrit.automat.AbstractAutomaton):
|
||
|
||
##############################
|
||
# Predefine class variables for scope protection
|
||
|
||
##############################
|
||
# Script necessity:
|
||
log = org.slf4j.LoggerFactory.getLogger(
|
||
"jmri.jmrit.jython.exec.script.AnyRailBuildSensorList"
|
||
)
|
||
##############################
|
||
# PanelPro target information:
|
||
SensorSystemName = ""
|
||
SensorUserName = ""
|
||
SensorComment = ""
|
||
|
||
##############################
|
||
# AnyRail parsing details:
|
||
# AnyRail provides a complicated userName for each Block with:
|
||
# a string identifying what Block Number it assigned (the most recent
|
||
# export anyway)
|
||
# concatenated with
|
||
# a string telling what "Section" Name, if one was provided by the
|
||
# track plan user(s),
|
||
# concatenated with
|
||
# a string reporting what "Usage" was assigned from a pull-down list
|
||
# dialog when the Section was most recently edited.
|
||
#
|
||
# The AnyRail Usage choices list follows here:
|
||
|
||
pickUsageList = [ # plagiarized from the AnyRail Sections menu pull-down list
|
||
"Break",
|
||
"Detection",
|
||
"Pass through",
|
||
"Polarization",
|
||
"Powerless",
|
||
"Slow down and accelerate",
|
||
"Stop",
|
||
"Unspecified"
|
||
] # In alphabetic order as shown on the AnyRail screen.
|
||
|
||
##############################
|
||
# Java Swing multi-thread issue avoidance strategy, of sorts:
|
||
# Original version would sometimes crash within a Java Swing
|
||
# activity, but only if a Table window was visible on the
|
||
# screen and getting updated as a Block edit or a Sensor Create
|
||
# or Edit.
|
||
#
|
||
dangerousFrameTitleList = [ # Avoid cross thread contamination
|
||
"Block Table",
|
||
"Blocks",
|
||
"Sensor Table",
|
||
"Sensors"
|
||
] # JMRIJFrame titles to be minimized AKA hidden
|
||
|
||
# Define an empty list that might get populated.
|
||
hiddenFrames = [] # List JMRIJFrame objects that the
|
||
# script has minimized
|
||
|
||
### The Jython print function to the Script Output window seems to
|
||
### be immune or maybe thread safe.
|
||
|
||
# END OF Data Declarations
|
||
##############################
|
||
|
||
# Create an unique Occupancy Sensor for each defined AnyRail Block
|
||
def init(self):
|
||
|
||
BlockCounter = 0
|
||
DuplicateSectionNameCounter = 0
|
||
NamelessBlockCounter = 0
|
||
NonAnyRailBlockCounter = 0
|
||
QuestionableSectionNameCounter = 0
|
||
|
||
self.log.info( "AnyRailBuildSensorList ver: 2023-04-19" )
|
||
|
||
self.log.info( "Creating an Occupancy Sensor for each AnyRail Block" )
|
||
|
||
# Prevent potential crash condition
|
||
self.AviodCrossThreadPossibilities()
|
||
|
||
for someBlock in blocks.getNamedBeanSet() :
|
||
|
||
##
|
||
## For sanity checking, report what the incoming data looks like
|
||
##
|
||
blockUserName = self.ReportBlock(
|
||
someBlock,
|
||
BlockCounter
|
||
)
|
||
|
||
# Protect against some prior assignment of an Occupancy Sensor
|
||
#
|
||
# Unless this script is accidentally executed a second time,
|
||
# it is highly unlikely that there is a prior assigned Sensor
|
||
priorOccupancySensor = someBlock.getSensor()
|
||
|
||
if not (priorOccupancySensor == None) :
|
||
# Do not attempt to override any previous assignment
|
||
tempString1 = priorOccupancySensor.getSystemName()
|
||
tempString2 = priorOccupancySensor.getUserName()
|
||
tempString = 'Previously defined Occupancy Sensor = "' \
|
||
+ tempString1 \
|
||
+ '" with userName = "' \
|
||
+ tempString2 \
|
||
+ '"'
|
||
self.log.warn(tempString)
|
||
print (tempString)
|
||
continue # skip over the rest of this iteration
|
||
|
||
# priorOccupancySensor does not exist
|
||
|
||
# pick out the useful information from the exported
|
||
# Block userName noise
|
||
isBlockAnyRail \
|
||
= self.parseBlockUserName(
|
||
blockUserName
|
||
)
|
||
|
||
if not (isBlockAnyRail) :
|
||
tempString = \
|
||
'Block Named "{0}" is NOT exported AnyRail - NO new Sensor is created' \
|
||
.format(blockUserName )
|
||
self.log.info(tempString)
|
||
print tempString
|
||
NonAnyRailBlockCounter += 1
|
||
continue # skip to next someBlock iteration
|
||
|
||
##
|
||
## Report parsed Occupancy Sensor Attributes
|
||
##
|
||
tempString1 = 'New Sensor systemName = "{0}"'.format(self.SensorSystemName)
|
||
tempString2 = ' userName = "{0}"'.format(self.SensorUserName)
|
||
tempString3 = ' comment = "{0}"'.format(self.SensorComment)
|
||
tempString = tempString1 + tempString2 + tempString3
|
||
# self.log.info(tempString)
|
||
print tempString
|
||
|
||
# Create a new Occupancy Sensor
|
||
newSensor = sensors.provideSensor(self.SensorSystemName)
|
||
|
||
# AnyRail does not require unique Section names
|
||
# If this script attempts to assign a previously
|
||
# defined userName to a different Sensor, JMRI
|
||
# will ignore the request without any error or warning.
|
||
|
||
trialSensor = sensors.getByUserName(self.SensorUserName)
|
||
|
||
if not (trialSensor == None) :
|
||
# A duplicate use of the userName has been discovered
|
||
# Announce it with output message
|
||
# also provide a non-typical comment for this
|
||
# subsequent Sensor to allow easy identification
|
||
# self.log.debug('trialSensor = "{0}"'.format(str(trialSensor)))
|
||
tempString = 'Another Occupancy Sensor = "' \
|
||
+ trialSensor.getSystemName() \
|
||
+ '\" with matching userName = \"' \
|
||
+ self.SensorUserName \
|
||
+ '\" was previously created'
|
||
self.log.info(tempString)
|
||
print (tempString)
|
||
tempString = \
|
||
'\tDUPLICATED AnyRail Section Name = \"' \
|
||
+ self.SensorUserName \
|
||
+ '\" from currently selected Block = \"' \
|
||
+ blockUserName \
|
||
+ '\"'
|
||
self.log.warn(tempString)
|
||
print (tempString)
|
||
newSensor.setComment(blockUserName)
|
||
DuplicateSectionNameCounter += 1
|
||
|
||
else :
|
||
# This is the desired case, the AnyRail Section name
|
||
# self.log.debug('OK userName = "{0}"'.format(self.SensorUserName) )
|
||
newSensor.setUserName(self.SensorUserName)
|
||
|
||
# It is still possible for the track plan to have
|
||
# unnamed Sections
|
||
# This one seems to be the first duplicated Block
|
||
# userName found on the list
|
||
if (self.SensorUserName == "") :
|
||
tempString = 'Occupancy Sensor = "' \
|
||
+ self.SensorSystemName \
|
||
+ '" was exported from an unnamed Section'
|
||
self.log.info(tempString)
|
||
print (tempString)
|
||
# tempString = '\tQuestionable Section Name = "' \
|
||
# + blockUserName \
|
||
# + '\" with only WhiteSpaces characters'
|
||
# self.log.warn(tempString)
|
||
# print (tempString)
|
||
QuestionableSectionNameCounter += 1
|
||
|
||
else :
|
||
# A new Sensor with a unique and non-blank userName
|
||
# has been created
|
||
newSensor.setComment(self.SensorComment)
|
||
|
||
if (isRenameBlocks) : # User has selected the option
|
||
someBlock.setUserName(self.SensorUserName)
|
||
someBlock.setComment(self.SensorComment)
|
||
|
||
someBlock.setSensor(newSensor.getSystemName() )
|
||
|
||
BlockCounter += 1
|
||
print ("") # Place a blank line separator on the Script Output window
|
||
# self.log.debug( 'BlockCounter = {0}'.format(BlockCounter))
|
||
|
||
###############################
|
||
####### END of "for" loop through exported Blocks
|
||
|
||
# print the tallies
|
||
self.SummariseTallies(
|
||
NonAnyRailBlockCounter,
|
||
QuestionableSectionNameCounter,
|
||
DuplicateSectionNameCounter,
|
||
BlockCounter
|
||
)
|
||
|
||
return
|
||
|
||
###############################
|
||
## End of AnyRailBuildSensorList.init()
|
||
|
||
# Define an almost empty task to run once
|
||
def handle(self):
|
||
# Clean up the minimized windows (if any) mess
|
||
for minimizedFrame in self.hiddenFrames :
|
||
minimizedFrame.setVisible(True)
|
||
self.log.info('Restoring window named "{0}"'.format(minimizedFrame.getTitle()) )
|
||
|
||
# Make a record for the log to indicate that we have completed the task
|
||
self.log.info( "All done" )
|
||
return False # To run at most once, and die
|
||
|
||
###############################
|
||
## End of AnyRailBuildSensorList.handle()
|
||
|
||
# Check the list of open windows AKA JMRIJFrame objects
|
||
# for known potential cross-thread contamination
|
||
#
|
||
# PanelPro is a multi-thread program, and Java Swing is
|
||
# not thread-safe. A duck-and-cover strategy is employed.
|
||
def AviodCrossThreadPossibilities(self) :
|
||
frameList = jmri.util.JmriJFrame.getFrameList()
|
||
|
||
for someFrame in frameList :
|
||
frameTitle = someFrame.getTitle()
|
||
if frameTitle in self.dangerousFrameTitleList :
|
||
# This someFrame window will be updated as the script
|
||
# creates and edits Sensors or else as the script
|
||
# edits Block attributes.
|
||
self.log.info ('Must minimize frame "{0}"'.format(frameTitle) )
|
||
someFrame.setVisible(False)
|
||
# keep the cookie crumbs for undo later
|
||
self.hiddenFrames.append(someFrame)
|
||
|
||
return
|
||
|
||
###############################
|
||
## End of AnyRailBuildSensorList.AviodCrossThreadPossibilities()
|
||
|
||
|
||
# PanelPro Blocks are always internal.
|
||
#
|
||
# The AnyRail exported XML file provides a one-to-one translation of
|
||
# the track plan list of "Sections" to PanelPro Blocks.
|
||
#
|
||
# AnyRail exported Blocks are sequentially identified with individual
|
||
# systemName choices as if some kind of "hardware" numerical
|
||
# identification were involved.
|
||
#
|
||
# The systemName list always starts with "IB1" and then "IB2", "IB3", ...
|
||
|
||
## At this time, a typical blockSystemName is of the form:
|
||
## "IB" + str(blockNumeralString),
|
||
## where blockNumeralString is a positive integer,
|
||
## starting with one.
|
||
## Expect one or more digits.
|
||
## Typically 3 or fewer, but script allows for up to 7.
|
||
|
||
# Isolate the important fragments of the exported Block userName
|
||
def parseBlockUserName(
|
||
self,
|
||
exportedBlockUserName # exported Block userName
|
||
) :
|
||
|
||
# Predefine local variables for scope protection
|
||
self.SensorSystemName = ""
|
||
self.SensorUserName = ""
|
||
self.SensorComment = ""
|
||
|
||
countSeparatorChars = exportedBlockUserName.count(fragmentSeparator)
|
||
# tempString = 'countSeparatorChars = {0}'.format(countSeparatorChars)
|
||
# self.log.debug(tempString)
|
||
# print(tempString)
|
||
|
||
if (countSeparatorChars < 2) :
|
||
# Not an AnyRail exported Block, too few fragmentSeparator characters
|
||
tempString = "Not an AnyRail exported Block"
|
||
# self.log.debug(tempString)
|
||
print(tempString)
|
||
return False
|
||
|
||
else :
|
||
# put parsed substring fragments into the list
|
||
fragmenteList = [] # the intended list of exported Block
|
||
# userName attributes
|
||
tempPartitonList = [] # a list of length 3 that is
|
||
# repeatedly the target of
|
||
# Python function named str.partition()
|
||
tempString = exportedBlockUserName
|
||
# iterate through the Block userName String
|
||
for n in range(countSeparatorChars + 1) :
|
||
tempPartitonList = tempString.partition(fragmentSeparator)
|
||
# of the three items in the returned list,
|
||
# only the first is important in this slice and dice
|
||
fragmenteList.append(str(tempPartitonList[0]))
|
||
# for j in range(3) : # range is defined by str.partition() results
|
||
# thing = ' {0} "{1}"'.format(j,tempPartitonList[j])
|
||
# print(thing)
|
||
if (tempPartitonList[2] == None) :
|
||
# only happens when the final fragmentSeparator has been discovered
|
||
# print "==== break out of loop"
|
||
break
|
||
|
||
# now examine what is still remaining of the
|
||
# original exportedBlockUserName string
|
||
tempString = tempPartitonList[2] # for next pass through loop
|
||
|
||
# print (fragmenteList) # debug only
|
||
|
||
# Check for AnyRail formated pattern
|
||
if (fragmenteList[0]=='B') :
|
||
# Prefix test OK
|
||
# 'B_nnn... where nnn represents a string of one
|
||
# or more numerals
|
||
# tempString = '1st test: AnyRail Prefix found'
|
||
# self.log.debug(tempString)
|
||
# print(tempString)
|
||
|
||
# The final fragment should match one of the Usage choices
|
||
if (fragmenteList[countSeparatorChars] in self.pickUsageList) :
|
||
# Postfix test OK
|
||
self.SensorComment = fragmenteList[countSeparatorChars]
|
||
# at least until something ugly is discovered
|
||
|
||
# AT THIS TIME: AnyRail exported Block userNames
|
||
# are formated "IB" + a numeric string.
|
||
# Since an Internal Block systemName does not require
|
||
# a hardware related choice, future versions of
|
||
# AniRail may not retain that formated pattern.
|
||
if (fragmenteList[1].isnumeric()) :
|
||
# Third test OK
|
||
tempAddress = int(fragmenteList[1])
|
||
# parsedSensorSystemName = \
|
||
self.SensorSystemName = \
|
||
defaultSensorPrefix + str(tempAddress)
|
||
# print 'Sensor systemName = "' + self.SensorSystemName + "'"
|
||
if (countSeparatorChars == 2) :
|
||
# AnyRail Section name is empty string
|
||
self.SensorUserName = ""
|
||
self.SensorComment = fragmenteList[2].strip()
|
||
elif (countSeparatorChars == 3) :
|
||
# Conventional String as the name for the Section
|
||
# but just for safety, trim off any leading
|
||
# trailing WhiteSpaces
|
||
self.SensorUserName = fragmenteList[2].strip()
|
||
else :
|
||
# Section name includes at least one fragmentSeparator
|
||
tempStart = len(fragmenteList[1]) + 3
|
||
tempSuffixLen = len(self.SensorComment) + 1
|
||
tempStop = len(exportedBlockUserName) - tempSuffixLen
|
||
# Finally the messy Section name is isolated
|
||
# but just for safety, trim off any leading
|
||
# trailing WhiteSpaces
|
||
self.SensorUserName = \
|
||
exportedBlockUserName[tempStart:tempStop].strip()
|
||
# tempString = 'Sensor userName = "' \
|
||
# + self.SensorUserName \
|
||
# + '"'
|
||
# self.log.debug(tempString)
|
||
# print(tempString)
|
||
# tempString = 'Sensor comment = "' \
|
||
# + self.SensorComment \
|
||
# + '"'
|
||
# self.log.debug(tempString)
|
||
# print(tempString)
|
||
else :
|
||
# Trailing Fragment is not an identified Usage choice
|
||
tempString = 'NOT an identified AnyRail Usage name'
|
||
# self.log.debug(tempString)
|
||
print(tempString)
|
||
return False
|
||
else :
|
||
# First character of exported Block userName is not "B"
|
||
tempString = 'NO leading "B" in Block userName'
|
||
# self.log.debug(tempString)
|
||
print(tempString)
|
||
return False
|
||
|
||
# self.log.debug('self.SensorUserName = "{0}"'.format(self.SensorUserName) )
|
||
# self.log.debug('parsedSensorSystemName = "{0}"'.format(parsedSensorSystemName) )
|
||
# self.log.debug('self.SensorUserName = "{0}"'.format(self.SensorUserName) )
|
||
# self.log.debug('parsedSensorComment = "{0}"'.format(parsedSensorComment) )
|
||
|
||
# All tests OK, ...
|
||
return True
|
||
|
||
###############################
|
||
## End of AnyRailBuildSensorList.parseBlockUserName()
|
||
|
||
# For the purpose of chasing down typos and other
|
||
# unpleasant details, in the original track plan data,
|
||
# provide the Block attributes before starting the parsing:
|
||
def ReportBlock(
|
||
self,
|
||
exportedBlock,
|
||
Counter
|
||
) :
|
||
|
||
# Get all important details for the selected Block:
|
||
|
||
tempString1 = 'Block # = "{0}", '.format(Counter)
|
||
|
||
# get the Block systemName from AnyRail Section
|
||
blockSystemName = exportedBlock.getSystemName()
|
||
tempString2 = 'systemName = "{0}", '.format(blockSystemName)
|
||
|
||
# get the userName for the AnyRail exported someBlock
|
||
blockUserName = exportedBlock.getUserName()
|
||
tempString3 = 'userName = "{0}", '.format(blockUserName)
|
||
|
||
# just to be cautious, get the comment field too
|
||
blockCommentField = exportedBlock.getComment()
|
||
tempString4 = 'comment = "{0}"'.format(blockCommentField)
|
||
|
||
# Provide the Block's identifying Attributes
|
||
tempString = tempString1 + tempString2 + tempString3 + tempString4
|
||
self.log.info(tempString)
|
||
print (tempString)
|
||
|
||
return blockUserName
|
||
|
||
###############################
|
||
## End of AnyRailBuildSensorList.ReportBlock()
|
||
|
||
# Provide the summary tallies
|
||
def SummariseTallies(
|
||
self,
|
||
NonAnyRailBlockCounter,
|
||
QuestionableSectionNameCounter,
|
||
DuplicateSectionNameCounter,
|
||
BlockCounter
|
||
):
|
||
print("")
|
||
print('--- Results ---')
|
||
print("")
|
||
if (NonAnyRailBlockCounter > 0) :
|
||
tempString = \
|
||
"A total of {0} Blocks are not recognized as exported from AnyRail" \
|
||
.format(NonAnyRailBlockCounter)
|
||
self.log.warn(tempString)
|
||
print (tempString)
|
||
if (QuestionableSectionNameCounter > 0) :
|
||
tempString = \
|
||
"A total of {0} Blocks have Questionable Section names" \
|
||
.format(QuestionableSectionNameCounter)
|
||
self.log.warn(tempString)
|
||
print (tempString)
|
||
if (DuplicateSectionNameCounter > 0) :
|
||
tempString = \
|
||
'A total of {0} duplicated AnyRail Section Names have been identified.' \
|
||
.format(DuplicateSectionNameCounter)
|
||
self.log.warn(tempString)
|
||
print (tempString)
|
||
tempString = \
|
||
"AnyRail exported Block Count = {0}" \
|
||
.format(BlockCounter)
|
||
self.log.info(tempString)
|
||
print (tempString)
|
||
return
|
||
|
||
###############################
|
||
## End of AnyRailBuildSensorList.SummariseTallies()
|
||
|
||
###############################
|
||
###############################
|
||
## End of AnyRailBuildSensorList class definition
|
||
|
||
# Launch the task
|
||
ABSL = AnyRailBuildSensorList( "AnyRail Sensors" )
|
||
ABSL.start()
|
||
|