# Sensor Hub Static Architecture

**Document Type:** Architecture Specification  
**Version:** 1.0  
**Date:** 2025-01-19  
**Traceability:** SRS Section 3.2, Annex B

## 1. Purpose and Scope

This document defines the static architecture of the Sensor Hub firmware, including component structure, interfaces, data flows, and concurrency model. This architecture enforces separation of concerns, hardware abstraction, and state-aware operation as defined in the SRS and cross-feature constraints.

**Audience:** Software architects, developers, reviewers, and test engineers.

## 2. Architectural Principles

### 2.1 Layered Architecture

The Sensor Hub follows a **strict layered architecture** with the following principles:

1. **Dependency Direction:** Dependencies flow downward only (Application → Drivers → OSAL → HAL)
2. **Hardware Abstraction:** Application layer SHALL NOT access hardware directly (CFC-ARCH-01)
3. **Persistence Abstraction:** All persistence access SHALL go through DP component (CFC-ARCH-01, CFC-DATA-01)
4. **State Awareness:** All features SHALL respect system state restrictions (CFC-ARCH-02)

### 2.2 Component Responsibilities

- **Single Responsibility:** Each component has one well-defined purpose
- **Clear Interfaces:** Public APIs are minimal and well-documented
- **Event-Driven Communication:** Cross-component communication via Event System
- **State-Dependent Behavior:** Components adapt behavior based on system state

## 3. Architecture Views

### 3.1 Context View

The Context View shows the Sensor Hub and its external actors.

```mermaid
graph TB
    subgraph External["External Actors"]
        MainHub[Main Hub]
        PeerHub[Peer Sensor Hub]
        Sensors[Environmental Sensors]
        SDCard[SD Card]
        OLED[OLED Display]
        Buttons[Buttons]
    end
    
    subgraph SensorHub["Sensor Hub System"]
        AppLayer[Application Layer]
        Drivers[Drivers Layer]
        OSAL[OSAL Layer]
        HAL[HAL/ESP-IDF]
    end
    
    MainHub <-->|"Encrypted Communication"| AppLayer
    PeerHub <-->|"Peer Communication"| AppLayer
    Sensors -->|"I2C/SPI/UART/Analog"| Drivers
    SDCard <-->|"SPI/SD Protocol"| Drivers
    OLED <-->|"I2C"| Drivers
    Buttons -->|"GPIO"| Drivers
    
    AppLayer --> Drivers
    Drivers --> OSAL
    OSAL --> HAL
```

**External Interfaces:**
- **Main Hub:** Bidirectional encrypted communication (Wi-Fi/Zigbee/LoRa)
- **Peer Sensor Hub:** Limited peer-to-peer communication
- **Sensors:** I2C, SPI, UART, Analog interfaces
- **SD Card:** SPI/SD protocol for persistent storage
- **OLED Display:** I2C for local HMI
- **Buttons:** GPIO inputs for user interaction

### 3.2 Component View

The Component View shows the major software components and their relationships.

```mermaid
graph TB
    subgraph AppLayer["Application Layer"]
        subgraph BusinessStack["Business Stack"]
            STM[State Manager<br/>STM]
            EventSys[Event System]
            SensorMgr[Sensor Manager]
            MCMgr[Machine Constant<br/>Manager]
            OTAMgr[OTA Manager]
            MainHubAPI[Main Hub APIs]
        end
        
        subgraph DPStack["DP Stack"]
            DataPool[Data Pool]
            Persistence[Persistence]
        end
        
        DiagTask[Diagnostics Task]
        ErrorHandler[Error Handler]
    end
    
    subgraph Drivers["Drivers Layer"]
        SensorDrivers[Sensor Drivers<br/>I2C/SPI/UART/ADC]
        NetworkStack[Network Stack<br/>Wi-Fi/Zigbee/LoRa]
        DiagProtocol[Diagnostic Protocol<br/>Stack]
        SDDriver[SD Card Driver]
        NVMDriver[NVM Driver]
        OLEDDriver[OLED Driver]
        ButtonDriver[Button Driver]
    end
    
    subgraph OSAL["OSAL Layer"]
        TaskOS[Task Abstraction]
        TimerOS[Software Timer]
        SocketOS[Socket Abstraction]
    end
    
    subgraph Utils["Utilities"]
        Logger[Logger]
        TimeUtils[Time Utils]
    end
    
    STM --> EventSys
    SensorMgr --> EventSys
    SensorMgr --> SensorDrivers
    MCMgr --> Persistence
    OTAMgr --> NetworkStack
    OTAMgr --> Persistence
    MainHubAPI --> NetworkStack
    MainHubAPI --> DataPool
    EventSys --> DataPool
    DataPool --> Persistence
    Persistence --> SDDriver
    Persistence --> NVMDriver
    DiagTask --> Persistence
    DiagTask --> EventSys
    ErrorHandler --> STM
    ErrorHandler --> DiagTask
    
    SensorMgr --> Logger
    OTAMgr --> Logger
    MainHubAPI --> Logger
    DiagTask --> Logger
    
    SensorMgr --> TimeUtils
    
    SensorDrivers --> TaskOS
    NetworkStack --> SocketOS
    NetworkStack --> TaskOS
    Persistence --> TaskOS
    
    SensorDrivers --> OSAL
    NetworkStack --> OSAL
    SDDriver --> OSAL
    OLEDDriver --> OSAL
    ButtonDriver --> OSAL
```

**Component Responsibilities:**

| Component | Responsibility | Non-Responsibility |
|-----------|----------------|-------------------|
| **State Manager (STM)** | System state machine, state transitions, teardown coordination | Feature logic, hardware access |
| **Event System** | Publish/subscribe event bus, cross-component communication | Business logic, state management |
| **Sensor Manager** | Sensor lifecycle, acquisition scheduling, data filtering | Hardware access, persistence, communication |
| **Machine Constant Manager** | MC loading, validation, update coordination | Sensor initialization, hardware access |
| **OTA Manager** | OTA negotiation, firmware reception, validation, activation | Network stack implementation, secure boot |
| **Main Hub APIs** | Main Hub communication protocol, message handling | Network stack implementation, sensor data generation |
| **Data Pool** | Runtime data storage, latest sensor values, system state | Persistence, communication |
| **Persistence** | Persistent storage abstraction, serialization, wear management | Business logic, hardware access |
| **Diagnostics Task** | Diagnostic event collection, storage, query interface | Fault detection, state management |
| **Error Handler** | Fault classification, escalation, state transition triggers | Diagnostic storage, feature logic |

### 3.3 Data Flow View

The Data Flow View shows how data flows through the system.

#### 3.3.1 Sensor Data Acquisition Flow

```mermaid
sequenceDiagram
    participant Sensor as Sensor Hardware
    participant Driver as Sensor Driver
    participant SMgr as Sensor Manager
    participant EventSys as Event System
    participant DP as Data Pool
    participant Persist as Persistence
    participant MainHub as Main Hub APIs
    
    Note over Sensor,MainHub: Normal Acquisition Cycle
    
    SMgr->>Driver: readSensor(sensor_id)
    Driver->>Sensor: I2C/SPI/UART read
    Sensor-->>Driver: raw_sample
    Driver-->>SMgr: raw_sample
    
    loop 10 samples
        SMgr->>Driver: readSensor(sensor_id)
        Driver-->>SMgr: raw_sample
    end
    
    SMgr->>SMgr: filter(raw_samples)
    SMgr->>SMgr: generateTimestamp()
    SMgr->>EventSys: publish(SENSOR_DATA_UPDATE, record)
    EventSys->>DP: update(sensor_id, record)
    EventSys->>Persist: async_persist(record)
    EventSys->>MainHub: notify(SENSOR_DATA_UPDATE)
    
    MainHub->>MainHub: queueForTransmission(record)
```

#### 3.3.2 Diagnostic Event Flow

```mermaid
sequenceDiagram
    participant Component as Any Component
    participant ErrorHandler as Error Handler
    participant DiagTask as Diagnostics Task
    participant EventSys as Event System
    participant STM as State Manager
    participant Persist as Persistence
    
    Component->>ErrorHandler: reportFault(diagnostic_code, severity)
    ErrorHandler->>ErrorHandler: classifyFault()
    ErrorHandler->>ErrorHandler: checkEscalation()
    
    alt Severity == FATAL
        ErrorHandler->>STM: triggerStateTransition(FAULT)
        STM->>EventSys: publish(STATE_CHANGED, FAULT)
    else Severity == WARNING
        ErrorHandler->>STM: triggerStateTransition(WARNING)
    end
    
    ErrorHandler->>DiagTask: logDiagnostic(event)
    DiagTask->>Persist: persistDiagnostic(event)
    DiagTask->>EventSys: publish(DIAGNOSTIC_EVENT, event)
```

#### 3.3.3 OTA Update Flow

```mermaid
sequenceDiagram
    participant MainHub as Main Hub
    participant MainHubAPI as Main Hub APIs
    participant OTAMgr as OTA Manager
    participant STM as State Manager
    participant Persist as Persistence
    participant NetworkStack as Network Stack
    participant Security as Security
    
    MainHub->>MainHubAPI: OTA_REQUEST(message)
    MainHubAPI->>OTAMgr: otaRequestReceived()
    OTAMgr->>OTAMgr: validateReadiness()
    OTAMgr->>STM: requestStateTransition(OTA_PREP)
    STM->>STM: validateTransition()
    STM->>EventSys: publish(STATE_CHANGED, OTA_PREP)
    
    OTAMgr->>MainHubAPI: otaAcknowledge(ACCEPT)
    MainHubAPI->>MainHub: OTA_ACK(ACCEPT)
    
    OTAMgr->>STM: requestStateTransition(TEARDOWN)
    STM->>Persist: flushCriticalData()
    Persist-->>STM: flushComplete()
    STM->>EventSys: publish(STATE_CHANGED, TEARDOWN)
    STM->>STM: transitionTo(OTA_UPDATE)
    
    loop Firmware Chunks
        MainHub->>NetworkStack: firmwareChunk(data)
        NetworkStack->>OTAMgr: firmwareChunkReceived(data)
        OTAMgr->>Persist: storeFirmwareChunk(data)
    end
    
    OTAMgr->>Security: validateFirmwareIntegrity()
    Security-->>OTAMgr: validationResult
    
    alt Validation Success
        OTAMgr->>OTAMgr: flashFirmware()
        OTAMgr->>STM: reboot()
    else Validation Failure
        OTAMgr->>STM: requestStateTransition(FAULT)
        OTAMgr->>MainHubAPI: otaStatus(FAILED)
    end
```

### 3.4 Concurrency View

The Concurrency View shows the task model, priorities, and resource ownership.

```mermaid
graph TB
    subgraph Tasks["RTOS Tasks"]
        SensorTask["Sensor Acquisition Task<br/>Priority: HIGH<br/>Stack: 8KB<br/>Period: 1s"]
        CommTask["Communication Task<br/>Priority: MEDIUM<br/>Stack: 12KB<br/>Event-driven"]
        PersistTask["Persistence Task<br/>Priority: MEDIUM<br/>Stack: 6KB<br/>Event-driven"]
        DiagTask["Diagnostics Task<br/>Priority: LOW<br/>Stack: 4KB<br/>Period: 10s"]
        HMITask["HMI Task<br/>Priority: LOW<br/>Stack: 4KB<br/>Event-driven"]
        OTATask["OTA Task<br/>Priority: HIGH<br/>Stack: 16KB<br/>Event-driven"]
        SystemTask["System Management Task<br/>Priority: HIGH<br/>Stack: 6KB<br/>Event-driven"]
    end
    
    subgraph Components["Components"]
        SensorMgr[Sensor Manager]
        MainHubAPI[Main Hub APIs]
        Persistence[Persistence]
        DiagTaskComp[Diagnostics Task]
        HMI[HMI]
        OTAMgr[OTA Manager]
        STM[State Manager]
    end
    
    SensorTask --> SensorMgr
    CommTask --> MainHubAPI
    PersistTask --> Persistence
    DiagTask --> DiagTaskComp
    HMITask --> HMI
    OTATask --> OTAMgr
    SystemTask --> STM
```

**Task Priorities and Responsibilities:**

| Task | Priority | Stack Size | Responsibility | Blocking Operations |
|------|----------|------------|---------------|---------------------|
| **Sensor Acquisition** | HIGH | 8KB | Sensor sampling, filtering | Sensor I/O (bounded) |
| **Communication** | MEDIUM | 12KB | Main Hub communication | Network I/O (bounded) |
| **Persistence** | MEDIUM | 6KB | Data persistence | Storage I/O (bounded) |
| **Diagnostics** | LOW | 4KB | Diagnostic collection | None (non-blocking) |
| **HMI** | LOW | 4KB | Display updates, button handling | Display I/O (bounded) |
| **OTA** | HIGH | 16KB | Firmware update operations | Network I/O, flash I/O |
| **System Management** | HIGH | 6KB | State machine, teardown | None (coordination only) |

**Resource Ownership:**

| Resource | Owner | Access Method | Concurrency Control |
|----------|-------|--------------|---------------------|
| **Sensor Drivers** | Sensor Acquisition Task | Direct (exclusive) | Task-level ownership |
| **Network Stack** | Communication Task | Direct (exclusive) | Task-level ownership |
| **SD Card** | Persistence Task | Direct (exclusive) | Mutex (if shared) |
| **NVM** | Persistence Task | Direct (exclusive) | Mutex (if shared) |
| **Data Pool** | All Tasks | Event System | Lock-free (atomic operations) |
| **Event System** | All Tasks | Publish/Subscribe | Lock-free queue |
| **State Machine** | System Management Task | Direct (exclusive) | Task-level ownership |

## 4. Component Specifications

### 4.1 State Manager (STM)

**Location:** `application_layer/business_stack/STM/`

**Responsibilities:**
- Implement system FSM as defined in System State Machine Specification
- Enforce valid state transitions
- Coordinate teardown sequences
- Notify components of state changes

**Public API:**
```c
// State query
system_state_t stm_getCurrentState(void);
bool stm_isStateValid(system_state_t state);

// State transition
bool stm_requestTransition(system_state_t target_state, transition_reason_t reason);
bool stm_validateTransition(system_state_t from, system_state_t to);

// Teardown coordination
bool stm_initiateTeardown(teardown_reason_t reason);
bool stm_isTeardownComplete(void);

// Component registration
bool stm_registerStateListener(state_listener_t listener);
```

**State Dependencies:**
- SHALL be initialized first (during INIT state)
- SHALL coordinate with Error Handler for fault-triggered transitions
- SHALL coordinate with OTA Manager for OTA-triggered transitions

### 4.2 Event System

**Location:** `application_layer/business_stack/event_system/`

**Responsibilities:**
- Provide publish/subscribe event bus
- Decouple components via events
- Ensure non-blocking event delivery

**Public API:**
```c
// Event types
typedef enum {
    EVENT_SENSOR_DATA_UPDATE,
    EVENT_DIAGNOSTIC_EVENT,
    EVENT_STATE_CHANGED,
    EVENT_OTA_REQUEST,
    // ... other event types
} event_type_t;

// Publish event
bool event_publish(event_type_t type, void* payload, size_t payload_size);

// Subscribe to events
bool event_subscribe(event_type_t type, event_handler_t handler);
bool event_unsubscribe(event_type_t type, event_handler_t handler);
```

**Constraints:**
- SHALL be non-blocking (lock-free queue)
- SHALL support multiple subscribers per event type
- SHALL NOT perform blocking operations in event handlers

### 4.3 Sensor Manager

**Location:** `application_layer/business_stack/sensor_manager/`

**Responsibilities:**
- Sensor lifecycle management (detection, initialization, sampling)
- High-frequency sampling and filtering
- Timestamp generation
- Sensor failure detection

**Public API:**
```c
// Sensor lifecycle
bool sensorMgr_initialize(void);
bool sensorMgr_detectSensors(void);
bool sensorMgr_startAcquisition(void);
bool sensorMgr_stopAcquisition(void);

// Sensor data access
bool sensorMgr_getLatestData(uint8_t sensor_id, sensor_data_record_t* record);
bool sensorMgr_getAllSensorData(sensor_data_record_t* records, size_t* count);

// Sensor status
bool sensorMgr_isSensorPresent(uint8_t sensor_id);
bool sensorMgr_isSensorEnabled(uint8_t sensor_id);
```

**State Dependencies:**
- SHALL NOT perform acquisition during OTA_UPDATE, MC_UPDATE, TEARDOWN states
- SHALL pause acquisition during SERVICE state (optional)
- SHALL continue acquisition during SD_DEGRADED state (without persistence)

### 4.4 Data Persistence (DP Component)

**Location:** `application_layer/DP_stack/persistence/`

**Responsibilities:**
- Abstract storage media (SD card, NVM)
- Serialize/deserialize structured data
- Manage wear-aware storage
- Ensure data integrity

**Public API:**
```c
// Data persistence
bool persistence_writeSensorData(const sensor_data_record_t* record);
bool persistence_writeDiagnostic(const diagnostic_event_t* event);
bool persistence_writeMachineConstants(const machine_constants_t* mc);

// Data retrieval
bool persistence_readSensorData(sensor_data_record_t* records, size_t* count);
bool persistence_readDiagnostics(diagnostic_event_t* events, size_t* count);
bool persistence_readMachineConstants(machine_constants_t* mc);

// Flush operations
bool persistence_flushCriticalData(void);
bool persistence_isFlushComplete(void);
```

**Constraints:**
- SHALL be the sole interface for persistent storage access (CFC-ARCH-01)
- SHALL NOT allow direct hardware access from application layer
- SHALL verify persistence completion before state transitions (CFC-DATA-02)

### 4.5 OTA Manager

**Location:** `application_layer/business_stack/fw_upgrader/`

**Responsibilities:**
- OTA negotiation with Main Hub
- Firmware reception and storage
- Firmware integrity validation
- Controlled firmware activation

**Public API:**
```c
// OTA operations
bool ota_handleRequest(const ota_request_t* request);
bool ota_receiveFirmwareChunk(const uint8_t* chunk, size_t chunk_size);
bool ota_validateFirmware(void);
bool ota_activateFirmware(void);

// OTA status
ota_status_t ota_getStatus(void);
bool ota_isReady(void);
```

**State Dependencies:**
- SHALL NOT operate during WARNING, FAULT, SERVICE, SD_DEGRADED states
- SHALL coordinate with STM for state transitions
- SHALL coordinate with Persistence for data flush before activation

## 5. Architectural Constraints Mapping

| Constraint | Architectural Mechanism | Enforcement |
|------------|-------------------------|-------------|
| **CFC-ARCH-01** (Hardware Abstraction) | Driver layer abstraction, OSAL layer | Compile-time (no direct HAL includes in application) |
| **CFC-ARCH-02** (State-Aware Execution) | STM state queries, per-state execution rules | Runtime (state checks in components) |
| **CFC-TIME-01** (Non-Blocking) | Event System, async operations | Design-time (no blocking calls in critical paths) |
| **CFC-TIME-02** (Deterministic) | Static memory allocation, bounded operations | Design-time (no dynamic allocation in acquisition) |
| **CFC-DATA-01** (Single Source of Truth) | DP component as sole persistence interface | Compile-time (no direct storage access) |
| **CFC-DATA-02** (Data Consistency) | Persistence flush before state transitions | Runtime (STM coordination) |
| **CFC-SEC-01** (Security First) | Secure boot before application start | Boot-time (hardware-enforced) |
| **CFC-SEC-02** (Encrypted Channels) | TLS/DTLS in Network Stack | Runtime (mandatory encryption) |
| **CFC-DBG-01** (Debug Isolation) | Debug session authentication, state restrictions | Runtime (authentication checks) |

## 6. Repository Structure Mapping

| Architecture Layer | Repository Path | Components |
|-------------------|-----------------|------------|
| **Application Layer** | `application_layer/business_stack/` | STM, Event System, Sensor Manager, MC Manager, OTA Manager, Main Hub APIs |
| **DP Stack** | `application_layer/DP_stack/` | Data Pool, Persistence |
| **Diagnostics** | `application_layer/diag_task/`, `application_layer/error_handler/` | Diagnostics Task, Error Handler |
| **Drivers** | `drivers/` | Network Stack, Diagnostic Protocol, SD Card, NVM, Sensors |
| **ESP-IDF Wrappers** | `ESP_IDF_FW_wrappers/` | GPIO, I2C, SPI, UART, ADC, DMA, Wi-Fi |
| **OSAL** | `os/` | Task, Software Timer |
| **Utilities** | `utils/` | Logger, Time Utils |

## 7. Traceability

- **SRS Section 3.2:** Interface Requirements
- **SRS Section 3.4:** Design Constraints
- **Cross-Feature Constraints:** All architectural constraints mapped
- **System State Machine Specification:** State-aware component behavior

## 8. Diagrams Summary

- **Context View:** External interfaces and actors
- **Component View:** Major components and relationships
- **Data Flow View:** Sensor data, diagnostic, and OTA flows
- **Concurrency View:** Task model, priorities, resource ownership

---

**Next Steps:**
- Component-level specifications (detailed APIs per component)
- Sequence diagrams for additional flows (MC update, diagnostic session)
- Interface Control Documents (ICD) for external interfaces
