various tidyups
This commit is contained in:
+1
-1
@@ -1 +1 @@
|
|||||||
{"pid": 74, "version": 1, "ha_version": "2026.7.3", "start_ts": 1784842567.418518}
|
{"pid": 70, "version": 1, "ha_version": "2026.7.4", "start_ts": 1785317114.2667625}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
# Your own instructions for OpenCode
|
||||||
|
|
||||||
|
Rename this file to `AGENTS.local.md` (drop the `.example`) and OpenCode will read
|
||||||
|
it at the start of every session, alongside the add-on's own `AGENTS.md`.
|
||||||
|
|
||||||
|
- The add-on **never** writes to `AGENTS.local.md`. Add-on updates cannot overwrite it.
|
||||||
|
- Delete the file to stop loading it. There is no setting to toggle.
|
||||||
|
- `AGENTS.md` wins if the two ever conflict — safety rules and approval requirements
|
||||||
|
stay in force regardless of what you put here.
|
||||||
|
- Everything in this file is sent to the model with **every** request, so keep it
|
||||||
|
short and specific. A page of standing preferences is useful; a diary is not.
|
||||||
|
- Never put passwords, tokens, or API keys here. Reference them with `!secret` instead.
|
||||||
|
|
||||||
|
Delete the examples below and write your own.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## About my setup
|
||||||
|
|
||||||
|
- All Zigbee devices go through Zigbee2MQTT, not ZHA. Do not suggest ZHA workflows.
|
||||||
|
- The house has three floors: basement, main, upstairs. Areas are named after rooms.
|
||||||
|
- Presence detection is unreliable in the garage — treat those sensors with suspicion.
|
||||||
|
|
||||||
|
## How I want you to work
|
||||||
|
|
||||||
|
- New configuration goes in `packages/`, one file per feature. Do not grow
|
||||||
|
`configuration.yaml`.
|
||||||
|
- Prefer template sensors over automations that write to `input_number` helpers.
|
||||||
|
- Name entities `<area>_<device>_<function>`, for example `kitchen_ceiling_brightness`.
|
||||||
|
- Always show me the diff before writing, even for one-line changes.
|
||||||
|
|
||||||
|
## Leave these alone
|
||||||
|
|
||||||
|
- Anything under `custom_components/` — those are managed through HACS.
|
||||||
|
- The `packages/energy.yaml` file. It is tuned and I do not want it reformatted.
|
||||||
|
|
||||||
|
## Useful context
|
||||||
|
|
||||||
|
- My electricity tariff changes at 07:00 and 22:00; automations that care about
|
||||||
|
cost should use those boundaries.
|
||||||
|
- The Sonos speakers drop off the network occasionally. That is expected, not a
|
||||||
|
configuration bug.
|
||||||
+807
@@ -0,0 +1,807 @@
|
|||||||
|
# Home Assistant OpenCode Rules
|
||||||
|
|
||||||
|
You are working directly within a Home Assistant installation. Your working directory is `/homeassistant`, which is the live Home Assistant configuration directory.
|
||||||
|
|
||||||
|
## CRITICAL: User Consent and Scope Rules
|
||||||
|
|
||||||
|
You MUST follow these rules strictly:
|
||||||
|
|
||||||
|
1. **Never exceed the user's request** - Do exactly what the user asks, nothing more. Do not "improve" or "enhance" beyond the stated scope.
|
||||||
|
|
||||||
|
2. **Never make changes without explicit approval** - Before modifying ANY file:
|
||||||
|
- Show the user exactly what you plan to change
|
||||||
|
- Wait for their explicit confirmation ("yes", "go ahead", "do it", etc.)
|
||||||
|
- If they haven't approved, DO NOT proceed
|
||||||
|
|
||||||
|
3. **Ask, don't assume** - If the user's request is ambiguous:
|
||||||
|
- Ask clarifying questions first
|
||||||
|
- Present options and let them choose
|
||||||
|
- Never guess at their intent
|
||||||
|
|
||||||
|
4. **Read-only by default** - When investigating or troubleshooting:
|
||||||
|
- Only read files and gather information
|
||||||
|
- Present findings and recommendations
|
||||||
|
- Wait for user instruction before making any changes
|
||||||
|
|
||||||
|
5. **One change at a time** - When making approved changes:
|
||||||
|
- Make the minimum change needed
|
||||||
|
- Show what was changed
|
||||||
|
- Let the user verify before proceeding to any next step
|
||||||
|
|
||||||
|
6. **No unsolicited modifications** - Never:
|
||||||
|
- "Clean up" code the user didn't ask about
|
||||||
|
- Add features they didn't request
|
||||||
|
- Refactor working configurations
|
||||||
|
- Fix issues they haven't mentioned
|
||||||
|
|
||||||
|
7. **Respect "no"** - If a user declines a suggestion, do not:
|
||||||
|
- Repeat the suggestion
|
||||||
|
- Make the change anyway
|
||||||
|
- Try to convince them otherwise
|
||||||
|
|
||||||
|
## Environment Context
|
||||||
|
|
||||||
|
- You are running inside the OpenCode app
|
||||||
|
- The current directory (`/homeassistant`) contains the live Home Assistant configuration
|
||||||
|
- Changes to YAML files here directly affect the Home Assistant instance
|
||||||
|
- If add-on folder access is enabled, `/addons` and `/addon_configs` are available for Home Assistant add-on development. Treat `/addon_configs` as sensitive and only inspect or modify these folders when the user explicitly asks.
|
||||||
|
- You may have access to MCP tools for interacting with Home Assistant (check with the user)
|
||||||
|
|
||||||
|
## Home Assistant Interaction Model
|
||||||
|
|
||||||
|
There are three primary, safe ways to interact with Home Assistant:
|
||||||
|
|
||||||
|
### 1. Configuration Files (YAML)
|
||||||
|
The standard way to define and customize Home Assistant behavior:
|
||||||
|
- Automations, scripts, scenes, and blueprints
|
||||||
|
- Integration and sensor configurations
|
||||||
|
- Templates, packages, and customizations
|
||||||
|
- Dashboard (Lovelace) definitions
|
||||||
|
|
||||||
|
These files are designed for user editing and are the source of truth for your Home Assistant setup.
|
||||||
|
|
||||||
|
### 2. MCP Tools (Runtime API)
|
||||||
|
Real-time interaction with the running Home Assistant instance:
|
||||||
|
- Query current entity states and history
|
||||||
|
- Control devices and call services
|
||||||
|
- Validate configurations
|
||||||
|
- Diagnose issues and detect anomalies
|
||||||
|
- Report OpenCode/HA agent capability status with `get_agent_capabilities`
|
||||||
|
|
||||||
|
### Native Home Assistant LLM Platform
|
||||||
|
Home Assistant is developing a native `llm` integration where Core integrations and custom integrations can expose curated tools through `<integration>/llm.py` and registered LLM APIs. New Home Assistant builds may also expose those APIs over native MCP endpoints such as `/api/mcp/<API ID>`; the built-in Assist API uses `/api/mcp/assist`. This is complementary to OpenCode MCP, not a replacement.
|
||||||
|
|
||||||
|
- If the optional `homeassistant_native` MCP server is available, prefer it for requests that fit the configured native Home Assistant LLM API because those tools are curated by Home Assistant.
|
||||||
|
- Use OpenCode MCP for configuration editing, safe writes, validation, admin/dev workflows, screenshots, updates, ESPHome, `hab`, Zigbee tasks, add-on development, and Home Assistant documentation lookup.
|
||||||
|
- Use `get_agent_capabilities` or `ha://agent/capabilities` to check whether the running HA instance reports the native `llm` component and native MCP endpoints.
|
||||||
|
- Use `get_home_context` for compact area/domain/entity understanding before broad state dumps.
|
||||||
|
- Use `get_ha_llm_development_guide` when helping develop or review a custom integration's native `<integration>/llm.py` provider.
|
||||||
|
- Do not assume this add-on can register tools directly with HA's native `llm` platform; native tool registration is internal to HA integrations/custom integrations. The add-on can consume configured native LLM APIs through native MCP when Home Assistant exposes them.
|
||||||
|
|
||||||
|
### 3. hab CLI (Home Assistant Builder)
|
||||||
|
A CLI tool designed for AI agents to manage Home Assistant. Run `hab` commands via the terminal:
|
||||||
|
- **Entity management**: `hab entity list`, `hab entity get light.living_room`, `hab entity logbook sensor.power --start 2h`
|
||||||
|
- **Service calls**: `hab action call light.turn_on --entity light.living_room --data '{"brightness": 200}'`
|
||||||
|
- **Automation CRUD**: `hab automation list`, `hab automation create`, `hab automation delete`
|
||||||
|
- **Dashboard management**: `hab dashboard list`, `hab dashboard view create`
|
||||||
|
- **Area/floor/zone/label**: `hab area list`, `hab area create "Kitchen"`
|
||||||
|
- **Helpers**: `hab helper list`, `hab helper create`
|
||||||
|
- **Scripts**: `hab script list`, `hab script create`
|
||||||
|
- **Scenes**: `hab scene list`, `hab scene create`, `hab scene activate "Movie Time"`
|
||||||
|
- **Blueprints**: `hab blueprint list`
|
||||||
|
- **Backups**: `hab backup list`, `hab backup create`
|
||||||
|
- **System**: `hab system info`, `hab system health`, `hab overview`
|
||||||
|
- **Devices**: `hab device list`
|
||||||
|
- **People**: `hab person list`, `hab person create`, `hab person update`
|
||||||
|
- **Categories**: `hab category list`, `hab category assign --entity light.kitchen`
|
||||||
|
- **To-do lists**: `hab todo list`, `hab todo item list todo.shopping`, `hab todo item add todo.shopping "Milk"`
|
||||||
|
- **Notifications**: `hab notification list`, `hab notification create --message "Hello" --title "Alert"`
|
||||||
|
- **Integrations**: `hab integration list`, `hab integration reload hue`, `hab integration disable mqtt`
|
||||||
|
- **Repairs**: `hab repairs list`, `hab repairs ignore <issue_id>`
|
||||||
|
- **Events**: `hab event list`, `hab event fire my_custom_event --data '{"key": "value"}'`
|
||||||
|
- **Templates**: `hab template render --expression "{{ states('sensor.temperature') }}"`
|
||||||
|
- **Search**: `hab search related`
|
||||||
|
|
||||||
|
`hab` outputs human-readable text by default. Use `--json` for structured JSON output (ideal for parsing).
|
||||||
|
`hab` is pre-authenticated via the Supervisor token - no login required.
|
||||||
|
Run `hab --help` or `hab <command> --help` for full usage details.
|
||||||
|
|
||||||
|
<!-- HAB_LIVE_HELP_START -->
|
||||||
|
```
|
||||||
|
Home Assistant Builder (hab) is a CLI utility designed for LLMs
|
||||||
|
to build and manage Home Assistant configurations.
|
||||||
|
|
||||||
|
Interactive sessions default to human-readable text. Non-interactive sessions default to JSON.
|
||||||
|
|
||||||
|
Start with 'hab guide' for workflow-level guidance optimized for LLM and agent usage.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
hab [command]
|
||||||
|
|
||||||
|
Getting Started:
|
||||||
|
auth Manage authentication
|
||||||
|
capability Inspect runtime capabilities
|
||||||
|
guide Display built-in usage guides
|
||||||
|
overview Show an overview of the Home Assistant instance
|
||||||
|
schema Show machine-readable command schema
|
||||||
|
|
||||||
|
Registry:
|
||||||
|
area Manage areas
|
||||||
|
device Manage devices
|
||||||
|
entity Manage entities
|
||||||
|
floor Manage floors
|
||||||
|
label Manage labels
|
||||||
|
person Manage persons
|
||||||
|
search Search for items and relationships
|
||||||
|
zone Manage zones
|
||||||
|
|
||||||
|
Automation:
|
||||||
|
action Call actions (services)
|
||||||
|
automation Manage automations
|
||||||
|
blueprint Manage blueprints
|
||||||
|
category Manage categories
|
||||||
|
helper Manage groups, templates, and other helpers
|
||||||
|
scene Manage scenes
|
||||||
|
script Manage scripts
|
||||||
|
|
||||||
|
Dashboard:
|
||||||
|
dashboard Manage dashboards
|
||||||
|
|
||||||
|
Other:
|
||||||
|
backup Manage backups
|
||||||
|
calendar Manage calendar events
|
||||||
|
diagnostics Manage diagnostics handlers
|
||||||
|
energy Manage energy dashboard settings
|
||||||
|
esphome Manage ESPHome devices
|
||||||
|
event Manage Home Assistant events
|
||||||
|
integration Manage integrations
|
||||||
|
network Manage network settings
|
||||||
|
notification Manage persistent notifications
|
||||||
|
repairs Manage Home Assistant repairs
|
||||||
|
system Manage system
|
||||||
|
template Work with Home Assistant templates
|
||||||
|
thread Manage Thread credentials
|
||||||
|
todo Manage to-do list items
|
||||||
|
update Update hab to the latest version
|
||||||
|
version Show version information
|
||||||
|
|
||||||
|
Additional Commands:
|
||||||
|
help Help about any command
|
||||||
|
|
||||||
|
Flags:
|
||||||
|
--config string Path to config directory (default: ~/.config/home-assistant-builder)
|
||||||
|
-h, --help help for hab
|
||||||
|
--json Use JSON output instead of human-readable text
|
||||||
|
--skip-update-check Skip automatic update check on startup
|
||||||
|
--text Use human-readable text output
|
||||||
|
--verbose Show verbose output
|
||||||
|
|
||||||
|
Use "hab [command] --help" for more information about a command.
|
||||||
|
```
|
||||||
|
<!-- HAB_LIVE_HELP_END -->
|
||||||
|
|
||||||
|
**Use configuration files when:** defining behavior, creating automations, setting up integrations
|
||||||
|
**Use MCP tools when:** checking current state, safe config writing, anomaly detection, entity diagnostics
|
||||||
|
**Use hab CLI when:** managing dashboards, areas, helpers, backups, blueprints, and bulk admin operations
|
||||||
|
|
||||||
|
### 4. zigporter CLI (Zigbee Toolkit)
|
||||||
|
A CLI for Zigbee device management in Home Assistant. Handles cascade renames (updating entity IDs across automations, scripts, scenes, and all Lovelace dashboards atomically), device inspection, stale device cleanup, and Zigbee mesh visualization.
|
||||||
|
|
||||||
|
**Cascade rename** — zigporter's unique value: when you rename an entity or device, it automatically patches every reference in automations, scripts, scenes, and Lovelace dashboards. `hab` can rename a single entity/device but does NOT cascade to references.
|
||||||
|
|
||||||
|
Key commands:
|
||||||
|
- **Cascade rename**: `zigporter rename-entity light.old_id light.new_id --apply`, `zigporter rename-device "Old Name" "New Name" --apply`
|
||||||
|
- **Device inventory**: `zigporter list-devices --json`, `zigporter list-z2m --json` (requires Z2M config)
|
||||||
|
- **Device inspection**: `zigporter inspect "Device Name" --json`, `zigporter inspect sensor.entity_id --json`
|
||||||
|
- **Stale device management**: `zigporter stale "Device" --action remove`, `zigporter stale "Device" --action ignore`
|
||||||
|
- **Post-migration cleanup**: `zigporter fix-device "Device" --apply`
|
||||||
|
- **Connectivity check**: `zigporter check`
|
||||||
|
- **ZHA export**: `zigporter export --output devices.json`
|
||||||
|
- **Mesh visualization**: `zigporter network-map --format table` (terminal), `zigporter network-map --output mesh.svg` (SVG file)
|
||||||
|
|
||||||
|
**Output format**: Use `--json` on listing/inspect commands for structured output (ideal for AI parsing). Rename commands output diffs and confirmation text.
|
||||||
|
|
||||||
|
zigporter is pre-authenticated via the Supervisor token. Z2M commands (`list-z2m`, `network-map --backend z2m`) require Z2M URL configuration in the add-on settings.
|
||||||
|
|
||||||
|
**Important limitations**:
|
||||||
|
- `rename-entity` / `rename-device` do NOT patch Jinja2 template expressions (e.g. `{{ states('old.id') }}`). A warning is printed listing affected files — inform the user these need manual review after renaming.
|
||||||
|
- The `migrate` command is inherently interactive (requires physical device actions) and must NOT be used by AI agents.
|
||||||
|
- Dry-run is the default for renames — always preview before using `--apply`.
|
||||||
|
|
||||||
|
<!-- ZIGPORTER_LIVE_HELP_START -->
|
||||||
|
```
|
||||||
|
|
||||||
|
Usage: zigporter [OPTIONS] COMMAND [ARGS]...
|
||||||
|
|
||||||
|
Migrate Zigbee devices between ZHA and Zigbee2MQTT. Supports both ZHA → Z2M
|
||||||
|
(default) and Z2M → ZHA (--direction z2m-to-zha).
|
||||||
|
|
||||||
|
╭─ Options ────────────────────────────────────────────────────────────────────╮
|
||||||
|
│ --version -v Show version and exit. │
|
||||||
|
│ --install-completion Install completion for the current shell. │
|
||||||
|
│ --show-completion Show completion for the current shell, to │
|
||||||
|
│ copy it or customize the installation. │
|
||||||
|
│ --help -h Show this message and exit. │
|
||||||
|
╰──────────────────────────────────────────────────────────────────────────────╯
|
||||||
|
╭─ Commands ───────────────────────────────────────────────────────────────────╮
|
||||||
|
│ setup Create or update the configuration file in the zigporter │
|
||||||
|
│ config directory. │
|
||||||
|
│ check Verify that all requirements are in place before migrating. │
|
||||||
|
│ export Export current ZHA devices, entities, areas, and automation │
|
||||||
|
│ references to JSON. │
|
||||||
|
│ export-z2m Export current Z2M devices, entities, areas, and automation │
|
||||||
|
│ references to JSON. │
|
||||||
|
│ list-z2m List all devices currently paired with Zigbee2MQTT. │
|
||||||
|
│ list-devices List all Home Assistant devices across all integrations. │
|
||||||
|
│ migrate Interactive wizard to migrate devices between ZHA and │
|
||||||
|
│ Zigbee2MQTT. │
|
||||||
|
│ inspect Show all automations, scripts, scenes, and dashboard cards │
|
||||||
|
│ that depend on a device. │
|
||||||
|
│ rename-entity Rename an entity ID and update all references in automations, │
|
||||||
|
│ scripts, scenes, and dashboards. │
|
||||||
|
│ rename-device Rename a device and cascade the change to all its entities, │
|
||||||
|
│ automations, scripts, scenes, and dashboards. │
|
||||||
|
│ stale Identify and manage offline/stale devices across all │
|
||||||
|
│ integrations. │
|
||||||
|
│ fix-device Remove stale ZHA device entries left behind after migration │
|
||||||
|
│ to Zigbee2MQTT. │
|
||||||
|
│ network-map Show Zigbee mesh topology with signal strength (LQI) for each │
|
||||||
|
│ device. │
|
||||||
|
╰──────────────────────────────────────────────────────────────────────────────╯
|
||||||
|
```
|
||||||
|
<!-- ZIGPORTER_LIVE_HELP_END -->
|
||||||
|
|
||||||
|
**Use zigporter CLI when:** renaming entities/devices with cascade updates, inspecting Zigbee devices across integrations, cleaning up stale or post-migration devices, visualizing the Zigbee mesh
|
||||||
|
|
||||||
|
### 5. Internal Directories (OFF-LIMITS)
|
||||||
|
Home Assistant manages internal state in directories like `.storage/`. These are:
|
||||||
|
- Not designed for direct access
|
||||||
|
- Subject to change without notice
|
||||||
|
- Potentially dangerous to modify
|
||||||
|
|
||||||
|
**Never access internal directories directly - use configuration files or MCP tools instead.**
|
||||||
|
|
||||||
|
## RESTRICTED: Internal Home Assistant Directories
|
||||||
|
|
||||||
|
**NEVER read, modify, or directly interact with these internal directories:**
|
||||||
|
|
||||||
|
| Directory | Contains | Use Instead |
|
||||||
|
|-----------|----------|-------------|
|
||||||
|
| `.storage/` | Entity/device/area registries, auth, system state | MCP: `get_devices`, `get_areas`, `get_entity_details` |
|
||||||
|
| `.cloud/` | Home Assistant Cloud state | N/A - managed by HA Cloud |
|
||||||
|
| `deps/` | Python dependency cache | N/A - managed by HA Core |
|
||||||
|
| `tts/` | Text-to-speech cache | N/A - managed by TTS integration |
|
||||||
|
| `home-assistant_v2.db` | History SQLite database | MCP: `get_history`, `get_logbook` |
|
||||||
|
| `home-assistant.log` | Raw system logs | MCP: `get_error_log` |
|
||||||
|
|
||||||
|
These contain internal Home Assistant state that:
|
||||||
|
1. Is managed exclusively by Home Assistant core
|
||||||
|
2. Can corrupt your installation if modified incorrectly
|
||||||
|
3. May be overwritten by Home Assistant at any time
|
||||||
|
4. Has no stable schema or format guarantees
|
||||||
|
|
||||||
|
**For information that seems to require internal access, there is always a proper alternative:**
|
||||||
|
- Need entity details? -> Read configuration files OR use `get_entity_details`
|
||||||
|
- Need device info? -> Use `get_devices` MCP tool
|
||||||
|
- Need to check history? -> Use `get_history` MCP tool
|
||||||
|
- Need to see errors? -> Use `get_error_log` MCP tool
|
||||||
|
|
||||||
|
## File Structure Knowledge
|
||||||
|
|
||||||
|
### Configuration Files (Primary Interface - Read/Write with User Approval)
|
||||||
|
These are the user-facing configuration files - the primary way to define Home Assistant behavior:
|
||||||
|
|
||||||
|
- `configuration.yaml` - Main configuration file
|
||||||
|
- `automations.yaml` - Automation definitions (if using UI or split config)
|
||||||
|
- `scripts.yaml` - Script definitions
|
||||||
|
- `scenes.yaml` - Scene definitions
|
||||||
|
- `secrets.yaml` - Sensitive values (NEVER commit or expose)
|
||||||
|
- `customize.yaml` - Entity customizations
|
||||||
|
- `groups.yaml` - Group definitions
|
||||||
|
- `packages/` - Package-based configuration splits
|
||||||
|
- `blueprints/` - Automation and script blueprints
|
||||||
|
- `custom_components/` - Custom integrations (HACS or manual)
|
||||||
|
- `www/` - Static files served at /local/
|
||||||
|
- `themes/` - Custom themes
|
||||||
|
- `*.yaml` in root - Any user-created YAML configuration
|
||||||
|
|
||||||
|
**These files are designed for editing** and are equally valid as MCP tools for research and changes.
|
||||||
|
|
||||||
|
### Internal Directories (OFF-LIMITS - Never Access Directly)
|
||||||
|
- `.storage/` - Internal registries and state (use MCP tools)
|
||||||
|
- `.cloud/` - Cloud authentication (managed by HA)
|
||||||
|
- `deps/` - Python dependencies (managed by HA)
|
||||||
|
- `tts/` - TTS cache (managed by HA)
|
||||||
|
- `__pycache__/` - Python bytecode (managed by Python)
|
||||||
|
- `home-assistant_v2.db` - History database (use MCP `get_history`)
|
||||||
|
- `home-assistant.log` - Logs (use MCP `get_error_log`)
|
||||||
|
|
||||||
|
## Working with YAML on the Command Line (`yq`)
|
||||||
|
|
||||||
|
To read, query, or convert YAML from the shell, use **`yq`** (the mikefarah/Go tool, pre-installed on `PATH`). It is the correct tool because it tolerates Home Assistant's custom tags — `!include`, `!secret`, `!env_var`, `!input`, and the `!include_dir_*` family.
|
||||||
|
|
||||||
|
**Do NOT reach for `python3 -c "import yaml"` (PyYAML) or Ruby's YAML for HA config** — both crash with a constructor error on the very first `!include`/`!secret`, because those tags are Home Assistant extensions, not standard YAML. `yq` parses them with no setup.
|
||||||
|
|
||||||
|
### Read / query (always safe — never errors on HA tags)
|
||||||
|
|
||||||
|
```
|
||||||
|
yq '.homeassistant.latitude' configuration.yaml # Print a nested value
|
||||||
|
yq '.automation | tag' configuration.yaml # Inspect the tag itself -> !include
|
||||||
|
yq 'keys' configuration.yaml # List top-level keys
|
||||||
|
yq -o=json '.' configuration.yaml | jq '.sensor' # Convert to JSON to pipe into jq
|
||||||
|
```
|
||||||
|
|
||||||
|
Note: output and JSON conversion strip the tag — `!secret home_latitude` prints as `home_latitude`. Use `| tag` when you need to see the tag. Never round-trip a file *through* JSON and back; that permanently loses every `!include`/`!secret`.
|
||||||
|
|
||||||
|
### Writing / editing
|
||||||
|
|
||||||
|
Prefer the sanctioned write path: **`write_config_safe`** (MCP — validates, backs up, and blocks accidental content loss) or read the full file and use the editor. Reserve `yq -i` for quick, low-risk edits, and only with these two caveats in mind:
|
||||||
|
|
||||||
|
1. **A custom tag sticks to the value you overwrite.** `yq -i '.homeassistant.latitude = 52.37'` on a `!secret`-tagged node produces the corrupt `latitude: !secret 52.37`. When replacing a tagged value, reset the tag in the *same* expression:
|
||||||
|
```
|
||||||
|
yq -i '(.homeassistant.latitude tag = "") | .homeassistant.latitude = 52.37' configuration.yaml
|
||||||
|
```
|
||||||
|
To *add* a secret reference, set the tag explicitly: `yq -i '.http.api_key = "my_api_key" | .http.api_key tag = "!secret"' configuration.yaml`
|
||||||
|
2. **`yq -i` strips blank separator lines** (and collapses inline-comment spacing) across the whole file. No data is lost, but diffs are noisier. When a clean, minimal diff matters, use the editor instead.
|
||||||
|
|
||||||
|
### Validation is not a syntax check
|
||||||
|
|
||||||
|
`yq` only confirms YAML *parses*. To validate a Home Assistant *configuration* (resolving `!include`/`!secret` and checking integration schemas), use `check_config_syntax` / `write_config_safe` (MCP), not `yq`.
|
||||||
|
|
||||||
|
## YAML Style Guide (MANDATORY)
|
||||||
|
|
||||||
|
All YAML written or modified MUST follow the official Home Assistant YAML Style Guide.
|
||||||
|
Reference: https://developers.home-assistant.io/docs/documenting/yaml-style-guide/
|
||||||
|
|
||||||
|
A Prettier formatter is configured for this environment and will auto-format files on save.
|
||||||
|
However, Prettier only enforces a subset of the rules below. You are responsible for following
|
||||||
|
ALL rules, especially those Prettier cannot enforce (marked with *).
|
||||||
|
|
||||||
|
### Indentation
|
||||||
|
|
||||||
|
2 spaces. Tabs are forbidden.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Good
|
||||||
|
example:
|
||||||
|
one: 1
|
||||||
|
|
||||||
|
# Bad
|
||||||
|
example:
|
||||||
|
bad: 2
|
||||||
|
```
|
||||||
|
|
||||||
|
### Booleans *
|
||||||
|
|
||||||
|
Only `true` and `false` in lowercase. Never use `Yes`, `No`, `On`, `Off`, `TRUE`, etc.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Good
|
||||||
|
one: true
|
||||||
|
two: false
|
||||||
|
|
||||||
|
# Bad
|
||||||
|
one: True
|
||||||
|
two: on
|
||||||
|
three: yes
|
||||||
|
```
|
||||||
|
|
||||||
|
### Strings
|
||||||
|
|
||||||
|
Double quotes for strings. Single quotes are not allowed.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Good
|
||||||
|
example: "Hi there!"
|
||||||
|
|
||||||
|
# Bad
|
||||||
|
example: 'Hi there!'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Exceptions** (no quotes needed): entity IDs, area IDs, device IDs, platform types,
|
||||||
|
trigger types, condition types, action names, device classes, event names, attribute names,
|
||||||
|
and values from a fixed set of options (e.g., `mode`).
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Good
|
||||||
|
actions:
|
||||||
|
- action: light.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: light.living_room
|
||||||
|
area_id: living_room
|
||||||
|
data:
|
||||||
|
message: "Hello!"
|
||||||
|
transition: 10
|
||||||
|
|
||||||
|
# Bad - don't quote entity IDs and action names
|
||||||
|
actions:
|
||||||
|
- action: "light.turn_on"
|
||||||
|
target:
|
||||||
|
entity_id: "light.living_room"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sequences (Lists) *
|
||||||
|
|
||||||
|
Use block style. Flow style `[1, 2, 3]` must not be used.
|
||||||
|
Block sequences must be indented under their key.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Good
|
||||||
|
options:
|
||||||
|
- 1
|
||||||
|
- 2
|
||||||
|
- 3
|
||||||
|
|
||||||
|
# Bad
|
||||||
|
options: [1, 2, 3]
|
||||||
|
|
||||||
|
# Bad - not indented under key
|
||||||
|
options:
|
||||||
|
- 1
|
||||||
|
- 2
|
||||||
|
```
|
||||||
|
|
||||||
|
### Mappings *
|
||||||
|
|
||||||
|
Block style only. Flow style `{ key: val }` must not be used.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Good
|
||||||
|
example:
|
||||||
|
one: 1
|
||||||
|
two: 2
|
||||||
|
|
||||||
|
# Bad
|
||||||
|
example: { one: 1, two: 2 }
|
||||||
|
```
|
||||||
|
|
||||||
|
### Null Values *
|
||||||
|
|
||||||
|
Use implicit null (just `key:` with no value). Never use `null` or `~`.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Good
|
||||||
|
initial:
|
||||||
|
|
||||||
|
# Bad
|
||||||
|
initial: null
|
||||||
|
initial: ~
|
||||||
|
```
|
||||||
|
|
||||||
|
### Comments
|
||||||
|
|
||||||
|
Capitalized, with a space after `#`, indented to match current level.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Good
|
||||||
|
example:
|
||||||
|
# This is a comment
|
||||||
|
one: true
|
||||||
|
|
||||||
|
# Bad
|
||||||
|
example:
|
||||||
|
# Comment at wrong indent
|
||||||
|
#Missing space
|
||||||
|
#lowercase start
|
||||||
|
one: true
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multiline Strings
|
||||||
|
|
||||||
|
Use literal `|` (preserves newlines) or folded `>` (joins lines) block scalars.
|
||||||
|
Avoid `\n` in strings. Prefer no-chomp (`|`, `>`) unless you need strip (`|-`, `>-`).
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Good
|
||||||
|
message: |
|
||||||
|
Hello!
|
||||||
|
This is a multiline
|
||||||
|
notification message.
|
||||||
|
|
||||||
|
# Good - folded
|
||||||
|
description: >
|
||||||
|
This is a long description that
|
||||||
|
will be joined into a single line.
|
||||||
|
|
||||||
|
# Bad
|
||||||
|
message: "Hello!\nThis is a multiline\nnotification message.\n"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Templates
|
||||||
|
|
||||||
|
Double quotes outside, single quotes inside. Use `states()` and `state_attr()`
|
||||||
|
helpers, not direct state object access. Split long templates across multiple lines.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Good
|
||||||
|
value_template: "{{ states('sensor.temperature') }}"
|
||||||
|
attribute_template: "{{ state_attr('climate.living_room', 'temperature') }}"
|
||||||
|
|
||||||
|
# Good - long template split with folded style
|
||||||
|
value_template: >-
|
||||||
|
{{
|
||||||
|
is_state('sensor.bedroom_co_status', 'Ok')
|
||||||
|
and is_state('sensor.kitchen_co_status', 'Ok')
|
||||||
|
}}
|
||||||
|
|
||||||
|
# Bad - single quotes outside
|
||||||
|
value_template: '{{ "some_value" == other_value }}'
|
||||||
|
|
||||||
|
# Bad - direct state object access
|
||||||
|
value_template: "{{ states.sensor.temperature.state }}"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Service Action Targets *
|
||||||
|
|
||||||
|
Always use `target:` for entity/device/area targeting. Do not put `entity_id` at
|
||||||
|
the action level or inside `data:`.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Good
|
||||||
|
actions:
|
||||||
|
- action: light.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: light.living_room
|
||||||
|
|
||||||
|
# Bad
|
||||||
|
actions:
|
||||||
|
- action: light.turn_on
|
||||||
|
entity_id: light.living_room
|
||||||
|
|
||||||
|
# Bad
|
||||||
|
actions:
|
||||||
|
- action: light.turn_on
|
||||||
|
data:
|
||||||
|
entity_id: light.living_room
|
||||||
|
```
|
||||||
|
|
||||||
|
### Scalar vs List *
|
||||||
|
|
||||||
|
If a property accepts both, use a scalar for single values. Do not wrap a single
|
||||||
|
value in a list. Do not use comma-separated strings.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Good
|
||||||
|
entity_id: light.living_room
|
||||||
|
entity_id:
|
||||||
|
- light.living_room
|
||||||
|
- light.office
|
||||||
|
|
||||||
|
# Bad - single value in a list
|
||||||
|
entity_id:
|
||||||
|
- light.living_room
|
||||||
|
|
||||||
|
# Bad - comma separated
|
||||||
|
entity_id: "light.living_room, light.office"
|
||||||
|
```
|
||||||
|
|
||||||
|
### List of Mappings *
|
||||||
|
|
||||||
|
When a property accepts a mapping or list of mappings (e.g., `actions`, `conditions`),
|
||||||
|
always use a list even for a single item.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Good
|
||||||
|
actions:
|
||||||
|
- action: light.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: light.living_room
|
||||||
|
|
||||||
|
# Bad
|
||||||
|
actions:
|
||||||
|
action: light.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: light.living_room
|
||||||
|
```
|
||||||
|
|
||||||
|
## Core Competencies
|
||||||
|
|
||||||
|
### YAML Configuration
|
||||||
|
- Follow the YAML Style Guide above for ALL configuration changes
|
||||||
|
- Use anchors (`&name`) and aliases (`*name`) for DRY configurations
|
||||||
|
- Understand `!include`, `!include_dir_named`, `!include_dir_list`, `!include_dir_merge_named`, `!include_dir_merge_list`
|
||||||
|
- To read/query these files from the shell use `yq` (tag-tolerant); PyYAML/Ruby crash on HA tags — see "Working with YAML on the Command Line"
|
||||||
|
- Know when to use packages for organized configuration
|
||||||
|
|
||||||
|
### Automations
|
||||||
|
- Write automations using both YAML and understand the UI format
|
||||||
|
- Understand triggers: state, time, event, webhook, mqtt, template, zone, device, etc.
|
||||||
|
- Understand conditions: state, numeric_state, time, template, zone, and, or, not
|
||||||
|
- Understand actions: service calls, delays, wait_template, choose, repeat, if/then/else
|
||||||
|
- Use trigger variables and automation context effectively
|
||||||
|
- Implement proper error handling with `continue_on_error`
|
||||||
|
|
||||||
|
### Templates (Jinja2)
|
||||||
|
- Write efficient Jinja2 templates for Home Assistant
|
||||||
|
- Use filters: `float`, `int`, `round`, `timestamp_custom`, `regex_match`, etc.
|
||||||
|
- Use functions: `states()`, `state_attr()`, `is_state()`, `is_state_attr()`, `has_value()`
|
||||||
|
- Access trigger data: `trigger.to_state`, `trigger.from_state`, `trigger.entity_id`
|
||||||
|
- Handle unavailable/unknown states gracefully
|
||||||
|
|
||||||
|
### Integrations
|
||||||
|
- Know common integrations and their configuration patterns
|
||||||
|
- Understand MQTT, REST, and template-based integrations
|
||||||
|
- Configure input_* helpers: input_boolean, input_number, input_select, input_text, input_datetime
|
||||||
|
- Set up utility_meter, statistics, and history_stats sensors
|
||||||
|
|
||||||
|
### Lovelace Dashboards
|
||||||
|
- Write Lovelace YAML configurations
|
||||||
|
- Know standard cards and their options
|
||||||
|
- Understand conditional cards, custom cards, and card-mod
|
||||||
|
- Configure views, themes, and resources
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
1. **Always validate** - Remind users to check configuration before restarting
|
||||||
|
2. **Use secrets** - Never hardcode sensitive data; use `!secret` references
|
||||||
|
3. **Backup first** - Suggest backups before major changes
|
||||||
|
4. **Incremental changes** - Make small, testable changes
|
||||||
|
5. **Comments** - Add YAML comments explaining complex logic
|
||||||
|
6. **Naming conventions** - Use consistent entity_id naming (e.g., `sensor.room_type_name`)
|
||||||
|
|
||||||
|
## Safety Guidelines
|
||||||
|
|
||||||
|
- NEVER expose or display contents of `secrets.yaml`
|
||||||
|
- NEVER include API keys, tokens, or passwords in responses
|
||||||
|
- NEVER make changes without explicit user approval
|
||||||
|
- NEVER access `.storage/`, `.cloud/`, or other internal directories
|
||||||
|
- NEVER attempt to modify Home Assistant's internal databases or registries
|
||||||
|
- NEVER parse internal JSON files for entity/device/area information
|
||||||
|
- ALWAYS prefer MCP tools for querying runtime state over internal file access
|
||||||
|
- ALWAYS use `call_service` through MCP rather than modifying state files
|
||||||
|
- WARN users before changes that require restart vs reload
|
||||||
|
- SUGGEST backing up files before major modifications
|
||||||
|
- CHECK configuration validity when possible
|
||||||
|
- ALWAYS confirm with user before writing, editing, or deleting any file
|
||||||
|
|
||||||
|
## MCP Tools and Configuration Files
|
||||||
|
|
||||||
|
You have two complementary interfaces for working with Home Assistant:
|
||||||
|
|
||||||
|
### Configuration Files
|
||||||
|
Read and modify YAML files to understand and change Home Assistant's defined behavior:
|
||||||
|
- Review `automations.yaml` to understand existing automations
|
||||||
|
- Edit `configuration.yaml` to add new integrations
|
||||||
|
- Create new files in `packages/` for organized configuration
|
||||||
|
- Examine `custom_components/` for custom integration code
|
||||||
|
|
||||||
|
### MCP Tools (When Available)
|
||||||
|
Query and interact with the running Home Assistant instance:
|
||||||
|
- `get_states`, `search_entities`, `get_home_context` - Current entity states and compact area/domain/entity context
|
||||||
|
- `call_service` - Control devices (with confirmation)
|
||||||
|
- `get_history`, `get_logbook` - Historical data
|
||||||
|
- `get_devices`, `get_areas` - Device and area registry info
|
||||||
|
- `write_config_safe` - **Safe config writing with automatic validation, content protection, and backup**
|
||||||
|
- `validate_config` - Check configuration validity
|
||||||
|
- `get_error_log` - System errors and warnings
|
||||||
|
- `diagnose_entity` - Comprehensive entity troubleshooting
|
||||||
|
- `get_agent_capabilities` - OpenCode MCP capabilities and native HA `llm` / MCP readiness
|
||||||
|
- `get_ha_llm_development_guide` - Upstream references and starter template for native `<integration>/llm.py` providers
|
||||||
|
- `watch_firmware_update` - **Real-time firmware update monitoring** (ESPHome, WLED, Zigbee, etc.)
|
||||||
|
- `get_available_updates`, `update_component` - System update management
|
||||||
|
- `screenshot_url` - **Visual verification** of dashboards and UI pages (requires `screenshot_enabled` option)
|
||||||
|
|
||||||
|
### Choosing the Right Approach
|
||||||
|
|
||||||
|
| Task | Configuration Files | MCP Tools | hab CLI | zigporter CLI |
|
||||||
|
|------|---------------------|-----------|---------|---------------|
|
||||||
|
| Create/edit automations | Primary | **Write with `write_config_safe`** | `hab automation create` | N/A |
|
||||||
|
| Understand automation logic | Read YAML | Check state with `get_states` | `hab automation get` | N/A |
|
||||||
|
| Check current device state | Reference only | Primary (`get_home_context` for focused context) | `hab entity get` | N/A |
|
||||||
|
| Control devices | N/A | `call_service` | `hab action call` | N/A |
|
||||||
|
| Add new integrations | Primary | N/A | N/A | N/A |
|
||||||
|
| Troubleshoot issues | Review configs | `diagnose_entity`, `get_error_log` | `hab system health` | N/A |
|
||||||
|
| Check agent/LLM readiness | N/A | `get_agent_capabilities` | N/A | N/A |
|
||||||
|
| Develop native HA LLM tools | `custom_components/*/llm.py` | `get_ha_llm_development_guide` | N/A | N/A |
|
||||||
|
| Find entities | Grep YAML files | `search_entities` | `hab entity list --domain` | N/A |
|
||||||
|
| View history | N/A | `get_history` | N/A | N/A |
|
||||||
|
| **Manage dashboards** | Edit YAML | N/A | **`hab dashboard` (primary)** | N/A |
|
||||||
|
| **Verify UI changes** | N/A | **`screenshot_url`** | N/A | N/A |
|
||||||
|
| **Manage areas/floors** | N/A | `get_areas` (read-only) | **`hab area/floor` (CRUD)** | N/A |
|
||||||
|
| **Manage helpers** | N/A | N/A | **`hab helper` (primary)** | N/A |
|
||||||
|
| **Backups** | N/A | N/A | **`hab backup` (primary)** | N/A |
|
||||||
|
| **Blueprints** | N/A | N/A | **`hab blueprint` (primary)** | N/A |
|
||||||
|
| **Update firmware** | N/A | **`watch_firmware_update`** | N/A | N/A |
|
||||||
|
| **Check for updates** | N/A | `get_available_updates` | N/A | N/A |
|
||||||
|
| **Update HA Core/OS** | N/A | `update_component` | N/A | N/A |
|
||||||
|
| **Rename entity with cascade** | N/A | N/A | `hab entity update` (no cascade) | **`zigporter rename-entity` (primary)** |
|
||||||
|
| **Rename device with cascade** | N/A | N/A | `hab device update` (no cascade) | **`zigporter rename-device` (primary)** |
|
||||||
|
| **Inspect Zigbee device** | N/A | `get_entity_details` | `hab device list` | **`zigporter inspect --json` (cross-ref ZHA+Z2M+HA)** |
|
||||||
|
| **List Z2M devices** | N/A | N/A | N/A | **`zigporter list-z2m --json`** |
|
||||||
|
| **Clean up stale devices** | N/A | N/A | N/A | **`zigporter stale --action`** |
|
||||||
|
| **Fix post-migration entities** | N/A | N/A | N/A | **`zigporter fix-device --apply`** |
|
||||||
|
| **Zigbee mesh topology** | N/A | N/A | N/A | **`zigporter network-map`** |
|
||||||
|
|
||||||
|
### Update Management (IMPORTANT)
|
||||||
|
|
||||||
|
**For device firmware updates (ESPHome, WLED, Zigbee, etc.):**
|
||||||
|
Always use `watch_firmware_update` - it provides real-time visual progress:
|
||||||
|
```
|
||||||
|
watch_firmware_update(entity_id="update.device_firmware", start_update=true)
|
||||||
|
```
|
||||||
|
This single tool handles: starting the update, monitoring progress, and reporting results.
|
||||||
|
|
||||||
|
**For system updates (Core, OS, Supervisor, Apps):**
|
||||||
|
```
|
||||||
|
1. get_available_updates() -> Check what needs updating
|
||||||
|
2. update_component(component="core") -> Start update (returns job_id)
|
||||||
|
3. get_update_progress(job_id="...") -> Monitor progress
|
||||||
|
```
|
||||||
|
|
||||||
|
**Both approaches are valid and complementary.** Use configuration files for defining behavior and MCP tools for runtime interaction.
|
||||||
|
|
||||||
|
## Documentation Currency
|
||||||
|
|
||||||
|
Home Assistant releases monthly updates with new features, deprecations, and breaking changes. Your training data may be outdated. **Always verify configuration syntax against current documentation.**
|
||||||
|
|
||||||
|
### Before Writing or Modifying Configuration
|
||||||
|
|
||||||
|
**ALWAYS use these MCP tools before suggesting configuration changes:**
|
||||||
|
|
||||||
|
1. **Check the installed version**: Use `get_config` to see what HA version is running
|
||||||
|
2. **Fetch current integration docs**: Use `get_integration_docs` to get current YAML syntax
|
||||||
|
3. **Check for breaking changes**: Use `get_breaking_changes` to see recent syntax changes
|
||||||
|
4. **Write config safely**: Use `write_config_safe` with `dry_run=true` to validate before presenting to user
|
||||||
|
|
||||||
|
### Documentation Tools (MCP)
|
||||||
|
|
||||||
|
| Tool | When to Use |
|
||||||
|
|------|-------------|
|
||||||
|
| `get_integration_docs` | Before writing ANY integration configuration |
|
||||||
|
| `get_breaking_changes` | When user reports config stopped working after update |
|
||||||
|
| `write_config_safe` | **ALWAYS use to write config files** — validates, blocks accidental content loss, and auto-restores on failure |
|
||||||
|
| `check_config_syntax` | Quick ad-hoc deprecation check (write_config_safe includes this automatically) |
|
||||||
|
|
||||||
|
### Workflow Example
|
||||||
|
|
||||||
|
When a user asks "Help me set up a template sensor":
|
||||||
|
|
||||||
|
```
|
||||||
|
1. get_config() -> Check HA version (e.g., 2024.12.1)
|
||||||
|
2. get_integration_docs("template") -> Get current syntax and examples
|
||||||
|
3. read_file(path) -> Read the EXISTING file content first
|
||||||
|
4. Draft configuration: include ALL existing content + new changes
|
||||||
|
5. write_config_safe(path, yaml, dry_run=true) -> Pre-validate everything
|
||||||
|
6. If errors: fix and repeat step 5
|
||||||
|
7. Present validated config to user and get approval
|
||||||
|
8. write_config_safe(path, yaml) -> Write for real (auto backup + validation)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Common Deprecation Patterns
|
||||||
|
|
||||||
|
Be especially careful with these frequently-changed areas:
|
||||||
|
- **Template sensors/binary_sensors**: `platform: template` under `sensor:` is deprecated; use top-level `template:`
|
||||||
|
- **Entity configurations**: Many moved from YAML to UI-based config
|
||||||
|
- **Trigger-based templates**: Newer syntax preferred over legacy template sensors
|
||||||
|
- **Device triggers**: Syntax evolves with new device types
|
||||||
|
- **MQTT platform syntax**: `platform: mqtt` under domain keys is deprecated; use top-level `mqtt:` key
|
||||||
|
- **Direct state access**: `states.sensor.x.state` is fragile; use `states('sensor.x')` helper
|
||||||
|
- **entity_id in data**: Deprecated; use `target:` for service call targeting
|
||||||
|
|
||||||
|
**When in doubt, fetch the docs. Never rely solely on training data for configuration syntax.**
|
||||||
|
|
||||||
|
## Common Tasks
|
||||||
|
|
||||||
|
### Creating an Automation
|
||||||
|
1. **Read the existing `automations.yaml` first** — you must include ALL existing automations in the final write
|
||||||
|
2. Understand the goal and identify trigger conditions
|
||||||
|
3. Determine required entities (search if MCP available)
|
||||||
|
4. Draft the automation YAML with clear comments
|
||||||
|
5. **Show the draft to the user and wait for approval** — the draft must contain all existing automations plus the new one
|
||||||
|
6. Only write the file after explicit user confirmation
|
||||||
|
7. Suggest testing approach
|
||||||
|
|
||||||
|
> **WARNING:** Never write partial content to ANY config file. Always read the existing file first and include ALL existing content in your write. `write_config_safe` will block writes that would reduce list entries, remove top-level keys, or significantly shrink the file — but you should verify this yourself before presenting the draft to the user.
|
||||||
|
|
||||||
|
### Troubleshooting
|
||||||
|
1. Check entity states and history (via MCP if available)
|
||||||
|
2. Review relevant configuration files
|
||||||
|
3. Check Home Assistant logs for errors
|
||||||
|
4. Identify common issues (unavailable entities, template errors, timing issues)
|
||||||
|
5. **Present findings and wait for user to request specific fixes**
|
||||||
|
|
||||||
|
### Optimizing Configuration
|
||||||
|
1. Identify redundant or inefficient patterns
|
||||||
|
2. **Present recommendations to user**
|
||||||
|
3. Wait for user to approve specific changes
|
||||||
|
4. Implement only the changes the user explicitly approves
|
||||||
+4349
-3783
File diff suppressed because it is too large
Load Diff
@@ -8,6 +8,10 @@
|
|||||||
# packages/16a_ev_charging_controls.yaml
|
# packages/16a_ev_charging_controls.yaml
|
||||||
#
|
#
|
||||||
# VERSION:
|
# VERSION:
|
||||||
|
# V1.3 2026-07-24
|
||||||
|
# - Added startup catch-up to offpeak_end: when HA starts outside the
|
||||||
|
# offpeak window in Normal mode, the relay is turned off immediately.
|
||||||
|
#
|
||||||
# V1.2 2026-07-20
|
# V1.2 2026-07-20
|
||||||
# - Added structured mode, timing, and restart behavior documentation.
|
# - Added structured mode, timing, and restart behavior documentation.
|
||||||
#
|
#
|
||||||
@@ -56,7 +60,8 @@
|
|||||||
#
|
#
|
||||||
# OPERATION NOTES:
|
# OPERATION NOTES:
|
||||||
# - Normal offpeak start and end use exact-time triggers.
|
# - Normal offpeak start and end use exact-time triggers.
|
||||||
# - There is no startup catch-up if Home Assistant is offline at either time.
|
# - The offpeak_end automation includes a startup trigger: if HA restarts
|
||||||
|
# outside the offpeak window in Normal mode, the relay turns off immediately.
|
||||||
#
|
#
|
||||||
# PACKAGE SETTINGS:
|
# PACKAGE SETTINGS:
|
||||||
# Car display name:
|
# Car display name:
|
||||||
@@ -168,12 +173,27 @@ automation:
|
|||||||
triggers:
|
triggers:
|
||||||
- trigger: time
|
- trigger: time
|
||||||
at: input_datetime.ev_16a_offpeak_end
|
at: input_datetime.ev_16a_offpeak_end
|
||||||
|
- trigger: homeassistant
|
||||||
|
event: start
|
||||||
|
|
||||||
conditions:
|
conditions:
|
||||||
- condition: state
|
- condition: state
|
||||||
entity_id: input_select.ev_16a_charge_mode
|
entity_id: input_select.ev_16a_charge_mode
|
||||||
state: "Normal (Offpeak)"
|
state: "Normal (Offpeak)"
|
||||||
|
|
||||||
|
- condition: template
|
||||||
|
value_template: >
|
||||||
|
{% set start = states('input_datetime.ev_16a_offpeak_start') %}
|
||||||
|
{% set end = states('input_datetime.ev_16a_offpeak_end') %}
|
||||||
|
{% set now_time = now().strftime('%H:%M:%S') %}
|
||||||
|
{% if start == end %}
|
||||||
|
{{ false }}
|
||||||
|
{% elif start < end %}
|
||||||
|
{{ not (start <= now_time < end) }}
|
||||||
|
{% else %}
|
||||||
|
{{ not (now_time >= start or now_time < end) }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
actions:
|
actions:
|
||||||
- action: switch.turn_off
|
- action: switch.turn_off
|
||||||
target:
|
target:
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
# PACKAGE: Appliance Monitor Processor
|
# PACKAGE: Appliance Monitor Processor
|
||||||
################################################################################
|
################################################################################
|
||||||
#
|
#
|
||||||
# Version: 1.3
|
# Version: 1.5
|
||||||
# Date: 2026-07-11
|
# Date: 2026-07-26
|
||||||
#
|
#
|
||||||
# Purpose:
|
# Purpose:
|
||||||
# Shared appliance power monitoring processor.
|
# Shared appliance power monitoring processor.
|
||||||
@@ -41,6 +41,15 @@
|
|||||||
# Finished
|
# Finished
|
||||||
#
|
#
|
||||||
# Notes:
|
# Notes:
|
||||||
|
# Version 1.5:
|
||||||
|
# - Standardized Sony TV and Pushover appliance notification titles as
|
||||||
|
# "Appliance Notification".
|
||||||
|
#
|
||||||
|
# Version 1.4:
|
||||||
|
# - Added power_available field and state machine guard.
|
||||||
|
# - Prevents false Operating→Finished transitions when power sensor is
|
||||||
|
# unavailable (e.g. during Home Assistant startup).
|
||||||
|
#
|
||||||
# Version 1.3:
|
# Version 1.3:
|
||||||
# - Updated completion announcements to support all current View Road
|
# - Updated completion announcements to support all current View Road
|
||||||
# announcement router channels.
|
# announcement router channels.
|
||||||
@@ -213,6 +222,12 @@ script:
|
|||||||
selector:
|
selector:
|
||||||
text:
|
text:
|
||||||
|
|
||||||
|
power_available:
|
||||||
|
name: Power Available
|
||||||
|
description: Whether the power sensor reported a valid numeric state.
|
||||||
|
selector:
|
||||||
|
boolean:
|
||||||
|
|
||||||
sequence:
|
sequence:
|
||||||
##########################################################################
|
##########################################################################
|
||||||
# CORE DEFAULTS AND PASSED VALUES
|
# CORE DEFAULTS AND PASSED VALUES
|
||||||
@@ -239,6 +254,8 @@ script:
|
|||||||
am_max_sample_gap_seconds: "{{ max_sample_gap_seconds | default(900, true) | int(900) }}"
|
am_max_sample_gap_seconds: "{{ max_sample_gap_seconds | default(900, true) | int(900) }}"
|
||||||
am_min_cycle_notify_seconds: "{{ min_cycle_notify_seconds | default(300, true) | int(300) }}"
|
am_min_cycle_notify_seconds: "{{ min_cycle_notify_seconds | default(300, true) | int(300) }}"
|
||||||
|
|
||||||
|
am_power_available: "{{ power_available | default(true, true) | bool(true) }}"
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
# ANNOUNCEMENT DEFAULTS AND PASSED VALUES
|
# ANNOUNCEMENT DEFAULTS AND PASSED VALUES
|
||||||
##########################################################################
|
##########################################################################
|
||||||
@@ -280,7 +297,7 @@ script:
|
|||||||
{{ long_announcement | default('', true) | string }}
|
{{ long_announcement | default('', true) | string }}
|
||||||
|
|
||||||
am_announcement_title: >-
|
am_announcement_title: >-
|
||||||
{{ title | default(am_appliance_name ~ ' Notification', true) | string }}
|
Appliance Notification
|
||||||
|
|
||||||
am_announcement_payload: >-
|
am_announcement_payload: >-
|
||||||
{% if announcement_payload is defined %}
|
{% if announcement_payload is defined %}
|
||||||
@@ -394,7 +411,9 @@ script:
|
|||||||
{% set standby = am_standby_power | float(2) %}
|
{% set standby = am_standby_power | float(2) %}
|
||||||
{% set operate = am_operating_power_min | float(12) %}
|
{% set operate = am_operating_power_min | float(12) %}
|
||||||
{% set prev = am_previous_state | string %}
|
{% set prev = am_previous_state | string %}
|
||||||
{% if prev == 'Operating' and avg < operate %}
|
{% if prev == 'Operating' and not am_power_available %}
|
||||||
|
{{ prev }}
|
||||||
|
{% elif prev == 'Operating' and avg < operate %}
|
||||||
Finished
|
Finished
|
||||||
{% elif avg < standby %}
|
{% elif avg < standby %}
|
||||||
Off
|
Off
|
||||||
|
|||||||
@@ -51,6 +51,10 @@
|
|||||||
# matrix_indicator.
|
# matrix_indicator.
|
||||||
#
|
#
|
||||||
# VERSION HISTORY:
|
# VERSION HISTORY:
|
||||||
|
# V1.6 2026-07-24
|
||||||
|
# - Added startup delay guard to prevent false completion announcements.
|
||||||
|
# - Added power_available field for the processor availability check.
|
||||||
|
#
|
||||||
# V1.5 2026-07-11
|
# V1.5 2026-07-11
|
||||||
# - Added full View Road announcement router parameter support.
|
# - Added full View Road announcement router parameter support.
|
||||||
# - Added per-appliance announcement_enabled.
|
# - Added per-appliance announcement_enabled.
|
||||||
@@ -421,6 +425,15 @@ automation:
|
|||||||
mqtt_feed: "3d_printer"
|
mqtt_feed: "3d_printer"
|
||||||
|
|
||||||
action:
|
action:
|
||||||
|
# On startup, wait for power sensors to report real values before processing.
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: trigger
|
||||||
|
id:
|
||||||
|
- ha_start
|
||||||
|
sequence:
|
||||||
|
- delay: "00:01:00"
|
||||||
|
|
||||||
#:####################################################################################:#
|
#:####################################################################################:#
|
||||||
# PUBLISH / REFRESH MQTT DISCOVERY CONFIG #
|
# PUBLISH / REFRESH MQTT DISCOVERY CONFIG #
|
||||||
#:####################################################################################:#
|
#:####################################################################################:#
|
||||||
@@ -574,6 +587,9 @@ automation:
|
|||||||
am_power_w: >-
|
am_power_w: >-
|
||||||
{{ states(repeat.item.power_entity) | float(0) }}
|
{{ states(repeat.item.power_entity) | float(0) }}
|
||||||
|
|
||||||
|
am_power_available: >-
|
||||||
|
{{ states(repeat.item.power_entity) not in ['unknown', 'unavailable'] }}
|
||||||
|
|
||||||
- action: script.appliance_monitor_process_sample
|
- action: script.appliance_monitor_process_sample
|
||||||
data:
|
data:
|
||||||
appliance_id: "{{ repeat.item.appliance_id }}"
|
appliance_id: "{{ repeat.item.appliance_id }}"
|
||||||
@@ -581,6 +597,7 @@ automation:
|
|||||||
appliance_action: "{{ repeat.item.appliance_action }}"
|
appliance_action: "{{ repeat.item.appliance_action }}"
|
||||||
|
|
||||||
power_w: "{{ am_power_w }}"
|
power_w: "{{ am_power_w }}"
|
||||||
|
power_available: "{{ am_power_available }}"
|
||||||
monitor_sensor: "{{ am_monitor_sensor }}"
|
monitor_sensor: "{{ am_monitor_sensor }}"
|
||||||
state_topic: "{{ am_state_topic }}"
|
state_topic: "{{ am_state_topic }}"
|
||||||
|
|
||||||
|
|||||||
@@ -113,13 +113,12 @@ automation:
|
|||||||
# Re-apply when the openHASP display comes online
|
# Re-apply when the openHASP display comes online
|
||||||
##########################################################################
|
##########################################################################
|
||||||
- trigger: mqtt
|
- trigger: mqtt
|
||||||
topic: hasp/openhasp_1/status
|
topic: "hasp/openhasp_1/LWT"
|
||||||
payload: online
|
|
||||||
|
|
||||||
actions:
|
actions:
|
||||||
- if:
|
- if:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ trigger.platform in ['homeassistant', 'mqtt'] }}"
|
value_template: "{{ trigger.platform == 'homeassistant' or (trigger.platform == 'mqtt' and trigger.payload == 'online') }}"
|
||||||
then:
|
then:
|
||||||
- delay: "00:00:02"
|
- delay: "00:00:02"
|
||||||
|
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ group:
|
|||||||
basement_lights:
|
basement_lights:
|
||||||
name: "Basement Lights"
|
name: "Basement Lights"
|
||||||
entities:
|
entities:
|
||||||
- switch.esp_officelights_relay_1_nighttime_lights
|
- switch.office_office_main_lightswitch_3_relay_1_bunker_lights
|
||||||
- switch.esp_officelights_relay_2_daytime_lights
|
- switch.office_office_main_lightswitch_3_relay_2_overhead_lights
|
||||||
- switch.esp_underhouselights_underhouse_entrance_lights
|
- switch.esp_underhouselights_underhouse_entrance_lights
|
||||||
- switch.esp_underhouselights_underhouse_storage_lights
|
- switch.esp_underhouselights_underhouse_storage_lights
|
||||||
- switch.esp_laundrylights_relay_1_laundry_lights
|
- switch.esp_laundrylights_relay_1_laundry_lights
|
||||||
|
|||||||
@@ -0,0 +1,642 @@
|
|||||||
|
#:########################################################################################:#
|
||||||
|
# Flounder Kiosk Package #
|
||||||
|
#:########################################################################################:#
|
||||||
|
#
|
||||||
|
# TITLE:
|
||||||
|
# Flounder Kiosk
|
||||||
|
#
|
||||||
|
# FILE:
|
||||||
|
# flounder_kiosk.yaml
|
||||||
|
#
|
||||||
|
# VERSION:
|
||||||
|
# V2.0 - 2026-07-28
|
||||||
|
#
|
||||||
|
# PURPOSE:
|
||||||
|
# Provides Home Assistant controls and status entities for the Flounder portrait
|
||||||
|
# touchscreen kiosk.
|
||||||
|
#
|
||||||
|
# DISPLAY CONTROL MODEL:
|
||||||
|
# A single MQTT select sets one persistent display mode:
|
||||||
|
# - Screen Lock
|
||||||
|
# - Screen Off
|
||||||
|
# - Screensaver
|
||||||
|
# - Screen On
|
||||||
|
#
|
||||||
|
# The selected display mode is separate from the actual physical screen and
|
||||||
|
# screensaver states. For example, Screen Off remains selected while a touch
|
||||||
|
# temporarily wakes the physical display.
|
||||||
|
#
|
||||||
|
# MQTT DEVICE:
|
||||||
|
# Name: Flounder Kiosk
|
||||||
|
# Identifier: flounder_kiosk
|
||||||
|
# Manufacturer: Dell
|
||||||
|
# Model: Portrait Touchscreen Kiosk
|
||||||
|
# Suggested Area: Lounge
|
||||||
|
#
|
||||||
|
# ENTITIES:
|
||||||
|
# select.flounder_kiosk_display_mode
|
||||||
|
# number.flounder_kiosk_brightness
|
||||||
|
# number.flounder_kiosk_presence_brightness
|
||||||
|
# sensor.flounder_kiosk_actual_brightness
|
||||||
|
# number.flounder_kiosk_presence_timeout
|
||||||
|
# binary_sensor.flounder_kiosk_presence_active
|
||||||
|
# switch.flounder_kiosk_motion_wake
|
||||||
|
# number.flounder_kiosk_volume
|
||||||
|
# switch.flounder_kiosk_mute
|
||||||
|
# binary_sensor.flounder_kiosk_screen_on
|
||||||
|
# binary_sensor.flounder_kiosk_screensaver_active
|
||||||
|
# binary_sensor.flounder_kiosk_motion
|
||||||
|
#
|
||||||
|
# REPLACED ENTITIES:
|
||||||
|
# The following writable entities from V1.7 are removed:
|
||||||
|
# - switch.flounder_kiosk_screen
|
||||||
|
# - switch.flounder_kiosk_screensaver
|
||||||
|
#
|
||||||
|
# They are replaced by:
|
||||||
|
# - select.flounder_kiosk_display_mode
|
||||||
|
# - binary_sensor.flounder_kiosk_screen_on
|
||||||
|
# - binary_sensor.flounder_kiosk_screensaver_active
|
||||||
|
#
|
||||||
|
# MQTT COMMAND TOPICS:
|
||||||
|
# viewroad-commands/flounder/display_mode/set
|
||||||
|
# viewroad-commands/flounder/brightness/set
|
||||||
|
# viewroad-commands/flounder/brightness/presence/set
|
||||||
|
# viewroad-commands/flounder/presence/timeout/set
|
||||||
|
# viewroad-commands/flounder/motion_wake/set
|
||||||
|
# viewroad-commands/flounder/audio/volume/set
|
||||||
|
# viewroad-commands/flounder/audio/mute/set
|
||||||
|
#
|
||||||
|
# MQTT STATE TOPICS:
|
||||||
|
# viewroad-status/flounder/display_mode/state
|
||||||
|
# viewroad-status/flounder/screen/state
|
||||||
|
# viewroad-status/flounder/screensaver/state
|
||||||
|
# viewroad-status/flounder/brightness/state
|
||||||
|
# viewroad-status/flounder/brightness/actual/state
|
||||||
|
# viewroad-status/flounder/brightness/presence/state
|
||||||
|
# viewroad-status/flounder/presence/state
|
||||||
|
# viewroad-status/flounder/presence/timeout/state
|
||||||
|
# viewroad-status/flounder/motion_wake/state
|
||||||
|
# viewroad-status/flounder/audio/volume/state
|
||||||
|
# viewroad-status/flounder/audio/mute/state
|
||||||
|
# viewroad-status/flounder/motion/state
|
||||||
|
#
|
||||||
|
# MQTT AVAILABILITY TOPIC:
|
||||||
|
# viewroad-status/flounder/availability
|
||||||
|
#
|
||||||
|
# DISPLAY MODES:
|
||||||
|
# Screen Lock:
|
||||||
|
# - Stops XScreenSaver.
|
||||||
|
# - Disables touchscreen input.
|
||||||
|
# - Keeps the physical panel off.
|
||||||
|
# - Ignores camera motion even when Motion Wake is enabled.
|
||||||
|
# - Camera motion detection and reporting continue in the background.
|
||||||
|
#
|
||||||
|
# Screen Off:
|
||||||
|
# - Keeps the physical panel off while activity is inactive.
|
||||||
|
# - Keeps the touchscreen enabled.
|
||||||
|
# - Touch always wakes the panel temporarily.
|
||||||
|
# - Camera motion wakes it when Motion Wake is enabled.
|
||||||
|
# - Activity applies Presence Brightness.
|
||||||
|
# - The panel returns to Screen Off after the shared Presence Timeout.
|
||||||
|
#
|
||||||
|
# Screensaver:
|
||||||
|
# - Turns the panel on at Current Brightness.
|
||||||
|
# - Starts XScreenSaver immediately.
|
||||||
|
# - Touch stops XScreenSaver and applies Presence Brightness.
|
||||||
|
# - Camera motion does the same when Motion Wake is enabled.
|
||||||
|
# - XScreenSaver restarts after the shared Presence Timeout.
|
||||||
|
#
|
||||||
|
# Screen On:
|
||||||
|
# - Keeps the panel on at Current Brightness while activity is inactive.
|
||||||
|
# - Touch applies Presence Brightness.
|
||||||
|
# - Camera motion does the same when Motion Wake is enabled.
|
||||||
|
# - The panel returns to Current Brightness after the Presence Timeout.
|
||||||
|
#
|
||||||
|
# PRESENCE AND TOUCH OPERATION:
|
||||||
|
# - Touch and camera motion use the same Presence Timeout.
|
||||||
|
# - Touch is active in every mode except Screen Lock.
|
||||||
|
# - Motion Wake controls camera motion only and does not disable touch wake.
|
||||||
|
# - Qualifying activity immediately applies Presence Brightness.
|
||||||
|
# - Camera motion holds presence active until the Motion entity returns to OFF.
|
||||||
|
# - A touch starts or restarts the ten-step brightness ramp immediately unless
|
||||||
|
# qualifying camera motion is currently holding presence active.
|
||||||
|
# - Presence Timeout is the total duration of the ten-step brightness ramp.
|
||||||
|
# - The final ramp step applies the latest Current Brightness.
|
||||||
|
# - The selected display mode is then restored automatically.
|
||||||
|
#
|
||||||
|
# DIAGNOSTIC STATE MEANING:
|
||||||
|
# - Screen On reports the real Linux DPMS panel state.
|
||||||
|
# - Screensaver Active reports whether XScreenSaver is running.
|
||||||
|
# - Presence Active reports whether temporary activity behaviour is active.
|
||||||
|
# - Actual Brightness reports the physical backlight percentage.
|
||||||
|
#
|
||||||
|
# VERSION HISTORY:
|
||||||
|
# V2.0 - 2026-07-28
|
||||||
|
# - Replaced the separate Screen and Screensaver switches with one persistent
|
||||||
|
# four-option Display Mode select.
|
||||||
|
# - Added Screen Lock, Screen Off, Screensaver, and Screen On modes.
|
||||||
|
# - Added shared touchscreen and camera-presence behaviour.
|
||||||
|
# - Added automatic return to the selected mode after the presence ramp.
|
||||||
|
# - Replaced writable Screen and Screensaver entities with diagnostics.
|
||||||
|
#
|
||||||
|
# V1.7 - 2026-07-27
|
||||||
|
# - Re-enabled DPMS after XScreenSaver activation.
|
||||||
|
# - Corrected Screen state reporting while XScreenSaver was running.
|
||||||
|
#
|
||||||
|
# V1.6 - 2026-07-27
|
||||||
|
# - Grouped all MQTT entities under one Flounder Kiosk device.
|
||||||
|
#
|
||||||
|
# V1.5 - 2026-07-27
|
||||||
|
# - Added Motion Wake control.
|
||||||
|
#
|
||||||
|
# V1.4 - 2026-07-27
|
||||||
|
# - Added the ten-step presence-brightness fade.
|
||||||
|
#
|
||||||
|
# V1.3 - 2026-07-27
|
||||||
|
# - Added presence brightness, timeout, and diagnostic entities.
|
||||||
|
#
|
||||||
|
# V1.2 - 2026-07-27
|
||||||
|
# - Added XScreenSaver control.
|
||||||
|
#
|
||||||
|
# V1.1 - 2026-07-27
|
||||||
|
# - Added MQTT availability monitoring.
|
||||||
|
#
|
||||||
|
# V1.0 - 2026-07-26
|
||||||
|
# - Initial package.
|
||||||
|
#
|
||||||
|
#:########################################################################################:#
|
||||||
|
# MQTT Entities #
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
|
mqtt:
|
||||||
|
#:########################################################################################:#
|
||||||
|
# Flounder Kiosk Display Mode #
|
||||||
|
#:########################################################################################:#
|
||||||
|
#
|
||||||
|
# Selects the persistent display operating mode.
|
||||||
|
#
|
||||||
|
# The selected mode remains unchanged while touch or camera activity temporarily
|
||||||
|
# changes the real panel or screensaver state.
|
||||||
|
#
|
||||||
|
|
||||||
|
- select:
|
||||||
|
name: "Display Mode"
|
||||||
|
unique_id: flounder_kiosk_display_mode
|
||||||
|
default_entity_id: select.flounder_kiosk_display_mode
|
||||||
|
|
||||||
|
device:
|
||||||
|
identifiers:
|
||||||
|
- flounder_kiosk
|
||||||
|
name: "Flounder Kiosk"
|
||||||
|
manufacturer: "Dell"
|
||||||
|
model: "Portrait Touchscreen Kiosk"
|
||||||
|
suggested_area: "Lounge"
|
||||||
|
|
||||||
|
command_topic: "viewroad-commands/flounder/display_mode/set"
|
||||||
|
state_topic: "viewroad-status/flounder/display_mode/state"
|
||||||
|
|
||||||
|
availability_topic: "viewroad-status/flounder/availability"
|
||||||
|
payload_available: "ON"
|
||||||
|
payload_not_available: "OFF"
|
||||||
|
|
||||||
|
options:
|
||||||
|
- "Screen Lock"
|
||||||
|
- "Screen Off"
|
||||||
|
- "Screensaver"
|
||||||
|
- "Screen On"
|
||||||
|
|
||||||
|
optimistic: false
|
||||||
|
retain: false
|
||||||
|
|
||||||
|
icon: mdi:monitor-dashboard
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# Flounder Kiosk Current Brightness #
|
||||||
|
#:########################################################################################:#
|
||||||
|
#
|
||||||
|
# Stores the normal inactive brightness from 1 to 100 percent.
|
||||||
|
#
|
||||||
|
# In Screensaver and Screen On modes it is the normal visible brightness.
|
||||||
|
# In Screen Off mode it is the final ramp target before the panel powers off.
|
||||||
|
# In Screen Lock mode it is stored for the next unlocked mode.
|
||||||
|
#
|
||||||
|
|
||||||
|
- number:
|
||||||
|
name: "Brightness"
|
||||||
|
unique_id: flounder_kiosk_brightness
|
||||||
|
default_entity_id: number.flounder_kiosk_brightness
|
||||||
|
|
||||||
|
device:
|
||||||
|
identifiers:
|
||||||
|
- flounder_kiosk
|
||||||
|
name: "Flounder Kiosk"
|
||||||
|
manufacturer: "Dell"
|
||||||
|
model: "Portrait Touchscreen Kiosk"
|
||||||
|
suggested_area: "Lounge"
|
||||||
|
|
||||||
|
command_topic: "viewroad-commands/flounder/brightness/set"
|
||||||
|
state_topic: "viewroad-status/flounder/brightness/state"
|
||||||
|
|
||||||
|
availability_topic: "viewroad-status/flounder/availability"
|
||||||
|
payload_available: "ON"
|
||||||
|
payload_not_available: "OFF"
|
||||||
|
|
||||||
|
min: 1
|
||||||
|
max: 100
|
||||||
|
step: 1
|
||||||
|
mode: slider
|
||||||
|
|
||||||
|
unit_of_measurement: "%"
|
||||||
|
|
||||||
|
optimistic: false
|
||||||
|
retain: false
|
||||||
|
|
||||||
|
icon: mdi:brightness-6
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# Flounder Kiosk Presence Brightness #
|
||||||
|
#:########################################################################################:#
|
||||||
|
#
|
||||||
|
# Sets the temporary brightness used after touch or qualifying camera motion.
|
||||||
|
#
|
||||||
|
# Changing it while Presence Active is ON immediately updates the physical
|
||||||
|
# backlight.
|
||||||
|
#
|
||||||
|
|
||||||
|
- number:
|
||||||
|
name: "Presence Brightness"
|
||||||
|
unique_id: flounder_kiosk_presence_brightness
|
||||||
|
default_entity_id: number.flounder_kiosk_presence_brightness
|
||||||
|
|
||||||
|
device:
|
||||||
|
identifiers:
|
||||||
|
- flounder_kiosk
|
||||||
|
name: "Flounder Kiosk"
|
||||||
|
manufacturer: "Dell"
|
||||||
|
model: "Portrait Touchscreen Kiosk"
|
||||||
|
suggested_area: "Lounge"
|
||||||
|
|
||||||
|
entity_category: config
|
||||||
|
|
||||||
|
command_topic: "viewroad-commands/flounder/brightness/presence/set"
|
||||||
|
state_topic: "viewroad-status/flounder/brightness/presence/state"
|
||||||
|
|
||||||
|
availability_topic: "viewroad-status/flounder/availability"
|
||||||
|
payload_available: "ON"
|
||||||
|
payload_not_available: "OFF"
|
||||||
|
|
||||||
|
min: 1
|
||||||
|
max: 100
|
||||||
|
step: 1
|
||||||
|
mode: slider
|
||||||
|
|
||||||
|
unit_of_measurement: "%"
|
||||||
|
|
||||||
|
optimistic: false
|
||||||
|
retain: false
|
||||||
|
|
||||||
|
icon: mdi:brightness-7
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# Flounder Kiosk Actual Brightness #
|
||||||
|
#:########################################################################################:#
|
||||||
|
#
|
||||||
|
# Reports the physical display backlight percentage.
|
||||||
|
#
|
||||||
|
# This may differ from Current Brightness while temporary activity is active or
|
||||||
|
# while the ten-step brightness ramp is running.
|
||||||
|
#
|
||||||
|
|
||||||
|
- sensor:
|
||||||
|
name: "Actual Brightness"
|
||||||
|
unique_id: flounder_kiosk_actual_brightness
|
||||||
|
default_entity_id: sensor.flounder_kiosk_actual_brightness
|
||||||
|
|
||||||
|
device:
|
||||||
|
identifiers:
|
||||||
|
- flounder_kiosk
|
||||||
|
name: "Flounder Kiosk"
|
||||||
|
manufacturer: "Dell"
|
||||||
|
model: "Portrait Touchscreen Kiosk"
|
||||||
|
suggested_area: "Lounge"
|
||||||
|
|
||||||
|
entity_category: diagnostic
|
||||||
|
|
||||||
|
state_topic: "viewroad-status/flounder/brightness/actual/state"
|
||||||
|
|
||||||
|
availability_topic: "viewroad-status/flounder/availability"
|
||||||
|
payload_available: "ON"
|
||||||
|
payload_not_available: "OFF"
|
||||||
|
|
||||||
|
unit_of_measurement: "%"
|
||||||
|
state_class: measurement
|
||||||
|
|
||||||
|
icon: mdi:brightness-percent
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# Flounder Kiosk Presence Timeout #
|
||||||
|
#:########################################################################################:#
|
||||||
|
#
|
||||||
|
# Sets the shared touch and camera-presence timeout.
|
||||||
|
#
|
||||||
|
# The value is the total duration of the ten-step brightness ramp. Home Assistant
|
||||||
|
# displays whole minutes while MQTT stores and transfers seconds.
|
||||||
|
#
|
||||||
|
|
||||||
|
- number:
|
||||||
|
name: "Presence Timeout"
|
||||||
|
unique_id: flounder_kiosk_presence_timeout
|
||||||
|
default_entity_id: number.flounder_kiosk_presence_timeout
|
||||||
|
|
||||||
|
device:
|
||||||
|
identifiers:
|
||||||
|
- flounder_kiosk
|
||||||
|
name: "Flounder Kiosk"
|
||||||
|
manufacturer: "Dell"
|
||||||
|
model: "Portrait Touchscreen Kiosk"
|
||||||
|
suggested_area: "Lounge"
|
||||||
|
|
||||||
|
entity_category: config
|
||||||
|
|
||||||
|
command_topic: "viewroad-commands/flounder/presence/timeout/set"
|
||||||
|
state_topic: "viewroad-status/flounder/presence/timeout/state"
|
||||||
|
|
||||||
|
availability_topic: "viewroad-status/flounder/availability"
|
||||||
|
payload_available: "ON"
|
||||||
|
payload_not_available: "OFF"
|
||||||
|
|
||||||
|
command_template: >-
|
||||||
|
{{ (value | float(1) * 60) | round(0) | int }}
|
||||||
|
|
||||||
|
value_template: >-
|
||||||
|
{{ (value | float(60) / 60) | round(0) | int }}
|
||||||
|
|
||||||
|
min: 1
|
||||||
|
max: 1440
|
||||||
|
step: 1
|
||||||
|
mode: box
|
||||||
|
|
||||||
|
unit_of_measurement: "min"
|
||||||
|
|
||||||
|
optimistic: false
|
||||||
|
retain: false
|
||||||
|
|
||||||
|
icon: mdi:timer-outline
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# Flounder Kiosk Presence Active #
|
||||||
|
#:########################################################################################:#
|
||||||
|
#
|
||||||
|
# Reports whether temporary touch or camera-presence behaviour is active.
|
||||||
|
#
|
||||||
|
# It remains ON through the brightness ramp and returns to OFF when the selected
|
||||||
|
# display mode has been restored.
|
||||||
|
#
|
||||||
|
|
||||||
|
- binary_sensor:
|
||||||
|
name: "Presence Active"
|
||||||
|
unique_id: flounder_kiosk_presence_active
|
||||||
|
default_entity_id: binary_sensor.flounder_kiosk_presence_active
|
||||||
|
|
||||||
|
device:
|
||||||
|
identifiers:
|
||||||
|
- flounder_kiosk
|
||||||
|
name: "Flounder Kiosk"
|
||||||
|
manufacturer: "Dell"
|
||||||
|
model: "Portrait Touchscreen Kiosk"
|
||||||
|
suggested_area: "Lounge"
|
||||||
|
|
||||||
|
entity_category: diagnostic
|
||||||
|
|
||||||
|
state_topic: "viewroad-status/flounder/presence/state"
|
||||||
|
|
||||||
|
availability_topic: "viewroad-status/flounder/availability"
|
||||||
|
payload_available: "ON"
|
||||||
|
payload_not_available: "OFF"
|
||||||
|
|
||||||
|
payload_on: "ON"
|
||||||
|
payload_off: "OFF"
|
||||||
|
|
||||||
|
icon: mdi:account-eye
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# Flounder Kiosk Motion Wake #
|
||||||
|
#:########################################################################################:#
|
||||||
|
#
|
||||||
|
# Controls whether camera motion counts as display activity.
|
||||||
|
#
|
||||||
|
# Motion Wake does not affect touchscreen activity. Screen Lock ignores camera
|
||||||
|
# motion regardless of this switch while motion detection continues reporting.
|
||||||
|
#
|
||||||
|
|
||||||
|
- switch:
|
||||||
|
name: "Motion Wake"
|
||||||
|
unique_id: flounder_kiosk_motion_wake
|
||||||
|
default_entity_id: switch.flounder_kiosk_motion_wake
|
||||||
|
|
||||||
|
device:
|
||||||
|
identifiers:
|
||||||
|
- flounder_kiosk
|
||||||
|
name: "Flounder Kiosk"
|
||||||
|
manufacturer: "Dell"
|
||||||
|
model: "Portrait Touchscreen Kiosk"
|
||||||
|
suggested_area: "Lounge"
|
||||||
|
|
||||||
|
entity_category: config
|
||||||
|
|
||||||
|
command_topic: "viewroad-commands/flounder/motion_wake/set"
|
||||||
|
state_topic: "viewroad-status/flounder/motion_wake/state"
|
||||||
|
|
||||||
|
availability_topic: "viewroad-status/flounder/availability"
|
||||||
|
payload_available: "ON"
|
||||||
|
payload_not_available: "OFF"
|
||||||
|
|
||||||
|
payload_on: "ON"
|
||||||
|
payload_off: "OFF"
|
||||||
|
|
||||||
|
optimistic: false
|
||||||
|
retain: false
|
||||||
|
|
||||||
|
icon: mdi:motion-sensor
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# Flounder Kiosk Volume #
|
||||||
|
#:########################################################################################:#
|
||||||
|
#
|
||||||
|
# Controls the active PipeWire audio-sink volume from 0 to 100 percent.
|
||||||
|
#
|
||||||
|
|
||||||
|
- number:
|
||||||
|
name: "Volume"
|
||||||
|
unique_id: flounder_kiosk_volume
|
||||||
|
default_entity_id: number.flounder_kiosk_volume
|
||||||
|
|
||||||
|
device:
|
||||||
|
identifiers:
|
||||||
|
- flounder_kiosk
|
||||||
|
name: "Flounder Kiosk"
|
||||||
|
manufacturer: "Dell"
|
||||||
|
model: "Portrait Touchscreen Kiosk"
|
||||||
|
suggested_area: "Lounge"
|
||||||
|
|
||||||
|
command_topic: "viewroad-commands/flounder/audio/volume/set"
|
||||||
|
state_topic: "viewroad-status/flounder/audio/volume/state"
|
||||||
|
|
||||||
|
availability_topic: "viewroad-status/flounder/availability"
|
||||||
|
payload_available: "ON"
|
||||||
|
payload_not_available: "OFF"
|
||||||
|
|
||||||
|
min: 0
|
||||||
|
max: 100
|
||||||
|
step: 1
|
||||||
|
mode: slider
|
||||||
|
|
||||||
|
unit_of_measurement: "%"
|
||||||
|
|
||||||
|
optimistic: false
|
||||||
|
retain: false
|
||||||
|
|
||||||
|
icon: mdi:volume-high
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# Flounder Kiosk Mute #
|
||||||
|
#:########################################################################################:#
|
||||||
|
#
|
||||||
|
# Controls the mute state of the active PipeWire audio sink.
|
||||||
|
#
|
||||||
|
|
||||||
|
- switch:
|
||||||
|
name: "Mute"
|
||||||
|
unique_id: flounder_kiosk_mute
|
||||||
|
default_entity_id: switch.flounder_kiosk_mute
|
||||||
|
|
||||||
|
device:
|
||||||
|
identifiers:
|
||||||
|
- flounder_kiosk
|
||||||
|
name: "Flounder Kiosk"
|
||||||
|
manufacturer: "Dell"
|
||||||
|
model: "Portrait Touchscreen Kiosk"
|
||||||
|
suggested_area: "Lounge"
|
||||||
|
|
||||||
|
command_topic: "viewroad-commands/flounder/audio/mute/set"
|
||||||
|
state_topic: "viewroad-status/flounder/audio/mute/state"
|
||||||
|
|
||||||
|
availability_topic: "viewroad-status/flounder/availability"
|
||||||
|
payload_available: "ON"
|
||||||
|
payload_not_available: "OFF"
|
||||||
|
|
||||||
|
payload_on: "ON"
|
||||||
|
payload_off: "OFF"
|
||||||
|
|
||||||
|
optimistic: false
|
||||||
|
retain: false
|
||||||
|
|
||||||
|
icon: mdi:volume-mute
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# Flounder Kiosk Screen On #
|
||||||
|
#:########################################################################################:#
|
||||||
|
#
|
||||||
|
# Reports the real physical panel state from Linux DPMS.
|
||||||
|
#
|
||||||
|
# This can report ON while Display Mode remains Screen Off because touch or
|
||||||
|
# qualifying camera motion has temporarily woken the panel.
|
||||||
|
#
|
||||||
|
|
||||||
|
- binary_sensor:
|
||||||
|
name: "Screen On"
|
||||||
|
unique_id: flounder_kiosk_screen_on
|
||||||
|
default_entity_id: binary_sensor.flounder_kiosk_screen_on
|
||||||
|
|
||||||
|
device:
|
||||||
|
identifiers:
|
||||||
|
- flounder_kiosk
|
||||||
|
name: "Flounder Kiosk"
|
||||||
|
manufacturer: "Dell"
|
||||||
|
model: "Portrait Touchscreen Kiosk"
|
||||||
|
suggested_area: "Lounge"
|
||||||
|
|
||||||
|
entity_category: diagnostic
|
||||||
|
|
||||||
|
state_topic: "viewroad-status/flounder/screen/state"
|
||||||
|
|
||||||
|
availability_topic: "viewroad-status/flounder/availability"
|
||||||
|
payload_available: "ON"
|
||||||
|
payload_not_available: "OFF"
|
||||||
|
|
||||||
|
payload_on: "ON"
|
||||||
|
payload_off: "OFF"
|
||||||
|
|
||||||
|
device_class: power
|
||||||
|
icon: mdi:monitor
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# Flounder Kiosk Screensaver Active #
|
||||||
|
#:########################################################################################:#
|
||||||
|
#
|
||||||
|
# Reports whether XScreenSaver is currently running.
|
||||||
|
#
|
||||||
|
# In Screensaver mode it normally reports ON, but temporarily reports OFF while
|
||||||
|
# touch or qualifying camera motion displays the Home Assistant kiosk.
|
||||||
|
#
|
||||||
|
|
||||||
|
- binary_sensor:
|
||||||
|
name: "Screensaver Active"
|
||||||
|
unique_id: flounder_kiosk_screensaver_active
|
||||||
|
default_entity_id: binary_sensor.flounder_kiosk_screensaver_active
|
||||||
|
|
||||||
|
device:
|
||||||
|
identifiers:
|
||||||
|
- flounder_kiosk
|
||||||
|
name: "Flounder Kiosk"
|
||||||
|
manufacturer: "Dell"
|
||||||
|
model: "Portrait Touchscreen Kiosk"
|
||||||
|
suggested_area: "Lounge"
|
||||||
|
|
||||||
|
entity_category: diagnostic
|
||||||
|
|
||||||
|
state_topic: "viewroad-status/flounder/screensaver/state"
|
||||||
|
|
||||||
|
availability_topic: "viewroad-status/flounder/availability"
|
||||||
|
payload_available: "ON"
|
||||||
|
payload_not_available: "OFF"
|
||||||
|
|
||||||
|
payload_on: "ON"
|
||||||
|
payload_off: "OFF"
|
||||||
|
|
||||||
|
icon: mdi:monitor-shimmer
|
||||||
|
|
||||||
|
#:########################################################################################:#
|
||||||
|
# Flounder Kiosk Motion #
|
||||||
|
#:########################################################################################:#
|
||||||
|
#
|
||||||
|
# Reports raw movement detected by the local Motion camera service.
|
||||||
|
#
|
||||||
|
# Motion continues reporting in Screen Lock and while Motion Wake is OFF. It only
|
||||||
|
# affects display activity when Motion Wake is ON and Display Mode is not
|
||||||
|
# Screen Lock.
|
||||||
|
#
|
||||||
|
|
||||||
|
- binary_sensor:
|
||||||
|
name: "Motion"
|
||||||
|
unique_id: flounder_kiosk_motion
|
||||||
|
default_entity_id: binary_sensor.flounder_kiosk_motion
|
||||||
|
|
||||||
|
device:
|
||||||
|
identifiers:
|
||||||
|
- flounder_kiosk
|
||||||
|
name: "Flounder Kiosk"
|
||||||
|
manufacturer: "Dell"
|
||||||
|
model: "Portrait Touchscreen Kiosk"
|
||||||
|
suggested_area: "Lounge"
|
||||||
|
|
||||||
|
state_topic: "viewroad-status/flounder/motion/state"
|
||||||
|
|
||||||
|
availability_topic: "viewroad-status/flounder/availability"
|
||||||
|
payload_available: "ON"
|
||||||
|
payload_not_available: "OFF"
|
||||||
|
|
||||||
|
payload_on: "ON"
|
||||||
|
payload_off: "OFF"
|
||||||
|
|
||||||
|
device_class: motion
|
||||||
@@ -2,6 +2,11 @@
|
|||||||
# PACKAGE: Free Power Time Automation #
|
# PACKAGE: Free Power Time Automation #
|
||||||
#:########################################################################################:#
|
#:########################################################################################:#
|
||||||
# VERSION:
|
# VERSION:
|
||||||
|
# 1.2.0 - 2026-07-24
|
||||||
|
# - Added startup catch-up to end_actions: when HA starts outside the
|
||||||
|
# free power window, the end actions (chargers off, dehumidifier off)
|
||||||
|
# are applied immediately.
|
||||||
|
#
|
||||||
# 1.1.0 - 2026-06-24
|
# 1.1.0 - 2026-06-24
|
||||||
# - Changed gas-to-heatpump handover so the heat pump setpoint is offset from
|
# - Changed gas-to-heatpump handover so the heat pump setpoint is offset from
|
||||||
# the gas heater setpoint.
|
# the gas heater setpoint.
|
||||||
@@ -316,5 +321,11 @@ automation:
|
|||||||
triggers:
|
triggers:
|
||||||
- trigger: time
|
- trigger: time
|
||||||
at: input_datetime.free_power_end_time
|
at: input_datetime.free_power_end_time
|
||||||
|
- trigger: homeassistant
|
||||||
|
event: start
|
||||||
|
conditions:
|
||||||
|
- condition: state
|
||||||
|
entity_id: binary_sensor.free_power_time_active
|
||||||
|
state: "off"
|
||||||
actions:
|
actions:
|
||||||
- action: script.free_power_end_actions
|
- action: script.free_power_end_actions
|
||||||
|
|||||||
@@ -9,9 +9,14 @@
|
|||||||
# packages/heat_pump_master_bedroom_schedules.yaml
|
# packages/heat_pump_master_bedroom_schedules.yaml
|
||||||
#
|
#
|
||||||
# VERSION:
|
# VERSION:
|
||||||
# V1.1 2026-07-20
|
# V1.2 2026-07-24
|
||||||
#
|
#
|
||||||
# VERSION HISTORY:
|
# VERSION HISTORY:
|
||||||
|
# V1.2 2026-07-24
|
||||||
|
# - Added startup catch-up to midnight_off: when HA starts between
|
||||||
|
# midnight and 21:00 with the Midnight Off or Night Power toggle on,
|
||||||
|
# the heat pump is turned off immediately.
|
||||||
|
#
|
||||||
# V1.1 2026-07-20
|
# V1.1 2026-07-20
|
||||||
# - Added structured documentation for schedules, boost, and helper behavior.
|
# - Added structured documentation for schedules, boost, and helper behavior.
|
||||||
#
|
#
|
||||||
@@ -50,7 +55,9 @@
|
|||||||
#
|
#
|
||||||
# OPERATION NOTES:
|
# OPERATION NOTES:
|
||||||
# - The 21:00 and midnight schedules use exact-time triggers.
|
# - The 21:00 and midnight schedules use exact-time triggers.
|
||||||
# - There is no startup catch-up if Home Assistant is offline at either time.
|
# - The midnight_off automation includes a startup trigger: if HA restarts
|
||||||
|
# between midnight and 21:00 with the Midnight Off or Night Power toggle
|
||||||
|
# on, the heat pump is turned off immediately.
|
||||||
#
|
#
|
||||||
##########################################################################################
|
##########################################################################################
|
||||||
|
|
||||||
@@ -214,6 +221,11 @@ automation:
|
|||||||
trigger:
|
trigger:
|
||||||
- platform: time
|
- platform: time
|
||||||
at: "00:00:00"
|
at: "00:00:00"
|
||||||
|
- platform: homeassistant
|
||||||
|
event: start
|
||||||
|
condition:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ now().hour < 21 }}"
|
||||||
action:
|
action:
|
||||||
- choose:
|
- choose:
|
||||||
- conditions:
|
- conditions:
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ script:
|
|||||||
#switch.esp_loungemiddleswitch_relay_3_downlights_north: "on"
|
#switch.esp_loungemiddleswitch_relay_3_downlights_north: "on"
|
||||||
switch.lounge_nspanel_touchscreen_lounge_stair_downlights: "on" # non dimmable pair
|
switch.lounge_nspanel_touchscreen_lounge_stair_downlights: "on" # non dimmable pair
|
||||||
light.esp_breakfastbarleds_breakfast_bar_leds: 90
|
light.esp_breakfastbarleds_breakfast_bar_leds: 90
|
||||||
light.esp_loungecabinetleds_lounge_cabinet_leds: 90
|
number.esp_loungecabinetleds_lounge_cabinet_leds_output_set_0_100: 100
|
||||||
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 90
|
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 90
|
||||||
switch.lounge_cupboard_dual_usb_xus09_l2: "on"
|
switch.lounge_cupboard_dual_usb_xus09_l2: "on"
|
||||||
switch.esp_loungesouthleftswitch_relay_1_wall_washer_left: "on"
|
switch.esp_loungesouthleftswitch_relay_1_wall_washer_left: "on"
|
||||||
@@ -146,7 +146,7 @@ script:
|
|||||||
light.esp_lounge6chdimmer_lounge_downlights_south: 60
|
light.esp_lounge6chdimmer_lounge_downlights_south: 60
|
||||||
light.esp_lounge6chdimmer_lounge_rafter_buttons: 40
|
light.esp_lounge6chdimmer_lounge_rafter_buttons: 40
|
||||||
light.esp_breakfastbarleds_breakfast_bar_leds: 60
|
light.esp_breakfastbarleds_breakfast_bar_leds: 60
|
||||||
light.esp_loungecabinetleds_lounge_cabinet_leds: 60
|
number.esp_loungecabinetleds_lounge_cabinet_leds_output_set_0_100: 66
|
||||||
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 60
|
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 60
|
||||||
#switch.esp_loungemiddleswitch_relay_3_downlights_north: "off" # non-dimmable pair
|
#switch.esp_loungemiddleswitch_relay_3_downlights_north: "off" # non-dimmable pair
|
||||||
switch.lounge_nspanel_touchscreen_lounge_stair_downlights: "off" # non dimmable pair
|
switch.lounge_nspanel_touchscreen_lounge_stair_downlights: "off" # non dimmable pair
|
||||||
@@ -167,7 +167,7 @@ script:
|
|||||||
light.esp_lounge6chdimmer_lounge_downlights_south: 40
|
light.esp_lounge6chdimmer_lounge_downlights_south: 40
|
||||||
light.esp_lounge6chdimmer_lounge_rafter_buttons: 30
|
light.esp_lounge6chdimmer_lounge_rafter_buttons: 30
|
||||||
light.esp_breakfastbarleds_breakfast_bar_leds: 50
|
light.esp_breakfastbarleds_breakfast_bar_leds: 50
|
||||||
light.esp_loungecabinetleds_lounge_cabinet_leds: 50
|
number.esp_loungecabinetleds_lounge_cabinet_leds_output_set_0_100: 55
|
||||||
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 50
|
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 50
|
||||||
#switch.esp_loungemiddleswitch_relay_3_downlights_north: "off" # non-dimmable pair
|
#switch.esp_loungemiddleswitch_relay_3_downlights_north: "off" # non-dimmable pair
|
||||||
switch.lounge_nspanel_touchscreen_lounge_stair_downlights: "off" # non dimmable pair
|
switch.lounge_nspanel_touchscreen_lounge_stair_downlights: "off" # non dimmable pair
|
||||||
@@ -188,7 +188,7 @@ script:
|
|||||||
light.esp_lounge6chdimmer_lounge_downlights_south: 30
|
light.esp_lounge6chdimmer_lounge_downlights_south: 30
|
||||||
light.esp_lounge6chdimmer_lounge_rafter_buttons: 0
|
light.esp_lounge6chdimmer_lounge_rafter_buttons: 0
|
||||||
light.esp_breakfastbarleds_breakfast_bar_leds: 40
|
light.esp_breakfastbarleds_breakfast_bar_leds: 40
|
||||||
light.esp_loungecabinetleds_lounge_cabinet_leds: 40
|
number.esp_loungecabinetleds_lounge_cabinet_leds_output_set_0_100: 44
|
||||||
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 40
|
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 40
|
||||||
#switch.esp_loungemiddleswitch_relay_3_downlights_north: "off"
|
#switch.esp_loungemiddleswitch_relay_3_downlights_north: "off"
|
||||||
switch.lounge_nspanel_touchscreen_lounge_stair_downlights: "off" # non dimmable pair
|
switch.lounge_nspanel_touchscreen_lounge_stair_downlights: "off" # non dimmable pair
|
||||||
@@ -228,7 +228,7 @@ script:
|
|||||||
light.esp_lounge6chdimmer_lounge_downlights_south: 0
|
light.esp_lounge6chdimmer_lounge_downlights_south: 0
|
||||||
light.esp_lounge6chdimmer_lounge_rafter_buttons: 0
|
light.esp_lounge6chdimmer_lounge_rafter_buttons: 0
|
||||||
light.esp_breakfastbarleds_breakfast_bar_leds: 5
|
light.esp_breakfastbarleds_breakfast_bar_leds: 5
|
||||||
light.esp_loungecabinetleds_lounge_cabinet_leds: 5
|
number.esp_loungecabinetleds_lounge_cabinet_leds_output_set_0_100: 4
|
||||||
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 5
|
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 5
|
||||||
#switch.esp_loungemiddleswitch_relay_3_downlights_north: "off"
|
#switch.esp_loungemiddleswitch_relay_3_downlights_north: "off"
|
||||||
switch.lounge_nspanel_touchscreen_lounge_stair_downlights: "off" # non dimmable pair
|
switch.lounge_nspanel_touchscreen_lounge_stair_downlights: "off" # non dimmable pair
|
||||||
@@ -246,7 +246,7 @@ script:
|
|||||||
light.esp_lounge6chdimmer_couch_spots_right: 20
|
light.esp_lounge6chdimmer_couch_spots_right: 20
|
||||||
light.esp_lounge6chdimmer_lounge_rafter_buttons: 15
|
light.esp_lounge6chdimmer_lounge_rafter_buttons: 15
|
||||||
light.esp_breakfastbarleds_breakfast_bar_leds: 25
|
light.esp_breakfastbarleds_breakfast_bar_leds: 25
|
||||||
light.esp_loungecabinetleds_lounge_cabinet_leds: 30
|
number.esp_loungecabinetleds_lounge_cabinet_leds_output_set_0_100: 33
|
||||||
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 30
|
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 30
|
||||||
#light.tasmo_h801_loungeled1_6180_a: 25
|
#light.tasmo_h801_loungeled1_6180_a: 25
|
||||||
#light.tasmo_h801_loungeled1_6180_b: 25
|
#light.tasmo_h801_loungeled1_6180_b: 25
|
||||||
@@ -270,7 +270,7 @@ script:
|
|||||||
#switch.esp_loungemiddleswitch_relay_3_downlights_north: "off"
|
#switch.esp_loungemiddleswitch_relay_3_downlights_north: "off"
|
||||||
switch.lounge_nspanel_touchscreen_lounge_stair_downlights: "off" # non dimmable pair
|
switch.lounge_nspanel_touchscreen_lounge_stair_downlights: "off" # non dimmable pair
|
||||||
light.esp_breakfastbarleds_breakfast_bar_leds: 0
|
light.esp_breakfastbarleds_breakfast_bar_leds: 0
|
||||||
light.esp_loungecabinetleds_lounge_cabinet_leds: 0
|
number.esp_loungecabinetleds_lounge_cabinet_leds_output_set_0_100: 0
|
||||||
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 0
|
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 0
|
||||||
switch.lounge_cupboard_dual_usb_xus09_l2: "off"
|
switch.lounge_cupboard_dual_usb_xus09_l2: "off"
|
||||||
switch.esp_loungesouthleftswitch_relay_1_wall_washer_left: "off"
|
switch.esp_loungesouthleftswitch_relay_1_wall_washer_left: "off"
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
################################################################################
|
################################################################################
|
||||||
# PACKAGE: Office Lights And Power Backup Occupancy Automation
|
# PACKAGE: Office Power Backup Occupancy Automation
|
||||||
################################################################################
|
################################################################################
|
||||||
#
|
#
|
||||||
# Version:
|
# Version:
|
||||||
|
# - 1.1 - 2026-07-25
|
||||||
|
# - Stripped light control (now handled by direct MQTT)
|
||||||
|
# - Retains power supply backup control only
|
||||||
|
#
|
||||||
# - 1.0 - 2026-04-25
|
# - 1.0 - 2026-04-25
|
||||||
# - Initial package version.
|
# - Initial package version.
|
||||||
# - Backup automation for Office lights and Office power.
|
# - Backup automation for Office lights and Office power.
|
||||||
@@ -10,19 +14,18 @@
|
|||||||
# - Uses Office spare button / relay as a backup manual master.
|
# - Uses Office spare button / relay as a backup manual master.
|
||||||
#
|
#
|
||||||
# Operation:
|
# Operation:
|
||||||
# - Turns Office lights and power on when the Office mmWave occupancy sensor
|
# - Turns Office power supplies on when the Office mmWave occupancy sensor
|
||||||
# detects occupancy or movement.
|
# detects occupancy or movement.
|
||||||
#
|
#
|
||||||
# - Turns Office lights and power off after the Office mmWave occupancy sensor
|
# - Turns Office power supplies off after the Office mmWave occupancy sensor
|
||||||
# has been clear for the configured delay period.
|
# has been clear for the configured delay period.
|
||||||
#
|
#
|
||||||
# - Provides a backup manual control path using the Office spare button.
|
# - Provides a backup manual control path using the Office spare button.
|
||||||
# This is useful if the occupancy sensor is offline.
|
# This is useful if the occupancy sensor is offline.
|
||||||
#
|
#
|
||||||
# Notes:
|
# Notes:
|
||||||
# - This is treated as a BACKUP automation.
|
# - This is treated as a BACKUP automation for POWER SUPPLIES ONLY.
|
||||||
# - The standard method should still be the direct ESPHome/MQTT control path.
|
# - Light control is handled by direct ESPHome/MQTT (see device YAMLs).
|
||||||
# - This HA automation provides a fallback path using HA entity states.
|
|
||||||
# - The physical spare button is read using:
|
# - The physical spare button is read using:
|
||||||
# binary_sensor.esp_officelights_button_3_spare
|
# binary_sensor.esp_officelights_button_3_spare
|
||||||
# - The spare relay is used as the manual master/latch state:
|
# - The spare relay is used as the manual master/latch state:
|
||||||
@@ -36,7 +39,7 @@
|
|||||||
|
|
||||||
input_number:
|
input_number:
|
||||||
office_lights_backup_clear_delay_seconds:
|
office_lights_backup_clear_delay_seconds:
|
||||||
name: "Office Lights Backup Clear Delay Seconds"
|
name: "Office Power Backup Clear Delay Seconds"
|
||||||
min: 0
|
min: 0
|
||||||
max: 3600
|
max: 3600
|
||||||
step: 1
|
step: 1
|
||||||
@@ -50,13 +53,14 @@ input_number:
|
|||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
automation:
|
automation:
|
||||||
- id: office_lights_power_backup_occupancy_control
|
- id: office_power_backup_occupancy_control
|
||||||
alias: "Office Lights And Power - Backup Occupancy Control"
|
alias: "Office Power - Backup Occupancy Control"
|
||||||
description: >
|
description: >
|
||||||
Backup automation for Office lights and power. Turns required devices on
|
Backup automation for Office power supplies. Turns power on when Office
|
||||||
when Office mmWave occupancy or movement is detected. Turns them off after
|
mmWave occupancy or movement is detected. Turns power off after the
|
||||||
the occupancy sensor is clear for the configured delay period. Also allows
|
occupancy sensor is clear for the configured delay period. Also allows
|
||||||
manual backup toggling using the Office spare button and spare relay.
|
manual backup toggling using the Office spare button and spare relay.
|
||||||
|
Light control is handled by direct ESPHome/MQTT sync.
|
||||||
mode: restart
|
mode: restart
|
||||||
triggers:
|
triggers:
|
||||||
##########################################################################
|
##########################################################################
|
||||||
@@ -79,8 +83,8 @@ automation:
|
|||||||
# Manual backup button press.
|
# Manual backup button press.
|
||||||
#
|
#
|
||||||
# The spare relay state is used as the master/latch:
|
# The spare relay state is used as the master/latch:
|
||||||
# - If spare relay is OFF when the button is pressed, turn everything ON.
|
# - If spare relay is OFF when the button is pressed, turn power ON.
|
||||||
# - If spare relay is ON when the button is pressed, turn everything OFF.
|
# - If spare relay is ON when the button is pressed, turn power OFF.
|
||||||
##########################################################################
|
##########################################################################
|
||||||
- trigger: state
|
- trigger: state
|
||||||
entity_id: binary_sensor.esp_officelights_button_3_spare
|
entity_id: binary_sensor.esp_officelights_button_3_spare
|
||||||
@@ -102,15 +106,15 @@ automation:
|
|||||||
- choose:
|
- choose:
|
||||||
######################################################################
|
######################################################################
|
||||||
# ON LOGIC:
|
# ON LOGIC:
|
||||||
# Occupancy detected - turn everything on.
|
# Occupancy detected - turn power supplies on.
|
||||||
######################################################################
|
######################################################################
|
||||||
- alias: "Occupancy detected - turn Office lights and power on"
|
- alias: "Occupancy detected - turn Office power on"
|
||||||
conditions:
|
conditions:
|
||||||
- condition: trigger
|
- condition: trigger
|
||||||
id: occupancy_detected
|
id: occupancy_detected
|
||||||
sequence:
|
sequence:
|
||||||
##############################################################
|
##############################################################
|
||||||
# Power first.
|
# Power supplies.
|
||||||
##############################################################
|
##############################################################
|
||||||
- alias: "Turn on Office ELV power supply if needed"
|
- alias: "Turn on Office ELV power supply if needed"
|
||||||
if:
|
if:
|
||||||
@@ -132,59 +136,6 @@ automation:
|
|||||||
target:
|
target:
|
||||||
entity_id: switch.esp_officedeskrightgpo_office_right_hand_gpo
|
entity_id: switch.esp_officedeskrightgpo_office_right_hand_gpo
|
||||||
|
|
||||||
#- alias: "Turn on Office USB Hub if needed"
|
|
||||||
# if:
|
|
||||||
# - condition: state
|
|
||||||
# entity_id: switch.esp_officeusbhubpower_usb_hub_power_supply
|
|
||||||
# state: "off"
|
|
||||||
# then:
|
|
||||||
# - action: switch.turn_on
|
|
||||||
# target:
|
|
||||||
# entity_id: switch.esp_officeusbhubpower_usb_hub_power_supply
|
|
||||||
|
|
||||||
##############################################################
|
|
||||||
# Lights.
|
|
||||||
##############################################################
|
|
||||||
- alias: "Turn on Office right hand bunker light if needed"
|
|
||||||
if:
|
|
||||||
- condition: state
|
|
||||||
entity_id: light.esp_officeduallights_light_1_right_hand_bunker_light
|
|
||||||
state: "off"
|
|
||||||
then:
|
|
||||||
- action: light.turn_on
|
|
||||||
target:
|
|
||||||
entity_id: light.esp_officeduallights_light_1_right_hand_bunker_light
|
|
||||||
|
|
||||||
- alias: "Turn on Office cool white overhead lights if needed"
|
|
||||||
if:
|
|
||||||
- condition: state
|
|
||||||
entity_id: light.esp_officeduallights_light_2_cool_white_overhead_lights
|
|
||||||
state: "off"
|
|
||||||
then:
|
|
||||||
- action: light.turn_on
|
|
||||||
target:
|
|
||||||
entity_id: light.esp_officeduallights_light_2_cool_white_overhead_lights
|
|
||||||
|
|
||||||
- alias: "Turn on Office nighttime lights relay if needed"
|
|
||||||
if:
|
|
||||||
- condition: state
|
|
||||||
entity_id: switch.esp_officelights_relay_1_nighttime_lights
|
|
||||||
state: "off"
|
|
||||||
then:
|
|
||||||
- action: switch.turn_on
|
|
||||||
target:
|
|
||||||
entity_id: switch.esp_officelights_relay_1_nighttime_lights
|
|
||||||
|
|
||||||
- alias: "Turn on Office daytime lights relay if needed"
|
|
||||||
if:
|
|
||||||
- condition: state
|
|
||||||
entity_id: switch.esp_officelights_relay_2_daytime_lights
|
|
||||||
state: "off"
|
|
||||||
then:
|
|
||||||
- action: switch.turn_on
|
|
||||||
target:
|
|
||||||
entity_id: switch.esp_officelights_relay_2_daytime_lights
|
|
||||||
|
|
||||||
##############################################################
|
##############################################################
|
||||||
# Manual master/latch relay.
|
# Manual master/latch relay.
|
||||||
##############################################################
|
##############################################################
|
||||||
@@ -200,9 +151,9 @@ automation:
|
|||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# OFF LOGIC:
|
# OFF LOGIC:
|
||||||
# Occupancy clear - wait, re-check, then turn everything off.
|
# Occupancy clear - wait, re-check, then turn power supplies off.
|
||||||
######################################################################
|
######################################################################
|
||||||
- alias: "Occupancy clear - wait, re-check, then turn Office lights and power off"
|
- alias: "Occupancy clear - wait, re-check, then turn Office power off"
|
||||||
conditions:
|
conditions:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: >
|
value_template: >
|
||||||
@@ -229,50 +180,7 @@ automation:
|
|||||||
state: "off"
|
state: "off"
|
||||||
|
|
||||||
##############################################################
|
##############################################################
|
||||||
# Lights off first.
|
# Power off.
|
||||||
##############################################################
|
|
||||||
- alias: "Turn off Office right hand bunker light if needed"
|
|
||||||
if:
|
|
||||||
- condition: state
|
|
||||||
entity_id: light.esp_officeduallights_light_1_right_hand_bunker_light
|
|
||||||
state: "on"
|
|
||||||
then:
|
|
||||||
- action: light.turn_off
|
|
||||||
target:
|
|
||||||
entity_id: light.esp_officeduallights_light_1_right_hand_bunker_light
|
|
||||||
|
|
||||||
- alias: "Turn off Office cool white overhead lights if needed"
|
|
||||||
if:
|
|
||||||
- condition: state
|
|
||||||
entity_id: light.esp_officeduallights_light_2_cool_white_overhead_lights
|
|
||||||
state: "on"
|
|
||||||
then:
|
|
||||||
- action: light.turn_off
|
|
||||||
target:
|
|
||||||
entity_id: light.esp_officeduallights_light_2_cool_white_overhead_lights
|
|
||||||
|
|
||||||
- alias: "Turn off Office nighttime lights relay if needed"
|
|
||||||
if:
|
|
||||||
- condition: state
|
|
||||||
entity_id: switch.esp_officelights_relay_1_nighttime_lights
|
|
||||||
state: "on"
|
|
||||||
then:
|
|
||||||
- action: switch.turn_off
|
|
||||||
target:
|
|
||||||
entity_id: switch.esp_officelights_relay_1_nighttime_lights
|
|
||||||
|
|
||||||
- alias: "Turn off Office daytime lights relay if needed"
|
|
||||||
if:
|
|
||||||
- condition: state
|
|
||||||
entity_id: switch.esp_officelights_relay_2_daytime_lights
|
|
||||||
state: "on"
|
|
||||||
then:
|
|
||||||
- action: switch.turn_off
|
|
||||||
target:
|
|
||||||
entity_id: switch.esp_officelights_relay_2_daytime_lights
|
|
||||||
|
|
||||||
##############################################################
|
|
||||||
# Power off after lights.
|
|
||||||
##############################################################
|
##############################################################
|
||||||
- alias: "Turn off Office right hand GPO if needed"
|
- alias: "Turn off Office right hand GPO if needed"
|
||||||
if:
|
if:
|
||||||
@@ -294,16 +202,6 @@ automation:
|
|||||||
target:
|
target:
|
||||||
entity_id: switch.esp_officeelvcontrol_office_elv_power_supply
|
entity_id: switch.esp_officeelvcontrol_office_elv_power_supply
|
||||||
|
|
||||||
#- alias: "Turn off Office USB Hub power supply if needed"
|
|
||||||
# if:
|
|
||||||
# - condition: state
|
|
||||||
# entity_id: switch.esp_officeusbhubpower_usb_hub_power_supply
|
|
||||||
# state: "on"
|
|
||||||
# then:
|
|
||||||
# - action: switch.turn_off
|
|
||||||
# target:
|
|
||||||
# entity_id: switch.esp_officeusbhubpower_usb_hub_power_supply
|
|
||||||
|
|
||||||
##############################################################
|
##############################################################
|
||||||
# Manual master/latch relay off last.
|
# Manual master/latch relay off last.
|
||||||
##############################################################
|
##############################################################
|
||||||
@@ -319,9 +217,9 @@ automation:
|
|||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# MANUAL BACKUP LOGIC:
|
# MANUAL BACKUP LOGIC:
|
||||||
# Button pressed while spare relay master is ON - turn everything OFF.
|
# Button pressed while spare relay master is ON - turn power off.
|
||||||
######################################################################
|
######################################################################
|
||||||
- alias: "Backup button pressed - spare relay on, turn everything off"
|
- alias: "Backup button pressed - spare relay on, turn power off"
|
||||||
conditions:
|
conditions:
|
||||||
- condition: trigger
|
- condition: trigger
|
||||||
id: backup_button_pressed
|
id: backup_button_pressed
|
||||||
@@ -330,50 +228,7 @@ automation:
|
|||||||
state: "on"
|
state: "on"
|
||||||
sequence:
|
sequence:
|
||||||
##############################################################
|
##############################################################
|
||||||
# Lights off first.
|
# Power off.
|
||||||
##############################################################
|
|
||||||
- alias: "Turn off Office right hand bunker light if needed"
|
|
||||||
if:
|
|
||||||
- condition: state
|
|
||||||
entity_id: light.esp_officeduallights_light_1_right_hand_bunker_light
|
|
||||||
state: "on"
|
|
||||||
then:
|
|
||||||
- action: light.turn_off
|
|
||||||
target:
|
|
||||||
entity_id: light.esp_officeduallights_light_1_right_hand_bunker_light
|
|
||||||
|
|
||||||
- alias: "Turn off Office cool white overhead lights if needed"
|
|
||||||
if:
|
|
||||||
- condition: state
|
|
||||||
entity_id: light.esp_officeduallights_light_2_cool_white_overhead_lights
|
|
||||||
state: "on"
|
|
||||||
then:
|
|
||||||
- action: light.turn_off
|
|
||||||
target:
|
|
||||||
entity_id: light.esp_officeduallights_light_2_cool_white_overhead_lights
|
|
||||||
|
|
||||||
- alias: "Turn off Office nighttime lights relay if needed"
|
|
||||||
if:
|
|
||||||
- condition: state
|
|
||||||
entity_id: switch.esp_officelights_relay_1_nighttime_lights
|
|
||||||
state: "on"
|
|
||||||
then:
|
|
||||||
- action: switch.turn_off
|
|
||||||
target:
|
|
||||||
entity_id: switch.esp_officelights_relay_1_nighttime_lights
|
|
||||||
|
|
||||||
- alias: "Turn off Office daytime lights relay if needed"
|
|
||||||
if:
|
|
||||||
- condition: state
|
|
||||||
entity_id: switch.esp_officelights_relay_2_daytime_lights
|
|
||||||
state: "on"
|
|
||||||
then:
|
|
||||||
- action: switch.turn_off
|
|
||||||
target:
|
|
||||||
entity_id: switch.esp_officelights_relay_2_daytime_lights
|
|
||||||
|
|
||||||
##############################################################
|
|
||||||
# Power off after lights.
|
|
||||||
##############################################################
|
##############################################################
|
||||||
- alias: "Turn off Office right hand GPO if needed"
|
- alias: "Turn off Office right hand GPO if needed"
|
||||||
if:
|
if:
|
||||||
@@ -395,16 +250,6 @@ automation:
|
|||||||
target:
|
target:
|
||||||
entity_id: switch.esp_officeelvcontrol_office_elv_power_supply
|
entity_id: switch.esp_officeelvcontrol_office_elv_power_supply
|
||||||
|
|
||||||
#- alias: "Turn off Office USB Hub power supply if needed"
|
|
||||||
# if:
|
|
||||||
# - condition: state
|
|
||||||
# entity_id: switch.esp_officeusbhubpower_usb_hub_power_supply
|
|
||||||
# state: "on"
|
|
||||||
# then:
|
|
||||||
# - action: switch.turn_off
|
|
||||||
# target:
|
|
||||||
# entity_id: switch.esp_officeusbhubpower_usb_hub_power_supply
|
|
||||||
|
|
||||||
##############################################################
|
##############################################################
|
||||||
# Manual master/latch relay off last.
|
# Manual master/latch relay off last.
|
||||||
##############################################################
|
##############################################################
|
||||||
@@ -420,12 +265,12 @@ automation:
|
|||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# MANUAL BACKUP LOGIC:
|
# MANUAL BACKUP LOGIC:
|
||||||
# Button pressed while spare relay master is OFF - turn everything ON.
|
# Button pressed while spare relay master is OFF - turn power on.
|
||||||
#
|
#
|
||||||
# No off timer is started from this manual press. If the occupancy
|
# No off timer is started from this manual press. If the occupancy
|
||||||
# sensor later changes to clear, the normal clear-delay logic will run.
|
# sensor later changes to clear, the normal clear-delay logic will run.
|
||||||
######################################################################
|
######################################################################
|
||||||
- alias: "Backup button pressed - spare relay off, turn everything on"
|
- alias: "Backup button pressed - spare relay off, turn power on"
|
||||||
conditions:
|
conditions:
|
||||||
- condition: trigger
|
- condition: trigger
|
||||||
id: backup_button_pressed
|
id: backup_button_pressed
|
||||||
@@ -434,7 +279,7 @@ automation:
|
|||||||
state: "off"
|
state: "off"
|
||||||
sequence:
|
sequence:
|
||||||
##############################################################
|
##############################################################
|
||||||
# Power first.
|
# Power supplies.
|
||||||
##############################################################
|
##############################################################
|
||||||
- alias: "Turn on Office ELV power supply if needed"
|
- alias: "Turn on Office ELV power supply if needed"
|
||||||
if:
|
if:
|
||||||
@@ -456,59 +301,6 @@ automation:
|
|||||||
target:
|
target:
|
||||||
entity_id: switch.esp_officedeskrightgpo_office_right_hand_gpo
|
entity_id: switch.esp_officedeskrightgpo_office_right_hand_gpo
|
||||||
|
|
||||||
# alias: "Turn on Office USB Hub power supply if needed"
|
|
||||||
# if:
|
|
||||||
# - condition: state
|
|
||||||
# entity_id: switch.esp_officeusbhubpower_usb_hub_power_supply
|
|
||||||
# state: "off"
|
|
||||||
# then:
|
|
||||||
# - action: switch.turn_on
|
|
||||||
# target:
|
|
||||||
# entity_id: switch.esp_officeusbhubpower_usb_hub_power_supply
|
|
||||||
|
|
||||||
##############################################################
|
|
||||||
# Lights.
|
|
||||||
##############################################################
|
|
||||||
- alias: "Turn on Office right hand bunker light if needed"
|
|
||||||
if:
|
|
||||||
- condition: state
|
|
||||||
entity_id: light.esp_officeduallights_light_1_right_hand_bunker_light
|
|
||||||
state: "off"
|
|
||||||
then:
|
|
||||||
- action: light.turn_on
|
|
||||||
target:
|
|
||||||
entity_id: light.esp_officeduallights_light_1_right_hand_bunker_light
|
|
||||||
|
|
||||||
- alias: "Turn on Office cool white overhead lights if needed"
|
|
||||||
if:
|
|
||||||
- condition: state
|
|
||||||
entity_id: light.esp_officeduallights_light_2_cool_white_overhead_lights
|
|
||||||
state: "off"
|
|
||||||
then:
|
|
||||||
- action: light.turn_on
|
|
||||||
target:
|
|
||||||
entity_id: light.esp_officeduallights_light_2_cool_white_overhead_lights
|
|
||||||
|
|
||||||
- alias: "Turn on Office nighttime lights relay if needed"
|
|
||||||
if:
|
|
||||||
- condition: state
|
|
||||||
entity_id: switch.esp_officelights_relay_1_nighttime_lights
|
|
||||||
state: "off"
|
|
||||||
then:
|
|
||||||
- action: switch.turn_on
|
|
||||||
target:
|
|
||||||
entity_id: switch.esp_officelights_relay_1_nighttime_lights
|
|
||||||
|
|
||||||
- alias: "Turn on Office daytime lights relay if needed"
|
|
||||||
if:
|
|
||||||
- condition: state
|
|
||||||
entity_id: switch.esp_officelights_relay_2_daytime_lights
|
|
||||||
state: "off"
|
|
||||||
then:
|
|
||||||
- action: switch.turn_on
|
|
||||||
target:
|
|
||||||
entity_id: switch.esp_officelights_relay_2_daytime_lights
|
|
||||||
|
|
||||||
##############################################################
|
##############################################################
|
||||||
# Manual master/latch relay.
|
# Manual master/latch relay.
|
||||||
##############################################################
|
##############################################################
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
#:########################################################################################:#
|
#:########################################################################################:#
|
||||||
# Package: Pet Feeding and Jobs Timing
|
# Package: Pet Feeding and Jobs Timing
|
||||||
# File: pet_feeding_and_jobs.yaml
|
# File: pet_feeding_and_jobs.yaml
|
||||||
# Version: v1.1.0
|
# Version: v1.4.0
|
||||||
# Date: 2026-07-21
|
# Date: 2026-07-26
|
||||||
#
|
#
|
||||||
# Purpose:
|
# Purpose:
|
||||||
# Provides legacy MQTT pet activity sensors and Jobs-derived timing sensors for
|
# Provides legacy MQTT pet activity sensors and Jobs-derived timing sensors for
|
||||||
# the Lounge dog-feeding and depooping gauges.
|
# the Lounge dog-feeding and depooping gauges.
|
||||||
|
# v1.2.0: Added input_datetime helpers and automations so the View Road Events
|
||||||
|
# home-feed-card shows correct X minutes ago after HA restart.
|
||||||
#
|
#
|
||||||
# Behaviour:
|
# Behaviour:
|
||||||
# - Dog feeding reports the newest valid morning or evening completion time.
|
# - Dog feeding reports the newest valid morning or evening completion time.
|
||||||
@@ -15,6 +17,12 @@
|
|||||||
# instead of exposing a numeric sentinel value.
|
# instead of exposing a numeric sentinel value.
|
||||||
#
|
#
|
||||||
# Version History:
|
# Version History:
|
||||||
|
# - v1.4.0 (2026-07-26): Announce four physical job completions on the Sony
|
||||||
|
# lounge TV and both Pushover devices.
|
||||||
|
# - v1.3.0 (2026-07-26): Restore retained dog-fed and jobs-done activity
|
||||||
|
# feed publishing when physical completion events are received.
|
||||||
|
# - v1.2.0 (2026-07-24): Added persistent input_datetime timestamps for
|
||||||
|
# home-feed-card so time-ago survives HA restart.
|
||||||
# - v1.1.0 (2026-07-21): Reject invalid Jobs timing attributes and remove the
|
# - v1.1.0 (2026-07-21): Reject invalid Jobs timing attributes and remove the
|
||||||
# 999999-hour fallback from the dog-feeding gauge source.
|
# 999999-hour fallback from the dog-feeding gauge source.
|
||||||
# - v1.0.0 (2026-07-21): Added Jobs-derived dog timing sensors for P010.
|
# - v1.0.0 (2026-07-21): Added Jobs-derived dog timing sensors for P010.
|
||||||
@@ -90,3 +98,132 @@ template:
|
|||||||
state: >-
|
state: >-
|
||||||
{% set hours = state_attr('sensor.jobs_tracker_dog_depooping', 'hours_since_completed') %}
|
{% set hours = state_attr('sensor.jobs_tracker_dog_depooping', 'hours_since_completed') %}
|
||||||
{{ hours | float(0) if is_number(hours) else none }}
|
{{ hours | float(0) if is_number(hours) else none }}
|
||||||
|
|
||||||
|
#:######################################################################################:#
|
||||||
|
# PERSISTENT EVENT TIMESTAMPS (survive HA restart)
|
||||||
|
#:######################################################################################:#
|
||||||
|
# These input_datetime entities store the actual wall-clock time of the most recent
|
||||||
|
# event. The home-feed-card uses last_changed for "X minutes ago".
|
||||||
|
# Since input_datetime state is restored from the database after restart,
|
||||||
|
# last_changed reflects the actual event time, not the restart time.
|
||||||
|
|
||||||
|
# input_datetime entities created via HA API (not in YAML)
|
||||||
|
|
||||||
|
#:######################################################################################:#
|
||||||
|
# AUTOMATIONS: Update timestamps on event
|
||||||
|
#:######################################################################################:#
|
||||||
|
automation:
|
||||||
|
- id: timestamp_dog_fed
|
||||||
|
alias: "Timestamp - Dog Fed"
|
||||||
|
mode: single
|
||||||
|
triggers:
|
||||||
|
- trigger: state
|
||||||
|
entity_id: event.jobs_dog_fed_button_x14bt_action
|
||||||
|
conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: >-
|
||||||
|
{{ trigger.to_state.state not in ['unknown', 'unavailable'] }}
|
||||||
|
actions:
|
||||||
|
- action: input_datetime.set_datetime
|
||||||
|
target:
|
||||||
|
entity_id: input_datetime.dog_last_fed
|
||||||
|
data:
|
||||||
|
timestamp: "{{ as_timestamp(now()) }}"
|
||||||
|
- action: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "viewroad-status/activityfeed/dogfed"
|
||||||
|
payload: "{{ now().strftime('%H:%M') }}"
|
||||||
|
qos: 0
|
||||||
|
retain: true
|
||||||
|
|
||||||
|
- id: timestamp_dog_depooped
|
||||||
|
alias: "Timestamp - Dog Depooped"
|
||||||
|
mode: single
|
||||||
|
triggers:
|
||||||
|
- trigger: state
|
||||||
|
entity_id: event.jobs_dog_depooped_button_x15bt_action
|
||||||
|
conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: >-
|
||||||
|
{{ trigger.to_state.state not in ['unknown', 'unavailable'] }}
|
||||||
|
actions:
|
||||||
|
- action: input_datetime.set_datetime
|
||||||
|
target:
|
||||||
|
entity_id: input_datetime.dog_last_depooped
|
||||||
|
data:
|
||||||
|
timestamp: "{{ as_timestamp(now()) }}"
|
||||||
|
|
||||||
|
- id: timestamp_jobs_done
|
||||||
|
alias: "Timestamp - Any Job Completed"
|
||||||
|
description: >-
|
||||||
|
Updates the jobs-done timestamp whenever any tracked job completion
|
||||||
|
event fires. This keeps the "Jobs Done" entry in the home-feed-card
|
||||||
|
showing the time of the most recent job completion.
|
||||||
|
mode: single
|
||||||
|
triggers:
|
||||||
|
- trigger: state
|
||||||
|
entity_id:
|
||||||
|
- event.jobs_dog_fed_button_x14bt_action
|
||||||
|
- event.jobs_dog_depooped_button_x15bt_action
|
||||||
|
- event.kitchen_jobs_kitchen_completed_buttons_button_1
|
||||||
|
- event.kitchen_jobs_kitchen_completed_buttons_button_2
|
||||||
|
conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: >-
|
||||||
|
{{ trigger.to_state.state not in ['unknown', 'unavailable'] }}
|
||||||
|
actions:
|
||||||
|
- action: input_datetime.set_datetime
|
||||||
|
target:
|
||||||
|
entity_id: input_datetime.last_jobs_done
|
||||||
|
data:
|
||||||
|
timestamp: "{{ as_timestamp(now()) }}"
|
||||||
|
- action: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "viewroad-status/activityfeed/jobsdone"
|
||||||
|
payload: "{{ now().strftime('%-I:%M %p') }}"
|
||||||
|
qos: 0
|
||||||
|
retain: true
|
||||||
|
|
||||||
|
- id: jobs_completion_announcements
|
||||||
|
alias: "Jobs - Completion Announcements"
|
||||||
|
description: >-
|
||||||
|
Announces physical dog feeding, dog depooping, dishwasher and rubbish
|
||||||
|
completion events on the lounge Sony TV and both Pushover devices.
|
||||||
|
mode: queued
|
||||||
|
max: 10
|
||||||
|
triggers:
|
||||||
|
- trigger: state
|
||||||
|
entity_id:
|
||||||
|
- event.jobs_dog_fed_button_x14bt_action
|
||||||
|
- event.jobs_dog_depooped_button_x15bt_action
|
||||||
|
- event.kitchen_jobs_kitchen_completed_buttons_button_1
|
||||||
|
- event.kitchen_jobs_kitchen_completed_buttons_button_2
|
||||||
|
conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: >-
|
||||||
|
{% set valid_state = trigger.to_state is not none
|
||||||
|
and trigger.to_state.state not in ['unknown', 'unavailable'] %}
|
||||||
|
{% set event_ts = as_timestamp(trigger.to_state.state, 0)
|
||||||
|
if valid_state else 0 %}
|
||||||
|
{% set event_age = as_timestamp(now()) - event_ts %}
|
||||||
|
{{ valid_state and event_ts > 0 and event_age >= 0 and event_age <= 30 }}
|
||||||
|
actions:
|
||||||
|
- variables:
|
||||||
|
completion_message: >-
|
||||||
|
{% if trigger.entity_id == 'event.jobs_dog_fed_button_x14bt_action' %}
|
||||||
|
Zorro has been fed
|
||||||
|
{% elif trigger.entity_id == 'event.jobs_dog_depooped_button_x15bt_action' %}
|
||||||
|
Zorro has been depooped
|
||||||
|
{% elif trigger.entity_id == 'event.kitchen_jobs_kitchen_completed_buttons_button_1' %}
|
||||||
|
Dishwasher has been emptied
|
||||||
|
{% elif trigger.entity_id == 'event.kitchen_jobs_kitchen_completed_buttons_button_2' %}
|
||||||
|
Rubbish has been removed
|
||||||
|
{% else %}
|
||||||
|
Job has been completed
|
||||||
|
{% endif %}
|
||||||
|
- action: script.view_road_announcement
|
||||||
|
data:
|
||||||
|
channels: "sony_tv_lounge, pushover_zorruno, pushover_kim"
|
||||||
|
title: "Jobs Announcement"
|
||||||
|
short_announcement: "{{ completion_message }}"
|
||||||
|
long_announcement: "{{ completion_message }}"
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
#:########################################################################################:#
|
||||||
|
# PACKAGE: Zorro Evening Feeding Reminder (P017-S013)
|
||||||
|
# FILE: packages/p017_s013_zorro_feeding_reminder.yaml
|
||||||
|
# VERSION: v1.0.1 2026-07-26
|
||||||
|
#:########################################################################################:#
|
||||||
|
# PURPOSE:
|
||||||
|
# Remind to feed Zorro (evening feeding) if not completed.
|
||||||
|
# LED matrix shows "Feed Zorro" every 30 min from 5pm to 10pm.
|
||||||
|
# Voice says "Zorro has not been fed this afternoon" every 30 min from 5pm to 8pm.
|
||||||
|
# Each announcement has a random delay of 0-10 min for natural variation.
|
||||||
|
# Clears LED matrix immediately when evening feeding is completed.
|
||||||
|
#:########################################################################################:#
|
||||||
|
# DEPENDENCIES:
|
||||||
|
# - packages/view_road_announcement_router.yaml for LED/voice announcements
|
||||||
|
# - packages/Job_Chore_Tracking/jobs_tracker_jobs.yaml for evening feeding sensor
|
||||||
|
# - ESPHome LED matrix for cancel_id MQTT topic
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
|
input_boolean:
|
||||||
|
zorro_feeding_reminder_enabled:
|
||||||
|
name: Zorro Feeding Reminder
|
||||||
|
icon: mdi:dog
|
||||||
|
initial: true
|
||||||
|
|
||||||
|
automation:
|
||||||
|
##############################################################################
|
||||||
|
# EVENING FEEDING REMINDER
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
- id: zorro_evening_feeding_reminder
|
||||||
|
alias: "Zorro - Evening Feeding Reminder"
|
||||||
|
mode: single
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
- trigger: time_pattern
|
||||||
|
minutes: "/30"
|
||||||
|
- trigger: homeassistant
|
||||||
|
event: start
|
||||||
|
|
||||||
|
condition:
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_boolean.zorro_feeding_reminder_enabled
|
||||||
|
state: "on"
|
||||||
|
|
||||||
|
- condition: template
|
||||||
|
value_template: >
|
||||||
|
{{ now().hour >= 17 and now().hour < 22 }}
|
||||||
|
|
||||||
|
- condition: template
|
||||||
|
value_template: >
|
||||||
|
{{ states('sensor.jobs_tracker_dog_feeding_evening') != 'Complete' }}
|
||||||
|
|
||||||
|
action:
|
||||||
|
- variables:
|
||||||
|
voice_hours: "{{ now().hour < 20 }}"
|
||||||
|
quiet_time: "{{ is_state('input_boolean.quiet_time', 'on') }}"
|
||||||
|
|
||||||
|
- delay:
|
||||||
|
seconds: "{{ range(0, 601) | random | int }}"
|
||||||
|
|
||||||
|
- action: script.view_road_announcement
|
||||||
|
data:
|
||||||
|
channels: "led_matrix_1, sony_tv_lounge"
|
||||||
|
title: "Zorro"
|
||||||
|
short_announcement: "Feed Zorro"
|
||||||
|
indicator: "zorro,1,15,10,6,5,0,0"
|
||||||
|
|
||||||
|
- if:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ voice_hours and not quiet_time }}"
|
||||||
|
then:
|
||||||
|
- action: script.view_road_announcement
|
||||||
|
data:
|
||||||
|
channels: "lounge_google_home_voice"
|
||||||
|
title: "Zorro"
|
||||||
|
short_announcement: "Zorro has not been fed this afternoon"
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
# CLEAR LED MATRIX WHEN FED
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
- id: zorro_clear_led_when_fed
|
||||||
|
alias: "Zorro - Clear LED Matrix When Fed"
|
||||||
|
mode: single
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
- trigger: state
|
||||||
|
entity_id: sensor.jobs_tracker_dog_feeding_evening
|
||||||
|
to: "Complete"
|
||||||
|
|
||||||
|
action:
|
||||||
|
- action: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "viewroad-commands/ledmatrix1/cancel_id"
|
||||||
|
payload: "zorro"
|
||||||
|
qos: 0
|
||||||
|
retain: false
|
||||||
@@ -0,0 +1,188 @@
|
|||||||
|
#:########################################################################################:#
|
||||||
|
# PACKAGE: Potplant Moisture Alerts
|
||||||
|
# FILE: packages/potplant_moisture_alerts.yaml
|
||||||
|
# VERSION: v1.1.0 2026-07-29
|
||||||
|
# - Preserve user-selected thresholds and master enable state across restarts.
|
||||||
|
#:########################################################################################:#
|
||||||
|
# PURPOSE:
|
||||||
|
# Alert when potplant soil moisture drops below a configurable threshold.
|
||||||
|
# Displays on the Lounge LED matrix and announces via Lounge Google Home voice.
|
||||||
|
#:########################################################################################:#
|
||||||
|
# SETTINGS:
|
||||||
|
# - input_number.*_moisture_threshold: per-plant dry threshold (default 30%)
|
||||||
|
# - input_boolean.potplant_alert_enabled: master enable toggle
|
||||||
|
#:########################################################################################:#
|
||||||
|
# DEPENDENCIES:
|
||||||
|
# - packages/view_road_announcement_router.yaml for script.view_road_announcement
|
||||||
|
# - sensor.table_plant_soil_moisture
|
||||||
|
# - sensor.tv_plant_soil_moisture
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
|
input_number:
|
||||||
|
table_plant_moisture_threshold:
|
||||||
|
name: Table Plant Moisture Threshold
|
||||||
|
min: 0
|
||||||
|
max: 100
|
||||||
|
step: 5
|
||||||
|
unit_of_measurement: "%"
|
||||||
|
icon: mdi:water-percent
|
||||||
|
|
||||||
|
tv_plant_moisture_threshold:
|
||||||
|
name: TV Plant Moisture Threshold
|
||||||
|
min: 0
|
||||||
|
max: 100
|
||||||
|
step: 5
|
||||||
|
unit_of_measurement: "%"
|
||||||
|
icon: mdi:water-percent
|
||||||
|
|
||||||
|
input_boolean:
|
||||||
|
potplant_alert_enabled:
|
||||||
|
name: Potplant Moisture Alerts
|
||||||
|
icon: mdi:sprout
|
||||||
|
|
||||||
|
template:
|
||||||
|
- binary_sensor:
|
||||||
|
- name: "Table Plant Needs Water"
|
||||||
|
unique_id: table_plant_needs_water
|
||||||
|
icon: mdi:flower
|
||||||
|
state: >-
|
||||||
|
{{ (states('sensor.table_plant_soil_moisture') | float(100)) <
|
||||||
|
(states('input_number.table_plant_moisture_threshold') | float(30)) }}
|
||||||
|
|
||||||
|
- name: "TV Plant Needs Water"
|
||||||
|
unique_id: tv_plant_needs_water
|
||||||
|
icon: mdi:flower
|
||||||
|
state: >-
|
||||||
|
{{ (states('sensor.tv_plant_soil_moisture') | float(100)) <
|
||||||
|
(states('input_number.tv_plant_moisture_threshold') | float(30)) }}
|
||||||
|
|
||||||
|
automation:
|
||||||
|
##############################################################################
|
||||||
|
# TABLE PLANT
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
- id: potplant_table_plant_alert
|
||||||
|
alias: "Potplant - Table Plant Needs Water"
|
||||||
|
mode: single
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
- trigger: state
|
||||||
|
entity_id: binary_sensor.table_plant_needs_water
|
||||||
|
to: "on"
|
||||||
|
- trigger: time_pattern
|
||||||
|
hours: "/2"
|
||||||
|
- trigger: homeassistant
|
||||||
|
event: start
|
||||||
|
|
||||||
|
condition:
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_boolean.potplant_alert_enabled
|
||||||
|
state: "on"
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_boolean.quiet_time
|
||||||
|
state: "off"
|
||||||
|
- condition: state
|
||||||
|
entity_id: binary_sensor.table_plant_needs_water
|
||||||
|
state: "on"
|
||||||
|
|
||||||
|
action:
|
||||||
|
- action: script.view_road_announcement
|
||||||
|
data:
|
||||||
|
channels: "led_matrix_1"
|
||||||
|
title: "Plants"
|
||||||
|
short_announcement: "Water Table Plant"
|
||||||
|
indicator: "table,1,15,10,6,5,0,0"
|
||||||
|
|
||||||
|
- action: script.view_road_announcement
|
||||||
|
data:
|
||||||
|
channels: "lounge_google_home_voice"
|
||||||
|
title: "Plants"
|
||||||
|
short_announcement: "Table plant needs water"
|
||||||
|
|
||||||
|
- action: script.view_road_announcement
|
||||||
|
data:
|
||||||
|
channels: "sony_tv_lounge"
|
||||||
|
title: "Plants Announcement"
|
||||||
|
short_announcement: "Table plant needs water"
|
||||||
|
|
||||||
|
- id: potplant_table_clear_led
|
||||||
|
alias: "Potplant - Clear Table Plant LED"
|
||||||
|
mode: single
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
- trigger: state
|
||||||
|
entity_id: binary_sensor.table_plant_needs_water
|
||||||
|
to: "off"
|
||||||
|
|
||||||
|
action:
|
||||||
|
- action: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "viewroad-commands/ledmatrix1/cancel_id"
|
||||||
|
payload: "table"
|
||||||
|
qos: 0
|
||||||
|
retain: false
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
# TV PLANT
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
- id: potplant_tv_plant_alert
|
||||||
|
alias: "Potplant - TV Plant Needs Water"
|
||||||
|
mode: single
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
- trigger: state
|
||||||
|
entity_id: binary_sensor.tv_plant_needs_water
|
||||||
|
to: "on"
|
||||||
|
- trigger: time_pattern
|
||||||
|
hours: "/2"
|
||||||
|
- trigger: homeassistant
|
||||||
|
event: start
|
||||||
|
|
||||||
|
condition:
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_boolean.potplant_alert_enabled
|
||||||
|
state: "on"
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_boolean.quiet_time
|
||||||
|
state: "off"
|
||||||
|
- condition: state
|
||||||
|
entity_id: binary_sensor.tv_plant_needs_water
|
||||||
|
state: "on"
|
||||||
|
|
||||||
|
action:
|
||||||
|
- action: script.view_road_announcement
|
||||||
|
data:
|
||||||
|
channels: "led_matrix_1"
|
||||||
|
title: "Plants"
|
||||||
|
short_announcement: "Water TV Plant"
|
||||||
|
indicator: "tvplant,1,15,10,6,5,0,0"
|
||||||
|
|
||||||
|
- action: script.view_road_announcement
|
||||||
|
data:
|
||||||
|
channels: "lounge_google_home_voice"
|
||||||
|
title: "Plants"
|
||||||
|
short_announcement: "TV plant needs water"
|
||||||
|
|
||||||
|
- action: script.view_road_announcement
|
||||||
|
data:
|
||||||
|
channels: "sony_tv_lounge"
|
||||||
|
title: "Plants Announcement"
|
||||||
|
short_announcement: "TV plant needs water"
|
||||||
|
|
||||||
|
- id: potplant_tv_clear_led
|
||||||
|
alias: "Potplant - Clear TV Plant LED"
|
||||||
|
mode: single
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
- trigger: state
|
||||||
|
entity_id: binary_sensor.tv_plant_needs_water
|
||||||
|
to: "off"
|
||||||
|
|
||||||
|
action:
|
||||||
|
- action: mqtt.publish
|
||||||
|
data:
|
||||||
|
topic: "viewroad-commands/ledmatrix1/cancel_id"
|
||||||
|
payload: "tvplant"
|
||||||
|
qos: 0
|
||||||
|
retain: false
|
||||||
+10
-2
@@ -1,8 +1,8 @@
|
|||||||
#:########################################################################################:#
|
#:########################################################################################:#
|
||||||
# Package: Recorder Configuration
|
# Package: Recorder Configuration
|
||||||
# File: recorder.yaml
|
# File: recorder.yaml
|
||||||
# Version: v1.1.0
|
# Version: v1.2.0
|
||||||
# Date: 2026-07-23
|
# Date: 2026-07-24
|
||||||
#
|
#
|
||||||
# Purpose:
|
# Purpose:
|
||||||
# Enables Home Assistant Recorder with targeted exclusions for high-frequency
|
# Enables Home Assistant Recorder with targeted exclusions for high-frequency
|
||||||
@@ -12,6 +12,8 @@
|
|||||||
# - ESPHome uptime sensors.
|
# - ESPHome uptime sensors.
|
||||||
# - Home Assistant summary v2 sensors.
|
# - Home Assistant summary v2 sensors.
|
||||||
# - Jobs Tracker summary sensor.
|
# - Jobs Tracker summary sensor.
|
||||||
|
# - Fisher & Paykel oven temperature sensors reporting Fahrenheit as Celsius.
|
||||||
|
# - Creality K1C static hardware-limit max-temp sensors.
|
||||||
#
|
#
|
||||||
# Notes:
|
# Notes:
|
||||||
# - Excluded entities remain available for current-state use.
|
# - Excluded entities remain available for current-state use.
|
||||||
@@ -19,6 +21,7 @@
|
|||||||
# defaults unless configured elsewhere.
|
# defaults unless configured elsewhere.
|
||||||
#
|
#
|
||||||
# Version History:
|
# Version History:
|
||||||
|
# - v1.2.0 (2026-07-24): Added GE Home oven F→C bogus sensor exclusions for F043 and 3D printer static max-temp exclusions for F044.
|
||||||
# - v1.1.0 (2026-07-23): Added targeted exclusions during P013-F010 cleanup.
|
# - v1.1.0 (2026-07-23): Added targeted exclusions during P013-F010 cleanup.
|
||||||
# - v1.0.0 (2022-10-11): Initial Recorder package.
|
# - v1.0.0 (2022-10-11): Initial Recorder package.
|
||||||
#:########################################################################################:#
|
#:########################################################################################:#
|
||||||
@@ -30,3 +33,8 @@ recorder:
|
|||||||
- sensor.ha_summary_v2_*
|
- sensor.ha_summary_v2_*
|
||||||
entities:
|
entities:
|
||||||
- sensor.jobs_tracker_summary
|
- sensor.jobs_tracker_summary
|
||||||
|
- sensor.ulv316566_user_temp_offset
|
||||||
|
- sensor.ulv316566_raw_temperature
|
||||||
|
- sensor.ulv316566_probe_display_temp
|
||||||
|
- sensor.under_house_creality_k1c_eff9_max_nozzle_temperature
|
||||||
|
- sensor.under_house_creality_k1c_eff9_max_bed_temperature
|
||||||
|
|||||||
@@ -0,0 +1,369 @@
|
|||||||
|
#:########################################################################################:#
|
||||||
|
# Package: Security Notifications
|
||||||
|
# File: security_notifications.yaml
|
||||||
|
# Version: v1.0.0
|
||||||
|
# Date: 2026-07-25
|
||||||
|
#
|
||||||
|
# Purpose:
|
||||||
|
# Sends security alerts through the View Road announcement router when doors
|
||||||
|
# and access points open or close. Includes a startup gate to suppress false
|
||||||
|
# alerts after HA or Zigbee coordinator restarts, and a garage-door reminder
|
||||||
|
# loop for prolonged-open warnings.
|
||||||
|
#
|
||||||
|
# Channels used per sensor:
|
||||||
|
# Kitchen Top Cupboard → pushover_zorruno
|
||||||
|
# Key Cupboard → pushover_zorruno
|
||||||
|
# Loft Hatch → pushover_zorruno, sony_tv_lounge
|
||||||
|
# Underhouse Stealth Door → pushover_zorruno
|
||||||
|
# Garage Roller Door → pushover_zorruno, sony_tv_lounge
|
||||||
|
#
|
||||||
|
# Startup gate:
|
||||||
|
# Every automation checks:
|
||||||
|
# 1. HA core uptime > 120 s (blocks false alerts after HA restart)
|
||||||
|
# 2. Previous state != unavailable/unknown (blocks false alerts after
|
||||||
|
# Zigbee coordinator restart – devices briefly go unavailable then
|
||||||
|
# re-report their last state)
|
||||||
|
#
|
||||||
|
# Garage reminder:
|
||||||
|
# When opened: immediate alert + 1-hour timer started
|
||||||
|
# Timer fires: door still open → reminder + restart (max 24 times)
|
||||||
|
# Door closed: timer cancelled, reminder count reset
|
||||||
|
#
|
||||||
|
# Dependencies:
|
||||||
|
# - packages/view_road_announcement_router.yaml (script.view_road_announcement)
|
||||||
|
#
|
||||||
|
# Version History:
|
||||||
|
# - v1.0.0 (2026-07-25): Created from Node-RED Security Alerts tab.
|
||||||
|
#:########################################################################################:#
|
||||||
|
|
||||||
|
###########################################################################################
|
||||||
|
# HELPERS
|
||||||
|
###########################################################################################
|
||||||
|
|
||||||
|
input_number:
|
||||||
|
garage_door_reminder_count:
|
||||||
|
name: Garage Door Reminder Count
|
||||||
|
icon: mdi:counter
|
||||||
|
min: 0
|
||||||
|
max: 24
|
||||||
|
step: 1
|
||||||
|
mode: box
|
||||||
|
|
||||||
|
timer:
|
||||||
|
garage_door_open_reminder:
|
||||||
|
name: Garage Door Open Reminder
|
||||||
|
duration: "01:00:00"
|
||||||
|
icon: mdi:timer-outline
|
||||||
|
|
||||||
|
###########################################################################################
|
||||||
|
# STARTUP GATE – common condition template
|
||||||
|
###########################################################################################
|
||||||
|
#
|
||||||
|
# Every automation below includes these two conditions:
|
||||||
|
#
|
||||||
|
# 1. HA has been running > 120 s
|
||||||
|
# "{{ states('sensor.home_assistant_core_uptime') | int(0) > 120 }}"
|
||||||
|
#
|
||||||
|
# 2. Entity was not unavailable/unknown before this transition
|
||||||
|
# "{{ trigger.from_state is not none and trigger.from_state.state not in ['unavailable', 'unknown'] }}"
|
||||||
|
#
|
||||||
|
# These are inlined so the package is self-contained and each automation
|
||||||
|
# remains easy to read, disable, or override individually.
|
||||||
|
#
|
||||||
|
###########################################################################################
|
||||||
|
|
||||||
|
###########################################################################################
|
||||||
|
# KITCHEN TOP CUPBOARD
|
||||||
|
###########################################################################################
|
||||||
|
|
||||||
|
automation:
|
||||||
|
- id: security_kitchen_cupboard_opened
|
||||||
|
alias: "Security – Kitchen Top Cupboard Opened"
|
||||||
|
description: "Notify via Pushover when the kitchen top cupboard is opened."
|
||||||
|
mode: single
|
||||||
|
triggers:
|
||||||
|
- trigger: state
|
||||||
|
entity_id: binary_sensor.kitchen_top_cupboard_x04rs_contact
|
||||||
|
from: "off"
|
||||||
|
to: "on"
|
||||||
|
conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ states('sensor.home_assistant_core_uptime') | int(0) > 120 }}"
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ trigger.from_state is not none and trigger.from_state.state not in ['unavailable', 'unknown'] }}"
|
||||||
|
actions:
|
||||||
|
- action: script.view_road_announcement
|
||||||
|
data:
|
||||||
|
channels: "pushover_zorruno"
|
||||||
|
title: "Security Alert"
|
||||||
|
short_announcement: "Kitchen cupboard opened"
|
||||||
|
long_announcement: "The kitchen top cupboard has been opened."
|
||||||
|
|
||||||
|
- id: security_kitchen_cupboard_closed
|
||||||
|
alias: "Security – Kitchen Top Cupboard Closed"
|
||||||
|
description: "Notify via Pushover when the kitchen top cupboard is closed."
|
||||||
|
mode: single
|
||||||
|
triggers:
|
||||||
|
- trigger: state
|
||||||
|
entity_id: binary_sensor.kitchen_top_cupboard_x04rs_contact
|
||||||
|
from: "on"
|
||||||
|
to: "off"
|
||||||
|
conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ states('sensor.home_assistant_core_uptime') | int(0) > 120 }}"
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ trigger.from_state is not none and trigger.from_state.state not in ['unavailable', 'unknown'] }}"
|
||||||
|
actions:
|
||||||
|
- action: script.view_road_announcement
|
||||||
|
data:
|
||||||
|
channels: "pushover_zorruno"
|
||||||
|
title: "Security Alert"
|
||||||
|
short_announcement: "Kitchen cupboard closed"
|
||||||
|
long_announcement: "The kitchen top cupboard is now closed."
|
||||||
|
|
||||||
|
###########################################################################################
|
||||||
|
# KEY CUPBOARD
|
||||||
|
###########################################################################################
|
||||||
|
|
||||||
|
- id: security_key_cupboard_opened
|
||||||
|
alias: "Security – Key Cupboard Opened"
|
||||||
|
description: "Notify via Pushover when the key cupboard is opened."
|
||||||
|
mode: single
|
||||||
|
triggers:
|
||||||
|
- trigger: state
|
||||||
|
entity_id: binary_sensor.key_cupboard_zrs06
|
||||||
|
from: "off"
|
||||||
|
to: "on"
|
||||||
|
conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ states('sensor.home_assistant_core_uptime') | int(0) > 120 }}"
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ trigger.from_state is not none and trigger.from_state.state not in ['unavailable', 'unknown'] }}"
|
||||||
|
actions:
|
||||||
|
- action: script.view_road_announcement
|
||||||
|
data:
|
||||||
|
channels: "pushover_zorruno"
|
||||||
|
title: "Security Alert"
|
||||||
|
short_announcement: "Key cupboard opened"
|
||||||
|
long_announcement: "The key cupboard has been opened."
|
||||||
|
|
||||||
|
- id: security_key_cupboard_closed
|
||||||
|
alias: "Security – Key Cupboard Closed"
|
||||||
|
description: "Notify via Pushover when the key cupboard is closed."
|
||||||
|
mode: single
|
||||||
|
triggers:
|
||||||
|
- trigger: state
|
||||||
|
entity_id: binary_sensor.key_cupboard_zrs06
|
||||||
|
from: "on"
|
||||||
|
to: "off"
|
||||||
|
conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ states('sensor.home_assistant_core_uptime') | int(0) > 120 }}"
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ trigger.from_state is not none and trigger.from_state.state not in ['unavailable', 'unknown'] }}"
|
||||||
|
actions:
|
||||||
|
- action: script.view_road_announcement
|
||||||
|
data:
|
||||||
|
channels: "pushover_zorruno"
|
||||||
|
title: "Security Alert"
|
||||||
|
short_announcement: "Key cupboard closed"
|
||||||
|
long_announcement: "The key cupboard is now closed."
|
||||||
|
|
||||||
|
###########################################################################################
|
||||||
|
# LOFT HATCH
|
||||||
|
###########################################################################################
|
||||||
|
|
||||||
|
- id: security_loft_hatch_opened
|
||||||
|
alias: "Security – Loft Hatch Opened"
|
||||||
|
description: "Notify via Pushover and Sony TV when the loft hatch is opened."
|
||||||
|
mode: single
|
||||||
|
triggers:
|
||||||
|
- trigger: state
|
||||||
|
entity_id: binary_sensor.upstairs_loft_hatch_x02rs_contact
|
||||||
|
from: "off"
|
||||||
|
to: "on"
|
||||||
|
conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ states('sensor.home_assistant_core_uptime') | int(0) > 120 }}"
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ trigger.from_state is not none and trigger.from_state.state not in ['unavailable', 'unknown'] }}"
|
||||||
|
actions:
|
||||||
|
- action: script.view_road_announcement
|
||||||
|
data:
|
||||||
|
channels: "pushover_zorruno, sony_tv_lounge"
|
||||||
|
title: "Security Alert"
|
||||||
|
short_announcement: "Loft hatch opened"
|
||||||
|
long_announcement: "The upstairs loft hatch has been opened."
|
||||||
|
|
||||||
|
- id: security_loft_hatch_closed
|
||||||
|
alias: "Security – Loft Hatch Closed"
|
||||||
|
description: "Notify via Pushover and Sony TV when the loft hatch is closed."
|
||||||
|
mode: single
|
||||||
|
triggers:
|
||||||
|
- trigger: state
|
||||||
|
entity_id: binary_sensor.upstairs_loft_hatch_x02rs_contact
|
||||||
|
from: "on"
|
||||||
|
to: "off"
|
||||||
|
conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ states('sensor.home_assistant_core_uptime') | int(0) > 120 }}"
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ trigger.from_state is not none and trigger.from_state.state not in ['unavailable', 'unknown'] }}"
|
||||||
|
actions:
|
||||||
|
- action: script.view_road_announcement
|
||||||
|
data:
|
||||||
|
channels: "pushover_zorruno, sony_tv_lounge"
|
||||||
|
title: "Security Alert"
|
||||||
|
short_announcement: "Loft hatch closed"
|
||||||
|
long_announcement: "The upstairs loft hatch is now closed."
|
||||||
|
|
||||||
|
###########################################################################################
|
||||||
|
# UNDERHOUSE STEALTH DOOR
|
||||||
|
###########################################################################################
|
||||||
|
|
||||||
|
- id: security_underhouse_stealth_door_opened
|
||||||
|
alias: "Security – Underhouse Stealth Door Opened"
|
||||||
|
description: "Notify via Pushover when the underhouse stealth door is opened."
|
||||||
|
mode: single
|
||||||
|
triggers:
|
||||||
|
- trigger: state
|
||||||
|
entity_id: binary_sensor.underhouse_stealth_door_x07rs_contact
|
||||||
|
from: "off"
|
||||||
|
to: "on"
|
||||||
|
conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ states('sensor.home_assistant_core_uptime') | int(0) > 120 }}"
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ trigger.from_state is not none and trigger.from_state.state not in ['unavailable', 'unknown'] }}"
|
||||||
|
actions:
|
||||||
|
- action: script.view_road_announcement
|
||||||
|
data:
|
||||||
|
channels: "pushover_zorruno"
|
||||||
|
title: "Security Alert"
|
||||||
|
short_announcement: "Stealth door opened"
|
||||||
|
long_announcement: "The underhouse stealth door has been opened."
|
||||||
|
|
||||||
|
- id: security_underhouse_stealth_door_closed
|
||||||
|
alias: "Security – Underhouse Stealth Door Closed"
|
||||||
|
description: "Notify via Pushover when the underhouse stealth door is closed."
|
||||||
|
mode: single
|
||||||
|
triggers:
|
||||||
|
- trigger: state
|
||||||
|
entity_id: binary_sensor.underhouse_stealth_door_x07rs_contact
|
||||||
|
from: "on"
|
||||||
|
to: "off"
|
||||||
|
conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ states('sensor.home_assistant_core_uptime') | int(0) > 120 }}"
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ trigger.from_state is not none and trigger.from_state.state not in ['unavailable', 'unknown'] }}"
|
||||||
|
actions:
|
||||||
|
- action: script.view_road_announcement
|
||||||
|
data:
|
||||||
|
channels: "pushover_zorruno"
|
||||||
|
title: "Security Alert"
|
||||||
|
short_announcement: "Stealth door closed"
|
||||||
|
long_announcement: "The underhouse stealth door is now closed."
|
||||||
|
|
||||||
|
###########################################################################################
|
||||||
|
# GARAGE ROLLER DOOR
|
||||||
|
###########################################################################################
|
||||||
|
|
||||||
|
- id: security_garage_door_opened
|
||||||
|
alias: "Security – Garage Roller Door Opened"
|
||||||
|
description: >
|
||||||
|
Notify via Pushover and Sony TV when the garage roller door opens.
|
||||||
|
Also starts the 1-hour reminder timer so a follow-up alert is sent
|
||||||
|
if the door stays open.
|
||||||
|
mode: single
|
||||||
|
triggers:
|
||||||
|
- trigger: state
|
||||||
|
entity_id: binary_sensor.garage_roller_door_x18rs_contact
|
||||||
|
from: "off"
|
||||||
|
to: "on"
|
||||||
|
conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ states('sensor.home_assistant_core_uptime') | int(0) > 120 }}"
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ trigger.from_state is not none and trigger.from_state.state not in ['unavailable', 'unknown'] }}"
|
||||||
|
actions:
|
||||||
|
- action: script.view_road_announcement
|
||||||
|
data:
|
||||||
|
channels: "pushover_zorruno, sony_tv_lounge"
|
||||||
|
title: "Security Alert"
|
||||||
|
short_announcement: "Garage door opened"
|
||||||
|
long_announcement: "The garage roller door has been opened."
|
||||||
|
- action: input_number.set_value
|
||||||
|
data:
|
||||||
|
entity_id: input_number.garage_door_reminder_count
|
||||||
|
value: 0
|
||||||
|
- action: timer.start
|
||||||
|
data:
|
||||||
|
entity_id: timer.garage_door_open_reminder
|
||||||
|
duration: "01:00:00"
|
||||||
|
|
||||||
|
- id: security_garage_door_closed
|
||||||
|
alias: "Security – Garage Roller Door Closed"
|
||||||
|
description: >
|
||||||
|
Notify via Pushover and Sony TV when the garage roller door closes.
|
||||||
|
Cancels the reminder timer and resets the reminder counter.
|
||||||
|
mode: single
|
||||||
|
triggers:
|
||||||
|
- trigger: state
|
||||||
|
entity_id: binary_sensor.garage_roller_door_x18rs_contact
|
||||||
|
from: "on"
|
||||||
|
to: "off"
|
||||||
|
conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ states('sensor.home_assistant_core_uptime') | int(0) > 120 }}"
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ trigger.from_state is not none and trigger.from_state.state not in ['unavailable', 'unknown'] }}"
|
||||||
|
actions:
|
||||||
|
- action: timer.cancel
|
||||||
|
data:
|
||||||
|
entity_id: timer.garage_door_open_reminder
|
||||||
|
- action: input_number.set_value
|
||||||
|
data:
|
||||||
|
entity_id: input_number.garage_door_reminder_count
|
||||||
|
value: 0
|
||||||
|
- action: script.view_road_announcement
|
||||||
|
data:
|
||||||
|
channels: "pushover_zorruno, sony_tv_lounge"
|
||||||
|
title: "Security Alert"
|
||||||
|
short_announcement: "Garage door closed"
|
||||||
|
long_announcement: "The garage roller door is now closed."
|
||||||
|
|
||||||
|
- id: security_garage_door_reminder
|
||||||
|
alias: "Security – Garage Roller Door Reminder"
|
||||||
|
description: >
|
||||||
|
Fires when the reminder timer finishes. If the door is still open and
|
||||||
|
the reminder has fired fewer than 24 times, send another reminder and
|
||||||
|
restart the timer.
|
||||||
|
mode: single
|
||||||
|
triggers:
|
||||||
|
- trigger: event
|
||||||
|
event_type: timer.finished
|
||||||
|
event_data:
|
||||||
|
entity_id: timer.garage_door_open_reminder
|
||||||
|
conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ states('sensor.home_assistant_core_uptime') | int(0) > 120 }}"
|
||||||
|
- condition: state
|
||||||
|
entity_id: binary_sensor.garage_roller_door_x18rs_contact
|
||||||
|
state: "on"
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ states('input_number.garage_door_reminder_count') | int(0) < 24 }}"
|
||||||
|
actions:
|
||||||
|
- action: input_number.increment
|
||||||
|
data:
|
||||||
|
entity_id: input_number.garage_door_reminder_count
|
||||||
|
- action: script.view_road_announcement
|
||||||
|
data:
|
||||||
|
channels: "pushover_zorruno, sony_tv_lounge"
|
||||||
|
title: "Security Alert"
|
||||||
|
short_announcement: "Garage door still open"
|
||||||
|
long_announcement: "A reminder, the garage roller door is still open."
|
||||||
|
- action: timer.start
|
||||||
|
data:
|
||||||
|
entity_id: timer.garage_door_open_reminder
|
||||||
|
duration: "01:00:00"
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#:########################################################################################:#
|
#:########################################################################################:#
|
||||||
# Package: Away-Light Security Simulation
|
# Package: Away-Light Security Simulation
|
||||||
# File: simulation_lights.yaml
|
# File: simulation_lights.yaml
|
||||||
# Version: v1.0.0
|
# Version: v1.1.0
|
||||||
# Date: 2026-07-24
|
# Date: 2026-07-24
|
||||||
#
|
#
|
||||||
# Purpose:
|
# Purpose:
|
||||||
@@ -10,6 +10,9 @@
|
|||||||
# automation selects a configured entity and operates it for a random period.
|
# automation selects a configured entity and operates it for a random period.
|
||||||
#
|
#
|
||||||
# Version History:
|
# Version History:
|
||||||
|
# - v1.1.0 (2026-07-24): Replaced stale group.downstairs_flat_lights member with direct
|
||||||
|
# entity IDs so downstairs flat lights participate in away simulation.
|
||||||
|
#
|
||||||
# - v1.0.0 (2026-07-24): Consolidated the simulation groups, away automation, and timed helper
|
# - v1.0.0 (2026-07-24): Consolidated the simulation groups, away automation, and timed helper
|
||||||
# script into one feature package.
|
# script into one feature package.
|
||||||
# - Preserved the existing automation ID, group keys, and script key.
|
# - Preserved the existing automation ID, group keys, and script key.
|
||||||
@@ -33,7 +36,14 @@ group:
|
|||||||
simulation_lights_all:
|
simulation_lights_all:
|
||||||
name: "Simulation Lights (All)"
|
name: "Simulation Lights (All)"
|
||||||
entities:
|
entities:
|
||||||
- group.downstairs_flat_lights
|
- switch.esp_downstloungemain_relay_1_main_lights
|
||||||
|
- switch.esp_downstloungemain_relay_2_back_wall_lights
|
||||||
|
- switch.esp_downstmasterbedrmlights_relay_1_main_lights
|
||||||
|
- switch.esp_downstbedrm2lights_relay_1_main_lights
|
||||||
|
- switch.esp_downstkitchlights_relay_2_kitchen_light
|
||||||
|
- switch.esp_downstkitchlights_relay_1_dining_light
|
||||||
|
- switch.esp_downstbathswitch_relay_1_main_lights
|
||||||
|
- switch.esp_downstbathswitch_relay_2_cabinet_light
|
||||||
- switch.esp_centralstairs_top_relay_2_stair_footer_lights
|
- switch.esp_centralstairs_top_relay_2_stair_footer_lights
|
||||||
- switch.esp_centralstairs_bottom_relay_1_main_stair_lights_lower
|
- switch.esp_centralstairs_bottom_relay_1_main_stair_lights_lower
|
||||||
- switch.esp_entrancebathrmlights_relay_1_main_lights
|
- switch.esp_entrancebathrmlights_relay_1_main_lights
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
#:########################################################################################:#
|
#:########################################################################################:#
|
||||||
# Package: Vehicle Announcements
|
# Package: Vehicle Announcements
|
||||||
# File: vehicle_announcements.yaml
|
# File: vehicle_announcements.yaml
|
||||||
# Version: v1.0.0
|
# Version: v1.1.0
|
||||||
# Date: 2026-07-23
|
# Date: 2026-07-26
|
||||||
#
|
#
|
||||||
# Purpose:
|
# Purpose:
|
||||||
# Sends vehicle arrival announcements through the View Road announcement router.
|
# Sends vehicle arrival announcements through the View Road announcement router.
|
||||||
|
# Requires the vehicle to have been continuously away for 20 minutes before
|
||||||
|
# announcing, suppressing short Bluetooth range dropouts while parked at home.
|
||||||
#:########################################################################################:#
|
#:########################################################################################:#
|
||||||
|
|
||||||
automation:
|
automation:
|
||||||
@@ -13,13 +15,23 @@ automation:
|
|||||||
alias: "BYD Atto 3 - Arrival Announcement"
|
alias: "BYD Atto 3 - Arrival Announcement"
|
||||||
description: >
|
description: >
|
||||||
Sends a Pushover notification to the Zorruno phone when the BYD Atto 3
|
Sends a Pushover notification to the Zorruno phone when the BYD Atto 3
|
||||||
Bermuda tracker arrives home.
|
Bermuda tracker arrives home after at least 20 minutes away.
|
||||||
mode: single
|
mode: single
|
||||||
|
variables:
|
||||||
|
minimum_away_minutes: 20
|
||||||
triggers:
|
triggers:
|
||||||
- trigger: state
|
- trigger: state
|
||||||
entity_id: device_tracker.byd_atto3_ibeacon_bur4c2a_bermuda_tracker
|
entity_id: device_tracker.byd_atto3_ibeacon_bur4c2a_bermuda_tracker
|
||||||
from: "not_home"
|
from: "not_home"
|
||||||
to: "home"
|
to: "home"
|
||||||
|
conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: >-
|
||||||
|
{% set away_started = as_timestamp(trigger.from_state.last_changed, 0) %}
|
||||||
|
{% set arrived = as_timestamp(trigger.to_state.last_changed, 0) %}
|
||||||
|
{{ away_started > 0
|
||||||
|
and arrived > away_started
|
||||||
|
and (arrived - away_started) >= (minimum_away_minutes * 60) }}
|
||||||
actions:
|
actions:
|
||||||
- action: script.view_road_announcement
|
- action: script.view_road_announcement
|
||||||
data:
|
data:
|
||||||
|
|||||||
@@ -1,6 +1,16 @@
|
|||||||
################################################################################
|
################################################################################
|
||||||
# PACKAGE: View Road Announcement Router
|
# PACKAGE: View Road Announcement Router
|
||||||
################################################################################
|
################################################################################
|
||||||
|
# 1.10: Date: 2026-07-24
|
||||||
|
# - Added 2s delay before TTS speak to separate the cast chime from
|
||||||
|
# the voice announcement.
|
||||||
|
#
|
||||||
|
# 1.9: Date: 2026-07-24
|
||||||
|
# - Added continue_on_error to all 7 channel blocks so a single channel
|
||||||
|
# failure does not block remaining channels.
|
||||||
|
# - Google Home voice channel now saves and restores the previous volume
|
||||||
|
# level after TTS completes.
|
||||||
|
#
|
||||||
# 1.8: Date: 2026-07-11
|
# 1.8: Date: 2026-07-11
|
||||||
# - Added MQTT View Rd Feed announcement channel.
|
# - Added MQTT View Rd Feed announcement channel.
|
||||||
# - Added mqtt_feed script field.
|
# - Added mqtt_feed script field.
|
||||||
@@ -483,7 +493,8 @@ script:
|
|||||||
# CHANNEL: PUSHOVER ZORRUNO
|
# CHANNEL: PUSHOVER ZORRUNO
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
- if:
|
- continue_on_error: true
|
||||||
|
if:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ ',pushover_zorruno,' in ann_channels_normalised }}"
|
value_template: "{{ ',pushover_zorruno,' in ann_channels_normalised }}"
|
||||||
- condition: state
|
- condition: state
|
||||||
@@ -499,7 +510,8 @@ script:
|
|||||||
# CHANNEL: PUSHOVER KIM
|
# CHANNEL: PUSHOVER KIM
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
- if:
|
- continue_on_error: true
|
||||||
|
if:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ ',pushover_kim,' in ann_channels_normalised }}"
|
value_template: "{{ ',pushover_kim,' in ann_channels_normalised }}"
|
||||||
- condition: state
|
- condition: state
|
||||||
@@ -515,7 +527,8 @@ script:
|
|||||||
# CHANNEL: SONY TV LOUNGE
|
# CHANNEL: SONY TV LOUNGE
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
- if:
|
- continue_on_error: true
|
||||||
|
if:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ ',sony_tv_lounge,' in ann_channels_normalised }}"
|
value_template: "{{ ',sony_tv_lounge,' in ann_channels_normalised }}"
|
||||||
- condition: state
|
- condition: state
|
||||||
@@ -539,7 +552,8 @@ script:
|
|||||||
#
|
#
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
- if:
|
- continue_on_error: true
|
||||||
|
if:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: >-
|
value_template: >-
|
||||||
{{
|
{{
|
||||||
@@ -561,6 +575,9 @@ script:
|
|||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ ann_voice_message | string | trim | length > 0 }}"
|
value_template: "{{ ann_voice_message | string | trim | length > 0 }}"
|
||||||
then:
|
then:
|
||||||
|
- variables:
|
||||||
|
previous_volume: >-
|
||||||
|
{{ state_attr(lounge_google_home_voice_media_player, 'volume_level') | float(-1) }}
|
||||||
- choose:
|
- choose:
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: template
|
- condition: template
|
||||||
@@ -594,6 +611,9 @@ script:
|
|||||||
- delay:
|
- delay:
|
||||||
seconds: 1
|
seconds: 1
|
||||||
|
|
||||||
|
- delay:
|
||||||
|
seconds: 2
|
||||||
|
|
||||||
- action: tts.speak
|
- action: tts.speak
|
||||||
target:
|
target:
|
||||||
entity_id: "{{ lounge_google_home_voice_tts_entity }}"
|
entity_id: "{{ lounge_google_home_voice_tts_entity }}"
|
||||||
@@ -606,6 +626,15 @@ script:
|
|||||||
preferred_format: mp3
|
preferred_format: mp3
|
||||||
preferred_sample_rate: 44100
|
preferred_sample_rate: 44100
|
||||||
|
|
||||||
|
- if:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ previous_volume >= 0 }}"
|
||||||
|
then:
|
||||||
|
- action: media_player.volume_set
|
||||||
|
data:
|
||||||
|
entity_id: "{{ lounge_google_home_voice_media_player }}"
|
||||||
|
volume_level: "{{ previous_volume }}"
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
# CHANNEL: LOUNGE TOUCHSCREEN VOICE
|
# CHANNEL: LOUNGE TOUCHSCREEN VOICE
|
||||||
##########################################################################
|
##########################################################################
|
||||||
@@ -640,7 +669,8 @@ script:
|
|||||||
#
|
#
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
- if:
|
- continue_on_error: true
|
||||||
|
if:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ ',mqtt_view_rd_feed,' in ann_channels_normalised }}"
|
value_template: "{{ ',mqtt_view_rd_feed,' in ann_channels_normalised }}"
|
||||||
- condition: state
|
- condition: state
|
||||||
@@ -679,7 +709,8 @@ script:
|
|||||||
#
|
#
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
- if:
|
- continue_on_error: true
|
||||||
|
if:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ ',led_matrix_1,' in ann_channels_normalised }}"
|
value_template: "{{ ',led_matrix_1,' in ann_channels_normalised }}"
|
||||||
- condition: state
|
- condition: state
|
||||||
@@ -716,7 +747,8 @@ script:
|
|||||||
#
|
#
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
- if:
|
- continue_on_error: true
|
||||||
|
if:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ ',led_matrix_2,' in ann_channels_normalised }}"
|
value_template: "{{ ',led_matrix_2,' in ann_channels_normalised }}"
|
||||||
- condition: state
|
- condition: state
|
||||||
|
|||||||
Reference in New Issue
Block a user