Tak ... pohadka uterni noci o vyhybkach, JMRI a XpressNetu.
Takove vyhybka. Ma stavy nejen 'rovne' (closed) a 'odbocka' (thrown), ale i 'inconsistent', 'unknown' ... to je vyborny napad, protoze co s vyhybkou kdyz ji vydate prikaz, a ona jej jeste neposle do centraly, nebo centrala jej jeste neprijme. Super; tady by se mohl TC mozna ucit
i kdyz interne to ma mozna take. JMRI ale umi signalizovat i vyhybku v 'podivnem stavu', pouzivame-li feedback 2 senzory.
Navenek tedy vyhybka prechazi mezi stavy UNKNOWN -> CLOSED -> (pozadavek na prepnuti) -> INCONSISTENT -> (odezva z kolejiste nebo potvrzeni) -> THROWN. Logicke, prijemne na pouzivani.
Interne je to trochu slozitejsi. Zatimco pro skript (nebo kliknuti) v JMRI legrace konci vyvolanim
setCommandedState, klidne i nekolikrat za sebou sem-tam (to je uplne korektni !), interne se musi (protokol XPressNet)
- pozadavek poslat do centraly
- pockat si na potvrzeni
- poslat pozadavek na vypnuti vyhybky, idealne PRED jakymkoliv dalsim pozadavkem na prehozeni teto (ale klidne prednostne i pred jakymkoliv jinym prehozenim)
- pockat si na potvrzeni
I tady funguje 'stavovy automat': IDLE -> STATUSREQUESTSENT -> IDLE -> COMMANDSENT -> OFFSENT -> IDLE. Takze teoreticky to vypada dobre.
Posledni sekvence je dana specifikaci XPressNet-u a jeho USB / LAN rozhrani smerem k pocitaci. Pro pripad vyhybek by melo platit:
- Kód: Vybrat vše
1/ #CMD -> ACK | FEEDBACK;
2/ [FEEDBACK]* ;
3/ #OFF -> ACK
4/ [FEEDBACK]* ;
# oznacuje zpravu poslanou z PC, * pak zadne nebo vice opakovani. Je dulezite uvedomit si, ze po odeslani CMD nemuze prijit nic jineho nez:
a. potvrzeni,
b. feedback o zmene, ktery je nasledkem CMD
c. feedback k necemu uplne jinemu
d. chyba (ale ta muze prijit po kazde zprave)
mezi jednotlivymi sekvencemi pozadavek-potvrzeni pak muze libovolne prichazet feedback. Dulezite je, ze nenastava situace
CMD -> FEEDBACK + ACK
Podle specifikace XPressnet totiz, pokud je "odpovedi" na prikaz broadcast, USB/LAN rozhrani ACK poslat _nema_. Protoze pak muzeme pripad
CMD -> ACK + FEEDBACK (dela DR5000)
prevest na proste potvrzeni prikazu, a nasledna (nevyzadanou) odezvu oznamujici zmenu.
Ovsem
to predpoklada, ze se odpovedi musely vzdy spravne "naparuji" k prikazum.
takze praxe:
1/ Po vytvoreni vyhybka hned dotazuje svuj stav z kolejiste. Zajimave je, ze vyhybka zustane ve stavu STATUSREQUESTSENT ... az do prepnuti. V kodu to 'zrovna nevadi' (jsou zdvojene podminky); robustni to ale neni. Stejne tak zustane 'viset' pri explicitnim vyzadani stavu od centraly.
2/ kdyz prijde Feedback ve stavu COMMANDSENT, posle se vypnuti vystupu. Ovsem vypnuti se posle "za chvili" (30ms odlozi).
Ironii je, ze diky serii chybek v kodu se tech OFF prikazu vytvori vice; a zatimco ten prvni se odlozi (cituji) "aby nedoslo k prehlceni centraly", ty dalsi se poslou primo (v mem vypisu 1 odlozeny prikaz, 2 naprimo odvysilane). Vyborna prevence zahlceni centraly.
Druha zabavna vec je, ze tim 'odlozenim o 30ms' bez koordinace s dalsimi povely se muze stat, ze vyhybka nahodou prehozena tam-zpet ve skutecnosti posle do centraly tuto sekvenci:
- Kód: Vybrat vše
1. vystup 0 ON
2. vystup 1 ON
3. vystup 0 OFF (odlozeny)
4. vystup 1 OFF (odlozeny)
tzn. formalne budou v urcity okamzik OBA vystupy "on"; to je asi super zejmena pro elmag prestavniky ... tak snad to chyti dekoder spravne.
No a treti zabavna vec, coz vidim i na beznem vypise komunikace XpressNet monitor je, ze ten "high priority" OFF prikaz, se ve skutecnosti vysle, az kdyz neni ve fronte ZADNA "normal priority" zprava:
10:15:00.518: [packet:52 03 88 D9] Požadavek na provoz dekodér příslušenství: Adresa výhybky 13 (adresa základní 3, podadresa 0) přepnout výstup 0 Zap.
10:15:00.524: [42 03 25 64] Odpověď zpětného ohlasu: Výhybka se zpětným ohlasem Výhybka: 13 Stav: Výhybka vlevo; Výhybka: 14 Stav: Výhybka vlevo
10:15:00.543: [packet:52 04 8E D8] Požadavek na provoz dekodér příslušenství: Adresa výhybky 20 (adresa základní 4, podadresa 3) přepnout výstup 0 Zap.
10:15:00.567: [42 04 35 73] Odpověď zpětného ohlasu: Výhybka se zpětným ohlasem Výhybka: 19 Stav: Výhybka vlevo; Výhybka: 20 Stav: Výhybka vlevo
10:15:00.587: [packet:52 05 8A DD] Požadavek na provoz dekodér příslušenství: Adresa výhybky 22 (adresa základní 5, podadresa 1) přepnout výstup 0 Zap.
10:15:00.615: [42 05 25 62] Odpověď zpětného ohlasu: Výhybka se zpětným ohlasem Výhybka: 21 Stav: Výhybka vlevo; Výhybka: 22 Stav: Výhybka vlevo
10:15:00.643: [packet:52 05 8C DB] Požadavek na provoz dekodér příslušenství: Adresa výhybky 23 (adresa základní 5, podadresa 2) přepnout výstup 0 Zap.
10:15:00.663: [42 05 35 72] Odpověď zpětného ohlasu: Výhybka se zpětným ohlasem Výhybka: 23 Stav: Výhybka vlevo; Výhybka: 24 Stav: Výhybka vlevo
10:15:00.791: [packet:52 03 80 D1] Požadavek na provoz dekodér příslušenství: Adresa výhybky 13 (adresa základní 3, podadresa 0) přepnout výstup 0 Vyp.
10:15:00.824: [01 04 05] Příkaz úspěšně odeslán/Normální provoz obnoven po uplynutí časového limitu
Bohuzel kod tomu odpovida; fronta "vysoke priority" se zkouma az pri vyprazdneni bezne fronty odesilajiciho vlakna
Z vypisu je take videt, ze v case 10:15:00.524 prisla odpoved (a byla naplanovana OFF zprava, a diky chybam viz vyse vyslany primo dalsi bez zdrzeni), presto prvni OFF zprava odesla az 10:15:00.824, po nejakych 300ms - rozhodne po "normalni" zprave odeslane 10:15:00.643 (tzn. +119ms).
Tak ted je otazka, zda je (dokumentovany) zamer jeste aktualni, nebo ne, jenom nikdo nevyhodil 'stary' kod... K vlastnimu parovani zprav, ve kterem jsou chyby vedouci k timeoutu se dostanu asi v pristim dile pohadky o tom jak se pise spatny software.
P.S. Programatorsky povzdech. Vytvoreni vyhybky vyvola okamzite dotazovani po XPressNet sbernici na stav. Nejde vyhybka zkonstruovat, pak parametrizovat ... a pak 'aktivovat' se vsemi dusledky. Tim padem nejde udelat 'docasny objekt' k editaci v oknech atd ... No a samozrejme se na startu vygeneruje fura zprav a VYZADUJE se funkcni pripojeni ihned na startu aplikace, behem cteni konfiguraku; namisto, aby se kontrolovane "zapnulo" pripojeni k layoutu. To je pitomy napad, protoze jak vime konektory se pripojuji a odpojuji ... V konstruktoru se, proboha, vykonne akce prece neprovadeji...
P.P.S: ono to neni umanutost bazirovani na milisekundach a tak. Kdyz se skutecna implementace rozchazi s 'modelem v hlave' programatora (ne v MOJI hlave - viz pojmenovani v kodu, komentare), jedna se prakticky vzdy o chybu ktera se driv nebo pozdeji vymsti - protoze se s modelem pocita nekde jinde.
Kdyby nebylo onoho "odlozeni" (ktere stejne nefunguje), probehl by interni cyklus vyhybky commandsent - offsent - idle bez preruseni (s vyhradou, ze ten stav se ma zmenit az pri skutecnem vyslani zpravy). A prave tento stav zbytek kodu predpoklada, a proto v urcitych pripadech (dvojklik na tlacitko co aktivuje cestu) blbe funguje.