93 lines
3.3 KiB
Python
93 lines
3.3 KiB
Python
# Listen to all sensors, printing an info line when they change state.
|
|
# If the sensor has a "matching" block, print some block detail and speak
|
|
# the most useful attributes audibly.
|
|
# This is useful for validating occupancy and block setup and wiring
|
|
#
|
|
# Author: mstevetodd, copyright 2013
|
|
# based on SensorLog.py and BlockLister.py
|
|
# Part of the JMRI distribution
|
|
|
|
import java
|
|
import java.beans
|
|
import jmri
|
|
|
|
# Define routine to map status numbers to text
|
|
def stateName(state) :
|
|
if (state == ACTIVE) :
|
|
return "ACTIVE"
|
|
if (state == INACTIVE) :
|
|
return "INACTIVE"
|
|
if (state == INCONSISTENT) :
|
|
return "INCONSISTENT"
|
|
if (state == UNKNOWN) :
|
|
return "UNKNOWN"
|
|
return "(invalid)"
|
|
|
|
# convert block state to english
|
|
def cvtBlockStateToText(state) :
|
|
rep = ""
|
|
if (state == jmri.Block.OCCUPIED) :
|
|
rep = rep + "Occupied "
|
|
if (state == jmri.Block.UNOCCUPIED) :
|
|
rep = rep + "Unoccupied "
|
|
return rep
|
|
|
|
# use external "nircmd" command to "speak" some text (I prefer this voice to eSpeak)
|
|
def speak(msg) :
|
|
#uncomment next line for speech (Jenkins doesn't like this command)
|
|
#java.lang.Runtime.getRuntime().exec('C:\\Progra~2\\nircmd\\nircmd speak text "' + msg +'"')
|
|
return
|
|
|
|
# Define the sensor listener:
|
|
# Print details on all sensor changes, and speak key blocks
|
|
# items if sensor is a block occupancy sensor
|
|
class SensorListener(java.beans.PropertyChangeListener):
|
|
def propertyChange(self, event):
|
|
if (event.propertyName == "KnownState") :
|
|
sensor_num = event.source.systemName[2:]
|
|
mesg = "Sensor "+event.source.systemName
|
|
if (event.source.userName != None) :
|
|
mesg += " ("+event.source.userName+")"
|
|
mesg += " from "+stateName(event.oldValue)
|
|
mesg += " to "+stateName(event.newValue)
|
|
|
|
#look for block based on our naming convention, and speak some info if found
|
|
block_name = "ILB" + sensor_num
|
|
b = blocks.getByUserName(block_name)
|
|
if (b != None) :
|
|
block_length = str(round(b.getLengthIn())).rstrip('0').rstrip('.') + " inches "
|
|
mesg += " for block " + block_name + ", " + block_length
|
|
#only speak for occupied blocks (cuts down on noise level)
|
|
if (b.getState() == jmri.Block.OCCUPIED) :
|
|
spoken_mesg = b.userName + " "
|
|
#spoken_mesg += cvtBlockStateToText(b.getState()) + ", "
|
|
spoken_mesg += block_length
|
|
speak(spoken_mesg)
|
|
print mesg
|
|
return
|
|
|
|
listener = SensorListener()
|
|
|
|
# Define a Manager listener. When invoked, a new
|
|
# item has been added, so go through the list of items removing the
|
|
# old listener and adding a new one (works for both already registered
|
|
# and new sensors)
|
|
class ManagerListener(java.beans.PropertyChangeListener):
|
|
def propertyChange(self, event):
|
|
list = event.source.getNamedBeanSet()
|
|
for sensor in list :
|
|
sensor.removePropertyChangeListener(listener)
|
|
sensor.addPropertyChangeListener(listener)
|
|
|
|
# Attach the sensor manager listener
|
|
sensors.addPropertyChangeListener(ManagerListener())
|
|
|
|
# For the sensors that exist, attach a sensor listener
|
|
list = sensors.getNamedBeanSet()
|
|
for i in list :
|
|
sensor.addPropertyChangeListener(listener)
|
|
|
|
speak("block occupancy announcer started")
|
|
|
|
|