diff --git a/docs/config_system.md b/docs/config_system.md index 9f09eca..1c577fa 100644 --- a/docs/config_system.md +++ b/docs/config_system.md @@ -15,22 +15,17 @@ The configuration is stored in a JSON file named `config.json` in the project ro ```json { "sensors": { - "temperature": { - "name": "Living Room Temperature", - "pin": 4, - "interval": 60, - "unit": "C" - }, - "humidity": { - "name": "Living Room Humidity", - "pin": 4, - "interval": 60 - }, "dht22": { "name": "Living Room DHT22", "pin": 4, "interval": 30, - "unit": "C" + "temperature": { + "name": "Living Room Temperature", + "unit": "C" + }, + "humidity": { + "name": "Living Room Humidity" + } } }, "displays": { @@ -99,29 +94,69 @@ oled_config = get_display_config("oled", config) ### Creating Sensors with Configuration -You can create sensors using the configuration system in two ways: +You can create sensors using the configuration system in three ways: -#### Method 1: Using sensor_type parameter +#### Method 1: Using sensor_config directly ```python from src.esp_sensors.temperature import TemperatureSensor -# Create a temperature sensor using configuration -sensor = TemperatureSensor(sensor_type="temperature") +# Get configuration +from src.esp_sensors.config import get_sensor_config +temp_config = get_sensor_config("temperature") + +# Create a temperature sensor with the configuration +sensor = TemperatureSensor(sensor_config=temp_config) ``` -#### Method 2: Overriding some parameters +#### Method 2: Overriding parameters directly ```python from src.esp_sensors.temperature import TemperatureSensor -# Create a temperature sensor with custom name but other parameters from config +# Create a temperature sensor with direct parameters sensor = TemperatureSensor( name="Custom Sensor", - sensor_type="temperature" + pin=5, + interval=30, + unit="F" ) ``` +You can also combine this with a configuration dictionary: + +```python +from src.esp_sensors.temperature import TemperatureSensor +from src.esp_sensors.config import get_sensor_config + +# Get configuration +temp_config = get_sensor_config("temperature") + +# Create a sensor with some parameters from config, others specified directly +sensor = TemperatureSensor( + name="Custom Sensor", # Override the name from config + unit="F", # Override the unit from config + sensor_config=temp_config # Use other parameters from config +) +``` + +#### Method 3: Creating a custom configuration dictionary + +```python +from src.esp_sensors.temperature import TemperatureSensor + +# Create a custom configuration dictionary +custom_config = { + "name": "Custom Temperature", + "pin": 5, + "interval": 30, + "unit": "F" +} + +# Create a temperature sensor with the custom configuration +sensor = TemperatureSensor(sensor_config=custom_config) +``` + ### Creating Displays with Configuration Similarly, you can create displays using the configuration system: @@ -140,6 +175,33 @@ display = OLEDDisplay( ) ``` +You can also use the display_config parameter directly: + +```python +from src.esp_sensors.oled_display import OLEDDisplay +from src.esp_sensors.config import get_display_config + +# Get display configuration +oled_config = get_display_config("oled") + +# Create an OLED display with the configuration +display = OLEDDisplay(display_config=oled_config) + +# Or create a custom configuration dictionary +custom_display_config = { + "name": "Custom OLED", + "scl_pin": 22, + "sda_pin": 21, + "width": 128, + "height": 32, + "address": "0x3C", + "interval": 30 +} + +# Create an OLED display with the custom configuration +display = OLEDDisplay(display_config=custom_display_config) +``` + ## Saving Configuration You can save a configuration to a file using the `save_config` function: @@ -180,15 +242,27 @@ create_default_config("custom_config.json") - `unit`: Temperature unit, either "C" for Celsius or "F" for Fahrenheit +### Humidity Sensor Parameters + +No additional parameters beyond the common ones. + +### DHT22 Sensor Parameters + +- `temperature`: A nested configuration object for temperature-specific settings + - `name`: The name for the temperature component + - `unit`: Temperature unit, either "C" for Celsius or "F" for Fahrenheit +- `humidity`: A nested configuration object for humidity-specific settings + - `name`: The name for the humidity component + ### OLED Display Parameters - `scl_pin`: The GPIO pin number for the SCL (clock) line - `sda_pin`: The GPIO pin number for the SDA (data) line - `width`: Display width in pixels - `height`: Display height in pixels -- `address`: I2C address of the display (in hex format, e.g., "0x3C") +- `address`: I2C address of the display (in hex format, e.g., "0x3C" or as an integer) ### Button Parameters - `pin`: The GPIO pin number the button is connected to -- `pull_up`: Whether to use internal pull-up resistor (true/false) \ No newline at end of file +- `pull_up`: Whether to use internal pull-up resistor (true/false) diff --git a/docs/dht22_sensor.md b/docs/dht22_sensor.md index 15e2aba..64a66cc 100644 --- a/docs/dht22_sensor.md +++ b/docs/dht22_sensor.md @@ -14,6 +14,9 @@ The DHT22 (also known as AM2302) is a digital temperature and humidity sensor th - Error handling for sensor reading failures - Temperature unit conversion methods - Comprehensive metadata including sensor type and last readings +- Configuration-based initialization +- Separate configuration options for temperature and humidity components +- Inherits functionality from both TemperatureSensor and HumiditySensor classes ## Hardware Requirements @@ -54,6 +57,28 @@ fahrenheit = sensor.to_fahrenheit() print(f"Temperature: {fahrenheit}°F") ``` +### Configuration-Based Usage + +```python +from src.esp_sensors.dht22 import DHT22Sensor + +# Initialize using configuration +sensor_config = { + "name": "bedroom", + "pin": 5, + "interval": 30, + "temperature": { + "name": "Bedroom Temperature", + "unit": "F" + }, + "humidity": { + "name": "Bedroom Humidity" + } +} + +sensor = DHT22Sensor(sensor_config=sensor_config) +``` + ### Advanced Usage ```python @@ -90,26 +115,35 @@ except KeyboardInterrupt: ### Class: DHT22Sensor -Extends the base `Sensor` class to provide DHT22-specific functionality. +Extends both the `TemperatureSensor` and `HumiditySensor` classes to provide DHT22-specific functionality for reading both temperature and humidity from a single sensor. #### Constructor ```python -DHT22Sensor(name: str, pin: int, interval: int = 60, unit: str = "C") +DHT22Sensor( + name: str = None, + pin: int = None, + interval: int = None, + temperature_unit: str = None, + sensor_config: Dict[str, Any] = None +) ``` -- **name**: A string identifier for 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") +- **name**: A string identifier for the sensor (if None, loaded from config) +- **pin**: The GPIO pin number the sensor is connected to (if None, loaded from config) +- **interval**: Reading interval in seconds (if None, loaded from config) +- **temperature_unit**: Temperature unit, either "C" for Celsius or "F" for Fahrenheit (if None, loaded from config) +- **sensor_config**: Sensor configuration dictionary (if provided, used instead of loading from file) #### Methods - **read()**: Reads the current temperature and updates humidity +- **read_temperature()**: Reads the current temperature (same as read()) - **read_humidity()**: Returns the current humidity reading - **to_fahrenheit()**: Converts the last reading to Fahrenheit if it was in Celsius - **to_celsius()**: Converts the last reading to Celsius if it was in Fahrenheit - **get_metadata()**: Returns a dictionary with sensor information including temperature unit and humidity +- **apply_parameters()**: Internal method to apply configuration parameters ## Example @@ -124,4 +158,4 @@ See the `examples/dht22_example.py` file for a complete example of how to use th ## License -This implementation is provided under the same license as the main project. \ No newline at end of file +This implementation is provided under the same license as the main project. diff --git a/docs/oled_display.md b/docs/oled_display.md index e1c1259..00065f7 100644 --- a/docs/oled_display.md +++ b/docs/oled_display.md @@ -10,6 +10,9 @@ This module provides a class for interfacing with SSD1306 OLED displays via I2C - Display a list of values (e.g., sensor readings) - Simulation mode for testing without hardware - Integration with the ESP Sensors framework +- Configuration-based initialization +- Inherits from the Sensor class for consistent API +- Support for both integer and hex string I2C addresses ## Hardware Requirements @@ -39,6 +42,25 @@ display = OLEDDisplay( ) ``` +### Configuration-Based Initialization + +```python +from esp_sensors.oled_display import OLEDDisplay + +# Initialize using configuration +display_config = { + "name": "Status Display", + "scl_pin": 22, + "sda_pin": 21, + "width": 128, + "height": 64, + "address": "0x3C", # Can be a hex string + "interval": 30 +} + +display = OLEDDisplay(display_config=display_config) +``` + ### Displaying Text ```python @@ -86,20 +108,32 @@ display.display_values([ ### Class: OLEDDisplay +Extends the base `Sensor` class to provide OLED display functionality. + #### Constructor ```python -OLEDDisplay(name, scl_pin, sda_pin, width=128, height=64, address=0x3C, interval=60) +OLEDDisplay( + name: str = None, + scl_pin: int = None, + sda_pin: int = None, + width: int = None, + height: int = None, + address: int | str = None, + interval: int = None, + display_config: Dict[str, Any] = None +) ``` Parameters: -- `name` (str): The name of the display -- `scl_pin` (int): The GPIO pin number for the SCL (clock) line -- `sda_pin` (int): The GPIO pin number for the SDA (data) line -- `width` (int): Display width in pixels (default: 128) -- `height` (int): Display height in pixels (default: 64) -- `address` (int): I2C address of the display (default: 0x3C) -- `interval` (int): Refresh interval in seconds (default: 60) +- `name` (str): The name of the display (if None, loaded from config) +- `scl_pin` (int): The GPIO pin number for the SCL (clock) line (if None, loaded from config) +- `sda_pin` (int): The GPIO pin number for the SDA (data) line (if None, loaded from config) +- `width` (int): Display width in pixels (if None, loaded from config) +- `height` (int): Display height in pixels (if None, loaded from config) +- `address` (int | str): I2C address of the display, can be an integer or a hex string (if None, loaded from config) +- `interval` (int): Refresh interval in seconds (if None, loaded from config) +- `display_config` (Dict[str, Any]): Configuration dictionary (if provided, used instead of loading from file) #### Methods @@ -136,6 +170,14 @@ Parameters: display.display_values(["Line 1", "Line 2", "Line 3"]) ``` +##### read() + +Updates the display (placeholder to satisfy Sensor interface). + +```python +display.read() # Always returns 1.0 to indicate success +``` + ##### get_metadata() Returns a dictionary containing display metadata. @@ -145,6 +187,18 @@ metadata = display.get_metadata() print(metadata) ``` +The metadata includes: +- `name`: The name of the display +- `pin`: The SDA pin number (inherited from Sensor) +- `interval`: Refresh interval in seconds +- `scl_pin`: The SCL pin number +- `sda_pin`: The SDA pin number +- `width`: Display width in pixels +- `height`: Display height in pixels +- `address`: I2C address of the display +- `type`: Always "SSD1306" +- `values_count`: Number of values currently displayed + ## Troubleshooting ### Display Not Working @@ -162,4 +216,4 @@ print(metadata) ## Example -See the `examples/oled_display_example.py` file for a complete example of using the OLED display with sensors. \ No newline at end of file +See the `examples/oled_display_example.py` file for a complete example of using the OLED display with sensors. diff --git a/examples/dht22_example.py b/examples/dht22_example.py index dbdbf03..f6d6546 100644 --- a/examples/dht22_example.py +++ b/examples/dht22_example.py @@ -32,7 +32,7 @@ if sys.implementation.name == "micropython": print(f"Sensor pin: {dht_config.get('pin')}") # Initialize the sensor using configuration - sensor = DHT22Sensor(sensor_config=config) + sensor = DHT22Sensor(sensor_config=dht_config) print("Starting sensor readings. Press Ctrl+C to stop.") @@ -80,7 +80,7 @@ else: print(f"Sensor pin: {dht_config.get('pin')}") # Initialize the sensor using configuration - sensor = DHT22Sensor(sensor_config=config) + sensor = DHT22Sensor(sensor_config=dht_config) print("Starting simulated sensor readings. Press Ctrl+C to stop.") diff --git a/examples/oled_display_example.py b/examples/oled_display_example.py index f5571c0..bc49743 100644 --- a/examples/oled_display_example.py +++ b/examples/oled_display_example.py @@ -33,7 +33,7 @@ def main(): # Initialize a DHT22 sensor with configuration dht_sensor = DHT22Sensor( # This will load config for this sensor type - sensor_config=config, # Pass the loaded config + sensor_config=dht_config, # Pass the sensor-specific config ) print( f"Created DHT22 sensor: {dht_sensor.name}, pin: {dht_sensor.pin}, interval: {dht_sensor.interval}s" @@ -48,7 +48,7 @@ def main(): name="Custom Display", interval=1, # Update every second # Other parameters will be loaded from config - config=config, + display_config=get_display_config("oled", config), ) print( f"Created OLED display: {display.name}, size: {display.width}x{display.height}, interval: {display.interval}s" diff --git a/src/esp_sensors/humidity.py b/src/esp_sensors/humidity.py index 713ab05..b24ee49 100644 --- a/src/esp_sensors/humidity.py +++ b/src/esp_sensors/humidity.py @@ -31,7 +31,7 @@ class HumiditySensor(Sensor): """ if sensor_config is None: sensor_config = {} - # Initialize base class with sensor_type for configuration loading + # Initialize base class with sensor_config for configuration super().__init__(name, pin, interval, sensor_config=sensor_config) self._last_humidity = None diff --git a/src/esp_sensors/temperature.py b/src/esp_sensors/temperature.py index 8fd7797..09cb60d 100644 --- a/src/esp_sensors/temperature.py +++ b/src/esp_sensors/temperature.py @@ -31,7 +31,7 @@ class TemperatureSensor(Sensor): """ if sensor_config is None: sensor_config = {} - # Initialize base class with sensor_type for configuration loading + # Initialize base class with sensor_config for configuration super().__init__(name, pin, interval, sensor_config=sensor_config) # Load configuration if not provided in parameters