Skip to content

Latest commit

 

History

29 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

IoT Component SDK

A simulation-first Python SDK for building IoT and Cyber-Physical Systems. Develop and test your entire IoT system without physical hardware, then deploy to real devices with zero code changes.

Features

  • Simulation-First Development - Full system runs without hardware using realistic physical models
  • Hardware Abstraction Layer - Swap between mock, simulated, and hardware backends via configuration
  • Realistic Environment Models - Temperature, humidity, and soil moisture with proper physics (evaporation, daily cycles, etc.)
  • Time Acceleration - Run simulations at 1x to 100x speed for rapid testing
  • Pub/Sub Messaging - MQTT-style topic wildcards with local or distributed brokers
  • Declarative Configuration - Define entire systems in YAML
  • Web Dashboard - Real-time monitoring with React, charts, and simulation controls
  • Fault Injection - Test resilience with sensor drift, stuck actuators, communication delays
  • Hysteresis Control - Built-in controllers to prevent actuator oscillation

Quick Start

Installation

# Clone the repository
git clone https://github.com/yourusername/iot-component-sdk.git
cd iot-component-sdk

# Install in development mode
pip install -e ".[dev]"

# Install UI dependencies (optional, for dashboard)
cd ui && npm install && cd ..

Run the Demo

# Run the smart greenhouse example
iot-sdk run examples/configs/agriculture.yaml

# Access the dashboard at http://localhost:8080

Validate a Configuration

iot-sdk validate examples/configs/agriculture.yaml

List Available Components

iot-sdk list

Architecture

┌─────────────────────────────────────────────────────────────────┐
│                        IoT System                                │
├─────────────────────────────────────────────────────────────────┤
│  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐            │
│  │ Sensor  │  │ Sensor  │  │Actuator │  │Controller│            │
│  │  (temp) │  │ (soil)  │  │ (pump)  │  │(hysteres)│            │
│  └────┬────┘  └────┬────┘  └────┬────┘  └────┬────┘            │
│       │            │            │            │                   │
│       └────────────┴────────────┴────────────┘                   │
│                          │                                       │
│              ┌───────────┴───────────┐                          │
│              │    Message Broker     │                          │
│              │  (Local or MQTT)      │                          │
│              └───────────┬───────────┘                          │
│                          │                                       │
│              ┌───────────┴───────────┐                          │
│              │  Simulation Engine    │                          │
│              │  - Time management    │                          │
│              │  - Environment models │                          │
│              │  - Fault injection    │                          │
│              └───────────────────────┘                          │
└─────────────────────────────────────────────────────────────────┘

Core Concepts

Concept Description
Component Building block: sensors, actuators, processors, controllers
Message Unit of communication with type, payload, timestamp, and metadata
Broker Routes messages between components (local in-memory or MQTT)
Simulation Engine Manages time, environment models, and fault injection
HAL Hardware Abstraction Layer with pluggable backends

Hardware Abstraction Layer (HAL)

Each component supports multiple backends:

Backend Description Use Case
mock Returns fixed/random values Unit testing
simulated Uses physical models with noise/drift Integration testing, demos
hardware Connects to real GPIO/I2C/SPI Production deployment

Switch backends with a single config change:

components:
  - id: temp-sensor
    type: sensor.temperature
    backend: simulated  # Change to "hardware" for production

Configuration

Systems are defined in YAML:

system:
  name: "smart-greenhouse"
  mode: "simulation"

  simulation:
    time_scale: 10.0      # 10x faster than real-time
    tick_interval: 0.1
    environment:
      initial_hour: 8.0
      num_zones: 1

  broker:
    type: local           # or "mqtt" for distributed

  api:
    enabled: true
    host: "0.0.0.0"
    port: 8080

components:
  # Temperature sensor publishing every 30 seconds
  - id: temp-sensor-1
    type: sensor.temperature
    backend: simulated
    config:
      interval: 30
      topic: sensors/temperature/zone1

  # Soil moisture sensor
  - id: soil-sensor-1
    type: sensor.soil_moisture
    backend: simulated
    config:
      interval: 30
      topic: sensors/soil/zone1
      zone: 0

  # Water pump actuator
  - id: pump-1
    type: actuator.pump
    backend: simulated
    config:
      command_topic: actuators/pump/command
      state_topic: actuators/pump/state
      flow_rate: 10.0

  # Hysteresis controller for irrigation
  # Turns pump ON when moisture < 30%, OFF when > 60%
  - id: irrigation-controller
    type: controller.hysteresis
    config:
      input_topic: sensors/soil/zone1
      output_topic: actuators/pump/command
      low_threshold: 30.0
      high_threshold: 60.0
      invert: false

Environment Variables

Configuration supports environment variable substitution:

broker:
  type: mqtt
  host: ${MQTT_HOST:localhost}
  port: ${MQTT_PORT:1883}
  username: ${MQTT_USER}
  password: ${MQTT_PASS}

Components

Sensors

Type Description Key Config
sensor.temperature Temperature readings (°C) interval, topic
sensor.humidity Relative humidity (%) interval, topic
sensor.soil_moisture Soil moisture (%) interval, topic, zone

Actuators

Type Description Key Config
actuator.pump Water pump control command_topic, state_topic, flow_rate
actuator.relay Generic relay control command_topic, state_topic

Controllers

Type Description Key Config
controller.hysteresis Bang-bang control with dead band input_topic, output_topic, low_threshold, high_threshold
controller.threshold Simple threshold alerts input_topic, output_topic, threshold, comparison

Environment Simulation

The simulation engine includes realistic physical models:

Temperature Model

  • Daily sine wave pattern (cooler at night, warmer at day)
  • Configurable base temperature and amplitude
  • Random noise for realism

Humidity Model

  • Inversely correlated with temperature
  • Responds to rain events
  • Bounded 0-100%

Soil Moisture Model

  • Evaporation increases with temperature, decreases with humidity
  • Irrigation adds moisture based on pump flow rate
  • Drainage when oversaturated
  • Per-zone tracking
class SoilMoistureModel:
    def update(self, dt_hours: float, temperature: float, humidity: float) -> float:
        # Evaporation rate depends on conditions
        evap_rate = self.base_evaporation * (1 + 0.05 * (temperature - 20))
        evap_rate *= (1 - humidity / 200)

        # Irrigation adds moisture
        if self.is_irrigating:
            self.moisture += self.irrigation_rate * dt_hours

        # Evaporation removes moisture
        self.moisture -= evap_rate * dt_hours

        return self.moisture

Web Dashboard

The SDK includes a React-based dashboard for real-time monitoring:

Features

  • System Overview - Component count, message throughput, uptime
  • Real-time Charts - Sensor readings with Recharts
  • Simulation Controls - Start/stop/pause, time acceleration slider
  • Message Inspector - Filter and inspect pub/sub traffic
  • Environment Panel - Current temperature, humidity, soil moisture
  • Component List - Status and details for all components

Running the Dashboard

The dashboard is served automatically when you run a system:

iot-sdk run config.yaml
# Dashboard available at http://localhost:8080

To run the UI in development mode (hot reload):

# Terminal 1: Run the backend
cd /path/to/iot-component-sdk
python examples/run_demo_server.py

# Terminal 2: Run the frontend
cd ui
npm run dev
# Dashboard at http://localhost:5173

Fault Injection

Test system resilience with fault injection:

scenarios:
  sensor-failure:
    description: "Test behavior when soil sensor fails"
    duration: 3600
    events:
      - time: 300
        action: inject_fault
        parameters:
          component: soil-sensor-1
          fault_type: sensor_stuck

      - time: 600
        action: clear_fault
        parameters:
          component: soil-sensor-1

Available Fault Types

Fault Description
sensor_stuck Sensor returns the same value repeatedly
sensor_drift Readings drift from true value over time
sensor_noise Excessive noise added to readings
actuator_stuck_on Actuator ignores OFF commands
actuator_stuck_off Actuator ignores ON commands
communication_delay Messages are delayed by specified duration

API Reference

REST Endpoints

Method Endpoint Description
GET /api/system System status and configuration
GET /api/components List all components
GET /api/components/{id} Get specific component
GET /api/simulation Simulation state
POST /api/simulation/start Start simulation
POST /api/simulation/stop Stop simulation
POST /api/simulation/pause Pause simulation
POST /api/simulation/resume Resume simulation
POST /api/simulation/speed Set time scale {"time_scale": 10.0}
GET /api/messages Recent message history
GET /api/sensors/latest Latest sensor readings
GET /api/environment Current environment state

WebSocket

Connect to /api/ws for real-time updates:

const ws = new WebSocket('ws://localhost:8080/api/ws');

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  // data.type: "sensor_reading", "actuator_state", "system_event"
  // data.payload: event-specific data
};

CLI Reference

# Run a system from configuration
iot-sdk run <config.yaml> [--no-api] [--port PORT]

# Validate a configuration file
iot-sdk validate <config.yaml>

# List available component types
iot-sdk list

# Show information about a component type
iot-sdk info <type>
# Example: iot-sdk info sensor.temperature

Project Structure

iot-component-sdk/
├── src/iot_sdk/
│   ├── core/
│   │   ├── component.py      # Base Component class
│   │   ├── message.py        # Message dataclass
│   │   ├── broker.py         # Broker interface + LocalBroker
│   │   └── registry.py       # Component registry
│   ├── components/
│   │   ├── sensors/          # Sensor implementations
│   │   ├── actuators/        # Actuator implementations
│   │   └── controllers/      # Controller implementations
│   ├── simulation/
│   │   ├── engine.py         # SimulationEngine
│   │   ├── environment.py    # Environment models
│   │   └── time.py           # Time management
│   ├── api/
│   │   ├── app.py            # FastAPI application
│   │   ├── routes.py         # REST endpoints
│   │   ├── websocket.py      # WebSocket handler
│   │   └── state.py          # Application state
│   ├── system/
│   │   ├── factory.py        # Component factory
│   │   ├── loader.py         # YAML config loader
│   │   ├── builder.py        # System builder
│   │   └── runner.py         # System runner
│   └── cli.py                # Command-line interface
├── ui/                       # React dashboard
│   ├── src/
│   │   ├── components/       # React components
│   │   ├── hooks/            # Custom hooks
│   │   ├── pages/            # Page components
│   │   └── types/            # TypeScript types
│   └── package.json
├── examples/
│   └── configs/
│       └── agriculture.yaml  # Smart greenhouse example
├── tests/
├── pyproject.toml
└── README.md

Development

Prerequisites

  • Python 3.11+
  • Node.js 18+ (for dashboard)

Setup

# Install Python dependencies
pip install -e ".[dev]"

# Install UI dependencies
cd ui && npm install

# Run tests
pytest

# Run tests with coverage
pytest --cov=iot_sdk

# Type checking
mypy src

# Linting
ruff check src tests

# Formatting
black src tests

Creating Custom Components

from iot_sdk.core.component import Component
from iot_sdk.core.message import Message

class CustomSensor(Component):
    """A custom sensor implementation."""

    component_type = "sensor.custom"

    def __init__(self, component_id: str, config: dict, broker):
        super().__init__(component_id, config, broker)
        self.interval = config.get("interval", 60)
        self.topic = config.get("topic", f"sensors/custom/{component_id}")

    async def start(self):
        await super().start()
        # Start reading loop
        self._task = asyncio.create_task(self._read_loop())

    async def _read_loop(self):
        while self._running:
            value = self._read_value()
            message = Message(
                type="sensor.reading",
                source=self.id,
                payload={"value": value, "unit": "custom"}
            )
            await self.publish(self.topic, message)
            await asyncio.sleep(self.interval)

    def _read_value(self) -> float:
        # Your sensor reading logic here
        return 42.0

Register your component:

from iot_sdk.system.factory import get_factory

factory = get_factory()
factory.register("sensor.custom", CustomSensor)

Use Cases

Smart Greenhouse

The primary example demonstrates automated irrigation:

  1. Soil moisture sensors monitor moisture levels in different zones
  2. Temperature/humidity sensors track environmental conditions
  3. Hysteresis controller makes irrigation decisions (ON below 30%, OFF above 60%)
  4. Water pump irrigates based on controller commands
  5. Dashboard provides real-time monitoring and manual override

Benefits of Simulation-First

  • Rapid iteration - No hardware setup required
  • Edge case testing - Simulate sensor failures, extreme conditions
  • Time compression - Test days of operation in minutes
  • Reproducibility - Same simulation produces same results
  • Cost savings - Develop and test before purchasing hardware
  • Team collaboration - Everyone can run the system locally

License

MIT License - see LICENSE for details.

Contributing

Contributions are welcome! Please read CONTRIBUTING.md for guidelines.

Acknowledgments

  • Built following NIST SP 800-183 IoT security guidelines
  • Inspired by industrial IoT frameworks and digital twin concepts

About

Python SDK for building IoT and Cyber-Physical Systems.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages