Skip to content

Programming Interface (API)

Antony Corbett edited this page Jul 19, 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. Information about Android and iOS remote control apps are available here: https://www.facebook.com/RemoteForOnlyT/

Description

Base URI

The base URI is as follows:

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

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:

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:

api/v2/timers?ApiCode=8273

The following API calls do not require the code:

api/
api/v2/system

System

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

api/v2/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:

api/v2/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:

api/v2/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]",
            "meetingSectionNameInternal": "[name of the meeting section]",
            "meetingSectionNameLocalised": "[localised name of the meeting section]",
            "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).
  • meetingSectionNameInternal - the name of the meeting section in which the talk is scheduled. The values do not change with different language versions of the application. In automatic mode, the values for the midweek meeting are 'Treasures', 'Ministry' and 'Living'.
  • meetingSectionNameLocalised - localised version of above.
  • 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:

api/v2/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:

api/v2/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:

api/v2/timers/[talk id]

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

Bell

The timer bell can be sounded by posting to the following URI:

api/v2/bell

Note that bell must be enabled in the OnlyT options.

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/v2/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, api/v2/timers/123456789 404 (not found)
1130 "Malformed URI" – you have specified a URI with too many segments. For example api/v2/timers/1000/foo 400 (bad request)
1131 "Malformed URI" – you have specified a URI with too few segments. For example api/v2/ 400 (bad request)
1134 "Malformed URI" – you have specified a prefix that OnlyT cannot handle. For example api/v2/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 cannot issue a POST request to the root of the timers resource 405 (method not allowed)
1138 "API version not supported" – you are trying to use an API version that is not supported by this version of OnlyT 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 security code in the header (or query string) of your request 401 (unauthorised)
1151 "API is not enabled" – the relevant API is not enabled 401 (unauthorised)
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).