Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.git
.venv
.pytest_cache
.ruff_cache
*.egg-info
__pycache__
tests/
.coverage
*.db
17 changes: 17 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM python:3.12-slim

RUN apt-get update \
&& apt-get install -y --no-install-recommends libdbus-1-3 \
&& rm -rf /var/lib/apt/lists/*

COPY . /app
RUN pip install --no-cache-dir /app \
&& chmod +x /app/entrypoint.sh

RUN useradd -u 1000 -m tado
USER tado

VOLUME /data
EXPOSE 4407

ENTRYPOINT ["/app/entrypoint.sh"]
53 changes: 52 additions & 1 deletion INSTALLATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,58 @@ pip install .
pip install git+https://github.com/ampscm/TadoLocal.git
```

### Method 4: Container (Docker/Podman)

Run TadoLocal in a container — no Python install required. Works on any platform
with Docker or Podman, including NAS devices and Raspberry Pi (ARM).

#### Build

```bash
# From the project directory
docker build -t tado-local .

# Or with Podman
podman build -t tado-local .
```

#### First-time pairing

The bridge PIN is only needed for the initial pairing. The pairing database is
persisted in the `/data` volume so it survives container restarts.

```bash
docker run -d --name tado-local \
-p 4407:4407 \
-v tado-data:/data \
-e TADO_BRIDGE_IP=192.168.1.100 \
-e TADO_BRIDGE_PIN=123-45-678 \
tado-local
```

#### Subsequent runs

Once paired, `TADO_BRIDGE_PIN` can be omitted:

```bash
docker run -d --name tado-local \
-p 4407:4407 \
-v tado-data:/data \
-e TADO_BRIDGE_IP=192.168.1.100 \
tado-local
```

#### Environment variables

| Variable | Required | Description |
|---|---|---|
| `TADO_BRIDGE_IP` | Yes (first run) | IP address of your Tado bridge |
| `TADO_BRIDGE_PIN` | First pairing only | HomeKit PIN printed on the bridge |
| `TADO_PORT` | No (default `4407`) | Port the API listens on inside the container |

> **Tip:** Replace `docker` with `podman` in all commands above if using Podman.
> The image is multi-arch and works on both AMD64 and ARM64.

## Usage

After installation, you can run the proxy in multiple ways:
Expand Down Expand Up @@ -132,7 +184,6 @@ pip uninstall tado-local

**Future Work**: 📋
- Comprehensive test suite
- Add Docker support
- Publish to PyPI
- CI/CD pipeline

Expand Down
37 changes: 37 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/bin/sh
set -e

STATE_DB="/data/tado-local.db"

if [ -z "$TADO_BRIDGE_IP" ] && [ ! -f "$STATE_DB" ]; then
echo "No TADO_BRIDGE_IP set and no existing pairing DB found at $STATE_DB."
echo "Set TADO_BRIDGE_IP (and TADO_BRIDGE_PIN for first pairing) then restart."
echo "Sleeping to keep container alive for debugging..."
exec sleep infinity
fi

ARGS="--state $STATE_DB --port ${TADO_PORT:-4407}"

if [ -n "$TADO_BRIDGE_IP" ]; then
ARGS="$ARGS --bridge-ip $TADO_BRIDGE_IP"
fi

if [ -n "$TADO_BRIDGE_PIN" ]; then
ARGS="$ARGS --pin $TADO_BRIDGE_PIN"
fi

# Forward-compatible: PR #40 accessory support (comma-separated IPs and PINs)
if [ -n "$TADO_ACCESSORY_IP" ]; then
IFS=','
set -- $TADO_ACCESSORY_IP
idx=0
for ip in "$@"; do
pin=$(echo "$TADO_ACCESSORY_PIN" | cut -d',' -f$((idx + 1)))
ARGS="$ARGS --accessory-ip $ip"
[ -n "$pin" ] && ARGS="$ARGS --accessory-pin $pin"
idx=$((idx + 1))
done
unset IFS
fi

exec tado-local $ARGS
Loading