Skip to content

Programming Interface (API)

Antony Corbett edited this page May 9, 2018 · 29 revisions

Introduction

OnlyT contains a built-in web server and offers a simple web API that allows clients to query and control the timer while it's running.

Description

Base URI

The base URI is as follows:

http://[IP address]:8096/api/v1

Please replace "IP address" with the name or IP address of the PC on which OnlyT is running. You must be able to connect to the machine from your client device, e.g. over a WiFi network. If you use an IP address you should ensure that it is a static address on the network (i.e. not subject to change over time).

Note that the port - which defaults to 8096 - is configurable in the OnlyT Settings page. The API version designation allows the interface to be modified in future revisions whilst retaining backwards compatibility. The idea is that if you write client code against a particular version of the API it will still work when subsequent versions are released.

Getting the Supported API Versions

You can retrieve the lowest and highest API versions supported by an OnlyT installation by issuing a GET request at the following address:

http://[IP address]:8096/api/

OnlyT responds with JSON structure in the following format:

{
  "lowVersion":[lowest version],
  "highVersion":[highest version]
}

The elements are described below

  • lowVersion – this is the lowest supported API version. Of course, we will try to retain backwards compatibility with all API versions.
  • highVersion – this is the highest supported API version.

You must enable the OnlyT web API (in the Settings page, Programming API section).

The "Web clock" section in the Settings page is used to control a web page served by OnlyT. This can be useful to test connectivity between your mobile device and the OnlyT application. Enable the setting, open a web browser on your client device and navigate to the following clock URI:

http://[IP address]:8096/index

The web browser should display the time of day. If you then start a timer in OnlyT, the browser should display the timer countdown value.

Security

OnlyT implements an optional security scheme which, when enabled, requires a code to be passed as a request header or as a query string field. To enable this feature, you must specify a code in the Settings page, Programming API, Code field.

The value can be anything you like and is not restricted to digits. However, if it needs to be entered on a mobile device then you may want to keep it short and use digits.

Please remember that unless communication between your clients and OnlyT is secured using SSL (https) then traffic will be in plain text and the remote access code will be available to a snooper.

If you decide to use a security code, when constructing client-side requests you must either add a header with the key "ApiCode" or pass a query string field named "ApiCode". The value should be as specified above in the OnlyT Settings page. See below for an example of the header:

GET /api HTTP/1.1
Host: localhost:8096
ApiCode: 8273
Content-Type: application/json

Passing the remote access code by the query string is illustrated below:

http://[IP address]:8096/api/v1/timers?ApiCode=8273

The following API calls do not require the code:

http://[IP address]:8096/api/
http://[IP address]:8096/api/v1/system

System

The system API provides access to some basic OnlyT information and has the following URI:

http://[IP address]:8096/api/v1/system

There is no need to provide a security code in your request. A GET request sent to the above address returns a single object in the following JSON format:

{
    "machineName": "[name of the PC]",
    "accountName": "[name of the windows account]",
    "onlyTVersion": "[OnlyT version number]",
    "apiVersion": {
        "lowVersion": [lowest API version supported],
        "highVersion": [highest API version supported]
    },
    "culture": {
        "name": "[culture name]",
        "isoCode2": "[ISO 2-character language code]",
        "isoCode3": "[ISO 3-character language code]"
    },
    "workingSet": [working set memory in bytes],
    "sessionId": "[OnlyT session Id string]",
    "apiEnabled": [true/false],
    "apiThrottled": [true/false],
    "apiCodeRequired": [true/false]
}

The elements are described below:

  • machineName – NetBIOS name of the machine on which OnlyT is running.
  • accountName – current logged on user account name.
  • onlyTVersion – OnlyT version, e.g. "1.1.0.3"
  • apiVersion.lowVersion – lowest supported API version.
  • apiVersion.highVersion – highest supported API version.
  • culture.name – name of the current culture, e.g. "en-GB".
  • culture.isoCode2 – ISO 2 character language code.
  • culture.isoCode3 – ISO 3 character language code.
  • workingSet – the amount of physical memory mapped to the process context (in bytes).
  • sessionId – a unique identifier that corresponds to an instance of OnlyT. You can use this to determine whether OnlyT has been closed and re-opened since your last request.
  • apiEnabled – a Boolean value indicating whether the timer can be controlled via the API.
  • apiThrottled - a Boolean value indicating whether the API is throttled to guard against spamming (accidental or otherwise).
  • apiCodeRequired – a Boolean value indicating whether use of the API requires a code.

Local Date and Time

You can get the current OnlyT date/time using this URI:

http://[IP address]:8096/api/v7/datetime

A sample JSON response is shown below:

{
  "year":2018,
  "month":4,
  "day":17,
  "hour":15,
  "min":11,
  "second":51
}

The fields are self-explanatory. If you want to display the “current time” in your client application, then it may be best to read the OnlyT local time at application startup and then store the difference between that and your device's local time - thus allowing you to display the OnlyT time whenever needed. Note that the latency of your network will affect the accuracy of the response value.

Timers

The timers API has the following base URI:

http://[IP address]:8096/api/v1/timers

Getting the Timer Collection

A GET request sent to the above URI returns the following JSON. It contains 2 main sections - "status" contains details of the current talk (the one that is selected in the OnlyT drop-down box); "timerInfo" contains a collection of timer objects, one for each of the talks in the current schedule:

{
    "status": {
        "talkId": [Id of the 'current' talk],
        "targetSeconds": [nominal duration in seconds],
        "isRunning": [true/false],
        "timeElapsed": "[time elapsed in the form 00:00:00.000]"
    },
    "timerInfo": [
        {
            "talkId": [Id of the talk],
            "talkTitle": "[title of the talk]",
            "originalDurationSecs": [nominal duration in seconds],
            "modifiedDurationSecs": [manually modified duration in seconds],
            "adaptedDurationSecs": [adapted duration in seconds],
            "actualDurationSecs": [actual duration in seconds],
            "usesBell": [true/false],
            "completedTimeSecs": [time taken in seconds],
            "countUp": [true/false]
        },
        ...
    ]
}

The elements are described below:

status

Values refer to the currently selected talk timer (as it appears in the OnlyT drop-down box).

  • talkId - the talk Id.
  • targetSeconds - the nominal duration of the talk in seconds.
  • isRunning - a Boolean value indicating whether the timer is currently running.
  • timeElapsed - the currently elapsed duration in the form 00:00:00.000 (hours:minutes:seconds.ms).

timerInfo

  • talkId - the talk Id.
  • talkTitle - the title of the talk (as it appears in the OnlyT drop-down).
  • originalDurationSecs - the nominal duration of the talk in seconds.
  • modifiedDurationSecs - the manually modified duration of the talk in seconds.
  • adaptedDurationSecs - the adapted duration of the talk in seconds (only applicable if using adaptive timing).
  • actualDurationSecs - the actual duration used when timing (will be the same as originalDurationSecs, modifiedDurationSecs or adaptedDurationSecs).
  • usesBell - a Boolean value indicating whether a bell is to be used.
  • completedTimeSecs - the actual duration taken (only available after a timer is stopped).
  • countUp - a Boolean value indicating whether the timer uses count up (true) or count down (false).

Getting an Individual Timer

A GET request sent to the following URL retrieves information about the specified talk timer:

http://[IP address]:8096/api/v1/timers/[talk id]

The json response is similar to that described above, except that the timerInfo collection contains a single object.

Starting a Timer

A POST request to the following URL starts a timer:

http://[IP address]:8096/api/v1/timers/[talk id]

OnlyT returns the following JSON response:

{
    "talkId": [the talk id],
    "command": [1 = start, 2 = stop],
    "success": [true/false],
    "currentStatus": {
        "talkId": [id of the current talk],
        "targetSeconds": [nominal duration of the current talk in seconds],
        "isRunning": [true/false],
        "timeElapsed": "[time elapsed in the form 00:00:00.000]"
    }
}

If success is true, the timer was successfully started and currentStatus refers to that of the timer just started. If success is false (e.g. if you tried to start a timer while another one was already running), the currentStatus provides details of the timer's current status.

  • talkId - the talk Id.
  • targetSeconds - the nominal duration of the talk in seconds.
  • isRunning - a Boolean value indicating whether the timer is currently running.
  • timeElapsed - the currently elapsed duration in the form 00:00:00.000 (hours:minutes:seconds.ms).

Stopping a Timer

A DELETE request to the following URL stops a timer:

http://[IP address]:8096/api/v1/timers/[talk id]

For details of the OnlyT response please see above under "Starting a Timer".

Error Handling

Standard http error codes are used where possible. A successful request meets with a response having an "ok" status code (200), but suppose you attempt to GET a talk timer that doesn't exist, e.g. by using the following address: http://[IP address]:8096/api/v1/timers/1234567890

In this case the OnlyT API returns an http error code 404 ("not found").

The OnlyT API also returns a JSON error object in the following format if more information is available:

{
  "errorCode":[An internal error code],
  "errorMessage":"[Description of the error]",
}

Error Code List

The following error codes are used (returned in the JSON error object described above):

Code Message and Description Http Status Code
0 "Success" 200 (ok)
1129 "Timer does not exist" – you have specified a timer index that doesn’t exist. For example, http://[IP address]:8096/api/v1/timers/123456789 404 (not found)
1130 "Malformed URI" – you have specified a URI with too many segments. For example http://[IP addresss]:8096/api/v1/timers/1000/foo 400 (bad request)

1131 “Malformed URI” – you have specified a URI with too few segments. For example http://soundbox_machine:8095/api/v7/ 400 (bad request) 1132 “Could not identify timer” – it wasn’t possible to identify a timer value in the URI. For example http://soundbox_machine:8095/api/v7/timers/abc 400 (bad request) 1133 “Could not identify song control” – it wasn’t possible to identify a song control value in the URI. For example http://soundbox_machine:8095/api/v7/songs/abc 400 (bad request) 1134 “Malformed URI” – you have specified a prefix that SoundBox cannot handle. For example http://soundbox_machine:8095/api/v7/foobar/1 400 (bad request) 1135 “Wrong http method used” – you have used an http method that is not supported by the target resource. For example you can issue a POST request to the root of the timers resource 405 (method not allowed) 1136 “Could not play/stop song” – you have successfully issued a request to toggle the status of a song but SoundBox cannot fulfil the request (e.g. because another song is playing) 409 (conflict) 1137 “Could not transition timer” – you have successfully issued a request to transition a timer but SoundBox cannot fulfil the request (e.g. because another timer is running) 409 (conflict) 1138 “API version not supported” – you are trying to use an API version that is not supported by this version of SoundBox 400 (bad request) 1139 “Not available in selected API version” – you are trying to use part of the API that is not available in the API version that you specified in the URI 400 (bad request) 1140 “Invalid API code” – you have not specified a valid remote access code in the header of your request 401 (unauthorised) 1141 “No media target display” – the media target display is not set 409 (conflict) 1142 “Invalid media command” – the specified action is unknown or not applicable in the current context 409 (conflict) 1143 “Media not found” – the media item was not found 404 (not found) 1144 “Unknown media tab name” – the specified media tab name is unknown 400 (bad request) 1145 “Bad media thumbnail key” 404 (not found) 1146 “Slideshow end” – reached the end of the slideshow 404 (not found) 1147 “Media busy” – another media item is already playing 409 (conflict) 1148 “Not a slideshow” – the request is only valid for slideshow items 400 (bad request) 1149 “Already playing” – you tried to play an item that is already playing 409 (conflict) 1150 “Already stopped” – you tried to stop a media item that was not playing 409 (conflict) 1151 “API is not enabled” – the relevant API is not enabled 401 (unauthorised) 1152 “Could not set song number” – it was not possible to set the song number (perhaps it is already playing or the number is not a valid song number) 409 (conflict) 1153 “Could not identify song number” – the song number specified in the URI is not a number 400 (bad request) 1154 “Invalid background music command” – the background music command is unknown or not applicable in the current context 409 (conflict) 1155 “Subscription address not found” – a bad address was specified in an event notification subscription request 400 (bad request) 1156 “Subscription port not found” – a bad port number was specified in an event notification subscription request 400 (bad request) 5128 “Unknown error” – any other errors 500 (internal server error)

Note that all errors are logged in the Windows event log.

Usage Tips

Try to keep the number of network calls to a minimum. In particular, if you want to dynamically update a timer's value don't attempt to poll the OnlyT server every 100 ms; poll it once to get a timer's value then maintain the display using a client-based timer, perhaps polling again every 2 or 3 seconds just to check that the timer hasn't been stopped (e.g. by the OnlyT operator).

Clone this wiki locally