home / skills / zhanghandong / rust-skills / domain-iot

domain-iot skill

/skills/domain-iot

This skill helps you design offline-first, power-efficient IoT apps with secure, reliable messaging and safe OTA updates.

npx playbooks add skill zhanghandong/rust-skills --skill domain-iot

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
4.3 KB
---
name: domain-iot
description: "Use when building IoT apps. Keywords: IoT, Internet of Things, sensor, MQTT, device, edge computing, telemetry, actuator, smart home, gateway, protocol, 物联网, 传感器, 边缘计算, 智能家居"
user-invocable: false
---

# IoT Domain

> **Layer 3: Domain Constraints**

## Domain Constraints → Design Implications

| Domain Rule | Design Constraint | Rust Implication |
|-------------|-------------------|------------------|
| Unreliable network | Offline-first | Local buffering |
| Power constraints | Efficient code | Sleep modes, minimal alloc |
| Resource limits | Small footprint | no_std where needed |
| Security | Encrypted comms | TLS, signed firmware |
| Reliability | Self-recovery | Watchdog, error handling |
| OTA updates | Safe upgrades | Rollback capability |

---

## Critical Constraints

### Network Unreliability

```
RULE: Network can fail at any time
WHY: Wireless, remote locations
RUST: Local queue, retry with backoff
```

### Power Management

```
RULE: Minimize power consumption
WHY: Battery life, energy costs
RUST: Sleep modes, efficient algorithms
```

### Device Security

```
RULE: All communication encrypted
WHY: Physical access possible
RUST: TLS, signed messages
```

---

## Trace Down ↓

From constraints to design (Layer 2):

```
"Need offline-first design"
    ↓ m12-lifecycle: Local buffer with persistence
    ↓ m13-domain-error: Retry with backoff

"Need power efficiency"
    ↓ domain-embedded: no_std patterns
    ↓ m10-performance: Minimal allocations

"Need reliable messaging"
    ↓ m07-concurrency: Async with timeout
    ↓ MQTT: QoS levels
```

---

## Environment Comparison

| Environment | Stack | Crates |
|-------------|-------|--------|
| Linux gateway | tokio + std | rumqttc, reqwest |
| MCU device | embassy + no_std | embedded-hal |
| Hybrid | Split workloads | Both |

## Key Crates

| Purpose | Crate |
|---------|-------|
| MQTT (std) | rumqttc, paho-mqtt |
| Embedded | embedded-hal, embassy |
| Async (std) | tokio |
| Async (no_std) | embassy |
| Logging (no_std) | defmt |
| Logging (std) | tracing |

## Design Patterns

| Pattern | Purpose | Implementation |
|---------|---------|----------------|
| Pub/Sub | Device comms | MQTT topics |
| Edge compute | Local processing | Filter before upload |
| OTA updates | Firmware upgrade | Signed + rollback |
| Power mgmt | Battery life | Sleep + wake events |
| Store & forward | Network reliability | Local queue |

## Code Pattern: MQTT Client

```rust
use rumqttc::{AsyncClient, MqttOptions, QoS};

async fn run_mqtt() -> anyhow::Result<()> {
    let mut options = MqttOptions::new("device-1", "broker.example.com", 1883);
    options.set_keep_alive(Duration::from_secs(30));

    let (client, mut eventloop) = AsyncClient::new(options, 10);

    // Subscribe to commands
    client.subscribe("devices/device-1/commands", QoS::AtLeastOnce).await?;

    // Publish telemetry
    tokio::spawn(async move {
        loop {
            let data = read_sensor().await;
            client.publish("devices/device-1/telemetry", QoS::AtLeastOnce, false, data).await.ok();
            tokio::time::sleep(Duration::from_secs(60)).await;
        }
    });

    // Process events
    loop {
        match eventloop.poll().await {
            Ok(event) => handle_event(event).await,
            Err(e) => {
                tracing::error!("MQTT error: {}", e);
                tokio::time::sleep(Duration::from_secs(5)).await;
            }
        }
    }
}
```

---

## Common Mistakes

| Mistake | Domain Violation | Fix |
|---------|-----------------|-----|
| No retry logic | Lost data | Exponential backoff |
| Always-on radio | Battery drain | Sleep between sends |
| Unencrypted MQTT | Security risk | TLS |
| No local buffer | Network outage = data loss | Persist locally |

---

## Trace to Layer 1

| Constraint | Layer 2 Pattern | Layer 1 Implementation |
|------------|-----------------|------------------------|
| Offline-first | Store & forward | Local queue + flush |
| Power efficiency | Sleep patterns | Timer-based wake |
| Network reliability | Retry | tokio-retry, backoff |
| Security | TLS | rustls, native-tls |

---

## Related Skills

| When | See |
|------|-----|
| Embedded patterns | domain-embedded |
| Async patterns | m07-concurrency |
| Error recovery | m13-domain-error |
| Performance | m10-performance |

Overview

This skill captures IoT domain constraints and practical design guidance for building reliable, low-power, and secure IoT applications. It maps high‑level rules (network unreliability, power limits, security, OTA) into concrete design constraints and Rust implementation patterns. The guidance covers embedded (no_std) and gateway (std) environments, recommended crates, and common pitfalls to avoid.

How this skill works

The skill inspects domain rules and translates them into layered design implications: offline‑first buffering, power management, secure comms, and safe OTA. It recommends implementation patterns (store & forward, edge compute, sleep cycles), specific Rust crates for each environment, and example code patterns such as an MQTT client with retry and local persistence. It also highlights typical mistakes and corrective measures like exponential backoff and TLS.

When to use it

  • Designing battery-powered sensors or actuators that must conserve energy.
  • Building gateways that bridge constrained devices to cloud services.
  • Implementing reliable telemetry where networks are intermittent.
  • Planning secure OTA firmware updates and rollback strategies.
  • Choosing crates and patterns for no_std embedded targets vs tokio-based gateways.

Best practices

  • Adopt offline-first: persist a local queue and flush on connectivity with retry/backoff.
  • Prioritize power: use sleep/wake cycles, minimize allocations, consider no_std where appropriate.
  • Secure everything: use TLS, signed firmware, and authenticated topics for MQTT.
  • Design for recovery: watchdogs, timeouts, and clear rollback paths for OTA.
  • Prefer edge compute: filter/aggregate at the device to reduce network and cloud load.

Example use cases

  • A battery sensor that buffers readings locally, sleeps between wakes, and uploads when the gateway is reachable.
  • A Linux gateway that uses tokio and rumqttc to aggregate device telemetry and forward to cloud endpoints.
  • An MCU implementing embassy and embedded-hal with defmt logging and no_std footprints.
  • Firmware OTA pipeline that verifies signatures and supports rollback on failure.
  • A hybrid edge setup that preprocesses data on gateways to reduce cloud costs and latency.

FAQ

Which MQTT QoS should I choose for telemetry?

Use AtLeastOnce (QoS 1) for telemetry to balance delivery guarantees and performance; use QoS 2 only when strict deduplication is required.

How do I handle network outages without losing data?

Persist messages locally in a queue, apply exponential backoff for retries, and drain the queue when connectivity returns.