-
-
Notifications
You must be signed in to change notification settings - Fork 208
Expand file tree
/
Copy pathopenApi.ts
More file actions
389 lines (386 loc) · 14.1 KB
/
Copy pathopenApi.ts
File metadata and controls
389 lines (386 loc) · 14.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
import { OpenApiDescription } from '../swagger'
const historyApiDoc = {
openapi: '3.0.0',
info: {
version: '0.0.1',
title: 'Signal K History API',
description:
'API for querying historical data, typically stored in a database. The actual storage backend is not defined by this API and can be implemented in various ways, typically as a plugin like [signalk-parquet](https://www.npmjs.com/package/signalk-parquet) and [signalk-to-influxdb2](https://www.npmjs.com/package/signalk-to-influxdb2). The most common use case for the API is to show graphs of past values.\n\n The time range can be defined as a combination of **from**, **to** and **duration** parameters. Omitted from and to parameters default to current moment in time, so that for example specifying just **duration** refers to the length of duration up to this moment.',
license: {
name: 'Apache 2.0',
url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
}
},
servers: [{ url: '/signalk/v2/api/history' }],
components: {
parameters: {
TimeRangeFrom: {
name: 'from',
in: 'query',
description: 'Start of the time range, inclusive as ISO 8601 timestamp',
schema: {
type: 'string',
format: 'date-time',
example: '2018-03-20T09:13:28Z'
}
},
TimeRangeDuration: {
name: 'duration',
in: 'query',
description:
"Duration of the time range in seconds (integer) or as an ISO8601 Duration string. Can be specified with either 'from' or 'to'. If they are both omitted is relative to 'now'. See https://datatracker.ietf.org/doc/html/rfc3339#appendix-A",
schema: {
oneOf: [
{ type: 'integer', description: 'Duration in seconds' },
{
type: 'string',
format: 'duration',
description: 'ISO8601 Duration string',
example: 'PT15M'
}
]
}
},
TimeRangeTo: {
name: 'to',
in: 'query',
description: "End of the time range, inclusive. 'Now' if omitted",
schema: {
type: 'string',
format: 'date-time',
example: '2018-03-20T09:13:28Z'
}
},
ProviderIdParam: {
in: 'path',
name: 'id',
required: true,
description: 'Plugin id of the history provider.',
schema: { type: 'string', example: 'signalk-to-influxdb2' }
},
ProviderIdQuery: {
in: 'query',
name: 'provider',
description:
'Plugin id of the history provider the request will be directed to.',
schema: { type: 'string', example: 'signalk-to-influxdb2' }
}
},
responses: {
'200OKResponse': {
description: 'OK',
content: {
'application/json': {
schema: {
type: 'object',
required: ['state', 'statusCode', 'message'],
properties: {
state: { type: 'string', enum: ['COMPLETED'] },
statusCode: { type: 'number', enum: [200] },
message: { type: 'string' }
}
}
}
}
},
ErrorResponse: {
description: 'Failed operation',
content: {
'application/json': {
schema: {
type: 'object',
required: ['state', 'statusCode', 'message'],
properties: {
state: { type: 'string', enum: ['FAILED'] },
statusCode: { type: 'number' },
message: { type: 'string' }
}
}
}
}
}
}
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
paths: {} as Record<string, any>
}
// Dynamic example timestamps
const yesterday = new Date()
yesterday.setDate(yesterday.getDate() - 1)
historyApiDoc.paths = {
'/values': {
get: {
summary: 'Retrieve historical data',
description:
'Returns historical data series for the paths and time range specified in query parameters',
parameters: [
{
$ref: '#/components/parameters/TimeRangeFrom',
example: yesterday.toISOString()
},
{ $ref: '#/components/parameters/TimeRangeDuration' },
{
$ref: '#/components/parameters/TimeRangeTo',
example: new Date().toISOString()
},
{
name: 'paths',
in: 'query',
description:
"Comma separated list of Signal K paths whose data should be retrieved, optional aggregation methods for each path as postfix separated by a colon, and optional source reference separated by a pipe (|). Aggregation methods: 'average' | 'min' | 'max' | 'first' | 'last' | 'mid' | 'middle_index' | 'sma' | 'ema'. The 'sma' (simple moving average) and 'ema' (exponential moving average) methods accept an optional numeric parameter separated by colon: for sma it is the number of samples, for ema it is the alpha value (0-1). If not provided, implementations should use sensible defaults. The source reference after | filters data to that specific source.",
example:
'navigation.speedOverGround:sma:5|n2k-on-ve.can0.115,navigation.speedThroughWater:max',
schema: { type: 'string' },
required: true
},
{
name: 'context',
in: 'query',
description:
"Signal K context that the data is about, defaults to 'vessels.self'",
example: 'vessels.urn:mrn:imo:mmsi:123456789',
schema: { type: 'string' }
},
{
name: 'resolution',
in: 'query',
description:
"Length of data sample time window in seconds or as a time expression ('1s', '1m', '1h', '1d'). If resolution is not specified the server should provide data in a reasonable time resolution, depending on the time range in the request.",
schema: { type: 'number', format: 'integer' }
},
{
name: 'sourcePolicy',
in: 'query',
description:
"Controls how multiple historical sources are handled. With 'all', providers should return values split by source and include $source in the values metadata. A sourceRef specified on an individual path remains an explicit filter; 'all' only expands paths that do not already specify a source.",
schema: { type: 'string', enum: ['all'] }
},
{ $ref: '#/components/parameters/ProviderIdQuery' }
],
responses: {
'200': {
description: 'Series data with header',
content: {
'application/json': {
schema: {
type: 'object',
required: ['context', '', 'target'],
properties: {
context: {
type: 'string',
description: 'Signal K context that the data is about',
example: 'vessels.urn:mrn:imo:mmsi:123456789'
},
range: {
type: 'object',
properties: {
from: {
type: 'string',
format: 'date-time',
description:
'Start of the time range, inclusive, as UTC timestamp',
example: '2018-03-20T09:12:28Z'
},
to: {
type: 'string',
format: 'date-time',
description:
'End of the time range, inclusive, as UTC timestamp',
example: '2018-03-20T09:13:28Z'
}
}
},
values: {
type: 'array',
items: {
type: 'object',
properties: {
path: {
type: 'string',
description: 'Signal K path'
},
method: {
type: 'string',
description: 'Aggregation method'
},
$source: {
type: 'string',
description:
'Source reference for this value series, present when source-aware history is requested, including sourcePolicy=all'
}
}
}
},
data: {
type: 'array',
items: {
type: 'array',
items: {
description:
'Data for a point in time. The first array element is the timestamp in ISO 8601 format. Missing data for a path is returned as null',
oneOf: [
{ type: 'string' },
{ type: 'number' },
{ type: 'null' },
{
type: 'array',
items: { type: 'number' }
}
]
}
},
example: [
['2023-11-09T02:45:38.160Z', 13.2, null, [-120.5, 59.2]]
]
}
}
}
}
}
}
}
}
},
'/contexts': {
get: {
summary: 'Get contexts that have some historical data',
description:
'Returns an array of contexts that have some historical data to query with /values for the specified time range',
parameters: [
{ $ref: '#/components/parameters/TimeRangeFrom' },
{ $ref: '#/components/parameters/TimeRangeDuration' },
{ $ref: '#/components/parameters/TimeRangeTo' },
{ $ref: '#/components/parameters/ProviderIdQuery' }
],
responses: {
'200': {
description: 'Array of contexts',
content: {
'application/json': {
schema: {
type: 'array',
items: {
type: 'string',
description: 'Signal K Context',
example: 'vessels.urn:mrn:imo:mmsi:123456789'
}
}
}
}
}
}
}
},
'/paths': {
get: {
summary: 'Get paths that have some historical data',
description:
'Returns an array of path that have some historical data to query with /values for the specified time range',
parameters: [
{ $ref: '#/components/parameters/TimeRangeFrom' },
{ $ref: '#/components/parameters/TimeRangeDuration' },
{ $ref: '#/components/parameters/TimeRangeTo' },
{ $ref: '#/components/parameters/ProviderIdQuery' }
],
responses: {
'200': {
description: 'Array of paths',
content: {
'application/json': {
schema: {
type: 'array',
items: {
type: 'string',
description: 'Signal K Path',
example: 'navigation.speedOverGround'
}
}
}
}
}
}
}
},
'/_providers': {
get: {
tags: ['Provider'],
summary: 'Retrieve list of registered history providers.',
responses: {
default: {
description:
'Return information about the registered history providers.',
content: {
'application/json': {
schema: {
type: 'object',
additionalProperties: {
type: 'object',
description: 'Provider status',
required: ['isDefault'],
properties: {
isDefault: {
type: 'boolean',
description:
'`true` if this provider is set as the default.'
}
},
example: { isDefault: true }
}
}
}
}
}
}
}
},
'/_providers/_default': {
get: {
tags: ['Provider'],
summary: 'Get the default history provider id.',
responses: {
default: {
description:
'Returns the id of the provider that is the target of requests (if provider is not specified).',
content: {
'application/json': {
schema: {
type: 'object',
required: ['id'],
properties: {
id: {
type: 'string',
description: 'Provider identifier.'
},
configured: {
type: 'string',
description:
'Provider identifier persisted in server settings, set either by a client through this API or by the server itself, which records the first provider to register when no default is configured and its settings are safe to save. May differ from `id` when the configured provider is not currently registered, and is absent on a server that has recorded nothing.'
}
},
example: { id: 'signalk-to-influxdb2' }
}
}
}
}
}
}
},
'/_providers/_default/{id}': {
parameters: [{ $ref: '#/components/parameters/ProviderIdParam' }],
post: {
tags: ['Provider'],
summary: 'Sets the default history provider.',
description:
'Sets the provider with the supplied `id` as the default and persists the choice in server settings.',
responses: {
default: { $ref: '#/components/responses/ErrorResponse' },
'200': { $ref: '#/components/responses/200OKResponse' }
}
}
}
}
export const historyApiRecord = {
name: 'history',
path: '/signalk/v2/api/history',
apiDoc: historyApiDoc as unknown as OpenApiDescription
}