06 Výhybka, snímač, návěstidlo…

Ukázky práce s nejčastěji používanými objekty ve skriptech.

Výhybky

Příklad práce s objektem typu výhybka. Výhybka může nabývat stavy s následujícími hodnotami:

UNKNOWN = 1

INCONSISTENT = 8

CLOSED = 2

THROWN = 4

Vzorový skript zjistí aktuální polohu výhybky a přestaví ji do opačné polohy.

# vyhybka_prehodit.py

import jmri

v1 = turnouts.provideTurnout("V1")

v2 = turnouts.provideTurnout("V2")

v3 = turnouts.provideTurnout("V3")

v4 = turnouts.provideTurnout("V4")

if (v2.getState() == CLOSED) :

    v2.setState(THROWN)

else :

    v2.setState(CLOSED)

Snímače

Příklad práce s objektem typu snímač. Snímač může nabývat stavy s následujícími hodnotami:

UNKNOWN = 1

INCONSISTENT = 8

ACTIVE = 2

INACTIVE = 4

Ukázkový skript otestuje u všech snímačů stav. Pokud jsou ve stavu Neznámý, tak je přestaví do stavu Neaktivní. Skript je dodán s aplikací jako vzorový http://jmri.org/jython/SetAllUnknownSensorsToInactive.py.

# Script to set all sensors with state UNKNOWN to INACTIVE

# This is particularly useful in simulator mode, when hardware sensors aren't updated

#

# Part of the JMRI distribution

import jmri

sCnt = 0

chgCnt = 0

# loop thru defined sensors, if UNKNOWN, set to INACTIVE

list = sensors.getNamedBeanSet()

for s in list :

    sCnt += 1

    cs = s.getKnownState()

    if cs == UNKNOWN :

      chgCnt += 1

      s.setKnownState(INACTIVE)

print str(sCnt) + " sensors found, " + str(chgCnt) + " changed to INACTIVE"

Paměťová proměnná

Příklad práce s objektem typu paměťová proměnná. Paměť může obsahovat libovolnou hodnotu. Doporučuji se omezit pouze na hodnoty typu celé číslo a textový řetězec. V našem příkladu použijeme dvě proměnné. Jedna bude typu celé číslo a druhá bude typu textový řetězec.

Práce s proměnnou typu číslo. Do paměťové proměnné můžeme zapisovat/číst hodnoty dvěma způsoby. Pomocí metod setValue()/getValue() může být argumentem libovolná hodnota. Při použití metod setState()/getState() může být argumentem pouze číslo. Vzorový skript:

# pametCislo.py

import jmri

promennaCislo = memories.provideMemory("promennaCislo")

print "původní hodnota getValue()  ".decode("UTF-8"), promennaCislo.getValue()

print "původní hodnota getState()  ".decode("UTF-8"), promennaCislo.getState()

promennaCislo.setValue("2")

print "nová hodnota setValue('2')  ".decode("UTF-8"), promennaCislo.getState()

promennaCislo.setState(3)

print "nová hodnota setState(3)    ".decode("UTF-8"), promennaCislo.getState()

promennaCislo.setValue("rst")

print "nová hodnota setValue('rst')".decode("UTF-8"), promennaCislo.getValue()

promennaCislo.setState("uvw")

print "nová hodnota setState('uvw')".decode("UTF-8"), promennaCislo.getValue()

Při spuštění vzorového skriptu bude výsledek následující:

původní hodnota getValue()   1

původní hodnota getState()   1

nová hodnota setValue('2')   2

nová hodnota setState(3)     3

nová hodnota setValue('rst') rst

Původní hodnota proměnné byla 1. Je jedno, zdali ji získáme metodou getState() nebo getValue(). Pokud nastavíme hodnotu poměnné pomocí setValue(“2”) bude uloženo číslo 2. Pokud nastavíme hodnotu poměnné pomocí setState(3) bude uloženo číslo 3. Pokud nastavíme hodnotu poměnné pomocí setValue(“rst”) dojde k přetypování proměnné a bude uložen řetězec rst. Na přetypování číselné proměnné si musíme dávat pozor. Pokud se pokusíme nastavit číselný typ pomocí metody setState(“uvw”) dojde k běhové chybě. Nová hodnota se neuloží a v Systémové konzoli se zobrazí chybové hlášení:

2019-07-27 08:59:38,906 jython.InputWindow                    ERROR - Error executing script [AWT-EventQueue-0]

javax.script.ScriptException: TypeError: setState(): 1st arg can't be coerced to int in <script> at line number 12

    at

    ...

Caused by: Traceback (most recent call last):

  File "<script>", line 12, in <module>

TypeError: setState(): 1st arg can't be coerced to int

    at

    ...

Práce s proměnnou typu text. Do paměťové proměnné můžeme zapisovat/číst hodnoty pouze jedním způsobem, a to pomocí metod setValue()/getValue(). Argumentem může být libovolný textový řetězec. Vzorový skript:

# pametText.py

import jmri

promennaText = memories.provideMemory("promennaText")

print "původní hodnota getValue()   ".decode("UTF-8"), promennaText.getValue()

promennaText.setValue("xyz")

print "nová hodnota setValue('xyz') ".decode("UTF-8"), promennaText.getValue()

print "pokus získat číslo getState()".decode("UTF-8"), promennaText.getState()

Při spuštění vzorového skriptu bude výsledek následující:

původní hodnota getValue()    abc

nová hodnota setValue('xyz')  xyz

pokus získat číslo getState() -1

Původní hodnota proměnné byla abc. Hodnotu jsme získali metodou getValue(). Metodou setValue(“xyz”) jsme nastavili novou hodnotu xyz. Při pokusu přečíst číslo metodou getState() získáme konstantu -1, která značí, že v proměnné není číslo. K žádné běhové chybě nedojde.

Návěstidlo

Příklad práce s objektem typu návěstidlo. V tabulce návěstidel si vytvoříme dvě návěstidla. Oddílové návěstidlo So a jeho předvěst PřSo.

Návěstidla budou používat návěstní systém ČSD 1962 základní návěstidla http://jmri.org/xml/signals/CSD-1962-zakladni/index.shtml. Jedno bude typu Oddílová návěstidla a druhé bude typu Předvěsti oddílové.

Ve skriptu návěstidla získáme metodou getSignalMast(). Argumentem je buď uživatelský nebo systémový název.

# navestidlo.py

import jmri

navestidlo_So = masts.getSignalMast("So")

navestidlo_PrSo = masts.getSignalMast("PřSo".decode("UTF-8"))

print navestidlo_So.getUserName(), navestidlo_So.getSystemName()

print navestidlo_PrSo.getUserName(), navestidlo_PrSo.getSystemName()

Výsledek skriptu je následující:

So LF$dsm:CSD-1962-zakladni:block(101)

PřSo LF$dsm:CSD-1962-zakladni:block_distant(102)

Kromě uživatelského a systémového názvu můžeme u návěstidla zjišťovat další vlastnosti. Například zjistíme jaký návěstní systém jsme návěstidlu přiřadili:

# navestidlo_2.py

import jmri

navestidlo_So = masts.getSignalMast("So")

system_navesti = navestidlo_So.getSignalSystem()

print system_navesti.getUserName()

print system_navesti.getSystemName()

Výsledek podle očekávání je:

ČSD 1962 základní návěstidla

CSD-1962-zakladni

U návěstního systému můžeme zjišťovat jaké všechny návěsti obsahuje:

# navestidlo_3.py

import jmri

navestidlo_So = masts.getSignalMast("So")

system_navesti = navestidlo_So.getSignalSystem()

vsechny_navesti = systemNavesti.getAspects()

for jedna_navest in vsechny_navesti :

    print jedna_navest

Výsledek opět nepřekvapí:

Stůj

Volno

Výstraha

Očekávej 40

Očekávej 60

Očekávej 80

Rychlost 40 a volno

Rychlost 40 a výstraha

Rychlost 40 a očekávej 40

Rychlost 40 a očekávej 60

Rychlost 40 a očekávej 80

Rychlost 60 a volno

Rychlost 60 a výstraha

Rychlost 60 a očekávej 40

Rychlost 60 a očekávej 60

Rychlost 60 a očekávej 80

Rychlost 80 a volno

Rychlost 80 a výstraha

Rychlost 80 a očekávej 40

Rychlost 80 a očekávej 60

Rychlost 80 a očekávej 80

Opakovaná volno

Opakovaná výstraha

Opakovaná očekávej 40

Opakovaná očekávej 60

Opakovaná očekávej 80

Zhasnuto

Posun zakázán

Posun dovolen

Posun dovolen - nezabezpečený

Opatrně na přivolávací návěst bez červené

Opatrně na přivolávací návěst

Podobně se můžeme zeptat návěstidla které návěsti může používat a které návěsti jsou u konkrétního návěstidla zakázané:

# navestidlo_4.py

import jmri

navestidlo_So = masts.getSignalMast("So")

mapa_navesti = navestidlo_So.getValidAspects()

for navest in mapa_navesti :

    print navest, navestidlo_So.isAspectDisabled(navest)

V našem případě jsou povolené pouze dvě návěsti a žádná z nich není zakázaná:

Stůj False

Volno False

U návěstidla můžeme přečíst aktuální návěst a libovolnou návěst nastavit:

# navestidlo_5.py

import jmri

navest_Stuj = "Stůj".decode("UTF-8")

navest_Volno = "Volno"

navest_Vystraha = "Výstraha".decode("UTF-8")

navestidlo_So = masts.getSignalMast("So")

navestidlo_PrSo = masts.getSignalMast("PřSo".decode("UTF-8"))

print navestidlo_So.getUserName(), navestidlo_So.getAspect()

print navestidlo_PrSo.getUserName(), navestidlo_PrSo.getAspect()

navestidlo_So.setAspect(navest_Stuj)

navestidlo_PrSo.setAspect(navest_Vystraha)

print navestidlo_So.getUserName(), navestidlo_So.getAspect()

print navestidlo_PrSo.getUserName(), navestidlo_PrSo.getAspect()

Výsledek je opět podle očekávání:

So None

PřSo None

So Stůj

PřSo Výstraha

Blok

Příklad práce s objektem typu blok. Blok je úsek koleje. Pokud je k bloku připojen snímač detekce obsazení, tak můžeme sledovat obsazenost daného bloku. Bloky jsou definovány v tabulce bloků.

Blok může nabývat stavy s následujícími hodnotami:

UNKNOWN = 1

INCONSISTENT = 8

OCCUPIED = 2

UNOCCUPIED = 4

UNDETECTED = 16

Vzorový skript zjistí aktuální stav bloku.

# blok.py

import jmri

blok_1 = blocks.getBlock("BK1")

blok_2 = blocks.getBlock("BK2")

blok_3 = blocks.getBlock("BK3")

blok_4 = blocks.getBlock("BK4")

print blok_1.getUserName(), blok_1.getSystemName(), blok_1.getState()

print blok_2.getUserName(), blok_2.getSystemName(), blok_2.getState()

print blok_3.getUserName(), blok_3.getSystemName(), blok_3.getState()

print blok_4.getUserName(), blok_4.getSystemName(), blok_4.getState()

Výsledek vypadá následovně:

BK1 IB1 4

BK2 IB:AUTO:0001 4

BK3 IB:AUTO:0002 4

BK4 IB:AUTO:0003 4

Layout blok

Příklad práce s objektem typu Layout blok. Layout blok je je blok, který je použit v Layout Editoru. Layout blok rozšiřuje vlastnosti bloku. Layout blok může nabývat stavy s následujícími hodnotami:

UNKNOWN = 1

OCCUPIED = 2

EMPTY = 4

RESERVED = 8

Vzorový skript zjistí aktuální stav bloku:

# layout_blok.py

import jmri

layout_bloky = layoutblocks.getNamedBeanSet()

for lb in layout_bloky :

    print lb.getUserName(), lb.getSystemName(), lb.getOccupancy(), lb.getUseExtraColor()

Výsledek může vypadat takto:

BK1 ILB1 2 False

BK2 ILB2 4 True

BK3 ILB3 4 True

BK4 ILB4 4 False

Layout blok BK1 je ve stavu 2, tedy je obsazený. Ostatní bloky jsou ve stavu 4, tedy volné. V Layout Editoru mohou být volné bloky ve dvou dalších stavech. Buď je blok neobsazený nebo může být blok v postavené vlakové cestě. Pokud je blok v postavené cestě, potom ze zobrazen na panelu v odlišné barvě.

Další objekty

Ve výše uvedeném návodu je popsán přístup k nejčastěji používaným objektům. Zástupci k dalším objektům jsou uvedeny v souboru jmri_bindings.py http://jmri.org/jython/jmri_bindings.py. Se znalostí programování a zdrojového kódu JMRI je pak možno přistupovat i k dalším objektům, které zde nebyly uvedeny.

vytvořeno 19. 9. 2019