isar 1.20.2__py3-none-any.whl → 1.34.13__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.
Files changed (134) hide show
  1. isar/apis/api.py +135 -86
  2. isar/apis/models/__init__.py +0 -1
  3. isar/apis/models/models.py +21 -11
  4. isar/apis/models/start_mission_definition.py +115 -170
  5. isar/apis/robot_control/robot_controller.py +41 -0
  6. isar/apis/schedule/scheduling_controller.py +123 -187
  7. isar/apis/security/authentication.py +5 -5
  8. isar/config/certs/ca-cert.pem +33 -31
  9. isar/config/keyvault/keyvault_service.py +4 -2
  10. isar/config/log.py +45 -40
  11. isar/config/logging.conf +16 -31
  12. isar/config/open_telemetry.py +102 -0
  13. isar/config/settings.py +74 -117
  14. isar/eventhandlers/eventhandler.py +123 -0
  15. isar/models/events.py +184 -0
  16. isar/models/status.py +22 -0
  17. isar/modules.py +117 -200
  18. isar/robot/robot.py +383 -0
  19. isar/robot/robot_battery.py +60 -0
  20. isar/robot/robot_monitor_mission.py +357 -0
  21. isar/robot/robot_pause_mission.py +74 -0
  22. isar/robot/robot_resume_mission.py +67 -0
  23. isar/robot/robot_start_mission.py +66 -0
  24. isar/robot/robot_status.py +61 -0
  25. isar/robot/robot_stop_mission.py +68 -0
  26. isar/robot/robot_upload_inspection.py +75 -0
  27. isar/script.py +58 -41
  28. isar/services/service_connections/mqtt/mqtt_client.py +47 -11
  29. isar/services/service_connections/mqtt/robot_heartbeat_publisher.py +5 -2
  30. isar/services/service_connections/mqtt/robot_info_publisher.py +3 -3
  31. isar/services/service_connections/persistent_memory.py +69 -0
  32. isar/services/utilities/mqtt_utilities.py +93 -0
  33. isar/services/utilities/robot_utilities.py +20 -0
  34. isar/services/utilities/scheduling_utilities.py +386 -100
  35. isar/state_machine/state_machine.py +242 -539
  36. isar/state_machine/states/__init__.py +0 -8
  37. isar/state_machine/states/await_next_mission.py +114 -0
  38. isar/state_machine/states/blocked_protective_stop.py +60 -0
  39. isar/state_machine/states/going_to_lockdown.py +95 -0
  40. isar/state_machine/states/going_to_recharging.py +92 -0
  41. isar/state_machine/states/home.py +115 -0
  42. isar/state_machine/states/intervention_needed.py +77 -0
  43. isar/state_machine/states/lockdown.py +38 -0
  44. isar/state_machine/states/maintenance.py +43 -0
  45. isar/state_machine/states/monitor.py +137 -247
  46. isar/state_machine/states/offline.py +51 -53
  47. isar/state_machine/states/paused.py +92 -23
  48. isar/state_machine/states/pausing.py +48 -0
  49. isar/state_machine/states/pausing_return_home.py +48 -0
  50. isar/state_machine/states/recharging.py +80 -0
  51. isar/state_machine/states/resuming.py +57 -0
  52. isar/state_machine/states/resuming_return_home.py +64 -0
  53. isar/state_machine/states/return_home_paused.py +109 -0
  54. isar/state_machine/states/returning_home.py +217 -0
  55. isar/state_machine/states/stopping.py +69 -0
  56. isar/state_machine/states/stopping_due_to_maintenance.py +61 -0
  57. isar/state_machine/states/stopping_go_to_lockdown.py +60 -0
  58. isar/state_machine/states/stopping_go_to_recharge.py +51 -0
  59. isar/state_machine/states/stopping_paused_mission.py +36 -0
  60. isar/state_machine/states/stopping_paused_return_home.py +59 -0
  61. isar/state_machine/states/stopping_return_home.py +59 -0
  62. isar/state_machine/states/unknown_status.py +74 -0
  63. isar/state_machine/states_enum.py +23 -5
  64. isar/state_machine/transitions/mission.py +225 -0
  65. isar/state_machine/transitions/return_home.py +108 -0
  66. isar/state_machine/transitions/robot_status.py +87 -0
  67. isar/state_machine/utils/common_event_handlers.py +138 -0
  68. isar/storage/blob_storage.py +70 -52
  69. isar/storage/local_storage.py +25 -12
  70. isar/storage/storage_interface.py +28 -7
  71. isar/storage/uploader.py +174 -55
  72. isar/storage/utilities.py +32 -29
  73. {isar-1.20.2.dist-info → isar-1.34.13.dist-info}/METADATA +119 -123
  74. isar-1.34.13.dist-info/RECORD +120 -0
  75. {isar-1.20.2.dist-info → isar-1.34.13.dist-info}/WHEEL +1 -1
  76. {isar-1.20.2.dist-info → isar-1.34.13.dist-info}/entry_points.txt +1 -0
  77. robot_interface/models/exceptions/robot_exceptions.py +91 -41
  78. robot_interface/models/inspection/__init__.py +0 -13
  79. robot_interface/models/inspection/inspection.py +42 -33
  80. robot_interface/models/mission/mission.py +14 -15
  81. robot_interface/models/mission/status.py +20 -26
  82. robot_interface/models/mission/task.py +154 -121
  83. robot_interface/models/robots/battery_state.py +6 -0
  84. robot_interface/models/robots/media.py +13 -0
  85. robot_interface/models/robots/robot_model.py +7 -7
  86. robot_interface/robot_interface.py +119 -84
  87. robot_interface/telemetry/mqtt_client.py +74 -12
  88. robot_interface/telemetry/payloads.py +91 -13
  89. robot_interface/utilities/json_service.py +7 -1
  90. isar/config/configuration_error.py +0 -2
  91. isar/config/keyvault/keyvault_error.py +0 -2
  92. isar/config/predefined_mission_definition/__init__.py +0 -0
  93. isar/config/predefined_mission_definition/default_exr.json +0 -51
  94. isar/config/predefined_mission_definition/default_mission.json +0 -91
  95. isar/config/predefined_mission_definition/default_turtlebot.json +0 -124
  96. isar/config/predefined_missions/__init__.py +0 -0
  97. isar/config/predefined_missions/default.json +0 -92
  98. isar/config/predefined_missions/default_turtlebot.json +0 -110
  99. isar/config/predefined_poses/__init__.py +0 -0
  100. isar/config/predefined_poses/predefined_poses.py +0 -616
  101. isar/config/settings.env +0 -25
  102. isar/mission_planner/__init__.py +0 -0
  103. isar/mission_planner/local_planner.py +0 -82
  104. isar/mission_planner/mission_planner_interface.py +0 -26
  105. isar/mission_planner/sequential_task_selector.py +0 -23
  106. isar/mission_planner/task_selector_interface.py +0 -31
  107. isar/models/communication/__init__.py +0 -0
  108. isar/models/communication/message.py +0 -12
  109. isar/models/communication/queues/__init__.py +0 -4
  110. isar/models/communication/queues/queue_io.py +0 -12
  111. isar/models/communication/queues/queue_timeout_error.py +0 -2
  112. isar/models/communication/queues/queues.py +0 -19
  113. isar/models/communication/queues/status_queue.py +0 -20
  114. isar/models/mission_metadata/__init__.py +0 -0
  115. isar/services/auth/__init__.py +0 -0
  116. isar/services/auth/azure_credentials.py +0 -14
  117. isar/services/readers/__init__.py +0 -0
  118. isar/services/readers/base_reader.py +0 -37
  119. isar/services/service_connections/request_handler.py +0 -153
  120. isar/services/service_connections/stid/__init__.py +0 -0
  121. isar/services/utilities/queue_utilities.py +0 -39
  122. isar/services/utilities/threaded_request.py +0 -68
  123. isar/state_machine/states/idle.py +0 -85
  124. isar/state_machine/states/initialize.py +0 -71
  125. isar/state_machine/states/initiate.py +0 -142
  126. isar/state_machine/states/off.py +0 -18
  127. isar/state_machine/states/stop.py +0 -95
  128. isar/storage/slimm_storage.py +0 -191
  129. isar-1.20.2.dist-info/RECORD +0 -116
  130. robot_interface/models/initialize/__init__.py +0 -1
  131. robot_interface/models/initialize/initialize_params.py +0 -9
  132. robot_interface/models/mission/step.py +0 -234
  133. {isar-1.20.2.dist-info → isar-1.34.13.dist-info/licenses}/LICENSE +0 -0
  134. {isar-1.20.2.dist-info → isar-1.34.13.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, Request, Security
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
- HTTP_URL = COMMON_ATTRIBUTES["HTTP_URL"]
28
- HTTP_STATUS_CODE = COMMON_ATTRIBUTES["HTTP_STATUS_CODE"]
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
- keyvault_client: Keyvault,
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.keyvault_client: Keyvault = keyvault_client
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.azure_ai_logging_enabled: bool = azure_ai_logging_enabled
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 run_app(self) -> None:
56
- uvicorn.run(
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=[self.authenticator.load_config, self._log_startup_message],
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:
@@ -106,37 +113,39 @@ class API:
106
113
  authentication_dependency: Security = Security(self.authenticator.get_scheme())
107
114
 
108
115
  router.add_api_route(
109
- path="/schedule/start-mission/{id}",
110
- endpoint=self.scheduling_controller.start_mission_by_id,
116
+ path="/schedule/start-mission",
117
+ endpoint=self.scheduling_controller.start_mission,
111
118
  methods=["POST"],
112
- deprecated=True,
113
119
  dependencies=[authentication_dependency],
114
- summary="Start a mission with id='id' from the current mission planner",
120
+ summary="Start the mission provided in JSON format",
115
121
  responses={
116
122
  HTTPStatus.OK.value: {
117
123
  "description": "Mission succesfully started",
118
124
  "model": StartMissionResponse,
119
125
  },
120
- HTTPStatus.NOT_FOUND.value: {
121
- "description": "Not found - Mission not found",
126
+ HTTPStatus.UNPROCESSABLE_ENTITY.value: {
127
+ "description": "Invalid body - The JSON is incorrect",
122
128
  },
123
129
  HTTPStatus.CONFLICT.value: {
124
130
  "description": "Conflict - Invalid command in the current state",
125
131
  },
132
+ HTTPStatus.BAD_REQUEST.value: {
133
+ "description": "Bad request - Robot does not have the capabilities to perform the mission",
134
+ },
126
135
  HTTPStatus.INTERNAL_SERVER_ERROR.value: {
127
136
  "description": "Internal Server Error - Current state of state machine unknown",
128
137
  },
129
138
  },
130
139
  )
131
140
  router.add_api_route(
132
- path="/schedule/start-mission",
133
- endpoint=self.scheduling_controller.start_mission,
141
+ path="/schedule/return-home",
142
+ endpoint=self.scheduling_controller.return_home,
134
143
  methods=["POST"],
135
144
  dependencies=[authentication_dependency],
136
- summary="Start the mission provided in JSON format",
145
+ summary="Start return home mission",
137
146
  responses={
138
147
  HTTPStatus.OK.value: {
139
- "description": "Mission succesfully started",
148
+ "description": "Return home mission succesfully started",
140
149
  "model": StartMissionResponse,
141
150
  },
142
151
  HTTPStatus.UNPROCESSABLE_ENTITY.value: {
@@ -161,9 +170,15 @@ class API:
161
170
  "description": "Mission succesfully stopped",
162
171
  "model": ControlMissionResponse,
163
172
  },
173
+ HTTPStatus.UNPROCESSABLE_ENTITY.value: {
174
+ "description": "Invalid body - The JSON is incorrect",
175
+ },
164
176
  HTTPStatus.CONFLICT.value: {
165
177
  "description": "Conflict - Invalid command in the current state",
166
178
  },
179
+ HTTPStatus.BAD_REQUEST.value: {
180
+ "description": "Bad request - Robot does not have the capabilities to perform the mission",
181
+ },
167
182
  HTTPStatus.INTERNAL_SERVER_ERROR.value: {
168
183
  "description": "Internal Server Error - Current state of state machine unknown",
169
184
  },
@@ -208,60 +223,86 @@ class API:
208
223
  },
209
224
  )
210
225
  router.add_api_route(
211
- path="/schedule/drive-to",
212
- endpoint=self.scheduling_controller.drive_to,
226
+ path="/schedule/lockdown",
227
+ endpoint=self.scheduling_controller.lockdown,
213
228
  methods=["POST"],
214
229
  dependencies=[authentication_dependency],
215
- summary="Drive to the provided pose",
230
+ summary="Send the robot to dock and ensure that it stays there",
216
231
  responses={
217
- HTTPStatus.OK.value: {
218
- "description": "Drive to succesfully started",
219
- },
232
+ HTTPStatus.OK.value: {"description": "Robot going to dock"},
220
233
  HTTPStatus.CONFLICT.value: {
221
- "description": "Conflict - Invalid command in the current state",
234
+ "description": "Conflict - Invalid command in the current state"
222
235
  },
223
236
  HTTPStatus.INTERNAL_SERVER_ERROR.value: {
224
- "description": "Internal Server Error - Current state of state machine unknown",
237
+ "description": "Internal Server Error - Current state of state machine unknown"
225
238
  },
226
239
  },
227
240
  )
228
241
  router.add_api_route(
229
- path="/schedule/start-localization-mission",
230
- endpoint=self.scheduling_controller.start_localization_mission,
242
+ path="/schedule/release-lockdown",
243
+ endpoint=self.scheduling_controller.release_lockdown,
231
244
  methods=["POST"],
232
245
  dependencies=[authentication_dependency],
233
- summary="Localize at the provided pose",
246
+ summary="Allow the robot to start missions again",
234
247
  responses={
235
248
  HTTPStatus.OK.value: {
236
- "description": "Localization succesfully started",
249
+ "description": "Robot is able to receive missions again"
237
250
  },
238
251
  HTTPStatus.CONFLICT.value: {
239
- "description": "Conflict - Invalid command in the current state",
252
+ "description": "Conflict - Invalid command in the current state"
240
253
  },
241
254
  HTTPStatus.INTERNAL_SERVER_ERROR.value: {
242
- "description": "Internal Server Error - Current state of state machine unknown",
255
+ "description": "Internal Server Error - Current state of state machine unknown"
243
256
  },
244
257
  },
245
258
  )
246
259
  router.add_api_route(
247
- path="/schedule/move_arm/{arm_pose_literal}",
248
- endpoint=self.scheduling_controller.start_move_arm_mission,
260
+ path="/schedule/maintenance-mode",
261
+ endpoint=self.scheduling_controller.set_maintenance_mode,
249
262
  methods=["POST"],
250
263
  dependencies=[authentication_dependency],
251
- summary="Move arm to the given arm pose literal",
264
+ summary="Place the robot in maintenance mode, where it will not run missions before begin released from maintenance mode",
252
265
  responses={
253
266
  HTTPStatus.OK.value: {
254
- "description": "Move arm mission successfully started",
267
+ "description": "Robot is in maintenance mode and cannot receive missions"
255
268
  },
256
- HTTPStatus.BAD_REQUEST.value: {
257
- "description": "A move arm mission was scheduled on a robot that "
258
- "does not support it or the input was incorrect",
269
+ HTTPStatus.CONFLICT.value: {"description": "Conflict"},
270
+ HTTPStatus.INTERNAL_SERVER_ERROR.value: {
271
+ "description": "Internal Server Error"
272
+ },
273
+ },
274
+ )
275
+ router.add_api_route(
276
+ path="/schedule/release-maintenance-mode",
277
+ endpoint=self.scheduling_controller.release_maintenance_mode,
278
+ methods=["POST"],
279
+ dependencies=[authentication_dependency],
280
+ summary="Allow the robot to start missions again",
281
+ responses={
282
+ HTTPStatus.OK.value: {
283
+ "description": "Robot is able to receive missions again"
284
+ },
285
+ HTTPStatus.CONFLICT.value: {"description": "Conflict"},
286
+ HTTPStatus.INTERNAL_SERVER_ERROR.value: {
287
+ "description": "Internal Server Error"
288
+ },
289
+ },
290
+ )
291
+ router.add_api_route(
292
+ path="/schedule/release-intervention-needed",
293
+ endpoint=self.scheduling_controller.release_intervention_needed,
294
+ methods=["POST"],
295
+ dependencies=[authentication_dependency],
296
+ summary="Release the intervention needed state",
297
+ responses={
298
+ HTTPStatus.OK.value: {
299
+ "description": "Robot released from intervention needed state"
259
300
  },
260
301
  HTTPStatus.CONFLICT.value: {
261
- "description": "Conflict - Invalid command in the current state",
302
+ "description": "Conflict - Invalid command in the current state"
262
303
  },
263
304
  HTTPStatus.INTERNAL_SERVER_ERROR.value: {
264
- "description": "Internal Server Error - Current state of state machine unknown",
305
+ "description": "Internal Server Error - Current state of state machine unknown"
265
306
  },
266
307
  },
267
308
  )
@@ -275,7 +316,7 @@ class API:
275
316
 
276
317
  router.add_api_route(
277
318
  path="/info/robot-settings",
278
- endpoint=self.scheduling_controller.get_info,
319
+ endpoint=self.robot_controller.get_info,
279
320
  methods=["GET"],
280
321
  dependencies=[authentication_dependency],
281
322
  summary="Information about the robot-settings",
@@ -283,6 +324,29 @@ class API:
283
324
 
284
325
  return router
285
326
 
327
+ def _create_media_control_router(self) -> APIRouter:
328
+ router: APIRouter = APIRouter(tags=["Media"])
329
+
330
+ authentication_dependency: Security = Security(self.authenticator.get_scheme())
331
+
332
+ router.add_api_route(
333
+ path="/media/media-stream-config",
334
+ endpoint=self.robot_controller.generate_media_config,
335
+ methods=["GET"],
336
+ dependencies=[authentication_dependency],
337
+ summary="Generates a media stream connection config",
338
+ responses={
339
+ HTTPStatus.OK.value: {
340
+ "description": "Media stream was successfully generated",
341
+ },
342
+ HTTPStatus.NO_CONTENT.value: {
343
+ "description": "Robot has no media config",
344
+ },
345
+ },
346
+ )
347
+
348
+ return router
349
+
286
350
  def _log_startup_message(self) -> None:
287
351
  address_format = "%s://%s:%d/docs"
288
352
  message = f"Uvicorn running on {address_format} (Press CTRL+C to quit)"
@@ -300,35 +364,20 @@ class API:
300
364
  extra={"color_message": color_message},
301
365
  )
302
366
 
303
- def _add_request_logging_middleware(self, app: FastAPI) -> None:
304
- connection_string: str
305
- try:
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
367
+ def _publish_startup_message(self) -> None:
368
+ if not self.mqtt_publisher:
369
+ return
324
370
 
325
- response = await call_next(request)
371
+ payload: StartUpMessagePayload = StartUpMessagePayload(
372
+ isar_id=settings.ISAR_ID,
373
+ timestamp=datetime.now(timezone.utc),
374
+ )
326
375
 
327
- tracer.add_attribute_to_current_span(
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
- )
376
+ self.logger.info("Publishing startup message to MQTT broker")
333
377
 
334
- return response
378
+ self.mqtt_publisher.publish(
379
+ topic=settings.TOPIC_ISAR_STARTUP,
380
+ payload=json.dumps(payload, cls=EnhancedJSONEncoder),
381
+ qos=1,
382
+ retain=True,
383
+ )
@@ -1 +0,0 @@
1
- from .models import InputPose, StartMissionResponse
@@ -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
- steps: List[StepResponse]
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
- mission_id: str
25
- mission_status: str
26
- task_id: str
27
- task_status: str
28
- step_id: str
29
- step_status: str
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):