-
Notifications
You must be signed in to change notification settings - Fork 24
Labels
Description
Story
- As a pysquared developer
- I want an interface to all of the sensors on the satellite's solar panel faces
- So that I can quickly and easily pull in data from them for downstream components.
Acceptance Criteria
- Implement Protocol for Collecting Data from a Sensor Group
- Create a Factory for Generating Groups of Sensors
- Create a VEML7700 Ambient Light Sensor Manager Component
- Create a MCP9808 Temperature Sensor Manager Component
- Create a DRV2605L Haptic Motor Controller Manager Component
Technical Details
In v1.0.0 of the PROVES Kit software we had a class called Big_Data.py that, as the name implies, would generate a BIG amount of data by pulling in all of the sensor data from the satellite's exterior faces into a single (kinda gross) tuple that would then be passed along to other parts of the software for whatever it was needed for (beacon data, detumbling, you name it we would call Big_Data for it!).
This class was removed in the recent v2.0.0-alpha-25w17 release of the pysquared library and functionality will need to be reimplemented across multiple sub issues before the v2.0.0-beta release!
Legacy Big_Data Implementation for Reference
import gc
import adafruit_tca9548a as adafruit_tca9548a # I2C Multiplexer
from .logger import Logger
try:
from typing import Union
except Exception:
pass
class Face:
def __init__(
self, add: int, pos: str, tca: adafruit_tca9548a.TCA9548A, logger: Logger
) -> None:
self.tca: adafruit_tca9548a.TCA9548A = tca
self.address: int = add
self.position: str = pos
self.logger: Logger = logger
# Use tuple instead of list for immutable data
self.senlist: tuple = ()
# Define sensors based on position using a dictionary lookup instead of if-elif chain
sensor_map: dict[str, tuple[str, ...]] = {
"x+": ("MCP", "VEML", "DRV"),
"x-": ("MCP", "VEML"),
"y+": ("MCP", "VEML", "DRV"),
"y-": ("MCP", "VEML"),
"z-": ("MCP", "VEML", "DRV"),
}
self.senlist: tuple[str, ...] = sensor_map.get(pos, ())
# Initialize sensor states dict only with needed sensors
self.sensors: dict[str, bool] = {sensor: False for sensor in self.senlist}
# Initialize sensor objects as None
self.mcp = None
self.veml = None
self.drv = None
def sensor_init(self, senlist, address) -> None:
gc.collect() # Force garbage collection before initializing sensors
if "MCP" in senlist:
try:
import adafruit_mcp9808 as adafruit_mcp9808
self.mcp: adafruit_mcp9808.MCP9808 = adafruit_mcp9808.MCP9808(
self.tca[address], address=27
)
self.sensors["MCP"] = True
except Exception as e:
self.logger.error("Error Initializing Temperature Sensor", e)
if "VEML" in senlist:
try:
import adafruit_veml7700 as adafruit_veml7700
self.veml: adafruit_veml7700.VEML7700 = adafruit_veml7700.VEML7700(
self.tca[address]
)
self.sensors["VEML"] = True
except Exception as e:
self.logger.error("Error Initializing Light Sensor", e)
if "DRV" in senlist:
try:
import adafruit_drv2605 as adafruit_drv2605
self.drv: adafruit_drv2605.DRV2605 = adafruit_drv2605.DRV2605(
self.tca[address]
)
self.sensors["DRV"] = True
except Exception as e:
self.logger.error("Error Initializing Motor Driver", e)
gc.collect() # Clean up after initialization
class AllFaces:
def __init__(self, tca: adafruit_tca9548a.TCA9548A, logger: Logger) -> None:
self.tca: adafruit_tca9548a.TCA9548A = tca
self.faces: list[Face] = []
self.logger: Logger = logger
# Create faces using a loop instead of individual variables
positions: list[tuple[str, int]] = [
("y+", 0),
("y-", 1),
("x+", 2),
("x-", 3),
("z-", 4),
]
for pos, addr in positions:
face: Face = Face(addr, pos, tca, self.logger)
face.sensor_init(face.senlist, face.address)
self.faces.append(face)
gc.collect() # Clean up after each face initialization
def face_test_all(self) -> list[list[float]]:
results: list[list[float]] = []
for face in self.faces:
if face:
try:
temp: Union[float, None] = (
face.mcp.temperature if face.sensors.get("MCP") else None
)
light: Union[float, None] = (
face.veml.lux if face.sensors.get("VEML") else None
)
results.append([temp, light])
except Exception:
results.append([None, None])
return results