Agent-driven IoT device design tool that produces ESPHome YAML.
Project description
wirestudio
Agent-driven IoT device design tool. Describe a goal (or pick parts); get ESPHome YAML, an ASCII wiring diagram, and a BOM that compile under upstream ESPHome.
A second generation target builds and flashes LoRaWAN firmware (RadioLib + LoRaWAN_ESP32) for US915 radio boards — TTGO T-Beam / LoRa32, Heltec WiFi LoRa 32 V2/V3 — over WebSerial from the browser, and provisions the device against ChirpStack.
Produces ESPHome configs but is not affiliated with the ESPHome
project — see weirded/fleet-for-esphome
for the OTA-deploy companion this studio's Push to fleet flow
talks to.
Documentation
Detailed docs live in docs/:
- Documentation index — architecture, repo layout, roadmap.
- User guide — Web UI, inspector, header actions, HTTP API, examples.
- Deployment — self-host with Docker or Kubernetes.
- Integrations — agent, fleet handoff, enclosure search, KiCad.
- MCP server — drive the studio from Claude Code / Desktop.
- Library reference — every board and component.
- LoRaWAN target — build + flash LoRaWAN firmware, provision against ChirpStack.
Status
v0.13.0 — on PyPI (pip install wirestudio). The studio has wide
surface area (YAML, schematic, enclosure, agent, MCP server, fleet
handoff, web UI, a LoRaWAN flash/provision target) and a set of things
actually verified against upstream tools. Three of the four priority
tiers (YAML, wiring schema, enclosure) are now gated in CI, and every
library component and board is exercised by a bundled example that
passes those gates. This section is honest about which is which, ordered
by how much it matters that it works.
Tiers, in priority order:
| Tier | Area | What it does | Verified by |
|---|---|---|---|
| Verified | ESPHome YAML production | render design.json → ESPHome YAML |
esphome config passes on every bundled example, every PR (gate); nightly esphome compile smoke against a representative example (compile) |
| Verified | CSP pin solver + compat checker | assign legal pins, surface boot-strap / ADC2-WiFi / voltage / locked-pin issues | unit tests + property checks in tests/test_pin_solver.py + tests/test_compatibility.py |
| Verified | Fleet handoff | push YAML to fleet-for-esphome ha-addon, optional compile + log relay |
round-trip tests in tests/test_fleet.py |
| Verified | KiCad schematic | emit a SKiDL Python script the user runs locally to produce a .kicad_sch |
every bundled example builds a KiCad netlist against the pinned upstream symbol libraries, every PR (gate) — no unresolved symbols or pins. Parts KiCad ships no symbol for (sensor/module breakouts) render as labeled generic headers |
| Verified | Parametric enclosure | OpenSCAD .scad from board mount-hole metadata |
every enclosure-capable board renders through real OpenSCAD to a non-empty, manifold (closed, printable) solid, every PR (gate) |
| Works (hardware-validated) | LoRaWAN target | build RadioLib + LoRaWAN_ESP32 firmware for US915 radio boards, flash over WebSerial, provision against ChirpStack | every radio board's firmware builds in CI (gate); validated end-to-end on a TTGO T-Beam against live ChirpStack 4.17 — no automated live-device gate |
| Works (lighter checks) | MCP server | drive the design tools from Claude Code / Desktop over the Model Context Protocol | tool / auth / resource tests in tests/test_mcp_*.py; not exercised against a live MCP client in CI |
| Experimental | Thingiverse search relay | rank community models for a board | smoke-tested; depends on a third-party search API that ranks unevenly |
| Experimental | Agent (Claude tool-using) | natural-language design driving | works in practice; tool surface is small; no auto-eval against task list yet |
| Deferred | KiCad PCB layout | Freerouting + Gerber + JLCPCB CPL/BOM | 1.0+, not started |
The Verified tier is the bar the project is asking to be judged on. Everything else is offered with the caveat that's spelled out in the table.
See CONTRIBUTING.md for the bar a change has to
clear before merging, CHANGELOG.md for per-release
deltas, and START.md for the longer-form design notes.
Tested against ESPHome ==2025.12.7 (pinned in
.github/workflows/esphome-config.yml + bumped deliberately). When
that pin moves, this line moves with it.
Quickstart
Docker
docker run --rm -p 8765:8765 \
-e ANTHROPIC_API_KEY=sk-ant-... \
-v wirestudio-data:/data \
ghcr.io/moellere/wirestudio:v0.13.0
Open http://localhost:8765. The image bundles the FastAPI server + the built web UI in one process. See Deployment for image tags, env vars, and the Kubernetes manifest.
CLI
pip install wirestudio # from PyPI
# ...or, for a dev checkout: pip install -e .[dev]
python -m wirestudio.generate wirestudio/examples/garage-motion.json
Prints rendered YAML and the ASCII wiring block to stdout.
HTTP API
python -m wirestudio.api # localhost:8765
python -m wirestudio.api --reload # dev mode (auto-reload on edits)
Browse the auto-generated OpenAPI docs at http://127.0.0.1:8765/docs. The agent, fleet handoff, and MCP surfaces are each gated by an env var — see Integrations.
Web UI (dev)
# In one terminal:
python -m wirestudio.api
# In another:
cd web && npm install && npm run dev
Open http://localhost:5173; Vite proxies /api/* to the studio API.
The User guide walks the panes and header actions.
Tests
python -m pytest # ~680 cases
python -m ruff check . # lint
cd web && npx vitest run # vitest + jsdom
pip install 'esphome==2025.12.7'
python scripts/check_examples.py # the YAML gate -- every example through `esphome config`
The esphome config gate is the headline test: it renders every
bundled example through the studio and runs upstream ESPHome's own
validator against the output. The GitHub Actions workflow runs the
YAML gate + the full suite + multi-arch image build on every PR and
merge to main. A nightly compile-smoke runs esphome compile
against a representative example. To run the gate before every push:
pip install pre-commit
pre-commit install --hook-type pre-push
Contributing
CONTRIBUTING.md is the substantive bar — what
"working" means for the artifacts the studio produces, including
the esphome config gate every PR has to clear. CLAUDE.md
covers the prose / commit / comment conventions (concise, no emojis,
default-to-no-comments, boundary-only validation, no premature
abstraction).
License
MIT. See LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file wirestudio-0.14.0.tar.gz.
File metadata
- Download URL: wirestudio-0.14.0.tar.gz
- Upload date:
- Size: 278.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d0aee330a50d89492bf1f9eee005c734ea7ad9256a08d7a6fee7f719b03a1af1
|
|
| MD5 |
54440f2494f45d8683e7189d9869369a
|
|
| BLAKE2b-256 |
fe8c51a44ef6d86e2963b9f4a0aaf188ac7d59a0c4bb2181705f6faad7722bd3
|
Provenance
The following attestation bundles were made for wirestudio-0.14.0.tar.gz:
Publisher:
release.yml on moellere/WireStudio
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
wirestudio-0.14.0.tar.gz -
Subject digest:
d0aee330a50d89492bf1f9eee005c734ea7ad9256a08d7a6fee7f719b03a1af1 - Sigstore transparency entry: 1631923141
- Sigstore integration time:
-
Permalink:
moellere/WireStudio@cb2adabef7ca2c630493bf25264b42839a7b3495 -
Branch / Tag:
refs/tags/v0.14.0 - Owner: https://github.com/moellere
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@cb2adabef7ca2c630493bf25264b42839a7b3495 -
Trigger Event:
push
-
Statement type:
File details
Details for the file wirestudio-0.14.0-py3-none-any.whl.
File metadata
- Download URL: wirestudio-0.14.0-py3-none-any.whl
- Upload date:
- Size: 319.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0fdd2c44a95f710f9629e7dc16923f04ecb9e41aadacf916e9fe1ba211b22f56
|
|
| MD5 |
fcdd5175a853051013a49283df8bbcd4
|
|
| BLAKE2b-256 |
097153d16e600e9b25e5218f4dddb322020477903507ec3a6f8ab47483f94f3b
|
Provenance
The following attestation bundles were made for wirestudio-0.14.0-py3-none-any.whl:
Publisher:
release.yml on moellere/WireStudio
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
wirestudio-0.14.0-py3-none-any.whl -
Subject digest:
0fdd2c44a95f710f9629e7dc16923f04ecb9e41aadacf916e9fe1ba211b22f56 - Sigstore transparency entry: 1631923152
- Sigstore integration time:
-
Permalink:
moellere/WireStudio@cb2adabef7ca2c630493bf25264b42839a7b3495 -
Branch / Tag:
refs/tags/v0.14.0 - Owner: https://github.com/moellere
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@cb2adabef7ca2c630493bf25264b42839a7b3495 -
Trigger Event:
push
-
Statement type: