Use it from your own agent
JasperNode is built to be driven by an agent. The
local web interface is a thin page over a plain HTTP API, and
anything that can send HTTP — curl, a script, your own AI agent — can do what the page does with
the same password.
Changes made here or by your own agent go straight to the running controller, with no sign-off and no checks beyond the controller’s own; they are recorded as the local operator, and JasperX sees them once the controller is online. Sign-off guards Jasper’s changes made through JasperX.
The password is set from JasperX, so a controller must be claimed once before its interface or your agent can use it.
Give this page to your agent
Section titled “Give this page to your agent”Give your agent three things: this page, the controller’s address (http://192.168.1.20:9009) and
the local web interface password. Then tell it what to do — “back up the programme”, “add a tag
plant/tank/alarm that is true above 90 %”. The controller also describes its API itself, in plain
text, at GET /api; an agent can read that first.
Auth and answers
Section titled “Auth and answers”- HTTP Basic auth on every request but
/health: any user name, the local web interface password (curl -u x:PASSWORD). - Answers are JSON. A refusal is
{"error": "..."}with a 4xx status, and the message says what to fix:400a bad request (a script with a non-literal path, say),403a write the controller does not take here,404no such tag,409a change the controller refused (a script that triggers on its own tag, say). A password failure is plain text:401wrong or missing password, or no password set yet;429another password check is running, try again in a moment. - Connector secrets are masked as
•••in every answer and in the backup; send•••back to keep the stored value.
This API is what the 2.1 page uses today. It is small and plain, but it is not versioned and may
change in a later release; GET /api on the controller always describes the one it runs.
The routes
Section titled “The routes”The examples use CONTROLLER for address:port and PASSWORD for the password.
List tags under a path (all tags outside __sys when under is empty): id, type, value.
curl -u x:PASSWORD "http://CONTROLLER/api/tags?under=plant"# {"tags":[{"id":"plant/tank/level","type":"number","value":86.4}, ...]}Read one tag: its value, its props and its script.
curl -u x:PASSWORD "http://CONTROLLER/api/tag?id=plant/pump/run"# {"id":"plant/pump/run","value":true,"props":{"valueType":"boolean","description":"..."},# "script":"return on(\"plant/tank/level\") > on(\"plant/tank/high_limit\");"}Create a tag, or change its props and script. A script is saved and runs at once; an empty
script deletes the script.
curl -u x:PASSWORD -X PUT "http://CONTROLLER/api/tag?id=plant/pump/run" \ -d '{"props":{"valueType":"boolean","description":"Pump runs above the limit"}, "script":"return on(\"plant/tank/level\") > on(\"plant/tank/high_limit\");"}'Set a value: the body is the JSON value.
curl -u x:PASSWORD -X POST "http://CONTROLLER/api/value?id=plant/tank/high_limit" -d '80'Delete a tag.
curl -u x:PASSWORD -X DELETE "http://CONTROLLER/api/tag?id=plant/tank/old"Back up the whole programme, connector secrets masked.
curl -u x:PASSWORD -o backup.json "http://CONTROLLER/api/backup"Restore a backup: it replaces the whole programme, all of it or none of it; masked secrets keep the values this controller holds.
curl -u x:PASSWORD -X PUT "http://CONTROLLER/api/backup" --data-binary @backup.json# {"contentHash":"ad0545…","tagCount":4}Health, with no password: answers ok.
curl "http://CONTROLLER/health"Connectors. An existing connector’s settings are the JSON value of its tag
__sys/node/user/connectors/<type>/<id>/config; set it with POST /api/value. This API cannot add
a connector or enable one (the controller answers 403), and a restored backup leaves every
connector disabled: connectors are added and enabled from JasperX.
See Tags and scripts for how scripts read other tags.