JaiaBot 2.6.0+14+g3cab9c46
JaiaBot micro-AUV software
 
Loading...
Searching...
No Matches
rest_api.proto
Go to the documentation of this file.
1syntax = "proto2";
2
3import "jaiabot/messages/jaia_dccl.proto";
4import "jaiabot/messages/hub.proto";
5import "jaiabot/messages/metadata.proto";
6import "jaiabot/messages/option_extensions.proto";
7import "jaiabot/messages/mission.proto";
8
9package jaiabot.protobuf;
10
11message TaskPacketQuery
12{
13 optional uint64 start_time = 1
14 [(jaia.field).rest_api = {
15 doc: "Start of time range as a Unix timestamp in microseconds. If not set, returns an open-ended search, starting from the earliest available data."
16 }];
17 optional uint64 end_time = 2
18 [(jaia.field).rest_api = {
19 doc: "End of time range as a Unix timestamp in microseconds. If not set, returns an open-ended search, ending at the latest available data."
20 }];
21 repeated string mission_name = 4
22 [(jaia.field).rest_api = {
23 doc: "If set, only return task packets associated with the given mission name(s)."
24 }];
25 optional bool included_only = 3
26 [default = true, (jaia.field).rest_api = {
27 presence: GUARANTEED,
28 doc: "Whether to only return included (non-excluded) task packets."
29 }];
30
31 enum Format {
32 JSON = 0 [(jaia.ev).rest_api = { presence: GUARANTEED }];
33 KMZ = 1 [(jaia.ev).rest_api = { presence: GUARANTEED }];
34 CSV = 2 [(jaia.ev).rest_api = { presence: GUARANTEED }];
35 GEOJSON_CONTOURS = 3 [(jaia.ev).rest_api = { presence: GUARANTEED }];
36 }
37
38 optional Format format = 16 [default = JSON, (jaia.field).rest_api.presence = GUARANTEED];
39}
40
41message TaskPacketQueryResults
42{
43 repeated TaskPacket packets = 1
44 [(jaia.field).rest_api.presence = GUARANTEED];
45}
46
47message MissionQuery
48{
49 optional uint64 start_time = 1
50 [(jaia.field).rest_api = {
51 doc: "Start of time range as a Unix timestamp in microseconds. If not set, returns an open-ended search, starting from the earliest available data."
52 }];
53 optional uint64 end_time = 2
54 [(jaia.field).rest_api = {
55 doc: "End of time range as a Unix timestamp in microseconds. If not set, returns an open-ended search, ending at the latest available data."
56 }];
57}
58
59message MissionQueryResults
60{
61 repeated MissionSummary mission_summaries = 1
62 [(jaia.field).rest_api.presence = GUARANTEED];
63}
64
65
66message CommandResult
67{
68 required bool command_sent = 1
69 [(jaia.field).rest_api.presence = GUARANTEED];
70}
71
72enum APIErrorCode
73{
74 // REST API URL errors
75 API_ERROR__UNSUPPORTED_API_VERSION = 1
76 [(jaia.ev).rest_api.presence = GUARANTEED];
77 API_ERROR__INVALID_ACTION = 2 [(jaia.ev).rest_api.presence = GUARANTEED];
78 API_ERROR__TARGETS_STRING_MALFORMATTED = 3
79 [(jaia.ev).rest_api.presence = GUARANTEED];
80 API_ERROR__ACTION_REQUIRES_JSON_POST_DATA = 4
81 [(jaia.ev).rest_api.presence = GUARANTEED];
82 API_ERROR__INVALID_TARGET = 5 [(jaia.ev).rest_api.presence = GUARANTEED];
83
84 // Parse errors
85 API_ERROR__COULD_NOT_PARSE_API_REQUEST_JSON = 10
86 [(jaia.ev).rest_api.presence = GUARANTEED];
87
88 // Missing fields
89 API_ERROR__REQUEST_NOT_INITIALIZED = 11
90 [(jaia.ev).rest_api.presence = GUARANTEED];
91 API_ERROR__NO_ACTION_SPECIFIED = 12
92 [(jaia.ev).rest_api.presence = GUARANTEED];
93
94 API_ERROR__INVALID_TYPE = 13 [(jaia.ev).rest_api.presence = GUARANTEED];
95
96 // Unimplemented
97 API_ERROR__NOT_IMPLEMENTED = 20;
98}
99
100message APIError
101{
102 required APIErrorCode code = 1
103 [(jaia.field).rest_api.presence = GUARANTEED];
104 optional string details = 2 [(jaia.field).rest_api.presence = GUARANTEED];
105}
106
107message APIRequest
108{
109 message Nodes
110 {
111 repeated int32 hubs = 1 [(jaia.field).rest_api.presence = GUARANTEED];
112 repeated int32 bots = 2 [(jaia.field).rest_api.presence = GUARANTEED];
113 optional bool all = 3
114 [default = false, (jaia.field).rest_api.presence = GUARANTEED];
115 }
116 required Nodes target = 1 [(jaia.field).rest_api.presence = GUARANTEED];
117 optional string api_key = 2 [(jaia.field).rest_api.presence = GUARANTEED];
118
119 oneof action
120 {
121 bool status = 11 [(jaia.field).rest_api = {
122 presence: GUARANTEED,
123 doc: "Query the status of bots/hubs. Expect a response of type 'status'."
124 example {
125 request: '{"api_key": "4vS6s2jnulxVjrKSB-__tQ", "status": true, "target": {"all": true}}'
126 response: '{"request":{"status":true,"target":{"all":true}},"status":{"bots":[{"attitude":{"course_over_ground":180.0,"heading":166.0,"pitch":85.0,"roll":-57.0},"battery_percent":95.0,"bot_id":1,"bot_type":"HYDRO","calibration_status":3,"depth":0.0,"hdop":0.25,"health_state":"HEALTH__OK","location":{"lat":41.657645,"lon":-71.27212},"mission_state":"PRE_DEPLOYMENT__IDLE","pdop":2.07,"received_time":"1722893284636801","salinity":20.0,"speed":{"over_ground":0.0},"temperature":15.06,"time":"1722878885000000","vcc_voltage":24.0,"wifi_link_quality_percentage":100},{"attitude":{"course_over_ground":180.0,"heading":166.0,"pitch":85.0,"roll":-57.0},"battery_percent":95.0,"bot_id":2,"bot_type":"HYDRO","calibration_status":3,"depth":0.0,"hdop":1.03,"health_state":"HEALTH__OK","location":{"lat":41.65765,"lon":-71.27212},"mission_state":"PRE_DEPLOYMENT__IDLE","pdop":1.47,"received_time":"1722893284635458","salinity":20.0,"speed":{"over_ground":0.0},"temperature":15.04,"time":"1722878885000000","vcc_voltage":24.0,"wifi_link_quality_percentage":100}],"hubs":[{"bot_ids_in_radio_file":[1,2],"fleet_id":0,"health_state":"HEALTH__OK","hub_id":1,"known_bot": [{"id": 1, "last_status_time": "1722893284000000"}, {"id": 2, "last_status_time": "1722893285000000"}],"linux_hardware_status":{"wifi":{"is_connected":true,"link_quality":70,"link_quality_percentage":100,"noise_level":0,"signal_level":33}},"location":{"lat":41.66268,"lon":-71.273018},"received_time":"1722893284552504","time":"8614394422756020"}]},"target":{"bots":[1,2],"hubs":[1]}}'
127 }
128 }];
129 bool metadata = 12 [(jaia.field).rest_api = {
130 presence: GUARANTEED,
131 doc: "Query the metadata of the hub. Expect a response of type 'metadata'."
132 example {
133 request: '{ "target": {"all": true },"metadata": true, "api_key": "4vS6s2jnulxVjrKSB-__tQ"}'
134 response: '{"metadata": {"hubs": [{"goby_version": "3.1.5", "intervehicle_api_version": 7, "is_simulation": true, "ivp_version": "19.8.1+svn9395-10~ubuntu20.04.1", "jaiabot_image_build_date": "Thu Aug 15 16:20:53 UTC 2024", "jaiabot_image_first_boot_date": "Thu Aug 15 13:50:13 UTC 2024", "jaiabot_image_version": "1.12.0~beta2", "jaiabot_version": {"deb_release_branch": "1.y", "deb_repository": "beta", "major": "1", "minor": "12", "patch": "0~beta2"}, "moos_version": "10.4.0", "name": "hub2-fleet6", "raspi_firmware_version": "1.20220331", "xbee_node_id": "Not Available", "xbee_serial_number": "Not Available"}, {"goby_version": "3.1.5", "intervehicle_api_version": 7, "is_simulation": true, "ivp_version": "19.8.1+svn9395-10~ubuntu20.04.1", "jaiabot_image_build_date": "Thu Aug 15 16:20:53 UTC 2024", "jaiabot_image_first_boot_date": "Thu Aug 15 13:50:11 UTC 2024", "jaiabot_image_version": "1.12.0~beta2", "jaiabot_version": {"deb_release_branch": "1.y", "deb_repository": "beta", "major": "1", "minor": "12", "patch": "0~beta2"}, "moos_version": "10.4.0", "name": "hub1-fleet6", "raspi_firmware_version": "1.20220331", "xbee_node_id": "Not Available", "xbee_serial_number": "Not Available"}]}, "request": {"api_key": "", "metadata": true, "target": {"all": true}}, "target": {"hubs": [2, 1]}}'
135 }
136 }];
137 TaskPacketQuery task_packets = 13 [(jaia.field).rest_api = {
138 presence: GUARANTEED,
139 doc: "Query task packets from a given range of time. Expect a response of type 'task_packets'."
140 example {
141 request: '{"target": {"bots": [1]}, "task_packets": {"start_time": 1722797666581176.0, "end_time": 1722970466581176.0}, "api_key": "4vS6s2jnulxVjrKSB-__tQ"}'
142 response: '{"request": {"api_key": "4vS6s2jnulxVjrKSB-__tQ", "target": {"bots": [1]}, "task_packets": {"end_time": "1722970466581176", "start_time": "1722797666581176"}}, "task_packets": {"packets": [{"bot_id": 1, "drift": {"drift_duration": 10, "end_location": {"lat": 41.658228, "lon": -71.275736}, "estimated_drift": {"heading": 237.0, "speed": 0.9}, "significant_wave_height": 0.0, "start_location": {"lat": 41.658275, "lon": -71.275645}}, "end_time": "1722895675000000", "start_time": "1722895664000000", "type": "SURFACE_DRIFT"}, {"bot_id": 1, "drift": {"drift_duration": 10, "end_location": {"lat": 41.65826, "lon": -71.2757}, "estimated_drift": {"heading": 316.0, "speed": 0.6}, "significant_wave_height": 0.0, "start_location": {"lat": 41.658225, "lon": -71.275651}}, "end_time": "1722896712000000", "start_time": "1722896702000000", "type": "SURFACE_DRIFT"}, {"bot_id": 1, "drift": {"drift_duration": 10, "end_location": {"lat": 41.659469, "lon": -71.272064}, "estimated_drift": {"heading": 72.0, "speed": 0.7}, "significant_wave_height": 0.0, "start_location": {"lat": 41.659448, "lon": -71.272146}}, "end_time": "1722896904000000", "start_time": "1722896893000000", "type": "SURFACE_DRIFT"}]}}'
143 }
144 }];
145 MissionQuery missions = 16 [(jaia.field).rest_api = {
146 presence: GUARANTEED,
147 doc: "Query missions from a given range of time. Expect a response of type 'missions'."
148 example {
149 request: '{"target": {"all": true}, "missions": {"start_time": 1722797666581176.0, "end_time": 1722970466581176.0}, "api_key": "4vS6s2jnulxVjrKSB-__tQ"}'
150 response: '{"missions": {"mission_summaries": [{"end_time": "1722896904000000", "mission_name": "mission1", "start_time": "1722895664000000", "task_packet_count": 3}]}, "request": {"api_key": "4vS6s2jnulxVjrKSB-__tQ", "missions": {"end_time": "1722970466581176", "start_time": "1722797666581176"}, "target": {"all": true}}, "target": {"hubs": [1], "bots": [1]}}'
151 }
152 }];
153 Command command = 14 [(jaia.field).rest_api = {
154 presence: GUARANTEED,
155 doc: "Send a command to one or more bots. Expect a response of type 'command_result'."
156 example {
157 request: '{"target": {"all": true}, "command": {"type": "STOP"}, "api_key": "4vS6s2jnulxVjrKSB-__tQ"}'
158 response: '{"command_result": {"command_sent": true}, "request": {"api_key": "4vS6s2jnulxVjrKSB-__tQ", "command": {"bot_id": 1, "time": "1722895468966813", "type": "STOP"}, "target": {"all": true}}, "target": {"hubs": [1], "bots": [2, 1]}}'
159 }
160 }];
161 CommandForHub command_for_hub = 15 [(jaia.field).rest_api = {
162 presence: GUARANTEED,
163 doc: "Send a command to the hub. Expect a response of type 'command_result'."
164 example {
165 request: '{"target": {"all": true}, "command_for_hub": {"type": "SET_HUB_LOCATION", "hub_location": {"lat": 41.7, "lon": -70.3}}, "api_key": "4vS6s2jnulxVjrKSB-__tQ"}'
166 response: '{"command_result": {"command_sent": true}, "request": {"api_key": "4vS6s2jnulxVjrKSB-__tQ", "command_for_hub": {"hub_id": 1, "hub_location": {"lat": 41.7, "lon": -70.3}, "time": "1722895686821358", "type": "SET_HUB_LOCATION"}, "target": {"all": true}}, "target": {"hubs": [1]}}'
167 }
168 }];
169 }
170}
171
172message APIResponse
173{
174 message Nodes
175 {
176 repeated int32 hubs = 1 [(jaia.field).rest_api.presence = GUARANTEED];
177 repeated int32 bots = 2 [(jaia.field).rest_api.presence = GUARANTEED];
178 }
179 optional Nodes target = 1 [(jaia.field).rest_api.presence = GUARANTEED];
180 message Statuses
181 {
182 repeated BotStatus bots = 1
183 [(jaia.field).rest_api.presence = GUARANTEED];
184 repeated HubStatus hubs = 2
185 [(jaia.field).rest_api.presence = GUARANTEED];
186 }
187
188 message Metadatas
189 {
190 repeated DeviceMetadata hubs = 1
191 [(jaia.field).rest_api.presence = GUARANTEED];
192 }
193
194 oneof action
195 {
196 APIError error = 10 [(jaia.field).rest_api = {
197 presence: GUARANTEED,
198 doc: "Error with API Request. This can be sent in response to any failed Request action."
199 }];
200 Statuses status = 11 [(jaia.field).rest_api = {
201 presence: GUARANTEED,
202 doc: "Bot/Hub status. This is sent in response to a successful Request 'status' action."
203 }];
204 Metadatas metadata = 12 [(jaia.field).rest_api = {
205 presence: GUARANTEED,
206 doc: "Metadata response. This is sent in response to a successful Request 'metadata' action."
207 }];
208 TaskPacketQueryResults task_packets = 13 [(jaia.field).rest_api = {
209 presence: GUARANTEED,
210 doc: "Task packet response. This is sent in response to a successful Request 'task_packets' action."
211 }];
212 MissionQueryResults missions = 15 [(jaia.field).rest_api = {
213 presence: GUARANTEED,
214 doc: "Mission query response. This is sent in response to a successful Request 'missions' action."
215 }];
216 CommandResult command_result = 14 [(jaia.field).rest_api = {
217 presence: GUARANTEED,
218 doc: "Command result. This is sent in response to a successful Request 'command' or 'command_for_hub' action."
219 }];
220 }
221
222 // copy of original request
223 required APIRequest request = 20
224 [(jaia.field).rest_api = { presence: GUARANTEED }];
225}
226
227message APIConfig
228{
229 message StreamingEndpoint
230 {
231 required int32 hub_id = 1;
232 required string hostname = 2;
233 required int32 port = 3;
234 }
235
236 repeated StreamingEndpoint streaming_endpoint = 1;
237
238 optional int32 flask_bind_port = 2 [default = 9092];
239
240 // set true if no API key is required
241 optional bool no_key_required = 3 [default = false];
242
243 message APIKey
244 {
245 required string private_key = 1;
246
247 enum Permission
248 {
249 ALL = 0 [(jaia.ev).rest_api = {
250 permitted_action: [
251 'status',
252 'metadata',
253 'task_packets',
254 'missions',
255 'command',
256 'command_for_hub'
257 ]
258 }];
259 READ = 1 [(jaia.ev).rest_api = {
260 permitted_action: [ 'status', 'metadata', 'task_packets', 'missions' ]
261 }];
262 WRITE = 2 [(jaia.ev).rest_api = {
263 permitted_action: [ 'command', 'command_for_hub' ]
264 }];
265 STATUS = 3
266 [(jaia.ev).rest_api = { permitted_action: [ 'status' ] }];
267 METADATA = 4
268 [(jaia.ev).rest_api = { permitted_action: [ 'metadata' ] }];
269 TASK_PACKETS = 5
270 [(jaia.ev).rest_api = { permitted_action: [ 'task_packets' ] }];
271 MISSIONS = 8
272 [(jaia.ev).rest_api = { permitted_action: [ 'missions' ] }];
273 COMMAND = 6
274 [(jaia.ev).rest_api = { permitted_action: [ 'command' ] }];
275 COMMAND_FOR_HUB = 7 [
276 (jaia.ev).rest_api = { permitted_action: [ 'command_for_hub' ] }
277 ];
278 }
279
280 repeated Permission permission = 2;
281 }
282 repeated APIKey key = 4;
283}