API
The ACS API allows you to connect your application to the ACS service that controls the NCAR AVAPS Telemetry Rack and Launcher. This API allows anyone to retrieve any and all data recorded realtime. It also is the entry point to prepare sondes for launching, starting & stopping channels, launching sondes, and monitoring system status.
In most cases the following HTTP status values are followed
Return Code | Constant | Description |
---|---|---|
200 | StatusOK | Successful, with a HTTP Body response |
204 | StatusNoContent | Successful, without any HTTP Body response |
401 | StatusUnauthorized | User does not have required permissions |
405 | StatusMethodNotAllowed | Unsuccessful, with a HTTP Body response |
406 | StatusNotAcceptable | Unsuccessful, without any HTTP Body response |
503 | StatusServiceUnavailable | Route is currently not accessible. |
Randomized JSON Data
All JSON objects are randomized, and there will be no attempt to normalize them (eg, sort alphabetically, pretty-format). For the sake of clarity, the JSON objects in this document WILL be formatted in a human readable way so you can deduce structure. The emitted JSON is valid, just use a JSON parser. Likewise, incoming JSON commands are also not assumed to be in any particular order, and will be unmarshalled from JSON to usable objects JSON.
Timestamp Handling
Any timestamp is always in UTC time. Any other time should be considered an error. Times should be formatted as per golang’s time.RFC3339Nano
which looks like “2006-01-02T15:04:05.999999999Z07:00”
API Radix
The API utilizes versioning, and may change in the future.
ACS version v1
https://{acs_server}:{port}/api/{version}
- acs_server: required(string)
The server that ACS is running on
- port: required(integer)
The configured HTTPS port ACS is listening on
- version: required(v1)
Heartbeat & Versioning
This route provides data that should be used to detect if the acs instance is running, and as a step to access the proper routes to log in, gather data, and perform operations. This is one of the few routes that does not require, nor check, for login.
radix
This route provides a field named radix which points to where the API starts. This should be understood to mean the root API calls begin at: http://server[:port][radix]
Static Data, but non-cachable
This route is not cached, mostly because it can be used as a heartbeat mechanism. Browsers aggressively utilize caching, and if this route is cached, clients do not have a good way to detect if ACS is operational.
Always On
This route is explicitly available without any sort of credentials in ACS. This means that this route can be used as a heartbeat mechanism - if data is returned, ACS is running. If the route cannot be accessed, it implies ACS is not operational. If ACS experencies a restart, accessing this route will work, but other routes will start returning unauthorized errors, and clients must re-authenticate.
Authentication
Authentication
ACS requires some form of authentication/ identification in order to access its services. This is not so much for security as it is for identification. ACS needs to know who is performing tasks so that correct metadata can be attached to a sounding. There is less concern about hacking attempts, although that may also be an operational concern. The authentication is really implemented in order to gather who, or what, is accessing the data realtime, and to limit access to the command & control functions. Due to the normally disconnected operation (i.e., no routeable access to the internet), this uses a simplistic login function with cookies rather than more common OAUTH / OAUTH2 tokens.
Access Roles
There are functionally only three levels of access, though one does some special things.
role=0: not logged in (default)
This is the default state of all clients interacting with ACS. At this point, the only thing available on the ACS daemon is /auth. The handler for / should check for some sort of authentication token, and if it is not present, redirect the user to /auth. There is a simple login page that should be hard coded. You are not required to use this login page, as long as you follow the login protocol
role=1: read only access
This is the first level that allows access to ACS. You should have full permissions to "GET" on any valid routes ACS supports. As of writing this, no password is required, just a valid email.
role=2: command and control (or read/write) access
This is the second, and maximal level that ACS handles. Anyone logged in with these credentials should have access to access all routes via all defined methods ("GET", "POST", "PUT", "DELETE"). A password is required to gain this access level, and should be configured in the configuration files.
role=3: hijack access - forcibly log out role>1 users.
This is a pseudo level - it functionally acts like a CommandAndControl, but during the login process, boots all other users with a level >= CommandAndControl. It is a hostile takeover of the system. A password is required to gain this access level, and should be configured in the configuration files.
Protocol
This should be really straightforward.
- POST your credentials to /auth
- Retrieve the authentication cookie stored as "acs_token" from the HTTP headers
- Include this cookie with any http request.
Roles
role | Name | Details |
---|---|---|
0 | Not logged in | Can only login. Unable to access any core functionality. Some routes are available |
1 | Read Only | Can fetch any data - Unable to control hardware, state machines, or modify data. A password is not required, and if present, will be ignored. |
2 | Command & Control | Same permissions as Read Only, but able to control hardware, alter state machines, and store data. Password should be the command and control password |
3 | Exclusive Command & Control | De-authorizes any access > Read Only, and then assumes Command & Control access. Password should be the exclusive control password |
Operational Considerations
- If you need access from multiple machines, don't fret - just login on any additional computer terminals. There is no maximal limit on logins
Attempt to de-authenticate / logout a user from ACS service. Accessing this route with a valid cookie removes the server side token as well as any client side token. A similar effect may be achieved by removing the client cookie.
Attempts to login with credentials. If login is successful, a secure cookie will be placed on the returned request. This cookie will be invalidated anytime the server restarts, or if logged in as a CommandAndControl user and an ExclusiveCommandAndControl logs in. Password is not required for ReadOnlyLogins
Auto-Initiate Soundings
Auto-initiate Sonde Mechanism
Interact with the structure that handles automatically starting a channel onces a sonde has been found. Set, clear, or poll the status of the state machine that automatically starts a channel onces the launcher detects an attached sonde. Additionally, a GET will return the preferred next frequency coming from the spectrum analyzer. This can can be used to guide manual frequency selection for sondes.
Enable automatically starting a channel onces a sonde has been found
Disable automatically starting a channel once a sonde has been found
Fetch the current auto state and the preferred next guidance frequency and error
Channel Ops
General
The /channel route interacts with constructs that surround individual channels. This is the main entry point to start, stop, read status, or otherwise manipulate a channel. In general, a channel is anything that records sonde data, stores it in the database, and keeps track of necessary accounting associated with the sonde. This can be thought of as nested routes, a master channel wrangler which can start, stop, reinit, pause channels, and the actual channels themselves that do all the work. Note that channels are identified by a number in the range 1..N, where N is the total number of configured channels.
Caching explicitly disabled
All data emitted from any GET routes located here has caching disabled purposefully due to the transient nature of everything emitted. GETs usually return status of some variety, and the status should be thought of as invalid the second it is received. Most of the state machines are retrieving data at multi-Hertz rates.
Action
Attempts creating and starting a channel listening on the specified frequency utilizing the passed UUID as the sounding UUID. If invalid, or invalid permissions, this just returns a 401 error. On creation errors (no free channels, invalid freq, or similar problems), a 406 status is returned with a basic human readable message. If successful, a 204 status is returned without any status messages
State Machinery
This interacts with the channel factory, which is responsible for opening, closing, and killing the active channels. Some errors are spawned from the factory, which detect invalid settings, and others may come from the actual channel instance. This process will block until the channel has been created, or an error returned.
Parameters
Parameter | Comments |
---|---|
uuid | Must be a valid UUID |
frequency | Must be between [400.02, 405.98] (inclusive) |
stream | Stream type. Currently types 1, 2, and 3 are supported |
Action
Attempt to terminate an active channel and run the post-drop routines
State Machinery
This interacts with the channel factory state machine. If the channel is not running, it immediately returns an error. If the channel is running, it will be stopped by the factory and then will call the postflight mechanism on the drop. After the channel has been closed, it can be immediately reused before the postflight completes.
Parameters
Parameter | Comments |
---|---|
cid | channel number to terminate |
Action
GETs will return a JSON object of various status bits related to the total number of channels available, currently active & inactive channels, as well as a list of any disabled channels.
Cache
HTTP Caching is explicitly disabled (no-cache)
Returned Parameters
Field | Value & Units |
---|---|
total | Total number of channels. Constant over the life of an ACS instance as you cannot on-the-fly add additional channels |
active | An array of the active data recording channels. If len(active) == total, no more channels are available |
disabled | An array of disabled data recording channels. A channel may be disabled and active. Disabled means the channel cannot be used for a new sounding, but disabling an active channel does not stop soundings currently occuring on that channel. |
inactive | An array of inactive data recording channels that are available for new soundings |
status | An array of status objects (see below for details). The len(status) should equal len(active). Each channel status is updated approximately 3 times a second, but are cached server side for efficiencys sake |
Optionally nil values
Almost all the fields in the status message associated with a channel may have null values, which means the data from the sonde is particularly mangled. The end user should assume that these values are NANs. JSON does not directly support NAN values, so null is used as a proxy.
Channel Factory Control
Routes under the /ops branch interacts with channel factory / wrangler which is responsible for managing the individual channels. Operations under this route perform tasks such as enabling / disabling channels, as well as attempting to forcibly reinitialize a channel (eg, hang up connection and redial into hardware).
Disabled & Active Channels
A disabled channel is one that cannot be used for recording new soundings. Disabling a currently active channel will not terminate the channel, nor will it intentionally drop data, nor will it affect its current operations. Disabled and enabled only refer to the ability to use this channel for new soundings.
Re-init'ing channels
Reiniting a channel should rarely ever be used. Channels naturally, once started, constantly attempt to maintain connections to the hardware. A Reinit will force the issue. There may be reasons to perform this operation but as a general rule, should be avoided and not done.
Attempt to enable the channel with ID cid for future use.
Attempt to disable the channel cid from future use. If a channel is currently in use, this will not inhibit current data collection, but it will keep the channel from being used until it has been enabled again. This will functionally limit the maximum number of channels that can be active at one time.
Attempt to re-init the channel cid. This hangs up opened connections and attempts to reconnect, lossing data while disconnected.
These are operations handled by the actual channels, and as such, actions taken are dependent on what the channel may choose to do.
Availability
These routes are only active when a channel is active. Once the channel has been stopped, or terminated, these routes become unavailable, and will immediately respond with a 503 error code.
Action
This will request the most recent channel status from the channel.
Performance
There is rarely a reason to do this directly. It is better to issue GET's on /channel (see above) which returns the status for all channels at once. There are performance hits for externally iterating across all channels. For example, do not do the following:
integer nchans = GET(/channel).total
for j = 1; j <= nchans; j++ {
ChannelStatus status = GET(/channel/$j)
#...do something with status
}
Action
Allows low-level command and control of the hardware behind a channel. These control word are entirely set by the actual channel implementer. These are expected to be used in more last-minute halt-the-hemorrhaging type scenarios rather than nominal operations.
Not a REST API
These operations are really stretching the assumptions of a REST API, so be cautious, aware of, and in the know of what will really happen - these are really hacky Async RPC over REST calls.
Targets
The control route ignores the value of target. There is only one target currently available, (the receiver).
Attempt to send a low level command to the hardware.
Retrieve a list of available low level commands that can be sent to the channel.
Allows low-level modification of various settings associated with a channel. These control word are entirely set by the actual channel implementer. Again, these are expected to be used in more last-minute halt-the-hemorrhaging type scenarios rather than nominal operations.
Action
Attempt to change a low level timer value. Non-empty JSON objects will be attempted to be altered.
Formatting
Key values should be in compressed time units in a format to akin to '12h32m10s500ms'
Unit | Meaning |
---|---|
h | hour(s) |
m | minute(s) |
s | second(s) |
ms | millisecond(s) |
us | microsecond(s) |
ns | nanoseconds(s) |
Caveats
Additional parameters will be ignored. If all the parameters provided were altered, then the operation will be considered successful. If any of the above fail, it is undetermined which parameters were altered.
Return a list of alterable settings along with their current values
Launcher Ops
General
The /launcher route handles incoming requests regarding the launcher, and actions surrounding the launcher. This interface support different types (manual, automated, etc) of launchers, but all respond to the following requests.
Unimplemented behavior
Every launcher instance will respond as given in this document, but not every launcher implements the behavior the route implies. For example, a manual launcher does not have a carriage, nor bins, so status bits related to bins are not emitted. A manual launcher is also unable to automatically load, so it returns a 405 error message. Generally speaking, if a launcher emits a 405 error, it means the launcher is uable to do the requested action.
State Machines
Many of the routes directly interact with state machines rather than actual hardware. This implies there is a slight delay between requesting an action, beginning the action on the hardware, and the final result of the actions.
Caching explicitly disabled
Much like in other routes, most of the data emitted from GETs is purposefully marked as non-cacheable due to the transient nature of everything emitted. GETs usually return status of some variety, and the status should be thought of as invalid the second it is received. Most of the state machines are retrieving data at multi-Hertz rates.
Much like the other /launcher handlers, this does not actually directly interact with the hardware, rather it interacts with the state machine that is constantly hunting for sondes. Provided that:
- A sonde has been found
- Metadata has been fully gathered
Accessing this this route with a frequency set to something within the range of [400.02:405.98] will initiate a recording channel at the specified frequency.
In the case of automated launchers, this route may be a no-op, since upon sonde detection the sonde is immediately initialized and a channel started. In this case, manually starting a channel through the launcher is not needed, and the normal state machine never lands upon the state that requires a frequency to start.
This aborts any sonde search state, and starts the search algorithm from the beginning state. Issuing this does not send commands to the hardware directly, but interrupts the state machine which does the actual searching for the sonde. Nothing is returned, and calling this multiple times will just interfere with finding any sondes that may be attached.
Request information about the current launcher, internal state, load/launch tallies, sonde detection status, metadata from the currently detected sonde, and overall capabilities of the launcher itself.
Storage Bin State
This route directly interacts with the state machine around the storage bins
Actions related to a sonde storage container bin
Conceptually thare is little that can be done with bins. They can be:
- loaded from - This is handled below, under the /load route
- disabled - configured to ignored during a load sequence
- enabled - configured to respond and be included in load sequences
- told how many sondes were loaded
This route covers the last 3 cases. All the routes in this section are fast as they only are fiddling bits or numbers in memory.
Indexing
{bin_id} is a zero-index count of bins in a launcher.
- Bin 0 is the first bin, and if enabled, will be depleted first
- Bin 3 is the fourth bin
- Bin N-1 is the Nth bin If you attempt to alter a bin that is greater than the actual number of bins, you will get a 404 error code.
If a bin is disabled, it will be enabled, and further GETs on the root /launcher route will reflect this change. This is idempotent, and does nothing if the requested bin is already enabled.
If a bin is enabled, it will be disabled, and further GETs on the root /launcher route will reflect this change. This is idempotent, and does nothing if the requested bin is already disabled.
This instructs the launcher about how many sondes were installed in a particular bin. If successful, GETs on the root /launcher route will immediately reflect this change.
Loading a Sonde
The routes described in this section provide a way to interact with loading sondes from a launcher.
Implementation Details & Considerations
Routes here will attempt to perform some sort of action, BUT, will functionally run in the background. Once it has been deduced that a command CAN be run with the current state of the launcher, a UUID that will be tagged to the actual low level commands will be created and returned instantly. What this means pragmatically is that responses coming from routes return quickly. Either they fail due to invalid state requirements, or a UUID for the commands to be sent is returned to the client. This UUID is also tagged into the optional field returned from GETs on the launcher root as loads.uuid.
This process is wrapped around a mutex, so if two users simultaneously issue the same request, the first request to be processed will succeed, and the second request will be ignored and be sent a return code.
Bin Selection
This will pick a sonde from the next bin that is enabled and has sondes, starting at 1.
Action
This route will attempt to load a sonde from a bin.
May be not implemented
If an operation is not supported, accessing this route will immediately return a 405 HTTP status code.
Immediate Failures
This will immediately return errors if any of the following are true:
- Sonde already in the launcher
- Launcher is not in the looking for sonde state
- No sondes are available, either because no bins have sonde, or the bins that contain sonde are not active
Assuming that the above conditions are met, this will return a structure that includes a valid flag if the command was sent, the issued timestamp, and a UUID to trace the command execution.
Action
This route will attempt to recover from a failed load
Not Implemented
This isn't implemented in the ACS anywhere, but is placeholder for future use
Launch a Sonde
The routes described in this section provide a way to interact with launching sondes.
Implementation Details & Considerations
Routes here will attempt to perform some sort of action, BUT, will functionally run in the background. Once it has been deduced that a command CAN be run with the current state of the launcher, a UUID that will be tagged to the actual low level commands will be created and returned instantly. What this means pragmatically is that responses coming from routes return quickly. Either they fail due to invalid state requirements, or a UUID for the commands to be sent is returned to the client. This UUID is also tagged into the optional field returned from GETs on the launcher root as loads.uuid.
This process is wrapped around a mutex, so if two users simultaneously issue the same request, the first request to be processed will succeed, and the second request will be ignored and be sent a return code.
Action
This route will attempt to load a sonde from a bin.
May be not implemented
If an operation is not supported, accessing this route will immediately return a 405 HTTP status code.
Immediate Failures
This will immediately return a 406 error if any of the following are true:
- Pilot Interlock is not Armed. Armed indicated the Pilot has OK'd the launch
- Sonde is NOT in the launcher
- Various State Parameters of the Launcher. These are highly dependent e.g.
- Motors in wrong places
- Mechanism not in proper state
- Launcher has not detected and properly intialized a sonde
Assuming that the above conditions are met, this will return a structure that includes a valid flag if the command was sent, the issued timestamp, and a UUID to trace the command execution.
Action
This route will attempt to recover from a failed launch command.
Most likely this attempts to get the launcher into a safe condition.
Not Implemented
This is not implemented on all launcher styles
Issue Arbitrary Commands
This route allows for low-level access to the underlying hardware. The user is actually interacting with state machines which eventually will issue commands. The functionality may not be implemented for particular launchers, and these commands should be used more in halt-the-hemorrhaging scenarios rather than nominal operations.
Targets
The control route accepts one of three targets from the low level command structure. If the launcher cannot send the command to the intended target, it will return with a 405 error immediately.
target= | End Device |
---|---|
snd | The radiosonde |
sndif | The sonde interface card |
lnchr | The launcher infrastructure |
Action
Attempt to send a low level command to the hardware.
Immediate rejection
If the requested command is not known, does not have the correct, missing, or too many args this function will immediately return a 400/Bad Request
Details
If a command is accepted, a UUID will be generated and immediately returned to the user. The user is reponsible to check the root ACS route /control for the final command status.
Retrieve a list of commands available to issue to the control side
Modify Settings
The settings route allows for alteration of a few operational parameters
The settings route allows for external control and query of various settings local to a launcher. The settings laid out in the following table are alterable and are presented with their meaning
JSON Key | Meaning |
---|---|
"min-battery" | This is minimal battery voltage to allow a sonde to emit before throwing error and refusing to activate it. |
"min-gps-svs" | This is the minimal number of satellites to allow before a quasi automated launcher will consider the sonde 'ready' |
"do-drop-heatcycle" | If true, this will perform the RH Regeneration before the sonde is launched |
"do-predrop-heatcycle" | If true, this will enable the RH regeneration during the flight |
"do-ephemeris" | If true, the launcher will attempt to upload ephemeris and almanac data to the sonde during the prepare stage |
"auto-terminate" | If > 0, the sonde will configured to terminate after this number of frames |
"prelaunch-power" | Allowed values are between 0-63. The per-launch power of the sonde will be set to this value |
"command-attempts" | Each command will be attempted this number of times before a failure is declared |
Alter specific setting(s) associated with a launcher to new values. Incoming json object MUST use known keys.
Retrieve a list of operationally alterable settings and their current values
Requesting Arbitrary Data
General
The /datastore routes interact with the underlaying datastore object, which holds all the data that the acs instance records. These routes provide a standard way to access any bit of data stored by acs. Data is usually represented as flat single-level structures which map nicely onto JSON objects, but this is not always the case. In some instances, the raw data is entirely hidden from direct and easy access, but regularized versions of the data is exposed. For example, there is no easy way to acess the raw data bits that represent an automated launcher's current state - instead a regular interface is exposed via /launcher. Although this is purposeful and intentional, the end user is not inhibited from manually accessing the low level bits, albieit there is no explicit description of what each parameter means. This is provided as a last ditch effort way to extract data without using the other more standard routes.
Writing Arbitrary Date
Currently there are no options to store arbitrary data. If there is enough interest, this could be added.
Speed & Performance
Although ACS strives to be performant, accessing many of these routes does do hard pulls on an underlying database which has performance implications. In order to alleviate these hits, the database based datastorer does attempt to cache, in memory, sounding and command data. This seems to be a reasonable tradeoff rather than relying only on database SELECTs.
HTTP Caching
Much of /datastore could be cached, but due to the changing values, most routes explicitly disable cashing. The notable exception is the /datastore/command routes which addings caching flags once a command has completed.
Although this is a NO-OP, nominally this could registering a particular format for insertion into the datastore.
Retrieve a JSON object that describes the internally stored data structures. This does update internally stored state and must be done at least once before attempting to access individual table data via sub-routes.
Request the status of any command that has been issued. Each command is individually tracked with a unique ID, and often times, different routes returns a UUID that must be checked against this route in order to check the completed status. Many of the command UUIDs returned by functions actually are "master" commands that may have multiple sub-commands. The easiest way to note these command is the response field is a comma-separated string of UUIDs, each of which was a child command. The error is nil if all the subcommands completed successfully, otherwise contains an error.
Retrieve a JSON object that describes the command status. If the command has completed, the result can be cached, and is marked accordingly.
Request data from the table described by {table}. This uses stored state to verify that the table does indeed exist. In order to refresh the internal state, access the parent's route via a GET.
Although not implemented, this is stubbed out to allow authorized users to insert arbitrary data into the table pointed to by the URI. It should be assumed that a rowid and createdat fields will be automatically added and will override any sort of datatype provided by the user.
Retrieves data from the table specified in the URI. Additionally, a set of variables to be extracted MUST be provided. Either row and/or nrows MUST be provided. Both row and nrows default to -2 if not provided, and work in conjunction with each other as described in the following table. * can be understood to mean any value.
nrow | nrows | Behavior |
---|---|---|
* | -1 | Fetch All Data |
-1 | * | Fetch Last Row |
* | n>0 | Fetch the last n rows |
n>0 | * | Fetch row n |
Metadata Extraction and Recording
ACS views any piece of information about a sounding as 'metadata' and most of it has a particular meaning. The /metadata
route allows one to retrieve or insert metadata about soundings, processes, or other useful tidbits about a sounding.
Predefined Values
Most metadata comes in a numerical form, and is defined by the documentation given on https://ncar.github.io/AVAPS-metadata, which is to say there is a systematic and intentional meaning. These pieces of data come in a key:value format where the key is a stringized integer value.
Freeform Values
The metadata structure is a map[string]string values, that is the key and value are both strings, where overlaping string keys are interpreted as the lastest copy is valid.
Retrieves a list of URI routes and parents. It should be noted that the number of rows may be greater than the number of keys. No keys are ever deleted nor alterered, so inserting multiple keys with the same or different values will render additional counts, but the same set of keys.
Work with metadata attached to parent. Usually this is a UUID or a string like "system" or "config". Data fields stored externally (via this API) will add new values to the database - you should have a record of what has changed
Insert key:value pair metadata into the datastore. If you insert multiple data points with the same key, they will all be stored in a time linear order, and will be unique. Functionally this will take any sort of JSON object and flatten it to a string:string key:value pair. Ideally, you should just provide the expected type for best results.
Retrieve key:value pairs metadata pieces attached to parent.
Sounding Data
Extract Sounding Data
The /soundings routes interact with extracting sounding data from the ACS instance. In some ways, it is a convenience wrapper around the more flexible /datastore route. You most likely what this route, not /datastore, for sonde data.
Caching explicitly disabled
All data emitted from any GET routes located here has caching disabled purposefully due to the transient nature of everything emitted. GETs usually return status of some variety, and the status should be thought of as invalid the second it is received. Most of the state machines are retrieving data at multi-Hertz rates.
Request data from a particular sounding
Retrieves data from a sounding with a particular UUID. As in other routes, row and nrows interact the manner described in the below table, but unlike other routes, variables may be omitted. Should variables be omitted, a default set of variables will be selected. The default set of variables may change with API versions, but is currently set to the following variables.
Variable | Variable | Variable | Variable |
---|---|---|---|
battery | chksum_eng | chksum_gps0 | chksum_gps1 |
chksum_gps2 | chksum_head | chksum_met | chksum_sensor |
framecount | gps_fix1 | gps_fix2 | gps_heading1 |
gps_heading2 | gps_latitude | gps_longitude | gps_msl_alt1 |
gps_msl_alt2 | gps_num_svs1 | gps_num_svs2 | gps_speed1 |
gps_speed2 | gps_vdown1 | gps_vdown2 | humidity |
internal_temp | launch_detect | pressure | sample_time |
sonde_id | stream_type | temperature | uuid |
Behavior
This route responds to one of the following query styles, which are mutually exclusive
- nrow && nrows queries - request data by row, or a number of rows
- since queries - request all data from a previous UTC timestamp
nrow and nrows behavior
This style query extract data by specified the rows you are interested in. Both nrow
and nrow
interact with the defined below behavior:
nrow | nrows | Behavior |
---|---|---|
* | -1 | Fetch All Data |
-1 | * | Fetch Last Row |
* | n>0 | Fetch the last n rows |
n>0 | * | Fetch row n |
since behavior
since
style queries attempt to pull all data from the database where the sampletime is greater than some queried timestamp. This is intended to be used by 'topping off' data by only requesting data that may have been recorded since a timestamp. The timestamp is the system clock of the ACS system, not the encoded time in a sounding.
Spectrum Sweep Data
This route provides access to periodic spectrum sweeps in the 400 to 406MHz frequency band. The returned structure is refreshed approximately every 6 seconds, and contains 3 different arrays reqpresenting a sweep. The values in each array are approximate power levels, in dBm from 400.00 to 406.00 MHz in ~200kHz steps, for a total of 299 individual points per array.
The "avg" array
The avg item is the average power level over the time frame determined by the references.speca.age
configuration parameter. Data older than references.speca.age
is expunged, and not used for this.
The "max" array
The max item is the maximal power level seen over the time frame determined by references.speca.age
. Data older than references.speca.age
is expunged, and not used for this.
The "current" array
This is the most recent sweep received. This may be an empty array if no sweep has been performed, or may not update if the hardware is not operational.
The "allowed" array
This is a list of allowable frequencies for transmission. The list is advisory only, as there is no attempt to prevent a user from selecting a frequency that is not on this list. This is controlled by the references.speca.band setting.
Time, as seen by the ACS daemon
Time Routes
The time routes allow user to query for basic timestamps realtime. All timestamps are in UTC, and nominally in the format of 'YYYY-mm-ddTHH:MM:SS.SSSZ'
Local-time
A GET on this route returns a time structure of the host computer ACS is running on. It does not affect the time of the remote ACS system.
Retrieve ACS's time (in UTC format).
This is very fast and does not block
NTP Time, as seen by the ACS daemon
Retrieve most recent NTP-ACS measurement
Requests ntp time and time delta information between the ACS instance and some configured NTP server. This value is always a ACS-cached value that is constantly updated by ACS on a pre-determined update rate. Requests should be fast
NTP & time skew
A GET on the /ntp sub-route returns a structure containing the time from a queried NTP structure and the server time ACS is running on, along with some simple flags users should use to help maintain clock accuracy. This is meant to be used to detect gross errors between a NTP server and the ACS's host system clock. This does not alter or mess with ACS's computer host's time
Retrieve a close estimate of the time delta between a NTP server and local time
Log Monitoring
Logging Infrastructure
This route provides users a way to actively extract log messages ACS has generated.
Buckets and Extraction
Logs are stored in named buckets. Currently, only one bucket is being utilized, but this could change in the future. The base route (this) only contains the number of logging items in each bucket. In order to retrieve a log message a user must directly fetch a log by its assigned ID number. Log messages are normally not exceedingly frequent, even in a debug environment. After fetching the logging buckets and messages from this route, users are then required to pull the logs one-at-a-time via /log/{bucket}/id.
Retrieve key:value pairs of the available logging buckets and number of messages.
Fetch A log message from a bucket
This route allows users to pull specific log messages out of the specified bucket. If the bucket doesn't exist, or ID is invalid, a 404 error will be returned with an empty body
Retrieve log values by ID from a bucket. Log values are not structured, can change without notice, and should not be machine parsed directly - they are meant for human operators to read.
User Interface Goodies
Helpful User Interface Parameters
This route serves out some basic parameters that users might want to use to improve user interface elements. This does include the currently logged in user, their role, other ACS users, and some parameters that might be useful to help users make decisions.
Mission => Sounding Table
Mission -> Sounding Lookup
This route requests a list of all soundings in an order sorted such that requesters can view which soundings belong to particular missions. Since ALL sounding data stored is available, this route exists to map soundings to a particular mission.
Command Info
Some action gave me a UUID...
This route allows you to look up command chains based on UUIDs. Many routes return a UUID, and little else, meaning the end user needs to check, if they care, the commands for a 'done' status. This route provides access to extract the full response of any command issued as part of the ACS daemon lifecycle. Any command sent to any subsection of ACS is logged and tagged with a UUID, however, not all commands have their UUIDs captured and stored.
Wrapped vs Unwrapped Commands
Often, as part of the normal command and control sequences, a large number of individual commands may be sent to fully configure, query, or modify the state of the hardware. This is most easily understood in context of a sonde - it must be instructed as to what frequency to tune to, GPS aiding information pushed to it, and other basic metadata read from it. Each of these events usually takes more than one command, and in order to track all of the commands, the individual steps are wrapped into a single 'master' command where the Response field is set to a comma separated list of UUIDs attached to the master. The master UUID is then recorded in appropriate places, so that all the sub commands can be retrieved.
Cache Considerations
Once the Completed
field is set to true, the values of the command will no longer change. The cache logic has not been set in the daemon, but would be simple to implement.
Export Data
Export Data
This route provides access to export raw data in a standard format. The data is a complete snapshot of what happened during a sounding, flight or mission.
Data Format
The exported data is in a binary format of encoded data specified in Dataformat
This route serves out some basic parameters that users might want to use to improve user interface elements. This does include the currently logged in user, their role, other ACS users, and some parameters that might be useful to help users make decisions.
Specifying the Format
This route does allow for specifing the desired output via a properly named #format URLfragments. The API is not stable, there is no way to discover what formats have been registered for, and the exact formats registered may changed depending software builds. Your best case is to just avoid specifiging the output and rely on the default behavior which will select the desired output on your behalf.
Download sounding, project, or flight data in a documented format.
query needs to be either a UUID of a sounding, a integer, or an empty string.
If query is an empty string, a complete snapshot of data up until now will be returned, but this is most likely not what you are interested in.
If query is convertable to a number (eg, "123", "5232", or similar) this will extract data associated with a particular instanceID of ACS. The instanceID is a random integer, and is not exposed via the REST API. Accessing the data in this manner will return a empty data file; accessing the data over the REST API in this manner is not supported.
If query is a UUID (like E93C4F38-6127-4432-9890-0C9CB66E22E0) then this will extract all the data associated with sounding specififed by the UUID. The data may be cached server side or may be extracted at the time of request - the only difference is that it may take longer to extract the data if not cached.
Caching
The returned data will be marked as Not Cachable unless a 200 status code is returned. In that case, the data will be explictly marked as "cachable" for browsers
Aircraft Data
Aircraft data
Although there is a very large number of different aircraft systems, each one maintains a slightly different aircraft data sample system, and emit slightly different data frames. This route returns data that has been decoded as IWGATDS1, and in the future, any other needed format.
IWGADTS
Most modern data systems emit IWGADTS1 packets over UDP transports.
Standards Body (IWGADTS)
IWGADTS (https://wiki.ucar.edu/display/iwgadts/Welcome+to+the+IWGADTS+Wiki) is a data format particular to research type aircraft where each message defines required, and optional variables. The format is a simple CSV format, but with most 'standards' there is room for interpretation. For the formal definition and meaning, and units of each of the IWGADTS1 fields, the standards body should be consulted.
Standards Deviation Management
IWGADTS1 isn't specific enough with what is to be in each field, so everyone does what is right in his own eyes: NCAR botches the timestamp, NOAA Add up to 73 extra fields, some with 'NONE' (rather than the standard mandated ',,') for missing value, NASA does some odd things with heights. The software under this routine is capable of undoing some of these errors if known a priori. As a way of warning, ACS understands the standard such that GPS_MSL_ALT should be altitude, and WGS84_ALT is a correction offset, not the corrected altitude. For this particular problem, the 3 aircraft I am directly aware of, the signature of each is:
Group | Data Signature |
---|---|
NCAR | GPS_MSL_ALT=height, WGS84_Alt=correction, but empty |
NOAA AOC | GPS_MSL_ALT=height, WGS84_Alt=correction |
NASA (GlobalHawk) | GPS_MSL_ALT=empty, WGS84_Alt=height |
ASCII Reference data
ACS allows the end user to configure parsing of free-running ASCII data streams. These sources are configured via a label, a connection string, and a regular expression for how to unpack data. Any parsed data will be available under a JSON key set by the label in the configuration. These labels are not controlled, nor enforced to be bounded. It is the responsibility of the end user to inspect the message for any sort of reference data.
GPS
Active GPS State
ACS requires access to some sort of GPS in order to properly function. The requirement is 2 fold: the GPS is used as a backup if the main 3rd party aircraft data systems fail, and as a source of GPS aiding information. The /gps route is mostly targeted as basic situational awareness - the end user needs a simple way to see that the ACS subsystems has a GPS lock.
Data
The data is marked as non-cacheable, and there is no ability to view previous data. All received GPS messages are stored in the database, and are available for discovery after the flight. No attempt is made within ACS to accommodate for dropped packets or missing data. If no new data is received for a long period, the last set of sampled data remains in the buffer
Monolithic State
Mega State Fetch
Now that you have spent some time working in the above routes, there is a simpler, what-is-acs-doing route: /api/{version}/state. The data presented on /state is a combination of data found on the following routes:
- /api/{version}/auto
- /api/{version}/channel
- /api/{version}/launcher
- /api/{version}/time
- /api/{version}/ntp
- /api/{version}/soundings
- /api/{version}/missions
- /api/{version}/speca
- /api/{version}/ui
- /api/{version}/acdata
- /api/{version}/gps
But bundled into a huge, 400kb message. It saves overhead on polling for 8 individual requests, and is executed by acs by accessing all the above routes using the credentials of the end user.
Rates
Some of the route, the soundings and missions data in particular, perform actual database pulls, so this route may take some time to respond and send data, on the order of 400ms or more. Additionally, the contents of this message may be cached server side, so polling frequently may not be advantageous anyways. Practically speaking, you should be able to poll this message every 1s or so without ill effects, which is fast enough for most use cases. If you need a faster rate, go ahead and directly poll the proper route rather than this.
Shutdown ACS Instance
Stats for Nerds
These are included for completeness for sanity. These are debugging access that shouldn't be used unless NCAR deems useful. These may work, break things, or set your computer on fire.
This is mostly for debugging purposes - It returns some general counter information about the REST operations the ACS daemon has performed.
Application monitoring. Not useful to you.