isar 1.31.1__py3-none-any.whl → 1.32.1__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.

Potentially problematic release.


This version of isar might be problematic. Click here for more details.

Files changed (35) hide show
  1. isar/apis/api.py +18 -0
  2. isar/apis/models/start_mission_definition.py +4 -0
  3. isar/apis/schedule/scheduling_controller.py +16 -0
  4. isar/config/log.py +1 -2
  5. isar/config/logging.conf +9 -30
  6. isar/config/settings.py +4 -0
  7. isar/models/events.py +5 -4
  8. isar/script.py +7 -16
  9. isar/services/utilities/scheduling_utilities.py +23 -3
  10. isar/state_machine/state_machine.py +26 -1
  11. isar/state_machine/states/await_next_mission.py +3 -3
  12. isar/state_machine/states/home.py +3 -3
  13. isar/state_machine/states/intervention_needed.py +43 -0
  14. isar/state_machine/states/monitor.py +2 -2
  15. isar/state_machine/states/paused.py +2 -2
  16. isar/state_machine/states/returning_home.py +2 -2
  17. isar/state_machine/states/robot_standing_still.py +3 -3
  18. isar/state_machine/states/unknown_status.py +1 -1
  19. isar/state_machine/states_enum.py +1 -0
  20. isar/state_machine/transitions/functions/fail_mission.py +7 -0
  21. isar/state_machine/transitions/functions/pause.py +1 -1
  22. isar/state_machine/transitions/functions/resume.py +1 -1
  23. isar/state_machine/transitions/functions/start_mission.py +4 -4
  24. isar/state_machine/transitions/functions/stop.py +12 -6
  25. isar/state_machine/transitions/mission.py +4 -10
  26. isar/state_machine/transitions/return_home.py +14 -2
  27. isar/state_machine/utils/common_event_handlers.py +2 -2
  28. {isar-1.31.1.dist-info → isar-1.32.1.dist-info}/METADATA +1 -1
  29. {isar-1.31.1.dist-info → isar-1.32.1.dist-info}/RECORD +35 -34
  30. robot_interface/models/mission/status.py +1 -0
  31. robot_interface/telemetry/payloads.py +8 -0
  32. {isar-1.31.1.dist-info → isar-1.32.1.dist-info}/WHEEL +0 -0
  33. {isar-1.31.1.dist-info → isar-1.32.1.dist-info}/entry_points.txt +0 -0
  34. {isar-1.31.1.dist-info → isar-1.32.1.dist-info}/licenses/LICENSE +0 -0
  35. {isar-1.31.1.dist-info → isar-1.32.1.dist-info}/top_level.txt +0 -0
isar/apis/api.py CHANGED
@@ -245,6 +245,24 @@ class API:
245
245
  },
246
246
  },
247
247
  )
248
+ router.add_api_route(
249
+ path="/schedule/release-intervention-needed",
250
+ endpoint=self.scheduling_controller.release_intervention_needed,
251
+ methods=["POST"],
252
+ dependencies=[authentication_dependency],
253
+ summary="Release the intervention needed state",
254
+ responses={
255
+ HTTPStatus.OK.value: {
256
+ "description": "Robot released from intervention needed state"
257
+ },
258
+ HTTPStatus.CONFLICT.value: {
259
+ "description": "Conflict - Invalid command in the current state"
260
+ },
261
+ HTTPStatus.INTERNAL_SERVER_ERROR.value: {
262
+ "description": "Internal Server Error - Current state of state machine unknown"
263
+ },
264
+ },
265
+ )
248
266
  router.add_api_route(
249
267
  path="/schedule/move_arm/{arm_pose_literal}",
250
268
  endpoint=self.scheduling_controller.start_move_arm_mission,
@@ -53,6 +53,7 @@ class StartMissionTaskDefinition(BaseModel):
53
53
 
54
54
 
55
55
  class StartMissionDefinition(BaseModel):
56
+ id: Optional[str] = None
56
57
  tasks: List[StartMissionTaskDefinition]
57
58
  name: Optional[str] = None
58
59
  start_pose: Optional[InputPose] = None
@@ -84,7 +85,10 @@ def to_isar_mission(
84
85
  if start_mission_definition.start_pose:
85
86
  start_pose = start_mission_definition.start_pose.to_alitra_pose()
86
87
 
88
+ id = start_mission_definition.id if start_mission_definition.id else uuid4_string()
89
+
87
90
  return Mission(
91
+ id=id,
88
92
  tasks=isar_tasks,
89
93
  name=isar_mission_name,
90
94
  start_pose=start_pose,
@@ -256,6 +256,22 @@ class SchedulingController:
256
256
  self.scheduling_utilities.start_mission(mission=mission)
257
257
  return self._api_response(mission)
258
258
 
259
+ def release_intervention_needed(self) -> None:
260
+ self.logger.info("Received request to release intervention needed state")
261
+
262
+ state: States = self.scheduling_utilities.get_state()
263
+
264
+ if state != States.InterventionNeeded:
265
+ error_message = f"Conflict - Release intervention needed command received in invalid state - State: {state}"
266
+ self.logger.warning(error_message)
267
+ raise HTTPException(
268
+ status_code=HTTPStatus.CONFLICT,
269
+ detail=error_message,
270
+ )
271
+
272
+ self.scheduling_utilities.release_intervention_needed()
273
+ self.logger.info("Released intervention needed state successfully")
274
+
259
275
  def _api_response(self, mission: Mission) -> StartMissionResponse:
260
276
  return StartMissionResponse(
261
277
  id=mission.id,
isar/config/log.py CHANGED
@@ -5,11 +5,10 @@ from importlib.resources import as_file, files
5
5
  import yaml
6
6
  from uvicorn.logging import ColourizedFormatter
7
7
 
8
- from isar.config.keyvault.keyvault_service import Keyvault
9
8
  from isar.config.settings import settings
10
9
 
11
10
 
12
- def setup_loggers(keyvault: Keyvault) -> None:
11
+ def setup_loggers() -> None:
13
12
  log_levels: dict = settings.LOG_LEVELS
14
13
  log_config = load_log_config()
15
14
 
isar/config/logging.conf CHANGED
@@ -5,50 +5,29 @@ formatters:
5
5
  colourized:
6
6
  style: "{"
7
7
  format: "{asctime} - {levelprefix:<8} - {name} - {message}"
8
- handlers:
9
- api:
10
- class: logging.FileHandler
11
- formatter: simple
12
- filename: api.log
13
- main:
14
- class: logging.FileHandler
15
- formatter: simple
16
- filename: main.log
17
- mqtt:
18
- class: logging.FileHandler
19
- formatter: simple
20
- filename: mqtt.log
21
- state_machine:
22
- class: logging.FileHandler
23
- formatter: simple
24
- filename: state_machine.log
25
- uploader:
26
- class: logging.FileHandler
27
- formatter: simple
28
- filename: uploader.log
29
8
  loggers:
30
9
  console:
31
10
  handlers: []
32
11
  propagate: no
33
12
  main:
34
- handlers: [main]
13
+ handlers: []
35
14
  propagate: no
36
15
  api:
37
- handlers: [api]
16
+ handlers: []
38
17
  propagate: no
39
18
  mqtt:
40
- handlers: [mqtt]
41
- propagate: False
19
+ handlers: []
20
+ propagate: no
42
21
  state_machine:
43
- handlers: [state_machine]
44
- propagate: False
22
+ handlers: []
23
+ propagate: no
45
24
  uploader:
46
- handlers: [uploader]
47
- propagate: False
25
+ handlers: []
26
+ propagate: no
48
27
  urllib3:
49
28
  handlers: []
50
29
  uvicorn:
51
- handlers: [api]
30
+ handlers: []
52
31
  propagate: no
53
32
  azure:
54
33
  handlers: []
isar/config/settings.py CHANGED
@@ -224,6 +224,9 @@ class Settings(BaseSettings):
224
224
  default="robot_heartbeat", validate_default=True
225
225
  )
226
226
  TOPIC_ISAR_STARTUP: str = Field(default="startup", validate_default=True)
227
+ TOPIC_ISAR_INTERVENTION_NEEDED: str = Field(
228
+ default="intervention_needed", validate_default=True
229
+ )
227
230
 
228
231
  # Logging
229
232
 
@@ -275,6 +278,7 @@ class Settings(BaseSettings):
275
278
  "TOPIC_ISAR_INSPECTION_RESULT",
276
279
  "TOPIC_ISAR_INSPECTION_VALUE",
277
280
  "TOPIC_ISAR_STARTUP",
281
+ "TOPIC_ISAR_INTERVENTION_NEEDED",
278
282
  )
279
283
  @classmethod
280
284
  def prefix_isar_topics(cls, v: Any, info: ValidationInfo):
isar/models/events.py CHANGED
@@ -70,13 +70,13 @@ class Events:
70
70
 
71
71
  class APIEvent(Generic[T1, T2]):
72
72
  """
73
- Creates input and output event. The events are defined such that the input is from
74
- api to state machine while the output is from state machine to api.
73
+ Creates request and response event. The events are defined such that the request is from
74
+ api to state machine while the response is from state machine to api.
75
75
  """
76
76
 
77
77
  def __init__(self):
78
- self.input: Event[T1] = Event()
79
- self.output: Event[T2] = Event()
78
+ self.request: Event[T1] = Event()
79
+ self.response: Event[T2] = Event()
80
80
 
81
81
 
82
82
  class APIRequests:
@@ -86,6 +86,7 @@ class APIRequests:
86
86
  self.pause_mission: APIEvent[bool, ControlMissionResponse] = APIEvent()
87
87
  self.resume_mission: APIEvent[bool, ControlMissionResponse] = APIEvent()
88
88
  self.return_home: APIEvent[bool, bool] = APIEvent()
89
+ self.release_intervention_needed: APIEvent[bool, bool] = APIEvent()
89
90
 
90
91
 
91
92
  class StateMachineEvents:
isar/script.py CHANGED
@@ -36,7 +36,8 @@ def print_setting(
36
36
 
37
37
 
38
38
  def print_startup_info():
39
- print(
39
+ logger: Logger = logging.getLogger("main")
40
+ logger.info(
40
41
  """
41
42
  __ ________ ___ ________
42
43
  / / / ______/ / | / ____ /
@@ -48,21 +49,15 @@ def print_startup_info():
48
49
  """
49
50
  )
50
51
 
51
- WIDTH = 48
52
-
53
52
  def print_setting(setting: str = "", value: Any = "", fillchar: str = " "):
54
53
  separator = ": " if value != "" else ""
55
- text = setting.ljust(22, fillchar) + separator + str(value)
56
- print("*", text.ljust(WIDTH - 4, fillchar), "*")
54
+ logger.info(setting + separator + str(value))
57
55
 
58
- print("Integration and Supervisory control".center(WIDTH, " "))
59
- print("of Autonomous Robots".center(WIDTH, " "))
60
- print()
61
- print(f"Version: {isar.__version__}\n".center(WIDTH, " "))
56
+ logger.info(
57
+ f"Integration and Supervisory control of Autonomous Robots - Version: {isar.__version__}\n"
58
+ )
62
59
 
63
- print_setting(fillchar="*")
64
60
  print_setting("ISAR settings")
65
- print_setting(fillchar="-")
66
61
  print_setting("Robot package", settings.ROBOT_PACKAGE)
67
62
  print_setting("Robot name", settings.ROBOT_NAME)
68
63
  print_setting("Running on port", settings.API_PORT)
@@ -74,17 +69,13 @@ def print_startup_info():
74
69
  print_setting("Plant code", settings.PLANT_CODE)
75
70
  print_setting("Plant name", settings.PLANT_NAME)
76
71
  print_setting("Plant shortname", settings.PLANT_SHORT_NAME)
77
- print_setting(fillchar="-")
78
72
  print_setting("Robot capabilities", robot_settings.CAPABILITIES)
79
- print_setting(fillchar="*")
80
- print()
81
73
 
82
74
 
83
75
  def start() -> None:
84
76
  injector: ApplicationContainer = get_injector()
85
77
 
86
- keyvault = injector.keyvault()
87
- setup_loggers(keyvault=keyvault)
78
+ setup_loggers()
88
79
  setup_open_telemetry(app=injector.api().app)
89
80
  logger: Logger = logging.getLogger("main")
90
81
 
@@ -290,12 +290,32 @@ class SchedulingUtilities:
290
290
  self.logger.info("OK - Mission successfully stopped")
291
291
  return stop_mission_response
292
292
 
293
+ def release_intervention_needed(self) -> None:
294
+ """Release intervention needed state
295
+
296
+ Raises
297
+ ------
298
+ HTTPException 500 Internal Server Error
299
+ If the intervention needed state could not be released
300
+ """
301
+ try:
302
+ self._send_command(True, self.api_events.release_intervention_needed)
303
+ self.logger.info("OK - Intervention needed state released")
304
+ except EventTimeoutError:
305
+ error_message = (
306
+ "Internal Server Error - Failed to release intervention needed state"
307
+ )
308
+ self.logger.error(error_message)
309
+ raise HTTPException(
310
+ status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=error_message
311
+ )
312
+
293
313
  def _send_command(self, input: T1, api_event: APIEvent[T1, T2]) -> T2:
294
- api_event.input.trigger_event(input)
314
+ api_event.request.trigger_event(input)
295
315
  try:
296
- return api_event.output.consume_event(timeout=self.queue_timeout)
316
+ return api_event.response.consume_event(timeout=self.queue_timeout)
297
317
  except EventTimeoutError as e:
298
318
  self.logger.error("Queue timed out")
299
- api_event.input.clear_event()
319
+ api_event.request.clear_event()
300
320
  self.logger.error("No output received for command to state machine")
301
321
  raise e
@@ -18,6 +18,7 @@ from isar.models.events import Events, SharedState
18
18
  from isar.state_machine.states.await_next_mission import AwaitNextMission
19
19
  from isar.state_machine.states.blocked_protective_stop import BlockedProtectiveStop
20
20
  from isar.state_machine.states.home import Home
21
+ from isar.state_machine.states.intervention_needed import InterventionNeeded
21
22
  from isar.state_machine.states.monitor import Monitor
22
23
  from isar.state_machine.states.offline import Offline
23
24
  from isar.state_machine.states.paused import Paused
@@ -41,6 +42,7 @@ from robot_interface.models.mission.task import TASKS, InspectionTask, Task
41
42
  from robot_interface.robot_interface import RobotInterface
42
43
  from robot_interface.telemetry.mqtt_client import MqttClientInterface
43
44
  from robot_interface.telemetry.payloads import (
45
+ InterventionNeededPayload,
44
46
  MissionPayload,
45
47
  RobotStatusPayload,
46
48
  TaskPayload,
@@ -101,6 +103,7 @@ class StateMachine(object):
101
103
  self.await_next_mission_state: State = AwaitNextMission(self)
102
104
  self.home_state: State = Home(self)
103
105
  self.robot_standing_still_state: State = RobotStandingStill(self)
106
+ self.intervention_needed_state: State = InterventionNeeded(self)
104
107
 
105
108
  # Status states
106
109
  self.offline_state: State = Offline(self)
@@ -120,6 +123,7 @@ class StateMachine(object):
120
123
  self.offline_state,
121
124
  self.blocked_protective_stopping_state,
122
125
  self.unknown_status_state,
126
+ self.intervention_needed_state,
123
127
  ]
124
128
 
125
129
  self.machine = Machine(
@@ -282,6 +286,25 @@ class StateMachine(object):
282
286
  retain=True,
283
287
  )
284
288
 
289
+ def publish_intervention_needed(self, error_message: str) -> None:
290
+ """Publishes the intervention needed message to the MQTT Broker"""
291
+ if not self.mqtt_publisher:
292
+ return
293
+
294
+ payload: InterventionNeededPayload = InterventionNeededPayload(
295
+ isar_id=settings.ISAR_ID,
296
+ robot_name=settings.ROBOT_NAME,
297
+ reason=error_message,
298
+ timestamp=datetime.now(timezone.utc),
299
+ )
300
+
301
+ self.mqtt_publisher.publish(
302
+ topic=settings.TOPIC_ISAR_INTERVENTION_NEEDED,
303
+ payload=json.dumps(payload, cls=EnhancedJSONEncoder),
304
+ qos=1,
305
+ retain=True,
306
+ )
307
+
285
308
  def publish_status(self) -> None:
286
309
  if not self.mqtt_publisher:
287
310
  return
@@ -314,6 +337,8 @@ class StateMachine(object):
314
337
  return RobotStatus.Offline
315
338
  elif self.current_state == States.BlockedProtectiveStop:
316
339
  return RobotStatus.BlockedProtectiveStop
340
+ elif self.current_state == States.InterventionNeeded:
341
+ return RobotStatus.InterventionNeeded
317
342
  else:
318
343
  return RobotStatus.Busy
319
344
 
@@ -343,7 +368,7 @@ class StateMachine(object):
343
368
  )
344
369
 
345
370
  def _queue_empty_response(self) -> None:
346
- self.events.api_requests.stop_mission.output.put(
371
+ self.events.api_requests.stop_mission.response.put(
347
372
  ControlMissionResponse(
348
373
  mission_id="None",
349
374
  mission_status="None",
@@ -24,17 +24,17 @@ class AwaitNextMission(EventHandlerBase):
24
24
  event_handlers: List[EventHandlerMapping] = [
25
25
  EventHandlerMapping(
26
26
  name="start_mission_event",
27
- event=events.api_requests.start_mission.input,
27
+ event=events.api_requests.start_mission.request,
28
28
  handler=lambda event: start_mission_event_handler(state_machine, event),
29
29
  ),
30
30
  EventHandlerMapping(
31
31
  name="return_home_event",
32
- event=events.api_requests.return_home.input,
32
+ event=events.api_requests.return_home.request,
33
33
  handler=lambda event: return_home_event_handler(state_machine, event),
34
34
  ),
35
35
  EventHandlerMapping(
36
36
  name="stop_mission_event",
37
- event=events.api_requests.return_home.input,
37
+ event=events.api_requests.return_home.request,
38
38
  handler=lambda event: stop_mission_event_handler(state_machine, event),
39
39
  ),
40
40
  ]
@@ -22,17 +22,17 @@ class Home(EventHandlerBase):
22
22
  event_handlers: List[EventHandlerMapping] = [
23
23
  EventHandlerMapping(
24
24
  name="start_mission_event",
25
- event=events.api_requests.start_mission.input,
25
+ event=events.api_requests.start_mission.request,
26
26
  handler=lambda event: start_mission_event_handler(state_machine, event),
27
27
  ),
28
28
  EventHandlerMapping(
29
29
  name="return_home_event",
30
- event=events.api_requests.return_home.input,
30
+ event=events.api_requests.return_home.request,
31
31
  handler=lambda event: return_home_event_handler(state_machine, event),
32
32
  ),
33
33
  EventHandlerMapping(
34
34
  name="stop_mission_event",
35
- event=events.api_requests.return_home.input,
35
+ event=events.api_requests.return_home.request,
36
36
  handler=lambda event: stop_mission_event_handler(state_machine, event),
37
37
  ),
38
38
  EventHandlerMapping(
@@ -0,0 +1,43 @@
1
+ from collections.abc import Callable
2
+ from typing import TYPE_CHECKING, List, Optional
3
+
4
+ from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
5
+ from isar.models.events import Event
6
+ from isar.state_machine.utils.common_event_handlers import return_home_event_handler
7
+
8
+ if TYPE_CHECKING:
9
+ from isar.state_machine.state_machine import StateMachine
10
+
11
+
12
+ class InterventionNeeded(EventHandlerBase):
13
+
14
+ def __init__(self, state_machine: "StateMachine"):
15
+ events = state_machine.events
16
+
17
+ def release_intervention_needed_handler(
18
+ event: Event[bool],
19
+ ) -> Optional[Callable]:
20
+ if event.consume_event():
21
+ state_machine.events.api_requests.release_intervention_needed.response.trigger_event(
22
+ True
23
+ )
24
+ return state_machine.release_intervention_needed # type: ignore
25
+ return None
26
+
27
+ event_handlers: List[EventHandlerMapping] = [
28
+ EventHandlerMapping(
29
+ name="return_home_event",
30
+ event=events.api_requests.return_home.request,
31
+ handler=lambda event: return_home_event_handler(state_machine, event),
32
+ ),
33
+ EventHandlerMapping(
34
+ name="release_intervention_needed_event",
35
+ event=events.api_requests.release_intervention_needed.request,
36
+ handler=release_intervention_needed_handler,
37
+ ),
38
+ ]
39
+ super().__init__(
40
+ state_name="intervention_needed",
41
+ state_machine=state_machine,
42
+ event_handler_mappings=event_handlers,
43
+ )
@@ -49,12 +49,12 @@ class Monitor(EventHandlerBase):
49
49
  event_handlers: List[EventHandlerMapping] = [
50
50
  EventHandlerMapping(
51
51
  name="stop_mission_event",
52
- event=events.api_requests.stop_mission.input,
52
+ event=events.api_requests.stop_mission.request,
53
53
  handler=lambda event: stop_mission_event_handler(state_machine, event),
54
54
  ),
55
55
  EventHandlerMapping(
56
56
  name="pause_mission_event",
57
- event=events.api_requests.pause_mission.input,
57
+ event=events.api_requests.pause_mission.request,
58
58
  handler=_pause_mission_event_handler,
59
59
  ),
60
60
  EventHandlerMapping(
@@ -14,12 +14,12 @@ class Paused(EventHandlerBase):
14
14
  event_handlers: List[EventHandlerMapping] = [
15
15
  EventHandlerMapping(
16
16
  name="stop_mission_event",
17
- event=events.api_requests.stop_mission.input,
17
+ event=events.api_requests.stop_mission.request,
18
18
  handler=lambda event: state_machine.stop if event.consume_event() else None, # type: ignore
19
19
  ),
20
20
  EventHandlerMapping(
21
21
  name="resume_mission_event",
22
- event=events.api_requests.resume_mission.input,
22
+ event=events.api_requests.resume_mission.request,
23
23
  handler=lambda event: state_machine.resume if event.consume_event() else None, # type: ignore
24
24
  ),
25
25
  ]
@@ -41,7 +41,7 @@ class ReturningHome(EventHandlerBase):
41
41
  event_handlers: List[EventHandlerMapping] = [
42
42
  EventHandlerMapping(
43
43
  name="stop_mission_event",
44
- event=events.api_requests.stop_mission.input,
44
+ event=events.api_requests.stop_mission.request,
45
45
  handler=lambda event: stop_mission_event_handler(state_machine, event),
46
46
  ),
47
47
  EventHandlerMapping(
@@ -60,7 +60,7 @@ class ReturningHome(EventHandlerBase):
60
60
  ),
61
61
  EventHandlerMapping(
62
62
  name="start_mission_event",
63
- event=events.api_requests.start_mission.input,
63
+ event=events.api_requests.start_mission.request,
64
64
  handler=_start_mission_event_handler,
65
65
  ),
66
66
  EventHandlerMapping(
@@ -22,17 +22,17 @@ class RobotStandingStill(EventHandlerBase):
22
22
  event_handlers: List[EventHandlerMapping] = [
23
23
  EventHandlerMapping(
24
24
  name="start_mission_event",
25
- event=events.api_requests.start_mission.input,
25
+ event=events.api_requests.start_mission.request,
26
26
  handler=lambda event: start_mission_event_handler(state_machine, event),
27
27
  ),
28
28
  EventHandlerMapping(
29
29
  name="return_home_event",
30
- event=events.api_requests.return_home.input,
30
+ event=events.api_requests.return_home.request,
31
31
  handler=lambda event: return_home_event_handler(state_machine, event),
32
32
  ),
33
33
  EventHandlerMapping(
34
34
  name="stop_mission_event",
35
- event=events.api_requests.return_home.input,
35
+ event=events.api_requests.return_home.request,
36
36
  handler=lambda event: stop_mission_event_handler(state_machine, event),
37
37
  ),
38
38
  EventHandlerMapping(
@@ -31,7 +31,7 @@ class UnknownStatus(EventHandlerBase):
31
31
  event_handlers: List[EventHandlerMapping] = [
32
32
  EventHandlerMapping(
33
33
  name="stop_mission_event",
34
- event=events.api_requests.stop_mission.input,
34
+ event=events.api_requests.stop_mission.request,
35
35
  handler=lambda event: stop_mission_event_handler(state_machine, event),
36
36
  ),
37
37
  EventHandlerMapping(
@@ -12,6 +12,7 @@ class States(str, Enum):
12
12
  Offline = "offline"
13
13
  BlockedProtectiveStop = "blocked_protective_stop"
14
14
  UnknownStatus = "unknown_status"
15
+ InterventionNeeded = "intervention_needed"
15
16
 
16
17
  def __repr__(self):
17
18
  return self.value
@@ -11,3 +11,10 @@ def report_failed_mission_and_finalize(state_machine: "StateMachine") -> None:
11
11
  state_machine.current_mission.status = MissionStatus.Failed
12
12
  state_machine.publish_task_status(task=state_machine.current_task)
13
13
  state_machine._finalize()
14
+
15
+
16
+ def report_failed_return_home_and_intervention_needed(
17
+ state_machine: "StateMachine",
18
+ ) -> None:
19
+ error_message: str = "Return home failed."
20
+ state_machine.publish_intervention_needed(error_message=error_message)
@@ -29,7 +29,7 @@ def pause_mission(state_machine: "StateMachine") -> bool:
29
29
  paused_mission_response: ControlMissionResponse = (
30
30
  state_machine._make_control_mission_response()
31
31
  )
32
- state_machine.events.api_requests.pause_mission.output.put(
32
+ state_machine.events.api_requests.pause_mission.response.put(
33
33
  paused_mission_response
34
34
  )
35
35
 
@@ -35,7 +35,7 @@ def resume_mission(state_machine: "StateMachine") -> bool:
35
35
  resume_mission_response: ControlMissionResponse = (
36
36
  state_machine._make_control_mission_response()
37
37
  )
38
- state_machine.events.api_requests.resume_mission.output.put(
38
+ state_machine.events.api_requests.resume_mission.response.put(
39
39
  resume_mission_response
40
40
  )
41
41
 
@@ -11,12 +11,12 @@ from robot_interface.models.exceptions.robot_exceptions import (
11
11
  from robot_interface.models.mission.status import MissionStatus, TaskStatus
12
12
 
13
13
 
14
- def put_start_mission_on_queue(state_machine: "StateMachine") -> bool:
15
- state_machine.events.api_requests.start_mission.output.put(True)
14
+ def acknowledge_mission(state_machine: "StateMachine") -> bool:
15
+ state_machine.events.api_requests.start_mission.response.put(True)
16
16
  return True
17
17
 
18
18
 
19
- def initiate_mission(state_machine: "StateMachine") -> bool:
19
+ def prepare_state_machine_before_mission(state_machine: "StateMachine") -> bool:
20
20
  state_machine.logger.info(
21
21
  "Initiating mission:\n"
22
22
  f" Mission ID: {state_machine.current_mission.id}\n"
@@ -70,5 +70,5 @@ def trigger_start_mission_event(state_machine: "StateMachine") -> bool:
70
70
 
71
71
 
72
72
  def _initialization_failed(state_machine: "StateMachine") -> None:
73
- state_machine.events.api_requests.start_mission.output.put(False)
73
+ state_machine.events.api_requests.start_mission.response.put(False)
74
74
  state_machine._finalize()
@@ -31,7 +31,9 @@ def stop_mission_cleanup(state_machine: "StateMachine") -> bool:
31
31
  stopped_mission_response: ControlMissionResponse = (
32
32
  state_machine._make_control_mission_response()
33
33
  )
34
- state_machine.events.api_requests.stop_mission.output.put(stopped_mission_response)
34
+ state_machine.events.api_requests.stop_mission.response.put(
35
+ stopped_mission_response
36
+ )
35
37
  state_machine.publish_task_status(task=state_machine.current_task)
36
38
  state_machine._finalize()
37
39
  return True
@@ -41,7 +43,9 @@ def stop_mission_failed(state_machine: "StateMachine") -> bool:
41
43
  stopped_mission_response: ControlMissionResponse = (
42
44
  state_machine._make_control_mission_response()
43
45
  )
44
- state_machine.events.api_requests.stop_mission.output.put(stopped_mission_response)
46
+ state_machine.events.api_requests.stop_mission.response.put(
47
+ stopped_mission_response
48
+ )
45
49
  return True
46
50
 
47
51
 
@@ -51,7 +55,7 @@ def stop_return_home_mission_cleanup(state_machine: "StateMachine") -> bool:
51
55
  state_machine.reset_state_machine()
52
56
  return True
53
57
 
54
- if not state_machine.events.api_requests.start_mission.input.has_event():
58
+ if not state_machine.events.api_requests.start_mission.request.has_event():
55
59
  state_machine.current_mission.status = MissionStatus.Cancelled
56
60
 
57
61
  for task in state_machine.current_mission.tasks:
@@ -65,7 +69,7 @@ def stop_return_home_mission_cleanup(state_machine: "StateMachine") -> bool:
65
69
  stopped_mission_response: ControlMissionResponse = (
66
70
  state_machine._make_control_mission_response()
67
71
  )
68
- state_machine.events.api_requests.stop_mission.output.put(
72
+ state_machine.events.api_requests.stop_mission.response.put(
69
73
  stopped_mission_response
70
74
  )
71
75
 
@@ -74,10 +78,12 @@ def stop_return_home_mission_cleanup(state_machine: "StateMachine") -> bool:
74
78
 
75
79
 
76
80
  def stop_return_home_mission_failed(state_machine: "StateMachine") -> bool:
77
- if state_machine.events.api_requests.start_mission.input.has_event():
81
+ if state_machine.events.api_requests.start_mission.request.has_event():
78
82
  return True
79
83
  stopped_mission_response: ControlMissionResponse = (
80
84
  state_machine._make_control_mission_response()
81
85
  )
82
- state_machine.events.api_requests.stop_mission.output.put(stopped_mission_response)
86
+ state_machine.events.api_requests.stop_mission.response.put(
87
+ stopped_mission_response
88
+ )
83
89
  return True
@@ -7,9 +7,9 @@ from isar.state_machine.transitions.functions.finish_mission import finish_missi
7
7
  from isar.state_machine.transitions.functions.pause import pause_mission
8
8
  from isar.state_machine.transitions.functions.resume import resume_mission
9
9
  from isar.state_machine.transitions.functions.start_mission import (
10
+ acknowledge_mission,
10
11
  initialize_robot,
11
- initiate_mission,
12
- put_start_mission_on_queue,
12
+ prepare_state_machine_before_mission,
13
13
  set_mission_to_in_progress,
14
14
  trigger_start_mission_event,
15
15
  )
@@ -94,9 +94,9 @@ def get_mission_transitions(state_machine: "StateMachine") -> List[dict]:
94
94
  state_machine.robot_standing_still_state,
95
95
  ],
96
96
  "dest": state_machine.monitor_state,
97
- "prepare": def_transition(state_machine, put_start_mission_on_queue),
97
+ "prepare": def_transition(state_machine, acknowledge_mission),
98
98
  "conditions": [
99
- def_transition(state_machine, initiate_mission),
99
+ def_transition(state_machine, prepare_state_machine_before_mission),
100
100
  def_transition(state_machine, initialize_robot),
101
101
  ],
102
102
  "before": [
@@ -122,12 +122,6 @@ def get_mission_transitions(state_machine: "StateMachine") -> List[dict]:
122
122
  "dest": state_machine.home_state,
123
123
  "before": def_transition(state_machine, report_failed_mission_and_finalize),
124
124
  },
125
- {
126
- "trigger": "request_mission_start",
127
- "source": state_machine.returning_home_state,
128
- "dest": state_machine.returning_home_state,
129
- "before": def_transition(state_machine, report_failed_mission_and_finalize),
130
- },
131
125
  {
132
126
  "trigger": "mission_failed_to_start",
133
127
  "source": [state_machine.monitor_state, state_machine.returning_home_state],
@@ -2,6 +2,7 @@ from typing import TYPE_CHECKING, List
2
2
 
3
3
  from isar.state_machine.transitions.functions.fail_mission import (
4
4
  report_failed_mission_and_finalize,
5
+ report_failed_return_home_and_intervention_needed,
5
6
  )
6
7
  from isar.state_machine.transitions.functions.return_home import (
7
8
  return_home_finished,
@@ -26,6 +27,7 @@ def get_return_home_transitions(state_machine: "StateMachine") -> List[dict]:
26
27
  state_machine.await_next_mission_state,
27
28
  state_machine.home_state,
28
29
  state_machine.robot_standing_still_state,
30
+ state_machine.intervention_needed_state,
29
31
  ],
30
32
  "dest": state_machine.returning_home_state,
31
33
  "conditions": [
@@ -62,8 +64,18 @@ def get_return_home_transitions(state_machine: "StateMachine") -> List[dict]:
62
64
  {
63
65
  "trigger": "return_home_failed",
64
66
  "source": state_machine.returning_home_state,
65
- "dest": state_machine.robot_standing_still_state,
66
- "before": def_transition(state_machine, report_failed_mission_and_finalize),
67
+ "dest": state_machine.intervention_needed_state,
68
+ "before": [
69
+ def_transition(
70
+ state_machine, report_failed_return_home_and_intervention_needed
71
+ ),
72
+ def_transition(state_machine, report_failed_mission_and_finalize),
73
+ ],
74
+ },
75
+ {
76
+ "trigger": "release_intervention_needed",
77
+ "source": state_machine.intervention_needed_state,
78
+ "dest": state_machine.unknown_status_state,
67
79
  },
68
80
  ]
69
81
  return return_home_transitions
@@ -24,7 +24,7 @@ def return_home_event_handler(
24
24
  state_machine: "StateMachine", event: Event[bool]
25
25
  ) -> Optional[Callable]:
26
26
  if event.consume_event():
27
- state_machine.events.api_requests.return_home.output.put(True)
27
+ state_machine.events.api_requests.return_home.response.put(True)
28
28
  return state_machine.request_return_home # type: ignore
29
29
  return None
30
30
 
@@ -48,7 +48,7 @@ def stop_mission_event_handler(
48
48
  if state_machine.current_mission.id == mission_id or mission_id == "":
49
49
  return state_machine.stop # type: ignore
50
50
  else:
51
- state_machine.events.api_requests.stop_mission.output.put(
51
+ state_machine.events.api_requests.stop_mission.response.put(
52
52
  ControlMissionResponse(
53
53
  mission_id=mission_id,
54
54
  mission_status=state_machine.current_mission.status,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: isar
3
- Version: 1.31.1
3
+ Version: 1.32.1
4
4
  Summary: Integration and Supervisory control of Autonomous Robots
5
5
  Author-email: Equinor ASA <fg_robots_dev@equinor.com>
6
6
  License: Eclipse Public License version 2.0
@@ -1,22 +1,22 @@
1
1
  isar/__init__.py,sha256=cH8p8bVveu3FUL6kBhldcSlLaoHgD82Kd0-SwSNfGXw,87
2
2
  isar/modules.py,sha256=1QdULg-9gV5Ds4pMV4IQTlImSgsVwqs-g15ifllF2kg,4757
3
- isar/script.py,sha256=8wDcpsbOdFzSkkOOUBFxz9OJYzBiqnTDqr-175tiyL4,6211
3
+ isar/script.py,sha256=LCb7CHvNyZhQz1OaQ-BUX8w7RDmu975zA0kL6FPwfzk,5912
4
4
  isar/apis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- isar/apis/api.py,sha256=B0fVZPKtnvrxzk48xoazGPYsJVjjBH4IL6glDJ3PGWI,13328
5
+ isar/apis/api.py,sha256=VM_WBlHJ4Juv9A0FvaUTeaMVYCN6a7pAojxIGCmDtf0,14154
6
6
  isar/apis/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  isar/apis/models/models.py,sha256=GMOss2C8lBeRFV7E37mLwSOM6RhiyLQLcLBRzm_51d4,1835
8
- isar/apis/models/start_mission_definition.py,sha256=m9M5dZCmvRM1b4N8xYGquCSplSr4GDk376s2QoVL8F4,6231
8
+ isar/apis/models/start_mission_definition.py,sha256=v-wt1XDd53Sw7DCdFAkxBBut-xd_uGJa7qMJnE3VI9k,6364
9
9
  isar/apis/robot_control/robot_controller.py,sha256=0EHjMqOBdfJlMrCItGPz5X-4X2kc-2XlNnUU2LOcLfc,1219
10
10
  isar/apis/schedule/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
- isar/apis/schedule/scheduling_controller.py,sha256=yQM2HMgelBnbkzPR_tLHOY2EbThUcSO5jMA6Xtp5FQA,9915
11
+ isar/apis/schedule/scheduling_controller.py,sha256=S93DNyOWqVYAe3EnBnWuoCHLkeVFFjkR7ayBRw9J7f4,10603
12
12
  isar/apis/security/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  isar/apis/security/authentication.py,sha256=Se2puhe2TUBmfio2RLma52-VSLRhqvWgu0Cd1bhdwMo,2000
14
14
  isar/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
15
  isar/config/configuration_error.py,sha256=rO6WOhafX6xvVib8WxV-eY483Z0PpN-9PxGsq5ATfKc,46
16
- isar/config/log.py,sha256=_zeHrsI4XqoHc1Um50PLHFjlwGiClM_M5CzcXoqwZuY,1380
17
- isar/config/logging.conf,sha256=mYO1xf27gAopEMHhGzY7-mwyfN16rwRLkPNMvy3zn2g,1127
16
+ isar/config/log.py,sha256=f_mLLz5RSa0kZkdpi1m0iMdwwDc4RQp12mnT6gu2exE,1303
17
+ isar/config/logging.conf,sha256=a7ZBvZkrMDaPU3eRGAjL_eZz6hZsa6BaRJOfx8mbnnM,629
18
18
  isar/config/open_telemetry.py,sha256=965IlPi7urVTL0Yy4uYu4e1P2Ne6HC_RXizM2vCX9kY,2371
19
- isar/config/settings.py,sha256=-fBxs0TUGmoCX4nF1Rwg0YMZ-WQ6qsqFZpWHxqwOrlk,13029
19
+ isar/config/settings.py,sha256=dRQwL6qCnFoyJkMiBxzVv_JwTfs8UJTnuPnwPlQFhUM,13187
20
20
  isar/config/certs/ca-cert.pem,sha256=qoNljfad_qcMxhXJIUMLd7nT-Qwf_d4dYSdoOFEOE8I,2179
21
21
  isar/config/keyvault/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
22
  isar/config/keyvault/keyvault_error.py,sha256=zvPCsZLjboxsxthYkxpRERCTFxYV8R5WmACewAUQLwk,41
@@ -42,7 +42,7 @@ isar/mission_planner/mission_planner_interface.py,sha256=UgpPIM4FbrWOD7fGY3Ul64k
42
42
  isar/mission_planner/sequential_task_selector.py,sha256=66agRPHuJnEa1vArPyty4muTasAZ50XPjjrSaTdY_Cc,643
43
43
  isar/mission_planner/task_selector_interface.py,sha256=pnLeaGPIuyXThcflZ_A7YL2b2xQjFT88hAZidkMomxU,707
44
44
  isar/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
- isar/models/events.py,sha256=9NgvX68Nb8WJyuafD-NYyxxb2Bo9zN15ozNPKURyrxk,3782
45
+ isar/models/events.py,sha256=Q9YaHSsjI6gS-mZ16HLEXpbSBuEFcgHMxG_MeEEfdBo,3870
46
46
  isar/robot/robot.py,sha256=keqsYmfRlyIC4CWkMG0erDt_4uIC0IPvyG2ni4MemyI,5350
47
47
  isar/robot/robot_start_mission.py,sha256=RPYH9VtXDFdPqhOpt6kSbT17RHkJQPKkQ6d4784_pFE,3210
48
48
  isar/robot/robot_status.py,sha256=NMZZOV1DHOVrJwMsSjKbDSaSiWYnrfAW1cQHtc6heKk,1903
@@ -59,42 +59,43 @@ isar/services/service_connections/mqtt/robot_heartbeat_publisher.py,sha256=_bUOG
59
59
  isar/services/service_connections/mqtt/robot_info_publisher.py,sha256=AxokGk51hRPTxxD2r0P9braPJCMrf1InaCxrUBKkF4g,1402
60
60
  isar/services/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
61
61
  isar/services/utilities/robot_utilities.py,sha256=4zCigsLXfqDC8POHchktSq81zr1_pTaRve_LQsVr6Mk,514
62
- isar/services/utilities/scheduling_utilities.py,sha256=O-V6EBfYcx8HMxa2bf0QBxX7Km5m1hBf9h4P5RGlMfY,10907
62
+ isar/services/utilities/scheduling_utilities.py,sha256=jxwvVahRJeuoYDtOcVyLwm1BTFKKq92icjR-bA_R0bg,11674
63
63
  isar/services/utilities/threaded_request.py,sha256=py4G-_RjnIdHljmKFAcQ6ddqMmp-ZYV39Ece-dqRqjs,1874
64
64
  isar/state_machine/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
65
- isar/state_machine/state_machine.py,sha256=RDpUngEf1BAVXDRC52FkUVMSIVhmfTEgQw_kDC06WPE,15663
66
- isar/state_machine/states_enum.py,sha256=Z3dO6k6JmQAZ1lzcR58oVCxoCky_-ZS9MaL3RSaNbZ4,434
65
+ isar/state_machine/state_machine.py,sha256=vrsQfDyUUHOh20nEZ0qZaMUmSb2KkMx1fnWHyfHdRWc,16670
66
+ isar/state_machine/states_enum.py,sha256=4XZ6dGGjXVZ8PwQCnAIH3MMNbMP2h3bmmPHFk6m_RlY,481
67
67
  isar/state_machine/states/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
68
- isar/state_machine/states/await_next_mission.py,sha256=RDWqGFdQ6PX7AtSjlrR-fH6s441mKooOpkceTO7pvkc,1873
68
+ isar/state_machine/states/await_next_mission.py,sha256=VfsJFHh_G371bUVkJgh_5o7d0DLNeMexV35Bw6Jsj7M,1879
69
69
  isar/state_machine/states/blocked_protective_stop.py,sha256=GEOvxnHXjpCsrh3aa8Idtn1zMYv5HLQzj9qQAq8HvaU,1180
70
- isar/state_machine/states/home.py,sha256=NUVmSmwG5_N7ZDLfbS0eWMnDVpVXmADrZXjh-s_klks,1862
71
- isar/state_machine/states/monitor.py,sha256=QEV_lc-lHoFAOK2e6HD4FdzpN607LbqZx2Y9-LknrLA,3666
70
+ isar/state_machine/states/home.py,sha256=tbwWoxQdrZb4zkqgXpDjzTZD-IqKTgHoC_MmFdTEjKQ,1868
71
+ isar/state_machine/states/intervention_needed.py,sha256=A0QYz1vD1tDKAealihXDuoGuMLtXrRfn_AwFoaUhT_Q,1640
72
+ isar/state_machine/states/monitor.py,sha256=366CZSEf1HRVqpm0RkFjIDGnc_9fjeer7qwu1fvbcKQ,3670
72
73
  isar/state_machine/states/offline.py,sha256=5wdNzC1wG0cWrpuT_r_mk8UNFHA4QSyg8ejXUTAg4Io,1137
73
- isar/state_machine/states/paused.py,sha256=tegYTUioSIKP2TUiMqBLNp9owyLwcuEM3a_LyKZSwQM,1087
74
- isar/state_machine/states/returning_home.py,sha256=bO8i61xzQAvT0upgK1Fi_OzyRfsRaZlfK3A_2-tThpo,3420
75
- isar/state_machine/states/robot_standing_still.py,sha256=ee2ORQD0IfUMMBz7bpuUMyA_sMYtdiy17h48KrZJxRc,1897
74
+ isar/state_machine/states/paused.py,sha256=osmLZhm0-2jcZmNRauveeidCBYayDZvLy-1TNYv6CgQ,1091
75
+ isar/state_machine/states/returning_home.py,sha256=6NEszX7phRN46ST25YFZZja75Z1RHSswWSv7V1-26wU,3424
76
+ isar/state_machine/states/robot_standing_still.py,sha256=78W465FlVBCTUpmjQHzO5MT7fI6_M8Rh9gS-M8Y9irs,1903
76
77
  isar/state_machine/states/stopping.py,sha256=fMXXvcXtzML-Q5A-uRD_gXePy51fnt9jhOTVFN-3qqA,2420
77
- isar/state_machine/states/unknown_status.py,sha256=m9XoGGgdjhjX-LRW31mwiU8r7LREB0yOSv2DFZtZH7Y,1789
78
- isar/state_machine/transitions/mission.py,sha256=Lsiee_hSn5wd7KWpmvIdaG-49f6HGdkCdiXAo5L0ciE,5803
79
- isar/state_machine/transitions/return_home.py,sha256=6aBpKpozT48RJ__w13gv-r7dSz-fEOCzkAuKq5Hwm6k,2728
78
+ isar/state_machine/states/unknown_status.py,sha256=Y-g9cgme5zriyZ6YUzFRYhOvv9ZylCSwfaY8MJ7xEJ0,1791
79
+ isar/state_machine/transitions/mission.py,sha256=mUOtEyK2UX_kdK-_L4wq5a60882H2KnlxImO72YMtuo,5557
80
+ isar/state_machine/transitions/return_home.py,sha256=Vy_Q_mmTj4wsWL8qxUkmC1CTXEzGsdKNYb4V4rw2IeE,3202
80
81
  isar/state_machine/transitions/robot_status.py,sha256=c1ceyWRGCtx-KTDtxHXRD7oPbt8TQ2ej24A0wyim8vc,2720
81
- isar/state_machine/transitions/functions/fail_mission.py,sha256=_6HqBMALDinFZ4yh5GMpeqqgV5tw5i8OVMj5UDdqesg,495
82
+ isar/state_machine/transitions/functions/fail_mission.py,sha256=jHHXhfQVYQEzCXgTEhv5e6uEK9p6iDPFFXqS9bzs_-A,720
82
83
  isar/state_machine/transitions/functions/finish_mission.py,sha256=TRQrk7HdllmAkwsp25HRZAFAk46Y1hLx3jmkIAKrHDI,1442
83
- isar/state_machine/transitions/functions/pause.py,sha256=oaIFd4aZnbeaHb-EGQE9ozJctskqXKsRKkNc68M8sp0,1975
84
- isar/state_machine/transitions/functions/resume.py,sha256=HgAEn4jQOPkVPWWZCAh7dqnIerdF8nGcgFcZ1KsCNSQ,2104
84
+ isar/state_machine/transitions/functions/pause.py,sha256=gWr-s76gL0-otrZxCBNmTxUicrAVsdNWDQmHSAOvs6E,1977
85
+ isar/state_machine/transitions/functions/resume.py,sha256=ji4GjQvQQCr_jYRUGYHSYt-vePtO2z7VAUeKF-hyLBw,2106
85
86
  isar/state_machine/transitions/functions/return_home.py,sha256=UlniwYvpz74hxqgN0TyVv3LCmiMsqsosKEtEGLqkNj0,1139
86
87
  isar/state_machine/transitions/functions/robot_status.py,sha256=P1Cu8xVysbiKRKL4E8mSyoL2-72HfxrLvvOcdnBOlvw,889
87
- isar/state_machine/transitions/functions/start_mission.py,sha256=ricRfhLH1_lNpqWxneMZcm7ps2YfY6sQGHkiT0Glf6M,2564
88
- isar/state_machine/transitions/functions/stop.py,sha256=5tPYE4WB98iammX81wEdrAUvX0huJ2PBooVaY_7i6GY,2902
88
+ isar/state_machine/transitions/functions/start_mission.py,sha256=PcD9ANNN3Hxyq6hzvpISMiR94-y1BPNupU-wlRysqT8,2581
89
+ isar/state_machine/transitions/functions/stop.py,sha256=ZG33TK3VuJwT-LAQ0a3thgt714yCIu42_bo-u1-V1J0,2956
89
90
  isar/state_machine/transitions/functions/utils.py,sha256=Wa72Ocq4QT1E6qkpEJZQ3h5o33pGvx7Tlkt2JZ2Grbk,314
90
- isar/state_machine/utils/common_event_handlers.py,sha256=Grv34hVwDjzi9BizqRLMJAKtRpucuklXGR3hoC_0kkQ,5773
91
+ isar/state_machine/utils/common_event_handlers.py,sha256=hyzOvj5EA4Ob9DjbtbnPKge_t6Umd0_Cc-b6wfy8CP8,5777
91
92
  isar/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
92
93
  isar/storage/blob_storage.py,sha256=D67y3Z939iXoRxs8npOuKOhgs2o6dYz2ivTm5IXXhJE,3168
93
94
  isar/storage/local_storage.py,sha256=Bnmoi5gyN8r-oRh0aHrOdGqaH3JqRScFKMRXYojW5kY,1855
94
95
  isar/storage/storage_interface.py,sha256=DYDry4I7aZpDHJhsBF6s8zrgokFAc7fdKJKfA8AvL7o,828
95
96
  isar/storage/uploader.py,sha256=uD1DzvJ2yYtNAwQGa7UD7kNOxZfKxJ1cCdi7sfOVZ10,9443
96
97
  isar/storage/utilities.py,sha256=oLH0Rp7UtrQQdilfITnmXO1Z0ExdeDhBImYHid55vBA,3449
97
- isar-1.31.1.dist-info/licenses/LICENSE,sha256=3fc2-ebLwHWwzfQbulGNRdcNob3SBQeCfEVUDYxsuqw,14058
98
+ isar-1.32.1.dist-info/licenses/LICENSE,sha256=3fc2-ebLwHWwzfQbulGNRdcNob3SBQeCfEVUDYxsuqw,14058
98
99
  robot_interface/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
99
100
  robot_interface/robot_interface.py,sha256=-jCAKkZ2eiyzUyHVQmOzw4hMgLWR7pE8MHj-WZo85ZY,7978
100
101
  robot_interface/test_robot_interface.py,sha256=FV1urn7SbsMyWBIcTKjsBwAG4IsXeZ6pLHE0mA9EGGs,692
@@ -106,7 +107,7 @@ robot_interface/models/inspection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeR
106
107
  robot_interface/models/inspection/inspection.py,sha256=2T8czQcNt9J1M96tKGQA6P3s5CikdZ7-0RevXQ4-CfA,2520
107
108
  robot_interface/models/mission/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
108
109
  robot_interface/models/mission/mission.py,sha256=MQ9p5cuclLXexaZu9bkDh5-aN99eunvYC0vP-Z_kUwI,960
109
- robot_interface/models/mission/status.py,sha256=UOCARLfLxLFXJEjfIH7aXYXO7xajOKBJsxz-Wd6gZQ4,740
110
+ robot_interface/models/mission/status.py,sha256=rlgU9Xpsk-rOHF-z6ziIMCYpOAqtu7lOMIUY1e0yZCY,786
110
111
  robot_interface/models/mission/task.py,sha256=YzaqJ_KIIm-3S2Y2-BG4Pdkc8sjFMzMx5jj8FtXSmFg,4744
111
112
  robot_interface/models/robots/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
112
113
  robot_interface/models/robots/battery_state.py,sha256=ktOtJ8ltdK0k_i7BoqYfhc5dbOzIG6Oo-uWC67fCWio,98
@@ -114,12 +115,12 @@ robot_interface/models/robots/media.py,sha256=8A-CuuubfngzPprs6zWB9hSaqe3jzgsE8r
114
115
  robot_interface/models/robots/robot_model.py,sha256=-0jNKWPcEgtF_2klb1It3u0SCoAR0hSW9nce58Zq0Co,417
115
116
  robot_interface/telemetry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
116
117
  robot_interface/telemetry/mqtt_client.py,sha256=ueXdtIFNCwciTj4spvdJj9emd-IOmUuJjpsXQSSWZPY,2987
117
- robot_interface/telemetry/payloads.py,sha256=PpvmV7XeGgfhc_aRUYFOdwBTwV2x8TwTBINJ-rKchVw,2804
118
+ robot_interface/telemetry/payloads.py,sha256=Fqkfv77_T2Ttk5EjWRU5HH0XAxFhIuz7k-LMftuXk2k,2927
118
119
  robot_interface/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
119
120
  robot_interface/utilities/json_service.py,sha256=qkzVkb60Gi_pto-b5n1vNzCrQze2yqgIJqSLNLYj1Fg,1034
120
121
  robot_interface/utilities/uuid_string_factory.py,sha256=_NQIbBQ56w0qqO0MUDP6aPpHbxW7ATRhK8HnQiBSLkc,76
121
- isar-1.31.1.dist-info/METADATA,sha256=bilh123vt-dD-IraRBTR4yhxI1YJim_NydR9zPveUYA,31217
122
- isar-1.31.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
123
- isar-1.31.1.dist-info/entry_points.txt,sha256=TFam7uNNw7J0iiDYzsH2gfG0u1eV1wh3JTw_HkhgKLk,49
124
- isar-1.31.1.dist-info/top_level.txt,sha256=UwIML2RtuQKCyJJkatcSnyp6-ldDjboB9k9JgKipO-U,21
125
- isar-1.31.1.dist-info/RECORD,,
122
+ isar-1.32.1.dist-info/METADATA,sha256=AOF9icV4ETW8Ddolnlh6hQzjWm1B_3Z9Go1B4q3WfOQ,31217
123
+ isar-1.32.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
124
+ isar-1.32.1.dist-info/entry_points.txt,sha256=TFam7uNNw7J0iiDYzsH2gfG0u1eV1wh3JTw_HkhgKLk,49
125
+ isar-1.32.1.dist-info/top_level.txt,sha256=UwIML2RtuQKCyJJkatcSnyp6-ldDjboB9k9JgKipO-U,21
126
+ isar-1.32.1.dist-info/RECORD,,
@@ -29,3 +29,4 @@ class RobotStatus(Enum):
29
29
  Blocked = "blocked"
30
30
  BlockedProtectiveStop = "blockedprotectivestop"
31
31
  ReturningHome = "returninghome"
32
+ InterventionNeeded = "interventionneeded"
@@ -138,3 +138,11 @@ class InspectionValuePayload:
138
138
  class StartUpMessagePayload:
139
139
  isar_id: str
140
140
  timestamp: datetime
141
+
142
+
143
+ @dataclass
144
+ class InterventionNeededPayload:
145
+ isar_id: str
146
+ robot_name: str
147
+ reason: str
148
+ timestamp: datetime
File without changes