Objective
This article explains how to obtain the current and projected crewing status of one or more appliances through the FireServiceRota API in a machine readable format.
Background
Within the user interface of FireServiceRota, the status of appliances is represented using simple color codes. See the image below for an explanation of these codes.
Preparation
The remainder of this article assumes that you possess credentials that provide at least read-access to the appliances in question. See How do I access the API? for instructions.
Retrieving appliance statuses using the RESTful API
Step 1: Obtain a list of available appliances
The endpoint GET /availability_requirements
returns a list of all appliances.
See below for an example.
[
{
"id": 941,
"name": "UAHT",
"short_code": null,
"html_color": "black",
"single_skill_availability_requirements": [
{
"id": 1426,
"skill_id": 7951,
"assigned": 1,
"standby": 0
}
],
"task_ids": [
7482
],
"group_ids": [
24866,
24865
]
}
]
Here, there is a single appliance named "UAHT", requiring that 1 person is available with a certain skill. It is linked to a single appliance (Task), which is crewed by users from two groups. All referenced objects (Skills, Tasks, Groups) can be accessed through their respective endpoints.
Step 2: Obtain a schedule of appliance statuses
The endpoint
GET/availability_requirements/{id}/schedule
?start_time=[start_time]&end_time=[end_time]
returns a schedule of current and projected statuses for a single appliance.
Note: For performance and caching reasons, the start_time and end_time must be aligned with the start of the day (00:00). This allows FireServiceRota to quickly respond to requests if no changes to rotas were made. We recommend polling to keep the statuses of appliances up to date at a frequency no greater than once per minute. If appliance statuses are required in real-time, we also have a Websocket API available (see below).
See below for an example. Information not relevant to achieve this task has been replaced by ellipsis (...
).
{
"availability_requirement": {
"id": 942,
"name": "CAHO",
"short_code": null,
"html_color": "black",
"single_skill_availability_requirements": [
...
]
},
"start_time": "2020-01-01T00:00:00.000+00:00",
"end_time": "2020-01-02T00:00:00.000+00:00",
"intervals": [
{
"start_time": "2020-01-01T00:00:00.000+00:00",
"end_time": "2020-01-01T02:00:00.000+01:00",
"service_level": "in_service",
"warning_level": "on_required",
"available_memberships": [
...
],
"skill_statuses": [
{
"skill_id": 7952,
"level": "on_required",
"minimum": 1,
"buffer": 0,
"assigned_count": 1,
"available_memberships": [
...
]
}
],
"unchecked_skill_statuses": [
...
],
"availability_requirement": {
...
"task_availability_codes": {
...
}
},
{
"start_time": "2020-01-01T02:00:00.000+01:00",
"end_time": "2020-01-02T00:00:00.000+00:00",
"service_level": "in_service",
"warning_level": "below_required",
...
}
]
}
The important part of what is returned by the API are the intervals. In the example above, there are 2 intervals.
For every status change, the intervals array contains a single element. Every interval has a start and end time, and a service and warning level.
The service_level encodes whether the appliance is currently in service.
The warning_level can have 5 different values corresponding to the image in section Background:
- below_required: red
- on_required: orange
- below_buffer: yellow
- on_buffer: yellow (exactly on the buffer)
- above_buffer: green
If only the current status is needed, some processing needs to be done by the client to identify the interval that is currently active.
Retrieving appliance statuses using the Websocket (real-time) API
To connect to the Incident WebSockets you need to connect to this url: wss://www.fireservicerota.co.uk/cable?access_token={access_token} and
connect to the channel called "AvailabilityRequirementNotificationsChannel" for the specific station you wish to receive updates for.
FireServiceRota uses Rails/ActionCable. These are plain websockets, but use a specific format to subscribe to a channel. See below for example code in Javascript. All major languages have production-ready websocket libraries.
The WebSockets returns the same exact format as described above, every time there is an update for a specific period. If there are no updates for a specific period, it means that the earlier communicated status for that period is still valid. It is up to the client to maintain a consistent view of the full current status.
// Opens a WebSocket connection to a specific stream.
function openWebsocketConnection() {
// Creates the new WebSocket connection.
socket = new WebSocket(urlWithAccessToken);
socket.onopen = function(event) {
console.log('WebSocket is connected.');
const msg = {
command: 'subscribe',
identifier: JSON.stringify({
channel: 'AvailabilityRequirementNotificationsChannel',
// station ID for which you want updates for. Omit if any.
group_id: String(groupId)
}),
}; socket.send(JSON.stringify(msg));
};
// When the connection is closed, this code will run.
socket.onclose = function(event) {
console.log('WebSocket is closed.');
};
// When a message is received through the websocket, this code will run.
socket.onmessage = function(event) {
const response = event.data;
const msg = JSON.parse(response);
// Ignores pings.
if (msg.type === "ping") {
return;
} console.log("FROM RAILS: ", msg);
// Do something with msg
};
// When an error occurs through the websocket connection, this code is run printing the error message.
socket.onerror = function(error) {
console.log('WebSocket Error: ' + error);
};
}
Comments
0 comments
Please sign in to leave a comment.