lox controls, monitors and manages a Loxone Miniserver from the terminal.
It talks to the Miniserver directly over your local network, without a cloud service. It is one ~4 MB binary for
Windows, macOS and Linux.
The Loxone app is made for tapping on a phone. lox covers what it can't: scripts, cron jobs, headless
machines, AI agents, and treating the Miniserver config like source code.
lox on "Licht Wohnzimmer" # switch a light
lox blind "Beschattung Süd" pos 70 # move a blind
lox get "Temperatur [Schlafzimmer]" # read a sensor
lox if "Temperatur Außen" gt 28 && lox blind "Beschattung Süd" pos 70
lox tui # live terminal UI| Control | Lights, moods, dimmers, colors, blinds, gates, thermostats, alarms, door locks, intercoms, wallboxes, virtual inputs, scenes. Controls are found by name, no UUIDs. |
| Monitor | Sensors, energy meters and the energy flow (PV, grid, battery), statistics, device health (batteries, signal, offline devices), a real-time state stream, OpenTelemetry export. |
| Terminal UI | lox tui: a full-screen live view of the house, with rooms, events, energy flow, system stats and the config wiring behind each control. |
| AI agents | JSON output and exit codes on every command, --dry-run, a command schema, and an MCP server (lox mcp serve) for Claude, ChatGPT, Cursor and others. |
| Config versioning | Download the Miniserver config into git on a schedule, with commit messages that list the logic that changed. Diff, inspect and restore any version. |
| Config as code | Write logic in .loxl text files, review it in a pull request, compile it into the config and deploy it with a verified upload. |
| Access | NFC tags and access codes for users, the door access log, and why can't this user open the door? |
- Install · Setup
- Controlling the home · Terminal UI · A 8000 I agents and MCP
- Config versioning · Config as code
- Configuration reference · Requirements
- Documentation · Related projects · Status · License
Homebrew (macOS, Linux)
brew tap discostu105/lox https://github.com/discostu105/lox
brew install discostu105/lox/loxWindows (PowerShell)
irm https://raw.githubusercontent.com/discostu105/lox/main/install.ps1 | iexThis puts the latest release in %LOCALAPPDATA%\lox and adds it to your PATH. To install by hand, download
lox-windows-x86_64.exe from the latest release, rename it
to lox.exe and put it on your PATH.
From source (Rust 1.91+, no OpenSSL needed)
git clone https://github.com/discostu105/lox
cd lox
cargo build --release # → target/release/loxlox setup set --host https://192.168.1.100 --user USER --pass PASS
lox status # check the connection
lox ls # list the controls lox can seeTo keep the password out of your shell history and the process list, use LOX_PASS instead of --pass:
read -rs LOX_PASS && export LOX_PASS. More options (several Miniservers, aliases, completions) are under
Configuration reference.
Names are matched as case-insensitive substrings. When a name matches several controls, add the room with
--room or as "Name [Room]".
lox ls -t Jalousie -r "EG" # filter by type, room, category
lox get "Temperatur" --room "Schlafzimmer" # read a control's state
lox on "Licht Wohnzimmer" # on / off
lox light mood "Wohnzimmer" plus # next light mood
lox thermostat "Heizung" temp 22.5 # set the temperature
lox alarm "Alarmanlage" arm # arm the alarm
lox sensors --type door-window # open windows and doors
lox energy # energy meters
lox energy flow # PV, consumption, grid import/export, battery
lox energy --top 5 # the meters drawing the most power
lox health --problems # low batteries, weak signal, offline devices
lox hw status --problems # devices missing, offline, replaced or not in the program
lox run abend # run a scene
lox stream --room "Kitchen" -o json # state changes as they happen
lox otel serve --endpoint http://… # push metrics, logs and traces via OTLP| Control type | Commands |
|---|---|
LightControllerV2 |
on, off, light mood <name> plus/minus/off/<id>, light moods <name> |
Jalousie / CentralJalousie |
blind <name> up/down/stop/shade/pos <0-100> |
Switch / Pushbutton |
on, off, input pulse |
Dimmer |
light dim <name> <0-100> |
ColorPickerV2 |
light color <name> "#RRGGBB" / "hsv(h,s,v)" / "temp(brightness,kelvin)" |
Gate / CentralGate |
gate <name> open/close/stop |
IRoomControllerV2 |
thermostat <name> temp <°C> / mode <auto…> / override <°C> [min] |
Alarm |
alarm <name> arm/arm-home/disarm/quit |
| Door lock, intercom, wallbox | door … lock/unlock/open, intercom … answer/hangup/open, charger … start/stop/pause |
| Analog / virtual inputs | input set <name> <value> |
| Sensors, meters | get, sensors, energy, history (read-only) |
| Any | send <name> <raw-command>, lock, unlock |
Scenes are YAML files in ~/.lox/scenes/, run with lox run <name>:
# ~/.lox/scenes/abend.yaml
name: Abend
steps:
- control: "Lichtsteuerung Wohnzimmer"
cmd: on
- control: "Beschattung Südseite"
cmd: "pos 70"
- control: "LED Küche"
cmd: off
delay_ms: 500Users and door access
lox access check alice # why alice may (not) open the NFC Code Touch
lox access log "Code Touch" # who opened when, denied attempts
lox access learn "Code Touch" --user alice --name "alice phone" # read an NFC tag, pair it
lox user code set alice # new access code (hidden prompt)Every command and flag is in COMMANDS.md.
lox tui is a full-screen, keyboard-driven live view of your installation, like btop for your house.
Recorded from lox tui --demo with scripts/demo-video. No Miniserver needed.
lox tui # connect to the current context
lox tui --demo # a synthetic demo house
lox tui --read-only # wall display: look, don't touch- Home: room cards, what needs attention (open windows, low batteries, offline devices), pinned controls, a live feed
- Rooms: every control with its live value;
␣toggles,+/-dims,=sets a value,mpicks a mood,ashows all actions - Events: every state change as it happens, filterable, with what happened just before
- Energy: animated PV / home / grid / battery flow, meters, today's curve
- System: CPU, heap, devices, CAN bus and LAN, the Miniserver log, and config history with logic diffs
(
⏎browses a snapshot,mcompares two commits,wopens a changed block's wiring) - Sites: all your Miniservers at a glance; switch live
- Wiring (
w): the config program around a control with live values on the wires, to answer why is this light on?ttraces the path to the sensors or actuators,Hshows the block's history - History (
c): a control's statistics over 6 h to a year, with period compare, a cursor and extra series
: opens a fuzzy palette for rooms, controls, scenes and any lox command, ? lists the keys, and y copies
the equivalent lox command. Doors, alarms, gates and controls on your confirm: list ask before acting;
reboot and update ask you to type the context name. All keys and flags:
COMMANDS.md.
Every command exits 0 on success and non-zero on error, and -o json gives structured output (errors too,
as JSON envelopes with error codes). An agent with a shell tool can discover the house and act on it without
a custom integration:
lox schema -o json # discover the commands
lox ls -o json # discover the controls
lox --dry-run on "Licht" -o json # preview before executing
lox --trace-id "run-42" on "Licht" # execute, correlated in the logs
lox health --problems -o json # check device health--non-interactive fails instead of prompting (implied by -o json).
MCP server. Clients that speak the Model Context Protocol (Claude
Desktop, Claude Code, ChatGPT, Cursor, …) can launch lox mcp serve. It exposes typed tools over stdio:
rooms, controls, live state, switches, blinds, lights, climate, scenes, the config wiring behind a control (with live values on the wires),
door access, learning NFC tags and setting access codes, and read-only config-as-code tools (check, diff, drift,
compile into a scratch directory, a push dry run). Doors, gates, the alarm, every change to users and
any control on your confirm: list ask you to confirm in the client before anything is sent.
lox mcp config # print a ready-to-paste client config
claude mcp add loxone -- lox mcp serve # Claude Code
lox mcp tools # the tools a client will seeTool list and safety model: AI agent guide.
Keep the Miniserver configuration in a git repository, with one commit per change:
lox config init ~/loxone-config # one-time setup
lox config pull # download, diff, commit (--quiet for cron)
lox config log # history
lox config restore abc123 --force && lox reboot --yes # back to an old versionEach pull downloads the config over FTP, decompresses Loxone's LoxCC format to XML, diffs the logic (blocks, parameters and wires, per page) against the previous snapshot and writes it into the commit message:
[504F94AABBCC] Config backup 2026-03-08 18:22:56 (v42)
= 1 added · 1 parameter · wires +1 −0
# Garage
+ block Garage light (Switch)
~ param Garage door · Runtime 20 s → 25 s
+ wire Motion Garage.Q → Garage light.Tg
Every snapshot stays inspectable:
lox config diff v271 # what changed in the logic since version 271
lox config wiring "Licht" --trace up # what drives this light, back to the sensors
lox config show -p Wohnzimmer # a logic page as Lox Logic source
lox config find bewegung # search blocks by name, type, device, room
lox config lint # dead blocks, unwired inputs and motors, duplicate names
lox config history "Licht" # how one block changed over time--at v42 runs show, wiring, find and lint on an old snapshot. Each Miniserver gets its own
subdirectory (by serial number). A restore uploads the original backup ZIP from git as sps_new.zip, without
recompressing it, and the Miniserver loads it on its next start.
Guide: Config versioning.
Write Miniserver logic as text, review it in a pull request, and compile it into the real config:
temp_hoch = GreaterEqual("Temp über 28", In1: aussentemp, In2: 28)
extern jal_sued = AutoJalousie(title: "Beschattung Süd", AutoShade: temp_hoch and sonne)
lox logic compilewrites the same XML Loxone Config would have written, and pins every UUID it creates in a lockfile, so the next compile changes only what you changed.- Everything the source doesn't manage (hardware, rooms, visualization, other logic) passes through byte for
byte.
lox logic diffshows it. lox logic drifttells you when Loxone Config or the app changed the config since.lox logic coverageshows how much of the config the source owns.lox config push --forcedeploys a project: drift check, compile against the live config, a check for user changes the upload would discard, byte-exact upload, restart, and a download that confirms the Miniserver runs the compiled file. It refuses when the rules changed in the app since the last push.lox config syncchecks that source, lock and the live config agree.lox config mergetakes over automatic rules edited in the app into the source, so the next push keeps them.lox logic lspis a language server for your editor.lox logic templatesships tested templates for common automations, andlox logic types --searchsays what each block type is for.
lox config download --extract --save-as base.zip # the deployed config → base.Loxone
lox logic adopt base.Loxone --out-dir pages --out-lock logic.lock.json # take over existing blocks
$EDITOR pages/*.loxl # with base, module and lock in lox.toml:
lox logic compile && lox config diff base.Loxone out.Loxone
lox config push --force # deploy, verifiedWalkthrough: Config as Code guide. Reference: COMMANDS.md and the Lox Logic docs.
The toolchain is the loxone-config crate in this repository, a library without network
access (also on crates.io). Its CLI is the loxl binary. lox uses it for
lox logic, the logic diffs, the TUI's Wiring view and lox config show/wiring/find/lint/history.
The config lives in ~/.lox/config.yaml (Windows: C:\Users\<YOU>\.lox\config.yaml). --serial in
lox setup set is optional: it names the Miniserver's folder in the config repo and its OpenTelemetry
device.id.
Several Miniservers: named contexts.
lox ctx add home --host https://192.168.1.100 --user admin --pass secret
lox ctx add office --host https://10.0.0.50 --user admin --pass secret
lox ctx use home # switch the active context
lox --ctx office status # one command against another contextAliases: short names for controls you use often.
host: https://192.168.1.100
user: admin
pass: secret
aliases:
wz: "1d8af56e-036e-e9ad-ffffed57184a04d2" # Lichtsteuerung Wohnzimmer
kueche: "20236c09-0055-6e94-ffffed57184a04d2" # Licht Küche InselThen lox on wz, lox off kueche.
Shell completions: Homebrew installs them. Otherwise run lox completions --install (detects your
shell), or print them with lox completions bash|zsh|fish|powershell. For PowerShell, add this to $PROFILE:
lox completions powershell | Out-String | Invoke-ExpressionFiles
~/.lox/
config.yaml # host, credentials, aliases, confirm: list (one Miniserver or named contexts)
tui.yaml # lox tui preferences
contexts/<name>/ # per context (a single-Miniserver config keeps these directly in ~/.lox/)
cache/structure.json # LoxApp3.json (24 h TTL, ~150 KB)
token.json # token auth (optional)
scenes/*.yaml # your scenes
Caching: the structure file (LoxApp3.json) is cached for 24 h. Run lox cache refresh after you change
the config in Loxone Config.
| Operation | Cold cache | Warm cache |
|---|---|---|
lox on "Licht", lox ls |
~1.2 s | ~80 ms |
lox ls --values |
~1.2 s + one request per control | one request per control |
lox status |
~120 ms | ~120 ms |
- Loxone Miniserver Gen 1 or Gen 2, firmware 12.0+
- Network access to the Miniserver (local, or DynDNS)
- An admin user for
lox log - Windows (x86_64, ARM64), macOS (x86_64, Apple Silicon), Linux (x86_64, ARM64)
TLS uses rustls. The Miniserver's self-signed certificate is accepted unless you set verify_ssl: true.
- COMMANDS.md: every command and flag
- Getting started
- Guides: AI agents, Terminal UI, Config versioning, Config as code, Scenes, OpenTelemetry
- Architecture and contributing
- The docs as a website: discostu105.github.io/lox
The parts of lox that other Rust projects can use are published as crates:
- loxone-client (crates.io): talks to a Miniserver: the HTTP API, token auth, the WebSocket state stream, FTP backups, statistics.
- loxone-config (crates.io): the program file: the lossless
.Loxonemodel, backup ZIPs, the.loxllanguage, semantic diff. No network access.
-
eisber/lox-cli: a separate project by Markus Cozowicz, based on an earlier version of lox. Its own code is AGPL-3.0 or commercial. It edits a config differently:
- An AI agent builds the logic one command per step (
lox config add,set-param,wire-connector), and lox-cli writes each step straight into the.LoxoneXML. - It tests the result in an offline simulator,
lox sim. - lox instead keeps the logic as
.loxlsource and compiles it with pinned UUIDs. Everything the source doesn't own stays byte for byte, and lox verifies the result on the Miniserver after the upload.
The projects share no code.
loxl testruns its scenarios in its own simulator, and--lox <path>runs them in lox-cli'slox siminstead. Both projects install a binary namedlox, so rename one of them if you install both. - An AI agent builds the logic one command per step (
This project is an experiment. Expect rough edges: not every Miniserver configuration has been tested. Contributions are welcome.
Use at your own risk. Commands that change your Miniserver (config upload, config push, reboot,
update, …) affect your live system. Keep a backup.
Licensed under the Apache License 2.0.