Source code for herosdevices.core.bus.i2c

"""Primitive functions and classes representing I2C connections."""

from collections.abc import Iterator
from contextlib import contextmanager
from typing import TYPE_CHECKING, cast

if TYPE_CHECKING:
    from types import ModuleType

try:
    import smbus2
except ModuleNotFoundError:
    smbus2 = cast("ModuleType", None)


[docs] class I2CConnection: """A class to manage I2C communication connections via smbus2. Args: bus_id: I2C bus id (e.g. 1 for /dev/i2c-1). keep_alive: if True, keep the bus open between operations. """ def __init__(self, bus_id: int, keep_alive: bool = True) -> None: if smbus2 is None: raise ModuleNotFoundError("Could not import the 'smbus2' python module, I2C devices will not be available") self.bus_id = bus_id self.keep_alive = keep_alive self.connection = smbus2.SMBus() @property def is_open(self) -> bool: """Return whether the bus is currently open. Returns: True if the bus file descriptor is open. """ return self.connection.fd is not None
[docs] def open(self) -> None: """Open the I2C bus if not already open.""" if not self.is_open: self.connection.open(self.bus_id)
[docs] def close(self) -> None: """Close the I2C bus.""" self.connection.close()
[docs] @contextmanager def operation(self) -> Iterator[None]: """Context manager for I2C operations. Ensures the bus is open before performing operations and closes it afterward if keep_alive is False. Yields: Yields control back to the caller. """ self.open() try: yield finally: if not self.keep_alive: self.close()