In the lines below, DC1 and DC2 characters separating fields have been omitted for legibility.
On connecting, my program sends these commands:
{NAME}Betreibswerk
{VER}3.7.32
{CH?}
The RemoteSign responds with its name etc...
{NAME}RemoteSign
{VER}2.7.13
{ASPECT}625
{READY}
My program sets up the RemoteSign with 26 rows, analog clock and syncs the time, etc.
{ROWS} 26
{CLEAR}H
{STUCK}0
{CLOCK}F
{CLOCK}A 5
{SOUND}1
{TIME}20:40:43
It then sends the screen layout. In this example, the RemoteSign is in fact handling two separate stations.
- For each station it displays the name of the station, and column headings
- For each track it displays the track number, and if a train is present, the train name
- In this example, in the first station (Wilsnack Hbf.), one train is present (SZ Wür) and does not yet have any destination so it displays "NICHT EINSTEIGEN" (= Do not board)
- In the second station (Wilsnack Tief) there are trains in both tracks, both also without destinations.
{TEXT} 1 Wilsnack Hbf. 5 1 20 L 65535 0 200
{TEXT} 2 Gl 6 1 3 L 12632256 0 75
{TEXT} 3 Zug 6 4 8 L 12632256 0 75
{TEXT} 4 Von/Nach 6 13 20 L 12632256 0 75
{ROW} 7 01 22833333333833333333333333333333811822422 0 0
{ROW} 7 01 SZ Wür NICHT EINSTEIGEN 22833333333833333333333333333333811822422 1
{ROW} 8 02 22833333333833333333333333333333811822422 0 0
{ROW} 8 02 22833333333833333333333333333333811822422 1
{ROW} 9 03 22833333333833333333333333333333811822422 0 0
{ROW} 9 03 22833333333833333333333333333333811822422 1
{ROW} 10 04 22833333333833333333333333333333811822422 0 0
{ROW} 10 04 22833333333833333333333333333333811822422 1
{ROW} 11 05 22833333333833333333333333333333811822422 0 0
{ROW} 11 05 22833333333833333333333333333333811822422 1
{ROW} 12 0 1
{TEXT} 5 Wilsnack Tief 13 1 20 L 65535 0 200
{TEXT} 6 Gl 14 1 3 L 12632256 0 75
{TEXT} 7 Zug 14 4 8 L 12632256 0 75
{TEXT} 8 Von/Nach 14 13 20 L 12632256 0 75
{ROW} 15 01 22833333333833333333333333333333811822422 0 0
{ROW} 15 01 S1 NICHT EINSTEIGEN 22833333333833333333333333333333811822422 1
{ROW} 16 02 22833333333833333333333333333333811822422 0 0
{ROW} 16 02 S3 NICHT EINSTEIGEN 22833333333833333333333333333333811822422 1
{ROW} 17 0 1
{ROW} 18 0 1
{ROW} 19 0 1
{ROW} 20 0 1
{ROW} 21 0 1
{ROW} 22 0 1
{ROW} 23 0 1
{ROW} 24 0 1
{ROW} 25 0 1
{ROW} 26 0 1
The RemoteSign responds with the channel data requested earlier, stating that it is a Regular RemoteSign on Ch 1, and Ch 2 has 10 sensors. (A sign will always be channel 1 so you can probably ignore this data initially. People may find the sensor data very useful though for triggering all sorts of stuff very cheaply, but I suggest handling that later!)
{CH}1 R 40 48 RemoteSign 2.7.13
{CH}2 S 10
Now, a train gets scheduled to arrive in track 2 of the main station. My program sends one line:
The train name is "ICE 1355", and it is coming from Göppingen, arriving at 20:48
{ROW} 8 02 ICE 1355 Göppingen An 20:48 22833333333833333333333333333333811822422 1
After it has arrived, and it is scheduled to depart, its destination is displayed:
{ROW} 8 02 ICE 1355 Köln Hbf. Ab 20:54 22833333333833333333333333333333811822422 1
Once it has left, the row is cleared:
{ROW} 8 02 22833333333833333333333333333333811822422 1
Here is an example of a RemoteSign that is dedicated as a platform sign (Typically a small ESP8266 sign in the actual station)
In this example it is a platform sign for the same track as above, so you can see corresponding details:
This time, it sets up the screen with just 4 rows, and a digital clock:
{ROWS} 4
{CLEAR}H
{STUCK}0
{CLOCK}F
{CLOCK}D
{SOUND}1
{TIME}20:45:38
When the train "ICE 1355" is scheduled, it sends these commands
{CLEAR}
{ROWS}4
{CLOCK}D
It defines the platform number as 2 on reverse video, 200% size
{TEXT}1 2 2 1 5 C 0 16711680 200
Ensures no scrolling text is active
{SCROLL}0
Displays the arrival time
{TEXT}2 20:48 1 7 5 L 16777215 0 100
Displays the train name
{TEXT}3 ICE 1355 2 7 9 L 16777215 0 100
Displays "from" in German in small text
{TEXT}4 von 2 18 3 L 16777215 0 50
Displays the origin city, centered
{TEXT}5 Göppingen 4 1 25 C 16777215 0 100
If no train is present, (say it just departed), it clears the screen, keeps the platform number in place, and displays an advert in scrolling text:
(The scrolling text is placed on row 3 or 4 randomly)
{CLEAR}
{ROWS}4
{CLOCK}D
{TEXT}1 2 2 1 5 C 0 16711680 200
{SCROLL} 3 City-Ticket: Nahverkehr inklusive - jetzt bei Sparpreis und Flexpreis im Fernverkehr.
When my program decides to disconnect from a RemoteSign it sends:
{BYE}
Platform states
The states I handle for a track in my layout software are:- no train present
- train scheduled to arrive from some origin
- train present and scheduled to depart to some destination
- train present but not scheduled to go anywhere (route cancelled, or none yet set)
- train schedule to pass through
Other states may be more appropriate for your software.
General notes
- I maintain an array of RemoteSigns, sending different commands to each sign as needed. (I initially coded for just one, but found one can have a bunch of them!)
- For animated rows (with the flap boards) use the mask data to tune the characters that get flipped through, or blank columns.
- Monitor the events for connections and disconnections so that when a sign connects, you can set up its screen for its intended purpose once. (rows, clock type, etc)
- I also send a {PING} command periodically in case a RemoteSign disconnected in such a manner that I never got a disconnect event. If it has disconnected, this typically generates an error event that I can use to clean up the disconnection.
- For RemoteSigns that have been set up, but are not connected, I periodically (60s) try to connect. Sometimes the machine running the RemoteSign has not been powered up.
- For each RemoteSign, I allow the user to define the IP/host name, a name for that RemoteSign (used in logging, and displaying {MSG} or {ERROR} content), pick lists etc., how many rows to use, the type of clock, (digital/analog/none) and if analog, the clock colors, etc.
- When adding a new RemoteSign, I also offer a way to locate them on the network, by sending connection request on port 50601 to all the IP addresses on the LAN, when RemoteSigns respond, I put their IP address (and host name) into a list in the UI for the user to pick. (Initially I just provided a place to enter the IP address or hostname!)
Data Structures
Typical data structure in (Visual Basic syntax) I use for each RemoteSign:Name As String
IPaddress As String
Port As Long ' TCPIP port number
ScreenRows As Byte ' current number of rows in the RemoteSign
Clock As ClockSettingsType
Sensors() As Integer ' index 0 = count. Sensors available via this RemoteSign
' data from other end
HostAppName As String
HostVersion As String
' these fields will be populated with data {CH} the remote device
CH() As RemoteSignChannelType
LastError As String ' last winsock error
Dirty As Boolean ' true if this RemoteSign has been edited in the UI and needs to be saved
Typical structure of clock settings:
Analog As Boolean ' analog or digital?
H24 As Boolean ' 24 hour or not
FaceColor As Long
HandColor As Long
TickColor As Long
SecondHandColor As Long
SecondHand As Boolean ' show second hand or not
Size As Integer ' screen rows
Speed As Byte ' fast speed. zero or 1 = real time. 2 = 2x etc.
StartTime As Date ' a time value to force into the clock
Hopefully your software provides the events and hooks needed to know when to update the status of a track in a station.