Skip to content

Commit

Permalink
Merge pull request #14 from tcfranks/main
Browse files Browse the repository at this point in the history
Add Missing Type Annotations
  • Loading branch information
tekktrik authored Sep 27, 2022
2 parents b6fcd49 + 3792f83 commit 3f2ad26
Showing 1 changed file with 37 additions and 22 deletions.
59 changes: 37 additions & 22 deletions adafruit_ltr390.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@
from adafruit_register.i2c_bits import RWBits
from adafruit_register.i2c_bit import RWBit, ROBit

try:
from typing import Iterable, Optional, Tuple, Type
from busio import I2C
except ImportError:
pass

__version__ = "0.0.0+auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_LTR390.git"

Expand Down Expand Up @@ -65,7 +71,11 @@ def __init__(self, register_address, struct_format, bitwidth, length):
self._width = bitwidth
self._num_bytes = length

def __get__(self, obj, objtype=None):
def __get__(
self,
obj: Optional["LTR390"],
objtype: Optional[Type["LTR390"]] = None,
) -> int:
# read bytes into buffer at correct alignment
raw_value = unpack_from(self.format, self.buffer, offset=1)[0]

Expand All @@ -81,7 +91,7 @@ def __get__(self, obj, objtype=None):
raw_value = unpack_from(self.format, self.buffer, offset=1)[0]
return raw_value >> 8

def __set__(self, obj, value):
def __set__(self, obj: Optional["LTR390"], value: int) -> None:
pack_into(self.format, self.buffer, 1, value)
with obj.i2c_device as i2c:
i2c.write(self.buffer)
Expand All @@ -91,7 +101,12 @@ class CV:
"""struct helper"""

@classmethod
def add_values(cls, value_tuples):
def add_values(
cls,
value_tuples: Iterable[
Tuple[str, int, str, Optional[float], int, Optional[float]]
],
) -> None:
"""Add CV values to the class"""
cls.string = {}
cls.lsb = {}
Expand All @@ -107,7 +122,7 @@ def add_values(cls, value_tuples):
cls.integration[value] = integration

@classmethod
def is_valid(cls, value):
def is_valid(cls, value: int) -> bool:
"""Validate that a given value is a member"""
return value in cls.string

Expand Down Expand Up @@ -276,7 +291,7 @@ class LTR390: # pylint:disable=too-many-instance-attributes
Once read, this property will be False until it is updated in the next measurement cycle"""

def __init__(self, i2c, address=_DEFAULT_I2C_ADDR):
def __init__(self, i2c: I2C, address: int = _DEFAULT_I2C_ADDR) -> None:
self.i2c_device = i2c_device.I2CDevice(i2c, address)
if self._id_reg != 0xB2:

Expand All @@ -285,7 +300,7 @@ def __init__(self, i2c, address=_DEFAULT_I2C_ADDR):
self._mode_cache = None
self.initialize()

def initialize(self):
def initialize(self) -> None:
"""Reset the sensor to it's initial unconfigured state and configure it with sensible
defaults so it can be used"""

Expand All @@ -303,7 +318,7 @@ def initialize(self):
# self.high_threshold = 1000
# ltr.configInterrupt(true, LTR390_MODE_UVS);

def _reset(self):
def _reset(self) -> None:
# The LTR390 software reset is ill behaved and can leave I2C bus in bad state.
# Instead, just manually set register reset values per datasheet.
with self.i2c_device as i2c:
Expand All @@ -316,11 +331,11 @@ def _reset(self):
i2c.write(bytes((_THRESH_LOW, 0x00, 0x00, 0x00)))

@property
def _mode(self):
def _mode(self) -> bool:
return self._mode_bit

@_mode.setter
def _mode(self, value):
def _mode(self, value: bool) -> None:
if not value in [ALS, UV]:
raise AttributeError("Mode must be ALS or UV")
if self._mode_cache != value:
Expand All @@ -330,44 +345,44 @@ def _mode(self, value):

# something is wrong here; I had to add a sleep to the loop to get both to update correctly
@property
def uvs(self):
def uvs(self) -> int:
"""The calculated UV value"""
self._mode = UV
while not self.data_ready:
sleep(0.010)
return self._uvs_data_reg

@property
def light(self):
def light(self) -> int:
"""The currently measured ambient light level"""
self._mode = ALS
while not self.data_ready:
sleep(0.010)
return self._als_data_reg

@property
def gain(self):
def gain(self) -> int:
"""The amount of gain the raw measurements are multiplied by"""
return self._gain_bits

@gain.setter
def gain(self, value):
def gain(self, value: int):
if not Gain.is_valid(value):
raise AttributeError("gain must be a Gain")
self._gain_bits = value

@property
def resolution(self):
def resolution(self) -> int:
"""Set the precision of the internal ADC used to read the light measurements"""
return self._resolution_bits

@resolution.setter
def resolution(self, value):
def resolution(self, value: int):
if not Resolution.is_valid(value):
raise AttributeError("resolution must be a Resolution")
self._resolution_bits = value

def enable_alerts(self, enable, source, persistance):
def enable_alerts(self, enable: bool, source: bool, persistance: int) -> None:
"""The configuration of alerts raised by the sensor
:param enable: Whether the interrupt output is enabled
Expand All @@ -386,19 +401,19 @@ def enable_alerts(self, enable, source, persistance):
self._int_persistance_bits = persistance

@property
def measurement_delay(self):
def measurement_delay(self) -> int:
"""The delay between measurements. This can be used to set the measurement rate which
affects the sensor power usage."""
return self._measurement_delay_bits

@measurement_delay.setter
def measurement_delay(self, value):
def measurement_delay(self, value: int) -> None:
if not MeasurementDelay.is_valid(value):
raise AttributeError("measurement_delay must be a MeasurementDelay")
self._measurement_delay_bits = value

@property
def uvi(self):
def uvi(self) -> float:
"""Read UV count and return calculated UV Index (UVI) value based upon the rated sensitivity
of 1 UVI per 2300 counts at 18X gain factor and 20-bit resolution."""
return (
Expand All @@ -413,22 +428,22 @@ def uvi(self):
)

@property
def lux(self):
def lux(self) -> float:
"""Read light level and return calculated Lux value."""
return (
(self.light * 0.6)
/ (Gain.factor[self.gain] * Resolution.integration[self.resolution])
) * self._window_factor

@property
def window_factor(self):
def window_factor(self) -> float:
"""Window transmission factor (Wfac) for UVI and Lux calculations.
A factor of 1 (default) represents no window or clear glass; > 1 for a tinted window.
Factor of > 1 requires an empirical calibration with a reference light source."""
return self._window_factor

@window_factor.setter
def window_factor(self, factor=1):
def window_factor(self, factor: float = 1) -> None:
if factor < 1:
raise ValueError(
"window transmission factor must be a value of 1.0 or greater"
Expand Down

0 comments on commit 3f2ad26

Please sign in to comment.