mirror of
https://github.com/techartdev/OpenClawHomeAssistant.git
synced 2026-08-14 08:52:15 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
57d0a588ac | ||
|
|
73646113ae | ||
|
|
8007c6e907 | ||
|
|
df94522752 | ||
|
|
a329088436 | ||
|
|
d64ed0666f | ||
|
|
e92947a3ac | ||
|
|
b057adfaad | ||
|
|
0a429df132 | ||
|
|
779433a66c | ||
|
|
ea9c70be5c | ||
|
|
6e8a64b15d | ||
|
|
378f419cf3 | ||
|
|
b2c9c17da5 | ||
|
|
cf892cd022 | ||
|
|
6b74131a54 | ||
|
|
f9c80534ea | ||
|
|
517a4fbbd7 | ||
|
|
65de88dc14 | ||
|
|
c3301c2445 | ||
|
|
c59417a180 | ||
|
|
9e4987d25f | ||
|
|
e6d6f62da6 | ||
|
|
5000cc94b1 | ||
|
|
9ff267ca45 | ||
|
|
71734b49f0 | ||
|
|
197a1692f5 | ||
|
|
d2251fb4d8 | ||
|
|
2dec26b243 |
@@ -153,14 +153,26 @@ This allows using the Control UI over LAN HTTP.
|
||||
This add-on keeps options minimal but practical. See `openclaw_assistant_dev/config.yaml` for the full schema.
|
||||
|
||||
### Gateway Network Settings
|
||||
Control how the OpenClaw gateway binds to the network:
|
||||
Control how the OpenClaw gateway operates and binds to the network:
|
||||
|
||||
- **`gateway_mode`** (string: **local** or **remote**, default **local**)
|
||||
- **local**: Run the gateway locally in this add-on (recommended for most users)
|
||||
- **remote**: Connect to a remote gateway running elsewhere
|
||||
- This setting determines whether OpenClaw runs its own gateway or connects to an existing one
|
||||
|
||||
- **`gateway_bind_mode`** (string: **loopback** or **lan**, default **loopback**)
|
||||
- **loopback**: Bind to 127.0.0.1 only — secure, local access only
|
||||
- **lan**: Bind to all interfaces — accessible from your local network
|
||||
- Only applies when `gateway_mode` is **local**
|
||||
|
||||
- **`gateway_port`** (int, default **18789**)
|
||||
- Port number for the gateway to listen on
|
||||
- Only applies when `gateway_mode` is **local**
|
||||
|
||||
- **`enable_openai_api`** (bool, default **false**)
|
||||
- Enable the OpenAI-compatible Chat Completions endpoint (`/v1/chat/completions`)
|
||||
- Required for integrating with HA Assist pipeline via [Extended OpenAI Conversation](https://github.com/jekalmin/extended_openai_conversation)
|
||||
- See section 6 for full setup instructions
|
||||
|
||||
- **`allow_insecure_auth`** (bool, default **false**)
|
||||
- Allow HTTP authentication for gateway access on LAN
|
||||
@@ -170,7 +182,13 @@ Control how the OpenClaw gateway binds to the network:
|
||||
These settings are applied automatically on add-on startup. No need to run `openclaw config` commands manually.
|
||||
|
||||
### Terminal
|
||||
- `enable_terminal` (bool, default **true**)
|
||||
- **`enable_terminal`** (bool, default **true**)
|
||||
- Enable or disable the web terminal button inside Home Assistant
|
||||
|
||||
- **`terminal_port`** (int, default **7681**)
|
||||
- Port number for the web terminal (ttyd) to listen on
|
||||
- Change this if port 7681 conflicts with another service on your system
|
||||
- Valid range: 1024-65535
|
||||
|
||||
Security note: the terminal gives shell access inside the add-on container.
|
||||
|
||||
@@ -196,8 +214,100 @@ How to provide the key:
|
||||
|
||||
---
|
||||
|
||||
## 6) Integrate with Home Assistant Assist Pipeline
|
||||
|
||||
OpenClaw's Gateway exposes an **OpenAI-compatible Chat Completions endpoint**. This means you can use OpenClaw as a **conversation agent** in Home Assistant's Assist pipeline — enabling voice control, automations, and smart home commands powered by OpenClaw.
|
||||
|
||||
### How it works
|
||||
|
||||
1. OpenClaw Gateway serves `POST /v1/chat/completions` (same port as the gateway)
|
||||
2. [Extended OpenAI Conversation](https://github.com/jekalmin/extended_openai_conversation) (HACS integration) connects HA's Assist pipeline to any OpenAI-compatible endpoint
|
||||
3. Both run on the same machine, so communication is via `127.0.0.1`
|
||||
|
||||
### Step 1 — Enable the OpenAI API endpoint
|
||||
|
||||
**Via add-on configuration (recommended)**:
|
||||
1. Go to Home Assistant → **Settings → Add-ons → OpenClaw Assistant → Configuration**
|
||||
2. Set `enable_openai_api`: **true**
|
||||
3. Restart the add-on
|
||||
|
||||
**Via terminal (manual)**:
|
||||
```sh
|
||||
openclaw config set gateway.http.endpoints.chatCompletions.enabled true
|
||||
```
|
||||
|
||||
### Step 2 — Install Extended OpenAI Conversation
|
||||
|
||||
1. Install [HACS](https://hacs.xyz/) if you haven't already
|
||||
2. In HACS, add **Extended OpenAI Conversation** as a custom repository:
|
||||
- Repository: `https://github.com/jekalmin/extended_openai_conversation`
|
||||
- Category: **Integration**
|
||||
3. Install it and restart Home Assistant
|
||||
|
||||
### Step 3 — Get your Gateway token
|
||||
|
||||
In the add-on terminal, run:
|
||||
|
||||
```sh
|
||||
openclaw config get gateway.auth.token
|
||||
```
|
||||
|
||||
Copy the token — you'll need it as the API key.
|
||||
|
||||
### Step 4 — Configure Extended OpenAI Conversation
|
||||
|
||||
1. Go to **Settings → Devices & Services → Add Integration**
|
||||
2. Search for **Extended OpenAI Conversation**
|
||||
3. Configure:
|
||||
- **API Key**: Paste your gateway token
|
||||
- **Base URL**: `http://127.0.0.1:18789/v1` or a LAN url if you use `gateway_bind_mode: lan`
|
||||
- **Api Version**: leave empty
|
||||
- **Organization**: leave empty
|
||||
- **Skip Authentication**: **true**
|
||||
|
||||
### Step 5 — Set as Conversation Agent
|
||||
|
||||
1. Go to **Settings → Voice Assistants**
|
||||
2. Edit your assistant (default: "Home Assistant")
|
||||
3. Under **Conversation agent**, select **Extended OpenAI Conversation**
|
||||
|
||||
### Step 6 — Expose entities
|
||||
|
||||
Expose the entities you want OpenClaw to control:
|
||||
- Go to `http://{your-ha}/config/voice-assistants/expose`
|
||||
- Toggle on the entities OpenClaw should be able to see and control
|
||||
|
||||
### Done!
|
||||
|
||||
You can now use Assist (voice or text) and OpenClaw will handle the conversation. It can:
|
||||
- Control your smart home devices
|
||||
- Answer questions using its skills
|
||||
- Create automations
|
||||
- Query entity history
|
||||
|
||||
**Tip**: If using LAN access (`gateway_bind_mode: lan`), other HA instances on your network can also connect to this endpoint.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Some skills fail to install (Homebrew errors)
|
||||
|
||||
If you see errors like:
|
||||
- `Homebrew's x86_64 support on Linux requires a CPU with SSSE3 support!`
|
||||
- `spawn brew ENOENT` or `brew: command not found`
|
||||
|
||||
**Cause**: Your CPU doesn't support SSSE3 instructions (required by Homebrew). This affects older CPUs like some Intel Atom, Celeron, or pre-2006 processors.
|
||||
|
||||
**Impact**: Skills that depend on CLI tools installed via Homebrew (e.g., `gemini`, `aider`) won't install. Core OpenClaw functionality still works.
|
||||
|
||||
**Solutions**:
|
||||
1. **Use a newer CPU** with SSSE3 support (Intel Core 2 or newer, ~2006+)
|
||||
2. **Install dependencies manually** if you know which tools are needed
|
||||
3. **Use alternative skills** that don't require Homebrew dependencies
|
||||
|
||||
The add-on will still start and work - Homebrew is optional.
|
||||
|
||||
### I get ERR_CONNECTION_REFUSED
|
||||
- The gateway is not reachable at that IP/port.
|
||||
- Confirm bind/port in terminal:
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# OpenClaw Assistant – Home Assistant Add-on
|
||||
|
||||

|
||||
|
||||
This repository contains a Home Assistant add-on that runs **OpenClaw** inside **Home Assistant OS (HAOS)**.
|
||||
|
||||
> Upstream rename history (FYI): clawdbot → moltbot → **openclaw** (final).
|
||||
@@ -42,6 +44,8 @@ So we **don’t embed** it. Instead, the Ingress page gives you a button that op
|
||||
- `openclaw configure`
|
||||
3. (Optional, but recommended) Set **gateway_public_url** in add-on options.
|
||||
- Then the Ingress page will show an "Open Gateway Web UI" button.
|
||||
|
||||
See **[DOCS.md](DOCS.md)** for a step-by-step first-time setup guide + troubleshooting.
|
||||
|
||||
## Add-on options (kept intentionally small)
|
||||
|
||||
@@ -53,10 +57,6 @@ See `openclaw_assistant/config.yaml` for the authoritative schema.
|
||||
- `homeassistant_token` (optional) — written to `/config/secrets/homeassistant.token` for local scripts.
|
||||
- `router_ssh_*` (optional) — SSH settings for a router/network device (custom automation).
|
||||
|
||||
## Docs
|
||||
|
||||
See **DOCS.md** for a step-by-step first-time setup guide + troubleshooting.
|
||||
|
||||
## Support / Donations
|
||||
|
||||
If you find this useful and you want to bring me a coffee to make more useful things, or support the project, use the link below:
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 65 KiB |
@@ -21,6 +21,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
nginx \
|
||||
gnupg \
|
||||
build-essential \
|
||||
sudo \
|
||||
vim \
|
||||
nano \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
@@ -40,9 +43,61 @@ RUN ARCH=$(echo ${TARGETARCH:-$(dpkg --print-architecture)} | sed 's|arm64|aarch
|
||||
|
||||
RUN node -v && npm -v
|
||||
|
||||
# Install pnpm globally (required by some OpenClaw skills like clawhub)
|
||||
RUN npm install -g pnpm && pnpm -v
|
||||
|
||||
# Install Chromium for website automation tasks
|
||||
# Includes necessary dependencies for headless browser operation
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
chromium \
|
||||
chromium-driver \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Homebrew (Linuxbrew) for OpenClaw skill dependencies
|
||||
# Homebrew is optional - some skills need CLI tools like gemini, aider, etc.
|
||||
# NOTE: Homebrew requires CPU with SSSE3 support (Intel Core 2 or newer, ~2006+)
|
||||
# If installation fails (e.g., older CPUs), the add-on will still work but some skills may not install
|
||||
ENV HOMEBREW_NO_AUTO_UPDATE=1 \
|
||||
HOMEBREW_NO_INSTALL_CLEANUP=1 \
|
||||
HOMEBREW_NO_ANALYTICS=1
|
||||
|
||||
RUN useradd -m -s /bin/bash linuxbrew \
|
||||
&& mkdir -p /home/linuxbrew/.linuxbrew \
|
||||
&& chown -R linuxbrew:linuxbrew /home/linuxbrew
|
||||
|
||||
USER linuxbrew
|
||||
RUN /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" || \
|
||||
(echo "WARNING: Homebrew installation failed (likely unsupported CPU - requires SSSE3). Some skills may not work." && exit 0)
|
||||
RUN if [ -d /home/linuxbrew/.linuxbrew/Homebrew ]; then \
|
||||
cd /home/linuxbrew/.linuxbrew/Homebrew && \
|
||||
git config --global --add safe.directory /home/linuxbrew/.linuxbrew/Homebrew && \
|
||||
/home/linuxbrew/.linuxbrew/bin/brew update --force || true; \
|
||||
fi
|
||||
USER root
|
||||
|
||||
# Add Homebrew to PATH for all users (wrapper comes first to intercept root calls)
|
||||
# PATH is set even if brew failed - wrapper will handle missing brew gracefully
|
||||
ENV PATH="/usr/local/bin:/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:${PATH}"
|
||||
|
||||
# Copy brew wrapper that allows root to run brew by delegating to linuxbrew user
|
||||
COPY brew-wrapper.sh /usr/local/bin/brew
|
||||
RUN chmod +x /usr/local/bin/brew
|
||||
|
||||
# Verify brew is available and install gcc (needed for compiling some brew packages)
|
||||
# Skip if brew installation failed
|
||||
USER linuxbrew
|
||||
RUN if [ -x /home/linuxbrew/.linuxbrew/bin/brew ]; then \
|
||||
/home/linuxbrew/.linuxbrew/bin/brew --version && \
|
||||
/home/linuxbrew/.linuxbrew/bin/brew install gcc || true; \
|
||||
else \
|
||||
echo "Skipping gcc installation - Homebrew not available"; \
|
||||
fi
|
||||
USER root
|
||||
|
||||
# Install OpenClaw globally
|
||||
RUN npm config set fund false && npm config set audit false \
|
||||
&& npm install -g openclaw@2026.1.30
|
||||
&& npm install -g openclaw@2026.2.6-3
|
||||
|
||||
COPY run.sh /run.sh
|
||||
COPY oc_config_helper.py /oc_config_helper.py
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
# Wrapper script for brew that runs as linuxbrew user when called by root
|
||||
# This is needed because Homebrew refuses to run as root
|
||||
|
||||
REAL_BREW="/home/linuxbrew/.linuxbrew/bin/brew"
|
||||
|
||||
# Check if Homebrew is actually installed
|
||||
if [ ! -x "$REAL_BREW" ]; then
|
||||
echo "ERROR: Homebrew is not installed (likely due to unsupported CPU - requires SSSE3)." >&2
|
||||
echo "Some OpenClaw skills that depend on CLI tools (gemini, aider, etc.) will not work." >&2
|
||||
echo "Consider using a newer CPU or installing dependencies manually." >&2
|
||||
exit 127
|
||||
fi
|
||||
|
||||
if [ "$(id -u)" = "0" ]; then
|
||||
# Running as root - use sudo to run as linuxbrew user
|
||||
# Preserve necessary environment variables and properly pass all arguments
|
||||
exec sudo -u linuxbrew \
|
||||
HOMEBREW_NO_AUTO_UPDATE="${HOMEBREW_NO_AUTO_UPDATE:-1}" \
|
||||
HOMEBREW_NO_ANALYTICS="${HOMEBREW_NO_ANALYTICS:-1}" \
|
||||
HOME="/home/linuxbrew" \
|
||||
PATH="/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:$PATH" \
|
||||
"$REAL_BREW" "$@"
|
||||
else
|
||||
# Not root - run directly
|
||||
exec "$REAL_BREW" "$@"
|
||||
fi
|
||||
@@ -1,5 +1,5 @@
|
||||
name: OpenClaw Assistant
|
||||
version: "0.5.28"
|
||||
version: "0.5.37"
|
||||
slug: openclaw_assistant
|
||||
description: Run OpenClaw Assistant (OpenClaw-compatible) as a Home Assistant add-on.
|
||||
url: https://github.com/techartdev/OpenClawHomeAssistant
|
||||
@@ -28,6 +28,9 @@ options:
|
||||
# Enable web terminal inside Home Assistant (Ingress) via ttyd
|
||||
enable_terminal: true
|
||||
|
||||
# Terminal port (change if 7681 conflicts with another service)
|
||||
terminal_port: 7681
|
||||
|
||||
# Public base URL for opening the Gateway Web UI in a new tab (not embedded).
|
||||
# Recommended: NO trailing slash.
|
||||
# Example: "https://example.duckdns.org:12345" or "http://192.168.1.10:18789"
|
||||
@@ -47,6 +50,12 @@ options:
|
||||
clean_session_locks_on_start: true
|
||||
clean_session_locks_on_exit: true
|
||||
|
||||
# Gateway mode:
|
||||
# - local: Run gateway locally (recommended for most users)
|
||||
# - remote: Connect to a remote gateway
|
||||
# Default is local.
|
||||
gateway_mode: local
|
||||
|
||||
# Gateway network bind mode:
|
||||
# - loopback: bind to 127.0.0.1 only (local access only, more secure)
|
||||
# - lan: bind to all interfaces (accessible from local network)
|
||||
@@ -56,6 +65,11 @@ options:
|
||||
# Gateway port to listen on
|
||||
gateway_port: 18789
|
||||
|
||||
# Enable OpenAI-compatible Chat Completions API endpoint
|
||||
# When enabled, OpenClaw can be used as a conversation agent in HA Assist pipeline
|
||||
# via Extended OpenAI Conversation (HACS) or any OpenAI-compatible client
|
||||
enable_openai_api: false
|
||||
|
||||
# Allow insecure HTTP authentication (required for HTTP gateway access on LAN)
|
||||
# WARNING: Only enable if you're using HTTP (not HTTPS) for gateway_public_url
|
||||
# Default is false for security.
|
||||
@@ -65,6 +79,7 @@ options:
|
||||
schema:
|
||||
timezone: str
|
||||
enable_terminal: bool?
|
||||
terminal_port: int(1024,65535)?
|
||||
gateway_public_url: str?
|
||||
homeassistant_token: str?
|
||||
|
||||
@@ -74,7 +89,9 @@ schema:
|
||||
|
||||
clean_session_locks_on_start: bool?
|
||||
clean_session_locks_on_exit: bool?
|
||||
gateway_mode: list(local|remote)?
|
||||
gateway_bind_mode: list(loopback|lan)?
|
||||
gateway_port: int(1,65535)?
|
||||
enable_openai_api: bool?
|
||||
allow_insecure_auth: bool?
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ http {
|
||||
# Proxy everything under /terminal/ (including websocket /terminal/ws)
|
||||
location ^~ /terminal/ {
|
||||
# IMPORTANT: no trailing slash in proxy_pass so nginx preserves the full URI
|
||||
proxy_pass http://127.0.0.1:7681;
|
||||
proxy_pass http://127.0.0.1:__TERMINAL_PORT__;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
|
||||
@@ -57,15 +57,22 @@ def set_gateway_setting(key, value):
|
||||
return write_config(cfg)
|
||||
|
||||
|
||||
def apply_gateway_settings(bind_mode: str, port: int, allow_insecure_auth: bool):
|
||||
def apply_gateway_settings(mode: str, bind_mode: str, port: int, enable_openai_api: bool, allow_insecure_auth: bool):
|
||||
"""
|
||||
Apply gateway settings to OpenClaw config.
|
||||
|
||||
Args:
|
||||
mode: "local" or "remote"
|
||||
bind_mode: "loopback" or "lan"
|
||||
port: Port number to listen on (must be 1-65535)
|
||||
enable_openai_api: Enable OpenAI-compatible Chat Completions endpoint
|
||||
allow_insecure_auth: Allow insecure HTTP authentication
|
||||
"""
|
||||
# Validate gateway mode
|
||||
if mode not in ["local", "remote"]:
|
||||
print(f"ERROR: Invalid mode '{mode}'. Must be 'local' or 'remote'")
|
||||
return False
|
||||
|
||||
# Validate bind mode
|
||||
if bind_mode not in ["loopback", "lan"]:
|
||||
print(f"ERROR: Invalid bind_mode '{bind_mode}'. Must be 'loopback' or 'lan'")
|
||||
@@ -89,14 +96,29 @@ def apply_gateway_settings(bind_mode: str, port: int, allow_insecure_auth: bool)
|
||||
if "controlUi" not in gateway:
|
||||
gateway["controlUi"] = {}
|
||||
|
||||
control_ui = gateway["controlUi"]
|
||||
# http.endpoints.chatCompletions should be nested inside gateway
|
||||
if "http" not in gateway:
|
||||
gateway["http"] = {}
|
||||
if "endpoints" not in gateway["http"]:
|
||||
gateway["http"]["endpoints"] = {}
|
||||
if "chatCompletions" not in gateway["http"]["endpoints"]:
|
||||
gateway["http"]["endpoints"]["chatCompletions"] = {}
|
||||
|
||||
control_ui = gateway["controlUi"]
|
||||
chat_completions = gateway["http"]["endpoints"]["chatCompletions"]
|
||||
|
||||
current_mode = gateway.get("mode", "")
|
||||
current_bind = gateway.get("bind", "")
|
||||
current_port = gateway.get("port", 18789)
|
||||
current_openai_api = chat_completions.get("enabled", False)
|
||||
current_insecure = control_ui.get("allowInsecureAuth", False)
|
||||
|
||||
changes = []
|
||||
|
||||
if current_mode != mode:
|
||||
gateway["mode"] = mode
|
||||
changes.append(f"mode: {current_mode} -> {mode}")
|
||||
|
||||
if current_bind != bind_mode:
|
||||
gateway["bind"] = bind_mode
|
||||
changes.append(f"bind: {current_bind} -> {bind_mode}")
|
||||
@@ -105,6 +127,10 @@ def apply_gateway_settings(bind_mode: str, port: int, allow_insecure_auth: bool)
|
||||
gateway["port"] = port
|
||||
changes.append(f"port: {current_port} -> {port}")
|
||||
|
||||
if current_openai_api != enable_openai_api:
|
||||
chat_completions["enabled"] = enable_openai_api
|
||||
changes.append(f"chatCompletions.enabled: {current_openai_api} -> {enable_openai_api}")
|
||||
|
||||
if current_insecure != allow_insecure_auth:
|
||||
control_ui["allowInsecureAuth"] = allow_insecure_auth
|
||||
changes.append(f"allowInsecureAuth: {current_insecure} -> {allow_insecure_auth}")
|
||||
@@ -117,7 +143,7 @@ def apply_gateway_settings(bind_mode: str, port: int, allow_insecure_auth: bool)
|
||||
print("ERROR: Failed to write config")
|
||||
return False
|
||||
else:
|
||||
print(f"INFO: Gateway settings already correct (bind={bind_mode}, port={port}, allowInsecureAuth={allow_insecure_auth})")
|
||||
print(f"INFO: Gateway settings already correct (mode={mode}, bind={bind_mode}, port={port}, chatCompletions={enable_openai_api}, allowInsecureAuth={allow_insecure_auth})")
|
||||
return True
|
||||
|
||||
|
||||
@@ -130,13 +156,15 @@ def main():
|
||||
cmd = sys.argv[1]
|
||||
|
||||
if cmd == "apply-gateway-settings":
|
||||
if len(sys.argv) != 5:
|
||||
print("Usage: oc_config_helper.py apply-gateway-settings <loopback|lan> <port> <true|false>")
|
||||
if len(sys.argv) != 7:
|
||||
print("Usage: oc_config_helper.py apply-gateway-settings <local|remote> <loopback|lan> <port> <enable_openai_api:true|false> <allow_insecure:true|false>")
|
||||
sys.exit(1)
|
||||
bind_mode = sys.argv[2]
|
||||
port = int(sys.argv[3])
|
||||
allow_insecure_auth = sys.argv[4].lower() == "true"
|
||||
success = apply_gateway_settings(bind_mode, port, allow_insecure_auth)
|
||||
mode = sys.argv[2]
|
||||
bind_mode = sys.argv[3]
|
||||
port = int(sys.argv[4])
|
||||
enable_openai_api = sys.argv[5].lower() == "true"
|
||||
allow_insecure_auth = sys.argv[6].lower() == "true"
|
||||
success = apply_gateway_settings(mode, bind_mode, port, enable_openai_api, allow_insecure_auth)
|
||||
sys.exit(0 if success else 1)
|
||||
|
||||
elif cmd == "get":
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Ensure Homebrew and brew-installed binaries are in PATH
|
||||
# This is needed for OpenClaw skills that depend on CLI tools (gemini, aider, etc.)
|
||||
export PATH="/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:${PATH}"
|
||||
|
||||
# Home Assistant add-on options are usually rendered to /data/options.json
|
||||
OPTIONS_FILE="/data/options.json"
|
||||
|
||||
@@ -17,6 +21,19 @@ TZNAME=$(jq -r '.timezone // "Europe/Sofia"' "$OPTIONS_FILE")
|
||||
GW_PUBLIC_URL=$(jq -r '.gateway_public_url // empty' "$OPTIONS_FILE")
|
||||
HA_TOKEN=$(jq -r '.homeassistant_token // empty' "$OPTIONS_FILE")
|
||||
ENABLE_TERMINAL=$(jq -r '.enable_terminal // true' "$OPTIONS_FILE")
|
||||
TERMINAL_PORT_RAW=$(jq -r '.terminal_port // 7681' "$OPTIONS_FILE")
|
||||
|
||||
# SECURITY: Validate TERMINAL_PORT to prevent nginx config injection
|
||||
# Only allow numeric values in valid port range (1024-65535)
|
||||
if [[ "$TERMINAL_PORT_RAW" =~ ^[0-9]+$ ]] && [ "$TERMINAL_PORT_RAW" -ge 1024 ] && [ "$TERMINAL_PORT_RAW" -le 65535 ]; then
|
||||
TERMINAL_PORT="$TERMINAL_PORT_RAW"
|
||||
else
|
||||
echo "ERROR: Invalid terminal_port '$TERMINAL_PORT_RAW'. Must be numeric 1024-65535. Using default 7681."
|
||||
TERMINAL_PORT="7681"
|
||||
fi
|
||||
|
||||
echo "DEBUG: enable_terminal config value: '$ENABLE_TERMINAL'"
|
||||
echo "DEBUG: terminal_port config value: '$TERMINAL_PORT' (validated)"
|
||||
|
||||
# Generic router SSH settings
|
||||
ROUTER_HOST=$(jq -r '.router_ssh_host // empty' "$OPTIONS_FILE")
|
||||
@@ -27,9 +44,11 @@ ROUTER_KEY=$(jq -r '.router_ssh_key_path // "/data/keys/router_ssh"' "$OPTIONS_F
|
||||
CLEAN_LOCKS_ON_START=$(jq -r '.clean_session_locks_on_start // true' "$OPTIONS_FILE")
|
||||
CLEAN_LOCKS_ON_EXIT=$(jq -r '.clean_session_locks_on_exit // true' "$OPTIONS_FILE")
|
||||
|
||||
# Gateway bind mode (loopback or lan)
|
||||
# Gateway configuration
|
||||
GATEWAY_MODE=$(jq -r '.gateway_mode // "local"' "$OPTIONS_FILE")
|
||||
GATEWAY_BIND_MODE=$(jq -r '.gateway_bind_mode // "loopback"' "$OPTIONS_FILE")
|
||||
GATEWAY_PORT=$(jq -r '.gateway_port // 18789' "$OPTIONS_FILE")
|
||||
ENABLE_OPENAI_API=$(jq -r '.enable_openai_api // false' "$OPTIONS_FILE")
|
||||
ALLOW_INSECURE_AUTH=$(jq -r '.allow_insecure_auth // false' "$OPTIONS_FILE")
|
||||
|
||||
export TZ="$TZNAME"
|
||||
@@ -39,6 +58,13 @@ set +x
|
||||
|
||||
# HA add-ons mount persistent storage at /config (maps to /addon_configs/<slug> on the host).
|
||||
export HOME=/config
|
||||
|
||||
# Explicitly set OpenClaw directories to ensure they persist across add-on updates
|
||||
# This prevents loss of installed skills, configuration, and workspace state
|
||||
export OPENCLAW_CONFIG_DIR=/config/.openclaw
|
||||
export OPENCLAW_WORKSPACE_DIR=/config/clawd
|
||||
export XDG_CONFIG_HOME=/config
|
||||
|
||||
mkdir -p /config/.openclaw /config/clawd /config/keys /config/secrets
|
||||
|
||||
# Back-compat: some docs/scripts assume /data; point it at /config.
|
||||
@@ -181,6 +207,11 @@ cfg = {
|
||||
"mode": "token",
|
||||
"token": secrets.token_urlsafe(24)
|
||||
}
|
||||
},
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"workspace": "/config/clawd"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,7 +234,7 @@ fi
|
||||
|
||||
if [ -f "$OPENCLAW_CONFIG_PATH" ]; then
|
||||
if [ -f "$HELPER_PATH" ]; then
|
||||
if ! python3 "$HELPER_PATH" apply-gateway-settings "$GATEWAY_BIND_MODE" "$GATEWAY_PORT" "$ALLOW_INSECURE_AUTH"; then
|
||||
if ! python3 "$HELPER_PATH" apply-gateway-settings "$GATEWAY_MODE" "$GATEWAY_BIND_MODE" "$GATEWAY_PORT" "$ENABLE_OPENAI_API" "$ALLOW_INSECURE_AUTH"; then
|
||||
rc=$?
|
||||
echo "ERROR: Failed to apply gateway settings via oc_config_helper.py (exit code ${rc})."
|
||||
echo "ERROR: Gateway configuration may be incorrect; aborting startup."
|
||||
@@ -223,12 +254,29 @@ openclaw gateway run &
|
||||
GW_PID=$!
|
||||
|
||||
# Start web terminal (optional)
|
||||
if [ "$ENABLE_TERMINAL" = "true" ]; then
|
||||
echo "Starting web terminal (ttyd) on 127.0.0.1:7681 ..."
|
||||
ttyd -W -i 127.0.0.1 -p 7681 -b /terminal bash &
|
||||
TTYD_PID_FILE="/var/run/openclaw-ttyd.pid"
|
||||
|
||||
# Clean up stale ttyd process from previous run using PID file
|
||||
if [ -f "$TTYD_PID_FILE" ]; then
|
||||
OLD_PID=$(cat "$TTYD_PID_FILE" 2>/dev/null || echo "")
|
||||
if [ -n "$OLD_PID" ] && kill -0 "$OLD_PID" 2>/dev/null; then
|
||||
echo "Stopping previous ttyd process (PID $OLD_PID)..."
|
||||
kill "$OLD_PID" 2>/dev/null || true
|
||||
sleep 1
|
||||
# Force kill if still running
|
||||
kill -9 "$OLD_PID" 2>/dev/null || true
|
||||
fi
|
||||
rm -f "$TTYD_PID_FILE"
|
||||
fi
|
||||
|
||||
if [ "$ENABLE_TERMINAL" = "true" ] || [ "$ENABLE_TERMINAL" = "1" ]; then
|
||||
echo "Starting web terminal (ttyd) on 127.0.0.1:${TERMINAL_PORT} ..."
|
||||
ttyd -W -i 127.0.0.1 -p "${TERMINAL_PORT}" -b /terminal bash &
|
||||
TTYD_PID=$!
|
||||
echo "$TTYD_PID" > "$TTYD_PID_FILE"
|
||||
echo "ttyd started with PID $TTYD_PID"
|
||||
else
|
||||
echo "Terminal disabled (enable_terminal=false)"
|
||||
echo "Terminal disabled (enable_terminal=$ENABLE_TERMINAL)"
|
||||
fi
|
||||
|
||||
# Start ingress reverse proxy (nginx). This provides the add-on UI inside HA.
|
||||
@@ -238,20 +286,22 @@ fi
|
||||
# The gateway token is NOT managed by the add-on; OpenClaw will generate/store it.
|
||||
# Best-effort: query it via CLI (works even if openclaw.json is JSON5). If unknown, we hide the button.
|
||||
GW_TOKEN="$(timeout 2s openclaw config get gateway.auth.token 2>/dev/null | tr -d '\n' || true)"
|
||||
GW_PUBLIC_URL="$GW_PUBLIC_URL" GW_TOKEN="$GW_TOKEN" python3 - <<'PY'
|
||||
GW_PUBLIC_URL="$GW_PUBLIC_URL" GW_TOKEN="$GW_TOKEN" TERMINAL_PORT="$TERMINAL_PORT" python3 - <<'PY'
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
tpl = Path('/etc/nginx/nginx.conf.tpl').read_text()
|
||||
landing_tpl = Path('/etc/nginx/landing.html.tpl').read_text()
|
||||
public_url = os.environ.get('GW_PUBLIC_URL','')
|
||||
terminal_port = os.environ.get('TERMINAL_PORT', '7681')
|
||||
|
||||
# Token comes from environment (best-effort CLI query in run.sh)
|
||||
token = os.environ.get('GW_TOKEN','')
|
||||
|
||||
gw_path = '' if public_url.endswith('/') else '/'
|
||||
|
||||
conf = tpl
|
||||
# Replace terminal port placeholder in nginx config
|
||||
conf = tpl.replace('__TERMINAL_PORT__', terminal_port)
|
||||
Path('/etc/nginx/nginx.conf').write_text(conf)
|
||||
|
||||
landing = landing_tpl.replace('__GATEWAY_TOKEN__', token)
|
||||
|
||||
@@ -7,6 +7,10 @@ configuration:
|
||||
name: Активиране на уеб терминал
|
||||
description: Активиране на уеб терминал бутона в Home Assistant (Ingress) чрез ttyd
|
||||
|
||||
terminal_port:
|
||||
name: Порт на терминал
|
||||
description: Номер на порт за уеб терминала (по подразбиране - 7681). Променете, ако този порт е в конфликт с друга услуга.
|
||||
|
||||
gateway_public_url:
|
||||
name: Публичен URL на Gateway
|
||||
description: Публичен базов URL за отваряне на Gateway уеб интерфейса в нов таб (не вграден). Пример - https://example.duckdns.org:12345 или http://192.168.1.10:18789
|
||||
@@ -35,6 +39,10 @@ configuration:
|
||||
name: Изчистване на заключвания при изход
|
||||
description: Изчистване на заключващи файлове на сесии при нормално спиране на добавката
|
||||
|
||||
gateway_mode:
|
||||
name: Режим на Gateway
|
||||
description: Режим на работа на Gateway - local (локално изпълнение на gateway, препоръчително) или remote (свързване към отдалечен gateway)
|
||||
|
||||
gateway_bind_mode:
|
||||
name: Режим на свързване на Gateway
|
||||
description: Режим на мрежово свързване - loopback (само 127.0.0.1, по-сигурно) или lan (всички интерфейси, достъпно от локалната мрежа)
|
||||
@@ -43,6 +51,10 @@ configuration:
|
||||
name: Порт на Gateway
|
||||
description: Номер на порт, на който OpenClaw gateway да слуша (по подразбиране - 18789)
|
||||
|
||||
enable_openai_api:
|
||||
name: Активиране на OpenAI API
|
||||
description: Активиране на OpenAI-съвместим Chat Completions ендпойнт. Позволява използването на OpenClaw като разговорен агент в HA Assist pipeline чрез Extended OpenAI Conversation (HACS) или всеки OpenAI-съвместим клиент.
|
||||
|
||||
allow_insecure_auth:
|
||||
name: Разрешаване на HTTP автентикация
|
||||
description: Разрешаване на HTTP автентикация за достъп до gateway в локалната мрежа. ВНИМАНИЕ - Активирайте само ако използвате HTTP (не HTTPS) за gateway_public_url. Необходимо за достъп от браузър през HTTP.
|
||||
|
||||
@@ -7,6 +7,10 @@ configuration:
|
||||
name: Web-Terminal aktivieren
|
||||
description: Web-Terminal-Schaltfläche in Home Assistant (Ingress) über ttyd aktivieren
|
||||
|
||||
terminal_port:
|
||||
name: Terminal-Port
|
||||
description: Portnummer für das Web-Terminal (Standard - 7681). Ändern Sie diese, wenn dieser Port mit einem anderen Dienst in Konflikt steht.
|
||||
|
||||
gateway_public_url:
|
||||
name: Öffentliche Gateway-URL
|
||||
description: Öffentliche Basis-URL zum Öffnen der Gateway-Weboberfläche in einem neuen Tab (nicht eingebettet). Beispiel - https://example.duckdns.org:12345 oder http://192.168.1.10:18789
|
||||
@@ -35,6 +39,10 @@ configuration:
|
||||
name: Sitzungssperren beim Beenden bereinigen
|
||||
description: Sitzungssperrdateien beim ordnungsgemäßen Stoppen des Add-ons bereinigen
|
||||
|
||||
gateway_mode:
|
||||
name: Gateway-Modus
|
||||
description: Gateway-Betriebsmodus - local (Gateway lokal ausführen, empfohlen) oder remote (mit einem entfernten Gateway verbinden)
|
||||
|
||||
gateway_bind_mode:
|
||||
name: Gateway-Bindungsmodus
|
||||
description: Netzwerk-Bindungsmodus - loopback (nur 127.0.0.1, sicherer) oder lan (alle Schnittstellen, vom lokalen Netzwerk aus zugänglich)
|
||||
@@ -43,6 +51,10 @@ configuration:
|
||||
name: Gateway-Port
|
||||
description: Portnummer, auf der das OpenClaw-Gateway lauscht (Standard - 18789)
|
||||
|
||||
enable_openai_api:
|
||||
name: OpenAI API aktivieren
|
||||
description: OpenAI-kompatiblen Chat Completions Endpunkt aktivieren. Ermöglicht die Verwendung von OpenClaw als Gesprächsagent in der HA Assist Pipeline über Extended OpenAI Conversation (HACS) oder jeden OpenAI-kompatiblen Client.
|
||||
|
||||
allow_insecure_auth:
|
||||
name: Unsichere HTTP-Authentifizierung erlauben
|
||||
description: HTTP-Authentifizierung für Gateway-Zugriff im LAN erlauben. WARNUNG - Nur aktivieren, wenn HTTP (nicht HTTPS) für gateway_public_url verwendet wird. Erforderlich für Browser-Zugriff über HTTP.
|
||||
|
||||
@@ -7,6 +7,10 @@ configuration:
|
||||
name: Enable Web Terminal
|
||||
description: Enable web terminal Button inside Home Assistant (Ingress) via ttyd
|
||||
|
||||
terminal_port:
|
||||
name: Terminal Port
|
||||
description: Port number for the web terminal (default - 7681). Change if this port conflicts with another service.
|
||||
|
||||
gateway_public_url:
|
||||
name: Gateway Public URL
|
||||
description: Public base URL for opening the Gateway Web UI in a new tab (not embedded). Example - https://example.duckdns.org:12345 or http://192.168.1.10:18789
|
||||
@@ -35,6 +39,10 @@ configuration:
|
||||
name: Clean Session Locks on Exit
|
||||
description: Cleanup session lock files when add-on stops gracefully
|
||||
|
||||
gateway_mode:
|
||||
name: Gateway Mode
|
||||
description: Gateway operation mode - local (run gateway locally, recommended) or remote (connect to a remote gateway)
|
||||
|
||||
gateway_bind_mode:
|
||||
name: Gateway Bind Mode
|
||||
description: Network bind mode - loopback (127.0.0.1 only, more secure) or lan (all interfaces, accessible from local network)
|
||||
@@ -43,6 +51,10 @@ configuration:
|
||||
name: Gateway Port
|
||||
description: Port number for the OpenClaw gateway to listen on (default - 18789)
|
||||
|
||||
enable_openai_api:
|
||||
name: Enable OpenAI API
|
||||
description: Enable OpenAI-compatible Chat Completions endpoint. Allows using OpenClaw as a conversation agent in HA Assist pipeline via Extended OpenAI Conversation (HACS) or any OpenAI-compatible client.
|
||||
|
||||
allow_insecure_auth:
|
||||
name: Allow Insecure HTTP Auth
|
||||
description: Allow HTTP authentication for gateway access on LAN. WARNING - Only enable if using HTTP (not HTTPS) for gateway_public_url. Required for browser access over HTTP.
|
||||
|
||||
@@ -7,6 +7,10 @@ configuration:
|
||||
name: Activar terminal web
|
||||
description: Activar botón de terminal web dentro de Home Assistant (Ingress) mediante ttyd
|
||||
|
||||
terminal_port:
|
||||
name: Puerto del terminal
|
||||
description: Número de puerto para el terminal web (predeterminado - 7681). Cambie si este puerto entra en conflicto con otro servicio.
|
||||
|
||||
gateway_public_url:
|
||||
name: URL pública del Gateway
|
||||
description: URL base pública para abrir la interfaz web del Gateway en una nueva pestaña (no integrada). Ejemplo - https://example.duckdns.org:12345 o http://192.168.1.10:18789
|
||||
@@ -35,6 +39,10 @@ configuration:
|
||||
name: Limpiar bloqueos de sesión al salir
|
||||
description: Limpiar archivos de bloqueo de sesión cuando el complemento se detiene correctamente
|
||||
|
||||
gateway_mode:
|
||||
name: Modo del Gateway
|
||||
description: Modo de operación del Gateway - local (ejecutar gateway localmente, recomendado) o remote (conectar a un gateway remoto)
|
||||
|
||||
gateway_bind_mode:
|
||||
name: Modo de enlace del Gateway
|
||||
description: Modo de enlace de red - loopback (solo 127.0.0.1, más seguro) o lan (todas las interfaces, accesible desde la red local)
|
||||
@@ -43,6 +51,10 @@ configuration:
|
||||
name: Puerto del Gateway
|
||||
description: Número de puerto en el que el gateway de OpenClaw escuchará (predeterminado - 18789)
|
||||
|
||||
enable_openai_api:
|
||||
name: Activar API OpenAI
|
||||
description: Activar endpoint de Chat Completions compatible con OpenAI. Permite usar OpenClaw como agente de conversación en HA Assist pipeline mediante Extended OpenAI Conversation (HACS) o cualquier cliente compatible con OpenAI.
|
||||
|
||||
allow_insecure_auth:
|
||||
name: Permitir autenticación HTTP insegura
|
||||
description: Permitir autenticación HTTP para acceso al gateway en LAN. ADVERTENCIA - Solo habilitar si usa HTTP (no HTTPS) para gateway_public_url. Requerido para acceso desde navegador por HTTP.
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
configuration:
|
||||
timezone:
|
||||
name: Strefa czasowa
|
||||
description: Strefa czasowa dla dodatku (np. Europe/Warsaw, America/New_York)
|
||||
|
||||
enable_terminal:
|
||||
name: Włącz terminal webowy
|
||||
description: Włącz przycisk terminala webowego w Home Assistant (Ingress) przez ttyd
|
||||
|
||||
terminal_port:
|
||||
name: Port terminala
|
||||
description: Numer portu dla terminala webowego (domyślnie - 7681). Zmień jeśli ten port koliduje z inną usługą.
|
||||
|
||||
gateway_public_url:
|
||||
name: Publiczny URL Gateway
|
||||
description: Publiczny bazowy URL do otwierania Web UI Gateway w nowej karcie (nie osadzone). Przykład - https://example.duckdns.org:12345 lub http://192.168.1.10:18789
|
||||
|
||||
homeassistant_token:
|
||||
name: Token Home Assistant
|
||||
description: Opcjonalnie - długoterminowy token Home Assistant dla lokalnych skryptów/narzędzi API HA
|
||||
|
||||
router_ssh_host:
|
||||
name: Host SSH routera
|
||||
description: Opcjonalnie - nazwa hosta SSH routera/firewalla lub adres IP
|
||||
|
||||
router_ssh_user:
|
||||
name: Użytkownik SSH routera
|
||||
description: Opcjonalnie - nazwa użytkownika SSH routera/firewalla
|
||||
|
||||
router_ssh_key_path:
|
||||
name: Ścieżka klucza SSH routera
|
||||
description: Ścieżka do klucza prywatnego SSH dla dostępu do routera (domyślnie - /data/keys/router_ssh)
|
||||
|
||||
clean_session_locks_on_start:
|
||||
name: Wyczyść blokady sesji przy starcie
|
||||
description: Usuń przestarzałe pliki blokad sesji pozostawione po awariach/restartach gdy dodatek się uruchamia
|
||||
|
||||
clean_session_locks_on_exit:
|
||||
name: Wyczyść blokady sesji przy wyjściu
|
||||
description: Usuń pliki blokad sesji gdy dodatek zatrzymuje się poprawnie
|
||||
|
||||
gateway_bind_mode:
|
||||
name: Tryb bindowania Gateway
|
||||
description: Tryb bindowania sieci - loopback (tylko 127.0.0.1, bardziej bezpieczny) lub lan (wszystkie interfejsy, dostępny z sieci lokalnej)
|
||||
|
||||
gateway_port:
|
||||
name: Port Gateway
|
||||
description: Numer portu na którym gateway OpenClaw będzie nasłuchiwał (domyślnie - 18789)
|
||||
|
||||
enable_openai_api:
|
||||
name: Włącz API OpenAI
|
||||
description: Włącz endpoint Chat Completions kompatybilny z OpenAI. Pozwala używać OpenClaw jako agenta konwersacji w HA Assist pipeline przez Extended OpenAI Conversation (HACS) lub dowolnego klienta kompatybilnego z OpenAI.
|
||||
|
||||
allow_insecure_auth:
|
||||
name: Zezwól na niezabezpieczone uwierzytelnianie HTTP
|
||||
description: Zezwól na uwierzytelnianie HTTP dla dostępu do gateway w sieci LAN. UWAGA - Włącz tylko jeśli używasz HTTP (nie HTTPS) dla gateway_public_url. Wymagane dla dostępu przez przeglądarkę przez HTTP.
|
||||
|
||||
gateway_mode:
|
||||
name: Tryb Gateway
|
||||
description: Tryb działania gateway - local (uruchom gateway lokalnie, zalecane) lub remote (połącz się ze zdalnym gateway)
|
||||
Reference in New Issue
Block a user