isar 1.25.9__py3-none-any.whl → 1.26.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 (48) hide show
  1. isar/apis/models/start_mission_definition.py +55 -112
  2. isar/apis/robot_control/robot_controller.py +5 -4
  3. isar/apis/schedule/scheduling_controller.py +6 -57
  4. isar/apis/security/authentication.py +2 -2
  5. isar/config/settings.env +1 -3
  6. isar/config/settings.py +6 -6
  7. isar/models/communication/message.py +0 -4
  8. isar/models/communication/queues/events.py +57 -0
  9. isar/models/communication/queues/queue_utils.py +32 -0
  10. isar/models/communication/queues/status_queue.py +7 -5
  11. isar/modules.py +26 -13
  12. isar/robot/robot.py +124 -0
  13. isar/robot/robot_start_mission.py +73 -0
  14. isar/robot/robot_status.py +49 -0
  15. isar/robot/robot_stop_mission.py +72 -0
  16. isar/robot/robot_task_status.py +92 -0
  17. isar/script.py +14 -7
  18. isar/services/utilities/scheduling_utilities.py +21 -30
  19. isar/state_machine/state_machine.py +70 -212
  20. isar/state_machine/states/blocked_protective_stop.py +10 -30
  21. isar/state_machine/states/idle.py +45 -67
  22. isar/state_machine/states/monitor.py +129 -139
  23. isar/state_machine/states/offline.py +12 -33
  24. isar/state_machine/states/paused.py +6 -3
  25. isar/state_machine/states/stop.py +29 -58
  26. isar/state_machine/states_enum.py +0 -2
  27. isar/state_machine/transitions/fail_mission.py +13 -0
  28. isar/state_machine/transitions/finish_mission.py +39 -0
  29. isar/state_machine/transitions/pause.py +24 -0
  30. isar/state_machine/transitions/resume.py +27 -0
  31. isar/state_machine/transitions/start_mission.py +73 -0
  32. isar/state_machine/transitions/stop.py +40 -0
  33. isar/state_machine/transitions/utils.py +10 -0
  34. isar/storage/slimm_storage.py +2 -2
  35. isar/storage/uploader.py +5 -5
  36. {isar-1.25.9.dist-info → isar-1.26.1.dist-info}/METADATA +5 -19
  37. {isar-1.25.9.dist-info → isar-1.26.1.dist-info}/RECORD +45 -34
  38. {isar-1.25.9.dist-info → isar-1.26.1.dist-info}/WHEEL +1 -1
  39. robot_interface/models/mission/task.py +1 -1
  40. robot_interface/telemetry/mqtt_client.py +0 -1
  41. robot_interface/telemetry/payloads.py +3 -3
  42. robot_interface/utilities/json_service.py +1 -1
  43. isar/models/communication/queues/queues.py +0 -19
  44. isar/state_machine/states/initialize.py +0 -70
  45. isar/state_machine/states/initiate.py +0 -111
  46. {isar-1.25.9.dist-info → isar-1.26.1.dist-info}/entry_points.txt +0 -0
  47. {isar-1.25.9.dist-info → isar-1.26.1.dist-info/licenses}/LICENSE +0 -0
  48. {isar-1.25.9.dist-info → isar-1.26.1.dist-info}/top_level.txt +0 -0
@@ -1,16 +1,16 @@
1
1
  import logging
2
2
  import time
3
+ from queue import Queue
3
4
  from typing import TYPE_CHECKING, Optional
4
5
 
5
6
  from transitions import State
6
7
 
7
- from isar.config.settings import settings
8
8
  from isar.models.communication.message import StartMissionMessage
9
- from isar.services.utilities.threaded_request import (
10
- ThreadedRequest,
11
- ThreadedRequestNotFinishedError,
9
+ from isar.models.communication.queues.queue_utils import (
10
+ check_for_event,
11
+ check_shared_state,
12
12
  )
13
- from robot_interface.models.exceptions.robot_exceptions import RobotException
13
+ from isar.models.communication.queues.status_queue import StatusQueue
14
14
  from robot_interface.models.mission.status import RobotStatus
15
15
 
16
16
  if TYPE_CHECKING:
@@ -22,82 +22,60 @@ class Idle(State):
22
22
  super().__init__(name="idle", on_enter=self.start, on_exit=self.stop)
23
23
  self.state_machine: "StateMachine" = state_machine
24
24
  self.logger = logging.getLogger("state_machine")
25
- self.robot_status_thread: Optional[ThreadedRequest] = None
26
25
  self.last_robot_status_poll_time: float = time.time()
27
- self.status_checked_at_least_once: bool = False
26
+ self.events = self.state_machine.events
27
+ self.shared_state = self.state_machine.shared_state
28
28
 
29
29
  def start(self) -> None:
30
30
  self.state_machine.update_state()
31
31
  self._run()
32
32
 
33
33
  def stop(self) -> None:
34
- if self.robot_status_thread:
35
- self.robot_status_thread.wait_for_thread()
36
- self.robot_status_thread = None
37
- self.status_checked_at_least_once = False
34
+ return
38
35
 
39
- def _is_ready_to_poll_for_status(self) -> bool:
40
- if not self.status_checked_at_least_once:
36
+ def _check_and_handle_stop_mission_event(self, event: Queue) -> bool:
37
+ if check_for_event(event):
38
+ self.state_machine.stop() # type: ignore
41
39
  return True
42
-
43
- time_since_last_robot_status_poll = (
44
- time.time() - self.last_robot_status_poll_time
45
- )
46
- return (
47
- time_since_last_robot_status_poll > settings.ROBOT_API_STATUS_POLL_INTERVAL
48
- )
40
+ return False
41
+
42
+ def _check_and_handle_start_mission_event(
43
+ self, event: Queue[StartMissionMessage]
44
+ ) -> bool:
45
+ start_mission: Optional[StartMissionMessage] = check_for_event(event)
46
+ if start_mission:
47
+ self.state_machine.start_mission(mission=start_mission.mission)
48
+ self.state_machine.request_mission_start() # type: ignore
49
+ return True
50
+ return False
51
+
52
+ def _check_and_handle_robot_status_event(
53
+ self, event: StatusQueue[RobotStatus]
54
+ ) -> bool:
55
+ robot_status: RobotStatus = check_shared_state(event)
56
+ if robot_status == RobotStatus.Offline:
57
+ self.state_machine.robot_turned_offline() # type: ignore
58
+ return True
59
+ elif robot_status == RobotStatus.BlockedProtectiveStop:
60
+ self.state_machine.robot_protective_stop_engaged() # type: ignore
61
+ return True
62
+ return False
49
63
 
50
64
  def _run(self) -> None:
51
65
  while True:
52
- if self.state_machine.should_stop_mission():
53
- transition = self.state_machine.stop # type: ignore
66
+ if self._check_and_handle_stop_mission_event(
67
+ self.events.api_requests.stop_mission.input
68
+ ):
54
69
  break
55
70
 
56
- if self.status_checked_at_least_once:
57
- start_mission: Optional[StartMissionMessage] = (
58
- self.state_machine.should_start_mission()
59
- )
60
- if start_mission:
61
- self.state_machine.start_mission(
62
- mission=start_mission.mission,
63
- initial_pose=start_mission.initial_pose,
64
- )
65
- transition = self.state_machine.mission_started # type: ignore
66
- break
67
- time.sleep(self.state_machine.sleep_time)
68
-
69
- if not self._is_ready_to_poll_for_status():
70
- continue
71
-
72
- if not self.robot_status_thread:
73
- self.robot_status_thread = ThreadedRequest(
74
- request_func=self.state_machine.robot.robot_status
75
- )
76
- self.robot_status_thread.start_thread(
77
- name="State Machine Offline Get Robot Status"
78
- )
79
-
80
- try:
81
- robot_status: RobotStatus = self.robot_status_thread.get_output()
82
- self.status_checked_at_least_once = True
83
- except ThreadedRequestNotFinishedError:
84
- time.sleep(self.state_machine.sleep_time)
85
- continue
86
-
87
- except RobotException as e:
88
- self.logger.error(
89
- f"Failed to get robot status because: {e.error_description}"
90
- )
91
-
92
- self.last_robot_status_poll_time = time.time()
93
-
94
- if robot_status == RobotStatus.Offline:
95
- transition = self.state_machine.robot_turned_offline # type: ignore
96
- break
97
- elif robot_status == RobotStatus.BlockedProtectiveStop:
98
- transition = self.state_machine.robot_protective_stop_engaged # type: ignore
71
+ if self._check_and_handle_start_mission_event(
72
+ self.events.api_requests.start_mission.input
73
+ ):
99
74
  break
100
75
 
101
- self.robot_status_thread = None
76
+ if self._check_and_handle_robot_status_event(
77
+ self.shared_state.robot_status
78
+ ):
79
+ break
102
80
 
103
- transition()
81
+ time.sleep(self.state_machine.sleep_time)
@@ -1,23 +1,19 @@
1
1
  import logging
2
2
  import time
3
3
  from copy import deepcopy
4
- from typing import TYPE_CHECKING, Callable, Optional, Tuple, Union
4
+ from queue import Queue
5
+ from typing import TYPE_CHECKING, Optional, Tuple
5
6
 
6
7
  from injector import inject
7
8
  from transitions import State
8
9
 
9
10
  from isar.config.settings import settings
10
- from isar.services.utilities.threaded_request import (
11
- ThreadedRequest,
12
- ThreadedRequestNotFinishedError,
13
- )
11
+ from isar.models.communication.queues.queue_utils import check_for_event, trigger_event
12
+ from isar.services.utilities.threaded_request import ThreadedRequest
14
13
  from robot_interface.models.exceptions.robot_exceptions import (
15
14
  ErrorMessage,
16
- RobotCommunicationException,
17
- RobotCommunicationTimeoutException,
18
15
  RobotException,
19
16
  RobotRetrieveInspectionException,
20
- RobotTaskStatusException,
21
17
  )
22
18
  from robot_interface.models.inspection.inspection import Inspection
23
19
  from robot_interface.models.mission.mission import Mission
@@ -33,131 +29,146 @@ class Monitor(State):
33
29
  def __init__(self, state_machine: "StateMachine") -> None:
34
30
  super().__init__(name="monitor", on_enter=self.start, on_exit=self.stop)
35
31
  self.state_machine: "StateMachine" = state_machine
36
- self.request_status_failure_counter: int = 0
37
- self.request_status_failure_counter_limit: int = (
38
- settings.REQUEST_STATUS_FAILURE_COUNTER_LIMIT
39
- )
40
32
 
41
33
  self.logger = logging.getLogger("state_machine")
42
- self.task_status_thread: Optional[ThreadedRequest] = None
34
+ self.events = self.state_machine.events
35
+
36
+ self.awaiting_task_status: bool = False
43
37
 
44
38
  def start(self) -> None:
45
39
  self.state_machine.update_state()
46
40
  self._run()
47
41
 
48
42
  def stop(self) -> None:
49
- if self.task_status_thread:
50
- self.task_status_thread.wait_for_thread()
51
- self.task_status_thread = None
43
+ self.state_machine.mission_ongoing = False
44
+ return
52
45
 
53
- def _run(self) -> None:
54
- transition: Callable
55
- while True:
56
- if self.state_machine.should_stop_mission():
57
- transition = self.state_machine.stop # type: ignore
58
- break
46
+ def _check_and_handle_stop_mission_event(self, event: Queue) -> bool:
47
+ if check_for_event(event):
48
+ self.state_machine.stop() # type: ignore
49
+ return True
50
+ return False
59
51
 
60
- if self.state_machine.should_pause_mission():
61
- transition = self.state_machine.pause # type: ignore
62
- break
52
+ def _check_and_handle_pause_mission_event(self, event: Queue) -> bool:
53
+ if check_for_event(event):
54
+ self.state_machine.pause() # type: ignore
55
+ return True
56
+ return False
63
57
 
64
- if not self.task_status_thread:
65
- self._run_get_status_thread(
66
- status_function=self.state_machine.robot.task_status,
67
- function_argument=self.state_machine.current_task.id,
68
- thread_name="State Machine Monitor Get Task Status",
69
- )
70
- try:
71
- status: TaskStatus = self.task_status_thread.get_output()
72
- self.request_status_failure_counter = 0
73
- except ThreadedRequestNotFinishedError:
74
- time.sleep(self.state_machine.sleep_time)
75
- continue
76
- except (
77
- RobotCommunicationTimeoutException,
78
- RobotCommunicationException,
79
- ) as e:
80
- retry_limit_exceeded: bool = self._check_if_exceeded_retry_limit(e)
81
- if retry_limit_exceeded:
82
- self.logger.error(
83
- f"Monitoring task {self.state_machine.current_task.id[:8]} failed "
84
- f"because: {e.error_description}"
85
- )
86
- status = TaskStatus.Failed
87
- else:
88
- time.sleep(settings.REQUEST_STATUS_COMMUNICATION_RECONNECT_DELAY)
89
- continue
90
-
91
- except RobotTaskStatusException as e:
92
- self.state_machine.current_task.error_message = ErrorMessage(
93
- error_reason=e.error_reason, error_description=e.error_description
94
- )
95
- self.logger.error(
96
- f"Monitoring task {self.state_machine.current_task.id[:8]} failed "
97
- f"because: {e.error_description}"
98
- )
99
- status = TaskStatus.Failed
58
+ def _check_and_handle_mission_started_event(self, event: Queue) -> None:
59
+ if not self.state_machine.mission_ongoing:
60
+ if check_for_event(event):
61
+ self.state_machine.mission_ongoing = True
62
+
63
+ def _check_and_handle_mission_failed_event(self, event: Queue) -> bool:
64
+ mission_failed: Optional[ErrorMessage] = check_for_event(event)
65
+ if mission_failed is not None:
66
+ self.state_machine.logger.warning(
67
+ f"Failed to initiate mission "
68
+ f"{str(self.state_machine.current_mission.id)[:8]} because: "
69
+ f"{mission_failed.error_description}"
70
+ )
71
+ self.state_machine.current_mission.error_message = ErrorMessage(
72
+ error_reason=mission_failed.error_reason,
73
+ error_description=mission_failed.error_description,
74
+ )
100
75
 
101
- except RobotException as e:
102
- self._set_error_message(e)
103
- status = TaskStatus.Failed
76
+ self.state_machine.mission_failed_to_start() # type: ignore
77
+ return True
78
+ return False
104
79
 
105
- self.logger.error(
106
- f"Retrieving the status failed because: {e.error_description}"
107
- )
80
+ def _check_and_handle_task_status_failed_event(self, event: Queue) -> bool:
81
+ task_failure: Optional[ErrorMessage] = check_for_event(event)
82
+ if task_failure is not None:
83
+ self.awaiting_task_status = False
84
+ self.state_machine.current_task.error_message = task_failure
85
+ self.logger.error(
86
+ f"Monitoring task {self.state_machine.current_task.id[:8]} failed "
87
+ f"because: {task_failure.error_description}"
88
+ )
89
+ return self._handle_new_task_status(TaskStatus.Failed)
90
+ elif not self.awaiting_task_status:
91
+ trigger_event(
92
+ self.events.state_machine_events.task_status_request,
93
+ self.state_machine.current_task.id,
94
+ )
95
+ self.awaiting_task_status = True
96
+ return False
108
97
 
109
- if not isinstance(status, TaskStatus):
110
- self.logger.error(
111
- f"Received an invalid status update {status} when monitoring mission. "
112
- "Only TaskStatus is expected."
113
- )
114
- break
98
+ def _check_and_handle_task_status_event(self, event: Queue) -> bool:
99
+ status: Optional[TaskStatus] = check_for_event(event)
100
+ if status is not None:
101
+ self.awaiting_task_status = False
102
+ return self._handle_new_task_status(status)
103
+ elif not self.awaiting_task_status:
104
+ trigger_event(
105
+ self.events.state_machine_events.task_status_request,
106
+ self.state_machine.current_task.id,
107
+ )
108
+ self.awaiting_task_status = True
109
+ return False
110
+
111
+ def _handle_new_task_status(self, status: TaskStatus) -> bool:
112
+ if self.state_machine.current_task is None:
113
+ self.state_machine.iterate_current_task()
114
+
115
+ self.state_machine.current_task.status = status
115
116
 
117
+ if self._should_upload_inspections():
118
+ get_inspection_thread = ThreadedRequest(self._queue_inspections_for_upload)
119
+ get_inspection_thread.start_thread(
120
+ deepcopy(self.state_machine.current_mission),
121
+ deepcopy(self.state_machine.current_task),
122
+ name="State Machine Get Inspections",
123
+ )
124
+
125
+ if self.state_machine.current_task.is_finished():
126
+ self._report_task_status(self.state_machine.current_task)
127
+ self.state_machine.publish_task_status(task=self.state_machine.current_task)
128
+
129
+ self.state_machine.iterate_current_task()
116
130
  if self.state_machine.current_task is None:
117
- self.state_machine.iterate_current_task()
131
+ self.state_machine.mission_finished() # type: ignore
132
+ return True
118
133
 
119
- self.state_machine.current_task.status = status
134
+ # Report and update next task
135
+ self.state_machine.current_task.update_task_status()
136
+ self.state_machine.publish_task_status(task=self.state_machine.current_task)
137
+ return False
120
138
 
121
- if (
122
- not settings.UPLOAD_INSPECTIONS_ASYNC
123
- and self._should_upload_inspections()
139
+ def _run(self) -> None:
140
+ self.awaiting_task_status = False
141
+ while True:
142
+ if self._check_and_handle_stop_mission_event(
143
+ self.events.api_requests.stop_mission.input
124
144
  ):
125
- get_inspection_thread = ThreadedRequest(
126
- self._queue_inspections_for_upload
127
- )
128
- get_inspection_thread.start_thread(
129
- deepcopy(self.state_machine.current_mission),
130
- deepcopy(self.state_machine.current_task),
131
- name="State Machine Get Inspections",
132
- )
145
+ break
133
146
 
134
- if self.state_machine.current_task.is_finished():
135
- self._report_task_status(self.state_machine.current_task)
136
- self.state_machine.publish_task_status(
137
- task=self.state_machine.current_task
138
- )
147
+ if self._check_and_handle_pause_mission_event(
148
+ self.events.api_requests.pause_mission.input
149
+ ):
150
+ break
139
151
 
140
- self.state_machine.iterate_current_task()
141
- if self.state_machine.current_task is None:
142
- transition = self.state_machine.mission_finished # type: ignore
143
- break
152
+ self._check_and_handle_mission_started_event(
153
+ self.events.robot_service_events.mission_started
154
+ )
144
155
 
145
- # Report and update next task
146
- self.state_machine.current_task.update_task_status()
147
- self.state_machine.publish_task_status(
148
- task=self.state_machine.current_task
149
- )
156
+ if self._check_and_handle_mission_failed_event(
157
+ self.events.robot_service_events.mission_failed
158
+ ):
159
+ break
150
160
 
151
- self.task_status_thread = None
152
- time.sleep(self.state_machine.sleep_time)
161
+ if self._check_and_handle_task_status_failed_event(
162
+ self.events.robot_service_events.task_status_failed
163
+ ):
164
+ break
153
165
 
154
- transition()
166
+ if self._check_and_handle_task_status_event(
167
+ self.events.robot_service_events.task_status_updated
168
+ ):
169
+ break
155
170
 
156
- def _run_get_status_thread(
157
- self, status_function: Callable, function_argument: str, thread_name: str
158
- ) -> None:
159
- self.task_status_thread = ThreadedRequest(request_func=status_function)
160
- self.task_status_thread.start_thread(function_argument, name=thread_name)
171
+ time.sleep(settings.FSM_SLEEP_TIME)
161
172
 
162
173
  def _queue_inspections_for_upload(
163
174
  self, mission: Mission, current_task: InspectionTask
@@ -180,6 +191,12 @@ class Monitor(State):
180
191
  )
181
192
  return
182
193
 
194
+ except Exception as e:
195
+ self.logger.error(
196
+ f"Failed to retrieve inspections because of unexpected error: {e}"
197
+ )
198
+ return
199
+
183
200
  if not inspection:
184
201
  self.logger.warning(
185
202
  f"No inspection result data retrieved for task {str(current_task.id)[:8]}"
@@ -191,7 +208,7 @@ class Monitor(State):
191
208
  inspection,
192
209
  mission,
193
210
  )
194
- self.state_machine.queues.upload_queue.put(message)
211
+ self.state_machine.events.upload_queue.put(message)
195
212
  self.logger.info(
196
213
  f"Inspection result: {str(inspection.id)[:8]} queued for upload"
197
214
  )
@@ -207,6 +224,9 @@ class Monitor(State):
207
224
  )
208
225
 
209
226
  def _should_upload_inspections(self) -> bool:
227
+ if settings.UPLOAD_INSPECTIONS_ASYNC:
228
+ return False
229
+
210
230
  return (
211
231
  self.state_machine.current_task.is_finished()
212
232
  and self.state_machine.current_task.status == TaskStatus.Successful
@@ -218,33 +238,3 @@ class Monitor(State):
218
238
  error_reason=e.error_reason, error_description=e.error_description
219
239
  )
220
240
  self.state_machine.current_task.error_message = error_message
221
-
222
- def _check_if_exceeded_retry_limit(
223
- self, e: Union[RobotCommunicationTimeoutException, RobotCommunicationException]
224
- ) -> bool:
225
- self.state_machine.current_mission.error_message = ErrorMessage(
226
- error_reason=e.error_reason, error_description=e.error_description
227
- )
228
- self.task_status_thread = None
229
- self.request_status_failure_counter += 1
230
- self.logger.warning(
231
- f"Monitoring task {self.state_machine.current_task.id} failed #: "
232
- f"{self.request_status_failure_counter} failed because: {e.error_description}"
233
- )
234
-
235
- if (
236
- self.request_status_failure_counter
237
- >= self.request_status_failure_counter_limit
238
- ):
239
- self.state_machine.current_task.error_message = ErrorMessage(
240
- error_reason=e.error_reason,
241
- error_description=e.error_description,
242
- )
243
- self.logger.error(
244
- f"Task will be cancelled after failing to get task status "
245
- f"{self.request_status_failure_counter} times because: "
246
- f"{e.error_description}"
247
- )
248
- return True
249
-
250
- return False
@@ -1,15 +1,10 @@
1
1
  import logging
2
2
  import time
3
- from typing import TYPE_CHECKING, Optional
3
+ from typing import TYPE_CHECKING
4
4
 
5
5
  from transitions import State
6
6
 
7
- from isar.config.settings import settings
8
- from isar.services.utilities.threaded_request import (
9
- ThreadedRequest,
10
- ThreadedRequestNotFinishedError,
11
- )
12
- from robot_interface.models.exceptions.robot_exceptions import RobotException
7
+ from isar.models.communication.queues.queue_utils import check_shared_state
13
8
  from robot_interface.models.mission.status import RobotStatus
14
9
 
15
10
  if TYPE_CHECKING:
@@ -21,43 +16,27 @@ class Offline(State):
21
16
  super().__init__(name="offline", on_enter=self.start, on_exit=self.stop)
22
17
  self.state_machine: "StateMachine" = state_machine
23
18
  self.logger = logging.getLogger("state_machine")
24
- self.robot_status_thread: Optional[ThreadedRequest] = None
19
+ self.shared_state = self.state_machine.shared_state
25
20
 
26
21
  def start(self) -> None:
27
22
  self.state_machine.update_state()
28
23
  self._run()
29
24
 
30
25
  def stop(self) -> None:
31
- if self.robot_status_thread:
32
- self.robot_status_thread.wait_for_thread()
33
- self.robot_status_thread = None
26
+ return
34
27
 
35
28
  def _run(self) -> None:
36
29
  while True:
37
- if not self.robot_status_thread:
38
- self.robot_status_thread = ThreadedRequest(
39
- request_func=self.state_machine.robot.robot_status
40
- )
41
- self.robot_status_thread.start_thread(
42
- name="State Machine Offline Get Robot Status"
43
- )
44
-
45
- try:
46
- robot_status: RobotStatus = self.robot_status_thread.get_output()
47
- except ThreadedRequestNotFinishedError:
48
- time.sleep(self.state_machine.sleep_time)
49
- continue
50
-
51
- except RobotException as e:
52
- self.logger.error(
53
- f"Failed to get robot status because: {e.error_description}"
54
- )
55
-
56
- if robot_status != RobotStatus.Offline:
30
+ robot_status: RobotStatus = check_shared_state(
31
+ self.shared_state.robot_status
32
+ )
33
+ if robot_status == RobotStatus.BlockedProtectiveStop:
34
+ transition = self.state_machine.robot_protective_stop_engaged # type: ignore
35
+ break
36
+ elif robot_status != RobotStatus.Offline:
57
37
  transition = self.state_machine.robot_turned_online # type: ignore
58
38
  break
59
39
 
60
- self.robot_status_thread = None
61
- time.sleep(settings.ROBOT_API_STATUS_POLL_INTERVAL)
40
+ time.sleep(self.state_machine.sleep_time)
62
41
 
63
42
  transition()
@@ -1,9 +1,11 @@
1
1
  import logging
2
2
  import time
3
- from typing import Callable, TYPE_CHECKING
3
+ from typing import TYPE_CHECKING, Callable
4
4
 
5
5
  from transitions import State
6
6
 
7
+ from isar.models.communication.queues.queue_utils import check_for_event
8
+
7
9
  if TYPE_CHECKING:
8
10
  from isar.state_machine.state_machine import StateMachine
9
11
 
@@ -13,6 +15,7 @@ class Paused(State):
13
15
  super().__init__(name="paused", on_enter=self.start)
14
16
  self.state_machine: "StateMachine" = state_machine
15
17
  self.logger = logging.getLogger("state_machine")
18
+ self.events = self.state_machine.events
16
19
 
17
20
  def start(self) -> None:
18
21
  self.state_machine.update_state()
@@ -21,11 +24,11 @@ class Paused(State):
21
24
  def _run(self) -> None:
22
25
  transition: Callable
23
26
  while True:
24
- if self.state_machine.should_stop_mission():
27
+ if check_for_event(self.events.api_requests.pause_mission.input):
25
28
  transition = self.state_machine.stop # type: ignore
26
29
  break
27
30
 
28
- if self.state_machine.should_resume_mission():
31
+ if check_for_event(self.events.api_requests.resume_mission.input):
29
32
  transition = self.state_machine.resume # type: ignore
30
33
  break
31
34