blueye.sdk.connection - Blueye SDK

Skip to content

# blueye.sdk.connection

## `` connection

Modules:

- `blueye` –
- `threading` –

  Thread module emulating a subset of Java's threading model.

Classes:

- `Callback` –

  Specifications for callback for telemetry messages.

- `CtrlClient` –

  A thread that handles control messages to the drone.

- `ReqRepClient` –

  A thread that handles request-reply messages to and from the drone.

- `TelemetryClient` –

  A thread that handles telemetry messages from the drone

- `WatchdogPublisher` –

  A thread that publishes watchdog messages to keep the connection alive.

Attributes:

- `logger` –

### `` logger `module-attribute`

    logger = getLogger(__name__)

### `` Callback

Bases: `NamedTuple`

Specifications for callback for telemetry messages.

Attributes:

- `message_filter` (`List[Message]`) –

  The list of message types to filter.

- `function` (`Callable[[str, Message], None]`) –

  The callback function.

- `pass_raw_data` (`bool`) –

  Whether to pass raw data to the callback.

- `uuid_hex` (`str`) –

  The UUID of the callback in hexadecimal format.

- `kwargs` (`Dict[str, Any]`) –

  Additional keyword arguments for the callback.

### `` CtrlClient

    CtrlClient(
        parent_drone: "blueye.sdk.Drone",
        context: Context = None,
    )

Bases: `Thread`

A thread that handles control messages to the drone.

Parameters:

- `parent_drone` (`Drone`) –

  The parent drone instance.

- `context` (`Context`, default: `None` ) –

  The ZeroMQ context.

Methods:

- `getName` –

  Return a string used for identification purposes only.

- `isDaemon` –

  Return whether this thread is a daemon.

- `is_alive` –

  Return whether the thread is alive.

- `join` –

  Wait until the thread terminates.

- `run` –

  Run the control client thread.

- `setDaemon` –

  Set whether this thread is a daemon.

- `setName` –

  Set the name string for this thread.

- `set_auto_altitude_state` –

  Enable or disable auto altitude control.

- `set_auto_depth_state` –

  Enable or disable auto depth control.

- `set_auto_heading_state` –

  Enable or disable auto heading control.

- `set_generic_servo_angle` –

  Set the angle of a generic servo on the guest port.

- `set_gripper_velocities` –

  Set the gripper velocities.

- `set_guest_port_lights` –

  Set the intensity of the guest port lights.

- `set_laser_intensity` –

  Set the laser intensity.

- `set_lights` –

  Set the intensity of the lights.

- `set_motion_input` –

  Set the motion input values.

- `set_multibeam_servo_angle` –

  Set the angle of the servo on the multibeam skid.

- `set_recording_state` –

  Enable or disable recording.

- `set_station_keeping_state` –

  Enable or disable station keeping.

- `set_tilt_stabilization` –

  Enable or disable tilt stabilization.

- `set_tilt_velocity` –

  Set the tilt velocity.

- `set_water_density` –

  Set the water density.

- `set_weather_vaning_state` –

  Enable or disable weather vaning.

- `start` –

  Start the thread's activity.

- `stop` –

  Stop the control client thread.

- `take_still_picture` –

  Take a still picture.

Attributes:

- `daemon` –

  A boolean value indicating whether this thread is a daemon thread.

- `ident` –

  Thread identifier of this thread or None if it has not been started.

- `name` –

  A string used for identification purposes only.

- `native_id` –

  Native integral thread ID of this thread, or None if it has not been started.

Source code in `blueye/sdk/connection.py`

    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    def __init__(
        self,
        parent_drone: "blueye.sdk.Drone",
        context: zmq.Context = None,
    ):
        """Initialize the CtrlClient.

        Args:
            parent_drone (blueye.sdk.Drone): The parent drone instance.
            context (zmq.Context, optional): The ZeroMQ context.
        """
        super().__init__(daemon=True)
        self._context = context or zmq.Context().instance()
        self._parent_drone = parent_drone
        self._drone_pub_socket = self._context.socket(zmq.PUB)
        self._drone_pub_socket.connect(f"tcp://{self._parent_drone._ip}:5557")
        self._messages_to_send = queue.Queue()
        self._exit_flag = threading.Event()

#### `` daemon `property` `writable`

    daemon

A boolean value indicating whether this thread is a daemon thread.

This must be set before start() is called, otherwise RuntimeError is raised. Its initial value is inherited from the creating thread; the main thread is not a daemon thread and therefore all threads created in the main thread default to daemon = False.

The entire Python program exits when only daemon threads are left.

#### `` ident `property`

    ident

Thread identifier of this thread or None if it has not been started.

This is a nonzero integer. See the get_ident() function. Thread identifiers may be recycled when a thread exits and another thread is created. The identifier is available even after the thread has exited.

#### `` name `property` `writable`

    name

A string used for identification purposes only.

It has no semantics. Multiple threads may be given the same name. The initial name is set by the constructor.

#### `` native_id `property`

    native_id

Native integral thread ID of this thread, or None if it has not been started.

This is a non-negative integer. See the get_native_id() function. This represents the Thread ID as reported by the kernel.

#### `` getName

    getName()

Return a string used for identification purposes only.

This method is deprecated, use the name attribute instead.

Source code in `python3.13/threading.py`

    1194
    1195
    1196
    1197
    1198
    1199
    1200
    1201
    1202
    1203
    def getName(self):
        """Return a string used for identification purposes only.

        This method is deprecated, use the name attribute instead.

        """
        import warnings
        warnings.warn('getName() is deprecated, get the name attribute instead',
                      DeprecationWarning, stacklevel=2)
        return self.name

#### `` isDaemon

    isDaemon()

Return whether this thread is a daemon.

This method is deprecated, use the daemon attribute instead.

Source code in `python3.13/threading.py`

    1172
    1173
    1174
    1175
    1176
    1177
    1178
    1179
    1180
    1181
    def isDaemon(self):
        """Return whether this thread is a daemon.

        This method is deprecated, use the daemon attribute instead.

        """
        import warnings
        warnings.warn('isDaemon() is deprecated, get the daemon attribute instead',
                      DeprecationWarning, stacklevel=2)
        return self.daemon

#### `` is_alive

    is_alive()

Return whether the thread is alive.

This method returns True just before the run() method starts until just after the run() method terminates. See also the module function enumerate().

Source code in `python3.13/threading.py`

    1136
    1137
    1138
    1139
    1140
    1141
    1142
    1143
    1144
    1145
    def is_alive(self):
        """Return whether the thread is alive.

        This method returns True just before the run() method starts until just
        after the run() method terminates. See also the module function
        enumerate().

        """
        assert self._initialized, "Thread.__init__() not called"
        return self._started.is_set() and not self._handle.is_done()

#### `` join

    join(timeout=None)

Wait until the thread terminates.

This blocks the calling thread until the thread whose join() method is called terminates -- either normally or through an unhandled exception or until the optional timeout occurs.

When the timeout argument is present and not None, it should be a floating-point number specifying a timeout for the operation in seconds (or fractions thereof). As join() always returns None, you must call is_alive() after join() to decide whether a timeout happened -- if the thread is still alive, the join() call timed out.

When the timeout argument is not present or None, the operation will block until the thread terminates.

A thread can be join()ed many times.

join() raises a RuntimeError if an attempt is made to join the current thread as that would cause a deadlock. It is also an error to join() a thread before it has been started and attempts to do so raises the same exception.

Source code in `python3.13/threading.py`

    1058
    1059
    1060
    1061
    1062
    1063
    1064
    1065
    1066
    1067
    1068
    1069
    1070
    1071
    1072
    1073
    1074
    1075
    1076
    1077
    1078
    1079
    1080
    1081
    1082
    1083
    1084
    1085
    1086
    1087
    1088
    1089
    1090
    1091
    1092
    1093
    1094
    def join(self, timeout=None):
        """Wait until the thread terminates.

        This blocks the calling thread until the thread whose join() method is
        called terminates -- either normally or through an unhandled exception
        or until the optional timeout occurs.

        When the timeout argument is present and not None, it should be a
        floating-point number specifying a timeout for the operation in seconds
        (or fractions thereof). As join() always returns None, you must call
        is_alive() after join() to decide whether a timeout happened -- if the
        thread is still alive, the join() call timed out.

        When the timeout argument is not present or None, the operation will
        block until the thread terminates.

        A thread can be join()ed many times.

        join() raises a RuntimeError if an attempt is made to join the current
        thread as that would cause a deadlock. It is also an error to join() a
        thread before it has been started and attempts to do so raises the same
        exception.

        """
        if not self._initialized:
            raise RuntimeError("Thread.__init__() not called")
        if not self._started.is_set():
            raise RuntimeError("cannot join thread before it is started")
        if self is current_thread():
            raise RuntimeError("cannot join current thread")

        # the behavior of a negative timeout isn't documented, but
        # historically .join(timeout=x) for x<0 has acted as if timeout=0
        if timeout is not None:
            timeout = max(timeout, 0)

        self._handle.join(timeout)

#### `` run

    run()

Run the control client thread.

Source code in `blueye/sdk/connection.py`

    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    def run(self):
        """Run the control client thread."""
        while not self._exit_flag.is_set():
            try:
                msg = self._messages_to_send.get(timeout=0.1)
                self._drone_pub_socket.send_multipart(
                    [
                        bytes(msg._pb.DESCRIPTOR.full_name, "utf-8"),
                        msg.__class__.serialize(msg),
                    ]
                )
            except queue.Empty:
                # No messages to send, so we can
                continue

#### `` setDaemon

    setDaemon(daemonic)

Set whether this thread is a daemon.

This method is deprecated, use the .daemon property instead.

Source code in `python3.13/threading.py`

    1183
    1184
    1185
    1186
    1187
    1188
    1189
    1190
    1191
    1192
    def setDaemon(self, daemonic):
        """Set whether this thread is a daemon.

        This method is deprecated, use the .daemon property instead.

        """
        import warnings
        warnings.warn('setDaemon() is deprecated, set the daemon attribute instead',
                      DeprecationWarning, stacklevel=2)
        self.daemon = daemonic

#### `` setName

    setName(name)

Set the name string for this thread.

This method is deprecated, use the name attribute instead.

Source code in `python3.13/threading.py`

    1205
    1206
    1207
    1208
    1209
    1210
    1211
    1212
    1213
    1214
    def setName(self, name):
        """Set the name string for this thread.

        This method is deprecated, use the name attribute instead.

        """
        import warnings
        warnings.warn('setName() is deprecated, set the name attribute instead',
                      DeprecationWarning, stacklevel=2)
        self.name = name

#### `` set_auto_altitude_state

    set_auto_altitude_state(enabled: bool)

Enable or disable auto altitude control.

Parameters:

- `enabled` (`bool`) –

  Whether to enable auto altitude control.

Source code in `blueye/sdk/connection.py`

    321
    322
    323
    324
    325
    326
    327
    328
    def set_auto_altitude_state(self, enabled: bool):
        """Enable or disable auto altitude control.

        Args:
            enabled (bool): Whether to enable auto altitude control.
        """
        msg = blueye.protocol.AutoAltitudeCtrl(state={"enabled": enabled})
        self._messages_to_send.put(msg)

#### `` set_auto_depth_state

    set_auto_depth_state(enabled: bool)

Enable or disable auto depth control.

Parameters:

- `enabled` (`bool`) –

  Whether to enable auto depth control.

Source code in `blueye/sdk/connection.py`

    303
    304
    305
    306
    307
    308
    309
    310
    def set_auto_depth_state(self, enabled: bool):
        """Enable or disable auto depth control.

        Args:
            enabled (bool): Whether to enable auto depth control.
        """
        msg = blueye.protocol.AutoDepthCtrl(state={"enabled": enabled})
        self._messages_to_send.put(msg)

#### `` set_auto_heading_state

    set_auto_heading_state(enabled: bool)

Enable or disable auto heading control.

Parameters:

- `enabled` (`bool`) –

  Whether to enable auto heading control.

Source code in `blueye/sdk/connection.py`

    312
    313
    314
    315
    316
    317
    318
    319
    def set_auto_heading_state(self, enabled: bool):
        """Enable or disable auto heading control.

        Args:
            enabled (bool): Whether to enable auto heading control.
        """
        msg = blueye.protocol.AutoHeadingCtrl(state={"enabled": enabled})
        self._messages_to_send.put(msg)

#### `` set_generic_servo_angle

    set_generic_servo_angle(
        angle: float, gp_number: GuestPortNumber
    ) -> None

Set the angle of a generic servo on the guest port.

Parameters:

- `angle` (`float`) –

  The angle in degrees.

- `gp_number` (`GuestPortNumber`) –

  The guest port number.

Source code in `blueye/sdk/connection.py`

    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    def set_generic_servo_angle(
        self, angle: float, gp_number: blueye.protocol.GuestPortNumber
    ) -> None:
        """Set the angle of a generic servo on the guest port.

        Args:
            angle (float): The angle in degrees.
            gp_number (blueye.protocol.GuestPortNumber): The guest port number.
        """
        msg = blueye.protocol.GenericServoCtrl(
            servo={"value": angle, "guest_port_number": gp_number}
        )
        self._messages_to_send.put(msg)

#### `` set_gripper_velocities

    set_gripper_velocities(grip: float, rotation: float)

Set the gripper velocities.

Parameters:

- `grip` (`float`) –

  The grip velocity.

- `rotation` (`float`) –

  The rotation velocity.

Source code in `blueye/sdk/connection.py`

    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    def set_gripper_velocities(self, grip: float, rotation: float):
        """Set the gripper velocities.

        Args:
            grip (float): The grip velocity.
            rotation (float): The rotation velocity.
        """
        msg = blueye.protocol.GripperCtrl(
            gripper_velocities={"grip_velocity": grip, "rotate_velocity": rotation}
        )
        self._messages_to_send.put(msg)

#### `` set_guest_port_lights

    set_guest_port_lights(value: float)

Set the intensity of the guest port lights.

Parameters:

- `value` (`float`) –

  The intensity value.

Source code in `blueye/sdk/connection.py`

    242
    243
    244
    245
    246
    247
    248
    249
    def set_guest_port_lights(self, value: float):
        """Set the intensity of the guest port lights.

        Args:
            value (float): The intensity value.
        """
        msg = blueye.protocol.GuestportLightsCtrl(lights={"value": value})
        self._messages_to_send.put(msg)

#### `` set_laser_intensity

    set_laser_intensity(intensity: float)

Set the laser intensity.

Parameters:

- `intensity` (`float`) –

  The laser intensity value.

Source code in `blueye/sdk/connection.py`

    377
    378
    379
    380
    381
    382
    383
    384
    def set_laser_intensity(self, intensity: float):
        """Set the laser intensity.

        Args:
            intensity (float): The laser intensity value.
        """
        msg = blueye.protocol.LaserCtrl(laser={"value": intensity})
        self._messages_to_send.put(msg)

#### `` set_lights

    set_lights(value: float)

Set the intensity of the lights.

Parameters:

- `value` (`float`) –

  The intensity value.

Source code in `blueye/sdk/connection.py`

    233
    234
    235
    236
    237
    238
    239
    240
    def set_lights(self, value: float):
        """Set the intensity of the lights.

        Args:
            value (float): The intensity value.
        """
        msg = blueye.protocol.LightsCtrl(lights={"value": value})
        self._messages_to_send.put(msg)

#### `` set_motion_input

    set_motion_input(
        surge: float,
        sway: float,
        heave: float,
        yaw: float,
        slow: float,
        boost: float,
    )

Set the motion input values.

Parameters:

- `surge` (`float`) –

  The surge value.

- `sway` (`float`) –

  The sway value.

- `heave` (`float`) –

  The heave value.

- `yaw` (`float`) –

  The yaw value.

- `slow` (`float`) –

  The slow value.

- `boost` (`float`) –

  The boost value.

Source code in `blueye/sdk/connection.py`

    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    def set_motion_input(
        self, surge: float, sway: float, heave: float, yaw: float, slow: float, boost: float
    ):
        """Set the motion input values.

        Args:
            surge (float): The surge value.
            sway (float): The sway value.
            heave (float): The heave value.
            yaw (float): The yaw value.
            slow (float): The slow value.
            boost (float): The boost value.
        """
        msg = blueye.protocol.MotionInputCtrl(
            motion_input={
                "surge": surge,
                "sway": sway,
                "heave": heave,
                "yaw": yaw,
                "slow": slow,
                "boost": boost,
            }
        )
        self._messages_to_send.put(msg)

#### `` set_multibeam_servo_angle

    set_multibeam_servo_angle(angle: float) -> None

Set the angle of the servo on the multibeam skid.

Parameters:

- `angle` (`float`) –

  The angle in degrees.

Source code in `blueye/sdk/connection.py`

    398
    399
    400
    401
    402
    403
    404
    405
    def set_multibeam_servo_angle(self, angle: float) -> None:
        """Set the angle of the servo on the multibeam skid.

        Args:
            angle (float): The angle in degrees.
        """
        msg = blueye.protocol.MultibeamServoCtrl(servo={"angle": angle})
        self._messages_to_send.put(msg)

#### `` set_recording_state

    set_recording_state(
        main_enabled: bool, guestport_enabled: bool
    )

Enable or disable recording.

Parameters:

- `main_enabled` (`bool`) –

  Whether to enable main recording.

- `guestport_enabled` (`bool`) –

  Whether to enable guest port recording.

Source code in `blueye/sdk/connection.py`

    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    def set_recording_state(self, main_enabled: bool, guestport_enabled: bool):
        """Enable or disable recording.

        Args:
            main_enabled (bool): Whether to enable main recording.
            guestport_enabled (bool): Whether to enable guest port recording.
        """
        msg = blueye.protocol.RecordCtrl(
            record_on={"main": main_enabled, "guestport": guestport_enabled}
        )
        self._messages_to_send.put(msg)

#### `` set_station_keeping_state

    set_station_keeping_state(enabled: bool)

Enable or disable station keeping.

Parameters:

- `enabled` (`bool`) –

  Whether to enable station keeping.

Source code in `blueye/sdk/connection.py`

    330
    331
    332
    333
    334
    335
    336
    337
    def set_station_keeping_state(self, enabled: bool):
        """Enable or disable station keeping.

        Args:
            enabled (bool): Whether to enable station keeping.
        """
        msg = blueye.protocol.StationKeepingCtrl(state={"enabled": enabled})
        self._messages_to_send.put(msg)

#### `` set_tilt_stabilization

    set_tilt_stabilization(enabled: bool)

Enable or disable tilt stabilization.

Parameters:

- `enabled` (`bool`) –

  Whether to enable tilt stabilization.

Source code in `blueye/sdk/connection.py`

    269
    270
    271
    272
    273
    274
    275
    276
    def set_tilt_stabilization(self, enabled: bool):
        """Enable or disable tilt stabilization.

        Args:
            enabled (bool): Whether to enable tilt stabilization.
        """
        msg = blueye.protocol.TiltStabilizationCtrl(state={"enabled": enabled})
        self._messages_to_send.put(msg)

#### `` set_tilt_velocity

    set_tilt_velocity(value: float)

Set the tilt velocity.

Parameters:

- `value` (`float`) –

  The tilt velocity value.

Source code in `blueye/sdk/connection.py`

    260
    261
    262
    263
    264
    265
    266
    267
    def set_tilt_velocity(self, value: float):
        """Set the tilt velocity.

        Args:
            value (float): The tilt velocity value.
        """
        msg = blueye.protocol.TiltVelocityCtrl(velocity={"value": value})
        self._messages_to_send.put(msg)

#### `` set_water_density

    set_water_density(value: float)

Set the water density.

Parameters:

- `value` (`float`) –

  The water density value.

Source code in `blueye/sdk/connection.py`

    251
    252
    253
    254
    255
    256
    257
    258
    def set_water_density(self, value: float):
        """Set the water density.

        Args:
            value (float): The water density value.
        """
        msg = blueye.protocol.WaterDensityCtrl(density={"value": value})
        self._messages_to_send.put(msg)

#### `` set_weather_vaning_state

    set_weather_vaning_state(enabled: bool)

Enable or disable weather vaning.

Parameters:

- `enabled` (`bool`) –

  Whether to enable weather vaning.

Source code in `blueye/sdk/connection.py`

    339
    340
    341
    342
    343
    344
    345
    346
    def set_weather_vaning_state(self, enabled: bool):
        """Enable or disable weather vaning.

        Args:
            enabled (bool): Whether to enable weather vaning.
        """
        msg = blueye.protocol.WeatherVaningCtrl(state={"enabled": enabled})
        self._messages_to_send.put(msg)

#### `` start

    start()

Start the thread's activity.

It must be called at most once per thread object. It arranges for the object's run() method to be invoked in a separate thread of control.

This method will raise a RuntimeError if called more than once on the same thread object.

Source code in `python3.13/threading.py`

    955
    956
    957
    958
    959
    960
    961
    962
    963
    964
    965
    966
    967
    968
    969
    970
    971
    972
    973
    974
    975
    976
    977
    978
    979
    980
    981
    def start(self):
        """Start the thread's activity.

        It must be called at most once per thread object. It arranges for the
        object's run() method to be invoked in a separate thread of control.

        This method will raise a RuntimeError if called more than once on the
        same thread object.

        """
        if not self._initialized:
            raise RuntimeError("thread.__init__() not called")

        if self._started.is_set():
            raise RuntimeError("threads can only be started once")

        with _active_limbo_lock:
            _limbo[self] = self
        try:
            # Start joinable thread
            _start_joinable_thread(self._bootstrap, handle=self._handle,
                                   daemon=self.daemon)
        except Exception:
            with _active_limbo_lock:
                del _limbo[self]
            raise
        self._started.wait()  # Will set ident and native_id

#### `` stop

    stop()

Stop the control client thread.

Source code in `blueye/sdk/connection.py`

    229
    230
    231
    def stop(self):
        """Stop the control client thread."""
        self._exit_flag.set()

#### `` take_still_picture

    take_still_picture()

Take a still picture.

Source code in `blueye/sdk/connection.py`

    360
    361
    362
    363
    def take_still_picture(self):
        """Take a still picture."""
        msg = blueye.protocol.TakePictureCtrl()
        self._messages_to_send.put(msg)

### `` ReqRepClient

    ReqRepClient(
        parent_drone: "blueye.sdk.Drone",
        context: Context = None,
    )

Bases: `Thread`

A thread that handles request-reply messages to and from the drone.

Parameters:

- `parent_drone` (`Drone`) –

  The parent drone instance.

- `context` (`Context`, default: `None` ) –

  The ZeroMQ context.

Methods:

- `connect_client` –

  Connect a client to the drone.

- `disconnect_client` –

  Disconnect a client from the drone.

- `getName` –

  Return a string used for identification purposes only.

- `get_active_mission` –

  Get the active mission from the drone

- `get_camera_parameters` –

  Get the camera parameters.

- `get_overlay_parameters` –

  Get the overlay parameters.

- `get_telemetry_msg` –

  Get a telemetry message.

- `isDaemon` –

  Return whether this thread is a daemon.

- `is_alive` –

  Return whether the thread is alive.

- `join` –

  Wait until the thread terminates.

- `ping` –

  Send a ping request to the drone.

- `run` –

  Run the request-reply client thread.

- `setDaemon` –

  Set whether this thread is a daemon.

- `setName` –

  Set the name string for this thread.

- `set_camera_parameters` –

  Set the camera parameters.

- `set_mission` –

  Send a new mission to the drone

- `set_overlay_parameters` –

  Set the overlay parameters.

- `set_telemetry_msg_publish_frequency` –

  Set the telemetry message publish frequency.

- `start` –

  Start the thread's activity.

- `stop` –

  Stop the request-reply client thread.

- `sync_time` –

  Synchronize the time with the drone.

Attributes:

- `daemon` –

  A boolean value indicating whether this thread is a daemon thread.

- `ident` –

  Thread identifier of this thread or None if it has not been started.

- `name` –

  A string used for identification purposes only.

- `native_id` –

  Native integral thread ID of this thread, or None if it has not been started.

Source code in `blueye/sdk/connection.py`

    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    def __init__(self, parent_drone: "blueye.sdk.Drone", context: zmq.Context = None):
        """Initialize the ReqRepClient.

        Args:
            parent_drone (blueye.sdk.Drone): The parent drone instance.
            context (zmq.Context, optional): The ZeroMQ context.
        """
        super().__init__(daemon=True)
        self._context = context or zmq.Context().instance()
        self._parent_drone = parent_drone
        self._socket = self._context.socket(zmq.REQ)
        self._socket.connect(f"tcp://{self._parent_drone._ip}:5556")
        self._requests_to_send = queue.Queue()
        self._exit_flag = threading.Event()

#### `` daemon `property` `writable`

    daemon

A boolean value indicating whether this thread is a daemon thread.

This must be set before start() is called, otherwise RuntimeError is raised. Its initial value is inherited from the creating thread; the main thread is not a daemon thread and therefore all threads created in the main thread default to daemon = False.

The entire Python program exits when only daemon threads are left.

#### `` ident `property`

    ident

Thread identifier of this thread or None if it has not been started.

This is a nonzero integer. See the get_ident() function. Thread identifiers may be recycled when a thread exits and another thread is created. The identifier is available even after the thread has exited.

#### `` name `property` `writable`

    name

A string used for identification purposes only.

It has no semantics. Multiple threads may be given the same name. The initial name is set by the constructor.

#### `` native_id `property`

    native_id

Native integral thread ID of this thread, or None if it has not been started.

This is a non-negative integer. See the get_native_id() function. This represents the Thread ID as reported by the kernel.

#### `` connect_client

    connect_client(
        client_info: ClientInfo = None,
        is_observer: bool = False,
        timeout: float = 0.05,
    ) -> ConnectClientRep

Connect a client to the drone.

Parameters:

- `client_info` (`ClientInfo`, default: `None` ) –

  The client information.

- `is_observer` (`bool`, default: `False` ) –

  Whether the client is an observer.

- `timeout` (`float`, default: `0.05` ) –

  The timeout for the response.

Returns:

- `ConnectClientRep` –

  The connect client response.

Source code in `blueye/sdk/connection.py`

    623
    624
    625
    626
    627
    628
    629
    630
    631
    632
    633
    634
    635
    636
    637
    638
    639
    640
    641
    642
    def connect_client(
        self,
        client_info: blueye.protocol.ClientInfo = None,
        is_observer: bool = False,
        timeout: float = 0.05,
    ) -> blueye.protocol.ConnectClientRep:
        """Connect a client to the drone.

        Args:
            client_info (blueye.protocol.ClientInfo, optional): The client information.
            is_observer (bool, optional): Whether the client is an observer.
            timeout (float, optional): The timeout for the response.

        Returns:
            The connect client response.
        """
        client = client_info or self._get_client_info()
        client.is_observer = is_observer
        request = blueye.protocol.ConnectClientReq(client_info=client)
        return self._send_request_get_response(request, blueye.protocol.ConnectClientRep, timeout)

#### `` disconnect_client

    disconnect_client(
        client_id: int, timeout: float = 0.05
    ) -> DisconnectClientRep

Disconnect a client from the drone.

Parameters:

- `client_id` (`int`) –

  The client ID.

- `timeout` (`float`, default: `0.05` ) –

  The timeout for the response.

Returns:

- `DisconnectClientRep` –

  The disconnect client response.

Source code in `blueye/sdk/connection.py`

    644
    645
    646
    647
    648
    649
    650
    651
    652
    653
    654
    655
    656
    657
    658
    659
    def disconnect_client(
        self, client_id: int, timeout: float = 0.05
    ) -> blueye.protocol.DisconnectClientRep:
        """Disconnect a client from the drone.

        Args:
            client_id (int): The client ID.
            timeout (float, optional): The timeout for the response.

        Returns:
            The disconnect client response.
        """
        request = blueye.protocol.DisconnectClientReq(client_id=client_id)
        return self._send_request_get_response(
            request, blueye.protocol.DisconnectClientRep, timeout
        )

#### `` getName

    getName()

Return a string used for identification purposes only.

This method is deprecated, use the name attribute instead.

Source code in `python3.13/threading.py`

    1194
    1195
    1196
    1197
    1198
    1199
    1200
    1201
    1202
    1203
    def getName(self):
        """Return a string used for identification purposes only.

        This method is deprecated, use the name attribute instead.

        """
        import warnings
        warnings.warn('getName() is deprecated, get the name attribute instead',
                      DeprecationWarning, stacklevel=2)
        return self.name

#### `` get_active_mission

    get_active_mission(timeout: float = 0.05) -> GetMissionRep

Get the active mission from the drone

Source code in `blueye/sdk/connection.py`

    697
    698
    699
    700
    def get_active_mission(self, timeout: float = 0.05) -> blueye.protocol.GetMissionRep:
        """Get the active mission from the drone"""
        request = blueye.protocol.GetMissionReq()
        return self._send_request_get_response(request, blueye.protocol.GetMissionRep, timeout)

#### `` get_camera_parameters

    get_camera_parameters(
        camera: Camera, timeout: float = 0.05
    ) -> CameraParameters

Get the camera parameters.

Parameters:

- `camera` (`Camera`) –

  The camera instance.

- `timeout` (`float`, default: `0.05` ) –

  The timeout for the response.

Returns:

- `CameraParameters` –

  The camera parameters.

Source code in `blueye/sdk/connection.py`

    539
    540
    541
    542
    543
    544
    545
    546
    547
    548
    549
    550
    551
    552
    553
    554
    555
    def get_camera_parameters(
        self, camera: blueye.protocol.Camera, timeout: float = 0.05
    ) -> blueye.protocol.CameraParameters:
        """Get the camera parameters.

        Args:
            camera (blueye.protocol.Camera): The camera instance.
            timeout (float, optional): The timeout for the response.

        Returns:
            The camera parameters.
        """
        request = blueye.protocol.GetCameraParametersReq(camera=camera)
        response = self._send_request_get_response(
            request, blueye.protocol.GetCameraParametersRep, timeout
        )
        return response.camera_parameters

#### `` get_overlay_parameters

    get_overlay_parameters(
        timeout: float = 0.05,
    ) -> OverlayParameters

Get the overlay parameters.

Parameters:

- `timeout` (`float`, default: `0.05` ) –

  The timeout for the response.

Returns:

- `OverlayParameters` –

  blueye.protocol.OverlayParameters: The overlay parameters.

Source code in `blueye/sdk/connection.py`

    576
    577
    578
    579
    580
    581
    582
    583
    584
    585
    586
    587
    588
    589
    def get_overlay_parameters(self, timeout: float = 0.05) -> blueye.protocol.OverlayParameters:
        """Get the overlay parameters.

        Args:
            timeout (float, optional): The timeout for the response.

        Returns:
            blueye.protocol.OverlayParameters: The overlay parameters.
        """
        request = blueye.protocol.GetOverlayParametersReq()
        response = self._send_request_get_response(
            request, blueye.protocol.GetOverlayParametersRep, timeout
        )
        return response.overlay_parameters

#### `` get_telemetry_msg

    get_telemetry_msg(
        msg: MessageMeta | str, timeout: float = 0.05
    ) -> GetTelemetryRep

Get a telemetry message.

Parameters:

- `msg` (`MessageMeta | str`) –

  The message type.

- `timeout` (`float`, default: `0.05` ) –

  The timeout for the response.

Returns:

- `GetTelemetryRep` –

  The telemetry message.

Source code in `blueye/sdk/connection.py`

    681
    682
    683
    684
    685
    686
    687
    688
    689
    690
    691
    692
    693
    694
    695
    def get_telemetry_msg(
        self, msg: proto.message.MessageMeta | str, timeout: float = 0.05
    ) -> blueye.protocol.GetTelemetryRep:
        """Get a telemetry message.

        Args:
            msg (proto.message.MessageMeta | str): The message type.
            timeout (float, optional): The timeout for the response.

        Returns:
            The telemetry message.
        """
        message_type = self._parse_type_to_string(msg)
        request = blueye.protocol.GetTelemetryReq(message_type=message_type)
        return self._send_request_get_response(request, blueye.protocol.GetTelemetryRep, timeout)

#### `` isDaemon

    isDaemon()

Return whether this thread is a daemon.

This method is deprecated, use the daemon attribute instead.

Source code in `python3.13/threading.py`

    1172
    1173
    1174
    1175
    1176
    1177
    1178
    1179
    1180
    1181
    def isDaemon(self):
        """Return whether this thread is a daemon.

        This method is deprecated, use the daemon attribute instead.

        """
        import warnings
        warnings.warn('isDaemon() is deprecated, get the daemon attribute instead',
                      DeprecationWarning, stacklevel=2)
        return self.daemon

#### `` is_alive

    is_alive()

Return whether the thread is alive.

This method returns True just before the run() method starts until just after the run() method terminates. See also the module function enumerate().

Source code in `python3.13/threading.py`

    1136
    1137
    1138
    1139
    1140
    1141
    1142
    1143
    1144
    1145
    def is_alive(self):
        """Return whether the thread is alive.

        This method returns True just before the run() method starts until just
        after the run() method terminates. See also the module function
        enumerate().

        """
        assert self._initialized, "Thread.__init__() not called"
        return self._started.is_set() and not self._handle.is_done()

#### `` join

    join(timeout=None)

Wait until the thread terminates.

This blocks the calling thread until the thread whose join() method is called terminates -- either normally or through an unhandled exception or until the optional timeout occurs.

When the timeout argument is present and not None, it should be a floating-point number specifying a timeout for the operation in seconds (or fractions thereof). As join() always returns None, you must call is_alive() after join() to decide whether a timeout happened -- if the thread is still alive, the join() call timed out.

When the timeout argument is not present or None, the operation will block until the thread terminates.

A thread can be join()ed many times.

join() raises a RuntimeError if an attempt is made to join the current thread as that would cause a deadlock. It is also an error to join() a thread before it has been started and attempts to do so raises the same exception.

Source code in `python3.13/threading.py`

    1058
    1059
    1060
    1061
    1062
    1063
    1064
    1065
    1066
    1067
    1068
    1069
    1070
    1071
    1072
    1073
    1074
    1075
    1076
    1077
    1078
    1079
    1080
    1081
    1082
    1083
    1084
    1085
    1086
    1087
    1088
    1089
    1090
    1091
    1092
    1093
    1094
    def join(self, timeout=None):
        """Wait until the thread terminates.

        This blocks the calling thread until the thread whose join() method is
        called terminates -- either normally or through an unhandled exception
        or until the optional timeout occurs.

        When the timeout argument is present and not None, it should be a
        floating-point number specifying a timeout for the operation in seconds
        (or fractions thereof). As join() always returns None, you must call
        is_alive() after join() to decide whether a timeout happened -- if the
        thread is still alive, the join() call timed out.

        When the timeout argument is not present or None, the operation will
        block until the thread terminates.

        A thread can be join()ed many times.

        join() raises a RuntimeError if an attempt is made to join the current
        thread as that would cause a deadlock. It is also an error to join() a
        thread before it has been started and attempts to do so raises the same
        exception.

        """
        if not self._initialized:
            raise RuntimeError("Thread.__init__() not called")
        if not self._started.is_set():
            raise RuntimeError("cannot join thread before it is started")
        if self is current_thread():
            raise RuntimeError("cannot join current thread")

        # the behavior of a negative timeout isn't documented, but
        # historically .join(timeout=x) for x<0 has acted as if timeout=0
        if timeout is not None:
            timeout = max(timeout, 0)

        self._handle.join(timeout)

#### `` ping

    ping(timeout: float) -> PingRep

Send a ping request to the drone.

Parameters:

- `timeout` (`float`) –

  The timeout for the response.

Returns:

- `PingRep` –

  blueye.protocol.PingRep: The ping response.

Source code in `blueye/sdk/connection.py`

    527
    528
    529
    530
    531
    532
    533
    534
    535
    536
    537
    def ping(self, timeout: float) -> blueye.protocol.PingRep:
        """Send a ping request to the drone.

        Args:
            timeout (float): The timeout for the response.

        Returns:
            blueye.protocol.PingRep: The ping response.
        """
        request = blueye.protocol.PingReq()
        return self._send_request_get_response(request, blueye.protocol.PingRep, timeout)

#### `` run

    run()

Run the request-reply client thread.

Source code in `blueye/sdk/connection.py`

    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    def run(self):
        """Run the request-reply client thread."""
        while not self._exit_flag.is_set():
            try:
                msg, response_type, response_callback_queue = self._requests_to_send.get(
                    timeout=0.1
                )
                self._socket.send_multipart(
                    [
                        bytes(msg._pb.DESCRIPTOR.full_name, "utf-8"),
                        msg.__class__.serialize(msg),
                    ]
                )
            except queue.Empty:
                # No requests to send, so we can
                continue
            # TODO: Deal with timeout
            resp = self._socket.recv_multipart()
            resp_deserialized = response_type.deserialize(resp[1])
            response_callback_queue.put(resp_deserialized)

#### `` setDaemon

    setDaemon(daemonic)

Set whether this thread is a daemon.

This method is deprecated, use the .daemon property instead.

Source code in `python3.13/threading.py`

    1183
    1184
    1185
    1186
    1187
    1188
    1189
    1190
    1191
    1192
    def setDaemon(self, daemonic):
        """Set whether this thread is a daemon.

        This method is deprecated, use the .daemon property instead.

        """
        import warnings
        warnings.warn('setDaemon() is deprecated, set the daemon attribute instead',
                      DeprecationWarning, stacklevel=2)
        self.daemon = daemonic

#### `` setName

    setName(name)

Set the name string for this thread.

This method is deprecated, use the name attribute instead.

Source code in `python3.13/threading.py`

    1205
    1206
    1207
    1208
    1209
    1210
    1211
    1212
    1213
    1214
    def setName(self, name):
        """Set the name string for this thread.

        This method is deprecated, use the name attribute instead.

        """
        import warnings
        warnings.warn('setName() is deprecated, set the name attribute instead',
                      DeprecationWarning, stacklevel=2)
        self.name = name

#### `` set_camera_parameters

    set_camera_parameters(
        parameters: CameraParameters, timeout: float = 0.05
    ) -> SetCameraParametersRep

Set the camera parameters.

Parameters:

- `parameters` (`CameraParameters`) –

  The camera parameters.

- `timeout` (`float`, default: `0.05` ) –

  The timeout for the response.

Returns:

- `SetCameraParametersRep` –

  The response message.

Source code in `blueye/sdk/connection.py`

    557
    558
    559
    560
    561
    562
    563
    564
    565
    566
    567
    568
    569
    570
    571
    572
    573
    574
    def set_camera_parameters(
        self,
        parameters: blueye.protocol.CameraParameters,
        timeout: float = 0.05,
    ) -> blueye.protocol.SetCameraParametersRep:
        """Set the camera parameters.

        Args:
            parameters (blueye.protocol.CameraParameters): The camera parameters.
            timeout (float, optional): The timeout for the response.

        Returns:
            The response message.
        """
        request = blueye.protocol.SetCameraParametersReq(camera_parameters=parameters)
        return self._send_request_get_response(
            request, blueye.protocol.SetCameraParametersRep, timeout
        )

#### `` set_mission

    set_mission(
        mission: Mission, timeout: float = 0.05
    ) -> SetMissionRep

Send a new mission to the drone

Requires that the drone is ready to receive a new mission.

Source code in `blueye/sdk/connection.py`

    702
    703
    704
    705
    706
    707
    708
    709
    710
    def set_mission(
        self, mission: blueye.protocol.Mission, timeout: float = 0.05
    ) -> blueye.protocol.SetMissionRep:
        """Send a new mission to the drone

        Requires that the drone is ready to receive a new mission.
        """
        request = blueye.protocol.SetMissionReq(mission=mission)
        return self._send_request_get_response(request, blueye.protocol.SetMissionRep, timeout)

#### `` set_overlay_parameters

    set_overlay_parameters(
        parameters: OverlayParameters, timeout: float = 0.05
    ) -> SetOverlayParametersRep

Set the overlay parameters.

Parameters:

- `parameters` (`OverlayParameters`) –

  The overlay parameters.

- `timeout` (`float`, default: `0.05` ) –

  The timeout for the response.

Returns:

- `SetOverlayParametersRep` –

  The response message.

Source code in `blueye/sdk/connection.py`

    591
    592
    593
    594
    595
    596
    597
    598
    599
    600
    601
    602
    603
    604
    605
    606
    def set_overlay_parameters(
        self, parameters: blueye.protocol.OverlayParameters, timeout: float = 0.05
    ) -> blueye.protocol.SetOverlayParametersRep:
        """Set the overlay parameters.

        Args:
            parameters (blueye.protocol.OverlayParameters): The overlay parameters.
            timeout (float, optional): The timeout for the response.

        Returns:
            The response message.
        """
        request = blueye.protocol.SetOverlayParametersReq(overlay_parameters=parameters)
        return self._send_request_get_response(
            request, blueye.protocol.SetOverlayParametersRep, timeout
        )

#### `` set_telemetry_msg_publish_frequency

    set_telemetry_msg_publish_frequency(
        msg: MessageMeta | str,
        frequency: float,
        timeout: float = 0.05,
    ) -> SetPubFrequencyRep

Set the telemetry message publish frequency.

Parameters:

- `msg` (`MessageMeta | str`) –

  The message type.

- `frequency` (`float`) –

  The publish frequency.

- `timeout` (`float`, default: `0.05` ) –

  The timeout for the response.

Returns:

- `SetPubFrequencyRep` –

  The set publish frequency response.

Source code in `blueye/sdk/connection.py`

    661
    662
    663
    664
    665
    666
    667
    668
    669
    670
    671
    672
    673
    674
    675
    676
    677
    678
    679
    def set_telemetry_msg_publish_frequency(
        self, msg: proto.message.MessageMeta | str, frequency: float, timeout: float = 0.05
    ) -> blueye.protocol.SetPubFrequencyRep:
        """Set the telemetry message publish frequency.

        Args:
            msg (proto.message.MessageMeta | str): The message type.
            frequency (float): The publish frequency.
            timeout (float, optional): The timeout for the response.

        Returns:
            The set publish frequency response.
        """
        message_type = self._parse_type_to_string(msg)
        request = blueye.protocol.SetPubFrequencyReq(
            message_type=message_type,
            frequency=frequency,
        )
        return self._send_request_get_response(request, blueye.protocol.SetPubFrequencyRep, timeout)

#### `` start

    start()

Start the thread's activity.

It must be called at most once per thread object. It arranges for the object's run() method to be invoked in a separate thread of control.

This method will raise a RuntimeError if called more than once on the same thread object.

Source code in `python3.13/threading.py`

    955
    956
    957
    958
    959
    960
    961
    962
    963
    964
    965
    966
    967
    968
    969
    970
    971
    972
    973
    974
    975
    976
    977
    978
    979
    980
    981
    def start(self):
        """Start the thread's activity.

        It must be called at most once per thread object. It arranges for the
        object's run() method to be invoked in a separate thread of control.

        This method will raise a RuntimeError if called more than once on the
        same thread object.

        """
        if not self._initialized:
            raise RuntimeError("thread.__init__() not called")

        if self._started.is_set():
            raise RuntimeError("threads can only be started once")

        with _active_limbo_lock:
            _limbo[self] = self
        try:
            # Start joinable thread
            _start_joinable_thread(self._bootstrap, handle=self._handle,
                                   daemon=self.daemon)
        except Exception:
            with _active_limbo_lock:
                del _limbo[self]
            raise
        self._started.wait()  # Will set ident and native_id

#### `` stop

    stop()

Stop the request-reply client thread.

Source code in `blueye/sdk/connection.py`

    495
    496
    497
    def stop(self):
        """Stop the request-reply client thread."""
        self._exit_flag.set()

#### `` sync_time

    sync_time(time: int, timeout: float = 0.05) -> SyncTimeRep

Synchronize the time with the drone.

Parameters:

- `time` (`int`) –

  The Unix timestamp to synchronize.

- `timeout` (`float`, default: `0.05` ) –

  The timeout for the response.

Returns:

- `SyncTimeRep` –

  The response message.

Source code in `blueye/sdk/connection.py`

    608
    609
    610
    611
    612
    613
    614
    615
    616
    617
    618
    619
    620
    621
    def sync_time(self, time: int, timeout: float = 0.05) -> blueye.protocol.SyncTimeRep:
        """Synchronize the time with the drone.

        Args:
            time (int): The Unix timestamp to synchronize.
            timeout (float, optional): The timeout for the response.

        Returns:
            The response message.
        """
        request = blueye.protocol.SyncTimeReq(
            time={"unix_timestamp": {"seconds": time, "nanos": 0}}
        )
        return self._send_request_get_response(request, blueye.protocol.SyncTimeRep, timeout)

### `` TelemetryClient

    TelemetryClient(
        parent_drone: "blueye.sdk.Drone",
        context: Context = None,
    )

Bases: `Thread`

A thread that handles telemetry messages from the drone

Parameters:

- `parent_drone` (`Drone`) –

  The parent drone instance.

- `context` (`Context`, default: `None` ) –

  The ZeroMQ context.

Methods:

- `add_callback` –

  Add a callback for telemetry messages.

- `get` –

  Get the latest received message of a specific type.

- `getName` –

  Return a string used for identification purposes only.

- `isDaemon` –

  Return whether this thread is a daemon.

- `is_alive` –

  Return whether the thread is alive.

- `join` –

  Wait until the thread terminates.

- `remove_callback` –

  Remove a callback by its UUID.

- `run` –

  Run the telemetry client thread.

- `setDaemon` –

  Set whether this thread is a daemon.

- `setName` –

  Set the name string for this thread.

- `start` –

  Start the thread's activity.

- `stop` –

  Stop the telemetry client thread.

Attributes:

- `daemon` –

  A boolean value indicating whether this thread is a daemon thread.

- `ident` –

  Thread identifier of this thread or None if it has not been started.

- `name` –

  A string used for identification purposes only.

- `native_id` –

  Native integral thread ID of this thread, or None if it has not been started.

Source code in `blueye/sdk/connection.py`

     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    def __init__(self, parent_drone: "blueye.sdk.Drone", context: zmq.Context = None):
        """Initialize the TelemetryClient.

        Args:
            parent_drone (blueye.sdk.Drone): The parent drone instance.
            context (zmq.Context, optional): The ZeroMQ context.
        """
        super().__init__(daemon=True)
        self._parent_drone = parent_drone
        self._context = context or zmq.Context().instance()
        self._socket = self._context.socket(zmq.SUB)
        self._socket.connect(f"tcp://{self._parent_drone._ip}:5555")
        self._socket.setsockopt_string(zmq.SUBSCRIBE, "")
        self._exit_flag = threading.Event()
        self._state_lock = threading.Lock()
        self._callbacks: List[Callback] = []
        self._state: Dict[proto.message.Message, bytes] = {}
        """`_state` is dictionary of the latest received messages, where the key is the protobuf
        message class, eg. blueye.protocol.DepthTel and the value is the serialized protobuf
        message"""

#### `` daemon `property` `writable`

    daemon

A boolean value indicating whether this thread is a daemon thread.

This must be set before start() is called, otherwise RuntimeError is raised. Its initial value is inherited from the creating thread; the main thread is not a daemon thread and therefore all threads created in the main thread default to daemon = False.

The entire Python program exits when only daemon threads are left.

#### `` ident `property`

    ident

Thread identifier of this thread or None if it has not been started.

This is a nonzero integer. See the get_ident() function. Thread identifiers may be recycled when a thread exits and another thread is created. The identifier is available even after the thread has exited.

#### `` name `property` `writable`

    name

A string used for identification purposes only.

It has no semantics. Multiple threads may be given the same name. The initial name is set by the constructor.

#### `` native_id `property`

    native_id

Native integral thread ID of this thread, or None if it has not been started.

This is a non-negative integer. See the get_native_id() function. This represents the Thread ID as reported by the kernel.

#### `` add_callback

    add_callback(
        msg_filter: List[Message],
        callback_function: Callable[[str, Message], None],
        raw: bool,
        **kwargs: Dict[str, Any]
    ) -> str

Add a callback for telemetry messages.

Parameters:

- `msg_filter` (`List[Message]`) –

  The list of message types to run the callback function for.

- `callback_function` (`Callable[[str, Message], None]`) –

  The callback function.

- `raw` (`bool`) –

  Whether to pass raw data to the callback.

- `**kwargs` (`Dict[str, Any]`, default: `{}` ) –

  Additional keyword arguments for the callback.

Returns:

- `str` ( `str` ) –

  The UUID of the callback in hexadecimal format.

Source code in `blueye/sdk/connection.py`

    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    def add_callback(
        self,
        msg_filter: List[proto.message.Message],
        callback_function: Callable[[str, proto.message.Message], None],
        raw: bool,
        **kwargs: Dict[str, Any],
    ) -> str:
        """Add a callback for telemetry messages.

        Args:
            msg_filter (List[proto.message.Message]): The list of message types to run the callback
                                                      function for.
            callback_function (Callable[[str, proto.message.Message], None]): The callback function.
            raw (bool): Whether to pass raw data to the callback.
            **kwargs: Additional keyword arguments for the callback.

        Returns:
            str: The UUID of the callback in hexadecimal format.
        """
        uuid_hex = uuid.uuid1().hex
        self._callbacks.append(Callback(msg_filter, callback_function, raw, uuid_hex, kwargs))
        return uuid_hex

#### `` get

    get(key: Message) -> bytes

Get the latest received message of a specific type.

Parameters:

- `key` (`Message`) –

  The message type to retrieve.

Returns:

- `bytes` ( `bytes` ) –

  The serialized message payload.

Source code in `blueye/sdk/connection.py`

    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    def get(self, key: proto.message.Message) -> bytes:
        """Get the latest received message of a specific type.

        Args:
            key (proto.message.Message): The message type to retrieve.

        Returns:
            bytes: The serialized message payload.
        """
        with self._state_lock:
            return self._state[key]

#### `` getName

    getName()

Return a string used for identification purposes only.

This method is deprecated, use the name attribute instead.

Source code in `python3.13/threading.py`

    1194
    1195
    1196
    1197
    1198
    1199
    1200
    1201
    1202
    1203
    def getName(self):
        """Return a string used for identification purposes only.

        This method is deprecated, use the name attribute instead.

        """
        import warnings
        warnings.warn('getName() is deprecated, get the name attribute instead',
                      DeprecationWarning, stacklevel=2)
        return self.name

#### `` isDaemon

    isDaemon()

Return whether this thread is a daemon.

This method is deprecated, use the daemon attribute instead.

Source code in `python3.13/threading.py`

    1172
    1173
    1174
    1175
    1176
    1177
    1178
    1179
    1180
    1181
    def isDaemon(self):
        """Return whether this thread is a daemon.

        This method is deprecated, use the daemon attribute instead.

        """
        import warnings
        warnings.warn('isDaemon() is deprecated, get the daemon attribute instead',
                      DeprecationWarning, stacklevel=2)
        return self.daemon

#### `` is_alive

    is_alive()

Return whether the thread is alive.

This method returns True just before the run() method starts until just after the run() method terminates. See also the module function enumerate().

Source code in `python3.13/threading.py`

    1136
    1137
    1138
    1139
    1140
    1141
    1142
    1143
    1144
    1145
    def is_alive(self):
        """Return whether the thread is alive.

        This method returns True just before the run() method starts until just
        after the run() method terminates. See also the module function
        enumerate().

        """
        assert self._initialized, "Thread.__init__() not called"
        return self._started.is_set() and not self._handle.is_done()

#### `` join

    join(timeout=None)

Wait until the thread terminates.

This blocks the calling thread until the thread whose join() method is called terminates -- either normally or through an unhandled exception or until the optional timeout occurs.

When the timeout argument is present and not None, it should be a floating-point number specifying a timeout for the operation in seconds (or fractions thereof). As join() always returns None, you must call is_alive() after join() to decide whether a timeout happened -- if the thread is still alive, the join() call timed out.

When the timeout argument is not present or None, the operation will block until the thread terminates.

A thread can be join()ed many times.

join() raises a RuntimeError if an attempt is made to join the current thread as that would cause a deadlock. It is also an error to join() a thread before it has been started and attempts to do so raises the same exception.

Source code in `python3.13/threading.py`

    1058
    1059
    1060
    1061
    1062
    1063
    1064
    1065
    1066
    1067
    1068
    1069
    1070
    1071
    1072
    1073
    1074
    1075
    1076
    1077
    1078
    1079
    1080
    1081
    1082
    1083
    1084
    1085
    1086
    1087
    1088
    1089
    1090
    1091
    1092
    1093
    1094
    def join(self, timeout=None):
        """Wait until the thread terminates.

        This blocks the calling thread until the thread whose join() method is
        called terminates -- either normally or through an unhandled exception
        or until the optional timeout occurs.

        When the timeout argument is present and not None, it should be a
        floating-point number specifying a timeout for the operation in seconds
        (or fractions thereof). As join() always returns None, you must call
        is_alive() after join() to decide whether a timeout happened -- if the
        thread is still alive, the join() call timed out.

        When the timeout argument is not present or None, the operation will
        block until the thread terminates.

        A thread can be join()ed many times.

        join() raises a RuntimeError if an attempt is made to join the current
        thread as that would cause a deadlock. It is also an error to join() a
        thread before it has been started and attempts to do so raises the same
        exception.

        """
        if not self._initialized:
            raise RuntimeError("Thread.__init__() not called")
        if not self._started.is_set():
            raise RuntimeError("cannot join thread before it is started")
        if self is current_thread():
            raise RuntimeError("cannot join current thread")

        # the behavior of a negative timeout isn't documented, but
        # historically .join(timeout=x) for x<0 has acted as if timeout=0
        if timeout is not None:
            timeout = max(timeout, 0)

        self._handle.join(timeout)

#### `` remove_callback

    remove_callback(callback_id: str)

Remove a callback by its UUID.

Parameters:

- `callback_id` (`str`) –

  The UUID of the callback to remove.

Source code in `blueye/sdk/connection.py`

    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    def remove_callback(self, callback_id: str):
        """Remove a callback by its UUID.

        Args:
            callback_id (str): The UUID of the callback to remove.
        """
        try:
            self._callbacks.pop([cb.uuid_hex for cb in self._callbacks].index(callback_id))
        except ValueError:
            logger.warning(f"Callback with id {callback_id} not found, ignoring")

#### `` run

    run()

Run the telemetry client thread.

Source code in `blueye/sdk/connection.py`

    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    def run(self):
        """Run the telemetry client thread."""
        poller = zmq.Poller()
        poller.register(self._socket, zmq.POLLIN)

        while not self._exit_flag.is_set():
            events_to_be_processed = poller.poll(10)
            if len(events_to_be_processed) > 0:
                msg = self._socket.recv_multipart()
                self._handle_message(msg)

#### `` setDaemon

    setDaemon(daemonic)

Set whether this thread is a daemon.

This method is deprecated, use the .daemon property instead.

Source code in `python3.13/threading.py`

    1183
    1184
    1185
    1186
    1187
    1188
    1189
    1190
    1191
    1192
    def setDaemon(self, daemonic):
        """Set whether this thread is a daemon.

        This method is deprecated, use the .daemon property instead.

        """
        import warnings
        warnings.warn('setDaemon() is deprecated, set the daemon attribute instead',
                      DeprecationWarning, stacklevel=2)
        self.daemon = daemonic

#### `` setName

    setName(name)

Set the name string for this thread.

This method is deprecated, use the name attribute instead.

Source code in `python3.13/threading.py`

    1205
    1206
    1207
    1208
    1209
    1210
    1211
    1212
    1213
    1214
    def setName(self, name):
        """Set the name string for this thread.

        This method is deprecated, use the name attribute instead.

        """
        import warnings
        warnings.warn('setName() is deprecated, set the name attribute instead',
                      DeprecationWarning, stacklevel=2)
        self.name = name

#### `` start

    start()

Start the thread's activity.

It must be called at most once per thread object. It arranges for the object's run() method to be invoked in a separate thread of control.

This method will raise a RuntimeError if called more than once on the same thread object.

Source code in `python3.13/threading.py`

    955
    956
    957
    958
    959
    960
    961
    962
    963
    964
    965
    966
    967
    968
    969
    970
    971
    972
    973
    974
    975
    976
    977
    978
    979
    980
    981
    def start(self):
        """Start the thread's activity.

        It must be called at most once per thread object. It arranges for the
        object's run() method to be invoked in a separate thread of control.

        This method will raise a RuntimeError if called more than once on the
        same thread object.

        """
        if not self._initialized:
            raise RuntimeError("thread.__init__() not called")

        if self._started.is_set():
            raise RuntimeError("threads can only be started once")

        with _active_limbo_lock:
            _limbo[self] = self
        try:
            # Start joinable thread
            _start_joinable_thread(self._bootstrap, handle=self._handle,
                                   daemon=self.daemon)
        except Exception:
            with _active_limbo_lock:
                del _limbo[self]
            raise
        self._started.wait()  # Will set ident and native_id

#### `` stop

    stop()

Stop the telemetry client thread.

Source code in `blueye/sdk/connection.py`

    187
    188
    189
    def stop(self):
        """Stop the telemetry client thread."""
        self._exit_flag.set()

### `` WatchdogPublisher

    WatchdogPublisher(
        parent_drone: "blueye.sdk.Drone",
        context: Context = None,
    )

Bases: `Thread`

A thread that publishes watchdog messages to keep the connection alive.

Parameters:

- `parent_drone` (`Drone`) –

  The parent drone instance.

- `context` (`Context`, default: `None` ) –

  The ZeroMQ context.

Methods:

- `getName` –

  Return a string used for identification purposes only.

- `isDaemon` –

  Return whether this thread is a daemon.

- `is_alive` –

  Return whether the thread is alive.

- `join` –

  Wait until the thread terminates.

- `pet_watchdog` –

  Send a watchdog message.

- `run` –

  Run the watchdog publisher thread.

- `setDaemon` –

  Set whether this thread is a daemon.

- `setName` –

  Set the name string for this thread.

- `start` –

  Start the thread's activity.

- `stop` –

  Stop the watchdog thread started by run().

Attributes:

- `daemon` –

  A boolean value indicating whether this thread is a daemon thread.

- `ident` –

  Thread identifier of this thread or None if it has not been started.

- `name` –

  A string used for identification purposes only.

- `native_id` –

  Native integral thread ID of this thread, or None if it has not been started.

Source code in `blueye/sdk/connection.py`

    26
    27
    28
    29
    30
    31
    32
    def __init__(self, parent_drone: "blueye.sdk.Drone", context: zmq.Context = None):
        super().__init__(daemon=True)
        self._parent_drone = parent_drone
        self._context = context or zmq.Context().instance()
        self._socket = self._context.socket(zmq.PUB)
        self._socket.connect(f"tcp://{self._parent_drone._ip}:5557")
        self._exit_flag = threading.Event()

#### `` daemon `property` `writable`

    daemon

A boolean value indicating whether this thread is a daemon thread.

This must be set before start() is called, otherwise RuntimeError is raised. Its initial value is inherited from the creating thread; the main thread is not a daemon thread and therefore all threads created in the main thread default to daemon = False.

The entire Python program exits when only daemon threads are left.

#### `` ident `property`

    ident

Thread identifier of this thread or None if it has not been started.

This is a nonzero integer. See the get_ident() function. Thread identifiers may be recycled when a thread exits and another thread is created. The identifier is available even after the thread has exited.

#### `` name `property` `writable`

    name

A string used for identification purposes only.

It has no semantics. Multiple threads may be given the same name. The initial name is set by the constructor.

#### `` native_id `property`

    native_id

Native integral thread ID of this thread, or None if it has not been started.

This is a non-negative integer. See the get_native_id() function. This represents the Thread ID as reported by the kernel.

#### `` getName

    getName()

Return a string used for identification purposes only.

This method is deprecated, use the name attribute instead.

Source code in `python3.13/threading.py`

    1194
    1195
    1196
    1197
    1198
    1199
    1200
    1201
    1202
    1203
    def getName(self):
        """Return a string used for identification purposes only.

        This method is deprecated, use the name attribute instead.

        """
        import warnings
        warnings.warn('getName() is deprecated, get the name attribute instead',
                      DeprecationWarning, stacklevel=2)
        return self.name

#### `` isDaemon

    isDaemon()

Return whether this thread is a daemon.

This method is deprecated, use the daemon attribute instead.

Source code in `python3.13/threading.py`

    1172
    1173
    1174
    1175
    1176
    1177
    1178
    1179
    1180
    1181
    def isDaemon(self):
        """Return whether this thread is a daemon.

        This method is deprecated, use the daemon attribute instead.

        """
        import warnings
        warnings.warn('isDaemon() is deprecated, get the daemon attribute instead',
                      DeprecationWarning, stacklevel=2)
        return self.daemon

#### `` is_alive

    is_alive()

Return whether the thread is alive.

This method returns True just before the run() method starts until just after the run() method terminates. See also the module function enumerate().

Source code in `python3.13/threading.py`

    1136
    1137
    1138
    1139
    1140
    1141
    1142
    1143
    1144
    1145
    def is_alive(self):
        """Return whether the thread is alive.

        This method returns True just before the run() method starts until just
        after the run() method terminates. See also the module function
        enumerate().

        """
        assert self._initialized, "Thread.__init__() not called"
        return self._started.is_set() and not self._handle.is_done()

#### `` join

    join(timeout=None)

Wait until the thread terminates.

This blocks the calling thread until the thread whose join() method is called terminates -- either normally or through an unhandled exception or until the optional timeout occurs.

When the timeout argument is present and not None, it should be a floating-point number specifying a timeout for the operation in seconds (or fractions thereof). As join() always returns None, you must call is_alive() after join() to decide whether a timeout happened -- if the thread is still alive, the join() call timed out.

When the timeout argument is not present or None, the operation will block until the thread terminates.

A thread can be join()ed many times.

join() raises a RuntimeError if an attempt is made to join the current thread as that would cause a deadlock. It is also an error to join() a thread before it has been started and attempts to do so raises the same exception.

Source code in `python3.13/threading.py`

    1058
    1059
    1060
    1061
    1062
    1063
    1064
    1065
    1066
    1067
    1068
    1069
    1070
    1071
    1072
    1073
    1074
    1075
    1076
    1077
    1078
    1079
    1080
    1081
    1082
    1083
    1084
    1085
    1086
    1087
    1088
    1089
    1090
    1091
    1092
    1093
    1094
    def join(self, timeout=None):
        """Wait until the thread terminates.

        This blocks the calling thread until the thread whose join() method is
        called terminates -- either normally or through an unhandled exception
        or until the optional timeout occurs.

        When the timeout argument is present and not None, it should be a
        floating-point number specifying a timeout for the operation in seconds
        (or fractions thereof). As join() always returns None, you must call
        is_alive() after join() to decide whether a timeout happened -- if the
        thread is still alive, the join() call timed out.

        When the timeout argument is not present or None, the operation will
        block until the thread terminates.

        A thread can be join()ed many times.

        join() raises a RuntimeError if an attempt is made to join the current
        thread as that would cause a deadlock. It is also an error to join() a
        thread before it has been started and attempts to do so raises the same
        exception.

        """
        if not self._initialized:
            raise RuntimeError("Thread.__init__() not called")
        if not self._started.is_set():
            raise RuntimeError("cannot join thread before it is started")
        if self is current_thread():
            raise RuntimeError("cannot join current thread")

        # the behavior of a negative timeout isn't documented, but
        # historically .join(timeout=x) for x<0 has acted as if timeout=0
        if timeout is not None:
            timeout = max(timeout, 0)

        self._handle.join(timeout)

#### `` pet_watchdog

    pet_watchdog(duration)

Send a watchdog message.

Parameters:

- `duration` (`int`) –

  The duration of the connection.

Source code in `blueye/sdk/connection.py`

    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    def pet_watchdog(self, duration):
        """Send a watchdog message.

        Args:
            duration (int): The duration of the connection.
        """
        msg = blueye.protocol.WatchdogCtrl(
            connection_duration={"value": duration}, client_id=self._parent_drone.client_id
        )
        self._socket.send_multipart(
            [
                bytes(msg._pb.DESCRIPTOR.full_name, "utf-8"),
                blueye.protocol.WatchdogCtrl.serialize(msg),
            ]
        )

#### `` run

    run()

Run the watchdog publisher thread.

Source code in `blueye/sdk/connection.py`

    34
    35
    36
    37
    38
    39
    40
    def run(self):
        """Run the watchdog publisher thread."""
        duration = 0
        WATCHDOG_DELAY = 1
        while not self._exit_flag.wait(WATCHDOG_DELAY):
            self.pet_watchdog(duration)
            duration += 1

#### `` setDaemon

    setDaemon(daemonic)

Set whether this thread is a daemon.

This method is deprecated, use the .daemon property instead.

Source code in `python3.13/threading.py`

    1183
    1184
    1185
    1186
    1187
    1188
    1189
    1190
    1191
    1192
    def setDaemon(self, daemonic):
        """Set whether this thread is a daemon.

        This method is deprecated, use the .daemon property instead.

        """
        import warnings
        warnings.warn('setDaemon() is deprecated, set the daemon attribute instead',
                      DeprecationWarning, stacklevel=2)
        self.daemon = daemonic

#### `` setName

    setName(name)

Set the name string for this thread.

This method is deprecated, use the name attribute instead.

Source code in `python3.13/threading.py`

    1205
    1206
    1207
    1208
    1209
    1210
    1211
    1212
    1213
    1214
    def setName(self, name):
        """Set the name string for this thread.

        This method is deprecated, use the name attribute instead.

        """
        import warnings
        warnings.warn('setName() is deprecated, set the name attribute instead',
                      DeprecationWarning, stacklevel=2)
        self.name = name

#### `` start

    start()

Start the thread's activity.

It must be called at most once per thread object. It arranges for the object's run() method to be invoked in a separate thread of control.

This method will raise a RuntimeError if called more than once on the same thread object.

Source code in `python3.13/threading.py`

    955
    956
    957
    958
    959
    960
    961
    962
    963
    964
    965
    966
    967
    968
    969
    970
    971
    972
    973
    974
    975
    976
    977
    978
    979
    980
    981
    def start(self):
        """Start the thread's activity.

        It must be called at most once per thread object. It arranges for the
        object's run() method to be invoked in a separate thread of control.

        This method will raise a RuntimeError if called more than once on the
        same thread object.

        """
        if not self._initialized:
            raise RuntimeError("thread.__init__() not called")

        if self._started.is_set():
            raise RuntimeError("threads can only be started once")

        with _active_limbo_lock:
            _limbo[self] = self
        try:
            # Start joinable thread
            _start_joinable_thread(self._bootstrap, handle=self._handle,
                                   daemon=self.daemon)
        except Exception:
            with _active_limbo_lock:
                del _limbo[self]
            raise
        self._started.wait()  # Will set ident and native_id

#### `` stop

    stop()

Stop the watchdog thread started by run().

Source code in `blueye/sdk/connection.py`

    58
    59
    60
    def stop(self):
        """Stop the watchdog thread started by run()."""
        self._exit_flag.set()