JMRI Web Access
Basic Use
JMRI supports working with your layout from a web browser.
Services
Details of the JMRI web services.
Applications
By the community of JMRI.org:

JMRI Help:

Contents Index
Glossary FAQ

Donate to JMRI.org

JMRI JSON Servlet

The JMRI JSON Servlet provides a RESTful API and a WebSocket API for accessing and editing user defined objects in JMRI. This document describes how to enable the JMRI JSON servlet and provides some examples of use.

Note the JMRI JSON protocol is documented in JMRI API Documentation.

JMRI JSON Servlet

An overview of how Web Server operates using JSON between JMRI and the web browser, using web.servlet.panel as an example, can be found on PanelServlet Help page.

Setting up the JSON Servlet

The JMRI JSON Servlet is a feature that is part of the Web Server. To use this service:

  1. Ensure the web server's port is unique:
    • Open the Preferences dialog
    • Click Web Server on the left side
    • Ensure the port number is unique (for example 12080). Other ports are used by WiThrottle, JSON Server, etc.
    • Click Save
  2. Click Actions and Start Web Server to ensure the web server is running (Tools ⇒ Servers ⇒ Start JRMI Web Server in PanelPro).
  3. If you want the Web Server to run each time you start JMRI:
    • Open the JMRI Preferences dialog
    • Select Start Up in the left column
    • Click Add ▾
    • Select Perform action...
    • Select Start Web Server
    • Click OK

Paths

The servlet responds to the following paths:

/json
Depending on protocol:
HTTP
Open a JSON WebSocket console that allows experimentation with JSON sockets.
WS
Open a JSON WebSocket.
/json/type
Using the HTTP protocol:
GET
request a list of objects of type
PUT
add an object of type
A JSON array of valid types for your JMRI installation is available by using the type " type " (with JMRI Web Server running). You can also see the list using the Tables menu on the JMRI Web Server Home page. " /tables/type " See the protocol documentation for more details.
/json/type/name
Using the HTTP protocol:
GET
request the object of type with name name
POST
modify the object of type with name name
DELETE
remove the object of type with name name

JMRI JSON Server

The JMRI JSON server is functionally identical to the JSON WebSocket interface, but running over a standard network socket.

jquery.jmri.js

jquery.jmri.js is a jQuery library that ships with JMRI and makes the JSON protocol support "just work" on most current browsers.

Examples of use of the jquery.jmri.js JavaScript library that ships with JMRI include:

Operations Conductor
source /js/operations.js
Panel
source /js/panel.js
JSON Console
source /js/json-console.js

Note: The source code for the above is found in the web/ts directory, which contains the JavaScript and Typescript source code. This is compiled to the web/js directory for actual execution.

Power Demonstration (with JMRI Web Server running).
source /web/power.html

WebSocket Examples

The WebSocket feature of the servlet can be seen by browsing to the /json/ url, where a JSON console is provided for testing.
Notes: Method "get" is default. "get"ting an item sets up a listener which sends all subsequent changes as well.

Example commands and responses
command response notes
{"type":"sensor","data":{"name":"IS2"}} {"type":"sensor","data":{"name":"IS2","state":2,"userName":null,"comment":null,"properties":[],"inverted":false}} request current state of sensor IS2
{"type":"sensor","method":"post","data":{"name":"IS2","state":4}} {"type":"sensor","data":{"name":"IS2","state":4,"userName":null,"comment":null,"properties":[],"inverted":false}} set sensor IS2 to InActive (4)
{"type":"turnout","data":{"name":"IT99"}} {"type":"turnout","data":{"name":"IT99","state":4,"userName":null,"comment":null,"properties":[],"inverted":false,"feedbackMode":1,"feedbackModes":[16,32,128,1],"sensor":[null,null]}} request current state of turnout IT99
{"type":"turnout","method":"put","data":{"name":"IT98","userName":"Test Turnout 98"}} {"type":"turnout","data":{"name":"IT98","userName":"Test Turnout 98","comment":null,"properties":[],"inverted":false,"state":0,"feedbackMode":1,"feedbackModes":[16,32,128,1],"sensor":[null,null]}} creaate turnout IT98 using "put" method
{"type":"power"} {"type":"power","data":{"name":"LocoNet","state":2,"default":true}} get power state, "name" is optional, will return default if not passed
{"type":"memory","data":{"name":"IMCURRENTTIME"}} {"type":"memory","data":{"name":"IMCURRENTTIME","userName":null,"comment":null,"value":"2:53 PM"}} get builtin memory (fast)clock time.
{"type":"ping"} {"type":"pong"} ping request and response
{"list":"panels"} [{"type":"panel","data":{"name":"ControlPanel/R&R","URL":"/panel/ControlPanel/R&R?format=xml","userName":"R&R","type":"Control Panel"}},{"type":"panel","data":{"name":"Layout/Waccamaw%20Coast%20Line","URL":"/panel/Layout/Waccamaw%20Coast%20Line?format=xml","userName":"Waccamaw Coast Line","type":"Layout"}}] request a list of panels, respond with array, example shows two panels
{"type":"throttle","data":{"name":"CSX754","address":754}} {"type":"throttle","data":{"name":"CSX754","address":754,"speed":0.0,"forward":true, "F0":false,"F1":false,"F2":false,"F3":false,"F4":false,"F5":false,"F6":false,"F7":false, "F8":false,"F9":false,"F10":false,"F11":false,"F12":false,"F13":false,"F14":false, "F15":false,"F16":false,"F17":false,"F18":false,"F19":false,"F20":false,"F21":false, "F22":false,"F23":false,"F24":false,"F25":false,"F26":false,"F27":false,"F28":false, "throttle":"CSX754"}} request throttle for address 754, refer to it as "CSX754"
{"type":"throttle","data":{"name":"CSX754","speed":0.25}} {"type":"throttle","data":{"name":"CSX754","speed":0.25,"throttle":"CSX754"}} request speed of throttle "CSX754" to 25%
{"type":"throttle","data":{"name":"CSX754","release":null}} {"type":"throttle","data":{"name":"CSX754","release":null,"throttle":"CSX754"}} release the throttle "CSX754"
{"list":"lights"} If list is empty: [] Example showing list response if there are no objects of that type.
{"type":"block","data":{"name":"IB1"}} {"type":"block","data":{"name":"IB1","userName":"AUTOBLK:1","comment":null,"value":"ns2608"}} request current value for block IB1
{"type":"train","data":{"name":"3"}} {"type":"train","data":{"name":"3","userName":"BB","iconName":"BB 1017", "departureTime":"07:50","description":"Bakersfield - Sweeper","route":"Bksfld-turn", "routeId":"4","locations":[...],"engines":[...], "cars": [...],"trainDepartsName":"Bakersfield", "trainTerminatesName":"Bakersfield","location":"Bakersfield", "locationId":"4r1","status":"Partial 4/8 cars","statusCode":20, "length":87,"weight":144,"leadEngine":"SP 1017", "caboose":"NH 681"}} request train by name
NOTE: locations, engines and cars arrays not shown here for clarity
{"type":"car","method":"post","data":{"name":"ATSF10407", "trainId":null,"locationUnknown":true,"location":null}} {"type":"car","data":{"name":"ATSF10407","number":"10407","road":"ATSF","rfid":"","carType":"Boxcar","carSubType":"", "length":50,"weight":4.4,"weightTons":88.0,"color":"Tuscan","owner":"AT","built":"1943","comment":"", "outOfService":false,"locationUnknown":true,"location":null,"trainId":null,"trainName":null,"destination":null, "load":"L","hazardous":false,"caboose":false,"passenger":false,"fred":false,"removeComment":"","addComment":"", "kernel":"","utility":false,"isLocal":false,"finalDestination":null,"returnWhenEmpty":null,"returnWhenLoaded":null, "division":"","status":"<?>"}} use post method to remove car from train and mark it as LocationUnknown.