pianod2 JSON Support
JSON Requests
JSON request names and keys are case sensitive.
Message quoting should be done in accordance with the JSON specification.
When sent to pianod, the request must be sent on a
single line; returns are treated as end-of-message. Requests split
over multiple lines will fail with parse errors. Only one request
can be sent per line.
Any instruction can be sent as either a command line or
as a JSON request. The SCHEMA command (or its
equivalent request, getSchema) generates a list of all
requests, or details for a particular request. See the commands
section of this documentation for a more information on
commands.
For example:
SCHEMA getSchema
203 Data
132 Information: All requests take the form:
132 Information: {"requestname": {request parameters/options...}}
132 Information: getSchema: Dictionary containing:
132 Information: 'request' (optional)
132 Information: List (0 or more members) of String (no control characters allowed)
204 No data or end of data
If we wanted to use JSON to request the schema for authenticating:
{ "getSchema": {"request": ["authenticate"] } }
203 Data
132 Information: authenticate: Dictionary containing:
132 Information: 'username' (mandatory)
132 Information: Requires also: password
132 Information: String (no control characters allowed)
132 Information: 'password' (mandatory)
132 Information: Requires also: username
132 Information: String (no control characters allowed)
204 No data or end of data
There are 3 special keys that can be used in the main dictionary of the request:
asUser- Accepts a dictionary containing
usernameandpassword(both strings). Like theAS USERcommand-line counterpart, requests includingasUserwill close the connection when they complete (or fail). inRoom- accepts a dictionary containing
room(string). withSource- Accepts a dictionary named
sourcecontaining eitherid(numeric) or bothtypeandname(both strings).
JSON Responses
JSON response mode is selected at connection time. Initiate
Websocket connections with the query parameter
protocol=json, or connect on
pianod’s HTTP or HTTPS port and greet with
HELO pianod json\n for JSON over plain TCP.
All messages sent by the server are dictionaries, which take 3 forms:
- Replies (i.e., Successes/failures)
- Data
- Notifications
Messages are sent as a single, newline-terminated line, or a single Websocket message.
In response to a command or request, you will receive
either a reply or data. These both have the fields
code, which matches up with the success/command error
codes for the line protocol.
Data
If code is 203, the message contains the reply data
in a member called data. data is
always a list of dictionaries:
USER LIST PERETTE
{
"code":203,
"data":[
{
"id":"perette",
"privileges":{
"rank":"admin",
"deejay":false,
"present":true,
"service":false,
"influence":true,
"tuner":false,
"shadow":false
}
}
],
"status":"Data"
}
Note: Response message has been formatted for
legibility. The server will return it as a single line of
JSON, without newlines or identing. A command-line utility
json_format, included in src/parsnip, will beautify
JSON provided to it. Use it as a filter, or specify filenames on
the command line.
Replies
Other 2xx values for code (200–202,
205–299) indicate a success, and 400–499 indicate a
command error. For these, there will be both
successes and failures arrays. One or
both of these will be non-empty; it is possible to receive multiple
successes, failures, or a mix of both.
GRANT SERVICE TO Frank Edward
{
"code":404,
"successes":[],
"status":"Requested item not found",
"failures":[
{
"code":404,
"status":"Requested item not found",
"details":null,
"id":"Frank",
"name":"Frank"
}, {
"code":404,
"status":"Requested item not found",
"details":null,
"id":"Edward",
"name":"Edward"
}
]
}
Notifications
If there is no code present, the message is a
notification. Notifications can also be included with
replies.
There are 4 categories of notifications: events,
state, currentSong, and
errors. Here is a state notification:
{
"state":{
"volume":3
}
}
And another, this one featuring current playback information:
{
"state":{
"playbackState":"Paused"
},
"currentSong":{
"duration":309,
"timeIndex":4,
"timeRemaining":304
}
}
An event notification:
{
"events":[
{
"code":4,
"status":"Track playback complete",
"details":null
}
]
}
A current song notification:
{
"currentSong":{
"playlistName":"jazz",
"songInfoUrl":null,
"duration":456,
"name":"Ritual",
"playlistId":"2pp1080572466",
"source":{
"id":2,
"type":"filesystem",
"name":"perette"
},
"id":"2ss971186724-9",
"artistId":"2sa1792080946",
"artistName":"Chick Corea Elektric Band II",
"compilation":false,
"genre":"Jazz",
"trackId":"2ss971186724-9",
"albumArtUrl":null,
"albumId":"2sl971186724",
"trackName":"Ritual",
"year":1993
}
}
Notifications can carry several categories. In the following
message, currentSong is null to indicate
there is no current song because it was stopping.
{
"events":[
{
"code":4,
"status":"Track playback complete",
"details":null
}
],
"state":{
"playbackState":"idle"
},
"currentSong":null
}
Were instead play was continuing to a new track, the track playback complete event would be accompanied by the new track information:
{
"events":[
{
"code":4,
"status":"Track playback complete",
"details":null
}
],
"currentSong":{
"playlistName":"Short Stop",
"songInfoUrl":null,
"duration":313,
"name":"One Of Our Submarines",
"playlistId":"2pp1407280692",
"source":{
"id":2,
"type":"filesystem",
"name":"perette"
},
"id":"2ss1104797890-9",
"artistId":"2sa988499006",
"artistName":"Thomas Dolby",
"compilation":false,
"genre":"Rock",
"trackId":"2ss1104797890-9",
"albumArtUrl":null,
"albumId":"2sl1104797890",
"trackName":"One Of Our Submarines",
"year":null
}
}
