Add HTTPS/SSL support and enhance connection handling
- Implemented HTTPS/SSL support for OpenClaw gateways in `lan_https` mode. - Added configuration options for SSL certificate verification. - Improved auto-discovery for `lan_https` access mode. - Updated documentation in README and changelog for new features and fixes. - Fixed connection errors related to SSL certificate verification.
This commit is contained in:
@@ -2,6 +2,18 @@
|
|||||||
|
|
||||||
All notable changes to the OpenClaw Home Assistant Integration will be documented in this file.
|
All notable changes to the OpenClaw Home Assistant Integration will be documented in this file.
|
||||||
|
|
||||||
|
## [0.1.52] - 2026-02-23
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Added HTTPS / SSL support for connecting to OpenClaw gateways running in `lan_https` mode or behind TLS reverse proxies.
|
||||||
|
- Auto-discovery now detects `access_mode: lan_https` and connects to the internal gateway port automatically (no certificate setup needed for local addons).
|
||||||
|
- Added `Verify SSL certificate` option in manual config for self-signed certificate environments.
|
||||||
|
- Added `ssl_error` config flow error with actionable guidance.
|
||||||
|
- Added comprehensive remote connection documentation to README with setup table for all access modes.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Fixed "400 Bad Request — plain HTTP request was sent to HTTPS port" when the addon uses `lan_https` access mode.
|
||||||
|
|
||||||
## [0.1.51] - 2026-02-23
|
## [0.1.51] - 2026-02-23
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
@@ -38,10 +38,68 @@ OpenClaw is a Home Assistant custom integration that connects your HA instance t
|
|||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
- Home Assistant Core `2025.1.0+` (declared minimum)
|
- Home Assistant Core `2025.1.0+` (declared minimum)
|
||||||
- Supervisor is optional (used for auto-discovery)
|
- An **OpenClaw gateway** with `enable_openai_api` enabled — either:
|
||||||
- OpenClaw Assistant addon installed and running
|
- The [OpenClaw Assistant addon](https://github.com/techartdev/OpenClawHomeAssistant) running on the same HA instance (auto-discovery supported), **or**
|
||||||
|
- Any standalone [OpenClaw](https://github.com/openclaw/openclaw) installation reachable over the network (manual config)
|
||||||
|
- Supervisor is optional (used only for addon auto-discovery)
|
||||||
|
|
||||||
The integration can auto-detect the addon when Supervisor is available. You can always configure host/port/token manually.
|
> **No addon required.** If you have OpenClaw running anywhere — on a separate server, a VPS, a Docker container, or even another machine on your LAN — this integration can connect to it via the manual configuration flow.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Connection modes
|
||||||
|
|
||||||
|
The integration supports connecting to OpenClaw in several ways:
|
||||||
|
|
||||||
|
### Local addon (auto-discovery)
|
||||||
|
|
||||||
|
If the OpenClaw Assistant addon is installed on the **same** Home Assistant instance, the integration auto-discovers it:
|
||||||
|
- Reads token from the shared filesystem
|
||||||
|
- Detects `access_mode` and chooses the correct port automatically
|
||||||
|
- No manual config needed — just click **Submit** on the confirm step
|
||||||
|
|
||||||
|
> **`lan_https` mode**: The integration automatically connects to the internal gateway port (plain HTTP on loopback), bypassing the HTTPS proxy entirely. No certificate setup required.
|
||||||
|
|
||||||
|
### Remote or standalone OpenClaw instance (manual config)
|
||||||
|
|
||||||
|
You can connect to **any reachable OpenClaw gateway** — whether it's the HA addon on another machine, a standalone `openclaw` install on a VPS, or a Docker container on your LAN. The integration doesn't care how OpenClaw is installed; it only needs the `/v1/chat/completions` endpoint.
|
||||||
|
|
||||||
|
**Prerequisites on the OpenClaw instance:**
|
||||||
|
|
||||||
|
1. The OpenAI-compatible API must be **enabled**:
|
||||||
|
- **Addon users**: Set `enable_openai_api: true` in addon settings
|
||||||
|
- **Standalone users**: Set `gateway.http.endpoints.chatCompletions.enabled: true` in `openclaw.json`, or run:
|
||||||
|
```sh
|
||||||
|
openclaw config set gateway.http.endpoints.chatCompletions.enabled true
|
||||||
|
```
|
||||||
|
2. The gateway must be **network-reachable** from your HA instance (not bound to loopback only)
|
||||||
|
3. You need the **gateway auth token**:
|
||||||
|
```sh
|
||||||
|
openclaw config get gateway.auth.token
|
||||||
|
```
|
||||||
|
|
||||||
|
**Setup steps:**
|
||||||
|
|
||||||
|
1. Go to **Settings → Devices & Services → Add Integration → OpenClaw**
|
||||||
|
2. Auto-discovery will fail (no local addon) — you'll see the **Manual Configuration** form
|
||||||
|
3. Fill in:
|
||||||
|
- **Gateway Host**: IP or hostname of the remote machine (e.g. `192.168.1.50`)
|
||||||
|
- **Gateway Port**: The gateway port (default `18789`)
|
||||||
|
- **Gateway Token**: Auth token from the remote `openclaw.json`
|
||||||
|
- **Use SSL (HTTPS)**: Check if connecting to an HTTPS endpoint
|
||||||
|
- **Verify SSL certificate**: Uncheck for self-signed certificates (e.g. `lan_https` mode)
|
||||||
|
|
||||||
|
### Common remote scenarios
|
||||||
|
|
||||||
|
| Remote access mode | Host | Port | Use SSL | Verify SSL | Notes |
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
| Standalone OpenClaw (plain HTTP on LAN) | Remote IP | 18789 | ❌ | — | Default `openclaw gateway run` config |
|
||||||
|
| `lan_https` (addon built-in HTTPS proxy) | Remote IP | 18789 | ✅ | ❌ | Self-signed cert; disable verification |
|
||||||
|
| Behind reverse proxy (NPM/Caddy with Let's Encrypt) | Domain or IP | 443 | ✅ | ✅ | Trusted cert from a real CA |
|
||||||
|
| Plain HTTP addon on LAN | Remote IP | 18789 | ❌ | — | Addon `bind_mode` must be `lan` |
|
||||||
|
| Tailscale | Tailscale IP | 18789 | ❌ | — | Encrypted tunnel; plain HTTP is fine |
|
||||||
|
|
||||||
|
> **Security note**: Avoid exposing plain HTTP gateways to the public internet. Use `lan_https`, a reverse proxy with TLS, or Tailscale for remote access.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -307,6 +365,12 @@ action:
|
|||||||
- Verify `openclaw_message_received` is being fired in Developer Tools → Events
|
- Verify `openclaw_message_received` is being fired in Developer Tools → Events
|
||||||
- Confirm session IDs match between card and service calls
|
- Confirm session IDs match between card and service calls
|
||||||
|
|
||||||
|
### "400 Bad Request — plain HTTP request was sent to HTTPS port"
|
||||||
|
|
||||||
|
- The gateway is running in `lan_https` mode (built-in HTTPS proxy)
|
||||||
|
- **Local addon**: Remove and re-add the integration — auto-discovery now detects `lan_https` and uses the correct internal port automatically
|
||||||
|
- **Remote connection**: Enable **Use SSL (HTTPS)** and disable **Verify SSL certificate** in the manual config
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Development notes
|
## Development notes
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ from .const import (
|
|||||||
CONF_GATEWAY_PORT,
|
CONF_GATEWAY_PORT,
|
||||||
CONF_GATEWAY_TOKEN,
|
CONF_GATEWAY_TOKEN,
|
||||||
CONF_USE_SSL,
|
CONF_USE_SSL,
|
||||||
|
CONF_VERIFY_SSL,
|
||||||
CONF_CONTEXT_MAX_CHARS,
|
CONF_CONTEXT_MAX_CHARS,
|
||||||
CONF_CONTEXT_STRATEGY,
|
CONF_CONTEXT_STRATEGY,
|
||||||
CONF_ENABLE_TOOL_CALLS,
|
CONF_ENABLE_TOOL_CALLS,
|
||||||
@@ -92,7 +93,7 @@ _CARD_PATH = Path(__file__).parent / "www" / _CARD_FILENAME
|
|||||||
# URL at which the card JS is served (registered via register_static_path)
|
# URL at which the card JS is served (registered via register_static_path)
|
||||||
_CARD_STATIC_URL = f"/openclaw/{_CARD_FILENAME}"
|
_CARD_STATIC_URL = f"/openclaw/{_CARD_FILENAME}"
|
||||||
# Versioned URL used for Lovelace resource registration to avoid stale browser cache
|
# Versioned URL used for Lovelace resource registration to avoid stale browser cache
|
||||||
_CARD_URL = f"{_CARD_STATIC_URL}?v=0.1.51"
|
_CARD_URL = f"{_CARD_STATIC_URL}?v=0.1.52"
|
||||||
|
|
||||||
OpenClawConfigEntry = ConfigEntry
|
OpenClawConfigEntry = ConfigEntry
|
||||||
|
|
||||||
@@ -130,13 +131,16 @@ async def async_setup_entry(hass: HomeAssistant, entry: OpenClawConfigEntry) ->
|
|||||||
|
|
||||||
Creates the API client, coordinator, and forwards setup to platforms.
|
Creates the API client, coordinator, and forwards setup to platforms.
|
||||||
"""
|
"""
|
||||||
session = async_get_clientsession(hass)
|
use_ssl = entry.data.get(CONF_USE_SSL, False)
|
||||||
|
verify_ssl = entry.data.get(CONF_VERIFY_SSL, True)
|
||||||
|
session = async_get_clientsession(hass, verify_ssl=verify_ssl)
|
||||||
|
|
||||||
client = OpenClawApiClient(
|
client = OpenClawApiClient(
|
||||||
host=entry.data[CONF_GATEWAY_HOST],
|
host=entry.data[CONF_GATEWAY_HOST],
|
||||||
port=entry.data[CONF_GATEWAY_PORT],
|
port=entry.data[CONF_GATEWAY_PORT],
|
||||||
token=entry.data[CONF_GATEWAY_TOKEN],
|
token=entry.data[CONF_GATEWAY_TOKEN],
|
||||||
use_ssl=entry.data.get(CONF_USE_SSL, False),
|
use_ssl=use_ssl,
|
||||||
|
verify_ssl=verify_ssl,
|
||||||
session=session,
|
session=session,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ class OpenClawApiClient:
|
|||||||
port: int,
|
port: int,
|
||||||
token: str,
|
token: str,
|
||||||
use_ssl: bool = False,
|
use_ssl: bool = False,
|
||||||
|
verify_ssl: bool = True,
|
||||||
session: aiohttp.ClientSession | None = None,
|
session: aiohttp.ClientSession | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize the API client.
|
"""Initialize the API client.
|
||||||
@@ -58,14 +59,19 @@ class OpenClawApiClient:
|
|||||||
port: Gateway port number.
|
port: Gateway port number.
|
||||||
token: Authentication token from openclaw.json.
|
token: Authentication token from openclaw.json.
|
||||||
use_ssl: Use HTTPS instead of HTTP.
|
use_ssl: Use HTTPS instead of HTTP.
|
||||||
|
verify_ssl: Verify SSL certificates (set False for self-signed certs).
|
||||||
session: Optional aiohttp session (reused from HA).
|
session: Optional aiohttp session (reused from HA).
|
||||||
"""
|
"""
|
||||||
self._host = host
|
self._host = host
|
||||||
self._port = port
|
self._port = port
|
||||||
self._token = token
|
self._token = token
|
||||||
self._use_ssl = use_ssl
|
self._use_ssl = use_ssl
|
||||||
|
self._verify_ssl = verify_ssl
|
||||||
self._session = session
|
self._session = session
|
||||||
self._base_url = f"{'https' if use_ssl else 'http'}://{host}:{port}"
|
self._base_url = f"{'https' if use_ssl else 'http'}://{host}:{port}"
|
||||||
|
# ssl=False disables cert verification for self-signed certs;
|
||||||
|
# ssl=None uses default verification.
|
||||||
|
self._ssl_param: bool | None = False if (use_ssl and not verify_ssl) else None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def base_url(self) -> str:
|
def base_url(self) -> str:
|
||||||
@@ -121,6 +127,7 @@ class OpenClawApiClient:
|
|||||||
url,
|
url,
|
||||||
headers=self._headers(),
|
headers=self._headers(),
|
||||||
timeout=timeout,
|
timeout=timeout,
|
||||||
|
ssl=self._ssl_param,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
) as resp:
|
) as resp:
|
||||||
if resp.status == 401:
|
if resp.status == 401:
|
||||||
@@ -146,6 +153,13 @@ class OpenClawApiClient:
|
|||||||
)
|
)
|
||||||
return await resp.json()
|
return await resp.json()
|
||||||
|
|
||||||
|
except aiohttp.ClientConnectorCertificateError as err:
|
||||||
|
raise OpenClawConnectionError(
|
||||||
|
f"SSL certificate verification failed for {url}. "
|
||||||
|
f"If using self-signed certificates (e.g. lan_https mode), "
|
||||||
|
f"disable 'Verify SSL certificate' in the integration config. "
|
||||||
|
f"Error: {err}"
|
||||||
|
) from err
|
||||||
except (aiohttp.ClientConnectorError, aiohttp.ClientOSError, asyncio.TimeoutError) as err:
|
except (aiohttp.ClientConnectorError, aiohttp.ClientOSError, asyncio.TimeoutError) as err:
|
||||||
raise OpenClawConnectionError(
|
raise OpenClawConnectionError(
|
||||||
f"Cannot connect to OpenClaw gateway at {url}: {err}"
|
f"Cannot connect to OpenClaw gateway at {url}: {err}"
|
||||||
@@ -213,6 +227,7 @@ class OpenClawApiClient:
|
|||||||
headers=headers,
|
headers=headers,
|
||||||
json=payload,
|
json=payload,
|
||||||
timeout=STREAM_TIMEOUT,
|
timeout=STREAM_TIMEOUT,
|
||||||
|
ssl=self._ssl_param,
|
||||||
) as resp:
|
) as resp:
|
||||||
if resp.status == 401:
|
if resp.status == 401:
|
||||||
raise OpenClawAuthError("Authentication failed")
|
raise OpenClawAuthError("Authentication failed")
|
||||||
@@ -274,6 +289,7 @@ class OpenClawApiClient:
|
|||||||
headers=headers,
|
headers=headers,
|
||||||
json=payload,
|
json=payload,
|
||||||
timeout=STREAM_TIMEOUT,
|
timeout=STREAM_TIMEOUT,
|
||||||
|
ssl=self._ssl_param,
|
||||||
) as resp:
|
) as resp:
|
||||||
if resp.status == 401:
|
if resp.status == 401:
|
||||||
raise OpenClawAuthError("Authentication failed")
|
raise OpenClawAuthError("Authentication failed")
|
||||||
@@ -338,6 +354,7 @@ class OpenClawApiClient:
|
|||||||
headers=self._headers(),
|
headers=self._headers(),
|
||||||
json={"messages": [], "stream": False},
|
json={"messages": [], "stream": False},
|
||||||
timeout=API_TIMEOUT,
|
timeout=API_TIMEOUT,
|
||||||
|
ssl=self._ssl_param,
|
||||||
) as resp:
|
) as resp:
|
||||||
if resp.status in (401, 403):
|
if resp.status in (401, 403):
|
||||||
raise OpenClawAuthError(
|
raise OpenClawAuthError(
|
||||||
@@ -381,6 +398,7 @@ class OpenClawApiClient:
|
|||||||
async with session.get(
|
async with session.get(
|
||||||
self._base_url,
|
self._base_url,
|
||||||
timeout=API_TIMEOUT,
|
timeout=API_TIMEOUT,
|
||||||
|
ssl=self._ssl_param,
|
||||||
) as resp:
|
) as resp:
|
||||||
return resp.status < 500
|
return resp.status < 500
|
||||||
except (aiohttp.ClientConnectorError, aiohttp.ClientOSError, asyncio.TimeoutError) as err:
|
except (aiohttp.ClientConnectorError, aiohttp.ClientOSError, asyncio.TimeoutError) as err:
|
||||||
@@ -424,6 +442,7 @@ class OpenClawApiClient:
|
|||||||
headers=headers,
|
headers=headers,
|
||||||
json=payload,
|
json=payload,
|
||||||
timeout=STREAM_TIMEOUT,
|
timeout=STREAM_TIMEOUT,
|
||||||
|
ssl=self._ssl_param,
|
||||||
) as resp:
|
) as resp:
|
||||||
if resp.status == 401:
|
if resp.status == 401:
|
||||||
raise OpenClawAuthError("Authentication failed")
|
raise OpenClawAuthError("Authentication failed")
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ from .const import (
|
|||||||
CONF_GATEWAY_PORT,
|
CONF_GATEWAY_PORT,
|
||||||
CONF_GATEWAY_TOKEN,
|
CONF_GATEWAY_TOKEN,
|
||||||
CONF_USE_SSL,
|
CONF_USE_SSL,
|
||||||
|
CONF_VERIFY_SSL,
|
||||||
CONF_CONTEXT_MAX_CHARS,
|
CONF_CONTEXT_MAX_CHARS,
|
||||||
CONF_CONTEXT_STRATEGY,
|
CONF_CONTEXT_STRATEGY,
|
||||||
CONF_ENABLE_TOOL_CALLS,
|
CONF_ENABLE_TOOL_CALLS,
|
||||||
@@ -233,11 +234,30 @@ async def _async_try_discover_addon(hass: HomeAssistant) -> dict[str, Any] | Non
|
|||||||
if port is None:
|
if port is None:
|
||||||
port = DEFAULT_GATEWAY_PORT
|
port = DEFAULT_GATEWAY_PORT
|
||||||
|
|
||||||
|
# Detect access mode — lan_https uses a built-in HTTPS reverse proxy.
|
||||||
|
# In that mode nginx terminates TLS on the external (user-facing) port
|
||||||
|
# and the gateway itself listens on port+1 on loopback (plain HTTP).
|
||||||
|
# Since HA and the addon share host_network, we connect to the internal
|
||||||
|
# port via loopback to avoid self-signed certificate issues entirely.
|
||||||
|
access_mode = addon_options.get("access_mode", "custom")
|
||||||
|
use_ssl = False
|
||||||
|
verify_ssl = True
|
||||||
|
|
||||||
|
if access_mode == "lan_https":
|
||||||
|
_LOGGER.info(
|
||||||
|
"Detected access_mode=lan_https — using internal gateway port %d "
|
||||||
|
"(external HTTPS proxy is on port %d)",
|
||||||
|
port + 1,
|
||||||
|
port,
|
||||||
|
)
|
||||||
|
port = port + 1
|
||||||
|
|
||||||
return {
|
return {
|
||||||
CONF_GATEWAY_HOST: DEFAULT_GATEWAY_HOST,
|
CONF_GATEWAY_HOST: DEFAULT_GATEWAY_HOST,
|
||||||
CONF_GATEWAY_PORT: port,
|
CONF_GATEWAY_PORT: port,
|
||||||
CONF_GATEWAY_TOKEN: token,
|
CONF_GATEWAY_TOKEN: token,
|
||||||
CONF_USE_SSL: False,
|
CONF_USE_SSL: use_ssl,
|
||||||
|
CONF_VERIFY_SSL: verify_ssl,
|
||||||
CONF_ADDON_CONFIG_PATH: str(config_dir),
|
CONF_ADDON_CONFIG_PATH: str(config_dir),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,14 +268,16 @@ async def _async_validate_connection(
|
|||||||
port: int,
|
port: int,
|
||||||
token: str,
|
token: str,
|
||||||
use_ssl: bool = False,
|
use_ssl: bool = False,
|
||||||
|
verify_ssl: bool = True,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""Validate that we can connect and authenticate to the gateway."""
|
"""Validate that we can connect and authenticate to the gateway."""
|
||||||
session = async_get_clientsession(hass)
|
session = async_get_clientsession(hass, verify_ssl=verify_ssl)
|
||||||
client = OpenClawApiClient(
|
client = OpenClawApiClient(
|
||||||
host=host,
|
host=host,
|
||||||
port=port,
|
port=port,
|
||||||
token=token,
|
token=token,
|
||||||
use_ssl=use_ssl,
|
use_ssl=use_ssl,
|
||||||
|
verify_ssl=verify_ssl,
|
||||||
session=session,
|
session=session,
|
||||||
)
|
)
|
||||||
return await client.async_check_connection()
|
return await client.async_check_connection()
|
||||||
@@ -312,6 +334,7 @@ class OpenClawConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||||||
self._discovered[CONF_GATEWAY_PORT],
|
self._discovered[CONF_GATEWAY_PORT],
|
||||||
self._discovered[CONF_GATEWAY_TOKEN],
|
self._discovered[CONF_GATEWAY_TOKEN],
|
||||||
self._discovered.get(CONF_USE_SSL, False),
|
self._discovered.get(CONF_USE_SSL, False),
|
||||||
|
self._discovered.get(CONF_VERIFY_SSL, True),
|
||||||
)
|
)
|
||||||
except OpenClawAuthError:
|
except OpenClawAuthError:
|
||||||
connected = False
|
connected = False
|
||||||
@@ -355,17 +378,23 @@ class OpenClawConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||||||
port = user_input[CONF_GATEWAY_PORT]
|
port = user_input[CONF_GATEWAY_PORT]
|
||||||
token = user_input[CONF_GATEWAY_TOKEN]
|
token = user_input[CONF_GATEWAY_TOKEN]
|
||||||
use_ssl = user_input.get(CONF_USE_SSL, False)
|
use_ssl = user_input.get(CONF_USE_SSL, False)
|
||||||
|
verify_ssl = user_input.get(CONF_VERIFY_SSL, True)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
connected = await _async_validate_connection(
|
connected = await _async_validate_connection(
|
||||||
self.hass, host, port, token, use_ssl
|
self.hass, host, port, token, use_ssl, verify_ssl
|
||||||
)
|
)
|
||||||
except OpenClawAuthError:
|
except OpenClawAuthError:
|
||||||
errors["base"] = "invalid_auth"
|
errors["base"] = "invalid_auth"
|
||||||
connected = False
|
connected = False
|
||||||
except OpenClawConnectionError:
|
except OpenClawConnectionError as err:
|
||||||
errors["base"] = "cannot_connect"
|
err_msg = str(err).lower()
|
||||||
|
if "ssl" in err_msg or "certificate" in err_msg:
|
||||||
|
errors["base"] = "ssl_error"
|
||||||
|
else:
|
||||||
|
errors["base"] = "cannot_connect"
|
||||||
connected = False
|
connected = False
|
||||||
|
_LOGGER.warning("Connection error during config check: %s", err)
|
||||||
except OpenClawApiError as err:
|
except OpenClawApiError as err:
|
||||||
errors["base"] = "openai_api_disabled"
|
errors["base"] = "openai_api_disabled"
|
||||||
connected = False
|
connected = False
|
||||||
@@ -379,6 +408,7 @@ class OpenClawConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||||||
CONF_GATEWAY_PORT: port,
|
CONF_GATEWAY_PORT: port,
|
||||||
CONF_GATEWAY_TOKEN: token,
|
CONF_GATEWAY_TOKEN: token,
|
||||||
CONF_USE_SSL: use_ssl,
|
CONF_USE_SSL: use_ssl,
|
||||||
|
CONF_VERIFY_SSL: verify_ssl,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if "base" not in errors:
|
if "base" not in errors:
|
||||||
@@ -396,6 +426,7 @@ class OpenClawConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||||||
): vol.All(int, vol.Range(min=1, max=65535)),
|
): vol.All(int, vol.Range(min=1, max=65535)),
|
||||||
vol.Required(CONF_GATEWAY_TOKEN): str,
|
vol.Required(CONF_GATEWAY_TOKEN): str,
|
||||||
vol.Optional(CONF_USE_SSL, default=False): bool,
|
vol.Optional(CONF_USE_SSL, default=False): bool,
|
||||||
|
vol.Optional(CONF_VERIFY_SSL, default=True): bool,
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
errors=errors,
|
errors=errors,
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ CONF_GATEWAY_HOST = "gateway_host"
|
|||||||
CONF_GATEWAY_PORT = "gateway_port"
|
CONF_GATEWAY_PORT = "gateway_port"
|
||||||
CONF_GATEWAY_TOKEN = "gateway_token"
|
CONF_GATEWAY_TOKEN = "gateway_token"
|
||||||
CONF_USE_SSL = "use_ssl"
|
CONF_USE_SSL = "use_ssl"
|
||||||
|
CONF_VERIFY_SSL = "verify_ssl"
|
||||||
CONF_ADDON_CONFIG_PATH = "addon_config_path"
|
CONF_ADDON_CONFIG_PATH = "addon_config_path"
|
||||||
|
|
||||||
# Options
|
# Options
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
"iot_class": "local_polling",
|
"iot_class": "local_polling",
|
||||||
"issue_tracker": "https://github.com/techartdev/OpenClawHomeAssistant/issues",
|
"issue_tracker": "https://github.com/techartdev/OpenClawHomeAssistant/issues",
|
||||||
"requirements": [],
|
"requirements": [],
|
||||||
"version": "0.1.51",
|
"version": "0.1.52",
|
||||||
"dependencies": ["conversation"],
|
"dependencies": ["conversation"],
|
||||||
"after_dependencies": ["hassio", "lovelace"]
|
"after_dependencies": ["hassio", "lovelace"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,14 +17,14 @@
|
|||||||
"gateway_host": "Gateway Host",
|
"gateway_host": "Gateway Host",
|
||||||
"gateway_port": "Gateway Port",
|
"gateway_port": "Gateway Port",
|
||||||
"gateway_token": "Gateway Token",
|
"gateway_token": "Gateway Token",
|
||||||
"use_ssl": "Use SSL (HTTPS)"
|
"use_ssl": "Use SSL (HTTPS)",
|
||||||
|
"verify_ssl": "Verify SSL certificate"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"cannot_connect": "Cannot connect to the OpenClaw gateway. Ensure the addon is running.",
|
"cannot_connect": "Cannot connect to the OpenClaw gateway. Ensure the addon is running.",
|
||||||
"invalid_auth": "Invalid gateway token. Check your OpenClaw configuration.",
|
"invalid_auth": "Invalid gateway token. Check your OpenClaw configuration.", "ssl_error": "SSL certificate verification failed. If using self-signed certificates (e.g. lan_https mode), uncheck 'Verify SSL certificate' or use automatic discovery.", "openai_api_disabled": "The gateway returned an unexpected response — the OpenAI-compatible API is likely disabled. In the OpenClaw addon settings enable 'enable_openai_api', restart the addon, and try again.",
|
||||||
"openai_api_disabled": "The gateway returned an unexpected response — the OpenAI-compatible API is likely disabled. In the OpenClaw addon settings enable 'enable_openai_api', restart the addon, and try again.",
|
|
||||||
"unknown": "An unexpected error occurred."
|
"unknown": "An unexpected error occurred."
|
||||||
},
|
},
|
||||||
"abort": {
|
"abort": {
|
||||||
|
|||||||
@@ -17,13 +17,15 @@
|
|||||||
"gateway_host": "Gateway Host",
|
"gateway_host": "Gateway Host",
|
||||||
"gateway_port": "Gateway Port",
|
"gateway_port": "Gateway Port",
|
||||||
"gateway_token": "Gateway Token",
|
"gateway_token": "Gateway Token",
|
||||||
"use_ssl": "Use SSL (HTTPS)"
|
"use_ssl": "Use SSL (HTTPS)",
|
||||||
|
"verify_ssl": "Verify SSL certificate"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"cannot_connect": "Cannot connect to the OpenClaw gateway. Ensure the addon is running.",
|
"cannot_connect": "Cannot connect to the OpenClaw gateway. Ensure the addon is running.",
|
||||||
"invalid_auth": "Invalid gateway token. Check your OpenClaw configuration.",
|
"invalid_auth": "Invalid gateway token. Check your OpenClaw configuration.",
|
||||||
|
"ssl_error": "SSL certificate verification failed. If using self-signed certificates (e.g. lan_https mode), uncheck 'Verify SSL certificate' or use automatic discovery.",
|
||||||
"openai_api_disabled": "The gateway returned an unexpected response — the OpenAI-compatible API is likely disabled. In the OpenClaw addon settings enable 'enable_openai_api', restart the addon, and try again.",
|
"openai_api_disabled": "The gateway returned an unexpected response — the OpenAI-compatible API is likely disabled. In the OpenClaw addon settings enable 'enable_openai_api', restart the addon, and try again.",
|
||||||
"unknown": "An unexpected error occurred."
|
"unknown": "An unexpected error occurred."
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
if (!customElements.get("openclaw-chat-card")) {
|
if (!customElements.get("openclaw-chat-card")) {
|
||||||
const src = "/openclaw/openclaw-chat-card.js?v=0.1.51";
|
const src = "/openclaw/openclaw-chat-card.js?v=0.1.52";
|
||||||
console.info("OpenClaw loader importing", src);
|
console.info("OpenClaw loader importing", src);
|
||||||
await import(src);
|
await import(src);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user