Source code for j5.components.servo

"""Classes for supporting Servomotors."""

from abc import abstractmethod
from typing import Type, Union

from j5.components.component import Component, Interface

# A servo can be powered down by setting its position to None.
ServoPosition = Union[float, None]


[docs]class ServoInterface(Interface): """An interface containing the methods required to control a Servo."""
[docs] @abstractmethod def get_servo_position(self, identifier: int) -> ServoPosition: """Get the position of a Servo.""" raise NotImplementedError # pragma: no cover
[docs] @abstractmethod def set_servo_position( self, identifier: int, position: ServoPosition, ) -> None: """Set the position of a Servo.""" raise NotImplementedError # pragma: no cover
[docs]class Servo(Component): """A standard servomotor.""" def __init__(self, identifier: int, backend: ServoInterface) -> None: self._backend = backend self._identifier = identifier
[docs] @staticmethod def interface_class() -> Type[ServoInterface]: """Get the interface class that is required to use this component.""" return ServoInterface
@property def identifier(self) -> int: """An integer to identify the component on a board.""" return self._identifier @property def position(self) -> ServoPosition: """Get the current position of the Servo.""" return self._backend.get_servo_position(self._identifier) @position.setter def position(self, new_position: ServoPosition) -> None: """Set the position of the Servo.""" if new_position is not None: if not -1 <= new_position <= 1: raise ValueError self._backend.set_servo_position(self._identifier, new_position)