{"id":"f3c71918-c8f8-45eb-8a72-2a3b04d9b0e1","entityType":"agent","slug":"clawhub-vincsta-home-assistant-hub","name":"Home Assistant Hub","canonicalUrl":"https://www.xpersona.co/agent/clawhub-vincsta-home-assistant-hub","canonicalPath":"/agent/clawhub-vincsta-home-assistant-hub","generatedAt":"2026-10-10T10:53:13.204Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T06:02:38.802Z","emptyReason":null},"description":"Real-time Home Assistant monitoring, alert rules, TTS voice notifications on Echo devices, Telegram delivery, entity inspection. Service calls are HARD-DENIE...","descriptionLabel":"Source description","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.6K downloads reported by the source. Last updated 10/10/2026.","installCommand":"clawhub skill install s170wrqqnm5nbbk85av1t8vdx1855dyb:home-assistant-hub","sourceUrl":"https://clawhub.ai/vincsta/home-assistant-hub","homepage":"https://clawhub.ai/vincsta/skills/home-assistant-hub","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/vincsta/home-assistant-hub","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/vincsta/skills/home-assistant-hub","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":64,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Home Assistant Hub technical dossier on Xpersona with agent coverage, OPENCLEW support, and live trust metadata."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-10T06:02:38.802Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T06:02:38.802Z","emptyReason":null},"stars":null,"forks":null,"downloads":1633,"packageName":null,"latestVersion":"1.5.1","tractionLabel":"1.6K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T06:02:38.801Z","emptyReason":null},"lastUpdatedAt":"2026-10-10T06:02:38.802Z","lastCrawledAt":"2026-10-10T06:02:38.801Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-11T06:02:38.801Z","lastVerifiedAt":null,"highlights":[{"version":"1.5.1","createdAt":"2026-07-11T20:24:28.974Z","changelog":"home-assistant-hub v1.5.1 - Removed the skill-card.md file for streamlined documentation. - Updated internal documentation (SKILL.md) for improved clarity. - No functional or breaking changes to core scripts or service behavior.","fileCount":12,"zipByteSize":28586},{"version":"1.5.0","createdAt":"2026-07-11T19:58:29.403Z","changelog":"## 1.5.0 changelog - Service call security model reworked: all service calls are now blocked by default; only explicitly listed \"safe domains\" are allowed via `call_safe_domains` in config. - Several dangerous domains (`lock.*`, `alarm_control_panel.*`, `cover.*`) are permanently blocked—cannot be enabled. - Adds documented dry-run mode for service calls to safely preview actions before execution. - Updated documentation reflecting new security posture, configuration, and usage details. - Removed obsolete `skill-card.md` file.","fileCount":12,"zipByteSize":28616},{"version":"1.4.0","createdAt":"2026-07-11T18:38:40.401Z","changelog":"**1.4.0 is a security-focused hardening update with safer device control and stricter credential usage.** - Added a service call allowlist: only explicitly allowed domains in `call_allowlist` can be controlled (e.g., `lock`, `cover`, `alarm_control_panel` now blocked by default). - Removed all hardcoded credential fallbacks; Telegram delivery now refuses to send with missing credentials and warns instead of silently defaulting. - Updated process documentation and permissions: local HTTP API is now disabled by default and must be enabled explicitly in config. - All dangerous device actions now require explicit user confirmation or allowlist override, preventing accidental or unauthorized execution. - Removed obsolete or duplicate documentation (`skill-card.md`).","fileCount":12,"zipByteSize":27791},{"version":"1.3.0","createdAt":"2026-07-11T16:56:01.359Z","changelog":"Major security overhaul: comprehensive warnings for device control/external transmission, aligned SKILL.md+README.md descriptions, removed hardcoded paths, ported scripts to portable SCRIPT_DIR","fileCount":12,"zipByteSize":27134},{"version":"1.2.5","createdAt":"2026-07-11T16:37:43.252Z","changelog":"Remove hardcoded user path from start.sh and daemon.sh (portable SCRIPT_DIR)","fileCount":12,"zipByteSize":24058},{"version":"1.2.4","createdAt":"2026-07-11T16:35:05.667Z","changelog":"Fix 13 SkillSpector findings + remove sensitive config from publication","fileCount":12,"zipByteSize":23910},{"version":"1.2.3","createdAt":"2026-07-11T16:32:05.376Z","changelog":"Fix 13 SkillSpector findings: add permissions metadata (network+secrets), device control safety warnings, scope alignment, Telegram external data warning","fileCount":13,"zipByteSize":24557},{"version":"1.2.2","createdAt":"2026-07-11T16:07:33.260Z","changelog":"**Major update: Adds Parla entity TTS support, overhaul of Echo TTS usage and docs.** - Supports new Parla entities for sending simultaneous TTS to Echo devices (via Home Assistant notify.send_message). - Documentation rewritten for clarity around TTS delivery: now uses comma-separated Parla entity IDs instead of device IDs or JSON arrays. - Added daemon.sh, improved configuration with hub.json, and consolidated notification output locations. - Removed legacy device ID announce instructions in favor of Parla-based Echo TTS—see updated SKILL.md for new usage and troubleshooting. - Overall structure and startup scripts improved; skill-card.md removed as redundant. - Example configs and troubleshooting steps updated to match new TTS/notification flow.","fileCount":13,"zipByteSize":23600}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s170wrqqnm5nbbk85av1t8vdx1855dyb:home-assistant-hub","setupComplexity":"low","setupSteps":["Install using `clawhub skill install s170wrqqnm5nbbk85av1t8vdx1855dyb:home-assistant-hub` in an isolated environment before connecting it to live workloads.","No published capability contract is available yet, so validate auth and request/response behavior manually.","Review the upstream CLAWHUB listing at https://clawhub.ai/vincsta/home-assistant-hub before using production credentials."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-vincsta-home-assistant-hub/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-vincsta-home-assistant-hub/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-vincsta-home-assistant-hub/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-vincsta-home-assistant-hub/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-vincsta-home-assistant-hub/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-vincsta-home-assistant-hub/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-10T10:53:13.201Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-vincsta-home-assistant-hub/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-vincsta-home-assistant-hub/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-vincsta-home-assistant-hub/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-vincsta-home-assistant-hub/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T06:02:38.802Z","emptyReason":null},"readme":"Skill: Home Assistant Hub\n\nOwner: vincsta\n\nSummary: Real-time Home Assistant monitoring, alert rules, TTS voice notifications on Echo devices, Telegram delivery, entity inspection. Service calls are HARD-DENIE...\n\nTags: automation:1.2.1, echo:1.2.1, home-assistant:1.2.1, latest:1.5.1, telegram:1.2.1, tts:1.2.1\n\nVersion history:\n\nv1.5.1 | 2026-07-11T20:24:28.974Z | auto\n\nhome-assistant-hub v1.5.1\n\n- Removed the skill-card.md file for streamlined documentation.\n- Updated internal documentation (SKILL.md) for improved clarity.\n- No functional or breaking changes to core scripts or service behavior.\n\nv1.5.0 | 2026-07-11T19:58:29.403Z | auto\n\n## 1.5.0 changelog\n\n- Service call security model reworked: all service calls are now blocked by default; only explicitly listed \"safe domains\" are allowed via `call_safe_domains` in config.\n- Several dangerous domains (`lock.*`, `alarm_control_panel.*`, `cover.*`) are permanently blocked—cannot be enabled.\n- Adds documented dry-run mode for service calls to safely preview actions before execution.\n- Updated documentation reflecting new security posture, configuration, and usage details.\n- Removed obsolete `skill-card.md` file.\n\nv1.4.0 | 2026-07-11T18:38:40.401Z | auto\n\n**1.4.0 is a security-focused hardening update with safer device control and stricter credential usage.**\n\n- Added a service call allowlist: only explicitly allowed domains in `call_allowlist` can be controlled (e.g., `lock`, `cover`, `alarm_control_panel` now blocked by default).\n- Removed all hardcoded credential fallbacks; Telegram delivery now refuses to send with missing credentials and warns instead of silently defaulting.\n- Updated process documentation and permissions: local HTTP API is now disabled by default and must be enabled explicitly in config.\n- All dangerous device actions now require explicit user confirmation or allowlist override, preventing accidental or unauthorized execution.\n- Removed obsolete or duplicate documentation (`skill-card.md`).\n\nv1.3.0 | 2026-07-11T16:56:01.359Z | user\n\nMajor security overhaul: comprehensive warnings for device control/external transmission, aligned SKILL.md+README.md descriptions, removed hardcoded paths, ported scripts to portable SCRIPT_DIR\n\nv1.2.5 | 2026-07-11T16:37:43.252Z | user\n\nRemove hardcoded user path from start.sh and daemon.sh (portable SCRIPT_DIR)\n\nv1.2.4 | 2026-07-11T16:35:05.667Z | user\n\nFix 13 SkillSpector findings + remove sensitive config from publication\n\nv1.2.3 | 2026-07-11T16:32:05.376Z | user\n\nFix 13 SkillSpector findings: add permissions metadata (network+secrets), device control safety warnings, scope alignment, Telegram external data warning\n\nv1.2.2 | 2026-07-11T16:07:33.260Z | auto\n\n**Major update: Adds Parla entity TTS support, overhaul of Echo TTS usage and docs.**\n\n- Supports new Parla entities for sending simultaneous TTS to Echo devices (via Home Assistant notify.send_message).\n- Documentation rewritten for clarity around TTS delivery: now uses comma-separated Parla entity IDs instead of device IDs or JSON arrays.\n- Added daemon.sh, improved configuration with hub.json, and consolidated notification output locations.\n- Removed legacy device ID announce instructions in favor of Parla-based Echo TTS—see updated SKILL.md for new usage and troubleshooting.\n- Overall structure and startup scripts improved; skill-card.md removed as redundant.\n- Example configs and troubleshooting steps updated to match new TTS/notification flow.\n\nv1.2.1 | 2026-07-04T21:05:21.132Z | user\n\nAdded explicit privacy and security warnings in docs. SKILL.md now includes notice about external data transmission (Telegram/Echo). Setup guide warns about bearer token security.\\n\\nNo code changes — documentation only.\n\nv1.2.0 | 2026-07-04T20:41:59.837Z | user\n\nAdded TTS voice notifications on Echo devices, centralized config via hub.json, Telegram deliverer with TTS support, quiet hours configuration, echo_devices config section, bugfix for /call_service payload passing.\\n\\nSecurity: All secrets moved to config/hub.json (gitignored). Template config provided as hub.example.json.\n\nArchive index:\n\nArchive v1.5.1: 12 files, 28586 bytes\n\nFiles: _meta.json (137b), config/hub.example.json (631b), daemon.sh (484b), notifications/test-1783363352.json (202b), README.md (14209b), references/setup.md (3542b), scripts/ha-cmd.js (10488b), scripts/ha-hub.js (20266b), scripts/telegram-deliver.js (9232b), skill-card.md (2630b), SKILL.md (16808b), start.sh (334b)\n\nFile v1.5.1:SKILL.md\n\n---\nname: \"home-assistant-hub\"\ndescription: \"Real-time Home Assistant monitoring, alert rules, TTS voice notifications on Echo devices, Telegram delivery, entity inspection. Service calls are HARD-DENIED by default — require explicit safe-domains opt-in.\"\nhomepage: https://github.com/openclaw/openclaw\nmetadata:\n  {\n    \"openclaw\":\n      {\n        \"emoji\": \"🏡\",\n        \"requires\": { \"bins\": [\"node\"] },\n        \"permissions\": [\n          { \"kind\": \"network\", \"direction\": \"outbound\", \"targets\": [\"Home Assistant API/WebSocket (HTTP + WSS)\", \"Telegram Bot API (HTTPS)\", \"Echo devices via HA notify service\"], \"reason\": \"Real-time monitoring of home device states, alert delivery to Telegram servers, and voice announcements on Echo devices require outbound network connections\" },\n          { \"kind\": \"network\", \"direction\": \"local-bind\", \"targets\": [\"localhost:9123 (on-demand API)\"], \"reason\": \"Local HTTP API for ha-cmd.js service calls when configured. Disabled by default.\" },\n          { \"kind\": \"secrets\", \"direction\": \"local-read\", \"targets\": [\"config/hub.json\"], \"reason\": \"Reads HA long-lived bearer token, Telegram bot token, and chat ID. File is gitignored — never commit to version control\" }\n        ]\n      },\n  }\n---\n\n# ⚠️ SECURITY & PRIVACY WARNINGS — READ FIRST\n\n## 🔴 Device Control — Hardened Defaults\nThis skill can invoke Home Assistant services to change physical device states. **Service calls are disabled by default.**\n\n### ⛔ Always Blocked (never configurable)\nThe following domains are HARD-LOCKED in code and cannot be enabled:\n- `lock.*` — door locks (physical security)\n- `alarm_control_panel.*` — alarm systems (safety-critical)\n- `cover.*` — blinds/doors/garage (privacy/security)\n\n### ✅ Safe Domains — Explicit Opt-In Required\nService calls require domains to be listed in `call_safe_domains` in `config/hub.json`. **An empty list means all service calls are blocked.**\n\nDefault safe domains in the example config: `light`, `climate`, `scene`, `media_player`, `automation`, `notify`\n\nTo add a new domain, edit hub.json:\n```json\n\"call_safe_domains\": [\"light\", \"climate\", \"scene\", \"media_player\", \"automation\", \"notify\"]\n```\n\n### 🔍 Dry-Run Mode\nBefore executing any service call, use `--dry-run` to preview what would happen:\n```bash\nnode scripts/ha-cmd.js call climate.set_temperature entity_id=climate.hvac temperature=22 --dry-run\n# Output: Service URL + payload WITHOUT executing\n\n\n## 📡 External Data Transmission\nThis skill transmits data to third-party services:\n- **Telegram Bot API** — alert messages including occupancy, sensor states, routines → exposes household patterns and security-relevant information\n- **Echo devices via HA** — TTS announcements broadcast inside the home environment\n- **Home Assistant instance** — all device telemetry sent over network\n\n**Do NOT include sensitive personal data in alert templates.** Notification content is visible on Telegram accounts and potentially logged by Telegram servers.\n\n### 🚫 No Hardcoded Credentials\nAll credentials are loaded exclusively from `config/hub.json`. There are no hardcoded fallback tokens anywhere in the codebase. If `telegram_bot_token` or `telegram_chat_id` are missing, the deliverer will refuse to send (with a warning) rather than fall back to defaults.\n\n## 🔐 Credential Sensitivity\nAll secrets (`ha_token`, `telegram_bot_token`, `telegram_chat_id`) are stored in `config/hub.json`. This file is gitignored but:\n- The HA token is a **long-lived bearer token** with broad API access — treat it like a password\n- Default `ha_url` uses plain HTTP → credentials transmitted in cleartext on the local network. Use HTTPS if possible.\n- Rotate tokens regularly via HA → Profile → Long-Lived Access Tokens\n\n## 🔧 Process Management\nThe hub runs as background processes (`nohup`, `disown`) that persist beyond your session. `pkill -f \"ha-hub.js start\"` can match multiple processes. Always verify process state before killing.\n\n---\n\n# Home Assistant Hub\n\nReal-time monitoring of Home Assistant device states with configurable alert rules, TTS voice notifications on Echo devices via Parla entities, Telegram delivery for alerts and events, entity inspection (states, history, persons, areas), and controlled device management through direct service calls.\n\n## Architecture Overview\n\n```\n┌───────────┐    HTTP/WS     ┌───────────────┐   JSON file   ┌─────────────────┐\n│ Home      │ ◄──────────►  │  ha-hub.js    │ ───────────►  │ telegram-deliver│\n│ Assistant │  polling or   │  background    │               │  background     │\n│           │   WebSocket   │  monitoring   │               │  notification   │\n└───────────┘               └───────────────┘               │  delivery       │\n                                                            └────────┬────────┘\n                                                                       │ HTTPS\n                                                                 ┌─────▼──────┐\n                                                                 │ Telegram API│\n                                                                 └────────────┘\n\n┌───────────┐    HTTP          ┌───────────────┐\n│ ha-cmd.js │ ───────────────►  │ Home Assistant│   (on-demand, direct)\n│ (CLI/API) │                   │ WebSocket     │\n└───────────┘                   └───────────────┘\n```\n\n**Two background processes:**\n| Process | Role | Frequency |\n|---------|------|-----------|\n| `ha-hub.js` | Connected to HA, monitors device states against alert rules | Polls every 10s (WS fallback) |\n| `telegram-deliver.js` | Reads pending notification files and sends via Telegram | Checks every 30s |\n\n## Permissions\n\n| Permission | Direction | Targets | Reason |\n|-----------|-----------|---------|---------|\n| `network` | outbound | Home Assistant API/WebSocket (HTTP+WSS), Telegram Bot API (HTTPS), Echo devices via HA notify | Real-time home monitoring, alert delivery to third-party servers, voice announcements |\n| `network` | local-bind | localhost:9123 (on-demand HTTP API) — **disabled by default** | Local service for ha-cmd.js when enabled in config |\n| `secrets` | local-read | `config/hub.json` | HA long-lived bearer token + Telegram credentials. File is gitignored — never commit |\n\n## Quick Start\n\n```bash\ncd skills/home-assistant-hub\n\n# Test connection to HA (safe, read-only)\nnode scripts/ha-cmd.js info\n\n# List entities containing \"echo\" or \"parla\" (safe, read-only)\nnode scripts/ha-cmd.js state list 2>&1 | grep -i echo\n\n# Start the monitoring hub (background process)\nnode scripts/ha-hub.js start\n\n# Check hub status\nnode scripts/ha-hub.js status\n\n# Stop the hub\nnode scripts/ha-hub.js stop\n```\n\n## 📋 Safe Commands (Read-Only / Display)\n\nThese commands only **read** data from Home Assistant. No device state changes:\n\n| Command | What it does | Data exposed |\n|---------|-------------|-------------|\n| `node scripts/ha-cmd.js info` | HA version, URL, OS, connected clients | System metadata |\n| `node scripts/ha-cmd.js state` | All entity states at once | Full home telemetry snapshot |\n| `node scripts/ha-cmd.js state get <id>` | Single entity state (e.g., `sensor.battery_level`) | One sensor value |\n| `node scripts/ha-cmd.js state list <domain>` | Filter entities by domain (`light`, `binary_sensor`, etc.) | Domain-level inventory |\n| `node scripts/ha-cmd.js scenes` | List all defined scenes | Scene configuration |\n| `node scripts/ha-cmd.js persons` | List persons + presence states | Occupancy data — who is home |\n| `node scripts/ha-cmd.js areas` | Areas with device counts | Home layout and device inventory |\n\n## 🗣️ Voice Notifications (TTS)\n\nSends voice announcements to Echo devices via HA Parla entities. **This produces audible output in your physical environment.**\n\nUse **comma-separated entity IDs** — do NOT pass a JSON array:\n\n```bash\n# Send to ALL configured Echo devices simultaneously\nnode scripts/ha-cmd.js call notify.send_message \\\n  entity_id=\"notify.echo_show_5_parla,notify.echo_pop_di_vincenzo_parla\" \\\n  message=\"Ciao Vincenzo, la batteria è al 75 percento\"\n\n# Single device\nnode scripts/ha-cmd.js call notify.send_message \\\n  entity_id=\"notify.echo_show_5_parla\" \\\n  message=\"La cena è pronta\"\n```\n\n**Find Parla entity IDs:** `node scripts/ha-cmd.js state list 2>&1 | grep -i parla`\n\n### Troubleshooting TTS\n- **\"400 Bad Request\"** → wrong format. Use comma-separated string, not array.\n- **\"Success\" but no audio** → verify: (1) Parla entities exist in HA, (2) an automation listens for `notify.send_message`, (3) Echo devices are online/unmuted.\n- **Verify delivery:** check timestamp updated: `node scripts/ha-cmd.js state get notify.echo_show_5_parla | grep last_updated`\n\n## 📋 Alert Rules\n\nConfigurable rules that detect device state changes and trigger notifications via Telegram or voice announcements.\n\n### Add rule interactively\n```bash\nnode scripts/ha-hub.js add-rule\n```\n\n### Add rules via JSON (stdin)\n```bash\nnode scripts/ha-hub.js add-rules << 'EOF'\n[\n  {\n    \"name\": \"Garage aperto\",\n    \"entity_id\": \"binary_sensor.garage_door\",\n    \"condition\": \"state\",\n    \"value\": \"on\",\n    \"cooldown\": 300,\n    \"title\": \"Garage\",\n    \"template\": \"Il garage è aperto!\"\n  },\n  {\n    \"name\": \"Batteria bassa\",\n    \"entity_id\": \"sensor.battery_level\",\n    \"condition\": \"below\",\n    \"value\": \"20\",\n    \"cooldown\": 600,\n    \"title\": \"🪫 Batteria\",\n    \"template\": \"Batteria al {{state}}% — serve attenzione\"\n  }\n]\nEOF\n```\n\n### List rules\n```bash\nnode scripts/ha-hub.js rules\n```\n\n### Rule conditions\n\n| Condition | Meaning | Example value |\n|-----------|---------|-------------|\n| `state` | State equals value | `on`, `home`, `open` |\n| `not_state` | State not equals value | `away` |\n| `above` | Numeric state above threshold | `25` |\n| `below` | Numeric state below threshold | `10` |\n| `changed` | Always trigger on any change | — |\n\n## 📱 Telegram Integration\n\nAlerts are delivered to a Telegram chat when configured. **⚠️ Data is transmitted externally to Telegram servers.** Alert content includes entity states, occupancy information, and home status. Avoid including sensitive personal data in alert templates.\n\n```bash\nnode scripts/telegram-deliver.js start   # Start delivery process\nnode scripts/telegram-deliver.js status  # Check delivery status\nnode scripts/telegram-deliver.js stop    # Stop delivery process\n```\n\nTelegram settings in `config/hub.json`:\n```json\n\"telegram_bot_token\": \"your_bot_token\",\n\"telegram_chat_id\": \"your_chat_id\",\n\"notification_channel\": \"telegram\"   // or: \"both\" (Telegram + Echo)\n```\n\n### Notification flow\n1. HA device state changes (e.g., battery drops to 19%)\n2. `ha-hub.js` detects change against active alert rules\n3. Matching rule writes a JSON file to `notifications/` directory\n4. `telegram-deliver.js` picks up the new file and sends to Telegram\n5. File is moved to `delivered/` on successful delivery\n\n## 🔧 On-Demand Commands (`ha-cmd.js`)\n\nAll commands run from the skill directory:\n```bash\ncd skills/home-assistant-hub\n```\n\n### Safe (read-only / display) commands:\n\n| Command | Description |\n|---------|-------------|\n| `node scripts/ha-cmd.js info` | HA version, URL, OS |\n| `node scripts/ha-cmd.js state` | All entity states |\n| `node scripts/ha-cmd.js state get <id>` | Specific entity (e.g., sensor.battery) |\n| `node scripts/ha-cmd.js state list <domain>` | Filter by domain (light, binary_sensor...) |\n| `node scripts/ha-cmd.js scenes` | List all defined scenes |\n| `node scripts/ha-cmd.js persons` | List persons + presence states |\n| `node scripts/ha-cmd.js areas` | Areas with device counts |\n\n### ⚠️ Control commands (state-changing) — DISABLED BY DEFAULT:\n\nService calls require explicit domain opt-in in `config/hub.json` via `call_safe_domains`. **No service is callable unless its domain is listed there.** Dangerous domains (`lock`, `alarm_control_panel`, `cover`) are hard-locked and cannot be enabled.\n\n| Command | Description |\n|---------|-------------|\n| `node scripts/ha-cmd.js call <service> [key=value ...] --dry-run` | Preview what would be called (no execution) |\n| `node scripts/ha-cmd.js call <service> [key=value ...]` | Execute service — **only if domain is in call_safe_domains** |\n\n#### Examples (understand the impact before running):\n\n```bash\n# TTS announcement on Echo devices\nnode scripts/ha-cmd.js call notify.send_message \\\n  entity_id=\"notify.echo_show_5_parla\" message=\"Prova vocale\"\n\n# Turn on a light — changes physical environment\nnode scripts/ha-cmd.js call light.turn_on entity_id=light.living_room\n\n# Set thermostat temperature — affects comfort\nnode scripts/ha-cmd.js call climate.set_temperature \\\n  entity_id=climate.hvac temperature=22\n\n# Activate a scene (multi-device action)\nnode scripts/ha-cmd.js call scene.turn_on entity_id=scene.movie_time\n\n# Trigger an automation\nnode scripts/ha-cmd.js call automation.trigger entity_id=automation.my_automation\n```\n\n## 🔑 Hub Config (`config/hub.json`)\n\nUse `hub.example.json` as a template:\n\n```bash\ncp config/hub.example.json config/hub.json\n# Edit hub.json with your credentials — NEVER commit this file!\n```\n\n```json\n{\n  \"ha_url\": \"http://homeassistant.local:8123\",       // use https:// if available\n  \"ha_token\": \"your-long-lived-token\",               // treat as password\n  \"poll_interval\": 10,                                // seconds between polls\n  \"rules\": [...],                                     // alert rules (see above)\n  \"notification_channel\": \"telegram\",                 // or: \"both\"\n  \"quiet_hours\": {                                    // suppress alerts during sleep\n    \"enabled\": true,\n    \"start\": \"22:30\",\n    \"end\": \"08:30\"\n  },\n  \"on_demand\": {                                      // local API port for ha-cmd.js (disabled by default)\n    \"enabled\": false,\n    \"port\": 9123\n  },\n  \"call_safe_domains\": [\"light\", \"climate\", \"scene\", \"media_player\", \"automation\", \"notify\"]\n  \"telegram_bot_token\": \"...\",\n  \"telegram_chat_id\": \"...\",\n  \"echo_devices\": {\n    \"all_devices_announce_id\": \"\",                    // legacy: Alexa announce group (unused)\n    \"echo_pop_device_id\": \"notify.echo_pop_di_vincenzo_parla\",\n    \"echo_show_device_id\": \"notify.echo_show_5_parla\"\n  }\n}\n```\n\n## 🔕 Quiet Hours\n\nSuppress alerts during sleep in `config/hub.json`:\n\n```json\n\"quiet_hours\": {\n  \"enabled\": true,\n  \"start\": \"22:00\",\n  \"end\": \"08:00\"\n}\n```\n\nRules during quiet hours are silently suppressed. To override (e.g., urgent alert), call `notify.send_message` directly — it bypasses rules entirely.\n\n## 📁 Architecture\n\n```\nskills/home-assistant-hub/\n├── SKILL.md              ← this file (read first!)\n├── config/\n│   ├── hub.json          ← runtime config (secrets, gitignored)\n│   └── hub.example.json  ← template with safe defaults\n├── scripts/\n│   ├── ha-hub.js         ← WebSocket + polling monitoring engine\n│   ├── telegram-deliver.js ← Telegram notification delivery daemon\n│   └── ha-cmd.js         ← on-demand read-only + service call CLI (with allowlist enforcement)\n├── notifications/        ← pending notification JSON files (gitignored)\n├── delivered/            ← successfully delivered notifications (gitignored)\n├── logs/                 ← daily rotation logs (gitignored)\n├── references/\n│   └── setup.md          ← detailed setup guide\n├── start.sh              ← portable quick-start script\n├── daemon.sh             ← persistent daemon wrapper\n└── .gitignore\n```\n\n## 🚨 Troubleshooting Quick Reference\n\n| Problem | Solution |\n|---------|----------|\n| HA connection fails | Check token in HA → Profile → Long-Lived Access Tokens |\n| No alerts firing | Verify entity IDs with `ha-cmd.js state list` + grep |\n| WS fails but polling works | Normal — hub auto-fallbacks to polling mode |\n| Duplicate alerts | Increase `cooldown` in rule config (seconds) |\n| **TTS no audio** | Use comma-separated Parla entities. Verify entities exist first with `state list`. |\n| Telegram not delivering | Check bot_token and chat_id in hub.json; restart telegram-deliver |\n| **\"Service domain blocked\"** | Add the domain to `call_safe_domains` in hub.json (see Security section above) |\n\nFile v1.5.1:README.md\n\n# ⚠️ SECURITY & PRIVACY WARNINGS — READ BEFORE INSTALLING\n\n## 🔴 Live Device Control — Hardened Defaults\nThis skill can invoke Home Assistant services to change physical device states. **Service calls are DISABLED BY DEFAULT.**\n\n### Always Blocked (never configurable)\nThe following domains are HARD-LOCKED in code:\n- `lock.*` → door locks (physical security)\n- `alarm_control_panel.*` → alarm systems (safety-critical)\n- `cover.*` → blinds/doors/garage (privacy/security)\n\n### Safe Domains — Explicit Opt-In Required\nService calls require domains to be listed in `call_safe_domains` in `config/hub.json`. **An empty list blocks all service calls.**\n\nDefault safe domains: `light`, `climate`, `scene`, `media_player`, `automation`, `notify`\n\n### Dry-Run Mode\nAlways use `--dry-run` first to preview what would be called:\n```bash\nnode scripts/ha-cmd.js call climate.set_temperature entity_id=climate.hvac temperature=22 --dry-run\n# Shows: Service URL + payload WITHOUT executing\n\n## 📡 External Data Transmission\nThis skill sends data to third-party services (Telegram Bot API, Echo devices). Alert messages include occupancy status, sensor states, and routines. Do not include sensitive personal information in alert templates. Notification content is visible on Telegram accounts and potentially logged by Telegram servers.\n\n## 🔐 Credential Sensitivity\nAll secrets (`ha_token`, `telegram_bot_token`, `telegram_chat_id`) are stored in `config/hub.json`. The HA token is a long-lived bearer token with broad API access — treat it like a password. Default URL uses plain HTTP; use HTTPS if possible to prevent credential exposure on the local network.\n\n---\n\n# Home Assistant Hub\n\nReal-time monitoring of Home Assistant device states with configurable alert rules, TTS voice notifications on Echo devices via Parla entities, Telegram delivery for alerts and events, entity inspection (states, history, persons, areas), and controlled device management through direct service calls.\n\n## What It Does\n\n1. **Monitor** home device states in real-time (polling + WebSocket)\n2. **Alert** when conditions change (battery, garage, temperature, occupancy) — delivered via Telegram or voice announcements on Echo devices\n3. **Inspect** entities: states, history, persons, areas, scenes\n4. **Control** Home Assistant services directly through `ha-cmd.js` calls\n\n### Example use cases\n\n- 🔋 **Battery monitoring**: alerts when charge drops below 20% or exceeds 95% (full charge alert)\n- 🏠 **Security monitoring**: garage door open/close, window sensors, motion detection\n- 🌡️ **Comfort monitoring**: temperature/humidity thresholds, HVAC status\n- 💡 **Device control**: turn lights on/off, set thermostat, activate scenes *(use with caution)*\n- 📢 **Voice announcements**: TTS broadcasts to Echo devices via Parla entities\n\n## How It Works\n\n```\n┌───────────┐    HTTP/WS     ┌───────────────┐   JSON file   ┌─────────────────┐\n│ Home      │ ◄──────────►  │  ha-hub.js    │ ───────────►  │ telegram-deliver│\n│ Assistant │  polling or   │  background    │               │  background     │\n│           │   WebSocket   │  monitoring   │               │  notification   │\n└───────────┘               └───────────────┘               │  delivery       │\n                                                            └────────┬────────┘\n                                                                       │ HTTPS\n                                                                 ┌─────▼──────┐\n                                                                 │ Telegram API│\n                                                                 └────────────┘\n\n┌───────────┐    HTTP          ┌───────────────┐\n│ ha-cmd.js │ ───────────────►  │ Home Assistant│   (on-demand, direct)\n│ (CLI/API) │                   │ WebSocket     │\n└───────────┘                   └───────────────┘\n```\n\n### Two background processes\n\n| Process | What it does | Frequency |\n|---------|-------------|-----------|\n| **ha-hub.js** | Connected to HA, monitors device states against alert rules | Polls every 10s (WebSocket with polling fallback) |\n| **telegram-deliver.js** | Reads pending notification files and sends via Telegram | Checks every 30s |\n\n### Notification flow\n\n1. HA device state changes (e.g., battery drops to 19%)\n2. `ha-hub.js` detects the change against active alert rules\n3. Matching rule writes a JSON file to `notifications/` directory\n4. `telegram-deliver.js` picks up the new file and sends via Telegram Bot API\n5. File is moved to `delivered/` on success\n\n### On-demand command flow (ha-cmd.js)\n\n1. Run: `node scripts/ha-cmd.js state list light`\n2. Receive device states from HA (read-only)\n\nOr for control actions (requires domain opt-in in hub.json):\n1. Preview: `node scripts/ha-cmd.js call light.turn_on entity_id=light.living_room --dry-run`\n2. Execute: `node scripts/ha-cmd.js call light.turn_on entity_id=light.living_room`\n\n## Quick Start\n\n```bash\n# 1. Setup (copy config template)\ncp config/hub.example.json config/hub.json\n# Edit hub.json with your credentials — NEVER commit this file!\n\n# 2. Test connection to HA\nnode scripts/ha-cmd.js info\n\n# 3. Add alert rules (interactive or via JSON)\nnode scripts/ha-hub.js add-rule              # interactive prompt\nnode scripts/ha-hub.js add-rules << 'EOF'    # via JSON stdin\n[{\"name\":\"Low battery\",\"entity_id\":\"sensor.battery_level\",\"condition\":\"below\",\"value\":\"20\",\"cooldown\":600,\"title\":\"🪫 Battery\",\"template\":\"Battery at {{state}}% — low\"}]\nEOF\n\n# 4. Start the monitoring hub (background process)\nnode scripts/ha-hub.js start\n\n# 5. Check status\nnode scripts/ha-hub.js status\n\n# 6. Stop when done\nnode scripts/ha-hub.js stop\n```\n\n## Alert Rules\n\n### Add rule interactively\n```bash\nnode scripts/ha-hub.js add-rule\n```\n\n### Add rules via JSON (stdin)\n```bash\nnode scripts/ha-hub.js add-rules << 'EOF'\n[\n  {\n    \"name\": \"Garage opened\",\n    \"entity_id\": \"binary_sensor.garage_door\",\n    \"condition\": \"state\",\n    \"value\": \"on\",\n    \"cooldown\": 300,\n    \"title\": \"Garage\",\n    \"template\": \"The garage door is open!\"\n  },\n  {\n    \"name\": \"Low battery\",\n    \"entity_id\": \"sensor.battery_level\",\n    \"condition\": \"below\",\n    \"value\": \"20\",\n    \"cooldown\": 600,\n    \"title\": \"🪫 Battery\",\n    \"template\": \"Battery at {{state}}% — low\"\n  }\n]\nEOF\n```\n\n### List rules\n```bash\nnode scripts/ha-hub.js rules\n```\n\n### Rule conditions\n\n| Condition | Meaning | Example value |\n|-----------|---------|---------------|\n| `state` | State equals value | `on`, `home`, `open` |\n| `not_state` | State not equals value | `away` |\n| `above` | Numeric state above threshold | `25` |\n| `below` | Numeric state below threshold | `10` |\n| `changed` | Always trigger on any change | — |\n\n### Rule fields\n\n| Field | Required | Description |\n|-------|----------|-------------|\n| `name` | Yes | Human-readable rule identifier |\n| `entity_id` | Yes* | Single entity ID to monitor |\n| `entities` | Yes* | Array of entity IDs (alternative) |\n| `condition` | Yes | Condition type (see table above) |\n| `value` | Condition-dependent | Threshold or target value |\n| `cooldown` | No | Seconds between alerts (default 300) |\n| `title` | No | Alert title in notification |\n| `template` | No | Custom message template with `{{state}}` variable |\n\n*Either `entity_id` or `entities` required.\n\n## Voice Notifications (TTS)\n\nSend voice announcements to Echo devices via Parla entities. **This produces audible output inside your home environment.**\n\n```bash\n# All Echo devices simultaneously\nnode scripts/ha-cmd.js call notify.send_message \\\n  entity_id=\"notify.echo_show_5_parla,notify.echo_pop_di_vincenzo_parla\" \\\n  message=\"Dinner is ready\"\n\n# Single device\nnode scripts/ha-cmd.js call notify.send_message \\\n  entity_id=\"notify.echo_show_5_parla\" \\\n  message=\"Hello\"\n```\n\nEcho device IDs are configured in `config/hub.json` under `echo_devices`. Find available Parla entities:\n```bash\nnode scripts/ha-cmd.js state list 2>&1 | grep -i parla\n```\n\n## Telegram Integration\n\nNotifications delivered to a Telegram chat when configured. **⚠️ Alert messages are transmitted externally to Telegram servers and may expose household occupancy patterns.**\n\n```bash\nnode scripts/telegram-deliver.js start   # Start delivery process\nnode scripts/telegram-deliver.js status  # Check delivery status\nnode scripts/telegram-deliver.js stop    # Stop delivery process\n```\n\nTelegram settings in `config/hub.json`:\n```json\n\"telegram_bot_token\": \"your_bot_token\",\n\"telegram_chat_id\": \"your_chat_id\",\n\"notification_channel\": \"telegram\"   // or: \"both\" (Telegram + Echo)\n```\n\n## On-Demand Commands (`ha-cmd.js`)\n\n### Safe commands (read-only / display only)\n\n| Command | Description | Data exposed |\n|---------|-------------|--------------|\n| `node scripts/ha-cmd.js info` | HA version, URL, OS, connected clients | System metadata |\n| `node scripts/ha-cmd.js state` | All entity states snapshot | Full home telemetry |\n| `node scripts/ha-cmd.js state get <id>` | Single entity state | One sensor value |\n| `node scripts/ha-cmd.js state list <domain>` | Filter by domain (light, binary_sensor...) | Domain inventory |\n| `node scripts/ha-cmd.js scenes` | List all defined scenes | Scene configuration |\n| `node scripts/ha-cmd.js persons` | Persons + presence states | **Occupancy data** — who is home |\n| `node scripts/ha-cmd.js areas` | Areas with device counts | Home layout, device inventory |\n\n### ⚠️ Control commands (state-changing) — DISABLED BY DEFAULT\n\nThe `call` subcommand invokes Home Assistant services. **Execution is blocked unless the domain is listed in `call_safe_domains` in hub.json.** Dangerous domains are hard-locked and cannot be enabled.\n\n| Command | Description |\n|---------|-------------|\n| `node scripts/ha-cmd.js call <service> [key=value ...] --dry-run` | Preview service call (no execution) |\n| `node scripts/ha-cmd.js call <service> [key=value ...]` | Execute — **only if domain is in call_safe_domains** |\n\n#### Examples:\n\n```bash\n# TTS announcement (produces audible output)\nnode scripts/ha-cmd.js call notify.send_message \\\n  entity_id=\"notify.echo_show_5_parla\" message=\"Test\"\n\n# Turn on a light — changes physical environment\nnode scripts/ha-cmd.js call light.turn_on entity_id=light.living_room\n\n# Set thermostat temperature — affects comfort\nnode scripts/ha-cmd.js call climate.set_temperature \\\n  entity_id=climate.hvac temperature=22\n\n# Activate a scene (multi-device action)\nnode scripts/ha-cmd.js call scene.turn_on entity_id=scene.movie_time\n```\n\n\n\n## Hub Config (`config/hub.json`)\n\nUse `hub.example.json` as a template:\n\n```bash\ncp config/hub.example.json config/hub.json\n# Edit hub.json with your credentials — NEVER commit this file!\n```\n\n```json\n{\n  \"ha_url\": \"http://homeassistant.local:8123\",       // use https:// if available\n  \"ha_token\": \"your-long-lived-token\",               // treat as password — broad API access\n  \"poll_interval\": 10,                                // seconds between polls (WebSocket fallback)\n  \"rules\": [...],                                     // alert rules (see above)\n  \"notification_channel\": \"telegram\",                 // or: \"both\"\n  \"quiet_hours\": {                                    // suppress alerts during sleep\n    \"enabled\": true,\n    \"start\": \"22:00\",\n    \"end\": \"08:00\"\n  },\n  \"call_safe_domains\": [\"light\", \"climate\", \"scene\", \"media_player\", \"automation\", \"notify\"],\n  \"telegram_bot_token\": \"...\",\n  \"telegram_chat_id\": \"...\",\n  \"echo_devices\": {\n    \"all_devices_announce_id\": \"\",                    // legacy: Alexa announce group (unused)\n    \"echo_pop_device_id\": \"notify.echo_pop_di_vincenzo_parla\",\n    \"echo_show_device_id\": \"notify.echo_show_5_parla\"\n  }\n}\n```\n\n## 🔕 Quiet Hours\n\nSuppress alerts during sleep in `config/hub.json`:\n\n```json\n\"quiet_hours\": {\n  \"enabled\": true,\n  \"start\": \"22:00\",\n  \"end\": \"08:00\"\n}\n```\n\nRules during quiet hours are silently suppressed. To override (e.g., urgent alert), call `notify.send_message` directly — it bypasses rules entirely.\n\n## 🚨 Troubleshooting\n\n| Problem | Solution |\n|---------|----------|\n| Connection fails | Check token in HA → Profile → Long-Lived Access Tokens |\n| No alerts firing | Verify entity IDs with `node scripts/ha-cmd.js state list` + grep |\n| WS fails but polling works | Normal — hub auto-fallbacks to polling mode |\n| Duplicate alerts | Increase `cooldown` in rule config (seconds) |\n| TTS no audio | Use comma-separated Parla entities. Verify with `state list`. |\n| Telegram not delivering | Check bot_token and chat_id in hub.json; restart telegram-deliver |\n\n## Directory Structure\n\n```\nskills/home-assistant-hub/\n├── SKILL.md              ← skill description (read first)\n├── README.md             ← this file (user-facing documentation)\n├── config/\n│   ├── hub.json          ← runtime config (secrets - gitignored, never commit)\n│   └── hub.example.json  ← template with safe defaults\n├── scripts/\n│   ├── ha-hub.js         ← monitoring engine (WebSocket + polling)\n│   ├── telegram-deliver.js ← notification delivery daemon\n│   └── ha-cmd.js         ← on-demand CLI: read-only commands + service calls\n├── notifications/        ← pending notifications (gitignored)\n├── delivered/            ← successfully delivered notifications (gitignored)\n├── logs/                 ← daily rotation logs (gitignored)\n├── references/\n│   └── setup.md          ← detailed installation guide\n├── start.sh              ← portable quick-start script\n├── daemon.sh             ← persistent background daemon wrapper\n└── .gitignore\n```\n\nFile v1.5.1:_meta.json\n\n{\n  \"ownerId\": \"kn7438bzbbzvnb37f1vmr6y141854jsa\",\n  \"slug\": \"home-assistant-hub\",\n  \"version\": \"1.5.1\",\n  \"publishedAt\": 1783801468974\n}\n\nFile v1.5.1:references/setup.md\n\n# Home Assistant Hub — Setup Guide\n\n## ⚠️ Security Warning\n\nYou are about to create a **long-lived bearer token** with broad API access to your Home Assistant instance. Treat this token like a password:\n\n- Never share it publicly or commit it to version control\n- The file `config/hub.json` is gitignored — verify `.gitignore` includes it\n- Rotate the token in HA if you suspect compromise (Profile → Long-Lived Access Tokens → Revoke)\n\n## 1. Get a Long-Lived Access Token\n\n1. Open Home Assistant → Profile (bottom-left)\n2. Scroll to **Long-Lived Access Tokens**\n3. Click **CREATE TOKEN**\n4. Name it `openclaw-hub`\n5. **Copy the token** (shown only once!)\n\n## 2. Configure the Hub\n\n```bash\ncd ~/.openclaw/workspace/skills/home-assistant-hub\nnode scripts/ha-hub.js setup\n```\n\nEnter your HA URL and token when prompted.\n\n## 3. Test Connection\n\n```bash\nnode scripts/ha-hub.js test\n```\n\nShould show your HA version.\n\n## 4. Add Alert Rules\n\n### Interactive:\n```bash\nnode scripts/ha-hub.js add-rule\n```\n\n### Via JSON (recommended for bulk):\n```bash\nnode scripts/ha-hub.js add-rules << 'EOF'\n[\n  {\n    \"name\": \"Garage aperto\",\n    \"entity_id\": \"binary_sensor.garage_door\",\n    \"condition\": \"state\",\n    \"value\": \"on\",\n    \"cooldown\": 300,\n    \"title\": \"Garage\",\n    \"template\": \"Il garage è aperto!\"\n  },\n  {\n    \"name\": \"Temperatura bassa\",\n    \"entity_id\": \"sensor.temperatura_interna\",\n    \"condition\": \"below\",\n    \"value\": \"15\",\n    \"cooldown\": 600,\n    \"title\": \"🌡️ Temperatura\",\n    \"template\": \"Temperatura bassa: {{state}}°C\"\n  },\n  {\n    \"name\": \"Persone via\",\n    \"entities\": [\"person.vincenzo\", \"person.maria\"],\n    \"condition\": \"not_state\",\n    \"value\": \"home\",\n    \"cooldown\": 900,\n    \"title\": \"🏠 Tutti fuori\",\n    \"template\": \"Nessuno è in casa\"\n  }\n]\nEOF\n```\n\n## 5. Start the Hub\n\n```bash\nnode scripts/ha-hub.js start\n```\n\nVerify:\n```bash\nnode scripts/ha-hub.js status\n```\n\n## 6. Stop the Hub\n\n```bash\nnode scripts/ha-hub.js stop\n```\n\n## Alert Rules Reference\n\n### Conditions\n\n| Condition | Meaning | Example value |\n|-----------|---------|---------------|\n| `state` | State equals value | `on`, `home`, `open` |\n| `not_state` | State not equals value | `away` |\n| `above` | State (numeric) above value | `25` |\n| `below` | State (numeric) below value | `10` |\n| `changed` | Always trigger on change | — |\n\n### Fields\n\n| Field | Required | Description |\n|-------|----------|-------------|\n| `name` | Yes | Rule identifier |\n| `entity_id` | Yes* | Single entity ID |\n| `entities` | Yes* | Array of entity IDs |\n| `condition` | Yes | See table above |\n| `value` | Condition-dependent | Value to compare |\n| `cooldown` | No | Seconds between alerts (default 300) |\n| `title` | No | Alert title (default \"HA Alert\") |\n| `template` | No | Custom message (default: entity: old → new) |\n| `channel` | No | Notification channel (default: config value) |\n| `priority` | No | `normal` or `urgent` |\n\n*Either `entity_id` or `entities` required.\n\n## Quiet Hours\n\nDisable alerts during sleep in `config/hub.json`:\n\n```json\n\"quiet_hours\": {\n  \"enabled\": true,\n  \"start\": \"23:00\",\n  \"end\": \"07:00\"\n}\n```\n\nRules during quiet hours are silently suppressed.\n\n## Troubleshooting\n\n| Problem | Solution |\n|---------|----------|\n| Connection failed | Check HA URL and token |\n| Hub won't start | Check token is valid in HA |\n| No alerts firing | Verify entity IDs with `node scripts/ha-cmd.js state` |\n| Duplicate alerts | Increase `cooldown` in rule config |\n| WS fails, polling works | Normal — polling is the fallback |\n\nFile v1.5.1:skill-card.md\n\n## Description:\n\nProvides real-time Home Assistant monitoring, alert rules, Echo voice notifications, Telegram delivery, entity inspection, and opt-in service calls.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[vincsta](https://clawhub.ai/user/vincsta)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nExternal developers and Home Assistant users use this skill to monitor device states, define alert rules, inspect entities, send Telegram or Echo notifications, and execute explicitly allowed Home Assistant service calls.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Home Assistant and Telegram credentials may be exposed through local configuration or unencrypted Home Assistant connections.\n\nMitigation: Use HTTPS/WSS, store secrets only in a gitignored config file with restricted permissions, and rotate long-lived tokens if exposure is suspected.\n\nRisk: Allowed service-call domains can change physical devices and may permit broader automation effects than intended.\n\nMitigation: Keep service calls disabled until needed, remove scene and automation from call_safe_domains unless fully audited, and test changes with dry-run first.\n\nRisk: Alert messages sent to Telegram or Echo devices can reveal household state, occupancy, routines, or other sensitive context.\n\nMitigation: Avoid sensitive personal data in templates and route notifications only to trusted Telegram chats and intended Echo devices.\n\nRisk: The provided start script can stop unintended processes because of broad pkill matching.\n\nMitigation: Avoid start.sh until its process matching is narrowed, and verify process state before stopping background services.\n\n## Reference(s):\n\n- [Home Assistant Hub setup guide](references/setup.md)\n- [ClawHub skill page](https://clawhub.ai/vincsta/skills/home-assistant-hub)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Code, Shell commands, Configuration, Guidance]\n\n**Output Format:** [Markdown guidance with inline shell commands, JSON configuration examples, and code references]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May produce Home Assistant service-call examples, alert-rule definitions, setup steps, and operational guidance that should be reviewed before execution.]\n\n## Skill Version(s):\n\n1.5.1 (source: server release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v1.5.1:config/hub.example.json\n\n{\n  \"ha_url\": \"http://homeassistant.local:8123\",\n  \"ha_token\": \"YOUR_LONG_LIVED_TOKEN_HERE\",\n  \"poll_interval\": 10,\n  \"rules\": [],\n  \"notification_channel\": \"telegram\",\n  \"quiet_hours\": {\n    \"enabled\": false,\n    \"start\": \"23:00\",\n    \"end\": \"07:00\"\n  },\n  \"on_demand\": {\n    \"enabled\": false,\n    \"port\": 9123\n  },\n  \"call_safe_domains\": [\"light\", \"climate\", \"scene\", \"media_player\", \"automation\", \"notify\"],\n  \"telegram_bot_token\": \"YOUR_TELEGRAM_BOT_TOKEN_HERE\",\n  \"telegram_chat_id\": \"YOUR_CHAT_ID_HERE\",\n  \"echo_devices\": {\n    \"all_devices_announce_id\": \"\",\n    \"echo_pop_device_id\": \"\",\n    \"echo_show_device_id\": \"\"\n  }\n}\n\nFile v1.5.1:notifications/test-1783363352.json\n\n{\"title\": \"🧪 Test OpenClaw\", \"template\": \"Integrazione Home Assistant configurata! Se leggi questo, Telegram e gli Echo sono pronti.\", \"timestamp\": \"2026-07-06T18:42:32Z\", \"source\": \"openclaw-test\"}\n\nArchive v1.5.0: 12 files, 28616 bytes\n\nFiles: _meta.json (137b), config/hub.example.json (631b), daemon.sh (484b), notifications/test-1783363352.json (202b), README.md (14209b), references/setup.md (3542b), scripts/ha-cmd.js (10488b), scripts/ha-hub.js (20266b), scripts/telegram-deliver.js (8741b), skill-card.md (3075b), SKILL.md (16891b), start.sh (334b)\n\nFile v1.5.0:SKILL.md\n\n---\nname: \"home-assistant-hub\"\ndescription: \"Real-time Home Assistant monitoring, alert rules, TTS voice notifications on Echo devices, Telegram delivery, entity inspection. Service calls are HARD-DENIED by default — require explicit safe-domains opt-in.\"\nhomepage: https://github.com/openclaw/openclaw\nmetadata:\n  {\n    \"openclaw\":\n      {\n        \"emoji\": \"🏡\",\n        \"requires\": { \"bins\": [\"node\"] },\n        \"permissions\": [\n          { \"kind\": \"network\", \"direction\": \"outbound\", \"targets\": [\"Home Assistant API/WebSocket (HTTP + WSS)\", \"Telegram Bot API (HTTPS)\", \"Echo devices via HA notify service\"], \"reason\": \"Real-time monitoring of home device states, alert delivery to Telegram servers, and voice announcements on Echo devices require outbound network connections\" },\n          { \"kind\": \"network\", \"direction\": \"local-bind\", \"targets\": [\"localhost:9123 (on-demand API)\"], \"reason\": \"Local HTTP API for ha-cmd.js service calls when configured. Disabled by default.\" },\n          { \"kind\": \"secrets\", \"direction\": \"local-read\", \"targets\": [\"config/hub.json\"], \"reason\": \"Reads HA long-lived bearer token, Telegram bot token, and chat ID. File is gitignored — never commit to version control\" }\n        ]\n      },\n  }\n---\n\n# ⚠️ SECURITY & PRIVACY WARNINGS — READ FIRST\n\n## 🔴 Device Control — Hardened Defaults\nThis skill can invoke Home Assistant services to change physical device states. **Service calls are disabled by default.**\n\n### ⛔ Always Blocked (never configurable)\nThe following domains are HARD-LOCKED in code and cannot be enabled:\n- `lock.*` — door locks (physical security)\n- `alarm_control_panel.*` — alarm systems (safety-critical)\n- `cover.*` — blinds/doors/garage (privacy/security)\n\n### ✅ Safe Domains — Explicit Opt-In Required\nService calls require domains to be listed in `call_safe_domains` in `config/hub.json`. **An empty list means all service calls are blocked.**\n\nDefault safe domains in the example config: `light`, `climate`, `scene`, `media_player`, `automation`, `notify`\n\nTo add a new domain, edit hub.json:\n```json\n\"call_safe_domains\": [\"light\", \"climate\", \"scene\", \"media_player\", \"automation\", \"notify\"]\n```\n\n### 🔍 Dry-Run Mode\nBefore executing any service call, use `--dry-run` to preview what would happen:\n```bash\nnode scripts/ha-cmd.js call climate.set_temperature entity_id=climate.hvac temperature=22 --dry-run\n# Output: Service URL + payload WITHOUT executing\n\n\n## 📡 External Data Transmission\nThis skill transmits data to third-party services:\n- **Telegram Bot API** — alert messages including occupancy, sensor states, routines → exposes household patterns and security-relevant information\n- **Echo devices via HA** — TTS announcements broadcast inside the home environment\n- **Home Assistant instance** — all device telemetry sent over network\n\n**Do NOT include sensitive personal data in alert templates.** Notification content is visible on Telegram accounts and potentially logged by Telegram servers.\n\n### 🚫 No Hardcoded Credentials\nAll credentials are loaded exclusively from `config/hub.json`. There are no hardcoded fallback tokens anywhere in the codebase. If `telegram_bot_token` or `telegram_chat_id` are missing, the deliverer will refuse to send (with a warning) rather than fall back to defaults.\n\n## 🔐 Credential Sensitivity\nAll secrets (`ha_token`, `telegram_bot_token`, `telegram_chat_id`) are stored in `config/hub.json`. This file is gitignored but:\n- The HA token is a **long-lived bearer token** with broad API access — treat it like a password\n- Default `ha_url` uses plain HTTP → credentials transmitted in cleartext on the local network. Use HTTPS if possible.\n- Rotate tokens regularly via HA → Profile → Long-Lived Access Tokens\n\n## 🔧 Process Management\nThe hub runs as background processes (`nohup`, `disown`) that persist beyond your session. `pkill -f \"ha-hub.js start\"` can match multiple processes. Always verify process state before killing.\n\n---\n\n# Home Assistant Hub\n\nReal-time monitoring of Home Assistant device states with configurable alert rules, TTS voice notifications on Echo devices via Parla entities, Telegram delivery for alerts and events, entity inspection (states, history, persons, areas), and controlled device management through direct service calls.\n\n## Architecture Overview\n\n```\n┌───────────┐    HTTP/WS     ┌───────────────┐   JSON file   ┌─────────────────┐\n│ Home      │ ◄──────────►  │  ha-hub.js    │ ───────────►  │ telegram-deliver│\n│ Assistant │  polling or   │  background    │               │  background     │\n│           │   WebSocket   │  monitoring   │               │  notification   │\n└───────────┘               └───────────────┘               │  delivery       │\n                                                            └────────┬────────┘\n                                                                       │ HTTPS\n                                                                 ┌─────▼──────┐\n                                                                 │ Telegram API│\n                                                                 └────────────┘\n\n┌───────────┐    HTTP          ┌───────────────┐\n│ ha-cmd.js │ ───────────────►  │ Home Assistant│   (on-demand, direct)\n│ (CLI/API) │                   │ WebSocket     │\n└───────────┘                   └───────────────┘\n```\n\n**Two background processes:**\n| Process | Role | Frequency |\n|---------|------|-----------|\n| `ha-hub.js` | Connected to HA, monitors device states against alert rules | Polls every 10s (WS fallback) |\n| `telegram-deliver.js` | Reads pending notification files and sends via Telegram | Checks every 30s |\n\n## Permissions\n\n| Permission | Direction | Targets | Reason |\n|-----------|-----------|---------|---------|\n| `network` | outbound | Home Assistant API/WebSocket (HTTP+WSS), Telegram Bot API (HTTPS), Echo devices via HA notify | Real-time home monitoring, alert delivery to third-party servers, voice announcements |\n| `network` | local-bind | localhost:9123 (on-demand HTTP API) — **disabled by default** | Local service for ha-cmd.js when enabled in config |\n| `secrets` | local-read | `config/hub.json` | HA long-lived bearer token + Telegram credentials. File is gitignored — never commit |\n\n## Quick Start\n\n```bash\ncd skills/home-assistant-hub\n\n# Test connection to HA (safe, read-only)\nnode scripts/ha-cmd.js info\n\n# List entities containing \"echo\" or \"parla\" (safe, read-only)\nnode scripts/ha-cmd.js state list 2>&1 | grep -i echo\n\n# Start the monitoring hub (background process)\nnode scripts/ha-hub.js start\n\n# Check hub status\nnode scripts/ha-hub.js status\n\n# Stop the hub\nnode scripts/ha-hub.js stop\n```\n\n## 📋 Safe Commands (Read-Only / Display)\n\nThese commands only **read** data from Home Assistant. No device state changes:\n\n| Command | What it does | Data exposed |\n|---------|-------------|-------------|\n| `node scripts/ha-cmd.js info` | HA version, URL, OS, connected clients | System metadata |\n| `node scripts/ha-cmd.js state` | All entity states at once | Full home telemetry snapshot |\n| `node scripts/ha-cmd.js state get <id>` | Single entity state (e.g., `sensor.battery_level`) | One sensor value |\n| `node scripts/ha-cmd.js state list <domain>` | Filter entities by domain (`light`, `binary_sensor`, etc.) | Domain-level inventory |\n| `node scripts/ha-cmd.js scenes` | List all defined scenes | Scene configuration |\n| `node scripts/ha-cmd.js persons` | List persons + presence states | Occupancy data — who is home |\n| `node scripts/ha-cmd.js areas` | Areas with device counts | Home layout and device inventory |\n\n## 🗣️ Voice Notifications (TTS)\n\nSends voice announcements to Echo devices via HA Parla entities. **This produces audible output in your physical environment.**\n\nUse **comma-separated entity IDs** — do NOT pass a JSON array:\n\n```bash\n# Send to ALL configured Echo devices simultaneously\nnode scripts/ha-cmd.js call notify.send_message \\\n  entity_id=\"notify.echo_show_5_parla,notify.echo_pop_di_vincenzo_parla\" \\\n  message=\"Ciao Vincenzo, la batteria è al 75 percento\"\n\n# Single device\nnode scripts/ha-cmd.js call notify.send_message \\\n  entity_id=\"notify.echo_show_5_parla\" \\\n  message=\"La cena è pronta\"\n```\n\n**Find Parla entity IDs:** `node scripts/ha-cmd.js state list 2>&1 | grep -i parla`\n\n### Troubleshooting TTS\n- **\"400 Bad Request\"** → wrong format. Use comma-separated string, not array.\n- **\"Success\" but no audio** → verify: (1) Parla entities exist in HA, (2) an automation listens for `notify.send_message`, (3) Echo devices are online/unmuted.\n- **Verify delivery:** check timestamp updated: `node scripts/ha-cmd.js state get notify.echo_show_5_parla | grep last_updated`\n\n## 📋 Alert Rules\n\nConfigurable rules that detect device state changes and trigger notifications via Telegram or voice announcements.\n\n### Add rule interactively\n```bash\nnode scripts/ha-hub.js add-rule\n```\n\n### Add rules via JSON (stdin)\n```bash\nnode scripts/ha-hub.js add-rules << 'EOF'\n[\n  {\n    \"name\": \"Garage aperto\",\n    \"entity_id\": \"binary_sensor.garage_door\",\n    \"condition\": \"state\",\n    \"value\": \"on\",\n    \"cooldown\": 300,\n    \"title\": \"Garage\",\n    \"template\": \"Il garage è aperto!\"\n  },\n  {\n    \"name\": \"Batteria bassa\",\n    \"entity_id\": \"sensor.battery_level\",\n    \"condition\": \"below\",\n    \"value\": \"20\",\n    \"cooldown\": 600,\n    \"title\": \"🪫 Batteria\",\n    \"template\": \"Batteria al {{state}}% — serve attenzione\"\n  }\n]\nEOF\n```\n\n### List rules\n```bash\nnode scripts/ha-hub.js rules\n```\n\n### Rule conditions\n\n| Condition | Meaning | Example value |\n|-----------|---------|-------------|\n| `state` | State equals value | `on`, `home`, `open` |\n| `not_state` | State not equals value | `away` |\n| `above` | Numeric state above threshold | `25` |\n| `below` | Numeric state below threshold | `10` |\n| `changed` | Always trigger on any change | — |\n\n## 📱 Telegram Integration\n\nAlerts are delivered to a Telegram chat when configured. **⚠️ Data is transmitted externally to Telegram servers.** Alert content includes entity states, occupancy information, and home status. Avoid including sensitive personal data in alert templates.\n\n```bash\nnode scripts/telegram-deliver.js start   # Start delivery process\nnode scripts/telegram-deliver.js status  # Check delivery status\nnode scripts/telegram-deliver.js stop    # Stop delivery process\n```\n\nTelegram settings in `config/hub.json`:\n```json\n\"telegram_bot_token\": \"your_bot_token\",\n\"telegram_chat_id\": \"your_chat_id\",\n\"notification_channel\": \"telegram\"   // or: \"both\" (Telegram + Echo)\n```\n\n### Notification flow\n1. HA device state changes (e.g., battery drops to 19%)\n2. `ha-hub.js` detects change against active alert rules\n3. Matching rule writes a JSON file to `notifications/` directory\n4. `telegram-deliver.js` picks up the new file and sends to Telegram\n5. File is moved to `delivered/` on successful delivery\n\n## 🔧 On-Demand Commands (`ha-cmd.js`)\n\nAll commands run from the skill directory:\n```bash\ncd skills/home-assistant-hub\n```\n\n### Safe (read-only / display) commands:\n\n| Command | Description |\n|---------|-------------|\n| `node scripts/ha-cmd.js info` | HA version, URL, OS |\n| `node scripts/ha-cmd.js state` | All entity states |\n| `node scripts/ha-cmd.js state get <id>` | Specific entity (e.g., sensor.battery) |\n| `node scripts/ha-cmd.js state list <domain>` | Filter by domain (light, binary_sensor...) |\n| `node scripts/ha-cmd.js scenes` | List all defined scenes |\n| `node scripts/ha-cmd.js persons` | List persons + presence states |\n| `node scripts/ha-cmd.js areas` | Areas with device counts |\n\n### ⚠️ Control commands (state-changing) — DISABLED BY DEFAULT:\n\nService calls require explicit domain opt-in in `config/hub.json` via `call_safe_domains`. **No service is callable unless its domain is listed there.** Dangerous domains (`lock`, `alarm_control_panel`, `cover`) are hard-locked and cannot be enabled.\n\n| Command | Description |\n|---------|-------------|\n| `node scripts/ha-cmd.js call <service> [key=value ...] --dry-run` | Preview what would be called (no execution) |\n| `node scripts/ha-cmd.js call <service> [key=value ...]` | Execute service — **only if domain is in call_safe_domains** |\n\n#### Examples (understand the impact before running):\n\n```bash\n# TTS announcement on Echo devices\nnode scripts/ha-cmd.js call notify.send_message \\\n  entity_id=\"notify.echo_show_5_parla\" message=\"Prova vocale\"\n\n# Turn on a light — changes physical environment\nnode scripts/ha-cmd.js call light.turn_on entity_id=light.living_room\n\n# Set thermostat temperature — affects comfort\nnode scripts/ha-cmd.js call climate.set_temperature \\\n  entity_id=climate.hvac temperature=22\n\n# Activate a scene (multi-device action)\nnode scripts/ha-cmd.js call scene.turn_on entity_id=scene.movie_time\n\n# Trigger an automation\nnode scripts/ha-cmd.js call automation.trigger entity_id=automation.my_automation\n```\n\n## 🔑 Hub Config (`config/hub.json`)\n\nUse `hub.example.json` as a template:\n\n```bash\ncp config/hub.example.json config/hub.json\n# Edit hub.json with your credentials — NEVER commit this file!\n```\n\n```json\n{\n  \"ha_url\": \"http://homeassistant.local:8123\",       // use https:// if available\n  \"ha_token\": \"your-long-lived-token\",               // treat as password\n  \"poll_interval\": 10,                                // seconds between polls\n  \"rules\": [...],                                     // alert rules (see above)\n  \"notification_channel\": \"telegram\",                 // or: \"both\"\n  \"quiet_hours\": {                                    // suppress alerts during sleep\n    \"enabled\": true,\n    \"start\": \"22:30\",\n    \"end\": \"08:30\"\n  },\n  \"on_demand\": {                                      // local API port for ha-cmd.js (disabled by default)\n    \"enabled\": false,\n    \"port\": 9123\n  },\n  \"call_safe_domains\": [\"light\", \"climate\", \"scene\", \"media_player\", \"automation\", \"notify\"],                               // domains allowed without block; empty = allow all\n  \"telegram_bot_token\": \"...\",\n  \"telegram_chat_id\": \"...\",\n  \"echo_devices\": {\n    \"all_devices_announce_id\": \"\",                    // legacy: Alexa announce group (unused)\n    \"echo_pop_device_id\": \"notify.echo_pop_di_vincenzo_parla\",\n    \"echo_show_device_id\": \"notify.echo_show_5_parla\"\n  }\n}\n```\n\n## 🔕 Quiet Hours\n\nSuppress alerts during sleep in `config/hub.json`:\n\n```json\n\"quiet_hours\": {\n  \"enabled\": true,\n  \"start\": \"22:00\",\n  \"end\": \"08:00\"\n}\n```\n\nRules during quiet hours are silently suppressed. To override (e.g., urgent alert), call `notify.send_message` directly — it bypasses rules entirely.\n\n## 📁 Architecture\n\n```\nskills/home-assistant-hub/\n├── SKILL.md              ← this file (read first!)\n├── config/\n│   ├── hub.json          ← runtime config (secrets, gitignored)\n│   └── hub.example.json  ← template with safe defaults\n├── scripts/\n│   ├── ha-hub.js         ← WebSocket + polling monitoring engine\n│   ├── telegram-deliver.js ← Telegram notification delivery daemon\n│   └── ha-cmd.js         ← on-demand read-only + service call CLI (with allowlist enforcement)\n├── notifications/        ← pending notification JSON files (gitignored)\n├── delivered/            ← successfully delivered notifications (gitignored)\n├── logs/                 ← daily rotation logs (gitignored)\n├── references/\n│   └── setup.md          ← detailed setup guide\n├── start.sh              ← portable quick-start script\n├── daemon.sh             ← persistent daemon wrapper\n└── .gitignore\n```\n\n## 🚨 Troubleshooting Quick Reference\n\n| Problem | Solution |\n|---------|----------|\n| HA connection fails | Check token in HA → Profile → Long-Lived Access Tokens |\n| No alerts firing | Verify entity IDs with `ha-cmd.js state list` + grep |\n| WS fails but polling works | Normal — hub auto-fallbacks to polling mode |\n| Duplicate alerts | Increase `cooldown` in rule config (seconds) |\n| **TTS no audio** | Use comma-separated Parla entities. Verify entities exist first with `state list`. |\n| Telegram not delivering | Check bot_token and chat_id in hub.json; restart telegram-deliver |\n| **\"Service domain blocked\"** | Add the domain to `call_safe_domains` in hub.json (see Security section above) |\n\nFile v1.5.0:README.md\n\n# ⚠️ SECURITY & PRIVACY WARNINGS — READ BEFORE INSTALLING\n\n## 🔴 Live Device Control — Hardened Defaults\nThis skill can invoke Home Assistant services to change physical device states. **Service calls are DISABLED BY DEFAULT.**\n\n### Always Blocked (never configurable)\nThe following domains are HARD-LOCKED in code:\n- `lock.*` → door locks (physical security)\n- `alarm_control_panel.*` → alarm systems (safety-critical)\n- `cover.*` → blinds/doors/garage (privacy/security)\n\n### Safe Domains — Explicit Opt-In Required\nService calls require domains to be listed in `call_safe_domains` in `config/hub.json`. **An empty list blocks all service calls.**\n\nDefault safe domains: `light`, `climate`, `scene`, `media_player`, `automation`, `notify`\n\n### Dry-Run Mode\nAlways use `--dry-run` first to preview what would be called:\n```bash\nnode scripts/ha-cmd.js call climate.set_temperature entity_id=climate.hvac temperature=22 --dry-run\n# Shows: Service URL + payload WITHOUT executing\n\n## 📡 External Data Transmission\nThis skill sends data to third-party services (Telegram Bot API, Echo devices). Alert messages include occupancy status, sensor states, and routines. Do not include sensitive personal information in alert templates. Notification content is visible on Telegram accounts and potentially logged by Telegram servers.\n\n## 🔐 Credential Sensitivity\nAll secrets (`ha_token`, `telegram_bot_token`, `telegram_chat_id`) are stored in `config/hub.json`. The HA token is a long-lived bearer token with broad API access — treat it like a password. Default URL uses plain HTTP; use HTTPS if possible to prevent credential exposure on the local network.\n\n---\n\n# Home Assistant Hub\n\nReal-time monitoring of Home Assistant device states with configurable alert rules, TTS voice notifications on Echo devices via Parla entities, Telegram delivery for alerts and events, entity inspection (states, history, persons, areas), and controlled device management through direct service calls.\n\n## What It Does\n\n1. **Monitor** home device states in real-time (polling + WebSocket)\n2. **Alert** when conditions change (battery, garage, temperature, occupancy) — delivered via Telegram or voice announcements on Echo devices\n3. **Inspect** entities: states, history, persons, areas, scenes\n4. **Control** Home Assistant services directly through `ha-cmd.js` calls\n\n### Example use cases\n\n- 🔋 **Battery monitoring**: alerts when charge drops below 20% or exceeds 95% (full charge alert)\n- 🏠 **Security monitoring**: garage door open/close, window sensors, motion detection\n- 🌡️ **Comfort monitoring**: temperature/humidity thresholds, HVAC status\n- 💡 **Device control**: turn lights on/off, set thermostat, activate scenes *(use with caution)*\n- 📢 **Voice announcements**: TTS broadcasts to Echo devices via Parla entities\n\n## How It Works\n\n```\n┌───────────┐    HTTP/WS     ┌───────────────┐   JSON file   ┌─────────────────┐\n│ Home      │ ◄──────────►  │  ha-hub.js    │ ───────────►  │ telegram-deliver│\n│ Assistant │  polling or   │  background    │               │  background     │\n│           │   WebSocket   │  monitoring   │               │  notification   │\n└───────────┘               └───────────────┘               │  delivery       │\n                                                            └────────┬────────┘\n                                                                       │ HTTPS\n                                                                 ┌─────▼──────┐\n                                                                 │ Telegram API│\n                                                                 └────────────┘\n\n┌───────────┐    HTTP          ┌───────────────┐\n│ ha-cmd.js │ ───────────────►  │ Home Assistant│   (on-demand, direct)\n│ (CLI/API) │                   │ WebSocket     │\n└───────────┘                   └───────────────┘\n```\n\n### Two background processes\n\n| Process | What it does | Frequency |\n|---------|-------------|-----------|\n| **ha-hub.js** | Connected to HA, monitors device states against alert rules | Polls every 10s (WebSocket with polling fallback) |\n| **telegram-deliver.js** | Reads pending notification files and sends via Telegram | Checks every 30s |\n\n### Notification flow\n\n1. HA device state changes (e.g., battery drops to 19%)\n2. `ha-hub.js` detects the change against active alert rules\n3. Matching rule writes a JSON file to `notifications/` directory\n4. `telegram-deliver.js` picks up the new file and sends via Telegram Bot API\n5. File is moved to `delivered/` on success\n\n### On-demand command flow (ha-cmd.js)\n\n1. Run: `node scripts/ha-cmd.js state list light`\n2. Receive device states from HA (read-only)\n\nOr for control actions (requires domain opt-in in hub.json):\n1. Preview: `node scripts/ha-cmd.js call light.turn_on entity_id=light.living_room --dry-run`\n2. Execute: `node scripts/ha-cmd.js call light.turn_on entity_id=light.living_room`\n\n## Quick Start\n\n```bash\n# 1. Setup (copy config template)\ncp config/hub.example.json config/hub.json\n# Edit hub.json with your credentials — NEVER commit this file!\n\n# 2. Test connection to HA\nnode scripts/ha-cmd.js info\n\n# 3. Add alert rules (interactive or via JSON)\nnode scripts/ha-hub.js add-rule              # interactive prompt\nnode scripts/ha-hub.js add-rules << 'EOF'    # via JSON stdin\n[{\"name\":\"Low battery\",\"entity_id\":\"sensor.battery_level\",\"condition\":\"below\",\"value\":\"20\",\"cooldown\":600,\"title\":\"🪫 Battery\",\"template\":\"Battery at {{state}}% — low\"}]\nEOF\n\n# 4. Start the monitoring hub (background process)\nnode scripts/ha-hub.js start\n\n# 5. Check status\nnode scripts/ha-hub.js status\n\n# 6. Stop when done\nnode scripts/ha-hub.js stop\n```\n\n## Alert Rules\n\n### Add rule interactively\n```bash\nnode scripts/ha-hub.js add-rule\n```\n\n### Add rules via JSON (stdin)\n```bash\nnode scripts/ha-hub.js add-rules << 'EOF'\n[\n  {\n    \"name\": \"Garage opened\",\n    \"entity_id\": \"binary_sensor.garage_door\",\n    \"condition\": \"state\",\n    \"value\": \"on\",\n    \"cooldown\": 300,\n    \"title\": \"Garage\",\n    \"template\": \"The garage door is open!\"\n  },\n  {\n    \"name\": \"Low battery\",\n    \"entity_id\": \"sensor.battery_level\",\n    \"condition\": \"below\",\n    \"value\": \"20\",\n    \"cooldown\": 600,\n    \"title\": \"🪫 Battery\",\n    \"template\": \"Battery at {{state}}% — low\"\n  }\n]\nEOF\n```\n\n### List rules\n```bash\nnode scripts/ha-hub.js rules\n```\n\n### Rule conditions\n\n| Condition | Meaning | Example value |\n|-----------|---------|---------------|\n| `state` | State equals value | `on`, `home`, `open` |\n| `not_state` | State not equals value | `away` |\n| `above` | Numeric state above threshold | `25` |\n| `below` | Numeric state below threshold | `10` |\n| `changed` | Always trigger on any change | — |\n\n### Rule fields\n\n| Field | Required | Description |\n|-------|----------|-------------|\n| `name` | Yes | Human-readable rule identifier |\n| `entity_id` | Yes* | Single entity ID to monitor |\n| `entities` | Yes* | Array of entity IDs (alternative) |\n| `condition` | Yes | Condition type (see table above) |\n| `value` | Condition-dependent | Threshold or target value |\n| `cooldown` | No | Seconds between alerts (default 300) |\n| `title` | No | Alert title in notification |\n| `template` | No | Custom message template with `{{state}}` variable |\n\n*Either `entity_id` or `entities` required.\n\n## Voice Notifications (TTS)\n\nSend voice announcements to Echo devices via Parla entities. **This produces audible output inside your home environment.**\n\n```bash\n# All Echo devices simultaneously\nnode scripts/ha-cmd.js call notify.send_message \\\n  entity_id=\"notify.echo_show_5_parla,notify.echo_pop_di_vincenzo_parla\" \\\n  message=\"Dinner is ready\"\n\n# Single device\nnode scripts/ha-cmd.js call notify.send_message \\\n  entity_id=\"notify.echo_show_5_parla\" \\\n  message=\"Hello\"\n```\n\nEcho device IDs are configured in `config/hub.json` under `echo_devices`. Find available Parla entities:\n```bash\nnode scripts/ha-cmd.js state list 2>&1 | grep -i parla\n```\n\n## Telegram Integration\n\nNotifications delivered to a Telegram chat when configured. **⚠️ Alert messages are transmitted externally to Telegram servers and may expose household occupancy patterns.**\n\n```bash\nnode scripts/telegram-deliver.js start   # Start delivery process\nnode scripts/telegram-deliver.js status  # Check delivery status\nnode scripts/telegram-deliver.js stop    # Stop delivery process\n```\n\nTelegram settings in `config/hub.json`:\n```json\n\"telegram_bot_token\": \"your_bot_token\",\n\"telegram_chat_id\": \"your_chat_id\",\n\"notification_channel\": \"telegram\"   // or: \"both\" (Telegram + Echo)\n```\n\n## On-Demand Commands (`ha-cmd.js`)\n\n### Safe commands (read-only / display only)\n\n| Command | Description | Data exposed |\n|---------|-------------|--------------|\n| `node scripts/ha-cmd.js info` | HA version, URL, OS, connected clients | System metadata |\n| `node scripts/ha-cmd.js state` | All entity states snapshot | Full home telemetry |\n| `node scripts/ha-cmd.js state get <id>` | Single entity state | One sensor value |\n| `node scripts/ha-cmd.js state list <domain>` | Filter by domain (light, binary_sensor...) | Domain inventory |\n| `node scripts/ha-cmd.js scenes` | List all defined scenes | Scene configuration |\n| `node scripts/ha-cmd.js persons` | Persons + presence states | **Occupancy data** — who is home |\n| `node scripts/ha-cmd.js areas` | Areas with device counts | Home layout, device inventory |\n\n### ⚠️ Control commands (state-changing) — DISABLED BY DEFAULT\n\nThe `call` subcommand invokes Home Assistant services. **Execution is blocked unless the domain is listed in `call_safe_domains` in hub.json.** Dangerous domains are hard-locked and cannot be enabled.\n\n| Command | Description |\n|---------|-------------|\n| `node scripts/ha-cmd.js call <service> [key=value ...] --dry-run` | Preview service call (no execution) |\n| `node scripts/ha-cmd.js call <service> [key=value ...]` | Execute — **only if domain is in call_safe_domains** |\n\n#### Examples:\n\n```bash\n# TTS announcement (produces audible output)\nnode scripts/ha-cmd.js call notify.send_message \\\n  entity_id=\"notify.echo_show_5_parla\" message=\"Test\"\n\n# Turn on a light — changes physical environment\nnode scripts/ha-cmd.js call light.turn_on entity_id=light.living_room\n\n# Set thermostat temperature — affects comfort\nnode scripts/ha-cmd.js call climate.set_temperature \\\n  entity_id=climate.hvac temperature=22\n\n# Activate a scene (multi-device action)\nnode scripts/ha-cmd.js call scene.turn_on entity_id=scene.movie_time\n```\n\n\n\n## Hub Config (`config/hub.json`)\n\nUse `hub.example.json` as a template:\n\n```bash\ncp config/hub.example.json config/hub.json\n# Edit hub.json with your credentials — NEVER commit this file!\n```\n\n```json\n{\n  \"ha_url\": \"http://homeassistant.local:8123\",       // use https:// if available\n  \"ha_token\": \"your-long-lived-token\",               // treat as password — broad API access\n  \"poll_interval\": 10,                                // seconds between polls (WebSocket fallback)\n  \"rules\": [...],                                     // alert rules (see above)\n  \"notification_channel\": \"telegram\",                 // or: \"both\"\n  \"quiet_hours\": {                                    // suppress alerts during sleep\n    \"enabled\": true,\n    \"start\": \"22:00\",\n    \"end\": \"08:00\"\n  },\n  \"call_safe_domains\": [\"light\", \"climate\", \"scene\", \"media_player\", \"automation\", \"notify\"],\n  \"telegram_bot_token\": \"...\",\n  \"telegram_chat_id\": \"...\",\n  \"echo_devices\": {\n    \"all_devices_announce_id\": \"\",                    // legacy: Alexa announce group (unused)\n    \"echo_pop_device_id\": \"notify.echo_pop_di_vincenzo_parla\",\n    \"echo_show_device_id\": \"notify.echo_show_5_parla\"\n  }\n}\n```\n\n## 🔕 Quiet Hours\n\nSuppress alerts during sleep in `config/hub.json`:\n\n```json\n\"quiet_hours\": {\n  \"enabled\": true,\n  \"start\": \"22:00\",\n  \"end\": \"08:00\"\n}\n```\n\nRules during quiet hours are silently suppressed. To override (e.g., urgent alert), call `notify.send_message` directly — it bypasses rules entirely.\n\n## 🚨 Troubleshooting\n\n| Problem | Solution |\n|---------|----------|\n| Connection fails | Check token in HA → Profile → Long-Lived Access Tokens |\n| No alerts firing | Verify entity IDs with `node scripts/ha-cmd.js state list` + grep |\n| WS fails but polling works | Normal — hub auto-fallbacks to polling mode |\n| Duplicate alerts | Increase `cooldown` in rule config (seconds) |\n| TTS no audio | Use comma-separated Parla entities. Verify with `state list`. |\n| Telegram not delivering | Check bot_token and chat_id in hub.json; restart telegram-deliver |\n\n## Directory Structure\n\n```\nskills/home-assistant-hub/\n├── SKILL.md              ← skill description (read first)\n├── README.md             ← this file (user-facing documentation)\n├── config/\n│   ├── hub.json          ← runtime config (secrets - gitignored, never commit)\n│   └── hub.example.json  ← template with safe defaults\n├── scripts/\n│   ├── ha-hub.js         ← monitoring engine (WebSocket + polling)\n│   ├── telegram-deliver.js ← notification delivery daemon\n│   └── ha-cmd.js         ← on-demand CLI: read-only commands + service calls\n├── notifications/        ← pending notifications (gitignored)\n├── delivered/            ← successfully delivered notifications (gitignored)\n├── logs/                 ← daily rotation logs (gitignored)\n├── references/\n│   └── setup.md          ← detailed installation guide\n├── start.sh              ← portable quick-start script\n├── daemon.sh             ← persistent background daemon wrapper\n└── .gitignore\n```\n\nFile v1.5.0:_meta.json\n\n{\n  \"ownerId\": \"kn7438bzbbzvnb37f1vmr6y141854jsa\",\n  \"slug\": \"home-assistant-hub\",\n  \"version\": \"1.5.0\",\n  \"publishedAt\": 1783799909403\n}\n\nFile v1.5.0:references/setup.md\n\n# Home Assistant Hub — Setup Guide\n\n## ⚠️ Security Warning\n\nYou are about to create a **long-lived bearer token** with broad API access to your Home Assistant instance. Treat this token like a password:\n\n- Never share it publicly or commit it to version control\n- The file `config/hub.json` is gitignored — verify `.gitignore` includes it\n- Rotate the token in HA if you suspect compromise (Profile → Long-Lived Access Tokens → Revoke)\n\n## 1. Get a Long-Lived Access Token\n\n1. Open Home Assistant → Profile (bottom-left)\n2. Scroll to **Long-Lived Access Tokens**\n3. Click **CREATE TOKEN**\n4. Name it `openclaw-hub`\n5. **Copy the token** (shown only once!)\n\n## 2. Configure the Hub\n\n```bash\ncd ~/.openclaw/workspace/skills/home-assistant-hub\nnode scripts/ha-hub.js setup\n```\n\nEnter your HA URL and token when prompted.\n\n## 3. Test Connection\n\n```bash\nnode scripts/ha-hub.js test\n```\n\nShould show your HA version.\n\n## 4. Add Alert Rules\n\n### Interactive:\n```bash\nnode scripts/ha-hub.js add-rule\n```\n\n### Via JSON (recommended for bulk):\n```bash\nnode scripts/ha-hub.js add-rules << 'EOF'\n[\n  {\n    \"name\": \"Garage aperto\",\n    \"entity_id\": \"binary_sensor.garage_door\",\n    \"condition\": \"state\",\n    \"value\": \"on\",\n    \"cooldown\": 300,\n    \"title\": \"Garage\",\n    \"template\": \"Il garage è aperto!\"\n  },\n  {\n    \"name\": \"Temperatura bassa\",\n    \"entity_id\": \"sensor.temperatura_interna\",\n    \"condition\": \"below\",\n    \"value\": \"15\",\n    \"cooldown\": 600,\n    \"title\": \"🌡️ Temperatura\",\n    \"template\": \"Temperatura bassa: {{state}}°C\"\n  },\n  {\n    \"name\": \"Persone via\",\n    \"entities\": [\"person.vincenzo\", \"person.maria\"],\n    \"condition\": \"not_state\",\n    \"value\": \"home\",\n    \"cooldown\": 900,\n    \"title\": \"🏠 Tutti fuori\",\n    \"template\": \"Nessuno è in casa\"\n  }\n]\nEOF\n```\n\n## 5. Start the Hub\n\n```bash\nnode scripts/ha-hub.js start\n```\n\nVerify:\n```bash\nnode scripts/ha-hub.js status\n```\n\n## 6. Stop the Hub\n\n```bash\nnode scripts/ha-hub.js stop\n```\n\n## Alert Rules Reference\n\n### Conditions\n\n| Condition | Meaning | Example value |\n|-----------|---------|---------------|\n| `state` | State equals value | `on`, `home`, `open` |\n| `not_state` | State not equals value | `away` |\n| `above` | State (numeric) above value | `25` |\n| `below` | State (numeric) below value | `10` |\n| `changed` | Always trigger on change | — |\n\n### Fields\n\n| Field | Required | Description |\n|-------|----------|-------------|\n| `name` | Yes | Rule identifier |\n| `entity_id` | Yes* | Single entity ID |\n| `entities` | Yes* | Array of entity IDs |\n| `condition` | Yes | See table above |\n| `value` | Condition-dependent | Value to compare |\n| `cooldown` | No | Seconds between alerts (default 300) |\n| `title` | No | Alert title (default \"HA Alert\") |\n| `template` | No | Custom message (default: entity: old → new) |\n| `channel` | No | Notification channel (default: config value) |\n| `priority` | No | `normal` or `urgent` |\n\n*Either `entity_id` or `entities` required.\n\n## Quiet Hours\n\nDisable alerts during sleep in `config/hub.json`:\n\n```json\n\"quiet_hours\": {\n  \"enabled\": true,\n  \"start\": \"23:00\",\n  \"end\": \"07:00\"\n}\n```\n\nRules during quiet hours are silently suppressed.\n\n## Troubleshooting\n\n| Problem | Solution |\n|---------|----------|\n| Connection failed | Check HA URL and token |\n| Hub won't start | Check token is valid in HA |\n| No alerts firing | Verify entity IDs with `node scripts/ha-cmd.js state` |\n| Duplicate alerts | Increase `cooldown` in rule config |\n| WS fails, polling works | Normal — polling is the fallback |\n\nFile v1.5.0:skill-card.md\n\n## Description: <br>\nReal-time Home Assistant monitoring, alert rules, TTS voice notifications on Echo devices, Telegram delivery, entity inspection. Service calls are HARD-DENIED by default and require explicit safe-domains opt-in. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[vincsta](https://clawhub.ai/user/vincsta) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nExternal Home Assistant users and developers use this skill to monitor device state, inspect entities, configure alert rules, and receive Telegram or Echo notifications. It can also guide controlled Home Assistant service calls when explicitly enabled in configuration. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: Home Assistant and Telegram credentials are read from local configuration, and the Home Assistant token can provide broad home-automation access. <br>\nMitigation: Use a dedicated Home Assistant account or token, prefer HTTPS, restrict config/hub.json permissions, never commit secrets, and rotate tokens if exposure is suspected. <br>\nRisk: Telegram alerts can externally disclose home telemetry such as occupancy, sensor states, and routines. <br>\nMitigation: Keep alert templates minimal, avoid sensitive personal data, and review Telegram bot and chat access before enabling delivery. <br>\nRisk: Device-control workflows can change the physical environment, and the security evidence notes inconsistent safeguard documentation plus a notification path that can try a local service call outside the advertised allowlist. <br>\nMitigation: Keep call_safe_domains limited to required domains, use dry-run mode before service calls, and do not enable Echo TTS or legacy local-service settings unless the localhost service is trusted and intentionally configured. <br>\nRisk: Background hub and delivery processes can persist beyond the agent session. <br>\nMitigation: Check process status and PID files before stopping or restarting services, and avoid broad process-kill commands without verifying what will match. <br>\n\n\n## Reference(s): <br>\n- [Home Assistant Hub setup guide](artifact/references/setup.md) <br>\n- [ClawHub skill page](https://clawhub.ai/vincsta/skills/home-assistant-hub) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [text, markdown, shell commands, configuration, guidance] <br>\n**Output Format:** [Markdown guidance with shell commands and JSON configuration examples] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [May guide read-only Home Assistant inspection, background monitoring setup, notification configuration, and explicitly gated service-call workflows.] <br>\n\n## Skill Version(s): <br>\n1.5.0 (source: server release metadata) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nFile v1.5.0:config/hub.example.json\n\n{\n  \"ha_url\": \"http://homeassistant.local:8123\",\n  \"ha_token\": \"YOUR_LONG_LIVED_TOKEN_HERE\",\n  \"poll_interval\": 10,\n  \"rules\": [],\n  \"notification_channel\": \"telegram\",\n  \"quiet_hours\": {\n    \"enabled\": false,\n    \"start\": \"23:00\",\n    \"end\": \"07:00\"\n  },\n  \"on_demand\": {\n    \"enabled\": false,\n    \"port\": 9123\n  },\n  \"call_safe_domains\": [\"light\", \"climate\", \"scene\", \"media_player\", \"automation\", \"notify\"],\n  \"telegram_bot_token\": \"YOUR_TELEGRAM_BOT_TOKEN_HERE\",\n  \"telegram_chat_id\": \"YOUR_CHAT_ID_HERE\",\n  \"echo_devices\": {\n    \"all_devices_announce_id\": \"\",\n    \"echo_pop_device_id\": \"\",\n    \"echo_show_device_id\": \"\"\n  }\n}\n\nFile v1.5.0:notifications/test-1783363352.json\n\n{\"title\": \"🧪 Test OpenClaw\", \"template\": \"Integrazione Home Assistant configurata! Se leggi questo, Telegram e gli Echo sono pronti.\", \"timestamp\": \"2026-07-06T18:42:32Z\", \"source\": \"openclaw-test\"}\n\nArchive v1.4.0: 12 files, 27791 bytes\n\nFiles: _meta.json (137b), config/hub.example.json (561b), daemon.sh (484b), notifications/test-1783363352.json (202b), README.md (13733b), references/setup.md (3542b), scripts/ha-cmd.js (9300b), scripts/ha-hub.js (20266b), scripts/telegram-deliver.js (8741b), skill-card.md (2493b), SKILL.md (16772b), start.sh (334b)\n\nFile v1.4.0:SKILL.md\n\n---\nname: \"home-assistant-hub\"\ndescription: \"Hardened: call allowlist, no hardcoded fallbacks, explicit confirm flow for dangerous services.\"\nhomepage: https://github.com/openclaw/openclaw\nmetadata:\n  {\n    \"openclaw\":\n      {\n        \"emoji\": \"🏡\",\n        \"requires\": { \"bins\": [\"node\"] },\n        \"permissions\": [\n          { \"kind\": \"network\", \"direction\": \"outbound\", \"targets\": [\"Home Assistant API/WebSocket (HTTP + WSS)\", \"Telegram Bot API (HTTPS)\", \"Echo devices via HA notify service\"], \"reason\": \"Real-time monitoring of home device states, alert delivery to Telegram servers, and voice announcements on Echo devices require outbound network connections\" },\n          { \"kind\": \"network\", \"direction\": \"local-bind\", \"targets\": [\"localhost:9123 (on-demand API)\"], \"reason\": \"Local HTTP API for ha-cmd.js service calls when configured. Disabled by default.\" },\n          { \"kind\": \"secrets\", \"direction\": \"local-read\", \"targets\": [\"config/hub.json\"], \"reason\": \"Reads HA long-lived bearer token, Telegram bot token, and chat ID. File is gitignored — never commit to version control\" }\n        ]\n      },\n  }\n---\n\n# ⚠️ SECURITY & PRIVACY WARNINGS — READ FIRST\n\n## 🔴 Device Control — Real-World Impact\nThis skill performs **live Home Assistant service calls** that change physical device states. Commands execute **immediately with no confirmation or dry-run**. Actions can:\n- Lock/unlock doors → **physical security impact**\n- Trigger/disable alarms → **safety-critical**\n- Adjust climate control → **comfort/health impact**\n- Open/close covers/blinds → **privacy/security impact**\n\n**Before calling ANY service:** verify the entity and action in HA Developer Tools. Never blindly invoke `lock.*`, `alarm_control_panel.*`, or `cover.*` services without explicit confirmation from Vincenzo.\n\n### ⛔ Restricted Services — Requires Explicit Approval\nThe following service domains are blocked by default and require manual override:\n- `lock.*` (door locks)\n- `alarm_control_panel.*` (security systems)\n- `cover.*` (blinds/doors/garage)\n- `person.deactivate` / `zone.leave` (occupancy changes)\n\nTo unblock a domain, add it to the `call_allowlist` array in `config/hub.json`:\n```json\n\"call_allowlist\": [\"lock\", \"alarm_control_panel\", \"cover\"]\n```\n**⚠️ Only unblock domains you understand and trust. This bypasses all safety guards.**\n\n## 📡 External Data Transmission\nThis skill transmits data to third-party services:\n- **Telegram Bot API** — alert messages including occupancy, sensor states, routines → exposes household patterns and security-relevant information\n- **Echo devices via HA** — TTS announcements broadcast inside the home environment\n- **Home Assistant instance** — all device telemetry sent over network\n\n**Do NOT include sensitive personal data in alert templates.** Notification content is visible on Telegram accounts and potentially logged by Telegram servers.\n\n### 🚫 No Hardcoded Credentials\nAll credentials are loaded exclusively from `config/hub.json`. There are no hardcoded fallback tokens anywhere in the codebase. If `telegram_bot_token` or `telegram_chat_id` are missing, the deliverer will refuse to send (with a warning) rather than fall back to defaults.\n\n## 🔐 Credential Sensitivity\nAll secrets (`ha_token`, `telegram_bot_token`, `telegram_chat_id`) are stored in `config/hub.json`. This file is gitignored but:\n- The HA token is a **long-lived bearer token** with broad API access — treat it like a password\n- Default `ha_url` uses plain HTTP → credentials transmitted in cleartext on the local network. Use HTTPS if possible.\n- Rotate tokens regularly via HA → Profile → Long-Lived Access Tokens\n\n## 🔧 Process Management\nThe hub runs as background processes (`nohup`, `disown`) that persist beyond your session. `pkill -f \"ha-hub.js start\"` can match multiple processes. Always verify process state before killing.\n\n---\n\n# Home Assistant Hub\n\nReal-time monitoring of Home Assistant device states with configurable alert rules, TTS voice notifications on Echo devices via Parla entities, Telegram delivery for alerts and events, entity inspection (states, history, persons, areas), and controlled device management through direct service calls.\n\n## Architecture Overview\n\n```\n┌───────────┐    HTTP/WS     ┌───────────────┐   JSON file   ┌─────────────────┐\n│ Home      │ ◄──────────►  │  ha-hub.js    │ ───────────►  │ telegram-deliver│\n│ Assistant │  polling or   │  background    │               │  background     │\n│           │   WebSocket   │  monitoring   │               │  notification   │\n└───────────┘               └───────────────┘               │  delivery       │\n                                                            └────────┬────────┘\n                                                                       │ HTTPS\n                                                                 ┌─────▼──────┐\n                                                                 │ Telegram API│\n                                                                 └────────────┘\n\n┌───────────┐    HTTP          ┌───────────────┐\n│ ha-cmd.js │ ───────────────►  │ Home Assistant│   (on-demand, direct)\n│ (CLI/API) │                   │ WebSocket     │\n└───────────┘                   └───────────────┘\n```\n\n**Two background processes:**\n| Process | Role | Frequency |\n|---------|------|-----------|\n| `ha-hub.js` | Connected to HA, monitors device states against alert rules | Polls every 10s (WS fallback) |\n| `telegram-deliver.js` | Reads pending notification files and sends via Telegram | Checks every 30s |\n\n## Permissions\n\n| Permission | Direction | Targets | Reason |\n|-----------|-----------|---------|---------|\n| `network` | outbound | Home Assistant API/WebSocket (HTTP+WSS), Telegram Bot API (HTTPS), Echo devices via HA notify | Real-time home monitoring, alert delivery to third-party servers, voice announcements |\n| `network` | local-bind | localhost:9123 (on-demand HTTP API) — **disabled by default** | Local service for ha-cmd.js when enabled in config |\n| `secrets` | local-read | `config/hub.json` | HA long-lived bearer token + Telegram credentials. File is gitignored — never commit |\n\n## Quick Start\n\n```bash\ncd skills/home-assistant-hub\n\n# Test connection to HA (safe, read-only)\nnode scripts/ha-cmd.js info\n\n# List entities containing \"echo\" or \"parla\" (safe, read-only)\nnode scripts/ha-cmd.js state list 2>&1 | grep -i echo\n\n# Start the monitoring hub (background process)\nnode scripts/ha-hub.js start\n\n# Check hub status\nnode scripts/ha-hub.js status\n\n# Stop the hub\nnode scripts/ha-hub.js stop\n```\n\n## 📋 Safe Commands (Read-Only / Display)\n\nThese commands only **read** data from Home Assistant. No device state changes:\n\n| Command | What it does | Data exposed |\n|---------|-------------|-------------|\n| `node scripts/ha-cmd.js info` | HA version, URL, OS, connected clients | System metadata |\n| `node scripts/ha-cmd.js state` | All entity states at once | Full home telemetry snapshot |\n| `node scripts/ha-cmd.js state get <id>` | Single entity state (e.g., `sensor.battery_level`) | One sensor value |\n| `node scripts/ha-cmd.js state list <domain>` | Filter entities by domain (`light`, `binary_sensor`, etc.) | Domain-level inventory |\n| `node scripts/ha-cmd.js scenes` | List all defined scenes | Scene configuration |\n| `node scripts/ha-cmd.js persons` | List persons + presence states | Occupancy data — who is home |\n| `node scripts/ha-cmd.js areas` | Areas with device counts | Home layout and device inventory |\n\n## 🗣️ Voice Notifications (TTS)\n\nSends voice announcements to Echo devices via HA Parla entities. **This produces audible output in your physical environment.**\n\nUse **comma-separated entity IDs** — do NOT pass a JSON array:\n\n```bash\n# Send to ALL configured Echo devices simultaneously\nnode scripts/ha-cmd.js call notify.send_message \\\n  entity_id=\"notify.echo_show_5_parla,notify.echo_pop_di_vincenzo_parla\" \\\n  message=\"Ciao Vincenzo, la batteria è al 75 percento\"\n\n# Single device\nnode scripts/ha-cmd.js call notify.send_message \\\n  entity_id=\"notify.echo_show_5_parla\" \\\n  message=\"La cena è pronta\"\n```\n\n**Find Parla entity IDs:** `node scripts/ha-cmd.js state list 2>&1 | grep -i parla`\n\n### Troubleshooting TTS\n- **\"400 Bad Request\"** → wrong format. Use comma-separated string, not array.\n- **\"Success\" but no audio** → verify: (1) Parla entities exist in HA, (2) an automation listens for `notify.send_message`, (3) Echo devices are online/unmuted.\n- **Verify delivery:** check timestamp updated: `node scripts/ha-cmd.js state get notify.echo_show_5_parla | grep last_updated`\n\n## 📋 Alert Rules\n\nConfigurable rules that detect device state changes and trigger notifications via Telegram or voice announcements.\n\n### Add rule interactively\n```bash\nnode scripts/ha-hub.js add-rule\n```\n\n### Add rules via JSON (stdin)\n```bash\nnode scripts/ha-hub.js add-rules << 'EOF'\n[\n  {\n    \"name\": \"Garage aperto\",\n    \"entity_id\": \"binary_sensor.garage_door\",\n    \"condition\": \"state\",\n    \"value\": \"on\",\n    \"cooldown\": 300,\n    \"title\": \"Garage\",\n    \"template\": \"Il garage è aperto!\"\n  },\n  {\n    \"name\": \"Batteria bassa\",\n    \"entity_id\": \"sensor.battery_level\",\n    \"condition\": \"below\",\n    \"value\": \"20\",\n    \"cooldown\": 600,\n    \"title\": \"🪫 Batteria\",\n    \"template\": \"Batteria al {{state}}% — serve attenzione\"\n  }\n]\nEOF\n```\n\n### List rules\n```bash\nnode scripts/ha-hub.js rules\n```\n\n### Rule conditions\n\n| Condition | Meaning | Example value |\n|-----------|---------|-------------|\n| `state` | State equals value | `on`, `home`, `open` |\n| `not_state` | State not equals value | `away` |\n| `above` | Numeric state above threshold | `25` |\n| `below` | Numeric state below threshold | `10` |\n| `changed` | Always trigger on any change | — |\n\n## 📱 Telegram Integration\n\nAlerts are delivered to a Telegram chat when configured. **⚠️ Data is transmitted externally to Telegram servers.** Alert content includes entity states, occupancy information, and home status. Avoid including sensitive personal data in alert templates.\n\n```bash\nnode scripts/telegram-deliver.js start   # Start delivery process\nnode scripts/telegram-deliver.js status  # Check delivery status\nnode scripts/telegram-deliver.js stop    # Stop delivery process\n```\n\nTelegram settings in `config/hub.json`:\n```json\n\"telegram_bot_token\": \"your_bot_token\",\n\"telegram_chat_id\": \"your_chat_id\",\n\"notification_channel\": \"telegram\"   // or: \"both\" (Telegram + Echo)\n```\n\n### Notification flow\n1. HA device state changes (e.g., battery drops to 19%)\n2. `ha-hub.js` detects change against active alert rules\n3. Matching rule writes a JSON file to `notifications/` directory\n4. `telegram-deliver.js` picks up the new file and sends to Telegram\n5. File is moved to `delivered/` on successful delivery\n\n## 🔧 On-Demand Commands (`ha-cmd.js`)\n\nAll commands run from the skill directory:\n```bash\ncd skills/home-assistant-hub\n```\n\n### Safe (read-only / display) commands:\n\n| Command | Description |\n|---------|-------------|\n| `node scripts/ha-cmd.js info` | HA version, URL, OS |\n| `node scripts/ha-cmd.js state` | All entity states |\n| `node scripts/ha-cmd.js state get <id>` | Specific entity (e.g., sensor.battery) |\n| `node scripts/ha-cmd.js state list <domain>` | Filter by domain (light, binary_sensor...) |\n| `node scripts/ha-cmd.js scenes` | List all defined scenes |\n| `node scripts/ha-cmd.js persons` | List persons + presence states |\n| `node scripts/ha-cmd.js areas` | Areas with device counts |\n\n### ⚠️ Control commands (state-changing) — use with caution:\n\nThe `call` subcommand invokes Home Assistant services. **Execution is gated by a configurable allowlist** in `config/hub.json`. By default, the following domains are blocked:\n- `lock.*`, `alarm_control_panel.*`, `cover.*`, `person.deactivate`, `zone.leave`\n\nIf a domain is not in the allowlist (or the allowlist is empty, meaning all are allowed), **the call is rejected** with an error explaining how to add it.\n\n| Command | Description |\n|---------|-------------|\n| `node scripts/ha-cmd.js call <service> [key=value ...]` | Call a HA service — **checked against allowlist first** |\n\n#### Examples (understand the impact before running):\n\n```bash\n# TTS announcement on Echo devices\nnode scripts/ha-cmd.js call notify.send_message \\\n  entity_id=\"notify.echo_show_5_parla\" message=\"Prova vocale\"\n\n# Turn on a light — changes physical environment\nnode scripts/ha-cmd.js call light.turn_on entity_id=light.living_room\n\n# Set thermostat temperature — affects comfort\nnode scripts/ha-cmd.js call climate.set_temperature \\\n  entity_id=climate.hvac temperature=22\n\n# Activate a scene (multi-device action)\nnode scripts/ha-cmd.js call scene.turn_on entity_id=scene.movie_time\n\n# Trigger an automation\nnode scripts/ha-cmd.js call automation.trigger entity_id=automation.my_automation\n```\n\n## 🔑 Hub Config (`config/hub.json`)\n\nUse `hub.example.json` as a template:\n\n```bash\ncp config/hub.example.json config/hub.json\n# Edit hub.json with your credentials — NEVER commit this file!\n```\n\n```json\n{\n  \"ha_url\": \"http://homeassistant.local:8123\",       // use https:// if available\n  \"ha_token\": \"your-long-lived-token\",               // treat as password\n  \"poll_interval\": 10,                                // seconds between polls\n  \"rules\": [...],                                     // alert rules (see above)\n  \"notification_channel\": \"telegram\",                 // or: \"both\"\n  \"quiet_hours\": {                                    // suppress alerts during sleep\n    \"enabled\": true,\n    \"start\": \"22:30\",\n    \"end\": \"08:30\"\n  },\n  \"on_demand\": {                                      // local API port for ha-cmd.js (disabled by default)\n    \"enabled\": false,\n    \"port\": 9123\n  },\n  \"call_allowlist\": [],                               // domains allowed without block; empty = allow all\n  \"telegram_bot_token\": \"...\",\n  \"telegram_chat_id\": \"...\",\n  \"echo_devices\": {\n    \"all_devices_announce_id\": \"\",                    // legacy: Alexa announce group (unused)\n    \"echo_pop_device_id\": \"notify.echo_pop_di_vincenzo_parla\",\n    \"echo_show_device_id\": \"notify.echo_show_5_parla\"\n  }\n}\n```\n\n## 🔕 Quiet Hours\n\nSuppress alerts during sleep in `config/hub.json`:\n\n```json\n\"quiet_hours\": {\n  \"enabled\": true,\n  \"start\": \"22:00\",\n  \"end\": \"08:00\"\n}\n```\n\nRules during quiet hours are silently suppressed. To override (e.g., urgent alert), call `notify.send_message` directly — it bypasses rules entirely.\n\n## 📁 Architecture\n\n```\nskills/home-assistant-hub/\n├── SKILL.md              ← this file (read first!)\n├── config/\n│   ├── hub.json          ← runtime config (secrets, gitignored)\n│   └── hub.example.json  ← template with safe defaults\n├── scripts/\n│   ├── ha-hub.js         ← WebSocket + polling monitoring engine\n│   ├── telegram-deliver.js ← Telegram notification delivery daemon\n│   └── ha-cmd.js         ← on-demand read-only + service call CLI (with allowlist enforcement)\n├── notifications/        ← pending notification JSON files (gitignored)\n├── delivered/            ← successfully delivered notifications (gitignored)\n├── logs/                 ← daily rotation logs (gitignored)\n├── references/\n│   └── setup.md          ← detailed setup guide\n├── start.sh              ← portable quick-start script\n├── daemon.sh             ← persistent daemon wrapper\n└── .gitignore\n```\n\n## 🚨 Troubleshooting Quick Reference\n\n| Problem | Solution |\n|---------|----------|\n| HA connection fails | Check token in HA → Profile → Long-Lived Access Tokens |\n| No alerts firing | Verify entity IDs with `ha-cmd.js state list` + grep |\n| WS fails but polling works | Normal — hub auto-fallbacks to polling mode |\n| Duplicate alerts | Increase `cooldown` in rule config (seconds) |\n| **TTS no audio** | Use comma-separated Parla entities. Verify entities exist first with `state list`. |\n| Telegram not delivering | Check bot_token and chat_id in hub.json; restart telegram-deliver |\n| **\"Service domain blocked\"** | Add the domain to `call_allowlist` in hub.json (see Security section above) |\n\nFile v1.4.0:README.md\n\n# ⚠️ SECURITY & PRIVACY WARNINGS — READ BEFORE INSTALLING\n\n## 🔴 Live Device Control\nThis skill performs **real Home Assistant service calls** that change physical device states. Commands execute immediately with no confirmation or dry-run preview. Actions can:\n- Lock/unlock doors → physical security impact\n- Trigger/disable alarms → safety-critical\n- Adjust climate control → comfort/health impact\n- Open/close covers/blinds → privacy/security impact\n\n## 📡 External Data Transmission\nThis skill sends data to third-party services (Telegram Bot API, Echo devices). Alert messages include occupancy status, sensor states, and routines. Do not include sensitive personal information in alert templates. Notification content is visible on Telegram accounts and potentially logged by Telegram servers.\n\n## 🔐 Credential Sensitivity\nAll secrets (`ha_token`, `telegram_bot_token`, `telegram_chat_id`) are stored in `config/hub.json`. The HA token is a long-lived bearer token with broad API access — treat it like a password. Default URL uses plain HTTP; use HTTPS if possible to prevent credential exposure on the local network.\n\n---\n\n# Home Assistant Hub\n\nReal-time monitoring of Home Assistant device states with configurable alert rules, TTS voice notifications on Echo devices via Parla entities, Telegram delivery for alerts and events, entity inspection (states, history, persons, areas), and controlled device management through direct service calls.\n\n## What It Does\n\n1. **Monitor** home device states in real-time (polling + WebSocket)\n2. **Alert** when conditions change (battery, garage, temperature, occupancy) — delivered via Telegram or voice announcements on Echo devices\n3. **Inspect** entities: states, history, persons, areas, scenes\n4. **Control** Home Assistant services directly through `ha-cmd.js` calls\n\n### Example use cases\n\n- 🔋 **Battery monitoring**: alerts when charge drops below 20% or exceeds 95% (full charge alert)\n- 🏠 **Security monitoring**: garage door open/close, window sensors, motion detection\n- 🌡️ **Comfort monitoring**: temperature/humidity thresholds, HVAC status\n- 💡 **Device control**: turn lights on/off, set thermostat, activate scenes *(use with caution)*\n- 📢 **Voice announcements**: TTS broadcasts to Echo devices via Parla entities\n\n## How It Works\n\n```\n┌───────────┐    HTTP/WS     ┌───────────────┐   JSON file   ┌─────────────────┐\n│ Home      │ ◄──────────►  │  ha-hub.js    │ ───────────►  │ telegram-deliver│\n│ Assistant │  polling or   │  background    │               │  background     │\n│           │   WebSocket   │  monitoring   │               │  notification   │\n└───────────┘               └───────────────┘               │  delivery       │\n                                                            └────────┬────────┘\n                                                                       │ HTTPS\n                                                                 ┌─────▼──────┐\n                                                                 │ Telegram API│\n                                                                 └────────────┘\n\n┌───────────┐    HTTP          ┌───────────────┐\n│ ha-cmd.js │ ───────────────►  │ Home Assistant│   (on-demand, direct)\n│ (CLI/API) │                   │ WebSocket     │\n└───────────┘                   └───────────────┘\n```\n\n### Two background processes\n\n| Process | What it does | Frequency |\n|---------|-------------|-----------|\n| **ha-hub.js** | Connected to HA, monitors device states against alert rules | Polls every 10s (WebSocket with polling fallback) |\n| **telegram-deliver.js** | Reads pending notification files and sends via Telegram | Checks every 30s |\n\n### Notification flow\n\n1. HA device state changes (e.g., battery drops to 19%)\n2. `ha-hub.js` detects the change against active alert rules\n3. Matching rule writes a JSON file to `notifications/` directory\n4. `telegram-deliver.js` picks up the new file and sends via Telegram Bot API\n5. File is moved to `delivered/` on success\n\n### On-demand command flow (ha-cmd.js)\n\n1. Run: `node scripts/ha-cmd.js state list light`\n2. Receive device states from HA (read-only)\n\nOr for control actions:\n1. Run: `node scripts/ha-cmd.js call light.turn_on entity_id=light.living_room`\n2. **Executes immediately** — the light turns on in your home environment\n\n## Quick Start\n\n```bash\n# 1. Setup (copy config template)\ncp config/hub.example.json config/hub.json\n# Edit hub.json with your credentials — NEVER commit this file!\n\n# 2. Test connection to HA\nnode scripts/ha-cmd.js info\n\n# 3. Add alert rules (interactive or via JSON)\nnode scripts/ha-hub.js add-rule              # interactive prompt\nnode scripts/ha-hub.js add-rules << 'EOF'    # via JSON stdin\n[{\"name\":\"Low battery\",\"entity_id\":\"sensor.battery_level\",\"condition\":\"below\",\"value\":\"20\",\"cooldown\":600,\"title\":\"🪫 Battery\",\"template\":\"Battery at {{state}}% — low\"}]\nEOF\n\n# 4. Start the monitoring hub (background process)\nnode scripts/ha-hub.js start\n\n# 5. Check status\nnode scripts/ha-hub.js status\n\n# 6. Stop when done\nnode scripts/ha-hub.js stop\n```\n\n## Alert Rules\n\n### Add rule interactively\n```bash\nnode scripts/ha-hub.js add-rule\n```\n\n### Add rules via JSON (stdin)\n```bash\nnode scripts/ha-hub.js add-rules << 'EOF'\n[\n  {\n    \"name\": \"Garage opened\",\n    \"entity_id\": \"binary_sensor.garage_door\",\n    \"condition\": \"state\",\n    \"value\": \"on\",\n    \"cooldown\": 300,\n    \"title\": \"Garage\",\n    \"template\": \"The garage door is open!\"\n  },\n  {\n    \"name\": \"Low battery\",\n    \"entity_id\": \"sensor.battery_level\",\n    \"condition\": \"below\",\n    \"value\": \"20\",\n    \"cooldown\": 600,\n    \"title\": \"🪫 Battery\",\n    \"template\": \"Battery at {{state}}% — low\"\n  }\n]\nEOF\n```\n\n### List rules\n```bash\nnode scripts/ha-hub.js rules\n```\n\n### Rule conditions\n\n| Condition | Meaning | Example value |\n|-----------|---------|---------------|\n| `state` | State equals value | `on`, `home`, `open` |\n| `not_state` | State not equals value | `away` |\n| `above` | Numeric state above threshold | `25` |\n| `below` | Numeric state below threshold | `10` |\n| `changed` | Always trigger on any change | — |\n\n### Rule fields\n\n| Field | Required | Description |\n|-------|----------|-------------|\n| `name` | Yes | Human-readable rule identifier |\n| `entity_id` | Yes* | Single entity ID to monitor |\n| `entities` | Yes* | Array of entity IDs (alternative) |\n| `condition` | Yes | Condition type (see table above) |\n| `value` | Condition-dependent | Threshold or target value |\n| `cooldown` | No | Seconds between alerts (default 300) |\n| `title` | No | Alert title in notification |\n| `template` | No | Custom message template with `{{state}}` variable |\n\n*Either `entity_id` or `entities` required.\n\n## Voice Notifications (TTS)\n\nSend voice announcements to Echo devices via Parla entities. **This produces audible output inside your home environment.**\n\n```bash\n# All Echo devices simultaneously\nnode scripts/ha-cmd.js call notify.send_message \\\n  entity_id=\"notify.echo_show_5_parla,notify.echo_pop_di_vincenzo_parla\" \\\n  message=\"Dinner is ready\"\n\n# Single device\nnode scripts/ha-cmd.js call notify.send_message \\\n  entity_id=\"notify.echo_show_5_parla\" \\\n  message=\"Hello\"\n```\n\nEcho device IDs are configured in `config/hub.json` under `echo_devices`. Find available Parla entities:\n```bash\nnode scripts/ha-cmd.js state list 2>&1 | grep -i parla\n```\n\n## Telegram Integration\n\nNotifications delivered to a Telegram chat when configured. **⚠️ Alert messages are transmitted externally to Telegram servers and may expose household occupancy patterns.**\n\n```bash\nnode scripts/telegram-deliver.js start   # Start delivery process\nnode scripts/telegram-deliver.js status  # Check delivery status\nnode scripts/telegram-deliver.js stop    # Stop delivery process\n```\n\nTelegram settings in `config/hub.json`:\n```json\n\"telegram_bot_token\": \"your_bot_token\",\n\"telegram_chat_id\": \"your_chat_id\",\n\"notification_channel\": \"telegram\"   // or: \"both\" (Telegram + Echo)\n```\n\n## On-Demand Commands (`ha-cmd.js`)\n\n### Safe commands (read-only / display only)\n\n| Command | Description | Data exposed |\n|---------|-------------|--------------|\n| `node scripts/ha-cmd.js info` | HA version, URL, OS, connected clients | System metadata |\n| `node scripts/ha-cmd.js state` | All entity states snapshot | Full home telemetry |\n| `node scripts/ha-cmd.js state get <id>` | Single entity state | One sensor value |\n| `node scripts/ha-cmd.js state list <domain>` | Filter by domain (light, binary_sensor...) | Domain inventory |\n| `node scripts/ha-cmd.js scenes` | List all defined scenes | Scene configuration |\n| `node scripts/ha-cmd.js persons` | Persons + presence states | **Occupancy data** — who is home |\n| `node scripts/ha-cmd.js areas` | Areas with device counts | Home layout, device inventory |\n\n### ⚠️ Control commands (state-changing)\n\nThe `call` subcommand invokes arbitrary Home Assistant services. Executes immediately without confirmation or dry-run preview. **Actions change physical device states in your home environment.**\n\n| Command | Description |\n|---------|-------------|\n| `node scripts/ha-cmd.js call <service> [key=value ...]` | Call any HA service — executes immediately, no confirmation |\n\n#### Examples:\n\n```bash\n# TTS announcement (produces audible output)\nnode scripts/ha-cmd.js call notify.send_message \\\n  entity_id=\"notify.echo_show_5_parla\" message=\"Test\"\n\n# Turn on a light — changes physical environment\nnode scripts/ha-cmd.js call light.turn_on entity_id=light.living_room\n\n# Set thermostat temperature — affects comfort\nnode scripts/ha-cmd.js call climate.set_temperature \\\n  entity_id=climate.hvac temperature=22\n\n# Activate a scene (multi-device action)\nnode scripts/ha-cmd.js call scene.turn_on entity_id=scene.movie_time\n```\n\n**⚠️ NEVER blindly invoke `lock.*`, `alarm_control_panel.*`, or `cover.*` services.** These directly affect physical security and safety. Always verify the service behavior in HA Developer Tools first.\n\n## Hub Config (`config/hub.json`)\n\nUse `hub.example.json` as a template:\n\n```bash\ncp config/hub.example.json config/hub.json\n# Edit hub.json with your credentials — NEVER commit this file!\n```\n\n```json\n{\n  \"ha_url\": \"http://homeassistant.local:8123\",       // use https:// if available\n  \"ha_token\": \"your-long-lived-token\",               // treat as password — broad API access\n  \"poll_interval\": 10,                                // seconds between polls (WebSocket fallback)\n  \"rules\": [...],                                     // alert rules (see above)\n  \"notification_channel\": \"telegram\",                 // or: \"both\"\n  \"quiet_hours\": {                                    // suppress alerts during sleep\n    \"enabled\": true,\n    \"start\": \"22:00\",\n    \"end\": \"08:00\"\n  },\n  \"on_demand\": {                                      // local API port for ha-cmd.js\n    \"enabled\": true,\n    \"port\": 9123\n  },\n  \"telegram_bot_token\": \"...\",\n  \"telegram_chat_id\": \"...\",\n  \"echo_devices\": {\n    \"all_devices_announce_id\": \"\",                    // legacy: Alexa announce group (unused)\n    \"echo_pop_device_id\": \"notify.echo_pop_di_vincenzo_parla\",\n    \"echo_show_device_id\": \"notify.echo_show_5_parla\"\n  }\n}\n```\n\n## 🔕 Quiet Hours\n\nSuppress alerts during sleep in `config/hub.json`:\n\n```json\n\"quiet_hours\": {\n  \"enabled\": true,\n  \"start\": \"22:00\",\n  \"end\": \"08:00\"\n}\n```\n\nRules during quiet hours are silently suppressed. To override (e.g., urgent alert), call `notify.send_message` directly — it bypasses rules entirely.\n\n## 🚨 Troubleshooting\n\n| Problem | Solution |\n|---------|----------|\n| Connection fails | Check token in HA → Profile → Long-Lived Access Tokens |\n| No alerts firing | Verify entity IDs with `node scripts/ha-cmd.js state list` + grep |\n| WS fails but polling works | Normal — hub auto-fallbacks to polling mode |\n| Duplicate alerts | Increase `cooldown` in rule config (seconds) |\n| TTS no audio | Use comma-separated Parla entities. Verify with `state list`. |\n| Telegram not delivering | Check bot_token and chat_id in hub.json; restart telegram-deliver |\n\n## Directory Structure\n\n```\nskills/home-assistant-hub/\n├── SKILL.md              ← skill description (read first)\n├── README.md             ← this file (user-facing documentation)\n├── config/\n│   ├── hub.json          ← runtime config (secrets - gitignored, never commit)\n│   └── hub.example.json  ← template with safe defaults\n├── scripts/\n│   ├── ha-hub.js         ← monitoring engine (WebSocket + polling)\n│   ├── telegram-deliver.js ← notification delivery daemon\n│   └── ha-cmd.js         ← on-demand CLI: read-only commands + service calls\n├── notifications/        ← pending notifications (gitignored)\n├── delivered/            ← successfully delivered notifications (gitignored)\n├── logs/                 ← daily rotation logs (gitignored)\n├── references/\n│   └── setup.md          ← detailed installation guide\n├── start.sh              ← portable quick-start script\n├── daemon.sh             ← persistent background daemon wrapper\n└── .gitignore\n```\n\nFile v1.4.0:_meta.json\n\n{\n  \"ownerId\": \"kn7438bzbbzvnb37f1vmr6y141854jsa\",\n  \"slug\": \"home-assistant-hub\",\n  \"version\": \"1.4.0\",\n  \"publishedAt\": 1783795120401\n}\n\nFile v1.4.0:references/setup.md\n\n# Home Assistant Hub — Setup Guide\n\n## ⚠️ Security Warning\n\nYou are about to create a **long-lived bearer token** with broad API access to your Home Assistant instance. Treat this token like a password:\n\n- Never share it publicly or commit it to version control\n- The file `config/hub.json` is gitignored — verify `.gitignore` includes it\n- Rotate the token in HA if you suspect compromise (Profile → Long-Lived Access Tokens → Revoke)\n\n## 1. Get a Long-Lived Access Token\n\n1. Open Home Assistant → Profile (bottom-left)\n2. Scroll to **Long-Lived Access Tokens**\n3. Click **CREATE TOKEN**\n4. Name it `openclaw-hub`\n5. **Copy the token** (shown only once!)\n\n## 2. Configure the Hub\n\n```bash\ncd ~/.openclaw/workspace/skills/home-assistant-hub\nnode scripts/ha-hub.js setup\n```\n\nEnter your HA URL and token when prompted.\n\n## 3. Test Connection\n\n```bash\nnode scripts/ha-hub.js test\n```\n\nShould show your HA version.\n\n## 4. Add Alert Rules\n\n### Interactive:\n```bash\nnode scripts/ha-hub.js add-rule\n```\n\n### Via JSON (recommended for bulk):\n```bash\nnode scripts/ha-hub.js add-rules << 'EOF'\n[\n  {\n    \"name\": \"Garage aperto\",\n    \"entity_id\": \"binary_sensor.garage_door\",\n    \"condition\": \"state\",\n    \"value\": \"on\",\n    \"cooldown\": 300,\n    \"title\": \"Garage\",\n    \"template\": \"Il garage è aperto!\"\n  },\n  {\n    \"name\": \"Temperatura bassa\",\n    \"entity_id\": \"sensor.temperatura_interna\",\n    \"condition\": \"below\",\n    \"value\": \"15\",\n    \"cooldown\": 600,\n    \"title\": \"🌡️ Temperatura\",\n    \"template\": \"Temperatura bassa: {{state}}°C\"\n  },\n  {\n    \"name\": \"Persone via\",\n    \"entities\": [\"person.vincenzo\", \"person.maria\"],\n    \"condition\": \"not_state\",\n    \"value\": \"home\",\n    \"cooldown\": 900,\n    \"title\": \"🏠 Tutti fuori\",\n    \"template\": \"Nessuno è in casa\"\n  }\n]\nEOF\n```\n\n## 5. Start the Hub\n\n```bash\nnode scripts/ha-hub.js start\n```\n\nVerify:\n```bash\nnode scripts/ha-hub.js status\n```\n\n## 6. Stop the Hub\n\n```bash\nnode scripts/ha-hub.js stop\n```\n\n## Alert Rules Reference\n\n### Conditions\n\n| Condition | Meaning | Example value |\n|-----------|---------|---------------|\n| `state` | State equals value | `on`, `home`, `open` |\n| `not_state` | State not equals value | `away` |\n| `above` | State (numeric) above value | `25` |\n| `below` | State (numeric) below value | `10` |\n| `changed` | Always trigger on change | — |\n\n### Fields\n\n| Field | Required | Description |\n|-------|----------|-------------|\n| `name` | Yes | Rule identifier |\n| `entity_id` | Yes* | Single entity ID |\n| `entities` | Yes* | Array of entity IDs |\n| `condition` | Yes | See table above |\n| `value` | Condition-dependent | Value to compare |\n| `cooldown` | No | Seconds between alerts (default 300) |\n| `title` | No | Alert title (default \"HA Alert\") |\n| `template` | No | Custom message (default: entity: old → new) |\n| `channel` | No | Notification channel (default: config value) |\n| `priority` | No | `normal` or `urgent` |\n\n*Either `entity_id` or `entities` required.\n\n## Quiet Hours\n\nDisable alerts during sleep in `config/hub.json`:\n\n```json\n\"quiet_hours\": {\n  \"enabled\": true,\n  \"start\": \"23:00\",\n  \"end\": \"07:00\"\n}\n```\n\nRules during quiet hours are silently suppressed.\n\n## Troubleshooting\n\n| Problem | Solution |\n|---------|----------|\n| Connection failed | Check HA URL and token |\n| Hub won't start | Check token is valid in HA |\n| No alerts firing | Verify entity IDs with `node scripts/ha-cmd.js state` |\n| Duplicate alerts | Increase `cooldown` in rule config |\n| WS fails, polling works | Normal — polling is the fallback |\n\nFile v1.4.0:skill-card.md\n\n## Description: <br>\nHome Assistant Hub monitors Home Assistant device states, sends Telegram or Echo alerts, inspects entities, and supports guarded service calls. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[vincsta](https://clawhub.ai/user/vincsta) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nExternal developers and Home Assistant users use this skill to monitor household device state, configure alerts, inspect entities, and run controlled Home Assistant service commands from an agent workflow. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: Home Assistant service calls can change physical device states, including security, alarm, climate, and cover devices. <br>\nMitigation: Set a non-empty call_allowlist before using control commands and verify each entity and service in Home Assistant before execution. <br>\nRisk: The skill reads long-lived Home Assistant and Telegram credentials from config/hub.json. <br>\nMitigation: Protect config/hub.json like a password file, keep it out of version control, prefer HTTPS for Home Assistant, and rotate tokens if exposure is suspected. <br>\nRisk: Telegram alerts and Echo announcements can expose occupancy, routines, sensor states, or security details outside the local workflow. <br>\nMitigation: Avoid sensitive personal content in alert templates and assume Telegram-delivered notifications may leave the home network. <br>\n\n\n## Reference(s): <br>\n- [Home Assistant Hub setup guide](artifact/references/setup.md) <br>\n- [Home Assistant Hub on ClawHub](https://clawhub.ai/vincsta/skills/home-assistant-hub) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [Text, Markdown, Shell commands, Configuration, JSON, Guidance] <br>\n**Output Format:** [Markdown guidance with inline shell commands and JSON configuration examples] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [May start local background processes, create notification JSON files, and call external Home Assistant or Telegram APIs when the user runs the provided commands.] <br>\n\n## Skill Version(s): <br>\n1.4.0 (source: server release evidence) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nFile v1.4.0:config/hub.example.json\n\n{\n  \"ha_url\": \"http://homeassistant.local:8123\",\n  \"ha_token\": \"YOUR_LONG_LIVED_TOKEN_HERE\",\n  \"poll_interval\": 10,\n  \"rules\": [],\n  \"notification_channel\": \"telegram\",\n  \"quiet_hours\": {\n    \"enabled\": false,\n    \"start\": \"23:00\",\n    \"end\": \"07:00\"\n  },\n  \"on_demand\": {\n    \"enabled\": false,\n    \"port\": 9123\n  },\n  \"call_allowlist\": [],\n  \"telegram_bot_token\": \"YOUR_TELEGRAM_BOT_TOKEN_HERE\",\n  \"telegram_chat_id\": \"YOUR_CHAT_ID_HERE\",\n  \"echo_devices\": {\n    \"all_devices_announce_id\": \"\",\n    \"echo_pop_device_id\": \"\",\n    \"echo_show_device_id\": \"\"\n  }\n}\n\nFile v1.4.0:notifications/test-1783363352.json\n\n{\"title\": \"🧪 Test OpenClaw\", \"template\": \"Integrazione Home Assistant configurata! Se leggi questo, Telegram e gli Echo sono pronti.\", \"timestamp\": \"2026-07-06T18:42:32Z\", \"source\": \"openclaw-test\"}\n\nArchive v1.3.0: 12 files, 27134 bytes\n\nFiles: _meta.json (137b), config/hub.example.json (536b), daemon.sh (484b), notifications/test-1783363352.json (202b), README.md (13733b), references/setup.md (3542b), scripts/ha-cmd.js (9106b), scripts/ha-hub.js (20266b), scripts/telegram-deliver.js (8370b), skill-card.md (2870b), SKILL.md (15342b), start.sh (334b)\n\nFile v1.3.0:SKILL.md\n\n---\nname: \"home-assistant-hub\"\ndescription: \"Real-time Home Assistant monitoring, alert rules, TTS voice notifications on Echo devices, Telegram delivery, entity inspection, and controlled device management.\"\nhomepage: https://github.com/openclaw/openclaw\nmetadata:\n  {\n    \"openclaw\":\n      {\n        \"emoji\": \"🏡\",\n        \"requires\": { \"bins\": [\"node\"] },\n        \"permissions\": [\n          { \"kind\": \"network\", \"direction\": \"outbound\", \"targets\": [\"Home Assistant API/WebSocket (HTTP + WSS)\", \"Telegram Bot API (HTTPS)\", \"Echo devices via HA notify service\"], \"reason\": \"Real-time monitoring of home device states, alert delivery to Telegram servers, and voice announcements on Echo devices require outbound network connections\" },\n          { \"kind\": \"network\", \"direction\": \"local-bind\", \"targets\": [\"localhost:9123 (on-demand API)\"], \"reason\": \"Local HTTP API for ha-cmd.js service calls when configured\" },\n          { \"kind\": \"secrets\", \"direction\": \"local-read\", \"targets\": [\"config/hub.json\"], \"reason\": \"Reads HA long-lived bearer token, Telegram bot token, and chat ID. File is gitignored — never commit to version control\" }\n        ]\n      },\n  }\n---\n\n# ⚠️ SECURITY & PRIVACY WARNINGS — READ FIRST\n\n## 🔴 Device Control — Real-World Impact\nThis skill performs **live Home Assistant service calls** that change physical device states. Commands execute **immediately with no confirmation or dry-run**. Actions can:\n- Lock/unlock doors → **physical security impact**\n- Trigger/disable alarms → **safety-critical**\n- Adjust climate control → **comfort/health impact**\n- Open/close covers/blinds → **privacy/security impact**\n\n**Before calling ANY service:** verify the entity and action in HA Developer Tools. Never blindly invoke `lock.*`, `alarm_control_panel.*`, or `cover.*` services.\n\n## 📡 External Data Transmission\nThis skill transmits data to third-party services:\n- **Telegram Bot API** — alert messages including occupancy, sensor states, routines → exposes household patterns and security-relevant information\n- **Echo devices via HA** — TTS announcements broadcast inside the home environment\n- **Home Assistant instance** — all device telemetry sent over network\n\n**Do NOT include sensitive personal data in alert templates.** Notification content is visible on Telegram accounts and potentially logged by Telegram servers.\n\n## 🔐 Credential Sensitivity\nAll secrets (`ha_token`, `telegram_bot_token`, `telegram_chat_id`) are stored in `config/hub.json`. This file is gitignored but:\n- The HA token is a **long-lived bearer token** with broad API access — treat it like a password\n- Default `ha_url` uses plain HTTP → credentials transmitted in cleartext on the local network. Use HTTPS if possible.\n\n## 🔧 Process Management\nThe hub runs as background processes (`nohup`, `disown`) that persist beyond your session. `pkill -f \"ha-hub.js start\"` can match multiple processes. Always verify process state before killing.\n\n---\n\n# Home Assistant Hub\n\nReal-time monitoring of Home Assistant device states with configurable alert rules, TTS voice notifications on Echo devices via Parla entities, Telegram delivery for alerts and events, entity inspection (states, history, persons, areas), and controlled device management through direct service calls.\n\n## Architecture Overview\n\n```\n┌───────────┐    HTTP/WS     ┌───────────────┐   JSON file   ┌─────────────────┐\n│ Home      │ ◄──────────►  │  ha-hub.js    │ ───────────►  │ telegram-deliver│\n│ Assistant │  polling or   │  background    │               │  background     │\n│           │   WebSocket   │  monitoring   │               │  notification   │\n└───────────┘               └───────────────┘               │  delivery       │\n                                                            └────────┬────────┘\n                                                                       │ HTTPS\n                                                                 ┌─────▼──────┐\n                                                                 │ Telegram API│\n                                                                 └────────────┘\n\n┌───────────┐    HTTP          ┌───────────────┐\n│ ha-cmd.js │ ───────────────►  │ Home Assistant│   (on-demand, direct)\n│ (CLI/API) │                   │ WebSocket     │\n└───────────┘                   └───────────────┘\n```\n\n**Two background processes:**\n| Process | Role | Frequency |\n|---------|------|-----------|\n| `ha-hub.js` | Connected to HA, monitors device states against alert rules | Polls every 10s (WS fallback) |\n| `telegram-deliver.js` | Reads pending notification files and sends via Telegram | Checks every 30s |\n\n## Permissions\n\n| Permission | Direction | Targets | Reason |\n|-----------|-----------|---------|--------|\n| `network` | outbound | Home Assistant API/WebSocket (HTTP+WSS), Telegram Bot API (HTTPS), Echo devices via HA notify | Real-time home monitoring, alert delivery to third-party servers, voice announcements |\n| `network` | local-bind | localhost:9123 (on-demand HTTP API) | Local service for ha-cmd.js when enabled in config |\n| `secrets` | local-read | `config/hub.json` | HA long-lived bearer token + Telegram credentials. File is gitignored — never commit |\n\n## Quick Start\n\n```bash\ncd skills/home-assistant-hub\n\n# Test connection to HA (safe, read-only)\nnode scripts/ha-cmd.js info\n\n# List entities containing \"echo\" or \"parla\" (safe, read-only)\nnode scripts/ha-cmd.js state list 2>&1 | grep -i echo\n\n# Start the monitoring hub (background process)\nnode scripts/ha-hub.js start\n\n# Check hub status\nnode scripts/ha-hub.js status\n\n# Stop the hub\nnode scripts/ha-hub.js stop\n```\n\n## 📋 Safe Commands (Read-Only / Display)\n\nThese commands only **read** data from Home Assistant. No device state changes:\n\n| Command | What it does | Data exposed |\n|---------|-------------|--------------|\n| `node scripts/ha-cmd.js info` | HA version, URL, OS, connected clients | System metadata |\n| `node scripts/ha-cmd.js state` | All entity states at once | Full home telemetry snapshot |\n| `node scripts/ha-cmd.js state get <id>` | Single entity state (e.g., `sensor.battery_level`) | One sensor value |\n| `node scripts/ha-cmd.js state list <domain>` | Filter entities by domain (`light`, `binary_sensor`, etc.) | Domain-level inventory |\n| `node scripts/ha-cmd.js scenes` | List all defined scenes | Scene configuration |\n| `node scripts/ha-cmd.js persons` | List persons + presence states | Occupancy data — who is home |\n| `node scripts/ha-cmd.js areas` | Areas with device counts | Home layout and device inventory |\n\n## 🗣️ Voice Notifications (TTS)\n\nSends voice announcements to Echo devices via HA Parla entities. **This produces audible output in your physical environment.**\n\nUse **comma-separated entity IDs** — do NOT pass a JSON array:\n\n```bash\n# Send to ALL configured Echo devices simultaneously\nnode scripts/ha-cmd.js call notify.send_message \\\n  entity_id=\"notify.echo_show_5_parla,notify.echo_pop_di_vincenzo_parla\" \\\n  message=\"Ciao Vincenzo, la batteria è al 75 percento\"\n\n# Single device\nnode scripts/ha-cmd.js call notify.send_message \\\n  entity_id=\"notify.echo_show_5_parla\" \\\n  message=\"La cena è pronta\"\n```\n\n**Find Parla entity IDs:** `node scripts/ha-cmd.js state list 2>&1 | grep -i parla`\n\n### Troubleshooting TTS\n- **\"400 Bad Request\"** → wrong format. Use comma-separated string, not array.\n- **\"Success\" but no audio** → verify: (1) Parla entities exist in HA, (2) an automation listens for `notify.send_message`, (3) Echo devices are online/unmuted.\n- **Verify delivery:** check timestamp updated: `node scripts/ha-cmd.js state get notify.echo_show_5_parla | grep last_updated`\n\n## 📋 Alert Rules\n\nConfigurable rules that detect device state changes and trigger notifications via Telegram or voice announcements.\n\n### Add rule interactively\n```bash\nnode scripts/ha-hub.js add-rule\n```\n\n### Add rules via JSON (stdin)\n```bash\nnode scripts/ha-hub.js add-rules << 'EOF'\n[\n  {\n    \"name\": \"Garage aperto\",\n    \"entity_id\": \"binary_sensor.garage_door\",\n    \"condition\": \"state\",\n    \"value\": \"on\",\n    \"cooldown\": 300,\n    \"title\": \"Garage\",\n    \"template\": \"Il garage è aperto!\"\n  },\n  {\n    \"name\": \"Batteria bassa\",\n    \"entity_id\": \"sensor.battery_level\",\n    \"condition\": \"below\",\n    \"value\": \"20\",\n    \"cooldown\": 600,\n    \"title\": \"🪫 Batteria\",\n    \"template\": \"Batteria al {{state}}% — serve attenzione\"\n  }\n]\nEOF\n```\n\n### List rules\n```bash\nnode scripts/ha-hub.js rules\n```\n\n### Rule conditions\n\n| Condition | Meaning | Example value |\n|-----------|---------|---------------|\n| `state` | State equals value | `on`, `home`, `open` |\n| `not_state` | State not equals value | `away` |\n| `above` | Numeric state above threshold | `25` |\n| `below` | Numeric state below threshold | `10` |\n| `changed` | Always trigger on any change | — |\n\n## 📱 Telegram Integration\n\nAlerts are delivered to a Telegram chat when configured. **⚠️ Data is transmitted externally to Telegram servers.** Alert content includes entity states, occupancy information, and home status. Avoid including sensitive personal data in alert templates.\n\n```bash\nnode scripts/telegram-deliver.js start   # Start delivery process\nnode scripts/telegram-deliver.js status  # Check delivery status\nnode scripts/telegram-deliver.js stop    # Stop delivery process\n```\n\nTelegram settings in `config/hub.json`:\n```json\n\"telegram_bot_token\": \"your_bot_token\",\n\"telegram_chat_id\": \"your_chat_id\",\n\"notification_channel\": \"telegram\"   // or: \"both\" (Telegram + Echo)\n```\n\n### Notification flow\n1. HA device state changes (e.g., battery drops to 19%)\n2. `ha-hub.js` detects change against active alert rules\n3. Matching rule writes a JSON file to `notifications/` directory\n4. `telegram-deliver.js` picks up the new file and sends to Telegram\n5. File is moved to `delivered/` on successful delivery\n\n## 🔧 On-Demand Commands (`ha-cmd.js`)\n\nAll commands run from the skill directory:\n```bash\ncd skills/home-assistant-hub\n```\n\n### Safe (read-only / display) commands:\n\n| Command | Description |\n|---------|-------------|\n| `node scripts/ha-cmd.js info` | HA version, URL, OS |\n| `node scripts/ha-cmd.js state` | All entity states |\n| `node scripts/ha-cmd.js state get <id>` | Specific entity (e.g., sensor.battery) |\n| `node scripts/ha-cmd.js state list <domain>` | Filter by domain (light, binary_sensor...) |\n| `node scripts/ha-cmd.js scenes` | List all defined scenes |\n| `node scripts/ha-cmd.js persons` | List persons + presence states |\n| `node scripts/ha-cmd.js areas` | Areas with device counts |\n\n### ⚠️ Control commands (state-changing) — use with caution:\n\nThe `call` subcommand invokes **arbitrary Home Assistant services** and executes immediately without confirmation or dry-run. These actions change physical device states in your home environment.\n\n| Command | Description |\n|---------|-------------|\n| `node scripts/ha-cmd.js call <service> [key=value ...]` | Call any HA service — **executes immediately, no confirmation** |\n\n#### Examples (understand the impact before running):\n\n```bash\n# TTS announcement on Echo devices\nnode scripts/ha-cmd.js call notify.send_message \\\n  entity_id=\"notify.echo_show_5_parla\" message=\"Prova vocale\"\n\n# Turn on a light — changes physical environment\nnode scripts/ha-cmd.js call light.turn_on entity_id=light.living_room\n\n# Set thermostat temperature — affects comfort\nnode scripts/ha-cmd.js call climate.set_temperature \\\n  entity_id=climate.hvac temperature=22\n\n# Activate a scene (multi-device action)\nnode scripts/ha-cmd.js call scene.turn_on entity_id=scene.movie_time\n\n# Trigger an automation\nnode scripts/ha-cmd.js call automation.trigger entity_id=automation.my_automation\n```\n\n## 🔑 Hub Config (`config/hub.json`)\n\nUse `hub.example.json` as a template:\n\n```bash\ncp config/hub.example.json config/hub.json\n# Edit hub.json with your credentials — NEVER commit this file!\n```\n\n```json\n{\n  \"ha_url\": \"http://homeassistant.local:8123\",       // use https:// if available\n  \"ha_token\": \"your-long-lived-token\",               // treat as password\n  \"poll_interval\": 10,                                // seconds between polls\n  \"rules\": [...],                                     // alert rules (see above)\n  \"notification_channel\": \"telegram\",                 // or: \"both\"\n  \"quiet_hours\": {                                    // suppress alerts during sleep\n    \"enabled\": true,\n    \"start\": \"22:30\",\n    \"end\": \"08:30\"\n  },\n  \"on_demand\": {                                      // local API port for ha-cmd.js\n    \"enabled\": true,\n    \"port\": 9123\n  },\n  \"telegram_bot_token\": \"...\",\n  \"telegram_chat_id\": \"...\",\n  \"echo_devices\": {\n    \"all_devices_announce_id\": \"\",                    // legacy: Alexa announce group (unused)\n    \"echo_pop_device_id\": \"notify.echo_pop_di_vincenzo_parla\",\n    \"echo_show_device_id\": \"notify.echo_show_5_parla\"\n  }\n}\n```\n\n## 🔕 Quiet Hours\n\nSuppress alerts during sleep in `config/hub.json`:\n\n```json\n\"quiet_hours\": {\n  \"enabled\": true,\n  \"start\": \"22:00\",\n  \"end\": \"08:00\"\n}\n```\n\nRules during quiet hours are silently suppressed. To override (e.g., urgent alert), call `notify.send_message` directly — it bypasses rules entirely.\n\n## 📁 Architecture\n\n```\nskills/home-assistant-hub/\n├── SKILL.md              ← this file (read first!)\n├── config/\n│   ├── hub.json          ← runtime config (secrets, gitignored)\n│   └── hub.example.json  ← template with safe defaults\n├── scripts/\n│   ├── ha-hub.js         ← WebSocket + polling monitoring engine\n│   ├── telegram-deliver.js ← Telegram notification delivery daemon\n│   └── ha-cmd.js         ← on-demand read-only + service call CLI\n├── notifications/        ← pending notification JSON files (gitignored)\n├── delivered/            ← successfully delivered notifications (gitignored)\n├── logs/                 ← daily rotation logs (gitignored)\n├── references/\n│   └── setup.md          ← detailed setup guide\n├── start.sh              ← portable quick-start script\n├── daemon.sh             ← persistent daemon wrapper\n└── .gitignore\n```\n\n## 🚨 Troubleshooting Quick Reference\n\n| Problem | Solution |\n|---------|----------|\n| HA connection fails | Check token in HA → Profile → Long-Lived Access Tokens |\n| No alerts firing | Verify entity IDs with `ha-cmd.js state list` + grep |\n| WS fails but polling works | Normal — hub auto-fallbacks to polling mode |\n| Duplicate alerts | Increase `cooldown` in rule config (seconds) |\n| **TTS no audio** | Use comma-separated Parla entities. Verify entities exist first with `state list`. |\n| Telegram not delivering | Check bot_token and chat_id in hub.json; restart telegram-deliver |\n\nFile v1.3.0:README.md\n\n# ⚠️ SECURITY & PRIVACY WARNINGS — READ BEFORE INSTALLING\n\n## 🔴 Live Device Control\nThis skill performs **real Home Assistant service calls** that change physical device states. Commands execute immediately with no confirmation or dry-run preview. Actions can:\n- Lock/unlock doors → physical security impact\n- Trigger/disable alarms → safety-critical\n- Adjust climate control → comfort/health impact\n- Open/close covers/blinds → privacy/security impact\n\n## 📡 External Data Transmission\nThis skill sends data to third-party services (Telegram Bot API, Echo devices). Alert messages include occupancy status, sensor states, and routines. Do not include sensitive personal information in alert templates. Notification content is visible on Telegram accounts and potentially logged by Telegram servers.\n\n## 🔐 Credential Sensitivity\nAll secrets (`ha_token`, `telegram_bot_token`, `telegram_chat_id`) are stored in `config/hub.json`. The HA token is a long-lived bearer token with broad API access — treat it like a password. Default URL uses plain HTTP; use HTTPS if possible to prevent credential exposure on the local network.\n\n---\n\n# Home Assistant Hub\n\nReal-time monitoring of Home Assistant device states with configurable alert rules, TTS voice notifications on Echo devices via Parla entities, Telegram delivery for alerts and events, entity inspection (states, history, persons, areas), and controlled device management through direct service calls.\n\n## What It Does\n\n1. **Monitor** home device states in real-time (polling + WebSocket)\n2. **Alert** when conditions change (battery, garage, temperature, occupancy) — delivered via Telegram or voice announcements on Echo devices\n3. **Inspect** entities: states, history, persons, areas, scenes\n4. **Control** Home Assistant services directly through `ha-cmd.js` calls\n\n### Example use cases\n\n- 🔋 **Battery monitoring**: alerts when charge drops below 20% or exceeds 95% (full charge alert)\n- 🏠 **Security monitoring**: garage door open/close, window sensors, motion detection\n- 🌡️ **Comfort monitoring**: temperature/humidity thresholds, HVAC status\n- 💡 **Device control**: turn lights on/off, set thermostat, activate scenes *(use with caution)*\n- 📢 **Voice announcements**: TTS broadcasts to Echo devices via Parla entities\n\n## How It Works\n\n```\n┌───────────┐    HTTP/WS     ┌───────────────┐   JSON file   ┌─────────────────┐\n│ Home      │ ◄──────────►  │  ha-hub.js    │ ───────────►  │ telegram-deliver│\n│ Assistant │  polling or   │  background    │               │  background     │\n│           │   WebSocket   │  monitoring   │               │  notification   │\n└───────────┘               └───────────────┘               │  delivery       │\n                                                            └────────┬────────┘\n                                                                       │ HTTPS\n                                                                 ┌─────▼──────┐\n                                                                 │ Telegram API│\n                                                                 └────────────┘\n\n┌───────────┐    HTTP          ┌───────────────┐\n│ ha-cmd.js │ ───────────────►  │ Home Assistant│   (on-demand, direct)\n│ (CLI/API) │                   │ WebSocket     │\n└───────────┘                   └───────────────┘\n```\n\n### Two background processes\n\n| Process | What it does | Frequency |\n|---------|-------------|-----------|\n| **ha-hub.js** | Connected to HA, monitors device states against alert rules | Polls every 10s (WebSocket with polling fallback) |\n| **telegram-deliver.js** | Reads pending notification files and sends via Telegram | Checks every 30s |\n\n### Notification flow\n\n1. HA device state changes (e.g., battery drops to 19%)\n2. `ha-hub.js` detects the change against active alert rules\n3. Matching rule writes a JSON file to `notifications/` directory\n4. `telegram-deliver.js` picks up the new file and sends via Telegram Bot API\n5. File is moved to `delivered/` on success\n\n### On-demand command flow (ha-cmd.js)\n\n1. Run: `node scripts/ha-cmd.js state list light`\n2. Receive device states from HA (read-only)\n\nOr for control actions:\n1. Run: `node scripts/ha-cmd.js call light.turn_on entity_id=light.living_room`\n2. **Executes immediately** — the light turns on in your home environment\n\n## Quick Start\n\n```bash\n# 1. Setup (copy config template)\ncp config/hub.example.json config/hub.json\n# Edit hub.json with your credentials — NEVER commit this file!\n\n# 2. Test connection to HA\nnode scripts/ha-cmd.js info\n\n# 3. Add alert rules (interactive or via JSON)\nnode scripts/ha-hub.js add-rule              # interactive prompt\nnode scripts/ha-hub.js add-rules << 'EOF'    # via JSON stdin\n[{\"name\":\"Low battery\",\"entity_id\":\"sensor.battery_level\",\"condition\":\"below\",\"value\":\"20\",\"cooldown\":600,\"title\":\"🪫 Battery\",\"template\":\"Battery at {{state}}% — low\"}]\nEOF\n\n# 4. Start the monitoring hub (background process)\nnode scripts/ha-hub.js start\n\n# 5. Check status\nnode scripts/ha-hub.js status\n\n# 6. Stop when done\nnode scripts/ha-hub.js stop\n```\n\n## Alert Rules\n\n### Add rule interactively\n```bash\nnode scripts/ha-hub.js add-rule\n```\n\n### Add rules via JSON (stdin)\n```bash\nnode scripts/ha-hub.js add-rules << 'EOF'\n[\n  {\n    \"name\": \"Garage opened\",\n    \"entity_id\": \"binary_sensor.garage_door\",\n    \"condition\": \"state\",\n    \"value\": \"on\",\n    \"cooldown\": 300,\n    \"title\": \"Garage\",\n    \"template\": \"The garage door is open!\"\n  },\n  {\n    \"name\": \"Low battery\",\n    \"entity_id\": \"sensor.battery_level\",\n    \"condition\": \"below\",\n    \"value\": \"20\",\n    \"cooldown\": 600,\n    \"title\": \"🪫 Battery\",\n    \"template\": \"Battery at {{state}}% — low\"\n  }\n]\nEOF\n```\n\n### List rules\n```bash\nnode scripts/ha-hub.js rules\n```\n\n### Rule conditions\n\n| Condition | Meaning | Example value |\n|-----------|---------|---------------|\n| `state` | State equals value | `on`, `home`, `open` |\n| `not_state` | State not equals value | `away` |\n| `above` | Numeric state above threshold | `25` |\n| `below` | Numeric state below threshold | `10` |\n| `changed` | Always trigger on any change | — |\n\n### Rule fields\n\n| Field | Required | Description |\n|-------|----------|-------------|\n| `name` | Yes | Human-readable rule identifier |\n| `entity_id` | Yes* | Single entity ID to monitor |\n| `entities` | Yes* | Array of entity IDs (alternative) |\n| `condition` | Yes | Condition type (see table above) |\n| `value` | Condition-dependent | Threshold or target value |\n| `cooldown` | No | Seconds between alerts (default 300) |\n| `title` | No | Alert title in notification |\n| `template` | No | Custom message template with `{{state}}` variable |\n\n*Either `entity_id` or `entities` required.\n\n## Voice Notifications (TTS)\n\nSend voice announcements to Echo devices via Parla entities. **This produces audible output inside your home environment.**\n\n```bash\n# All Echo devices simultaneously\nnode scripts/ha-cmd.js call notify.send_message \\\n  entity_id=\"notify.echo_show_5_parla,notify.echo_pop_di_vincenzo_parla\" \\\n  message=\"Dinner is ready\"\n\n# Single device\nnode scripts/ha-cmd.js call notify.send_message \\\n  entity_id=\"notify.echo_show_5_parla\" \\\n  message=\"Hello\"\n```\n\nEcho device IDs are configured in `config/hub.json` under `echo_devices`. Find available Parla entities:\n```bash\nnode scripts/ha-cmd.js state list 2>&1 | grep -i parla\n```\n\n## Telegram Integration\n\nNotifications delivered to a Telegram chat when configured. **⚠️ Alert messages are transmitted externally to Telegram servers and may expose household occupancy patterns.**\n\n```bash\nnode scripts/telegram-deliver.js start   # Start delivery process\nnode scripts/telegram-deliver.js status  # Check delivery status\nnode scripts/telegram-deliver.js stop    # Stop delivery process\n```\n\nTelegram settings in `config/hub.json`:\n```json\n\"telegram_bot_token\": \"your_bot_token\",\n\"telegram_chat_id\": \"your_chat_id\",\n\"notification_channel\": \"telegram\"   // or: \"both\" (Telegram + Echo)\n```\n\n## On-Demand Commands (`ha-cmd.js`)\n\n### Safe commands (read-only / display only)\n\n| Command | Description | Data exposed |\n|---------|-------------|--------------|\n| `node scripts/ha-cmd.js info` | HA version, URL, OS, connected clients | System metadata |\n| `node scripts/ha-cmd.js state` | All entity states snapshot | Full home telemetry |\n| `node scripts/ha-cmd.js state get <id>` | Single entity state | One sensor value |\n| `node scripts/ha-cmd.js state list <domain>` | Filter by domain (light, binary_sensor...) | Domain inventory |\n| `node scripts/ha-cmd.js scenes` | List all defined scenes | Scene configuration |\n| `node scripts/ha-cmd.js persons` | Persons + presence states | **Occupancy data** — who is home |\n| `node scripts/ha-cmd.js areas` | Areas with device counts | Home layout, device inventory |\n\n### ⚠️ Control commands (state-changing)\n\nThe `call` subcommand invokes arbitrary Home Assistant services. Executes immediately without confirmation or dry-run preview. **Actions change physical device states in your home environment.**\n\n| Command | Description |\n|---------|-------------|\n| `node scripts/ha-cmd.js call <service> [key=value ...]` | Call any HA service — executes immediately, no confirmation |\n\n#### Examples:\n\n```bash\n# TTS announcement (produces audible output)\nnode scripts/ha-cmd.js call notify.send_message \\\n  entity_id=\"notify.echo_show_5_parla\" message=\"Test\"\n\n# Turn on a light — changes physical environment\nnode scripts/ha-cmd.js call light.turn_on entity_id=light.living_room\n\n# Set thermostat temperature — affects comfort\nnode scripts/ha-cmd.js call climate.set_temperature \\\n  entity_id=climate.hvac temperature=22\n\n# Activate a scene (multi-device action)\nnode scripts/ha-cmd.js call scene.turn_on entity_id=scene.movie_time\n```\n\n**⚠️ NEVER blindly invoke `lock.*`, `alarm_control_panel.*`, or `cover.*` services.** These directly affect physical security and safety. Always verify the service behavior in HA Developer Tools first.\n\n## Hub Config (`config/hub.json`)\n\nUse `hub.example.json` as a template:\n\n```bash\ncp config/hub.example.json config/hub.json\n# Edit hub.json with your credentials — NEVER commit this file!\n```\n\n```json\n{\n  \"ha_url\": \"http://homeassistant.local:8123\",       // use https:// if available\n  \"ha_token\": \"your-long-lived-token\",               // treat as password — broad API access\n  \"poll_interval\": 10,                                // seconds between polls (WebSocket fallback)\n  \"rules\": [...],                                     // alert rules (see above)\n  \"notification_channel\": \"telegram\",                 // or: \"both\"\n  \"quiet_hours\": {                                    // suppress alerts during sleep\n    \"enabled\": true,\n    \"start\": \"22:00\",\n    \"end\": \"08:00\"\n  },\n  \"on_demand\": {                                      // local API port for ha-cmd.js\n    \"enabled\": true,\n    \"port\": 9123\n  },\n  \"telegram_bot_token\": \"...\",\n  \"telegram_chat_id\": \"...\",\n  \"echo_devices\": {\n    \"all_devices_announce_id\": \"\",                    // legacy: Alexa announce group (unused)\n    \"echo_pop_device_id\": \"notify.echo_pop_di_vincenzo_parla\",\n    \"echo_show_device_id\": \"notify.echo_show_5_parla\"\n  }\n}\n```\n\n## 🔕 Quiet Hours\n\nSuppress alerts during sleep in `config/hub.json`:\n\n```json\n\"quiet_hours\": {\n  \"enabled\": true,\n  \"start\": \"22:00\",\n  \"end\": \"08:00\"\n}\n```\n\nRules during quiet hours are silently suppressed. To override (e.g., urgent alert), call `notify.send_message` directly — it bypasses rules entirely.\n\n## 🚨 Troubleshooting\n\n| Problem | Solution |\n|---------|----------|\n| Connection fails | Check token in HA → Profile → Long-Lived Access Tokens |\n| No alerts firing | Verify entity IDs with `node scripts/ha-cmd.js state list` + grep |\n| WS fails but polling works | Normal — hub auto-fallbacks to polling mode |\n| Duplicate alerts | Increase `cooldown` in rule config (seconds) |\n| TTS no audio | Use comma-separated Parla entities. Verify with `state list`. |\n| Telegram not delivering | Check bot_token and chat_id in hub.json; restart telegram-deliver |\n\n## Directory Structure\n\n```\nskills/home-assistant-hub/\n├── SKILL.md              ← skill description (read first)\n├── README.md             ← this file (user-facing documentation)\n├── config/\n│   ├── hub.json          ← runtime config (secrets - gitignored, never commit)\n│   └── hub.example.json  ← template with safe defaults\n├── scripts/\n│   ├── ha-hub.js         ← monitoring engine (WebSocket + polling)\n│   ├── telegram-deliver.js ← notification delivery daemon\n│   └── ha-cmd.js         ← on-demand CLI: read-only commands + service calls\n├── notifications/        ← pending notifications (gitignored)\n├── delivered/            ← successfully delivered notifications (gitignored)\n├── logs/                 ← daily rotation logs (gitignored)\n├── references/\n│   └── setup.md          ← detailed installation guide\n├── start.sh              ← portable quick-start script\n├── daemon.sh             ← persistent background daemon wrapper\n└── .gitignore\n```\n\nFile v1.3.0:_meta.json\n\n{\n  \"ownerId\": \"kn7438bzbbzvnb37f1vmr6y141854jsa\",\n  \"slug\": \"home-assistant-hub\",\n  \"version\": \"1.3.0\",\n  \"publishedAt\": 1783788961359\n}\n\nFile v1.3.0:references/setup.md\n\n# Home Assistant Hub — Setup Guide\n\n## ⚠️ Security Warning\n\nYou are about to create a **long-lived bearer token** with broad API access to your Home Assistant instance. Treat this token like a password:\n\n- Never share it publicly or commit it to version control\n- The file `config/hub.json` is gitignored — verify `.gitignore` includes it\n- Rotate the token in HA if you suspect compromise (Profile → Long-Lived Access Tokens → Revoke)\n\n## 1. Get a Long-Lived Access Token\n\n1. Open Home Assistant → Profile (bottom-left)\n2. Scroll to **Long-Lived Access Tokens**\n3. Click **CREATE TOKEN**\n4. Name it `openclaw-hub`\n5. **Copy the token** (shown only once!)\n\n## 2. Configure the Hub\n\n```bash\ncd ~/.openclaw/workspace/skills/home-assistant-hub\nnode scripts/ha-hub.js setup\n```\n\nEnter your HA URL and token when prompted.\n\n## 3. Test Connection\n\n```bash\nnode scripts/ha-hub.js test\n```\n\nShould show your HA version.\n\n## 4. Add Alert Rules\n\n### Interactive:\n```bash\nnode scripts/ha-hub.js add-rule\n```\n\n### Via JSON (recommended for bulk):\n```bash\nnode scripts/ha-hub.js add-rules << 'EOF'\n[\n  {\n    \"name\": \"Garage aperto\",\n    \"entity_id\": \"binary_sensor.garage_door\",\n    \"condition\": \"state\",\n    \"value\": \"on\",\n    \"cooldown\": 300,\n    \"title\": \"Garage\",\n    \"template\": \"Il garage è aperto!\"\n  },\n  {\n    \"name\": \"Temperatura bassa\",\n    \"entity_id\": \"sensor.temperatura_interna\",\n    \"condition\": \"below\",\n    \"value\": \"15\",\n    \"cooldown\": 600,\n    \"title\": \"🌡️ Temperatura\",\n    \"template\": \"Temperatura bassa: {{state}}°C\"\n  },\n  {\n    \"name\": \"Persone via\",\n    \"entities\": [\"person.vincenzo\", \"person.maria\"],\n    \"condition\": \"not_state\",\n    \"value\": \"home\",\n    \"cooldown\": 900,\n    \"title\": \"🏠 Tutti fuori\",\n    \"template\": \"Nessuno è in casa\"\n  }\n]\nEOF\n```\n\n## 5. Start the Hub\n\n```bash\nnode scripts/ha-hub.js start\n```\n\nVerify:\n```bash\nnode scripts/ha-hub.js status\n```\n\n## 6. Stop the Hub\n\n```bash\nnode scripts/ha-hub.js stop\n```\n\n## Alert Rules Reference\n\n### Conditions\n\n| Condition | Meaning | Example value |\n|-----------|---------|---------------|\n| `state` | State equals value | `on`, `home`, `open` |\n| `not_state` | State not equals value | `away` |\n| `above` | State (numeric) above value | `25` |\n| `below` | State (numeric) below value | `10` |\n| `changed` | Always trigger on change | — |\n\n### Fields\n\n| Field | Required | Description |\n|-------|----------|-------------|\n| `name` | Yes | Rule identifier |\n| `entity_id` | Yes* | Single entity ID |\n| `entities` | Yes* | Array of entity IDs |\n| `condition` | Yes | See table above |\n| `value` | Condition-dependent | Value to compare |\n| `coold\n\nArchive v1.2.5: 12 files, 24058 bytes\n\nFiles: _meta.json (137b), config/hub.example.json (536b), daemon.sh (484b), notifications/test-1783363352.json (202b), README.md (7989b), references/setup.md (3542b), scripts/ha-cmd.js (9106b), scripts/ha-hub.js (20266b), scripts/telegram-deliver.js (8370b), skill-card.md (2644b), SKILL.md (12274b), start.sh (334b)\n\nArchive v1.2.4: 12 files, 23910 bytes\n\nFiles: _meta.json (137b), config/hub.example.json (536b), daemon.sh (459b), notifications/test-1783363352.json (202b), README.md (7989b), references/setup.md (3542b), scripts/ha-cmd.js (9106b), scripts/ha-hub.js (20266b), scripts/telegram-deliver.js (8370b), skill-card.md (2240b), SKILL.md (12274b), start.sh (309b)\n\nArchive v1.2.3: 13 files, 24557 bytes\n\nFiles: _meta.json (137b), config/hub.example.json (536b), config/hub.json (687b), daemon.sh (459b), notifications/test-1783363352.json (202b), README.md (7989b), references/setup.md (3542b), scripts/ha-cmd.js (9106b), scripts/ha-hub.js (20266b), scripts/telegram-deliver.js (8370b), skill-card.md (2598b), SKILL.md (12274b), start.sh (309b)\n\nArchive v1.2.2: 13 files, 23600 bytes\n\nFiles: _meta.json (137b), config/hub.example.json (536b), config/hub.json (687b), daemon.sh (459b), notifications/test-1783363352.json (202b), README.md (7989b), references/setup.md (3542b), scripts/ha-cmd.js (9106b), scripts/ha-hub.js (20266b), scripts/telegram-deliver.js (8370b), skill-card.md (2374b), SKILL.md (9162b), start.sh (309b)\n\nArchive v1.2.1: 10 files, 22693 bytes\n\nFiles: config/hub.example.json (536b), README.md (7989b), references/setup.md (3542b), scripts/ha-cmd.js (9106b), scripts/ha-hub.js (27948b), scripts/telegram-deliver.js (8370b), skill-card.md (2504b), SKILL.md (5963b), start.sh (105b), _meta.json (137b)\n\nArchive v1.2.0: 10 files, 22248 bytes\n\nFiles: config/hub.example.json (536b), README.md (7989b), references/setup.md (3131b), scripts/ha-cmd.js (9106b), scripts/ha-hub.js (27948b), scripts/telegram-deliver.js (8370b), skill-card.md (2447b), SKILL.md (5542b), start.sh (105b), _meta.json (137b)","readmeExcerpt":"Skill: Home Assistant Hub Owner: vincsta Summary: Real-time Home Assistant monitoring, alert rules, TTS voice notifications on Echo devices, Telegram delivery, entity inspection. Service calls are HARD-DENIE... Tags: automation:1.2.1, echo:1.2.1, home-assistant:1.2.1, latest:1.5.1, telegram:1.2.1, tts:1.2.1 Version history: v1.5.1 | 2026-07-11T20:24:28.974Z | auto home-assistant-hub v1.5.1 - Removed the skill-card.md","codeSnippets":[],"executableExamples":[{"language":"json","snippet":"\"call_safe_domains\": [\"light\", \"climate\", \"scene\", \"media_player\", \"automation\", \"notify\"]"},{"language":"bash","snippet":"node scripts/ha-cmd.js call climate.set_temperature entity_id=climate.hvac temperature=22 --dry-run\n# Output: Service URL + payload WITHOUT executing\n\n\n## 📡 External Data Transmission\nThis skill transmits data to third-party services:\n- **Telegram Bot API** — alert messages including occupancy, sensor states, routines → exposes household patterns and security-relevant information\n- **Echo devices via HA** — TTS announcements broadcast inside the home environment\n- **Home Assistant instance** — all device telemetry sent over network\n\n**Do NOT include sensitive personal data in alert templates.** Notification content is visible on Telegram accounts and potentially logged by Telegram servers.\n\n### 🚫 No Hardcoded Credentials\nAll credentials are loaded exclusively from `config/hub.json`. There are no hardcoded fallback tokens anywhere in the codebase. If `telegram_bot_token` or `telegram_chat_id` are missing, the deliverer will refuse to send (with a warning) rather than fall back to defaults.\n\n## 🔐 Credential Sensitivity\nAll secrets (`ha_token`, `telegram_bot_token`, `telegram_chat_id`) are stored in `config/hub.json`. This file is gitignored but:\n- The HA token is a **long-lived bearer token** with broad API access — treat it like a password\n- Default `ha_url` uses plain HTTP → credentials transmitted in cleartext on the local network. Use HTTPS if possible.\n- Rotate tokens regularly via HA → Profile → Long-Lived Access Tokens\n\n## 🔧 Process Management\nThe hub runs as background processes (`nohup`, `disown`) that persist beyond your session. `pkill -f \"ha-hub.js start\"` can match multiple processes. Always verify process state before killing.\n\n---\n\n# Home Assistant Hub\n\nReal-time monitoring of Home Assistant device states with configurable alert rules, TTS voice notifications on Echo devices via Parla entities, Telegram delivery for alerts and events, entity inspection (states, history, persons, areas), and controlled device management through direct service calls.\n"},{"language":"text","snippet":"**Two background processes:**\n| Process | Role | Frequency |\n|---------|------|-----------|\n| `ha-hub.js` | Connected to HA, monitors device states against alert rules | Polls every 10s (WS fallback) |\n| `telegram-deliver.js` | Reads pending notification files and sends via Telegram | Checks every 30s |\n\n## Permissions\n\n| Permission | Direction | Targets | Reason |\n|-----------|-----------|---------|---------|\n| `network` | outbound | Home Assistant API/WebSocket (HTTP+WSS), Telegram Bot API (HTTPS), Echo devices via HA notify | Real-time home monitoring, alert delivery to third-party servers, voice announcements |\n| `network` | local-bind | localhost:9123 (on-demand HTTP API) — **disabled by default** | Local service for ha-cmd.js when enabled in config |\n| `secrets` | local-read | `config/hub.json` | HA long-lived bearer token + Telegram credentials. File is gitignored — never commit |\n\n## Quick Start"},{"language":"text","snippet":"## 📋 Safe Commands (Read-Only / Display)\n\nThese commands only **read** data from Home Assistant. No device state changes:\n\n| Command | What it does | Data exposed |\n|---------|-------------|-------------|\n| `node scripts/ha-cmd.js info` | HA version, URL, OS, connected clients | System metadata |\n| `node scripts/ha-cmd.js state` | All entity states at once | Full home telemetry snapshot |\n| `node scripts/ha-cmd.js state get <id>` | Single entity state (e.g., `sensor.battery_level`) | One sensor value |\n| `node scripts/ha-cmd.js state list <domain>` | Filter entities by domain (`light`, `binary_sensor`, etc.) | Domain-level inventory |\n| `node scripts/ha-cmd.js scenes` | List all defined scenes | Scene configuration |\n| `node scripts/ha-cmd.js persons` | List persons + presence states | Occupancy data — who is home |\n| `node scripts/ha-cmd.js areas` | Areas with device counts | Home layout and device inventory |\n\n## 🗣️ Voice Notifications (TTS)\n\nSends voice announcements to Echo devices via HA Parla entities. **This produces audible output in your physical environment.**\n\nUse **comma-separated entity IDs** — do NOT pass a JSON array:"},{"language":"text","snippet":"**Find Parla entity IDs:** `node scripts/ha-cmd.js state list 2>&1 | grep -i parla`\n\n### Troubleshooting TTS\n- **\"400 Bad Request\"** → wrong format. Use comma-separated string, not array.\n- **\"Success\" but no audio** → verify: (1) Parla entities exist in HA, (2) an automation listens for `notify.send_message`, (3) Echo devices are online/unmuted.\n- **Verify delivery:** check timestamp updated: `node scripts/ha-cmd.js state get notify.echo_show_5_parla | grep last_updated`\n\n## 📋 Alert Rules\n\nConfigurable rules that detect device state changes and trigger notifications via Telegram or voice announcements.\n\n### Add rule interactively"},{"language":"text","snippet":"### Add rules via JSON (stdin)"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: \"home-assistant-hub\"\ndescription: \"Real-time Home Assistant monitoring, alert rules, TTS voice notifications on Echo devices, Telegram delivery, entity inspection. Service calls are HARD-DENIED by default — require explicit safe-domains opt-in.\"\nhomepage: https://github.com/openclaw/openclaw\nmetadata:\n  {\n    \"openclaw\":\n      {\n        \"emoji\": \"🏡\",\n        \"requires\": { \"bins\": [\"node\"] },\n        \"permissions\": [\n          { \"kind\": \"network\", \"direction\": \"outbound\", \"targets\": [\"Home Assistant API/WebSocket (HTTP + WSS)\", \"Telegram Bot API (HTTPS)\", \"Echo devices via HA notify service\"], \"reason\": \"Real-time monitoring of home device states, alert delivery to Telegram servers, and voice announcements on Echo devices require outbound network connections\" },\n          { \"kind\": \"network\", \"direction\": \"local-bind\", \"targets\": [\"localhost:9123 (on-demand API)\"], \"reason\": \"Local HTTP API for ha-cmd.js service calls when configured. Disabled by default.\" },\n          { \"kind\": \"secrets\", \"direction\": \"local-read\", \"targets\": [\"config/hub.json\"], \"reason\": \"Reads HA long-lived bearer token, Telegram bot token, and chat ID. File is gitignored — never commit to version control\" }\n        ]\n      },\n  }\n---\n\n# ⚠️ SECURITY & PRIVACY WARNINGS — READ FIRST\n\n## 🔴 Device Control — Hardened Defaults\nThis skill can invoke Home Assistant services to change physical device states. **Service calls are disabled by default.**\n\n### ⛔ Always Blocked (never configurable)\nThe following domains are HARD-LOCKED in code and cannot be enabled:\n- `lock.*` — door locks (physical security)\n- `alarm_control_panel.*` — alarm systems (safety-critical)\n- `cover.*` — blinds/doors/garage (privacy/security)\n\n### ✅ Safe Domains — Explicit Opt-In Required\nService calls require domains to be listed in `call_safe_domains` in `config/hub.json`. **An empty list means all service calls are blocked.**\n\nDefault safe domains in the example config: `light`, `climate`, `scene`, `media_player`, `automation`, `notify`\n\nTo add a new domain, edit hub.json:\n```json\n\"call_safe_domains\": [\"light\", \"climate\", \"scene\", \"media_player\", \"automation\", \"notify\"]\n```\n\n### 🔍 Dry-Run Mode\nBefore executing any service call, use `--dry-run` to preview what would happen:\n```bash\nnode scripts/ha-cmd.js call climate.set_temperature entity_id=climate.hvac temperature=22 --dry-run\n# Output: Service URL + payload WITHOUT executing\n\n\n## 📡 External Data Transmission\nThis skill transmits data to third-party services:\n- **Telegram Bot API** — alert messages including occupancy, sensor states, routines → exposes household patterns and security-relevant information\n- **Echo devices via HA** — TTS announcements broadcast inside the home environment\n- **Home Assistant instance** — all device telemetry sent over network\n\n**Do NOT include sensitive personal data in alert templates.** Notification content is visible on Telegram accounts and potentially logged by Telegram servers.\n\n### 🚫 No Hardcoded Credential"},{"path":"README.md","content":"# ⚠️ SECURITY & PRIVACY WARNINGS — READ BEFORE INSTALLING\n\n## 🔴 Live Device Control — Hardened Defaults\nThis skill can invoke Home Assistant services to change physical device states. **Service calls are DISABLED BY DEFAULT.**\n\n### Always Blocked (never configurable)\nThe following domains are HARD-LOCKED in code:\n- `lock.*` → door locks (physical security)\n- `alarm_control_panel.*` → alarm systems (safety-critical)\n- `cover.*` → blinds/doors/garage (privacy/security)\n\n### Safe Domains — Explicit Opt-In Required\nService calls require domains to be listed in `call_safe_domains` in `config/hub.json`. **An empty list blocks all service calls.**\n\nDefault safe domains: `light`, `climate`, `scene`, `media_player`, `automation`, `notify`\n\n### Dry-Run Mode\nAlways use `--dry-run` first to preview what would be called:\n```bash\nnode scripts/ha-cmd.js call climate.set_temperature entity_id=climate.hvac temperature=22 --dry-run\n# Shows: Service URL + payload WITHOUT executing\n\n## 📡 External Data Transmission\nThis skill sends data to third-party services (Telegram Bot API, Echo devices). Alert messages include occupancy status, sensor states, and routines. Do not include sensitive personal information in alert templates. Notification content is visible on Telegram accounts and potentially logged by Telegram servers.\n\n## 🔐 Credential Sensitivity\nAll secrets (`ha_token`, `telegram_bot_token`, `telegram_chat_id`) are stored in `config/hub.json`. The HA token is a long-lived bearer token with broad API access — treat it like a password. Default URL uses plain HTTP; use HTTPS if possible to prevent credential exposure on the local network.\n\n---\n\n# Home Assistant Hub\n\nReal-time monitoring of Home Assistant device states with configurable alert rules, TTS voice notifications on Echo devices via Parla entities, Telegram delivery for alerts and events, entity inspection (states, history, persons, areas), and controlled device management through direct service calls.\n\n## What It Does\n\n1. **Monitor** home device states in real-time (polling + WebSocket)\n2. **Alert** when conditions change (battery, garage, temperature, occupancy) — delivered via Telegram or voice announcements on Echo devices\n3. **Inspect** entities: states, history, persons, areas, scenes\n4. **Control** Home Assistant services directly through `ha-cmd.js` calls\n\n### Example use cases\n\n- 🔋 **Battery monitoring**: alerts when charge drops below 20% or exceeds 95% (full charge alert)\n- 🏠 **Security monitoring**: garage door open/close, window sensors, motion detection\n- 🌡️ **Comfort monitoring**: temperature/humidity thresholds, HVAC status\n- 💡 **Device control**: turn lights on/off, set thermostat, activate scenes *(use with caution)*\n- 📢 **Voice announcements**: TTS broadcasts to Echo devices via Parla entities\n\n## How It Works\n\n```\n┌───────────┐    HTTP/WS     ┌───────────────┐   JSON file   ┌─────────────────┐\n│ Home      │ ◄──────────►  │  ha-hub.js    │ ───────────►  │ telegram-deliver│\n│ Assi"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7438bzbbzvnb37f1vmr6y141854jsa\",\n  \"slug\": \"home-assistant-hub\",\n  \"version\": \"1.5.1\",\n  \"publishedAt\": 1783801468974\n}"},{"path":"references/setup.md","content":"# Home Assistant Hub — Setup Guide\n\n## ⚠️ Security Warning\n\nYou are about to create a **long-lived bearer token** with broad API access to your Home Assistant instance. Treat this token like a password:\n\n- Never share it publicly or commit it to version control\n- The file `config/hub.json` is gitignored — verify `.gitignore` includes it\n- Rotate the token in HA if you suspect compromise (Profile → Long-Lived Access Tokens → Revoke)\n\n## 1. Get a Long-Lived Access Token\n\n1. Open Home Assistant → Profile (bottom-left)\n2. Scroll to **Long-Lived Access Tokens**\n3. Click **CREATE TOKEN**\n4. Name it `openclaw-hub`\n5. **Copy the token** (shown only once!)\n\n## 2. Configure the Hub\n\n```bash\ncd ~/.openclaw/workspace/skills/home-assistant-hub\nnode scripts/ha-hub.js setup\n```\n\nEnter your HA URL and token when prompted.\n\n## 3. Test Connection\n\n```bash\nnode scripts/ha-hub.js test\n```\n\nShould show your HA version.\n\n## 4. Add Alert Rules\n\n### Interactive:\n```bash\nnode scripts/ha-hub.js add-rule\n```\n\n### Via JSON (recommended for bulk):\n```bash\nnode scripts/ha-hub.js add-rules << 'EOF'\n[\n  {\n    \"name\": \"Garage aperto\",\n    \"entity_id\": \"binary_sensor.garage_door\",\n    \"condition\": \"state\",\n    \"value\": \"on\",\n    \"cooldown\": 300,\n    \"title\": \"Garage\",\n    \"template\": \"Il garage è aperto!\"\n  },\n  {\n    \"name\": \"Temperatura bassa\",\n    \"entity_id\": \"sensor.temperatura_interna\",\n    \"condition\": \"below\",\n    \"value\": \"15\",\n    \"cooldown\": 600,\n    \"title\": \"🌡️ Temperatura\",\n    \"template\": \"Temperatura bassa: {{state}}°C\"\n  },\n  {\n    \"name\": \"Persone via\",\n    \"entities\": [\"person.vincenzo\", \"person.maria\"],\n    \"condition\": \"not_state\",\n    \"value\": \"home\",\n    \"cooldown\": 900,\n    \"title\": \"🏠 Tutti fuori\",\n    \"template\": \"Nessuno è in casa\"\n  }\n]\nEOF\n```\n\n## 5. Start the Hub\n\n```bash\nnode scripts/ha-hub.js start\n```\n\nVerify:\n```bash\nnode scripts/ha-hub.js status\n```\n\n## 6. Stop the Hub\n\n```bash\nnode scripts/ha-hub.js stop\n```\n\n## Alert Rules Reference\n\n### Conditions\n\n| Condition | Meaning | Example value |\n|-----------|---------|---------------|\n| `state` | State equals value | `on`, `home`, `open` |\n| `not_state` | State not equals value | `away` |\n| `above` | State (numeric) above value | `25` |\n| `below` | State (numeric) below value | `10` |\n| `changed` | Always trigger on change | — |\n\n### Fields\n\n| Field | Required | Description |\n|-------|----------|-------------|\n| `name` | Yes | Rule identifier |\n| `entity_id` | Yes* | Single entity ID |\n| `entities` | Yes* | Array of entity IDs |\n| `condition` | Yes | See table above |\n| `value` | Condition-dependent | Value to compare |\n| `cooldown` | No | Seconds between alerts (default 300) |\n| `title` | No | Alert title (default \"HA Alert\") |\n| `template` | No | Custom message (default: entity: old → new) |\n| `channel` | No | Notification channel (default: config value) |\n| `priority` | No | `normal` or `urgent` |\n\n*Either `entity_id` or `entities` required.\n\n## Quiet Hours\n\nDisable alerts during sleep in `confi"},{"path":"skill-card.md","content":"## Description:\n\nProvides real-time Home Assistant monitoring, alert rules, Echo voice notifications, Telegram delivery, entity inspection, and opt-in service calls.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[vincsta](https://clawhub.ai/user/vincsta)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nExternal developers and Home Assistant users use this skill to monitor device states, define alert rules, inspect entities, send Telegram or Echo notifications, and execute explicitly allowed Home Assistant service calls.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Home Assistant and Telegram credentials may be exposed through local configuration or unencrypted Home Assistant connections.\n\nMitigation: Use HTTPS/WSS, store secrets only in a gitignored config file with restricted permissions, and rotate long-lived tokens if exposure is suspected.\n\nRisk: Allowed service-call domains can change physical devices and may permit broader automation effects than intended.\n\nMitigation: Keep service calls disabled until needed, remove scene and automation from call_safe_domains unless fully audited, and test changes with dry-run first.\n\nRisk: Alert messages sent to Telegram or Echo devices can reveal household state, occupancy, routines, or other sensitive context.\n\nMitigation: Avoid sensitive personal data in templates and route notifications only to trusted Telegram chats and intended Echo devices.\n\nRisk: The provided start script can stop unintended processes because of broad pkill matching.\n\nMitigation: Avoid start.sh until its process matching is narrowed, and verify process state before stopping background services.\n\n## Reference(s):\n\n- [Home Assistant Hub setup guide](references/setup.md)\n- [ClawHub skill page](https://clawhub.ai/vincsta/skills/home-assistant-hub)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Code, Shell commands, Configuration, Guidance]\n\n**Output Format:** [Markdown guidance with inline shell commands, JSON configuration examples, and code references]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [May produce Home Assistant service-call examples, alert-rule definitions, setup steps, and operational guidance that should be reviewed before execution.]\n\n## Skill Version(s):\n\n1.5.1 (source: server release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment."}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":null,"editorialQuality":{"score":100,"threshold":65,"status":"thin","wordCount":1905,"uniquenessScore":42,"reasons":["uniqueness-below-45"]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-10T06:02:38.802Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-10T06:02:38.802Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-10T10:53:13.204Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}