logo
Kurashizu Blogwhere ideas flow
  • Home
  • News
  • Blog
  • About
  • Home
  • News
  • Blog
  • About

© 2026 Kurashizu. All rights reserved.

Admin·New Post·Service Status
Powered by Cloudflare·02.11.26
← Back to news

An iroh powered smart fan

Original article
iroh.computer|156 points|52 comments|by surprisetalk|Jul 7, 2026

❄️ Building a Smart Fan Powered by Iroh

By Rüdiger Klaehn | July 2, 2026

If you are currently residing in the Northern Hemisphere—specifically Europe—you are likely enduring a brutal heatwave. To combat the rising temperatures and bring some much-needed "chill" back into the room, let's build a project using iroh.

While ESP32s are often used for simple data echoing, their true value lies in being an affordable gateway to read sensors and trigger actuators. In this guide, we will develop a straightforward end-to-end system: an ESP32 that monitors temperature and manages a fan.

The Core Philosophy: Unlike the vast majority of IoT ecosystems, this project contains no cloud components zero cloud dependency. Instead, it utilizes a lightweight website accessible from any browser with WebAssembly (WASM) support, regardless of where you are in the world.


🛠️ Hardware Requirements

For this build, the primary choice is an ESP32-WROVER devkit equipped with 4 MiB of PSRAM. This ensures we have the memory overhead required for Iroh's full networking suite, including relay connections for global remote access.

Hardware Compatibility Matrix

DevicePSRAMCompatibilityNotes
ESP32-WROVERYes✅ FullRecommended for all features.
M5StickC-Plus2Yes✅ PartialRequires GPIO pin adjustments.
ESP32-S3Yes✅ PartialRequires minor configuration tweaks.
Standard ESP32No⚠️ LimitedMust disable relays & tweak QUIC buffers.

⚙️ Basic Setup

We begin by leveraging an existing echo example from the iroh-esp32-examples repository. For the desktop side, we use a standard, "vanilla" client.

To transform this into a smart fan project, we perform the following renames:

  • server-esp32-psram →\rightarrow→ server-smart-fan
  • client →\rightarrow→ smart-fan-cli

Important Note: Because the ESP32 variant may require a specific patch of Iroh and utilizes a different toolchain than the desktop client, these are maintained as two entirely separate Rust projects.

Setup Checklist

  • Clone iroh-esp32-examples
  • Rename server project to server-smart-fan
  • Rename client project to smart-fan-cli
  • Configure WiFi credentials

🚀 Initial Flashing

To get the system running, execute cargo run within the server project. This command automatically detects the ESP32 via USB and flashes the firmware.

Compilation & Performance

  1. First Build: This is slow because the compiler must build both Iroh and the operating system for the xtensa architecture.
  2. Subsequent Builds: Much faster, as results are cached in the .embuild directory.
  3. Flashing Speed: Limited by the chip's data rate. You can optimize this using the ESPFLASH_BAUD environment variable.

To streamline the process, you can export your WiFi credentials so you don't have to type them repeatedly: export WIFI_CONFIG=SSID:PASSWORD

Execution Command:

ESPFLASH_BAUD=230400 WIFI_CONFIG=myap:mypass cargo run --release

Terminal Output:

cargo run --release
Finished `release` profile [optimized] target(s) in 0.56s
Running `espflash flash --monitor target/xtensa-esp32-espidf/release/esp32-psram`
[2026-07-01T07:14:23Z INFO ] 🚀 A new version of espflash is available: v4.4.0
[2026-07-01T07:14:23Z INFO ] Serial port: '/dev/cu.usbserial-210'
[2026-07-01T07:14:30Z INFO ] Using flash stub
Chip type: esp32 (revision v3.1)
Flash size: 4MB
App/part. size: 3,953,296/4,128,768 bytes, 95.75%
[00:04:11] [========================================] 2295/2295 0x10000 Verifying...

As indicated by the logs, the flash usage is quite high: Flash Utilization≈95.75%\text{Flash Utilization} \approx 95.75\%Flash Utilization≈95.75% However, adding pure Rust dependencies (like irpc) has a negligible impact on the binary size, so there is still some breathing room.


🔍 Testing the System

At this stage, the ESP32 is acting as a simple echo server. A critical requirement for IoT is a stable Endpoint ID. We don't want the ID to change every time the device reboots.

To achieve this, the device generates a secret key on the first boot and stores it in Non-Volatile Memory (NVM). Since flashing doesn't overwrite NVM, the device retains its identity unless the memory is explicitly wiped.

The Startup Sequence

Once the device boots, you will see the following logs:

I (7413) server_esp32_psram: Iroh endpoint bound
I (7413) server_esp32_psram: Listening on: 192.168.0.186:51831
I (7413) server_esp32_psram: Endpoint ID: 03b43add965a3eaa2d20d3b60dcb1aa2fa8fdd36cdc1544511af11c26f45fd4b
I (7423) server_esp32_psram: Short ticket: endpointaab3iow5sznd5krnedj3mdoldkrpvd65g3g4cvcfcgxrdqtpix6uwaa
I (7433) server_esp32_psram: Long ticket: endpointaab3iow5sznd5krnedj3mdoldkrpvd65g3g4cvcfcgxrdqtpix6uwaibadakqaf266kag
I (7443) server_esp32_psram: Router started, accepting connections

The device is assigned a local IP (e.g., 192.168.0.186:51831) via DHCP. While it provides both short and long tickets, it is initially only reachable locally via the long ticket.

Finally, the device uses QAD (Query Address Discovery) to determine its global position via various relay URLs:

W (7473) iroh::net_report: QADv4; relay_url=https://aps1-1.relay.n0.iroh.link./
W (7473) iroh::net_report: QADv4; relay_url=https://euc1-1.relay.n0.iroh.link./
W (7483) iroh::net_report: QADv4; relay_url=https://use1-1.relay.n0.iroh.link./
W (7493) iroh::net_report: QADv4; relay_url=https://usw1-1.relay.n0.iroh.link./

Assuming an active internet connection, the device is now ready to be controlled from anywhere.

Smart Fan Architecture