diff --git a/adafruit_tsl2561.py b/adafruit_tsl2561.py index ef20ae9..7615402 100644 --- a/adafruit_tsl2561.py +++ b/adafruit_tsl2561.py @@ -33,6 +33,12 @@ from adafruit_bus_device.i2c_device import I2CDevice from micropython import const +try: + from typing import Optional, Tuple, Union + from busio import I2C +except ImportError: + pass + __version__ = "0.0.0+auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_TSL2561.git" @@ -60,19 +66,19 @@ class TSL2561: """Class which provides interface to TSL2561 light sensor.""" - def __init__(self, i2c, address=_DEFAULT_ADDRESS): + def __init__(self, i2c: I2C, address: int = _DEFAULT_ADDRESS) -> None: self.buf = bytearray(3) self.i2c_device = I2CDevice(i2c, address) partno, revno = self.chip_id # data sheet says TSL2561 = 0001, reality says 0101 if not partno == 5: raise RuntimeError( - "Failed to find TSL2561! Part 0x%x Rev 0x%x" % (partno, revno) + f"Failed to find TSL2561! Part {hex(partno)} Rev {hex(revno)}" ) self.enabled = True @property - def chip_id(self): + def chip_id(self) -> Tuple[int, int]: """A tuple containing the part number and the revision number.""" chip_id = self._read_register(_REGISTER_ID) partno = (chip_id >> 4) & 0x0F @@ -80,12 +86,12 @@ def chip_id(self): return (partno, revno) @property - def enabled(self): + def enabled(self) -> bool: """The state of the sensor.""" return (self._read_register(_REGISTER_CONTROL) & 0x03) != 0 @enabled.setter - def enabled(self, enable): + def enabled(self, enable: bool) -> None: """Enable or disable the sensor.""" if enable: self._enable() @@ -93,33 +99,33 @@ def enabled(self, enable): self._disable() @property - def lux(self): + def lux(self) -> Optional[float]: """The computed lux value or None when value is not computable.""" return self._compute_lux() @property - def broadband(self): + def broadband(self) -> int: """The broadband channel value.""" return self._read_broadband() @property - def infrared(self): + def infrared(self) -> int: """The infrared channel value.""" return self._read_infrared() @property - def luminosity(self): + def luminosity(self) -> Tuple[int, int]: """The overall luminosity as a tuple containing the broadband channel and the infrared channel value.""" return (self.broadband, self.infrared) @property - def gain(self): + def gain(self) -> int: """The gain. 0:1x, 1:16x.""" return self._read_register(_REGISTER_TIMING) >> 4 & 0x01 @gain.setter - def gain(self, value): + def gain(self, value: int) -> None: """Set the gain. 0:1x, 1:16x.""" value &= 0x01 value <<= 4 @@ -130,13 +136,13 @@ def gain(self, value): i2c.write(self.buf, end=2) @property - def integration_time(self): + def integration_time(self) -> int: """The integration time. 0:13.7ms, 1:101ms, 2:402ms, or 3:manual""" current = self._read_register(_REGISTER_TIMING) return current & 0x03 @integration_time.setter - def integration_time(self, value): + def integration_time(self, value: int) -> None: """Set the integration time. 0:13.7ms, 1:101ms, 2:402ms, or 3:manual.""" value &= 0x03 current = self._read_register(_REGISTER_TIMING) @@ -146,13 +152,13 @@ def integration_time(self, value): i2c.write(self.buf, end=2) @property - def threshold_low(self): + def threshold_low(self) -> int: """The low light interrupt threshold level.""" low, high = self._read_register(_REGISTER_TH_LOW, 2) return high << 8 | low @threshold_low.setter - def threshold_low(self, value): + def threshold_low(self, value: int) -> None: self.buf[0] = _COMMAND_BIT | _WORD_BIT | _REGISTER_TH_LOW self.buf[1] = value & 0xFF self.buf[2] = (value >> 8) & 0xFF @@ -160,13 +166,13 @@ def threshold_low(self, value): i2c.write(self.buf) @property - def threshold_high(self): + def threshold_high(self) -> int: """The upper light interrupt threshold level.""" low, high = self._read_register(_REGISTER_TH_HIGH, 2) return high << 8 | low @threshold_high.setter - def threshold_high(self, value): + def threshold_high(self, value: int) -> None: self.buf[0] = _COMMAND_BIT | _WORD_BIT | _REGISTER_TH_HIGH self.buf[1] = value & 0xFF self.buf[2] = (value >> 8) & 0xFF @@ -174,14 +180,14 @@ def threshold_high(self, value): i2c.write(self.buf) @property - def cycles(self): + def cycles(self) -> int: """The number of integration cycles for which an out of bounds value must persist to cause an interrupt.""" value = self._read_register(_REGISTER_INT_CTRL) return value & 0x0F @cycles.setter - def cycles(self, value): + def cycles(self, value: int) -> None: current = self._read_register(_REGISTER_INT_CTRL) self.buf[0] = _COMMAND_BIT | _REGISTER_INT_CTRL self.buf[1] = current | (value & 0x0F) @@ -189,7 +195,7 @@ def cycles(self, value): i2c.write(self.buf, end=2) @property - def interrupt_mode(self): + def interrupt_mode(self) -> int: """The interrupt mode selection. ==== ========================= @@ -205,20 +211,20 @@ def interrupt_mode(self): return (self._read_register(_REGISTER_INT_CTRL) >> 4) & 0x03 @interrupt_mode.setter - def interrupt_mode(self, value): + def interrupt_mode(self, value: int) -> None: current = self._read_register(_REGISTER_INT_CTRL) self.buf[0] = _COMMAND_BIT | _REGISTER_INT_CTRL self.buf[1] = (current & 0x0F) | ((value & 0x03) << 4) with self.i2c_device as i2c: i2c.write(self.buf, end=2) - def clear_interrupt(self): + def clear_interrupt(self) -> None: """Clears any pending interrupt.""" self.buf[0] = 0xC0 with self.i2c_device as i2c: i2c.write(self.buf, end=1) - def _compute_lux(self): + def _compute_lux(self) -> Optional[float]: """Based on datasheet for FN package.""" ch0, ch1 = self.luminosity if ch0 == 0: @@ -247,15 +253,15 @@ def _compute_lux(self): lux *= _TIME_SCALE[self.integration_time] return lux - def _enable(self): + def _enable(self) -> None: self._write_control_register(_CONTROL_POWERON) - def _disable(self): + def _disable(self) -> None: self._write_control_register(_CONTROL_POWEROFF) - def _read_register(self, reg, count=1): - # pylint: disable=no-else-return - # Disable should be removed when refactor can be tested + def _read_register(self, reg: int, count: int = 1) -> Union[int, Tuple[int, int]]: + if count not in (1, 2): + raise RuntimeError("Can only read up to 2 consecutive registers") self.buf[0] = _COMMAND_BIT | reg if count == 2: self.buf[0] |= _WORD_BIT @@ -263,20 +269,18 @@ def _read_register(self, reg, count=1): i2c.write_then_readinto(self.buf, self.buf, out_end=1, in_start=1) if count == 1: return self.buf[1] - elif count == 2: - return self.buf[1], self.buf[2] - return None + return self.buf[1], self.buf[2] - def _write_control_register(self, reg): + def _write_control_register(self, reg: int) -> None: self.buf[0] = _COMMAND_BIT | _REGISTER_CONTROL self.buf[1] = reg with self.i2c_device as i2c: i2c.write(self.buf, end=2) - def _read_broadband(self): + def _read_broadband(self) -> int: low, high = self._read_register(_REGISTER_CHAN0_LOW, 2) return high << 8 | low - def _read_infrared(self): + def _read_infrared(self) -> int: low, high = self._read_register(_REGISTER_CHAN1_LOW, 2) return high << 8 | low