Add rover_startup/src/rover_startup/main.py

This commit is contained in:
Mika 2026-03-08 03:07:03 +00:00
commit 66d582c9ba

View file

@ -0,0 +1,124 @@
import time
import json
import logging
import os
import argparse
from dataclasses import dataclass, asdict
from typing import Any
try:
from gpiozero import LightSensor, MCP3008, CPUTemperature
except ImportError:
# Fallbacks in non-hardware environments
LightSensor = None # type: ignore
MCP3008 = None # type: ignore
CPUTemperature = None # type: ignore
logging.basicConfig(level=logging.INFO, format='[%(asctime)s] %(levelname)s: %(message)s')
logger = logging.getLogger(__name__)
@dataclass
class SensorData:
"""Struct for Rover sensor initialization values."""
light: float
infrared: float
sound: float
core_temp: float
battery_status: float
def to_json(self) -> str:
return json.dumps(asdict(self), indent=2)
def _read_light() -> float:
if LightSensor is None:
return 50.0
try:
sensor = LightSensor(18)
return float(sensor.value * 100.0)
except Exception as e:
logger.warning(f"Light sensor read fallback due to error: {e}")
return 50.0
def _read_infrared() -> float:
if MCP3008 is None:
return 25.0
try:
ir_channel = MCP3008(channel=0)
return float(ir_channel.value * 100.0)
except Exception as e:
logger.warning(f"Infrared sensor read fallback due to error: {e}")
return 25.0
def _read_sound() -> float:
if MCP3008 is None:
return 35.0
try:
sound_channel = MCP3008(channel=1)
return float(sound_channel.value * 120.0)
except Exception as e:
logger.warning(f"Sound sensor read fallback due to error: {e}")
return 35.0
def _read_core_temp() -> float:
if CPUTemperature is None:
return 42.0
try:
cpu_temp = CPUTemperature()
return float(cpu_temp.temperature)
except Exception as e:
logger.warning(f"CPU temperature read fallback due to error: {e}")
return 42.0
def _read_battery_status() -> float:
try:
# Placeholder: could be read via ADC pin on MCP3008 or from system sensors
return 95.0
except Exception as e:
logger.warning(f"Battery status fallback due to error: {e}")
return 95.0
def init_sensors() -> SensorData:
"""Initializes all rover sensors and returns structured initial readings."""
logger.info("Initializing sensors...")
time.sleep(0.5)
light = _read_light()
infrared = _read_infrared()
sound = _read_sound()
core_temp = _read_core_temp()
battery = _read_battery_status()
# Input validation
assert all(isinstance(v, (int, float)) for v in [light, infrared, sound, core_temp, battery]), "All sensor values must be numeric"
data = SensorData(
light=float(light),
infrared=float(infrared),
sound=float(sound),
core_temp=float(core_temp),
battery_status=float(battery)
)
logger.info("Sensor initialization complete.")
return data
def main(argv: Any = None) -> None:
parser = argparse.ArgumentParser(description="Initialize and read rover sensor data.")
args = parser.parse_args(argv)
data = init_sensors()
print("Rover Sensor Status:")
print(data.to_json())
if __name__ == "__main__":
main()