{"id":50577389,"url":"https://github.com/eisber/lox-cli","last_synced_at":"2026-06-04T23:02:45.894Z","repository":{"id":353079082,"uuid":"1217860122","full_name":"eisber/lox-cli","owner":"eisber","description":"AI agent tooling for Loxone Miniserver — natural language → config-as-code → deploy","archived":false,"fork":false,"pushed_at":"2026-06-02T22:31:51.000Z","size":9370,"stargazers_count":11,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-06-02T23:17:49.412Z","etag":null,"topics":["ai-agents","cli","config-as-code","copilot","home-automation","loxone","rust","smarthome"],"latest_commit_sha":null,"homepage":"https://github.com/eisber/lox-cli","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eisber.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-04-22T09:38:39.000Z","updated_at":"2026-06-02T22:31:56.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/eisber/lox-cli","commit_stats":null,"previous_names":["eisber/lox-cli"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/eisber/lox-cli","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eisber%2Flox-cli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eisber%2Flox-cli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eisber%2Flox-cli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eisber%2Flox-cli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eisber","download_url":"https://codeload.github.com/eisber/lox-cli/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eisber%2Flox-cli/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33923190,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-04T02:00:06.755Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-agents","cli","config-as-code","copilot","home-automation","loxone","rust","smarthome"],"created_at":"2026-06-04T23:02:45.375Z","updated_at":"2026-06-04T23:02:45.888Z","avatar_url":"https://github.com/eisber.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# lox — AI Agent Tooling for Loxone Miniserver\n\n[![CI](https://github.com/eisber/lox-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/eisber/lox-cli/actions/workflows/ci.yml)\n[![crates.io](https://img.shields.io/crates/v/lox-cli.svg)](https://crates.io/crates/lox-cli)\n[![License: AGPL-3.0](https://img.shields.io/badge/License-AGPL%20v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0)\n[![Eval](https://img.shields.io/badge/eval-80%25%20pass-brightgreen.svg)](#eval-results)\n\n**Tell an AI agent what you want. It configures your Loxone Miniserver.**\n\n*\"Set up the kitchen so the light comes on when dark, blinds go up in strong wind, and they close after five minutes of sunshine if there's no wind.\"* → Agent searches block types, adds 5 logic blocks, wires 3 circuits, fixes a pulse duration error after sim feedback, and verifies all 7 test scenarios — in under 5 minutes.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/assets/demo.gif\" alt=\"Demo: AI agent configures kitchen automation\" width=\"662\"\u003e\n  \u003cbr\u003e\u003csub\u003e▶ Click to play — Copilot CLI builds 3 kitchen circuits from a natural language prompt\u003c/sub\u003e\n\u003c/p\u003e\n\n## Why\n\n[Loxone Config](https://www.loxone.com/enen/products/software/loxone-config/) is a 400MB Windows-only desktop app. You drag blocks onto a canvas, wire them by hand, and hope you didn't miss a connection. For a single room with lighting, blinds, and climate you're easily placing 15+ blocks and 30+ wires.\n\nThis CLI replaces that with shell commands an AI agent can call. The agent reads a [skill reference](.github/skills/loxone-config/SKILL.md) (block types, connectors, common mistakes), builds the circuit, then self-tests with an offline SPS simulator — catching wiring errors before anything touches your live system.\n\nWorks with [GitHub Copilot CLI](https://docs.github.com/en/copilot/github-copilot-in-the-cli), [Claude Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/overview), [OpenCode](https://opencode.ai), or any agent that can run shell commands.\n\n## Install\n\n**Homebrew** (macOS/Linux):\n```bash\nbrew install eisber/tap/lox-cli\n```\n\n**Prebuilt binaries** (Linux, macOS, Windows) — see [Releases](https://github.com/eisber/lox-cli/releases):\n```bash\ncurl -LO https://github.com/eisber/lox-cli/releases/latest/download/lox-cli-linux-x86_64\nchmod +x lox-cli-linux-x86_64 \u0026\u0026 sudo mv lox-cli-linux-x86_64 /usr/local/bin/lox\n```\n\n**From crates.io:**\n```bash\ncargo install lox-cli\n```\n\n**From source:**\n```bash\ngit clone https://github.com/eisber/lox-cli \u0026\u0026 cd lox-cli\ncargo build --release    # Binary at target/release/lox (~14MB)\n```\n\n**Requirements:** Loxone Miniserver Gen 1 or 2 (firmware 12.0+), local network access.\n\n## Quick Start\n\n```bash\n# Connect to your Miniserver\nlox setup set --host https://192.168.1.100 --user admin --pass secret\n\n# Download \u0026 inspect config\nlox config download --extract\nlox config describe config.Loxone\n\n## How It Works\n\n```\nUser: \"Close the living room blinds when it's sunny and above 25°C\"\n  ↓\nAgent reads skill reference (.github/skills/loxone-config/)\n  ↓\nAgent runs CLI commands:\n  lox blocks search \"threshold\"           → GreaterEqual\n  lox config add --type GreaterEqual ...  → adds block, returns connector UUIDs\n  lox config wire-connector ...           → wires sensor → logic → actuator\n  lox sim run config.Loxone --sim '...'   → ✅ signal propagates correctly\n  ↓\nConfig ready to deploy: lox config push config.Loxone --reboot\n```\n\nThe CLI handles LoxCC compression, CRC32 checksums, UUID generation, connector maps for 221 block types, and wiring validation. All commands support `--json` (or `-o json`) for agent consumption.\n\n---\n\n## Config-as-Code\n\n```bash\n# Add logic blocks \u0026 wire them\nlox config add --type GreaterEqual --title \"Temp über 25\" config.Loxone -o json\n# {\"ok\":true,\"uuid\":\"...\",\"type\":\"GreaterEqual\",\"connectors\":[{\"key\":\"Input1\",\"uuid\":\"...\",\"direction\":\"I\"},...]\n\nlox config set-param config.Loxone \"Temp über 25\" Input2 25\nlox config wire-connector config.Loxone \"Temp über 25.Input1\" \"Außentemperatur.AQ\"\nlox config wire-connector config.Loxone \"Jalousie 1 [Wohnzimmer].InputTriggerDown\" \"Temp über 25.Q\"\n\n# Validate \u0026 test\nlox config check config.Loxone -o json     # Structured warnings/errors\nlox sim run config.Loxone --sim '{\"inputs\":{\"Außentemperatur\":30},...}'\n\n# Deploy\nlox config push config.Loxone --reboot --force  # Upload + SPS reload (~4s)\n```\n\nRoom templates for common setups:\n```bash\nlox config template config.Loxone bedroom --room \"DG Schlafzimmer\"\n# Creates LightController2, JalousieUpDown2, Thermostat with sensible defaults\n```\n\nGitOps versioning:\n```bash\nlox config pull    # Download → diff → semantic commit message\nlox config log     # Change history\n```\n\n## SPS Simulator\n\nOffline Miniserver SPS simulator — test config changes without hardware:\n\n- **215 block types** — logic, math, lighting, HVAC, timers, I/O\n- **Topological engine** — automatic evaluation order, cycle detection\n- **Temporal testing** — multi-step specs for heating cycles, timer delays, schedules\n- **6k lines of Rust** in `lox-sim/` with 367 unit tests\n\n```bash\nlox sim run config.Loxone --sim '{\n  \"inputs\": {\"Außentemperatur\": 30, \"Sonnenschein\": 1},\n  \"ticks\": 10, \"dt\": 0.1,\n  \"expected_outputs\": {\"Jalousie 1 [Wohnzimmer].InputTriggerDown\": {\"\u003e\": 0.5}}\n}'\n# {\"pass\":true,\"passed\":1,\"scenarios\":[{\"pass\":true,...}]}\n```\n\n---\n\n## Eval Results\n\nThe eval harness tests whether an AI agent can correctly configure a Loxone Miniserver from natural language instructions. Each case: utterance → agent builds circuit via CLI → Rust simulator verifies signals propagate correctly.\n\n**322 test cases across 13 categories.**\n\nRaw LLM pass rate (agent builds circuit from scratch each run):\n\n| Section | Score | Examples |\n|---------|-------|---------|\n| Synthetic | 20/20 (100%) | \"Close blinds when sunny and above 25°C\" |\n| Patterns | 25/25 (100%) | Memory blocks, delayed triggers, schedules |\n| Reference | 24/24 (100%) | Threshold, negation, fan-out, stairway light |\n| Generated | 50/50 (100%) | Natural language variants, German/English |\n| Rooms | 15/15 (100%) | Full room configurations (bedroom, bathroom, garden) |\n| Extended | 14/15 (93%) | Pushbutton, AutoJalousie, sunrise triggers |\n| Advanced | 28/29 (97%) | Multi-room goodnight, frost protection, solar pool |\n| Use-Cases | 35/40 (88%) | Wallbox charging, NFC lockers, alarm systems |\n| HVAC | 15/18 (83%) | Weather-compensated heating, dewpoint cooling |\n| HVAC-Extracted | 26/32 (81%) | IRC zones, fancoil, HRV ventilation, heat pump |\n| **Total** | **252/268 (94%)** | Core automation: 5 sections at 100% |\n\nNon-deterministic: scores vary ±5% across runs. The remaining failures are complex HVAC chains and specialized hardware (wallbox billing, NFC lockers) where the agent times out or misses wiring.\n\n### How Evals Work\n\nEach eval case is a JSON spec with an utterance and simulation tests. The fixture config (`fixture.Loxone`) provides pre-configured rooms with sensors (temperature, motion, brightness) and actuators (blinds, lights, fans) — the agent adds logic blocks and wires them:\n\n```json\n{\n  \"id\": \"s01-piano-protection\",\n  \"utterance\": \"Lower blinds in the living room when it's sunny and the temperature is over 25 degrees\",\n  \"expected\": {\n    \"simulation\": [\n      {\n        \"name\": \"blinds close when hot+sunny\",\n        \"inputs\": {\"Außentemperatur\": 30, \"Sonnenschein\": 1},\n        \"ticks\": 10, \"dt\": 0.1,\n        \"expected_outputs\": {\"Jalousie 1 [Wohnzimmer].InputTriggerDown\": {\"\u003e\": 0.5}}\n      },\n      {\n        \"name\": \"blinds stay when cold\",\n        \"inputs\": {\"Außentemperatur\": 15, \"Sonnenschein\": 0},\n        \"ticks\": 10, \"dt\": 0.1,\n        \"expected_outputs\": {\"Jalousie 1 [Wohnzimmer].InputTriggerDown\": {\"\u003c\": 0.5}}\n      }\n    ]\n  }\n}\n```\n\nThe pipeline:\n1. **Agent** receives the utterance + fixture config (with sensors \u0026 actuators) + skill reference\n2. **Agent** uses `lox config add`, `wire-connector`, `set-param` to add logic blocks and wire them\n3. **Simulator** injects test values into sensors, ticks the engine, checks actuator outputs\n4. **Pass/fail** based on whether the right actuator fires with the right inputs\n\n### Sample Transcript (actual LLM run)\n\n**Utterance:** *\"When humidity in the bathroom goes above 70%, turn on the fan. Keep it running for 5 minutes after humidity drops back down.\"*\n\nThe agent reads the skill reference, searches for block types, then builds:\n\n```bash\n# 1. Search for the right blocks\nlox blocks search \"greater equal threshold\"\n# → GreaterEqual (Threshold comparator)\nlox blocks search \"off delay timer\"\n# → OffDelay (keeps output on after input drops)\n\n# 2. Add blocks\nlox config add --type GreaterEqual --title \"Feuchte hoch\" --room Bad config.Loxone\n# ✓ Added GreaterEqual 'Feuchte hoch' on page 'Bad'\nlox config add --type OffDelay --title \"Lüfter Nachlauf\" --room Bad config.Loxone\n# ✓ Added OffDelay 'Lüfter Nachlauf' on page 'Bad'\n\n# 3. Set parameters\nlox config set-param config.Loxone \"Feuchte hoch\" Input2 70\n# ✓ Set 'Input2' to 70 on 'Feuchte hoch'\nlox config set-param config.Loxone \"Lüfter Nachlauf\" Time 300\n# ✓ Set 'Time' to 300 on 'Lüfter Nachlauf'\n\n# 4. Wire the signal path\nlox config wire-connector config.Loxone \"Feuchte hoch.Input1\" \"Raumfeuchtigkeit Bad.AQ\"\n# ✓ Wired Raumfeuchtigkeit Bad.AQ → Feuchte hoch.Input1\nlox config wire-connector config.Loxone \"Lüfter Nachlauf.InputTrigger\" \"Feuchte hoch.Q\"\n# ✓ Wired Feuchte hoch.Q → Lüfter Nachlauf.InputTrigger\nlox config wire-connector config.Loxone \"Lüfter Bad.I1\" \"Lüfter Nachlauf.Q\"\n# ✓ Wired Lüfter Nachlauf.Q → Lüfter Bad.I1\n\n# 5. Validate\nlox config check config.Loxone\n# 1 ok, 0 errors\n\n# 6. Test with simulator\nlox sim run config.Loxone --sim '{\"inputs\":{\"Raumfeuchtigkeit Bad\":80},\n  \"ticks\":10,\"dt\":0.1,\"expected_outputs\":{\"Lüfter Bad.I1\":{\"\u003e\":0.5}}}'\n# {\"pass\":true,\"passed\":1,\"scenarios\":[{\"pass\":true, ...}]}\n\nlox sim run config.Loxone --sim '{\"inputs\":{\"Raumfeuchtigkeit Bad\":50},\n  \"ticks\":10,\"dt\":0.1,\"expected_outputs\":{\"Lüfter Bad.I1\":{\"==\":0}}}'\n# {\"pass\":true,\"passed\":1,\"scenarios\":[{\"pass\":true, ...}]}\n```\n\n**Result:** Humidity 80% → fan ON ✅ · Humidity 50% → fan OFF ✅ · Total: 94 seconds, 6 premium requests.\n\n### Running Evals\n\n```bash\n# Single case\npython3 tests/eval/scripts/eval-agent.py --case s01-piano-protection --agent copilot\n\n# Full suite (parallel)\npython3 tests/eval/scripts/eval-agent.py --all --parallel 2 --agent copilot\n\n# Re-eval saved configs (no LLM calls)\nlox sim run saved-config.Loxone --sim '[...]'\n```\n\n---\n\n## For AI Agents\n\nSkill references in `.github/skills/` give agents everything they need:\n\n- **loxone-config** — CLI commands, 221 block types, worked examples, common mistakes\n- **loxone-sim** — simulator testing commands and patterns\n- **loxone-patterns** — 13 automation recipes (threshold, timer, schedule, HVAC)\n\nAll errors include fuzzy matching suggestions and available options:\n```\nError: Block 'Threshold' not found.\n  Did you mean: GreaterEqual, LessEqual, AnalogThresholdTrigger?\n```\n\n### Multiple Miniservers\n\n```bash\nlox ctx add home --host https://192.168.1.100 --user admin --pass secret\nlox ctx add office --host https://10.0.0.50 --user admin --pass secret\nlox ctx use home\n```\n\n---\n\n## Architecture\n\nSingle static Rust binary (~14MB). No runtime dependencies. Works on Linux, macOS, and Windows.\n\nSee **[COMMANDS.md](COMMANDS.md)** for the full command reference, **[DESIGN.md](DESIGN.md)** for architecture details, and **[AGENTS.md](AGENTS.md)** for AI agent integration guidance.\n\n## License\n\nDual-licensed: [AGPL-3.0](LICENSE-AGPL) for open use, [Commercial License](LICENSE-COMMERCIAL) for proprietary redistribution.\n\nBased on [lox](https://github.com/discostu105/lox) by Christoph Neumüller (GPL-3.0). See [NOTICE](NOTICE) for attribution details.\n\nCopyright © 2025-2026 Markus Cozowicz\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feisber%2Flox-cli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feisber%2Flox-cli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feisber%2Flox-cli/lists"}