isar 1.20.2__py3-none-any.whl → 1.34.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- isar/apis/api.py +148 -76
- isar/apis/models/__init__.py +0 -1
- isar/apis/models/models.py +21 -11
- isar/apis/models/start_mission_definition.py +110 -168
- isar/apis/robot_control/robot_controller.py +41 -0
- isar/apis/schedule/scheduling_controller.py +124 -162
- isar/apis/security/authentication.py +5 -5
- isar/config/certs/ca-cert.pem +33 -31
- isar/config/keyvault/keyvault_service.py +1 -1
- isar/config/log.py +45 -40
- isar/config/logging.conf +16 -31
- isar/config/open_telemetry.py +102 -0
- isar/config/predefined_mission_definition/default_exr.json +0 -2
- isar/config/predefined_mission_definition/default_mission.json +1 -5
- isar/config/predefined_mission_definition/default_turtlebot.json +4 -11
- isar/config/predefined_missions/default.json +67 -87
- isar/config/predefined_missions/default_extra_capabilities.json +107 -0
- isar/config/settings.py +76 -111
- isar/eventhandlers/eventhandler.py +123 -0
- isar/mission_planner/local_planner.py +6 -20
- isar/mission_planner/mission_planner_interface.py +1 -1
- isar/models/events.py +184 -0
- isar/models/status.py +18 -0
- isar/modules.py +118 -199
- isar/robot/robot.py +377 -0
- isar/robot/robot_battery.py +60 -0
- isar/robot/robot_monitor_mission.py +357 -0
- isar/robot/robot_pause_mission.py +74 -0
- isar/robot/robot_resume_mission.py +67 -0
- isar/robot/robot_start_mission.py +66 -0
- isar/robot/robot_status.py +61 -0
- isar/robot/robot_stop_mission.py +68 -0
- isar/robot/robot_upload_inspection.py +75 -0
- isar/script.py +57 -40
- isar/services/service_connections/mqtt/mqtt_client.py +47 -11
- isar/services/service_connections/mqtt/robot_heartbeat_publisher.py +5 -2
- isar/services/service_connections/mqtt/robot_info_publisher.py +3 -3
- isar/services/service_connections/persistent_memory.py +69 -0
- isar/services/utilities/mqtt_utilities.py +93 -0
- isar/services/utilities/robot_utilities.py +20 -0
- isar/services/utilities/scheduling_utilities.py +393 -65
- isar/state_machine/state_machine.py +219 -538
- isar/state_machine/states/__init__.py +0 -8
- isar/state_machine/states/await_next_mission.py +114 -0
- isar/state_machine/states/blocked_protective_stop.py +60 -0
- isar/state_machine/states/going_to_lockdown.py +95 -0
- isar/state_machine/states/going_to_recharging.py +92 -0
- isar/state_machine/states/home.py +115 -0
- isar/state_machine/states/intervention_needed.py +77 -0
- isar/state_machine/states/lockdown.py +38 -0
- isar/state_machine/states/maintenance.py +36 -0
- isar/state_machine/states/monitor.py +137 -247
- isar/state_machine/states/offline.py +51 -53
- isar/state_machine/states/paused.py +92 -23
- isar/state_machine/states/pausing.py +48 -0
- isar/state_machine/states/pausing_return_home.py +48 -0
- isar/state_machine/states/recharging.py +80 -0
- isar/state_machine/states/resuming.py +57 -0
- isar/state_machine/states/resuming_return_home.py +64 -0
- isar/state_machine/states/return_home_paused.py +109 -0
- isar/state_machine/states/returning_home.py +217 -0
- isar/state_machine/states/stopping.py +61 -0
- isar/state_machine/states/stopping_due_to_maintenance.py +61 -0
- isar/state_machine/states/stopping_go_to_lockdown.py +60 -0
- isar/state_machine/states/stopping_go_to_recharge.py +51 -0
- isar/state_machine/states/stopping_return_home.py +77 -0
- isar/state_machine/states/unknown_status.py +72 -0
- isar/state_machine/states_enum.py +21 -5
- isar/state_machine/transitions/mission.py +192 -0
- isar/state_machine/transitions/return_home.py +106 -0
- isar/state_machine/transitions/robot_status.py +80 -0
- isar/state_machine/utils/common_event_handlers.py +73 -0
- isar/storage/blob_storage.py +70 -52
- isar/storage/local_storage.py +25 -12
- isar/storage/storage_interface.py +28 -7
- isar/storage/uploader.py +174 -55
- isar/storage/utilities.py +32 -29
- {isar-1.20.2.dist-info → isar-1.34.9.dist-info}/METADATA +73 -110
- isar-1.34.9.dist-info/RECORD +135 -0
- {isar-1.20.2.dist-info → isar-1.34.9.dist-info}/WHEEL +1 -1
- {isar-1.20.2.dist-info → isar-1.34.9.dist-info}/entry_points.txt +1 -0
- robot_interface/models/exceptions/robot_exceptions.py +91 -41
- robot_interface/models/initialize/__init__.py +0 -1
- robot_interface/models/inspection/__init__.py +0 -13
- robot_interface/models/inspection/inspection.py +42 -33
- robot_interface/models/mission/mission.py +14 -15
- robot_interface/models/mission/status.py +20 -26
- robot_interface/models/mission/task.py +154 -121
- robot_interface/models/robots/battery_state.py +6 -0
- robot_interface/models/robots/media.py +13 -0
- robot_interface/models/robots/robot_model.py +7 -7
- robot_interface/robot_interface.py +119 -84
- robot_interface/telemetry/mqtt_client.py +74 -12
- robot_interface/telemetry/payloads.py +91 -13
- robot_interface/utilities/json_service.py +7 -1
- isar/config/predefined_missions/default_turtlebot.json +0 -110
- isar/config/predefined_poses/__init__.py +0 -0
- isar/config/predefined_poses/predefined_poses.py +0 -616
- isar/config/settings.env +0 -25
- isar/mission_planner/sequential_task_selector.py +0 -23
- isar/mission_planner/task_selector_interface.py +0 -31
- isar/models/communication/__init__.py +0 -0
- isar/models/communication/message.py +0 -12
- isar/models/communication/queues/__init__.py +0 -4
- isar/models/communication/queues/queue_io.py +0 -12
- isar/models/communication/queues/queue_timeout_error.py +0 -2
- isar/models/communication/queues/queues.py +0 -19
- isar/models/communication/queues/status_queue.py +0 -20
- isar/models/mission_metadata/__init__.py +0 -0
- isar/services/readers/__init__.py +0 -0
- isar/services/readers/base_reader.py +0 -37
- isar/services/service_connections/stid/__init__.py +0 -0
- isar/services/utilities/queue_utilities.py +0 -39
- isar/state_machine/states/idle.py +0 -85
- isar/state_machine/states/initialize.py +0 -71
- isar/state_machine/states/initiate.py +0 -142
- isar/state_machine/states/off.py +0 -18
- isar/state_machine/states/stop.py +0 -95
- isar/storage/slimm_storage.py +0 -191
- isar-1.20.2.dist-info/RECORD +0 -116
- robot_interface/models/initialize/initialize_params.py +0 -9
- robot_interface/models/mission/step.py +0 -234
- {isar-1.20.2.dist-info → isar-1.34.9.dist-info/licenses}/LICENSE +0 -0
- {isar-1.20.2.dist-info → isar-1.34.9.dist-info}/top_level.txt +0 -0
isar/apis/api.py
CHANGED
|
@@ -1,65 +1,70 @@
|
|
|
1
|
+
import json
|
|
1
2
|
import logging
|
|
3
|
+
import time
|
|
4
|
+
from datetime import datetime, timezone
|
|
2
5
|
from http import HTTPStatus
|
|
3
6
|
from logging import Logger
|
|
4
7
|
from typing import List, Union
|
|
5
8
|
|
|
6
9
|
import click
|
|
7
10
|
import uvicorn
|
|
8
|
-
from fastapi import FastAPI,
|
|
11
|
+
from fastapi import FastAPI, Security
|
|
9
12
|
from fastapi.middleware.cors import CORSMiddleware
|
|
10
13
|
from fastapi.routing import APIRouter
|
|
11
|
-
from injector import inject
|
|
12
|
-
from opencensus.ext.azure.trace_exporter import AzureExporter
|
|
13
|
-
from opencensus.trace.attributes_helper import COMMON_ATTRIBUTES
|
|
14
|
-
from opencensus.trace.samplers import ProbabilitySampler
|
|
15
|
-
from opencensus.trace.span import SpanKind
|
|
16
|
-
from opencensus.trace.tracer import Tracer
|
|
17
14
|
from pydantic import AnyHttpUrl
|
|
18
15
|
|
|
19
16
|
from isar.apis.models.models import ControlMissionResponse, StartMissionResponse
|
|
17
|
+
from isar.apis.robot_control.robot_controller import RobotController
|
|
20
18
|
from isar.apis.schedule.scheduling_controller import SchedulingController
|
|
21
19
|
from isar.apis.security.authentication import Authenticator
|
|
22
|
-
from isar.config.configuration_error import ConfigurationError
|
|
23
|
-
from isar.config.keyvault.keyvault_error import KeyvaultError
|
|
24
20
|
from isar.config.keyvault.keyvault_service import Keyvault
|
|
25
21
|
from isar.config.settings import settings
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
from robot_interface.telemetry.mqtt_client import MqttClientInterface
|
|
23
|
+
from robot_interface.telemetry.payloads import StartUpMessagePayload
|
|
24
|
+
from robot_interface.utilities.json_service import EnhancedJSONEncoder
|
|
29
25
|
|
|
30
26
|
|
|
31
27
|
class API:
|
|
32
|
-
@inject
|
|
33
28
|
def __init__(
|
|
34
29
|
self,
|
|
35
30
|
authenticator: Authenticator,
|
|
36
31
|
scheduling_controller: SchedulingController,
|
|
37
|
-
|
|
32
|
+
robot_controller: RobotController,
|
|
33
|
+
keyvault: Keyvault,
|
|
34
|
+
mqtt_publisher: MqttClientInterface,
|
|
38
35
|
port: int = settings.API_PORT,
|
|
39
|
-
azure_ai_logging_enabled: bool = settings.LOG_HANDLER_APPLICATION_INSIGHTS_ENABLED,
|
|
40
36
|
) -> None:
|
|
41
37
|
self.authenticator: Authenticator = authenticator
|
|
42
38
|
self.scheduling_controller: SchedulingController = scheduling_controller
|
|
43
|
-
self.
|
|
39
|
+
self.robot_controller: RobotController = robot_controller
|
|
40
|
+
self.keyvault: Keyvault = keyvault
|
|
44
41
|
self.host: str = "0.0.0.0" # Locking uvicorn to use 0.0.0.0
|
|
45
42
|
self.port: int = port
|
|
46
|
-
self.
|
|
43
|
+
self.mqtt_publisher: MqttClientInterface = mqtt_publisher
|
|
47
44
|
|
|
48
45
|
self.logger: Logger = logging.getLogger("api")
|
|
49
46
|
|
|
50
47
|
self.app: FastAPI = self._create_app()
|
|
48
|
+
self.server = self._setup_server()
|
|
51
49
|
|
|
52
50
|
def get_app(self) -> FastAPI:
|
|
53
51
|
return self.app
|
|
54
52
|
|
|
55
|
-
def
|
|
56
|
-
uvicorn.
|
|
53
|
+
def _setup_server(self) -> uvicorn.Server:
|
|
54
|
+
config = uvicorn.Config(
|
|
57
55
|
self.app,
|
|
58
56
|
port=self.port,
|
|
59
57
|
host=self.host,
|
|
60
58
|
reload=False,
|
|
61
59
|
log_config=None,
|
|
62
60
|
)
|
|
61
|
+
return uvicorn.Server(config)
|
|
62
|
+
|
|
63
|
+
def wait_for_api_server_ready(self) -> None:
|
|
64
|
+
while not self.server.started:
|
|
65
|
+
time.sleep(0.01)
|
|
66
|
+
self.logger.info("Uvicorn server has been started")
|
|
67
|
+
self._publish_startup_message()
|
|
63
68
|
|
|
64
69
|
def _create_app(self) -> FastAPI:
|
|
65
70
|
tags_metadata = [
|
|
@@ -70,7 +75,10 @@ class API:
|
|
|
70
75
|
]
|
|
71
76
|
app = FastAPI(
|
|
72
77
|
openapi_tags=tags_metadata,
|
|
73
|
-
on_startup=[
|
|
78
|
+
on_startup=[
|
|
79
|
+
self.authenticator.load_config,
|
|
80
|
+
self._log_startup_message,
|
|
81
|
+
],
|
|
74
82
|
swagger_ui_oauth2_redirect_url="/oauth2-redirect",
|
|
75
83
|
swagger_ui_init_oauth={
|
|
76
84
|
"usePkceWithAuthorizationCodeGrant": True,
|
|
@@ -91,13 +99,12 @@ class API:
|
|
|
91
99
|
allow_headers=["*"],
|
|
92
100
|
)
|
|
93
101
|
|
|
94
|
-
if self.azure_ai_logging_enabled:
|
|
95
|
-
self._add_request_logging_middleware(app)
|
|
96
|
-
|
|
97
102
|
app.include_router(router=self._create_scheduler_router())
|
|
98
103
|
|
|
99
104
|
app.include_router(router=self._create_info_router())
|
|
100
105
|
|
|
106
|
+
app.include_router(router=self._create_media_control_router())
|
|
107
|
+
|
|
101
108
|
return app
|
|
102
109
|
|
|
103
110
|
def _create_scheduler_router(self) -> APIRouter:
|
|
@@ -145,6 +152,31 @@ class API:
|
|
|
145
152
|
HTTPStatus.CONFLICT.value: {
|
|
146
153
|
"description": "Conflict - Invalid command in the current state",
|
|
147
154
|
},
|
|
155
|
+
HTTPStatus.BAD_REQUEST.value: {
|
|
156
|
+
"description": "Bad request - Robot does not have the capabilities to perform the mission",
|
|
157
|
+
},
|
|
158
|
+
HTTPStatus.INTERNAL_SERVER_ERROR.value: {
|
|
159
|
+
"description": "Internal Server Error - Current state of state machine unknown",
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
)
|
|
163
|
+
router.add_api_route(
|
|
164
|
+
path="/schedule/return-home",
|
|
165
|
+
endpoint=self.scheduling_controller.return_home,
|
|
166
|
+
methods=["POST"],
|
|
167
|
+
dependencies=[authentication_dependency],
|
|
168
|
+
summary="Start return home mission",
|
|
169
|
+
responses={
|
|
170
|
+
HTTPStatus.OK.value: {
|
|
171
|
+
"description": "Return home mission succesfully started",
|
|
172
|
+
"model": StartMissionResponse,
|
|
173
|
+
},
|
|
174
|
+
HTTPStatus.UNPROCESSABLE_ENTITY.value: {
|
|
175
|
+
"description": "Invalid body - The JSON is incorrect",
|
|
176
|
+
},
|
|
177
|
+
HTTPStatus.CONFLICT.value: {
|
|
178
|
+
"description": "Conflict - Invalid command in the current state",
|
|
179
|
+
},
|
|
148
180
|
HTTPStatus.INTERNAL_SERVER_ERROR.value: {
|
|
149
181
|
"description": "Internal Server Error - Current state of state machine unknown",
|
|
150
182
|
},
|
|
@@ -161,9 +193,15 @@ class API:
|
|
|
161
193
|
"description": "Mission succesfully stopped",
|
|
162
194
|
"model": ControlMissionResponse,
|
|
163
195
|
},
|
|
196
|
+
HTTPStatus.UNPROCESSABLE_ENTITY.value: {
|
|
197
|
+
"description": "Invalid body - The JSON is incorrect",
|
|
198
|
+
},
|
|
164
199
|
HTTPStatus.CONFLICT.value: {
|
|
165
200
|
"description": "Conflict - Invalid command in the current state",
|
|
166
201
|
},
|
|
202
|
+
HTTPStatus.BAD_REQUEST.value: {
|
|
203
|
+
"description": "Bad request - Robot does not have the capabilities to perform the mission",
|
|
204
|
+
},
|
|
167
205
|
HTTPStatus.INTERNAL_SERVER_ERROR.value: {
|
|
168
206
|
"description": "Internal Server Error - Current state of state machine unknown",
|
|
169
207
|
},
|
|
@@ -208,60 +246,86 @@ class API:
|
|
|
208
246
|
},
|
|
209
247
|
)
|
|
210
248
|
router.add_api_route(
|
|
211
|
-
path="/schedule/
|
|
212
|
-
endpoint=self.scheduling_controller.
|
|
249
|
+
path="/schedule/lockdown",
|
|
250
|
+
endpoint=self.scheduling_controller.lockdown,
|
|
213
251
|
methods=["POST"],
|
|
214
252
|
dependencies=[authentication_dependency],
|
|
215
|
-
summary="
|
|
253
|
+
summary="Send the robot to dock and ensure that it stays there",
|
|
216
254
|
responses={
|
|
217
|
-
HTTPStatus.OK.value: {
|
|
218
|
-
"description": "Drive to succesfully started",
|
|
219
|
-
},
|
|
255
|
+
HTTPStatus.OK.value: {"description": "Robot going to dock"},
|
|
220
256
|
HTTPStatus.CONFLICT.value: {
|
|
221
|
-
"description": "Conflict - Invalid command in the current state"
|
|
257
|
+
"description": "Conflict - Invalid command in the current state"
|
|
222
258
|
},
|
|
223
259
|
HTTPStatus.INTERNAL_SERVER_ERROR.value: {
|
|
224
|
-
"description": "Internal Server Error - Current state of state machine unknown"
|
|
260
|
+
"description": "Internal Server Error - Current state of state machine unknown"
|
|
225
261
|
},
|
|
226
262
|
},
|
|
227
263
|
)
|
|
228
264
|
router.add_api_route(
|
|
229
|
-
path="/schedule/
|
|
230
|
-
endpoint=self.scheduling_controller.
|
|
265
|
+
path="/schedule/release-lockdown",
|
|
266
|
+
endpoint=self.scheduling_controller.release_lockdown,
|
|
231
267
|
methods=["POST"],
|
|
232
268
|
dependencies=[authentication_dependency],
|
|
233
|
-
summary="
|
|
269
|
+
summary="Allow the robot to start missions again",
|
|
234
270
|
responses={
|
|
235
271
|
HTTPStatus.OK.value: {
|
|
236
|
-
"description": "
|
|
272
|
+
"description": "Robot is able to receive missions again"
|
|
237
273
|
},
|
|
238
274
|
HTTPStatus.CONFLICT.value: {
|
|
239
|
-
"description": "Conflict - Invalid command in the current state"
|
|
275
|
+
"description": "Conflict - Invalid command in the current state"
|
|
240
276
|
},
|
|
241
277
|
HTTPStatus.INTERNAL_SERVER_ERROR.value: {
|
|
242
|
-
"description": "Internal Server Error - Current state of state machine unknown"
|
|
278
|
+
"description": "Internal Server Error - Current state of state machine unknown"
|
|
243
279
|
},
|
|
244
280
|
},
|
|
245
281
|
)
|
|
246
282
|
router.add_api_route(
|
|
247
|
-
path="/schedule/
|
|
248
|
-
endpoint=self.scheduling_controller.
|
|
283
|
+
path="/schedule/maintenance-mode",
|
|
284
|
+
endpoint=self.scheduling_controller.set_maintenance_mode,
|
|
249
285
|
methods=["POST"],
|
|
250
286
|
dependencies=[authentication_dependency],
|
|
251
|
-
summary="
|
|
287
|
+
summary="Place the robot in maintenance mode, where it will not run missions before begin released from maintenance mode",
|
|
252
288
|
responses={
|
|
253
289
|
HTTPStatus.OK.value: {
|
|
254
|
-
"description": "
|
|
290
|
+
"description": "Robot is in maintenance mode and cannot receive missions"
|
|
255
291
|
},
|
|
256
|
-
HTTPStatus.
|
|
257
|
-
|
|
258
|
-
"
|
|
292
|
+
HTTPStatus.CONFLICT.value: {"description": "Conflict"},
|
|
293
|
+
HTTPStatus.INTERNAL_SERVER_ERROR.value: {
|
|
294
|
+
"description": "Internal Server Error"
|
|
295
|
+
},
|
|
296
|
+
},
|
|
297
|
+
)
|
|
298
|
+
router.add_api_route(
|
|
299
|
+
path="/schedule/release-maintenance-mode",
|
|
300
|
+
endpoint=self.scheduling_controller.release_maintenance_mode,
|
|
301
|
+
methods=["POST"],
|
|
302
|
+
dependencies=[authentication_dependency],
|
|
303
|
+
summary="Allow the robot to start missions again",
|
|
304
|
+
responses={
|
|
305
|
+
HTTPStatus.OK.value: {
|
|
306
|
+
"description": "Robot is able to receive missions again"
|
|
307
|
+
},
|
|
308
|
+
HTTPStatus.CONFLICT.value: {"description": "Conflict"},
|
|
309
|
+
HTTPStatus.INTERNAL_SERVER_ERROR.value: {
|
|
310
|
+
"description": "Internal Server Error"
|
|
311
|
+
},
|
|
312
|
+
},
|
|
313
|
+
)
|
|
314
|
+
router.add_api_route(
|
|
315
|
+
path="/schedule/release-intervention-needed",
|
|
316
|
+
endpoint=self.scheduling_controller.release_intervention_needed,
|
|
317
|
+
methods=["POST"],
|
|
318
|
+
dependencies=[authentication_dependency],
|
|
319
|
+
summary="Release the intervention needed state",
|
|
320
|
+
responses={
|
|
321
|
+
HTTPStatus.OK.value: {
|
|
322
|
+
"description": "Robot released from intervention needed state"
|
|
259
323
|
},
|
|
260
324
|
HTTPStatus.CONFLICT.value: {
|
|
261
|
-
"description": "Conflict - Invalid command in the current state"
|
|
325
|
+
"description": "Conflict - Invalid command in the current state"
|
|
262
326
|
},
|
|
263
327
|
HTTPStatus.INTERNAL_SERVER_ERROR.value: {
|
|
264
|
-
"description": "Internal Server Error - Current state of state machine unknown"
|
|
328
|
+
"description": "Internal Server Error - Current state of state machine unknown"
|
|
265
329
|
},
|
|
266
330
|
},
|
|
267
331
|
)
|
|
@@ -275,7 +339,7 @@ class API:
|
|
|
275
339
|
|
|
276
340
|
router.add_api_route(
|
|
277
341
|
path="/info/robot-settings",
|
|
278
|
-
endpoint=self.
|
|
342
|
+
endpoint=self.robot_controller.get_info,
|
|
279
343
|
methods=["GET"],
|
|
280
344
|
dependencies=[authentication_dependency],
|
|
281
345
|
summary="Information about the robot-settings",
|
|
@@ -283,6 +347,29 @@ class API:
|
|
|
283
347
|
|
|
284
348
|
return router
|
|
285
349
|
|
|
350
|
+
def _create_media_control_router(self) -> APIRouter:
|
|
351
|
+
router: APIRouter = APIRouter(tags=["Media"])
|
|
352
|
+
|
|
353
|
+
authentication_dependency: Security = Security(self.authenticator.get_scheme())
|
|
354
|
+
|
|
355
|
+
router.add_api_route(
|
|
356
|
+
path="/media/media-stream-config",
|
|
357
|
+
endpoint=self.robot_controller.generate_media_config,
|
|
358
|
+
methods=["GET"],
|
|
359
|
+
dependencies=[authentication_dependency],
|
|
360
|
+
summary="Generates a media stream connection config",
|
|
361
|
+
responses={
|
|
362
|
+
HTTPStatus.OK.value: {
|
|
363
|
+
"description": "Media stream was successfully generated",
|
|
364
|
+
},
|
|
365
|
+
HTTPStatus.NO_CONTENT.value: {
|
|
366
|
+
"description": "Robot has no media config",
|
|
367
|
+
},
|
|
368
|
+
},
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
return router
|
|
372
|
+
|
|
286
373
|
def _log_startup_message(self) -> None:
|
|
287
374
|
address_format = "%s://%s:%d/docs"
|
|
288
375
|
message = f"Uvicorn running on {address_format} (Press CTRL+C to quit)"
|
|
@@ -300,35 +387,20 @@ class API:
|
|
|
300
387
|
extra={"color_message": color_message},
|
|
301
388
|
)
|
|
302
389
|
|
|
303
|
-
def
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
connection_string = self.keyvault_client.get_secret(
|
|
307
|
-
"application-insights-connection-string"
|
|
308
|
-
).value
|
|
309
|
-
except KeyvaultError:
|
|
310
|
-
message: str = (
|
|
311
|
-
"Missing connection string for Application Insights in key vault. "
|
|
312
|
-
)
|
|
313
|
-
self.logger.critical(message)
|
|
314
|
-
raise ConfigurationError(message)
|
|
315
|
-
|
|
316
|
-
@app.middleware("http")
|
|
317
|
-
async def middlewareOpencensus(request: Request, call_next):
|
|
318
|
-
tracer = Tracer(
|
|
319
|
-
exporter=AzureExporter(connection_string=connection_string),
|
|
320
|
-
sampler=ProbabilitySampler(1.0),
|
|
321
|
-
)
|
|
322
|
-
with tracer.span("main") as span:
|
|
323
|
-
span.span_kind = SpanKind.SERVER
|
|
390
|
+
def _publish_startup_message(self) -> None:
|
|
391
|
+
if not self.mqtt_publisher:
|
|
392
|
+
return
|
|
324
393
|
|
|
325
|
-
|
|
394
|
+
payload: StartUpMessagePayload = StartUpMessagePayload(
|
|
395
|
+
isar_id=settings.ISAR_ID,
|
|
396
|
+
timestamp=datetime.now(timezone.utc),
|
|
397
|
+
)
|
|
326
398
|
|
|
327
|
-
|
|
328
|
-
attribute_key=HTTP_STATUS_CODE, attribute_value=response.status_code
|
|
329
|
-
)
|
|
330
|
-
tracer.add_attribute_to_current_span(
|
|
331
|
-
attribute_key=HTTP_URL, attribute_value=str(request.url)
|
|
332
|
-
)
|
|
399
|
+
self.logger.info("Publishing startup message to MQTT broker")
|
|
333
400
|
|
|
334
|
-
|
|
401
|
+
self.mqtt_publisher.publish(
|
|
402
|
+
topic=settings.TOPIC_ISAR_STARTUP,
|
|
403
|
+
payload=json.dumps(payload, cls=EnhancedJSONEncoder),
|
|
404
|
+
qos=1,
|
|
405
|
+
retain=True,
|
|
406
|
+
)
|
isar/apis/models/__init__.py
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
from .models import InputPose, StartMissionResponse
|
isar/apis/models/models.py
CHANGED
|
@@ -3,16 +3,14 @@ from typing import List, Optional
|
|
|
3
3
|
from alitra import Frame, Orientation, Pose, Position
|
|
4
4
|
from pydantic import BaseModel, Field
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
class StepResponse(BaseModel):
|
|
8
|
-
id: str
|
|
9
|
-
type: str
|
|
6
|
+
from robot_interface.models.mission.task import TaskTypes
|
|
10
7
|
|
|
11
8
|
|
|
12
9
|
class TaskResponse(BaseModel):
|
|
13
10
|
id: str
|
|
14
11
|
tag_id: Optional[str] = None
|
|
15
|
-
|
|
12
|
+
inspection_id: Optional[str] = None
|
|
13
|
+
type: TaskTypes
|
|
16
14
|
|
|
17
15
|
|
|
18
16
|
class StartMissionResponse(BaseModel):
|
|
@@ -21,12 +19,24 @@ class StartMissionResponse(BaseModel):
|
|
|
21
19
|
|
|
22
20
|
|
|
23
21
|
class ControlMissionResponse(BaseModel):
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
22
|
+
success: bool
|
|
23
|
+
failure_reason: Optional[str] = None
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class MissionStartResponse(BaseModel):
|
|
27
|
+
mission_id: Optional[str] = None
|
|
28
|
+
mission_started: bool
|
|
29
|
+
mission_not_started_reason: Optional[str] = None
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class LockdownResponse(BaseModel):
|
|
33
|
+
lockdown_started: bool
|
|
34
|
+
failure_reason: Optional[str] = None
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class MaintenanceResponse(BaseModel):
|
|
38
|
+
is_maintenance_mode: bool
|
|
39
|
+
failure_reason: Optional[str] = None
|
|
30
40
|
|
|
31
41
|
|
|
32
42
|
class RobotInfoResponse(BaseModel):
|