mirror of
https://github.com/scottlamb/moonfire-nvr.git
synced 2025-11-20 01:50:24 -05:00
read-only signals support (#28)
This is mostly untested and useless by itself, but it's a starting point. In particular: * there's no way to set up signals or add/remove/update events yet except by manual changes to the database. * if you associate a signal with a camera then remove the camera, hitting /api/ will error out.
This commit is contained in:
110
design/api.md
110
design/api.md
@@ -13,6 +13,12 @@ In the future, this is likely to be expanded:
|
||||
(at least for bootstrapping web authentication)
|
||||
* mobile interface
|
||||
|
||||
## Terminology
|
||||
|
||||
*signal:* a timeseries with an enum value. Signals might represent a camera's
|
||||
motion detection or day/night status. They could also represent an external
|
||||
input such as a burglar alarm system's zone status.
|
||||
|
||||
## Detailed design
|
||||
|
||||
All requests for JSON data should be sent with the header
|
||||
@@ -88,6 +94,21 @@ The `application/json` response will have a dict as follows:
|
||||
time zone. It is usually 24 hours after the start time. It
|
||||
might be 23 hours or 25 hours during spring forward or fall
|
||||
back, respectively.
|
||||
* `signals`: a map of all signals known to the server. Keys are ids. Values are
|
||||
dictionaries with the following properties:
|
||||
* `shortName`: a unique, human-readable description of the signal
|
||||
* `cameras`: a map of associated cameras' UUIDs to the type of association:
|
||||
`direct` or `indirect`. See `db/schema.sql` for more description.
|
||||
* `type`: a UUID, expected to match one of `signalTypes`.
|
||||
* `days`: as in `cameras.streams.days` above.
|
||||
* `signalTypes`: a list of all known signal types.
|
||||
* `uuid`: in text format.
|
||||
* `states`: a map of all possible states of the enumeration to more
|
||||
information about them:
|
||||
* `color`: a recommended color to use in UIs to represent this state,
|
||||
as in the [HTML specification](https://html.spec.whatwg.org/#colours).
|
||||
* `motion`: if present and true, directly associated cameras will be
|
||||
considered to have motion when this signal is in this state.
|
||||
* `session`: if logged in, a dict with the following properties:
|
||||
* `username`
|
||||
* `csrf`: a cross-site request forgery token for use in `POST` requests.
|
||||
@@ -126,9 +147,45 @@ Example response:
|
||||
},
|
||||
...
|
||||
],
|
||||
"signals": {
|
||||
1: {
|
||||
"shortName": "driveway motion",
|
||||
"cameras": {
|
||||
"fd20f7a2-9d69-4cb3-94ed-d51a20c3edfe": "direct"
|
||||
},
|
||||
"type": "ee66270f-d9c6-4819-8b33-9720d4cbca6b",
|
||||
"days": {
|
||||
"2016-05-01": {
|
||||
"endTime90k": 131595516000000,
|
||||
"startTime90k": 131587740000000,
|
||||
"totalDuration90k": 5400000
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"signalTypes": [
|
||||
{
|
||||
"uuid": "ee66270f-d9c6-4819-8b33-9720d4cbca6b",
|
||||
"states": {
|
||||
0: {
|
||||
"name": "unknown",
|
||||
"color": "#000000"
|
||||
},
|
||||
1: {
|
||||
"name": "off",
|
||||
"color": "#888888"
|
||||
},
|
||||
2: {
|
||||
"name": "on",
|
||||
"color": "#ff8888",
|
||||
"motion": true
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"session": {
|
||||
"username": "slamb",
|
||||
"csrf": "2DivvlnKUQ9JD4ao6YACBJm8XK4bFmOc",
|
||||
"csrf": "2DivvlnKUQ9JD4ao6YACBJm8XK4bFmOc"
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -182,9 +239,6 @@ Valid request parameters:
|
||||
server should return a `continue` key which is expected to be returned on
|
||||
following requests.)
|
||||
|
||||
TODO(slamb): once we support annotations, should they be included in the same
|
||||
URI or as a separate `/annotations`?
|
||||
|
||||
In the property `recordings`, returns a list of recordings in arbitrary order.
|
||||
Each recording object has the following properties:
|
||||
|
||||
@@ -420,6 +474,54 @@ a `codecs` parameter as specified in [RFC 6381][rfc-6381].
|
||||
A GET returns a `text/plain` debugging string for the `.mp4` generated by the
|
||||
same URL minus the `.txt` suffix.
|
||||
|
||||
### `/api/signals`
|
||||
|
||||
A GET returns an `application/json` response with state of every signal for
|
||||
the requested timespan.
|
||||
|
||||
Valid request parameters:
|
||||
|
||||
* `startTime90k` and and `endTime90k` limit the data returned to only
|
||||
events relevant to the given half-open interval. Either or both
|
||||
may be absent; they default to the beginning and end of time, respectively.
|
||||
This will return the current state as of the latest change (to any signal)
|
||||
before the start time (if any), then all changes in the interval. This
|
||||
allows the caller to determine the state at every moment during the
|
||||
selected timespan, as well as observe all events (even instantaneous
|
||||
ones).
|
||||
|
||||
Responses are several parallel arrays for each observation:
|
||||
|
||||
* `times90k`: the time of each event. Events are given in ascending order.
|
||||
* `signalIds`: the id of the relevant signal; expected to match one in the
|
||||
`signals` field of the `/api/` response.
|
||||
* `states`: the new state.
|
||||
|
||||
Example request URI (with added whitespace between parameters):
|
||||
|
||||
```
|
||||
/api/signals
|
||||
?startTime90k=130888729442361
|
||||
&endTime90k=130985466591817
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{
|
||||
"signalIds": [1, 1, 1],
|
||||
"states": [1, 2, 1],
|
||||
"times90k": [130888729440000, 130985424000000, 130985418600000]
|
||||
}
|
||||
```
|
||||
|
||||
This represents the following observations:
|
||||
|
||||
1. time 130888729440000 was the last change before the requested start;
|
||||
signal 1 (`driveway motion`) was in state 1 (`off`).
|
||||
2. signal 1 entered state 2 (`on`) at time 130985424000000.
|
||||
3. signal 1 entered state 1 (`off`) at time 130985418600000.
|
||||
|
||||
[media-segment]: https://w3c.github.io/media-source/isobmff-byte-stream-format.html#iso-media-segments
|
||||
[init-segment]: https://w3c.github.io/media-source/isobmff-byte-stream-format.html#iso-init-segments
|
||||
[rfc-6381]: https://tools.ietf.org/html/rfc6381
|
||||
|
||||
Reference in New Issue
Block a user