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

isar/apis/api.py CHANGED
@@ -232,6 +232,7 @@ class API:
232
232
  methods=["POST"],
233
233
  dependencies=[authentication_dependency],
234
234
  summary="Localize at the provided pose",
235
+ deprecated=True,
235
236
  responses={
236
237
  HTTPStatus.OK.value: {
237
238
  "description": "Localization succesfully started",
isar/config/settings.py CHANGED
@@ -140,6 +140,9 @@ class Settings(BaseSettings):
140
140
  # Keyvault name
141
141
  KEYVAULT_NAME: str = Field(default="IsarDevKv")
142
142
 
143
+ # Determines whether inspections are uploaded asynchronously or get_inspections in robotinterface
144
+ UPLOAD_INSPECTIONS_ASYNC: bool = Field(default=False)
145
+
143
146
  # URL to storage account for Azure Blob Storage
144
147
  BLOB_STORAGE_ACCOUNT_URL: str = Field(
145
148
  default="https://eqrobotdevstorage.blob.core.windows.net"
isar/script.py CHANGED
@@ -2,7 +2,7 @@ import logging
2
2
  import time
3
3
  from logging import Logger
4
4
  from threading import Thread
5
- from typing import Any, List
5
+ from typing import Any, List, Tuple
6
6
 
7
7
  from injector import Injector
8
8
 
@@ -20,6 +20,8 @@ from isar.services.service_connections.mqtt.robot_heartbeat_publisher import (
20
20
  from isar.services.service_connections.mqtt.robot_info_publisher import (
21
21
  RobotInfoPublisher,
22
22
  )
23
+ from robot_interface.models.inspection.inspection import Inspection
24
+ from robot_interface.models.mission.mission import Mission
23
25
  from isar.state_machine.state_machine import StateMachine, main
24
26
  from isar.storage.uploader import Uploader
25
27
  from robot_interface.robot_interface import RobotInterface
@@ -69,6 +71,7 @@ def print_startup_info():
69
71
  print_setting("Using local storage", settings.STORAGE_LOCAL_ENABLED)
70
72
  print_setting("Using blob storage", settings.STORAGE_BLOB_ENABLED)
71
73
  print_setting("Using SLIMM storage", settings.STORAGE_SLIMM_ENABLED)
74
+ print_setting("Using async inspection uploading", settings.UPLOAD_INSPECTIONS_ASYNC)
72
75
  print_setting("Plant code", settings.PLANT_CODE)
73
76
  print_setting("Plant name", settings.PLANT_NAME)
74
77
  print_setting("Plant shortname", settings.PLANT_SHORT_NAME)
@@ -103,6 +106,18 @@ def start():
103
106
  target=uploader.run, name="ISAR Uploader", daemon=True
104
107
  )
105
108
  threads.append(uploader_thread)
109
+
110
+ if settings.UPLOAD_INSPECTIONS_ASYNC:
111
+
112
+ def inspections_callback(inspection: Inspection):
113
+ message: Tuple[Inspection, Mission] = (
114
+ inspection,
115
+ state_machine.current_mission,
116
+ )
117
+ state_machine.queues.upload_queue.put(message)
118
+
119
+ robot.register_inspection_callback(inspections_callback)
120
+
106
121
  if settings.MQTT_ENABLED:
107
122
  mqtt_client: MqttClient = MqttClient(mqtt_queue=queues.mqtt_queue)
108
123
 
@@ -137,6 +152,7 @@ def start():
137
152
  robot_name=settings.ROBOT_NAME,
138
153
  isar_id=settings.ISAR_ID,
139
154
  )
155
+
140
156
  if publishers:
141
157
  threads.extend(publishers)
142
158
 
@@ -128,7 +128,7 @@ class SchedulingUtilities:
128
128
  """
129
129
  is_state_machine_ready_to_receive_mission = state == States.Idle
130
130
  if not is_state_machine_ready_to_receive_mission:
131
- error_message = f"Conflict - Mission already in progress - State: {state}"
131
+ error_message = f"Conflict - Robot is not idle - State: {state}"
132
132
  self.logger.warning(error_message)
133
133
  raise HTTPException(status_code=HTTPStatus.CONFLICT, detail=error_message)
134
134
 
@@ -17,6 +17,7 @@ from robot_interface.models.exceptions.robot_exceptions import (
17
17
  RobotException,
18
18
  RobotRetrieveInspectionException,
19
19
  RobotTaskStatusException,
20
+ RobotCommunicationException,
20
21
  )
21
22
  from robot_interface.models.inspection.inspection import Inspection
22
23
  from robot_interface.models.mission.mission import Mission
@@ -75,8 +76,11 @@ class Monitor(State):
75
76
  time.sleep(self.state_machine.sleep_time)
76
77
  continue
77
78
 
78
- except RobotCommunicationTimeoutException as e:
79
- task_failed: bool = self._handle_communication_timeout(e)
79
+ except (
80
+ RobotCommunicationTimeoutException,
81
+ RobotCommunicationException,
82
+ ) as e:
83
+ task_failed: bool = self._handle_communication_retry(e)
80
84
  if task_failed:
81
85
  status = TaskStatus.Failed
82
86
  else:
@@ -111,7 +115,10 @@ class Monitor(State):
111
115
 
112
116
  self.state_machine.current_task.status = status
113
117
 
114
- if self._should_upload_inspections():
118
+ if (
119
+ not settings.UPLOAD_INSPECTIONS_ASYNC
120
+ and self._should_upload_inspections()
121
+ ):
115
122
  get_inspection_thread = ThreadedRequest(
116
123
  self._queue_inspections_for_upload
117
124
  )
@@ -207,8 +214,8 @@ class Monitor(State):
207
214
  )
208
215
  self.state_machine.current_task.error_message = error_message
209
216
 
210
- def _handle_communication_timeout(
211
- self, e: RobotCommunicationTimeoutException
217
+ def _handle_communication_retry(
218
+ self, e: Union[RobotCommunicationTimeoutException, RobotCommunicationException]
212
219
  ) -> bool:
213
220
  self.state_machine.current_mission.error_message = ErrorMessage(
214
221
  error_reason=e.error_reason, error_description=e.error_description
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: isar
3
- Version: 1.23.2
3
+ Version: 1.23.4
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,8 +1,8 @@
1
1
  isar/__init__.py,sha256=cH8p8bVveu3FUL6kBhldcSlLaoHgD82Kd0-SwSNfGXw,87
2
2
  isar/modules.py,sha256=aO8bLSC4i_Qo4bOJ6aFfwAZRTJAw8o9SOOfkceUGCiU,6708
3
- isar/script.py,sha256=C6CTOZKjWu3JC-jOTN6QPd0Z6NxbydIcQcOM2tXMEXQ,5376
3
+ isar/script.py,sha256=UT-JVu25vOiGaTjGR7hESlfBBITZF6dCy4frtMSUc6Y,5969
4
4
  isar/apis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- isar/apis/api.py,sha256=zrNdnMe5GS1xMtPLsF2Za0NKEyYNKMAVim4l027qQA4,13141
5
+ isar/apis/api.py,sha256=PYJggz9Xh0alo2DWU3QD4lEBQY3PkEs335JE2qG87WQ,13170
6
6
  isar/apis/models/__init__.py,sha256=NI1BYyN__Ogr00Qqe0XJ-9gEVPva2brXo2RJsbrS4tM,52
7
7
  isar/apis/models/models.py,sha256=6E8VhGBti6EKJefYTDNVERxRu_g_omg4J2MriPUPkaw,1709
8
8
  isar/apis/models/start_mission_definition.py,sha256=oY2CRKNkf4DQys0lbz-WTib1Ppw_OUwHqhBTrBhUJQk,8044
@@ -15,7 +15,7 @@ isar/config/configuration_error.py,sha256=rO6WOhafX6xvVib8WxV-eY483Z0PpN-9PxGsq5
15
15
  isar/config/log.py,sha256=zHFLmGWQRn8TrcsxUS6KHpJt2JE86kYazU7b-bkcN9o,2285
16
16
  isar/config/logging.conf,sha256=mYO1xf27gAopEMHhGzY7-mwyfN16rwRLkPNMvy3zn2g,1127
17
17
  isar/config/settings.env,sha256=hJFfyl4S84nmcyf70Pz8nbGlPf4KTVx0UkgP3uf6T8E,534
18
- isar/config/settings.py,sha256=YCX8xV3nNCtEmFxh-kApZsl6hYprPzrQbLuc3c64e6c,13378
18
+ isar/config/settings.py,sha256=0FA0hXqfcJHcfbCJVbbGvSUJGfFX5a0PGTTq8TI6hnw,13539
19
19
  isar/config/certs/ca-cert.pem,sha256=ijutWtGOAnKx3xPydNLOVoCLip3tGkNKUpr6pTPQfJA,2179
20
20
  isar/config/keyvault/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
21
  isar/config/keyvault/keyvault_error.py,sha256=zvPCsZLjboxsxthYkxpRERCTFxYV8R5WmACewAUQLwk,41
@@ -64,7 +64,7 @@ isar/services/service_connections/mqtt/robot_info_publisher.py,sha256=5G6ahslydh
64
64
  isar/services/service_connections/stid/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
65
65
  isar/services/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
66
66
  isar/services/utilities/queue_utilities.py,sha256=Pw3hehSwkXJNeDv-bDVDfs58VOwtt3i5hpiJ2ZpphuQ,1225
67
- isar/services/utilities/scheduling_utilities.py,sha256=cLnB97EkoZM0GN6kG5ezpzxLzACSoHU_Mv86ncyHdfM,8386
67
+ isar/services/utilities/scheduling_utilities.py,sha256=UUMxhudY2mQRG6Edjq6BG7oxwlqmcu5h6fMyw4Vhl_o,8376
68
68
  isar/services/utilities/threaded_request.py,sha256=py4G-_RjnIdHljmKFAcQ6ddqMmp-ZYV39Ece-dqRqjs,1874
69
69
  isar/state_machine/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
70
70
  isar/state_machine/state_machine.py,sha256=A7qAaXEnErmPQ7--sM7w9VabceS0qJOProlmwMb9iaU,21299
@@ -73,7 +73,7 @@ isar/state_machine/states/__init__.py,sha256=kErbKPDTwNfCLijvdyN6_AuOqDwR23nu9F0
73
73
  isar/state_machine/states/idle.py,sha256=iAKESjETKUt9x3inE7TAPIohVM1iRsYyJjOoBeB3sVw,3079
74
74
  isar/state_machine/states/initialize.py,sha256=TVXV5Ps3N4_flM88j9pQiX88kZgLzLwzlJy_6hPbgcA,2359
75
75
  isar/state_machine/states/initiate.py,sha256=j1wvSC3zVODgRkKOVsQROiuWkjihSBtwCs5GsoivLvc,5655
76
- isar/state_machine/states/monitor.py,sha256=BktuQm8YSAdxFlhaGGR02pSGsx2jJ2pZR6wQY3fEsEo,9297
76
+ isar/state_machine/states/monitor.py,sha256=mQyJrmsjuMFwcit10SPmJFEbDAMRoSAtFUlooWb6vT0,9530
77
77
  isar/state_machine/states/off.py,sha256=jjqN_oJMpBtWuY7hP-c9f0w3p2CYCfe-NpmYHHPnmyI,544
78
78
  isar/state_machine/states/offline.py,sha256=ur5wDo4NWRLn7n-p5IUY6aSYcGApmqe_0IbRRywA6qA,2169
79
79
  isar/state_machine/states/paused.py,sha256=TIg1iJvAxGUIfzE_qWp0wrq4Ka0a3zEf3GNwIWLIK0M,1177
@@ -86,11 +86,11 @@ isar/storage/storage_interface.py,sha256=DYDry4I7aZpDHJhsBF6s8zrgokFAc7fdKJKfA8A
86
86
  isar/storage/uploader.py,sha256=_f-uIiL5ye6GLc7nYQxHrqDXrIquoL_t5tt9SSaYoDA,6440
87
87
  isar/storage/utilities.py,sha256=AGqOzhnyPXSStpJjBstqQ4QgUoHJioQB2DJ1NqeWn_w,3136
88
88
  robot_interface/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
89
- robot_interface/robot_interface.py,sha256=Jbfh1L7lPCjfHS6l3oQ_r0ACZw-KCazVc09PhxEIuao,8566
89
+ robot_interface/robot_interface.py,sha256=H1hsuiFDcB5tTfan3VsXQyWy2jArWeBkMTr1VvZ4vIs,9061
90
90
  robot_interface/test_robot_interface.py,sha256=FV1urn7SbsMyWBIcTKjsBwAG4IsXeZ6pLHE0mA9EGGs,692
91
91
  robot_interface/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
92
92
  robot_interface/models/exceptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
93
- robot_interface/models/exceptions/robot_exceptions.py,sha256=iRtN_JzwOSeuO0xBrGiWFtbIhWuajsw-Zg6Cz4y1hzk,9549
93
+ robot_interface/models/exceptions/robot_exceptions.py,sha256=tL3Pf45Nuh9dc9QDRt43SF4qZT3f2NVaRpYj1POVjsA,10093
94
94
  robot_interface/models/initialize/__init__.py,sha256=rz5neEDr59GDbzzI_FF0DId-C-I-50l113P-h-C_QBY,48
95
95
  robot_interface/models/initialize/initialize_params.py,sha256=2eG5Aq5bDKU6tVkaUMAoc46GERBgyaKkqv6yLupdRLc,164
96
96
  robot_interface/models/inspection/__init__.py,sha256=14wfuj4XZazrigKD7fL98khFKz-eckIpEgPcYRj40Kg,227
@@ -103,14 +103,14 @@ robot_interface/models/robots/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5N
103
103
  robot_interface/models/robots/robot_model.py,sha256=pZQsqhn9hh6XE3EjMZhWMzYqg5oJ4CJ4CXeOASKvEf8,452
104
104
  robot_interface/telemetry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
105
105
  robot_interface/telemetry/media_connection_type.py,sha256=Z8Jayi5SjBJh_xEd5KdS__A6bM-nofbSAedc6u41iAY,91
106
- robot_interface/telemetry/mqtt_client.py,sha256=um7j7XDSAlY6-wWLpBl6ZYjmQ-G0lY7f2_NaZ3ciZ7U,2757
106
+ robot_interface/telemetry/mqtt_client.py,sha256=RoXJFQ4YiaSQpHTlZ2LD-ICRPtfUhylEwgyt_3NE4xM,2916
107
107
  robot_interface/telemetry/payloads.py,sha256=FafpIwsOvcTNtaBZqyOX7r5EjG7nZ2uLNhyJo2l5GiI,1767
108
108
  robot_interface/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
109
109
  robot_interface/utilities/json_service.py,sha256=nU2Q_3P9Fq9hs6F_wtUjWtHfl_g1Siy-yDhXXSKwHwg,1018
110
110
  robot_interface/utilities/uuid_string_factory.py,sha256=_NQIbBQ56w0qqO0MUDP6aPpHbxW7ATRhK8HnQiBSLkc,76
111
- isar-1.23.2.dist-info/LICENSE,sha256=3fc2-ebLwHWwzfQbulGNRdcNob3SBQeCfEVUDYxsuqw,14058
112
- isar-1.23.2.dist-info/METADATA,sha256=5AyHbYGvN3bT16Mw_aoA2arjS0fFk1QPRpWgc5MahFM,30674
113
- isar-1.23.2.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
114
- isar-1.23.2.dist-info/entry_points.txt,sha256=TFam7uNNw7J0iiDYzsH2gfG0u1eV1wh3JTw_HkhgKLk,49
115
- isar-1.23.2.dist-info/top_level.txt,sha256=UwIML2RtuQKCyJJkatcSnyp6-ldDjboB9k9JgKipO-U,21
116
- isar-1.23.2.dist-info/RECORD,,
111
+ isar-1.23.4.dist-info/LICENSE,sha256=3fc2-ebLwHWwzfQbulGNRdcNob3SBQeCfEVUDYxsuqw,14058
112
+ isar-1.23.4.dist-info/METADATA,sha256=QffW0qReds1tlXA-Zb7bzrWkezchNIx2IiK1rkXhz6s,30674
113
+ isar-1.23.4.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
114
+ isar-1.23.4.dist-info/entry_points.txt,sha256=TFam7uNNw7J0iiDYzsH2gfG0u1eV1wh3JTw_HkhgKLk,49
115
+ isar-1.23.4.dist-info/top_level.txt,sha256=UwIML2RtuQKCyJJkatcSnyp6-ldDjboB9k9JgKipO-U,21
116
+ isar-1.23.4.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.1.0)
2
+ Generator: setuptools (75.3.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -16,6 +16,7 @@ class ErrorReason(str, Enum):
16
16
  RobotRetrieveDataException: str = "robot_retrieve_data_exception"
17
17
  RobotRetrieveInspectionException: str = "robot_retrieve_inspection_exception"
18
18
  RobotTelemetryException: str = "robot_telemetry_exception"
19
+ RobotTelemetryPoseException: str = "robot_telemetry_pose_exception"
19
20
  RobotMapException: str = "robot_map_exception"
20
21
  RobotTransformException: str = "robot_transform_exception"
21
22
  RobotUnknownErrorException: str = "robot_unknown_error_exception"
@@ -42,7 +43,7 @@ class RobotException(Exception):
42
43
 
43
44
 
44
45
  # An exception which should be thrown by the robot package if it is unable to
45
- # communicate with the robot API.
46
+ # communicate with the robot API. ISAR will retry the request.
46
47
  class RobotCommunicationException(RobotException):
47
48
  def __init__(self, error_description: str) -> None:
48
49
  super().__init__(
@@ -189,6 +190,18 @@ class RobotTelemetryException(RobotException):
189
190
  pass
190
191
 
191
192
 
193
+ # An exception which should be thrown by the robot package if it is unable to retrieve
194
+ # telemetry pose data. It should be used exclusively by the telemetry pose publisher.
195
+ class RobotTelemetryPoseException(RobotException):
196
+ def __init__(self, error_description: str) -> None:
197
+ super().__init__(
198
+ error_reason=ErrorReason.RobotTelemetryPoseException,
199
+ error_description=error_description,
200
+ )
201
+
202
+ pass
203
+
204
+
192
205
  # An exception which should be thrown by the robot package if it is unable to load the
193
206
  # configuration for maps and transformations. This could be caused by faulty
194
207
  # configuration and this exception will cause ISAR to crash as further execution is not
@@ -1,7 +1,7 @@
1
1
  from abc import ABCMeta, abstractmethod
2
2
  from queue import Queue
3
3
  from threading import Thread
4
- from typing import List
4
+ from typing import Callable, List
5
5
 
6
6
  from robot_interface.models.initialize import InitializeParams
7
7
  from robot_interface.models.inspection.inspection import Inspection
@@ -180,6 +180,24 @@ class RobotInterface(metaclass=ABCMeta):
180
180
  """
181
181
  raise NotImplementedError
182
182
 
183
+ @abstractmethod
184
+ def register_inspection_callback(
185
+ self, callback_function: Callable[[Inspection], None]
186
+ ) -> None:
187
+ """Register a function which should be run when inspection data is received
188
+ asynchronously. This function should expect to receive an Inspection from.
189
+
190
+ Parameters
191
+ ----------
192
+ callback_function : Callable[[Inspection]
193
+
194
+ Returns
195
+ -------
196
+ None
197
+
198
+ """
199
+ raise NotImplementedError
200
+
183
201
  @abstractmethod
184
202
  def initialize(self, params: InitializeParams) -> None:
185
203
  """Initializes the robot. The initialization needed is robot dependent and the
@@ -5,7 +5,10 @@ from datetime import datetime, timezone
5
5
  from queue import Queue
6
6
  from typing import Callable, Tuple
7
7
 
8
- from robot_interface.models.exceptions.robot_exceptions import RobotTelemetryException
8
+ from robot_interface.models.exceptions.robot_exceptions import (
9
+ RobotTelemetryException,
10
+ RobotTelemetryPoseException,
11
+ )
9
12
  from robot_interface.telemetry.payloads import CloudHealthPayload
10
13
  from robot_interface.utilities.json_service import EnhancedJSONEncoder
11
14
 
@@ -63,7 +66,7 @@ class MqttTelemetryPublisher(MqttClientInterface):
63
66
  self.retain: bool = retain
64
67
 
65
68
  def run(self, isar_id: str, robot_name: str) -> None:
66
- self.cloud_healt_topic: str = f"isar/{isar_id}/cloud_health"
69
+ self.cloud_health_topic: str = f"isar/{isar_id}/cloud_health"
67
70
  topic: str
68
71
  payload: str
69
72
 
@@ -71,12 +74,15 @@ class MqttTelemetryPublisher(MqttClientInterface):
71
74
  try:
72
75
  payload = self.telemetry_method(isar_id=isar_id, robot_name=robot_name)
73
76
  topic = self.topic
77
+ except RobotTelemetryPoseException:
78
+ time.sleep(self.interval)
79
+ continue
74
80
  except RobotTelemetryException:
75
81
  payload = json.dumps(
76
82
  CloudHealthPayload(isar_id, robot_name, datetime.now(timezone.utc)),
77
83
  cls=EnhancedJSONEncoder,
78
84
  )
79
- topic = self.cloud_healt_topic
85
+ topic = self.cloud_health_topic
80
86
 
81
87
  self.publish(topic=topic, payload=payload, qos=self.qos, retain=self.retain)
82
88
 
File without changes