User Tools

Site Tools


User Command Station Library

ContentCommand StationsUser Libraries

A user CS library must connect to a MQTT broker to get commands, and to publish field events.
With this method, the CS library is completely independent of the Rocrail sources, and can also be used with other software.
The programming language of choice is also independent, as long as its possible to connect to a MQTT broker.


Extra Python Libraries

Install the extra Python library:

pip install paho-mqtt
pip install pyserial

In case of Linux or macOS the commands must be executed in super user context:

sudo pip install paho-mqtt
sudo pip install pyserial


This example tries to make a serial connection with the DCC++ Command Station, and tries to subscribe to the MQTT broker.

Save the script as

import time
import os
import serial
import xml.etree.ElementTree as ET
import paho.mqtt.client as paho
# Open a serial connection with the DCC++ command station: 
ser = serial.Serial(
if ser.isOpen():
  print "Serial connection established."
def sendDCCpp(msg):
  if ser.isOpen():
    rc = ser.write(msg);
    print "" + str(rc) + " bytes send to DCC++"
# Handle system commands/events: 
def onSys(node):
  if node.get('cmd') == "shutdown":
    print("SYSTEM SHUTDOWN... Clean up and exit...")
  if node.get('cmd') == "stop":
  if node.get('cmd') == "go":
# Handle output commands/events: 
def onOutput(node):
  print("set output " + node.get('addr') + ":" + node.get('port') + " to " + node.get('cmd') )
# Handle clock commands/events: 
def onClock(node):
  print(node.get('cmd') + " clock to " + node.get('hour') + ":" + node.get('minute') )
# MQTT callback function:
def on_message(client, userdata, message):
  #evaluate the Rocrail command
  print("broker message = " + str(message.payload.decode("utf-8")))
  node = ET.fromstring(str(message.payload.decode("utf-8")))
  if node.tag == "sys":
  if node.tag == "co":
  if node.tag == "clock":
broker="nasRR" #this is the IP of the computer on which the MQTT broker is installed.
# Create client object 
client= paho.Client("client-001")
# Bind function to callback
print "connecting to broker " + broker
# Start loop to process received MQTT messages
# Subscribe: 
topic = "rocrail/service/command"
print "subscribe to " + topic
# Evaluate and handle DCC++ messages:
def onDCCpp(serin):
  print "DCCpp: " + serin
  if serin == "<p0>":
    print "DCC++ reports power OFF"
    client.publish("rocrail/service/field","<state iid=\"python\" power=\"false\"/>")
  if serin == "<p1>":
    print "DCC++ reports power ON"
    client.publish("rocrail/service/field","<state iid=\"python\" power=\"true\"/>")
  #evaluate the field sensors and publish
  addr  = "4711"
  state = "true"
  client.publish("rocrail/service/field","<fb iid=\"python\" addr=\""+addr+"\" state=\""+state+"\"/>")
# Main loop for reading the serial connection: 
while ser.isOpen():
  serin = ""
  if ser.inWaiting() > 0:
    serin =
    if serin == '<':
      serchar = ''
      while serchar != '>':
        serchar =
        serin += serchar
  if serin != '':
  if ser.inWaiting() == 0:
# Clean up 

There are Python modules which can be used to parse the incoming XML Rocrail commands in RCP Format.
The commands are relative simple structured, and can also be parsed with standard text functions.
If the iid attribute is set in a command, it must be checked if the command should be processed by this user library.



Start the script with python

MBA2019:digint robversluis$ python
connecting to broker nasRR
subscribe to  rocrail/service/command
broker message = <sys cmd="shutdown" informall="true" val="0"/>

SYSTEM SHUTDOWN... Clean up and exit...
DCCpp: <iDCC++ BASE STATION FOR ARDUINO UNO / ARDUINO MOTOR SHIELD: V-1.2.1+ / Jun  6 2019 07:58:21>
broker message = <fbinfo cmd="fbmods">
  <fbmods bus="0" modules="0,1,2"/>

broker message = <boosterlist/>

broker message = <clock divider="1" hour="8" minute="39" wday="4" mday="6" month="6" year="2019" time="1559803151" temp="20" bri="255" cmd="set"/>

set clock to 8:39


20190421.104604.509 r9999I clocktic OClntCon 0606 mqtt publish to [rocrail/service/command]:[<clock divider="1" hour="10" minute="46"]

20190421.104828.200 r9999I mqttread OClntCon 0799 broker published [rocrail/service/field]:[<fb iid="python" addr="4711" state="true"/>]
20190421.104828.201 r9999a mqttread OModel   5124 trying to match sensor event: [python] 0:4711 uidname=[] state=1 code=
20190421.104828.201 r9999a mqttread OModel   5160 sensor key: 0_4711_python_
20190421.104828.201 r9999a mqttread OModel   5180 unregistered sensor event: [python] 0:4711 uidname=[]

Configuration of User Libraries

The configuration of user libraries is not supported by Rocrail and must be done externally. For example with a text .conf file.

digint/user-en.txt · Last modified: 2019/06/06 12:26 by rjversluis