let junie create initial structure

This commit is contained in:
OMGeeky
2025-05-07 19:17:19 +02:00
parent c4c15db82e
commit 5d15df6bde
7 changed files with 373 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
"""
ESP Sensors package for home control and automation.
"""

48
src/esp_sensors/sensor.py Normal file
View File

@@ -0,0 +1,48 @@
"""
Base sensor module for ESP-based sensors.
"""
from typing import Dict, Any, Optional
class Sensor:
"""Base class for all sensors."""
def __init__(self, name: str, pin: int, interval: int = 60):
"""
Initialize a new sensor.
Args:
name: The name of the sensor
pin: The GPIO pin number the sensor is connected to
interval: Reading interval in seconds (default: 60)
"""
self.name = name
self.pin = pin
self.interval = interval
self._last_reading: Optional[float] = None
def read(self) -> float:
"""
Read the current sensor value.
Returns:
The sensor reading as a float
"""
# This is a placeholder that would be overridden by subclasses
# In a real implementation, this would interact with the hardware
self._last_reading = 0.0
return self._last_reading
def get_metadata(self) -> Dict[str, Any]:
"""
Get sensor metadata.
Returns:
A dictionary containing sensor metadata
"""
return {
"name": self.name,
"pin": self.pin,
"interval": self.interval,
"last_reading": self._last_reading,
}

View File

@@ -0,0 +1,72 @@
"""
Temperature sensor module for ESP-based sensors.
"""
import random
from .sensor import Sensor
class TemperatureSensor(Sensor):
"""Temperature sensor implementation."""
def __init__(self, name: str, pin: int, interval: int = 60, unit: str = "C"):
"""
Initialize a new temperature sensor.
Args:
name: The name of the sensor
pin: The GPIO pin number the sensor is connected to
interval: Reading interval in seconds (default: 60)
unit: Temperature unit, either "C" for Celsius or "F" for Fahrenheit (default: "C")
"""
super().__init__(name, pin, interval)
if unit not in ["C", "F"]:
raise ValueError("Unit must be either 'C' or 'F'")
self.unit = unit
def read(self) -> float:
"""
Read the current temperature.
Returns:
The temperature reading as a float
"""
# This is a simulation for testing purposes
# In a real implementation, this would read from the actual sensor
if self.unit == "C":
self._last_reading = round(random.uniform(15.0, 30.0), 1)
else:
self._last_reading = round(random.uniform(59.0, 86.0), 1)
return self._last_reading
def get_metadata(self):
"""
Get sensor metadata including temperature unit.
Returns:
A dictionary containing sensor metadata
"""
metadata = super().get_metadata()
metadata["unit"] = self.unit
return metadata
def to_fahrenheit(self) -> float | None:
"""
Convert the last reading to Fahrenheit if it was in Celsius.
Returns:
The temperature in Fahrenheit
"""
if self.unit == "F" or self._last_reading is None:
return self._last_reading
return (self._last_reading * 9 / 5) + 32
def to_celsius(self) -> float | None:
"""
Convert the last reading to Celsius if it was in Fahrenheit.
Returns:
The temperature in Celsius
"""
if self.unit == "C" or self._last_reading is None:
return self._last_reading
return (self._last_reading - 32) * 5 / 9