1 """Code to handle pins on a Firmata board."""
3 from __future__
import annotations
5 from collections.abc
import Callable
7 from typing
import cast
9 from .board
import FirmataBoard, FirmataPinType
10 from .const
import PIN_MODE_INPUT, PIN_MODE_PULLUP, PIN_TYPE_ANALOG
12 _LOGGER = logging.getLogger(__name__)
16 """Represents an exception when a pin is already in use."""
20 """Manages a single Firmata board pin."""
22 def __init__(self, board: FirmataBoard, pin: FirmataPinType, pin_mode: str) ->
None:
23 """Initialize the pin."""
28 self._state: bool | int |
None =
None
36 """Set up a pin and make sure it is valid."""
37 if not self.
boardboard.mark_pin_used(self.
_pin_pin):
42 """Representation of a Firmata Digital Output Pin."""
54 """Initialize the digital output pin."""
57 super().
__init__(board, pin, pin_mode)
60 """Set initial state on a pin."""
62 "Setting initial state for digital output pin %s on board %s",
66 api = self.
boardboard.api
68 await api.set_pin_mode_digital_output(self.
_firmata_pin_firmata_pin)
71 new_pin_state =
not self.
_negate_negate
73 new_pin_state = self.
_negate_negate
74 await api.digital_pin_write(self.
_firmata_pin_firmata_pin,
int(new_pin_state))
79 """Return true if digital output is on."""
83 """Turn on digital output."""
84 _LOGGER.debug(
"Turning digital output on pin %s on", self.
_pin_pin)
85 new_pin_state =
not self.
_negate_negate
90 """Turn off digital output."""
91 _LOGGER.debug(
"Turning digital output on pin %s off", self.
_pin_pin)
92 new_pin_state = self.
_negate_negate
98 """Representation of a Firmata PWM/analog Output Pin."""
111 """Initialize the PWM/analog output pin."""
116 super().
__init__(board, pin, pin_mode)
119 """Set initial state on a pin."""
121 "Setting initial state for PWM/analog output pin %s on board %s to %d",
123 self.
boardboard.name,
126 api = self.
boardboard.api
127 await api.set_pin_mode_pwm_output(self.
_firmata_pin_firmata_pin)
129 new_pin_state = round((self.
_initial_initial * self.
_range_range) / 255) + self.
_min_min
130 await api.pwm_write(self.
_firmata_pin_firmata_pin, new_pin_state)
135 """Return PWM/analog state."""
139 """Set PWM/analog output."""
140 _LOGGER.debug(
"Setting PWM/analog output on pin %s to %d", self.
_pin_pin, level)
141 new_pin_state = round((level * self.
_range_range) / 255) + self.
_min_min
142 await self.
boardboard.api.pwm_write(self.
_firmata_pin_firmata_pin, new_pin_state)
147 """Representation of a Firmata Digital Input Pin."""
152 self, board: FirmataBoard, pin: FirmataPinType, pin_mode: str, negate: bool
154 """Initialize the digital input pin."""
157 super().
__init__(board, pin, pin_mode)
159 async
def start_pin(self, forward_callback: Callable[[],
None]) ->
None:
160 """Get initial state and start reporting a pin."""
162 "Starting reporting updates for digital input pin %s on board %s",
164 self.
boardboard.name,
167 api = self.
boardboard.api
169 await api.set_pin_mode_digital_input(self.
_pin_pin, self.
latch_callbacklatch_callback)
171 await api.set_pin_mode_digital_input_pullup(self.
_pin_pin, self.
latch_callbacklatch_callback)
173 new_state = bool((await self.
boardboard.api.digital_read(self.
_firmata_pin_firmata_pin))[0])
175 new_state =
not new_state
178 await api.enable_digital_reporting(self.
_pin_pin)
182 """Stop reporting digital input pin."""
184 "Stopping reporting updates for digital input pin %s on board %s",
186 self.
boardboard.name,
188 api = self.
boardboard.api
189 await api.disable_digital_reporting(self.
_pin_pin)
193 """Return true if digital input is on."""
197 """Update pin state on callback."""
201 "Received latch %d for digital input pin %d on board %s",
204 self.
boardboard.name,
206 new_state = bool(data[2])
208 new_state =
not new_state
209 if self.
_state_state == new_state:
211 self.
_state_state = new_state
216 """Representation of a Firmata Analog Input Pin."""
222 self, board: FirmataBoard, pin: FirmataPinType, pin_mode: str, differential: int
224 """Initialize the analog input pin."""
227 super().
__init__(board, pin, pin_mode)
229 async
def start_pin(self, forward_callback: Callable[[],
None]) ->
None:
230 """Get initial state and start reporting a pin."""
232 "Starting reporting updates for analog input pin %s on board %s",
234 self.
boardboard.name,
237 api = self.
boardboard.api
239 await api.set_pin_mode_analog_input(
248 """Stop reporting analog input pin."""
250 "Stopping reporting updates for analog input pin %s on board %s",
252 self.
boardboard.name,
254 api = self.
boardboard.api
255 await api.disable_analog_reporting(self.
_analog_pin_analog_pin)
259 """Return sensor state."""
263 """Update pin state on callback."""
267 "Received latch %d for analog input pin %s on board %s",
270 self.
boardboard.name,
273 if self.
_state_state == new_state:
274 _LOGGER.debug(
"stopping")
276 self.
_state_state = new_state
None __init__(self, FirmataBoard board, FirmataPinType pin, str pin_mode, bool initial, bool negate)
None __init__(self, FirmataBoard board, FirmataPinType pin, str pin_mode)
None __init__(self, FirmataBoard board, FirmataPinType pin, str pin_mode, bool initial, int minimum, int maximum)
None set_level(self, int level)