# Sensor Manager Component Specification

**Component ID:** COMP-SENSOR-MGR  
**Version:** 1.0  
**Date:** 2025-01-19  
**Location:** `application_layer/business_stack/sensor_manager/`

## 1. Purpose

The Sensor Manager component coordinates all sensor-related operations including lifecycle management, data acquisition scheduling, high-frequency sampling, local filtering, and sensor state management. It serves as the central coordinator for the Sensor Data Acquisition feature (F-DAQ).

## 2. Responsibilities

### 2.1 Primary Responsibilities

- **Sensor Lifecycle Management:** Detection, initialization, configuration, and teardown
- **Data Acquisition Coordination:** Scheduling and executing sensor sampling cycles
- **High-Frequency Sampling:** Multiple samples per sensor per cycle with configurable parameters
- **Local Data Filtering:** Apply configurable filters (median, moving average, rate-of-change limiter)
- **Sensor State Management:** Track and manage sensor operational states
- **Data Record Generation:** Create timestamped sensor data records
- **Event Publication:** Publish sensor data updates and state changes via Event System

### 2.2 Non-Responsibilities

- **Hardware Access:** Delegated to sensor drivers (no direct I2C/SPI/UART access)
- **Data Persistence:** Delegated to Data Persistence component
- **Communication:** Delegated to Communication components
- **Fault Detection Logic:** Uses Error Handler for fault reporting
- **Time Management:** Uses Time Utils for timestamp generation

## 3. Public API

### 3.1 Initialization and Configuration

```c
/**
 * @brief Initialize Sensor Manager component
 * @return true if initialization successful, false otherwise
 */
bool sensorMgr_initialize(void);

/**
 * @brief Load sensor configuration from Machine Constants
 * @param mc Machine constants structure
 * @return true if configuration loaded, false on error
 */
bool sensorMgr_loadConfiguration(const machine_constants_t* mc);

/**
 * @brief Detect all connected sensors
 * @return Number of sensors detected
 */
uint8_t sensorMgr_detectSensors(void);

/**
 * @brief Shutdown Sensor Manager (cleanup resources)
 * @return true if shutdown successful, false otherwise
 */
bool sensorMgr_shutdown(void);
```

### 3.2 Acquisition Control

```c
/**
 * @brief Start sensor data acquisition
 * @return true if acquisition started, false on error
 */
bool sensorMgr_startAcquisition(void);

/**
 * @brief Stop sensor data acquisition
 * @return true if acquisition stopped, false on error
 */
bool sensorMgr_stopAcquisition(void);

/**
 * @brief Pause sensor data acquisition
 * @return true if acquisition paused, false on error
 */
bool sensorMgr_pauseAcquisition(void);

/**
 * @brief Resume sensor data acquisition
 * @return true if acquisition resumed, false on error
 */
bool sensorMgr_resumeAcquisition(void);

/**
 * @brief Check if acquisition is active
 * @return true if acquisition is running, false otherwise
 */
bool sensorMgr_isAcquisitionActive(void);
```

### 3.3 Sensor Control

```c
/**
 * @brief Enable a specific sensor
 * @param sensor_id Sensor identifier (0-6)
 * @return true if sensor enabled, false on error
 */
bool sensorMgr_enableSensor(uint8_t sensor_id);

/**
 * @brief Disable a specific sensor
 * @param sensor_id Sensor identifier (0-6)
 * @return true if sensor disabled, false on error
 */
bool sensorMgr_disableSensor(uint8_t sensor_id);

/**
 * @brief Configure sensor parameters
 * @param sensor_id Sensor identifier
 * @param config Sensor configuration structure
 * @return true if configuration applied, false on error
 */
bool sensorMgr_configureSensor(uint8_t sensor_id, const sensor_config_t* config);

/**
 * @brief Recalibrate a sensor
 * @param sensor_id Sensor identifier
 * @param calibration_data Calibration parameters
 * @return true if calibration applied, false on error
 */
bool sensorMgr_calibrateSensor(uint8_t sensor_id, const sensor_calibration_t* calibration_data);
```

### 3.4 Data Access

```c
/**
 * @brief Get latest data from a specific sensor
 * @param sensor_id Sensor identifier
 * @param record Output buffer for sensor data record
 * @return true if data retrieved, false on error
 */
bool sensorMgr_getLatestData(uint8_t sensor_id, sensor_data_record_t* record);

/**
 * @brief Get latest data from all sensors
 * @param records Output buffer for sensor data records
 * @param count Input: buffer size, Output: number of records filled
 * @return true if data retrieved, false on error
 */
bool sensorMgr_getAllSensorData(sensor_data_record_t* records, size_t* count);

/**
 * @brief Get sensor data with history (last N samples)
 * @param sensor_id Sensor identifier
 * @param records Output buffer for historical records
 * @param count Input: requested count, Output: actual count returned
 * @return true if data retrieved, false on error
 */
bool sensorMgr_getSensorHistory(uint8_t sensor_id, sensor_data_record_t* records, size_t* count);
```

### 3.5 State Management

```c
/**
 * @brief Get sensor operational state
 * @param sensor_id Sensor identifier
 * @return Current sensor state
 */
sensor_state_t sensorMgr_getSensorState(uint8_t sensor_id);

/**
 * @brief Check if sensor is present (detected)
 * @param sensor_id Sensor identifier
 * @return true if sensor is present, false otherwise
 */
bool sensorMgr_isSensorPresent(uint8_t sensor_id);

/**
 * @brief Check if sensor is enabled for acquisition
 * @param sensor_id Sensor identifier
 * @return true if sensor is enabled, false otherwise
 */
bool sensorMgr_isSensorEnabled(uint8_t sensor_id);

/**
 * @brief Check if sensor is healthy (no faults)
 * @param sensor_id Sensor identifier
 * @return true if sensor is healthy, false if faulty
 */
bool sensorMgr_isSensorHealthy(uint8_t sensor_id);

/**
 * @brief Get sensor information
 * @param sensor_id Sensor identifier
 * @param info Output buffer for sensor information
 * @return true if information retrieved, false on error
 */
bool sensorMgr_getSensorInfo(uint8_t sensor_id, sensor_info_t* info);
```

### 3.6 Statistics and Diagnostics

```c
/**
 * @brief Get sensor acquisition statistics
 * @param sensor_id Sensor identifier
 * @param stats Output buffer for statistics
 * @return true if statistics retrieved, false on error
 */
bool sensorMgr_getSensorStatistics(uint8_t sensor_id, sensor_stats_t* stats);

/**
 * @brief Reset sensor statistics
 * @param sensor_id Sensor identifier (SENSOR_ID_ALL for all sensors)
 * @return true if statistics reset, false on error
 */
bool sensorMgr_resetSensorStatistics(uint8_t sensor_id);

/**
 * @brief Get overall acquisition performance metrics
 * @param metrics Output buffer for performance metrics
 * @return true if metrics retrieved, false on error
 */
bool sensorMgr_getPerformanceMetrics(acquisition_metrics_t* metrics);
```

## 4. Data Types

### 4.1 Sensor States

```c
typedef enum {
    SENSOR_STATE_UNKNOWN = 0,      // Initial state, not yet detected
    SENSOR_STATE_DETECTED,         // Sensor presence confirmed
    SENSOR_STATE_INITIALIZED,      // Driver loaded and configured
    SENSOR_STATE_ENABLED,          // Active data acquisition
    SENSOR_STATE_DISABLED,         // Present but not acquiring data
    SENSOR_STATE_FAULTY,           // Detected failure condition
    SENSOR_STATE_REMOVED,          // Previously present, now absent
    SENSOR_STATE_CALIBRATING,      // Calibration in progress
    SENSOR_STATE_COUNT
} sensor_state_t;
```

### 4.2 Sensor Types

```c
typedef enum {
    SENSOR_TYPE_TEMPERATURE = 0,
    SENSOR_TYPE_HUMIDITY,
    SENSOR_TYPE_CO2,
    SENSOR_TYPE_NH3,
    SENSOR_TYPE_VOC,
    SENSOR_TYPE_PM,
    SENSOR_TYPE_LIGHT,
    SENSOR_TYPE_COUNT
} sensor_type_t;
```

### 4.3 Sensor Data Record

```c
typedef struct {
    uint8_t sensor_id;              // Sensor identifier (0-6)
    sensor_type_t sensor_type;      // Type of sensor
    float filtered_value;           // Processed sensor value
    char unit[8];                   // Unit of measurement (e.g., "°C", "%RH")
    uint64_t timestamp_ms;          // Timestamp in milliseconds
    data_validity_t validity;       // Data validity status
    uint16_t sample_count;          // Number of samples used for filtering
    float raw_min, raw_max;         // Min/max of raw samples
    float raw_stddev;               // Standard deviation of raw samples
    uint32_t acquisition_time_us;   // Time taken for acquisition (microseconds)
} sensor_data_record_t;
```

### 4.4 Sensor Configuration

```c
typedef struct {
    uint16_t sampling_count;        // Number of samples per cycle (5-20)
    uint32_t sampling_interval_ms;  // Interval between samples
    filter_type_t filter_type;      // Filter algorithm to use
    filter_params_t filter_params;  // Filter-specific parameters
    float min_valid_value;          // Minimum valid sensor value
    float max_valid_value;          // Maximum valid sensor value
    float rate_limit_per_sec;       // Maximum rate of change per second
    bool enable_outlier_rejection;  // Enable outlier detection
    float outlier_threshold;        // Outlier detection threshold (std devs)
} sensor_config_t;
```

### 4.5 Filter Types

```c
typedef enum {
    FILTER_TYPE_NONE = 0,           // No filtering (use raw average)
    FILTER_TYPE_MEDIAN,             // Median filter
    FILTER_TYPE_MOVING_AVERAGE,     // Moving average filter
    FILTER_TYPE_RATE_LIMITED,       // Rate-of-change limiter
    FILTER_TYPE_COMBINED,           // Combination of filters
    FILTER_TYPE_COUNT
} filter_type_t;

typedef struct {
    union {
        struct {
            uint8_t window_size;    // Window size for median filter
        } median;
        struct {
            uint8_t window_size;    // Window size for moving average
            float alpha;            // Exponential smoothing factor
        } moving_avg;
        struct {
            float max_rate;         // Maximum rate of change per second
            float recovery_time;    // Time to recover from rate limiting
        } rate_limit;
    };
} filter_params_t;
```

### 4.6 Sensor Statistics

```c
typedef struct {
    uint32_t total_acquisitions;    // Total number of acquisition cycles
    uint32_t successful_acquisitions; // Successful acquisitions
    uint32_t failed_acquisitions;   // Failed acquisitions
    uint32_t timeout_count;         // Number of timeouts
    uint32_t outlier_count;         // Number of outliers detected
    float avg_acquisition_time_ms;  // Average acquisition time
    float max_acquisition_time_ms;  // Maximum acquisition time
    float min_value, max_value;     // Min/max values recorded
    float avg_value;                // Average value
    uint64_t last_acquisition_time; // Timestamp of last acquisition
    uint32_t consecutive_failures;  // Current consecutive failure count
} sensor_stats_t;
```

## 5. Internal State Machine

### 5.1 Sensor State Transitions

```mermaid
stateDiagram-v2
    [*] --> UNKNOWN
    UNKNOWN --> DETECTED : Presence detected
    DETECTED --> INITIALIZED : Driver loaded successfully
    DETECTED --> UNKNOWN : Detection lost
    
    INITIALIZED --> ENABLED : Enable command
    INITIALIZED --> DETECTED : Initialization failed
    
    ENABLED --> DISABLED : Disable command
    ENABLED --> FAULTY : Failure detected
    ENABLED --> CALIBRATING : Calibration requested
    ENABLED --> REMOVED : Sensor removed
    
    DISABLED --> ENABLED : Enable command
    DISABLED --> REMOVED : Sensor removed
    
    FAULTY --> ENABLED : Recovery successful
    FAULTY --> REMOVED : Sensor removed
    
    CALIBRATING --> ENABLED : Calibration complete
    CALIBRATING --> FAULTY : Calibration failed
    
    REMOVED --> DETECTED : Sensor reconnected
```

### 5.2 Acquisition Cycle State Machine

```mermaid
stateDiagram-v2
    [*] --> IDLE
    IDLE --> SAMPLING : Acquisition cycle start
    SAMPLING --> FILTERING : All samples collected
    SAMPLING --> ERROR : Sampling timeout/failure
    FILTERING --> TIMESTAMPING : Filtering complete
    FILTERING --> ERROR : Filter failure
    TIMESTAMPING --> PUBLISHING : Timestamp generated
    PUBLISHING --> IDLE : Event published
    ERROR --> IDLE : Error handled
```

## 6. Component Interactions

### 6.1 Sensor Acquisition Flow

```mermaid
sequenceDiagram
    participant Timer as Acquisition Timer
    participant SM as Sensor Manager
    participant Driver as Sensor Driver
    participant Filter as Filter Engine
    participant TimeUtil as Time Utils
    participant EventSys as Event System
    participant DataPool as Data Pool
    
    Note over Timer,DataPool: 1-Second Acquisition Cycle
    
    Timer->>SM: acquisitionCycleStart()
    
    loop For each enabled sensor
        SM->>SM: checkSensorState(sensor_id)
        
        alt Sensor is healthy
            loop 10 samples
                SM->>Driver: readSensor(sensor_id)
                Driver-->>SM: raw_sample
            end
            
            SM->>Filter: applyFilter(raw_samples, filter_config)
            Filter-->>SM: filtered_value
            
            SM->>TimeUtil: getCurrentTimestamp()
            TimeUtil-->>SM: timestamp
            
            SM->>SM: createDataRecord(sensor_id, filtered_value, timestamp)
            SM->>EventSys: publish(SENSOR_DATA_UPDATE, record)
            EventSys->>DataPool: updateSensorData(record)
            
        else Sensor is faulty
            SM->>SM: handleSensorFault(sensor_id)
            SM->>EventSys: publish(SENSOR_FAULT_DETECTED, fault_info)
        end
    end
    
    SM->>SM: updateAcquisitionStatistics()
    
    Note over Timer,DataPool: Cycle complete, next cycle in 1 second
```

### 6.2 Sensor State Management Flow

```mermaid
sequenceDiagram
    participant SM as Sensor Manager
    participant Driver as Sensor Driver
    participant EventSys as Event System
    participant ErrorHandler as Error Handler
    participant MCMgr as MC Manager
    
    Note over SM,MCMgr: Sensor State Change Scenario
    
    SM->>Driver: checkSensorPresence(sensor_id)
    Driver-->>SM: presence_status
    
    alt Sensor newly detected
        SM->>SM: transitionState(UNKNOWN -> DETECTED)
        SM->>Driver: initializeSensor(sensor_id)
        Driver-->>SM: init_result
        
        alt Initialization successful
            SM->>SM: transitionState(DETECTED -> INITIALIZED)
            SM->>MCMgr: getSensorConfig(sensor_id)
            MCMgr-->>SM: sensor_config
            SM->>SM: applySensorConfig(sensor_config)
            SM->>SM: transitionState(INITIALIZED -> ENABLED)
            SM->>EventSys: publish(SENSOR_STATE_CHANGED, state_info)
        else Initialization failed
            SM->>SM: transitionState(DETECTED -> UNKNOWN)
            SM->>ErrorHandler: reportFault(SENSOR_INIT_FAILED)
        end
        
    else Sensor fault detected
        SM->>SM: transitionState(ENABLED -> FAULTY)
        SM->>ErrorHandler: reportFault(SENSOR_COMMUNICATION_FAILED)
        SM->>EventSys: publish(SENSOR_FAULT_DETECTED, fault_info)
        
        Note over SM,MCMgr: Attempt recovery after delay
        SM->>SM: scheduleRecoveryAttempt(sensor_id)
        
    else Sensor removed
        SM->>SM: transitionState(current -> REMOVED)
        SM->>EventSys: publish(SENSOR_REMOVED, sensor_info)
    end
```

## 7. Threading Model

- **Owner Task:** Sensor Acquisition Task (HIGH priority, 8KB stack)
- **Execution Model:** Periodic execution (1-second cycles) with event-driven state management
- **Thread Safety:** Thread-safe (mutex protection for configuration changes)
- **Blocking Operations:** Bounded sensor I/O operations (max 800ms per cycle)
- **ISR Access:** Not allowed (all operations require task context)

## 8. Resource Ownership

- **Sensor Drivers:** Exclusive access during acquisition cycles
- **Sensor Configuration:** Protected by mutex (shared with MC Manager)
- **Sensor Data Buffers:** Owned exclusively by Sensor Manager
- **Filter State:** Per-sensor filter state maintained internally

## 9. Error Model

### 9.1 Error Conditions

| Error | Condition | Response |
|-------|-----------|----------|
| `SENSOR_ERR_INVALID_ID` | Invalid sensor ID parameter | Return false, log warning |
| `SENSOR_ERR_NOT_PRESENT` | Sensor not detected/present | Return false, update state |
| `SENSOR_ERR_COMMUNICATION` | I2C/SPI/UART communication failure | Mark faulty, schedule recovery |
| `SENSOR_ERR_TIMEOUT` | Sensor read timeout | Mark faulty, continue with other sensors |
| `SENSOR_ERR_OUT_OF_RANGE` | Sensor value out of valid range | Mark data invalid, log diagnostic |
| `SENSOR_ERR_FILTER_FAILURE` | Filter algorithm failure | Use raw average, log error |
| `SENSOR_ERR_CONFIG_INVALID` | Invalid configuration parameters | Use default config, log error |

### 9.2 Diagnostics Emitted

- `DIAG-DAQ-SENSOR-0001`: Sensor communication failure (WARNING)
- `DIAG-DAQ-SENSOR-0002`: Sensor value out of range (WARNING)
- `DIAG-DAQ-SENSOR-0003`: Acquisition cycle timeout (ERROR)
- `DIAG-DAQ-SENSOR-0004`: Filter algorithm failure (ERROR)
- `DIAG-DAQ-SENSOR-0005`: Sensor configuration error (ERROR)
- `DIAG-DAQ-SENSOR-0006`: Consecutive sensor failures (FATAL)

## 10. State-Dependent Behavior

| System State | Sensor Manager Behavior |
|-------------|------------------------|
| **INIT** | Initialize sensors, load configuration, detect presence |
| **RUNNING** | Normal acquisition cycles, full functionality |
| **WARNING** | Continue acquisition, enhanced diagnostic reporting |
| **FAULT** | Stop acquisition, preserve sensor states |
| **OTA_UPDATE** | Stop acquisition, save sensor states for restoration |
| **MC_UPDATE** | Stop acquisition, reload configuration after update |
| **TEARDOWN** | Stop acquisition, flush pending data |
| **SERVICE** | Limited acquisition for diagnostics, enhanced access |
| **SD_DEGRADED** | Continue acquisition, no persistence (memory only) |

## 11. Dependencies

### 11.1 Required Components

- **Sensor Drivers:** Hardware interface for all sensor types
- **Event System:** Cross-component communication
- **Time Utils:** Timestamp generation
- **Machine Constant Manager:** Sensor configuration and calibration data
- **Logger:** Debug and diagnostic logging
- **Error Handler:** Fault reporting and escalation

### 11.2 Required Interfaces

- Sensor driver interfaces (I2C, SPI, UART, ADC wrappers)
- Event System publish/subscribe interface
- Time Utils timestamp interface
- MC Manager configuration interface
- Logger interface
- Error Handler fault reporting interface

## 12. Performance Requirements

### 12.1 Timing Constraints

- **Acquisition Cycle:** Complete within 1 second for all enabled sensors
- **Sampling Window:** Maximum 800ms per sensor (10 samples)
- **Filter Processing:** Maximum 50ms per sensor
- **State Transition:** Maximum 100ms for state changes
- **Event Publication:** Maximum 10ms delay

### 12.2 Resource Constraints

- **Memory Usage:** Maximum 32KB for sensor data buffers and state
- **CPU Usage:** Maximum 20% of available CPU time
- **Stack Usage:** Maximum 8KB stack for acquisition task

## 13. Acceptance Tests

### 13.1 Functional Tests

- **T-SENSOR-001:** All sensor types detected and initialized correctly
- **T-SENSOR-002:** Acquisition cycles complete within 1-second constraint
- **T-SENSOR-003:** High-frequency sampling (10 samples) works for all sensors
- **T-SENSOR-004:** Filter algorithms reduce noise by >90%
- **T-SENSOR-005:** Sensor state transitions occur correctly
- **T-SENSOR-006:** Fault detection and recovery mechanisms work

### 13.2 Performance Tests

- **T-SENSOR-007:** Acquisition timing meets requirements under full load
- **T-SENSOR-008:** Memory usage stays within 32KB limit
- **T-SENSOR-009:** CPU usage stays within 20% limit
- **T-SENSOR-010:** No memory leaks during continuous operation

### 13.3 Integration Tests

- **T-SENSOR-011:** Event System integration works correctly
- **T-SENSOR-012:** Data Pool integration maintains latest sensor data
- **T-SENSOR-013:** MC Manager integration loads configuration correctly
- **T-SENSOR-014:** Error Handler integration reports faults correctly

### 13.4 Stress Tests

- **T-SENSOR-015:** 24-hour continuous operation without failures
- **T-SENSOR-016:** Sensor fault injection and recovery scenarios
- **T-SENSOR-017:** Configuration changes during operation
- **T-SENSOR-018:** System state transitions during acquisition

## 14. Traceability

### 14.1 System Requirements

- **SR-DAQ-001:** Multi-sensor support for 7 sensor types
- **SR-DAQ-002:** High-frequency sampling (minimum 10 samples/cycle)
- **SR-DAQ-003:** Local data filtering with configurable algorithms
- **SR-DAQ-004:** Timestamped data generation (±1 second accuracy)
- **SR-DAQ-005:** Sensor state management and lifecycle control

### 14.2 Software Requirements

- **SWR-DAQ-001 to SWR-DAQ-015:** Complete sensor data acquisition implementation
- **SWR-PERF-001:** Acquisition cycle timing constraints
- **SWR-REL-001:** System availability requirements

### 14.3 Features

- **F-DAQ-001:** Multi-Sensor Data Acquisition
- **F-DAQ-002:** High-Frequency Sampling
- **F-DAQ-003:** Local Data Filtering
- **F-DAQ-004:** Timestamped Data Generation
- **F-DAQ-005:** Sensor State Management

## 15. Implementation Notes

### 15.1 Design Patterns

- **State Machine Pattern:** For sensor state management
- **Strategy Pattern:** For filter algorithm selection
- **Observer Pattern:** For sensor state change notifications
- **Template Method Pattern:** For acquisition cycle execution

### 15.2 Key Implementation Details

- Sensor drivers SHALL be accessed through uniform interface (SAL)
- Filter algorithms SHALL be pluggable and configurable
- Sensor states SHALL be persisted across system restarts
- Acquisition timing SHALL be deterministic and bounded
- Error handling SHALL be comprehensive and non-blocking

### 15.3 Future Extensibility

- Support for additional sensor types through driver registration
- Advanced filter algorithms (Kalman, adaptive filters)
- Sensor fusion capabilities for redundant sensors
- Machine learning-based sensor validation and prediction

---

**Document Status:** Final for Implementation Phase  
**Component Dependencies:** Verified against architecture  
**Requirements Traceability:** Complete (SR-DAQ, SWR-DAQ)  
**Next Review:** After implementation and testing