isar 1.33.5__py3-none-any.whl → 1.33.7__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 (40) hide show
  1. isar/apis/api.py +34 -0
  2. isar/apis/models/models.py +5 -0
  3. isar/apis/schedule/scheduling_controller.py +34 -0
  4. isar/config/settings.py +4 -0
  5. isar/models/events.py +19 -1
  6. isar/robot/robot.py +50 -1
  7. isar/robot/robot_battery.py +60 -0
  8. isar/robot/robot_pause_mission.py +63 -0
  9. isar/robot/robot_status.py +23 -10
  10. isar/robot/robot_stop_mission.py +1 -1
  11. isar/services/utilities/scheduling_utilities.py +50 -4
  12. isar/state_machine/state_machine.py +27 -7
  13. isar/state_machine/states/await_next_mission.py +19 -1
  14. isar/state_machine/states/blocked_protective_stop.py +9 -9
  15. isar/state_machine/states/going_to_lockdown.py +80 -0
  16. isar/state_machine/states/home.py +27 -4
  17. isar/state_machine/states/lockdown.py +37 -0
  18. isar/state_machine/states/monitor.py +16 -0
  19. isar/state_machine/states/offline.py +9 -10
  20. isar/state_machine/states/paused.py +19 -1
  21. isar/state_machine/states/pausing.py +74 -0
  22. isar/state_machine/states/pausing_return_home.py +74 -0
  23. isar/state_machine/states/recharging.py +16 -0
  24. isar/state_machine/states/return_home_paused.py +17 -1
  25. isar/state_machine/states/returning_home.py +18 -2
  26. isar/state_machine/states/stopping_go_to_lockdown.py +79 -0
  27. isar/state_machine/states_enum.py +5 -0
  28. isar/state_machine/transitions/functions/fail_mission.py +7 -0
  29. isar/state_machine/transitions/functions/pause.py +20 -80
  30. isar/state_machine/transitions/functions/robot_status.py +15 -0
  31. isar/state_machine/transitions/mission.py +55 -10
  32. isar/state_machine/transitions/return_home.py +62 -0
  33. isar/state_machine/utils/common_event_handlers.py +5 -2
  34. {isar-1.33.5.dist-info → isar-1.33.7.dist-info}/METADATA +1 -1
  35. {isar-1.33.5.dist-info → isar-1.33.7.dist-info}/RECORD +40 -33
  36. robot_interface/models/mission/status.py +2 -0
  37. {isar-1.33.5.dist-info → isar-1.33.7.dist-info}/WHEEL +0 -0
  38. {isar-1.33.5.dist-info → isar-1.33.7.dist-info}/entry_points.txt +0 -0
  39. {isar-1.33.5.dist-info → isar-1.33.7.dist-info}/licenses/LICENSE +0 -0
  40. {isar-1.33.5.dist-info → isar-1.33.7.dist-info}/top_level.txt +0 -0
@@ -1,11 +1,13 @@
1
- from typing import TYPE_CHECKING, List
1
+ from typing import TYPE_CHECKING, Callable, List, Optional
2
2
 
3
+ from isar.apis.models.models import LockdownResponse
3
4
  from isar.config.settings import settings
4
5
  from isar.eventhandlers.eventhandler import (
5
6
  EventHandlerBase,
6
7
  EventHandlerMapping,
7
8
  TimeoutHandlerMapping,
8
9
  )
10
+ from isar.models.events import Event
9
11
  from isar.state_machine.utils.common_event_handlers import (
10
12
  return_home_event_handler,
11
13
  start_mission_event_handler,
@@ -21,6 +23,17 @@ class AwaitNextMission(EventHandlerBase):
21
23
  def __init__(self, state_machine: "StateMachine"):
22
24
  events = state_machine.events
23
25
 
26
+ def _send_to_lockdown_event_handler(
27
+ event: Event[bool],
28
+ ) -> Optional[Callable]:
29
+ should_lockdown: bool = event.consume_event()
30
+ if should_lockdown:
31
+ events.api_requests.send_to_lockdown.response.trigger_event(
32
+ LockdownResponse(lockdown_started=True)
33
+ )
34
+ return state_machine.request_lockdown_mission # type: ignore
35
+ return None
36
+
24
37
  event_handlers: List[EventHandlerMapping] = [
25
38
  EventHandlerMapping(
26
39
  name="start_mission_event",
@@ -39,6 +52,11 @@ class AwaitNextMission(EventHandlerBase):
39
52
  event=events.api_requests.return_home.request,
40
53
  handler=lambda event: stop_mission_event_handler(state_machine, event),
41
54
  ),
55
+ EventHandlerMapping(
56
+ name="send_to_lockdown_event",
57
+ event=events.api_requests.send_to_lockdown.request,
58
+ handler=_send_to_lockdown_event_handler,
59
+ ),
42
60
  ]
43
61
 
44
62
  timers: List[TimeoutHandlerMapping] = [
@@ -1,7 +1,7 @@
1
1
  from typing import TYPE_CHECKING, List
2
2
 
3
3
  from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
4
- from isar.models.events import Event
4
+ from isar.state_machine.utils.common_event_handlers import robot_status_event_handler
5
5
  from robot_interface.models.mission.status import RobotStatus
6
6
 
7
7
  if TYPE_CHECKING:
@@ -11,19 +11,19 @@ if TYPE_CHECKING:
11
11
  class BlockedProtectiveStop(EventHandlerBase):
12
12
 
13
13
  def __init__(self, state_machine: "StateMachine"):
14
+ events = state_machine.events
14
15
  shared_state = state_machine.shared_state
15
16
 
16
- def _robot_status_event_handler(event: Event[RobotStatus]):
17
- robot_status: RobotStatus = event.check()
18
- if robot_status != RobotStatus.BlockedProtectiveStop:
19
- return state_machine.robot_status_changed # type: ignore
20
- return None
21
-
22
17
  event_handlers: List[EventHandlerMapping] = [
23
18
  EventHandlerMapping(
24
19
  name="robot_status_event",
25
- event=shared_state.robot_status,
26
- handler=_robot_status_event_handler,
20
+ event=events.robot_service_events.robot_status_changed,
21
+ handler=lambda event: robot_status_event_handler(
22
+ state_machine=state_machine,
23
+ expected_status=RobotStatus.BlockedProtectiveStop,
24
+ status_changed_event=event,
25
+ status_event=shared_state.robot_status,
26
+ ),
27
27
  ),
28
28
  ]
29
29
  super().__init__(
@@ -0,0 +1,80 @@
1
+ from typing import TYPE_CHECKING, Callable, List, Optional
2
+
3
+ from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
4
+ from isar.models.events import Event
5
+ from isar.state_machine.utils.common_event_handlers import (
6
+ mission_started_event_handler,
7
+ task_status_event_handler,
8
+ task_status_failed_event_handler,
9
+ )
10
+ from robot_interface.models.exceptions.robot_exceptions import ErrorMessage, ErrorReason
11
+ from robot_interface.models.mission.status import TaskStatus
12
+
13
+ if TYPE_CHECKING:
14
+ from isar.state_machine.state_machine import StateMachine
15
+
16
+
17
+ class GoingToLockdown(EventHandlerBase):
18
+
19
+ def __init__(self, state_machine: "StateMachine"):
20
+ events = state_machine.events
21
+
22
+ def _handle_task_completed(status: TaskStatus):
23
+ if status != TaskStatus.Successful:
24
+ state_machine.current_mission.error_message = ErrorMessage(
25
+ error_reason=ErrorReason.RobotActionException,
26
+ error_description="Lock down mission failed.",
27
+ )
28
+ return state_machine.lockdown_mission_failed # type: ignore
29
+ return state_machine.reached_lockdown # type: ignore
30
+
31
+ def _mission_failed_event_handler(
32
+ event: Event[Optional[ErrorMessage]],
33
+ ) -> Optional[Callable]:
34
+ mission_failed: Optional[ErrorMessage] = event.consume_event()
35
+ if mission_failed is not None:
36
+ state_machine.logger.warning(
37
+ f"Failed to initiate mission "
38
+ f"{str(state_machine.current_mission.id)[:8]} because: "
39
+ f"{mission_failed.error_description}"
40
+ )
41
+ state_machine.current_mission.error_message = ErrorMessage(
42
+ error_reason=mission_failed.error_reason,
43
+ error_description=mission_failed.error_description,
44
+ )
45
+ return state_machine.lockdown_mission_failed # type: ignore
46
+ return None
47
+
48
+ event_handlers: List[EventHandlerMapping] = [
49
+ EventHandlerMapping(
50
+ name="mission_started_event",
51
+ event=events.robot_service_events.mission_started,
52
+ handler=lambda event: mission_started_event_handler(
53
+ state_machine, event
54
+ ),
55
+ ),
56
+ EventHandlerMapping(
57
+ name="mission_failed_event",
58
+ event=events.robot_service_events.mission_failed,
59
+ handler=_mission_failed_event_handler,
60
+ ),
61
+ EventHandlerMapping(
62
+ name="task_status_failed_event",
63
+ event=events.robot_service_events.task_status_failed,
64
+ handler=lambda event: task_status_failed_event_handler(
65
+ state_machine, _handle_task_completed, event
66
+ ),
67
+ ),
68
+ EventHandlerMapping(
69
+ name="task_status_event",
70
+ event=events.robot_service_events.task_status_updated,
71
+ handler=lambda event: task_status_event_handler(
72
+ state_machine, _handle_task_completed, event
73
+ ),
74
+ ),
75
+ ]
76
+ super().__init__(
77
+ state_name="going_to_lockdown",
78
+ state_machine=state_machine,
79
+ event_handler_mappings=event_handlers,
80
+ )
@@ -1,5 +1,6 @@
1
1
  from typing import TYPE_CHECKING, Callable, List, Optional
2
2
 
3
+ from isar.apis.models.models import LockdownResponse
3
4
  from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
4
5
  from isar.models.events import Event
5
6
  from isar.state_machine.utils.common_event_handlers import (
@@ -19,10 +20,23 @@ class Home(EventHandlerBase):
19
20
  events = state_machine.events
20
21
  shared_state = state_machine.shared_state
21
22
 
23
+ def _send_to_lockdown_event_handler(event: Event[bool]):
24
+ should_send_robot_home: bool = event.consume_event()
25
+ if should_send_robot_home:
26
+ events.api_requests.send_to_lockdown.response.trigger_event(
27
+ LockdownResponse(lockdown_started=True)
28
+ )
29
+ return state_machine.reached_lockdown # type: ignore
30
+ return None
31
+
22
32
  def _robot_status_event_handler(
23
- event: Event[RobotStatus],
33
+ state_machine: "StateMachine",
34
+ status_changed_event: Event[bool],
35
+ status_event: Event[RobotStatus],
24
36
  ) -> Optional[Callable]:
25
- robot_status: RobotStatus = event.check()
37
+ if not status_changed_event.consume_event():
38
+ return None
39
+ robot_status: Optional[RobotStatus] = status_event.check()
26
40
  if not (
27
41
  robot_status == RobotStatus.Available
28
42
  or robot_status == RobotStatus.Home
@@ -50,8 +64,17 @@ class Home(EventHandlerBase):
50
64
  ),
51
65
  EventHandlerMapping(
52
66
  name="robot_status_event",
53
- event=shared_state.robot_status,
54
- handler=_robot_status_event_handler,
67
+ event=events.robot_service_events.robot_status_changed,
68
+ handler=lambda event: _robot_status_event_handler(
69
+ state_machine=state_machine,
70
+ status_changed_event=event,
71
+ status_event=shared_state.robot_status,
72
+ ),
73
+ ),
74
+ EventHandlerMapping(
75
+ name="send_to_lockdown_event",
76
+ event=events.api_requests.send_to_lockdown.request,
77
+ handler=_send_to_lockdown_event_handler,
55
78
  ),
56
79
  ]
57
80
  super().__init__(
@@ -0,0 +1,37 @@
1
+ from typing import TYPE_CHECKING, List
2
+
3
+ from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
4
+ from isar.models.events import Event
5
+
6
+ if TYPE_CHECKING:
7
+ from isar.state_machine.state_machine import StateMachine
8
+
9
+
10
+ class Lockdown(EventHandlerBase):
11
+
12
+ def __init__(self, state_machine: "StateMachine"):
13
+ events = state_machine.events
14
+
15
+ def _release_from_lockdown_handler(event: Event[bool]):
16
+ should_release_from_lockdown: bool = event.consume_event()
17
+ if should_release_from_lockdown:
18
+ events.api_requests.release_from_lockdown.response.trigger_event(True)
19
+ if state_machine.battery_level_is_above_mission_start_threshold():
20
+ return state_machine.release_from_lockdown # type: ignore
21
+ else:
22
+ return state_machine.starting_recharging # type: ignore
23
+ return None
24
+
25
+ event_handlers: List[EventHandlerMapping] = [
26
+ EventHandlerMapping(
27
+ name="release_from_lockdown",
28
+ event=events.api_requests.release_from_lockdown.request,
29
+ handler=_release_from_lockdown_handler,
30
+ ),
31
+ ]
32
+
33
+ super().__init__(
34
+ state_name="lockdown",
35
+ state_machine=state_machine,
36
+ event_handler_mappings=event_handlers,
37
+ )
@@ -63,6 +63,17 @@ class Monitor(EventHandlerBase):
63
63
  return state_machine.stop # type: ignore
64
64
  return None
65
65
 
66
+ def _send_to_lockdown_event_handler(
67
+ event: Event[bool],
68
+ ) -> Optional[Callable]:
69
+ should_lockdown: bool = event.consume_event()
70
+ if should_lockdown:
71
+ state_machine.logger.warning(
72
+ "Cancelling current mission due to robot going to lockdown"
73
+ )
74
+ return state_machine.stop_go_to_lockdown # type: ignore
75
+ return None
76
+
66
77
  event_handlers: List[EventHandlerMapping] = [
67
78
  EventHandlerMapping(
68
79
  name="stop_mission_event",
@@ -107,6 +118,11 @@ class Monitor(EventHandlerBase):
107
118
  event=shared_state.robot_battery_level,
108
119
  handler=_robot_battery_level_updated_handler,
109
120
  ),
121
+ EventHandlerMapping(
122
+ name="send_to_lockdown_event",
123
+ event=events.api_requests.send_to_lockdown.request,
124
+ handler=_send_to_lockdown_event_handler,
125
+ ),
110
126
  ]
111
127
  super().__init__(
112
128
  state_name="monitor",
@@ -1,7 +1,7 @@
1
1
  from typing import TYPE_CHECKING, List
2
2
 
3
3
  from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
4
- from isar.models.events import Event
4
+ from isar.state_machine.utils.common_event_handlers import robot_status_event_handler
5
5
  from robot_interface.models.mission.status import RobotStatus
6
6
 
7
7
  if TYPE_CHECKING:
@@ -11,20 +11,19 @@ if TYPE_CHECKING:
11
11
  class Offline(EventHandlerBase):
12
12
 
13
13
  def __init__(self, state_machine: "StateMachine"):
14
-
14
+ events = state_machine.events
15
15
  shared_state = state_machine.shared_state
16
16
 
17
- def _robot_status_event_handler(event: Event[RobotStatus]):
18
- robot_status: RobotStatus = event.check()
19
- if robot_status != RobotStatus.Offline:
20
- return state_machine.robot_status_changed # type: ignore
21
- return None
22
-
23
17
  event_handlers: List[EventHandlerMapping] = [
24
18
  EventHandlerMapping(
25
19
  name="robot_status_event",
26
- event=shared_state.robot_status,
27
- handler=_robot_status_event_handler,
20
+ event=events.robot_service_events.robot_status_changed,
21
+ handler=lambda event: robot_status_event_handler(
22
+ state_machine=state_machine,
23
+ expected_status=RobotStatus.Offline,
24
+ status_changed_event=event,
25
+ status_event=shared_state.robot_status,
26
+ ),
28
27
  ),
29
28
  ]
30
29
  super().__init__(
@@ -3,6 +3,7 @@ from typing import TYPE_CHECKING, Callable, List, Optional
3
3
  from isar.config.settings import settings
4
4
  from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
5
5
  from isar.models.events import Event
6
+ from isar.state_machine.utils.common_event_handlers import stop_mission_event_handler
6
7
 
7
8
  if TYPE_CHECKING:
8
9
  from isar.state_machine.state_machine import StateMachine
@@ -29,11 +30,23 @@ class Paused(EventHandlerBase):
29
30
  return state_machine.stop # type: ignore
30
31
  return None
31
32
 
33
+ def _send_to_lockdown_event_handler(
34
+ event: Event[bool],
35
+ ) -> Optional[Callable]:
36
+ should_lockdown: bool = event.consume_event()
37
+ if should_lockdown:
38
+ state_machine._finalize()
39
+ state_machine.logger.warning(
40
+ "Cancelling current mission due to robot going to lockdown"
41
+ )
42
+ return state_machine.stop_go_to_lockdown # type: ignore
43
+ return None
44
+
32
45
  event_handlers: List[EventHandlerMapping] = [
33
46
  EventHandlerMapping(
34
47
  name="stop_mission_event",
35
48
  event=events.api_requests.stop_mission.request,
36
- handler=lambda event: state_machine.stop if event.consume_event() else None, # type: ignore
49
+ handler=lambda event: stop_mission_event_handler(state_machine, event),
37
50
  ),
38
51
  EventHandlerMapping(
39
52
  name="resume_mission_event",
@@ -45,6 +58,11 @@ class Paused(EventHandlerBase):
45
58
  event=shared_state.robot_battery_level,
46
59
  handler=_robot_battery_level_updated_handler,
47
60
  ),
61
+ EventHandlerMapping(
62
+ name="send_to_lockdown_event",
63
+ event=events.api_requests.send_to_lockdown.request,
64
+ handler=_send_to_lockdown_event_handler,
65
+ ),
48
66
  ]
49
67
  super().__init__(
50
68
  state_name="paused",
@@ -0,0 +1,74 @@
1
+ from typing import TYPE_CHECKING, Callable, List, Optional
2
+
3
+ from isar.apis.models.models import ControlMissionResponse
4
+ from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
5
+ from isar.models.events import Event
6
+ from robot_interface.models.exceptions.robot_exceptions import ErrorMessage
7
+ from robot_interface.models.mission.status import MissionStatus, TaskStatus
8
+
9
+ if TYPE_CHECKING:
10
+ from isar.state_machine.state_machine import StateMachine
11
+
12
+
13
+ class Pausing(EventHandlerBase):
14
+
15
+ def __init__(self, state_machine: "StateMachine"):
16
+ events = state_machine.events
17
+
18
+ def _failed_pause_event_handler(
19
+ event: Event[ErrorMessage],
20
+ ) -> Optional[Callable]:
21
+ error_message: Optional[ErrorMessage] = event.consume_event()
22
+
23
+ paused_mission_response: ControlMissionResponse = (
24
+ state_machine._make_control_mission_response()
25
+ )
26
+
27
+ state_machine.events.api_requests.pause_mission.response.trigger_event(
28
+ paused_mission_response
29
+ )
30
+
31
+ state_machine.publish_mission_status()
32
+ state_machine.send_task_status()
33
+
34
+ if error_message is not None:
35
+ return state_machine.mission_pausing_failed # type: ignore
36
+ return None
37
+
38
+ def _successful_pause_event_handler(event: Event[bool]) -> Optional[Callable]:
39
+ if event.consume_event():
40
+
41
+ state_machine.current_mission.status = MissionStatus.Paused
42
+ state_machine.current_task.status = TaskStatus.Paused
43
+
44
+ paused_mission_response: ControlMissionResponse = (
45
+ state_machine._make_control_mission_response()
46
+ )
47
+
48
+ state_machine.events.api_requests.pause_mission.response.trigger_event(
49
+ paused_mission_response
50
+ )
51
+
52
+ state_machine.publish_mission_status()
53
+ state_machine.send_task_status()
54
+
55
+ return state_machine.mission_paused # type:ignore
56
+ return None
57
+
58
+ event_handlers: List[EventHandlerMapping] = [
59
+ EventHandlerMapping(
60
+ name="failed_pause_event",
61
+ event=events.robot_service_events.mission_failed_to_pause,
62
+ handler=_failed_pause_event_handler,
63
+ ),
64
+ EventHandlerMapping(
65
+ name="successful_pause_event",
66
+ event=events.robot_service_events.mission_successfully_paused,
67
+ handler=_successful_pause_event_handler,
68
+ ),
69
+ ]
70
+ super().__init__(
71
+ state_name="pausing",
72
+ state_machine=state_machine,
73
+ event_handler_mappings=event_handlers,
74
+ )
@@ -0,0 +1,74 @@
1
+ from typing import TYPE_CHECKING, Callable, List, Optional
2
+
3
+ from isar.apis.models.models import ControlMissionResponse
4
+ from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
5
+ from isar.models.events import Event
6
+ from robot_interface.models.exceptions.robot_exceptions import ErrorMessage
7
+ from robot_interface.models.mission.status import MissionStatus, TaskStatus
8
+
9
+ if TYPE_CHECKING:
10
+ from isar.state_machine.state_machine import StateMachine
11
+
12
+
13
+ class PausingReturnHome(EventHandlerBase):
14
+
15
+ def __init__(self, state_machine: "StateMachine"):
16
+ events = state_machine.events
17
+
18
+ def _failed_pause_event_handler(
19
+ event: Event[ErrorMessage],
20
+ ) -> Optional[Callable]:
21
+ error_message: Optional[ErrorMessage] = event.consume_event()
22
+
23
+ paused_mission_response: ControlMissionResponse = (
24
+ state_machine._make_control_mission_response()
25
+ )
26
+
27
+ state_machine.events.api_requests.pause_mission.response.trigger_event(
28
+ paused_mission_response
29
+ )
30
+
31
+ state_machine.publish_mission_status()
32
+ state_machine.send_task_status()
33
+
34
+ if error_message is not None:
35
+ return state_machine.return_home_mission_pausing_failed # type: ignore
36
+ return None
37
+
38
+ def _successful_pause_event_handler(event: Event[bool]) -> Optional[Callable]:
39
+ if event.consume_event():
40
+
41
+ state_machine.current_mission.status = MissionStatus.Paused
42
+ state_machine.current_task.status = TaskStatus.Paused
43
+
44
+ paused_mission_response: ControlMissionResponse = (
45
+ state_machine._make_control_mission_response()
46
+ )
47
+
48
+ state_machine.events.api_requests.pause_mission.response.trigger_event(
49
+ paused_mission_response
50
+ )
51
+
52
+ state_machine.publish_mission_status()
53
+ state_machine.send_task_status()
54
+
55
+ return state_machine.return_home_mission_paused # type: ignore
56
+ return None
57
+
58
+ event_handlers: List[EventHandlerMapping] = [
59
+ EventHandlerMapping(
60
+ name="failed_pause_event",
61
+ event=events.robot_service_events.mission_failed_to_pause,
62
+ handler=_failed_pause_event_handler,
63
+ ),
64
+ EventHandlerMapping(
65
+ name="successful_stop_event",
66
+ event=events.robot_service_events.mission_successfully_paused,
67
+ handler=_successful_pause_event_handler,
68
+ ),
69
+ ]
70
+ super().__init__(
71
+ state_name="pausing_return_home",
72
+ state_machine=state_machine,
73
+ event_handler_mappings=event_handlers,
74
+ )
@@ -1,5 +1,6 @@
1
1
  from typing import TYPE_CHECKING, List
2
2
 
3
+ from isar.apis.models.models import LockdownResponse
3
4
  from isar.config.settings import settings
4
5
  from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
5
6
  from isar.models.events import Event
@@ -13,6 +14,7 @@ class Recharging(EventHandlerBase):
13
14
 
14
15
  def __init__(self, state_machine: "StateMachine"):
15
16
  shared_state = state_machine.shared_state
17
+ events = state_machine.events
16
18
 
17
19
  def robot_battery_level_updated_handler(event: Event[float]):
18
20
  battery_level: float = event.check()
@@ -25,6 +27,15 @@ class Recharging(EventHandlerBase):
25
27
  if robot_status == RobotStatus.Offline:
26
28
  return state_machine.robot_went_offline # type: ignore
27
29
 
30
+ def _send_to_lockdown_event_handler(event: Event[bool]):
31
+ should_lockdown: bool = event.consume_event()
32
+ if should_lockdown:
33
+ events.api_requests.send_to_lockdown.response.trigger_event(
34
+ LockdownResponse(lockdown_started=True)
35
+ )
36
+ return state_machine.reached_lockdown # type: ignore
37
+ return None
38
+
28
39
  event_handlers: List[EventHandlerMapping] = [
29
40
  EventHandlerMapping(
30
41
  name="robot_battery_update_event",
@@ -36,6 +47,11 @@ class Recharging(EventHandlerBase):
36
47
  event=shared_state.robot_status,
37
48
  handler=robot_offline_handler,
38
49
  ),
50
+ EventHandlerMapping(
51
+ name="send_to_lockdown_event",
52
+ event=events.api_requests.send_to_lockdown.request,
53
+ handler=_send_to_lockdown_event_handler,
54
+ ),
39
55
  ]
40
56
  super().__init__(
41
57
  state_name="recharging",
@@ -1,6 +1,6 @@
1
1
  from typing import TYPE_CHECKING, Callable, List, Optional
2
2
 
3
- from isar.apis.models.models import MissionStartResponse
3
+ from isar.apis.models.models import LockdownResponse, MissionStartResponse
4
4
  from isar.config.settings import settings
5
5
  from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
6
6
  from isar.models.events import Event
@@ -42,6 +42,17 @@ class ReturnHomePaused(EventHandlerBase):
42
42
  return state_machine.stop_return_home # type: ignore
43
43
  return None
44
44
 
45
+ def _send_to_lockdown_event_handler(
46
+ event: Event[bool],
47
+ ) -> Optional[Callable]:
48
+ should_lockdown: bool = event.consume_event()
49
+ if should_lockdown:
50
+ events.api_requests.send_to_lockdown.response.trigger_event(
51
+ LockdownResponse(lockdown_started=True)
52
+ )
53
+ return state_machine.resume_lockdown # type: ignore
54
+ return None
55
+
45
56
  event_handlers: List[EventHandlerMapping] = [
46
57
  EventHandlerMapping(
47
58
  name="resume_return_home_event",
@@ -58,6 +69,11 @@ class ReturnHomePaused(EventHandlerBase):
58
69
  event=events.api_requests.start_mission.request,
59
70
  handler=_start_mission_event_handler,
60
71
  ),
72
+ EventHandlerMapping(
73
+ name="send_to_lockdown_event",
74
+ event=events.api_requests.send_to_lockdown.request,
75
+ handler=_send_to_lockdown_event_handler,
76
+ ),
61
77
  ]
62
78
  super().__init__(
63
79
  state_name="return_home_paused",
@@ -1,6 +1,6 @@
1
1
  from typing import TYPE_CHECKING, Callable, List, Optional
2
2
 
3
- from isar.apis.models.models import MissionStartResponse
3
+ from isar.apis.models.models import LockdownResponse, MissionStartResponse
4
4
  from isar.eventhandlers.eventhandler import EventHandlerBase, EventHandlerMapping
5
5
  from isar.models.events import Event
6
6
  from isar.state_machine.utils.common_event_handlers import (
@@ -25,7 +25,7 @@ class ReturningHome(EventHandlerBase):
25
25
 
26
26
  def _pause_mission_event_handler(event: Event[bool]) -> Optional[Callable]:
27
27
  if event.consume_event():
28
- return state_machine.pause # type: ignore
28
+ return state_machine.pause_return_home # type: ignore
29
29
  return None
30
30
 
31
31
  def _handle_task_completed(status: TaskStatus):
@@ -60,6 +60,17 @@ class ReturningHome(EventHandlerBase):
60
60
  return state_machine.stop_return_home # type: ignore
61
61
  return None
62
62
 
63
+ def _send_to_lockdown_event_handler(
64
+ event: Event[bool],
65
+ ) -> Optional[Callable]:
66
+ should_lockdown: bool = event.consume_event()
67
+ if should_lockdown:
68
+ events.api_requests.send_to_lockdown.response.trigger_event(
69
+ LockdownResponse(lockdown_started=True)
70
+ )
71
+ return state_machine.go_to_lockdown # type: ignore
72
+ return None
73
+
63
74
  event_handlers: List[EventHandlerMapping] = [
64
75
  EventHandlerMapping(
65
76
  name="pause_mission_event",
@@ -99,6 +110,11 @@ class ReturningHome(EventHandlerBase):
99
110
  state_machine, _handle_task_completed, event
100
111
  ),
101
112
  ),
113
+ EventHandlerMapping(
114
+ name="send_to_lockdown_event",
115
+ event=events.api_requests.send_to_lockdown.request,
116
+ handler=_send_to_lockdown_event_handler,
117
+ ),
102
118
  ]
103
119
  super().__init__(
104
120
  state_name="returning_home",