Topics

Throttle Creation / Loconet Slot Management Debugging Pointers?

Heiko Rosemann
 

Hello everyone,

Somehow missed the transition to groups.io, but now I made it...

I'm looking for pointers in debugging how JMRI (with a PR3) acquires a
loconet slot for controlling locos. Things like the
"log4j.category.jmri.jmrit.withrottle=DEBUG" setting for wiThrottle
(which I just found by chance while I was trying to make sense of
several different network captures...) - so anything you can give me I'd
be happy to take.

Background: I've been using JMRI 4.12 and 4.14 with a self-made
wiThrottle hardware throttle (https://newheiko.github.io/wiFred/ or
https://newheiko.github.io/wiFred/documentation/html/docu.html#sec7 for
a few pictures) with a PR3 on a Loconet controlled by an Intellibox.
Basically my setup works (tried with up to five throttles controlling up
to ten locos, some of them in multi throttles), but I've seen several
issues:

1) After another loconet throttle (a Fredi) has controlled a loco and
been plugged out, JMRI can't control it any more (neither through
wiThrottle nor through a "normal" on-screen throttle) - can mostly be
fixed by power-cycling the Intellibox.
2) Sometimes the same issue happens even if the loco in question has
never been controlled by the Intellibox. Sometimes even power-cycling
does not help.
3) Sometimes some locos react very sluggishly to (speed) changes on the
throttle. One time I was able to watch the loconet slot monitor when
this happened and realized the slot status was IDLE instead of IN_USE -
the speed setting of the slot changed "instantly" so I believe the issue
is somewhere in setting the slot status (which probably leads the
Intellibox to delay speed changes as it prioritizes the IN_USE slots)

It's hard (for me) to debug these issues, especially since I don't own
an Intellibox myself but only have our modular meets (when running
trains takes priority over debugging funky new hardware...).

I will try with my DCS51, but have not yet been able to fully recreate
these issues, but I'd definitely like to create a "working" debug output
to have something to compare against. To be honest, just trying to
organize my thoughts in this post has already helped me somewhat in
determining my next debugging steps ;)

Thank you for any kind of help you can give me,

Heiko

P.S:

Side question: What is the meaning of

PFT1500613200<;>1.0
PFT1500613200<;>0.0

in the wiThrottle server response? I get it in both working and failed
connections, but couldn't find anything in the documentation - and I'm
not very good yet at reading the source.

JFYI, this is a trace of a failed connection (prefacing what I sent with
'> ' and removing newlines):

VN2.0
HU5ccf7f6c7c1f
RL0
RCL0
PFT1500613200<;>1.0
PFT1500613200<;>0.0
PW12080
NHeiko 4
*+
MT+0<;>L4213
MTA0<;>X
*10
RCL0

...and this is the beginning of a working connection (from a different
session!):

VN2.0
HU5ccf7f6c96fb
RL0
RCL0
PFT1500613200<;>1.0
PFT1500613200<;>0.0
PW12080
NHeiko 5
*+
MT+0<;>L4244
MTA0<;>X
*10
MT+0<;>
MTA0<;>F00
MTA0<;>F11
MTA0<;>F02
MTA0<;>F13
MTA0<;>F04
MTA0<;>F05
MTA0<;>F06
MTA0<;>F07
MTA0<;>F18
MTA0<;>F19
MTA0<;>F010
MTA0<;>F011
MTA0<;>F112
MTA0<;>F013
MTA0<;>F014
MTA0<;>F015
MTA0<;>F016
MTA0<;>F017
MTA0<;>F018
MTA0<;>F019
MTA0<;>F020
MTA0<;>F021
MTA0<;>F022
MTA0<;>F023
MTA0<;>F024
MTA0<;>F025
MTA0<;>F026
MTA0<;>F027
MTA0<;>F028
MTA0<;>V-126
MTA0<;>R1
MTA0<;>s1

As you can probably tell, I'm not using any roster definition but just
trying to acquire and control locos through their DCC address.

I can't find any meaningful entries in the session.log or on the console
but then again I probably don't have the right debug settings, so I'm
back to my original question :)

--
eMails verschlüsseln mit PGP - privacy is your right!
Mein PGP-Key zur Verifizierung: http://pgp.mit.edu

david zuhn
 

PFT1500613200<;>1.0
PFT1500613200<;>0.0

Fast Time updates.   The First number is seconds since the epoch of the current fast time, and the second number is the current fast time rate.  0 means the clock is stopped.  The rate is optional.  

The LnWi will report the current time all within the first day of the epoch, so only the hours and minutes portion of the resulting date are meaningful.   JMRI WiThrottle server will update with the fast time but with times starting at the moment of the fast clock being set/reset, so conceivably you can represent fast time including dates since 1970.

JMRI sends out an update of this value every time the rate changes, and every 5 minutes (real time).  If the user changes the time on the JMRI clock but doesn't change the rate, no update message is sent except on that regular 5 minute schedule.

 
couldn't find anything in the documentation - and I'm not very good yet at reading the source.

Did you find the protocol documentation page?   http://jmri.org/help/en/package/jmri/jmrit/withrottle/Protocol.shtml

It's not complete, but what's there is more-or-less accurate.   More so for JMRI and less so (I'm finding) for communicating with the LnWi.   

And reading the source doesn't always help understand the intention.   :)
 
david zuhn

-- 
The State Belt Railway of California
zoo @ statebeltrailway.org

Heiko Rosemann
 

On 1/9/19 5:45 PM, david zuhn wrote:
PFT1500613200<;>1.0
PFT1500613200<;>0.0


Fast Time updates.   The First number is seconds since the epoch of the
current fast time, and the second number is the current fast time rate. 
0 means the clock is stopped.  The rate is optional.  
Thanks David - so it's something I can safely ignore for the time being :)

couldn't find anything in the documentation - and I'm not very good
yet at reading the source.


Did you find the protocol documentation page? 
 http://jmri.org/help/en/package/jmri/jmrit/withrottle/Protocol.shtml

It's not complete, but what's there is more-or-less accurate.   More so
for JMRI and less so (I'm finding) for communicating with the LnWi.   
Yes, I did, although I must have over-read the change in the key
requirement...

And reading the source doesn't always help understand the intention.   :)
...but I also managed to track down the change that made my controllers
fail:
https://github.com/JMRI/JMRI/commit/3b2546c82d4d4bdf4d2fcc2b25e9c70dbe0a1f40
adds a call to isValidAddr for the key part of the MultiThrottle
commands. Before, using MT+0<;>L1234 would work to acquire loco 1234,
after this change it has to be MT+Sdd<;>L1234 or MT+Ldddd<;>L1234.

Also, the loconet "automatic steal" seems to work much, much better now.
Will test on an Intellibox where I had problems earlier probably in a
few weeks, but with my Zephyr it seems to just work. Connect a Fredi
controller, run the loco, disconnect, activate wiThrottle controller,
run the loco.

Good night from Germany,
Heiko

P.S: Only thing puzzling me: Why didn't this work after downgrading back
to 4.12? Maybe I messed that up somehow...

--
eMails verschlüsseln mit PGP - privacy is your right!
Mein PGP-Key zur Verifizierung: http://pgp.mit.edu

david zuhn
 

> And reading the source doesn't always help understand the intention.   :)

...but I also managed to track down the change that made my controllers
fail:
https://github.com/JMRI/JMRI/commit/3b2546c82d4d4bdf4d2fcc2b25e9c70dbe0a1f40
adds a call to isValidAddr for the key part of the MultiThrottle
commands. Before, using MT+0<;>L1234 would work to acquire loco 1234,
after this change it has to be MT+Sdd<;>L1234 or MT+Ldddd<;>L1234.

Yeah, this just bit me too.  I don't understand why this key needs to conform to a loco address format when it's not the loco address.  

P.S: Only thing puzzling me: Why didn't this work after downgrading back
to 4.12? Maybe I messed that up somehow...

I don't claim to understand this protocol, nor the implementations.   I'm just in the same boat as you, trying to write code that uses this protocol.

david

 
--
The State Belt Railway of California
zoo @ statebeltrailway.org

Steve Todd
 

David and Heiko,
My goal with that change was to eliminate the silent failure when an invalid address were passed. I did not catch the distinction that the second part overrode the "key" (first part), which then allowed the key to be an arbitrary string. EngineDriver always enforced the relationship between the two. I will investigate checking the second part if it exists, to restore the previous behavior.
I would like to understand the advantage of creating another key value?
It would also be helpful if people would try out the test versions. This change was made several months before 4.14 was published.
Regards,
  SteveT

Heiko Rosemann
 

Steve,

thanks for the feedback :)

On 1/15/19 10:38 PM, Steve Todd wrote:
David and Heiko,
My goal with that change was to eliminate the silent failure when an
invalid address were passed. I did not catch the distinction that the
second part overrode the "key" (first part), which then allowed the key
to be an arbitrary string.
But also the second part does not have to be an address, it can also be
a roster entry (if I understand the documentation correctly, I always
just use addresses). I guess that makes validation is pretty hard, plus
there can be (more or less silent?) failures even when the address is
valid, but cannot be acquired (e.g. in use already)? Not sure about
that, will try to find more time (and hardware, my Zephyr seems pretty
forgiving) for debugging.

I would like to understand the advantage of creating another key value?
The throttle I am buildig* has four loco activation slide switches (and
no display or anything). So my code (for the ESP8266 wifi chip) is much
easier if I simply index the switches and the "MT keys" 0...3 and also
reuse those numbers as indizes to an array of loco information. Constant
length strings also make parsing the JMRI responses for function status
and direction so much easier, and when I turn off "switch 3" it's a
simple "MT-3<;>r" command, no need to match "switch number" to "MT key".

The code was something like (skipping the long/short decision):
for(int switch = 0; switch < 4; switch++)
{
if(wasToggled(switch))
{
if(isActive(switch))
{
client.print(String("MT+") + switch + "<;>L" + \
locos[switch].address + "\n");
}
else
{
client.print(String("MT-") + switch + "<;>r\n");
}
}
}

...so it seemed natural to use constant "MT keys" as simple as possible
for each loco activation switch, also getting around the problem of
maybe someone changing the configuration of the device (particularly the
loco[switch].address) while a loco is active, and parsing
response.substring(7) to get the function number and response.charAt(6)
to get the function status (don't pin me down on the offsets).

Now I'm simply using S1...S4 as "MT keys", which is only slightly more
complicated and passes the "isValidAddress" test. I do hope these "MT
keys" don't need to be unique throughout the wiThrottle server, but
haven't checked that yet...

It would also be helpful if people would try out the test versions. This
change was made several months before 4.14 was published.
Yes, my bad for not testing the test versions (or at least following the
github commits to those files interesting to me).

Didn't find much time after June 2018 for any testing... so yes,
updating just before the meet was stupid ;)

Best Regards and thanks for all your hard work,
Heiko

*see https://newHeiko.github.io/wiFred/ for the first prototypes
--
eMails verschlüsseln mit PGP - privacy is your right!
Mein PGP-Key zur Verifizierung: http://pgp.mit.edu

bhoffman351
 


On Jan 15, 2019, at 4:38 PM, Steve Todd <mstevetodd@...> wrote:

I would like to understand the advantage of creating another key value?

I am also curious about this, WiThrottle app also only uses the address as a key.  It seems that an arbitrary key would prevent universal consisting and potentially cause cross-contamination of commands. (Not necessarily on JMRI, but possibly on Wi-Fi modules.)

Regards,
Brett

david zuhn
 

My goal with that change was to eliminate the silent failure when an invalid address were passed. I did not catch the distinction that the second part overrode the "key" (first part), which then allowed the key to be an arbitrary string. EngineDriver always enforced the relationship between the two. I will investigate checking the second part if it exists, to restore the previous behavior.
I would like to understand the advantage of creating another key value?

My concern is that we're not "creating another key value", but that we've already got it.   The M command to assign a throttle is M /key/ + /another key/ <;> /address to select/.  

As I understand it, the first key seems to be to distinguish between multiple throttles on the same device.   The second is to distinguish between multiple locomotives to be controlled by a single throttle (aka, throttle assisted consisting).   Finally, there are three ways to select an address (Snn, Lnnnn, and E<text>).   

Given that the first key is arbitrary, it made sense by the previous documentation that the second key could also be arbitrary.   And it was, in JMRI, until somewhere in the 4.13 cycle, when it became required to be in address form.

Documentation for this is sketchy, and in trying things out on two different implementations, I get two different results.

MB+S98<;>S97 on the LNWI selects address 98.   I don't know what (if anything) it does with the S97 portion of that command

MC+S97<;>S96 on JMRI (4.14) selects and modifies address 96. 

My concern is that we have several things that look like addresses, but aren't always addresses.   

As Brett wrote:  

    I am also curious about this, WiThrottle app also only uses the address as a key.  It seems that an arbitrary key would prevent universal consisting and potentially cause cross-contamination of commands. (Not necessarily on JMRI, but possibly on Wi-Fi modules.)

Well, that helps narrow down the client side expectations.   But the server sides don't match.    It looks to me like we need to document the need for these to match.   Since LNWI doesn't have a roster, there isn't the chance there for a lookup via 'E<roster entry>' to mismatch against the address used as the key.    



Changes made to the interpretation of the WiThrottle protocol ought to be made in light of the fact that it's a protocol (and documented as such) and not an implementation.   Other implementations can exist beyond Engine Driver and JMRI (viz LnWI and MRC 1530, which I've not yet worked with directly).   Heiko is working on a throttle.   I'm working on a throttle.   I've talked with of people discussing adding code to support this to the Arduino DCC++.   It's bits on a wire, and we need to make clear what those bits mean, so that we can all interoperate.   

I'm working on adding to the documentation as I discover things (more PR's coming, especially for the "P" panel commands).   I've got the Engine Driver and JMRI code to look at, but that doesn't help me for the LNWI implementation or for WiThrottle itself.   


 
 
It would also be helpful if people would try out the test versions. This change was made several months before 4.14 was published.

I have been working with a few test versions.  However, I'm also in the middle of making changes to my own throttle implementation.   Working with two variables can make things that much harder to diagnose.   It's actually been easier as I started working with the LNWI too, since that's less variable at this time.   

david


--
The State Belt Railway of California
zoo @ statebeltrailway.org

david zuhn
 

The throttle I am buildig* has four loco activation slide switches (and
no display or anything). So my code (for the ESP8266 wifi chip) is much
easier if I simply index the switches and the "MT keys" 0...3 and also
reuse those numbers as indizes to an array of loco information.

Do you intend to allow consisting between the 4 possible addresses, so if you enable slide switches 2 and 3 you get ONE throttle with two addresses?

Or are you working as if it were a rotary, where only one of the 4 can be active at a time?

If it's the latter, I think you might be better served by treating these as 4 throttles (e.g., MA, MB, MC, MD) each with their own selected address and direction etc.

If you want to consist, then working as you are makes sense to me.   


What are you doing to map addresses to the slide switches?



--
The State Belt Railway of California
zoo @ statebeltrailway.org

Heiko Rosemann
 

On 1/16/19 2:31 AM, david zuhn wrote:
The throttle I am buildig* has four loco activation slide switches (and
no display or anything). So my code (for the ESP8266 wifi chip) is much
easier if I simply index the switches and the "MT keys" 0...3 and also
reuse those numbers as indizes to an array of loco information.


Do you intend to allow consisting between the 4 possible addresses, so
if you enable slide switches 2 and 3 you get ONE throttle with two
addresses?
That. It's one of the advantages of the throttle: Run a train with
helpers, uncouple the helpers from the train somewhere and stop them to
be picked up by another train. Run a local with "sandwich power" to
switch both trailing and facing sidings. Run a manifest train with
distributed power but still be able to switch out blocks of cars.

What are you doing to map addresses to the slide switches?
For the user: The throttle is running a web server to configure that
(among other stuff like the WiFi SSID and PSK). The approach my club
uses is basically one throttle per consist, so this configuration is
done once per meet at max.

Programmatically, I have an array[4] of locoInfo:
typedef struct
{
int16_t address;
bool longAddress;
functionInfo functions[MAX_FUNCTION + 1];
bool reverse;
} locoInfo;

Thanks for the hints on the LNWI, seems like I can't get away with my
simple approach if the LNWI uses the "MT key" to get the DCC address.
Never had my hands on one, oh well...

Heiko

--
eMails verschlüsseln mit PGP - privacy is your right!
Mein PGP-Key zur Verifizierung: http://pgp.mit.edu

Steve Todd
 

On Tue, Jan 15, 2019 at 02:26 PM, Heiko Rosemann wrote:
when I turn off "switch 3" it's a simple "MT-3<;>r" command, no need to match "switch number" to "MT key".
Heiko, perhaps your code could modify the "multithrottle instance key", which is the "T" in the examples. That is always a single char, and can be numeric. You can also use the "*" wildcard key for the 1st address (for all except the add) So dropping the loco from throttle 3 would be "M3*<;>r"

Heiko Rosemann
 

On 1/16/19 8:43 PM, Steve Todd wrote:
On Tue, Jan 15, 2019 at 02:26 PM, Heiko Rosemann wrote:

when I turn off "switch 3" it's a simple "MT-3<;>r" command, no need
to match "switch number" to "MT key".

Heiko, perhaps your code could modify the "multithrottle instance key",
which is the "T" in the examples. That is always a single char, and can
be numeric. You can also use the "*" wildcard key for the 1st address
(for all except the add) So dropping the loco from throttle 3 would be
"M3*<;>r"
Thanks Steve, for thinking along, but no, then I would need to send
speed (and ESTOP) commands separately to every multithrottle instance -
I am running all four locos together in a consist (or at least keeping
that option open).

I guess with the Info from David about the LNWI, I will re-write those
code sections to actually use the correct address. It's not that that's
overly difficult or complex, just more so than what I did so far ;)

Heiko

--
eMails verschlüsseln mit PGP - privacy is your right!
Mein PGP-Key zur Verifizierung: http://pgp.mit.edu