Compare commits
12 Commits
d8bcf05bf6
...
4e2107f7f7
| Author | SHA1 | Date | |
|---|---|---|---|
| 4e2107f7f7 | |||
| 66bee0ccf7 | |||
| 5b675e1d62 | |||
| a76dbb6b16 | |||
| e20e36cdb5 | |||
| a2fb86aa93 | |||
| c6e8d7721c | |||
| 3ff67b883b | |||
| 2e645793f0 | |||
| 4ff90ea60a | |||
| dcd43a18c1 | |||
| 2b6b91f829 |
+1
-1
@@ -1 +1 @@
|
||||
{"pid": 71, "version": 1, "ha_version": "2026.7.2", "start_ts": 1784512870.0398877}
|
||||
{"pid": 71, "version": 1, "ha_version": "2026.7.2", "start_ts": 1784593872.104367}
|
||||
@@ -39,6 +39,19 @@ You MUST follow these rules strictly:
|
||||
- Make the change anyway
|
||||
- Try to convince them otherwise
|
||||
|
||||
## Project Context Protocol
|
||||
|
||||
- Treat every user request as related to a tracked project.
|
||||
- Identify the project by ID or name before beginning work.
|
||||
- If the project is unclear, ask the user which project applies.
|
||||
- Read `PROJECTS.md` and the relevant project section before investigating or making recommendations.
|
||||
- Keep project IDs stable.
|
||||
- Record durable decisions, changes, verification results, blockers, and next steps under the relevant project.
|
||||
- Follow the existing approval rules before writing context updates.
|
||||
- Never mark a project `Complete` unless the user explicitly confirms completion.
|
||||
- When a project appears complete, ask: "Should I close Pxxx?"
|
||||
- Do not store secrets, credentials, or large transient logs in project context.
|
||||
|
||||
## Environment Context
|
||||
|
||||
- You are running inside the OpenCode app
|
||||
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
# Project Tracker
|
||||
|
||||
Use this file as the source of truth for projects being worked on with OpenCode.
|
||||
|
||||
- Associate each user request with a project ID before beginning work.
|
||||
- Ask the user which project applies when the request is ambiguous.
|
||||
- Keep project IDs stable and use the relevant section to store durable context.
|
||||
- Update context as work progresses, subject to the approval rules in `AGENTS.md`.
|
||||
- Never mark a project complete unless the user explicitly confirms it is complete.
|
||||
- Ask the user before closing a project that appears complete.
|
||||
- Use these statuses: `Active`, `Paused`, and `Complete`.
|
||||
|
||||
| ID | Project | Status | Next Step | Last Updated |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| P001 | Bedside panel alarm audio | Active | Deploy and verify alarm audio and volume behavior. | 2026-07-20 |
|
||||
| P002 | reTerminal E1001 dashboard | Active | Test display refresh, wake buttons, MQTT control, and deep sleep. | 2026-07-20 |
|
||||
| P003 | ESPHome MQTT topic normalization | Active | Deploy paired devices and verify retained synchronization and external clients. | 2026-07-20 |
|
||||
| P004 | Appliance completion announcements | Active | Test an appliance cycle and resolve feed/timestamp inconsistencies. | 2026-07-20 |
|
||||
| P005 | Jobs and Chore Tracker V2.3 | Active | Test completion boundaries and resolve stale or duplicated entities. | 2026-07-20 |
|
||||
| P006 | Bedside rain forecast | Active | Verify forecast boundaries and API-failure handling. | 2026-07-20 |
|
||||
| P007 | Bedtime stair shutdown | Active | Verify both stair relays during a bedtime run. | 2026-07-20 |
|
||||
| P008 | Spook unused entity cleanup | Complete | None. | 2026-07-21 |
|
||||
| P009 | Lounge front-door camera layout | Complete | None. | 2026-07-21 |
|
||||
| P010 | Main-page Jobs timing gauges | Complete | None. | 2026-07-21 |
|
||||
| P011 | Downstairs occupancy helper cleanup | Complete | None. | 2026-07-21 |
|
||||
| P012 | EdgeRouter X SNMP monitoring | Active | Investigate the current EdgeOS failure and v3.0.x-compatible SNMP approach. | 2026-07-21 |
|
||||
|
||||
## P001: Bedside Panel Alarm Audio
|
||||
|
||||
- Objective: Provide reliable local alarm audio and user-adjustable volume on the bedside panel.
|
||||
- Current context: ES8311 and I2S output, amplifier control, persistent volume, and Beep/Alarm/Stop controls were added and repeatedly tuned. Compilation, deployment, and hardware behavior have not been confirmed.
|
||||
- Key files: `esphome/esp-bedside-panel.yaml`.
|
||||
- Known issue: The file changelog records V1.47 while `project_version` still reports v1.46.
|
||||
- Next step: Compile and deploy, then test startup noise, Beep/Alarm/Stop, volume endpoints, persistence, and amplifier shutdown.
|
||||
- Activity: 2026-07-20 - Implemented and tuned the alarm-audio feature through V1.47.
|
||||
|
||||
## P002: reTerminal E1001 Dashboard
|
||||
|
||||
- Objective: Build a low-power e-paper dashboard for job and appliance status.
|
||||
- Current context: Added ESP32-S3 hardware support, Jobs and Appliances pages, Home Assistant entity imports, icons, buttons, MQTT controls, change-only refresh, retained page hashes, wake-source handling, and deep sleep. Runtime behavior has not been confirmed.
|
||||
- Key files: `esphome/esp-reterminal-e1001.yaml`.
|
||||
- Next step: Compile and deploy, then test entity data, rendering, page buttons, timer and button wake, MQTT keep-awake control, fallback sleep, and battery usage.
|
||||
- Activity: 2026-07-20 - Created the device configuration and developed it through v0.6.1.
|
||||
|
||||
## P003: ESPHome MQTT Topic Normalization
|
||||
|
||||
- Objective: Simplify MQTT command and status topics across related ESPHome devices while preserving synchronization.
|
||||
- Current context: Flattened component-specific MQTT topics to logical device roots across eleven devices. Updated paired lounge and master-bedroom consumers and restored direct pantry-light control. Deployment and external-client compatibility have not been confirmed.
|
||||
- Key files: Related device configurations under `esphome/`, including lounge, kitchen, office, bedroom, breakfast-bar, and master-bedroom devices.
|
||||
- Next step: Compile and deploy paired devices together, verify root commands and retained state, audit external MQTT consumers, and remove stale retained messages from superseded topics when safe.
|
||||
- Activity: 2026-07-20 - Applied the MQTT topic normalization across the related devices.
|
||||
|
||||
## P004: Appliance Completion Announcements
|
||||
|
||||
- Objective: Route appliance completion events to configured announcement channels and MQTT activity feeds.
|
||||
- Current context: Added per-appliance announcement settings, payloads, channels, LED-matrix indicators, MQTT feed suffixes, suppression logging, retained attributes, and expanded washer, dryer, dishwasher, and EV-charger handling.
|
||||
- Key files: `packages/Appliance_Monitoring/appliance_monitor_processor.yaml`, `packages/Appliance_Monitoring/appliances_status_monitoring.yaml`, `packages/view_road_announcement_router.yaml`, and `packages/appliance_status_mqttfeed.yaml`.
|
||||
- Known issues: MQTT feed channels may not yet be enabled for each appliance, and timestamp sensors may receive time-only payloads.
|
||||
- Next step: Resolve the feed and timestamp inconsistencies, then test a complete appliance cycle end to end.
|
||||
- Activity: 2026-07-20 - Expanded appliance monitoring and completion-feed routing.
|
||||
|
||||
## P005: Jobs and Chore Tracker V2.3
|
||||
|
||||
- Objective: Maintain household jobs through a registry-driven tracker with discovery entities and completion windows.
|
||||
- Current context: Centralized five jobs, added generic completion routing, morning and evening dog-feeding windows, MQTT Discovery entities, summary and count entities, manual buttons, missed-job handling, and completion-window expiry.
|
||||
- Key files: `packages/Job_Chore_Tracking/jobs_tracker_jobs.yaml` and `packages/Job_Chore_Tracking/jobs_tracker_processor.yaml`.
|
||||
- Known issue: Some count entities may be stale or have duplicated `jobs_tracker` naming.
|
||||
- Next step: Test completion-window boundaries and clean up stale or double-prefixed entities after confirming which entities are current.
|
||||
- Activity: 2026-07-20 - Implemented the V2.3 registry and processor changes.
|
||||
|
||||
## P006: Bedside Rain Forecast
|
||||
|
||||
- Objective: Supply the bedside panel with useful rain-chance forecasts for today and tomorrow.
|
||||
- Current context: Added Open-Meteo REST sensors for today's remaining forecast period and tomorrow's daylight period using the Home zone coordinates.
|
||||
- Key files: `packages/open_meteo_rain_chance.yaml` and `esphome/esp-bedside-panel.yaml`.
|
||||
- Next step: Verify sunrise and sunset boundary behavior, stale-data handling, and API-failure recovery.
|
||||
- Activity: 2026-07-20 - Added the Open-Meteo rain forecast package and bedside-panel inputs.
|
||||
|
||||
## P007: Bedtime Stair Shutdown
|
||||
|
||||
- Objective: Ensure the central stair lighting turns off as part of bedtime mode.
|
||||
- Current context: Added the lower main stair lights and stair footer lights to the bedtime shutdown sequence with no delay.
|
||||
- Key files: `packages/bedtime_mode_actions.yaml`.
|
||||
- Next step: Run bedtime mode and verify both relays switch off as intended.
|
||||
- Activity: 2026-07-20 - Added both central stair relays to bedtime shutdown.
|
||||
|
||||
## P008: Spook Unused Entity Cleanup
|
||||
|
||||
- Objective: Resolve Spook warnings caused by stale entity references.
|
||||
- Current context: The Master Bedroom Echo Show Environment view now uses the live Bedroom 1 Environment (Z19TH) temperature and humidity entities, and the related Spook repair has cleared.
|
||||
- Replacement entities: `sensor.bedroom_1_environment_z19th_temperature` and `sensor.bedroom_1_environment_z19th_humidity`.
|
||||
- Verification: The stored card definitions reference the replacement entities, and Spook no longer reports the Master Bedroom Echo Show issue. Automated visual verification was unavailable because the screenshot tool is disabled.
|
||||
- Next step: None.
|
||||
- Activity: 2026-07-21 - Created the project and selected the live Bedroom 1 Environment (Z19TH) sensor pair.
|
||||
- Activity: 2026-07-21 - Replaced both stale dashboard references and confirmed that the Spook repair cleared.
|
||||
- Activity: 2026-07-21 - User confirmed completion.
|
||||
|
||||
## P009: Lounge Front-Door Camera Layout
|
||||
|
||||
- Objective: Display the Front Door Camera in landscape orientation on the Lounge dashboard.
|
||||
- Current context: The Lounge Home view now displays the live `camera.camera2` card at a 4:3 landscape aspect ratio.
|
||||
- Verification: The saved view retains all seven cards and the Front Door Camera live-view settings, and `camera.camera2` is streaming. Automated visual verification was unavailable because the screenshot tool is disabled.
|
||||
- Next step: None.
|
||||
- Activity: 2026-07-21 - Created the project and identified the Front Door Camera card on the Lounge Home view.
|
||||
- Activity: 2026-07-21 - Changed the Front Door Camera card from 3:4 to 4:3 and verified the saved dashboard configuration.
|
||||
- Activity: 2026-07-21 - User confirmed completion.
|
||||
|
||||
## P010: Main-Page Jobs Timing Gauges
|
||||
|
||||
- Objective: Make the Lounge Home dog-feeding and depooping gauges use timing from the Jobs routine.
|
||||
- Current context: The gauges now use Jobs-derived template sensors. Dog feeding uses the latest morning/evening completion, and depooping uses the weekly job completion.
|
||||
- Selected design: Keep two gauges. Dog feeding uses the latest morning/evening completion; depooping uses the weekly job completion.
|
||||
- Key file: `packages/pet_feeding_and_jobs.yaml`.
|
||||
- Verification: Home Assistant accepted the configuration, both template sensors loaded, the feeding gauge reports 17 hours, the depooping gauge reports 156 hours, and all other Home view cards were preserved. Automated visual verification was unavailable because the screenshot tool is disabled.
|
||||
- Next step: None.
|
||||
- Activity: 2026-07-21 - Created the project and selected the two-gauge Jobs-derived design.
|
||||
- Activity: 2026-07-21 - Added the Jobs-derived sensors, reloaded templates, and updated both Lounge Home gauges.
|
||||
- Activity: 2026-07-21 - User confirmed completion.
|
||||
|
||||
## P011: Downstairs Occupancy Helper Cleanup
|
||||
|
||||
- Objective: Eliminate the duplicate downstairs guest occupancy helper.
|
||||
- Canonical helper: `input_boolean.downstairs_flat_occupied`, which is YAML-managed and used by the downstairs lockout behavior.
|
||||
- Removed duplicate: `input_boolean.guest_area_occupied`, which was UI-managed and referenced only by the Test dashboard.
|
||||
- Current context: All nine stored Test dashboard references now use the canonical helper, the duplicate helper has been deleted, and the Lounge row of eight downstairs-flat light icons now greys out and blocks taps while occupied.
|
||||
- Verification: The duplicate returns entity not found, the canonical helper remains available with its automation and script relationships, no Test dashboard broken-reference repair was created, and the saved Lounge templates render both the enabled and occupied branches correctly. Automated visual verification was unavailable because the screenshot tool is disabled.
|
||||
- Next step: None.
|
||||
- Activity: 2026-07-21 - Created the project and completed the dependency audit.
|
||||
- Activity: 2026-07-21 - Migrated the Test dashboard references and deleted the duplicate helper.
|
||||
- Activity: 2026-07-21 - Added occupancy-driven greying and tap blocking to the Lounge downstairs-flat light row.
|
||||
- Activity: 2026-07-21 - User verified the Lounge lockout and confirmed completion.
|
||||
|
||||
## P012: EdgeRouter X SNMP Monitoring
|
||||
|
||||
- Objective: Restore EdgeRouter X monitoring on firmware v3.0.x using a compatible SNMP-based approach.
|
||||
- Current context: The existing EdgeRouter interface is not working after the router moved to firmware v3.0.x. Prior EdgeRouter/SNMP work was not recorded in project context.
|
||||
- Next step: Inspect the current configuration, entities, errors, and documentation without changing runtime behavior.
|
||||
- Activity: 2026-07-21 - Created the project and began the compatibility investigation.
|
||||
+1386
File diff suppressed because it is too large
Load Diff
+620
-434
File diff suppressed because it is too large
Load Diff
@@ -6,6 +6,7 @@
|
||||
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-bedrm1arlecbulb.yaml
|
||||
#:########################################################################################:#
|
||||
# VERSIONS:
|
||||
# v1.3 2026-07-20 Simplified local MQTT command and status topics to the device root
|
||||
# v1.2 2026-02-25 Updated yaml to zorruno layout V1.1
|
||||
# v1.1 2026-02-21 Add "Jump Fade Up/Down" switch + configurable Jump Fade (%)
|
||||
# v1.0 2026-02-21 Initial version (ported from Athom bulb YAML to Arlec GLD120HA)
|
||||
@@ -42,7 +43,6 @@
|
||||
# - Accurate time is NOT needed (SNTP not needed).
|
||||
#:########################################################################################:#
|
||||
|
||||
|
||||
#:########################################################################################:#
|
||||
# SUBSTITUTIONS: Specific device variable substitutions
|
||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||
@@ -56,7 +56,7 @@ substitutions:
|
||||
|
||||
# Project Naming
|
||||
project_name: "Grid Connect GLD120HA RGBWW.Arlec"
|
||||
project_version: "v1.2"
|
||||
project_version: "v1.3"
|
||||
|
||||
# Passwords & Secrets (Unfortunately, you can't use substitutions inside secret names)
|
||||
# Re-using your existing bulb flasher secrets (adjust if you prefer per-device secrets)
|
||||
@@ -156,32 +156,32 @@ esphome:
|
||||
# Mode 0: Fade up to full (obeys fade settings; forces Warm endpoint)
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(restart_mode) == 0;'
|
||||
lambda: "return id(restart_mode) == 0;"
|
||||
then:
|
||||
- lambda: 'id(ramp_switch_target_on) = true;'
|
||||
- lambda: "id(ramp_switch_target_on) = true;"
|
||||
- script.execute: ramp_on_script
|
||||
|
||||
# Mode 1: Restore Brightness (deferred; forces Warm endpoint)
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(restart_mode) == 1;'
|
||||
lambda: "return id(restart_mode) == 1;"
|
||||
then:
|
||||
- script.execute: deferred_restore_brightness
|
||||
|
||||
# Mode 2: Remain Off
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(restart_mode) == 2;'
|
||||
lambda: "return id(restart_mode) == 2;"
|
||||
then:
|
||||
- script.stop: ramp_on_script
|
||||
- script.stop: ramp_off_script
|
||||
- lambda: 'id(ramp_switch_target_on) = false;'
|
||||
- lambda: "id(ramp_switch_target_on) = false;"
|
||||
- light.turn_off:
|
||||
id: bulb_light
|
||||
transition_length: 0s
|
||||
|
||||
# Boot complete: allow OFF handlers again
|
||||
- lambda: 'id(booting) = false;'
|
||||
- lambda: "id(booting) = false;"
|
||||
|
||||
#:########################################################################################:#
|
||||
# ESP PLATFORM AND FRAMEWORK
|
||||
@@ -301,12 +301,12 @@ logger:
|
||||
#:########################################################################################:#
|
||||
mqtt:
|
||||
on_message:
|
||||
- topic: "${mqtt_local_command_topic}/light/set"
|
||||
- topic: "${mqtt_local_command_topic}"
|
||||
payload: "${mqtt_local_device_command_ON}"
|
||||
then:
|
||||
- switch.turn_on: bulb_ramp_switch
|
||||
|
||||
- topic: "${mqtt_local_command_topic}/light/set"
|
||||
- topic: "${mqtt_local_command_topic}"
|
||||
payload: "${mqtt_local_device_command_OFF}"
|
||||
then:
|
||||
- switch.turn_off: bulb_ramp_switch
|
||||
@@ -536,7 +536,7 @@ light:
|
||||
|
||||
on_turn_on:
|
||||
- mqtt.publish:
|
||||
topic: "${mqtt_local_status_topic}/light/state"
|
||||
topic: "${mqtt_local_status_topic}"
|
||||
payload: "${mqtt_local_device_command_ON}"
|
||||
retain: true
|
||||
- lambda: |-
|
||||
@@ -546,20 +546,20 @@ light:
|
||||
- script.stop: max_on_watchdog
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(max_on_hours) > 0;'
|
||||
lambda: "return id(max_on_hours) > 0;"
|
||||
then:
|
||||
- script.execute: max_on_watchdog
|
||||
|
||||
on_turn_off:
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return !id(booting);'
|
||||
lambda: "return !id(booting);"
|
||||
then:
|
||||
- mqtt.publish:
|
||||
topic: "${mqtt_local_status_topic}/light/state"
|
||||
topic: "${mqtt_local_status_topic}"
|
||||
payload: "${mqtt_local_device_command_OFF}"
|
||||
retain: true
|
||||
- lambda: 'id(ramp_switch_target_on) = false;'
|
||||
- lambda: "id(ramp_switch_target_on) = false;"
|
||||
- script.stop: max_on_watchdog
|
||||
- lambda: |-
|
||||
id(last_brightness_pct) = 0.0f;
|
||||
@@ -667,9 +667,9 @@ number:
|
||||
set_action:
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return x <= 0.0f;'
|
||||
lambda: "return x <= 0.0f;"
|
||||
then:
|
||||
- lambda: 'id(suppress_slider_sync) = true;'
|
||||
- lambda: "id(suppress_slider_sync) = true;"
|
||||
- script.stop: ramp_on_script
|
||||
- script.stop: ramp_off_script
|
||||
- light.turn_off:
|
||||
@@ -681,7 +681,7 @@ number:
|
||||
id(last_brightness_pct) = 0.0f;
|
||||
id(last_set_pos) = 0;
|
||||
- delay: 400ms
|
||||
- lambda: 'id(suppress_slider_sync) = false;'
|
||||
- lambda: "id(suppress_slider_sync) = false;"
|
||||
else:
|
||||
- lambda: |-
|
||||
id(suppress_slider_sync) = true;
|
||||
@@ -713,7 +713,7 @@ number:
|
||||
if (out_pct > maxp) out_pct = maxp;
|
||||
id(last_brightness_pct) = out_pct;
|
||||
- delay: 400ms
|
||||
- lambda: 'id(suppress_slider_sync) = false;'
|
||||
- lambda: "id(suppress_slider_sync) = false;"
|
||||
|
||||
- platform: template
|
||||
id: cfg_max_on_hours
|
||||
@@ -736,12 +736,12 @@ number:
|
||||
id(cfg_max_on_hours).publish_state((float) hrs);
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(bulb_light).current_values.is_on();'
|
||||
lambda: "return id(bulb_light).current_values.is_on();"
|
||||
then:
|
||||
- script.stop: max_on_watchdog
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(max_on_hours) > 0;'
|
||||
lambda: "return id(max_on_hours) > 0;"
|
||||
then:
|
||||
- script.execute: max_on_watchdog
|
||||
|
||||
@@ -753,7 +753,7 @@ script:
|
||||
- id: ramp_on_script
|
||||
mode: restart
|
||||
then:
|
||||
- lambda: 'id(is_ramping) = true;'
|
||||
- lambda: "id(is_ramping) = true;"
|
||||
- script.stop: ramp_off_script
|
||||
|
||||
- if:
|
||||
@@ -766,13 +766,13 @@ script:
|
||||
- light.turn_on:
|
||||
id: bulb_light
|
||||
color_temperature: "${bulb_warm_kelvin}"
|
||||
brightness: !lambda 'return id(min_brightness_pct) / 100.0f;'
|
||||
brightness: !lambda "return id(min_brightness_pct) / 100.0f;"
|
||||
transition_length: 80ms
|
||||
|
||||
- light.turn_on:
|
||||
id: bulb_light
|
||||
color_temperature: "${bulb_warm_kelvin}"
|
||||
brightness: !lambda 'return id(max_brightness_pct) / 100.0f;'
|
||||
brightness: !lambda "return id(max_brightness_pct) / 100.0f;"
|
||||
transition_length: !lambda |-
|
||||
const auto &cv = id(bulb_light).current_values;
|
||||
const float floor = id(min_brightness_pct) / 100.0f;
|
||||
@@ -795,7 +795,7 @@ script:
|
||||
id(last_ramp_ms) = (int) (id(ramp_up_ms) * frac);
|
||||
return (uint32_t) id(last_ramp_ms);
|
||||
|
||||
- delay: !lambda 'return (uint32_t) id(last_ramp_ms);'
|
||||
- delay: !lambda "return (uint32_t) id(last_ramp_ms);"
|
||||
- lambda: |-
|
||||
id(is_ramping) = false;
|
||||
const auto &cv = id(bulb_light).current_values;
|
||||
@@ -807,7 +807,7 @@ script:
|
||||
- id: ramp_to_target_script
|
||||
mode: restart
|
||||
then:
|
||||
- lambda: 'id(is_ramping) = true;'
|
||||
- lambda: "id(is_ramping) = true;"
|
||||
- script.stop: ramp_off_script
|
||||
|
||||
- if:
|
||||
@@ -820,7 +820,7 @@ script:
|
||||
- light.turn_on:
|
||||
id: bulb_light
|
||||
color_temperature: "${bulb_warm_kelvin}"
|
||||
brightness: !lambda 'return id(min_brightness_pct) / 100.0f;'
|
||||
brightness: !lambda "return id(min_brightness_pct) / 100.0f;"
|
||||
transition_length: 80ms
|
||||
|
||||
- light.turn_on:
|
||||
@@ -858,7 +858,7 @@ script:
|
||||
id(last_ramp_ms) = (int) (id(ramp_up_ms) * frac);
|
||||
return (uint32_t) id(last_ramp_ms);
|
||||
|
||||
- delay: !lambda 'return (uint32_t) id(last_ramp_ms);'
|
||||
- delay: !lambda "return (uint32_t) id(last_ramp_ms);"
|
||||
- lambda: |-
|
||||
id(is_ramping) = false;
|
||||
const auto &cv = id(bulb_light).current_values;
|
||||
@@ -878,7 +878,7 @@ script:
|
||||
- light.turn_on:
|
||||
id: bulb_light
|
||||
color_temperature: "${bulb_warm_kelvin}"
|
||||
brightness: !lambda 'return id(min_brightness_pct) / 100.0f;'
|
||||
brightness: !lambda "return id(min_brightness_pct) / 100.0f;"
|
||||
transition_length: !lambda |-
|
||||
const auto &cv = id(bulb_light).current_values;
|
||||
const float floor = id(min_brightness_pct) / 100.0f;
|
||||
@@ -895,7 +895,7 @@ script:
|
||||
id(last_ramp_ms) = (int) (id(ramp_down_ms) * frac);
|
||||
return (uint32_t) id(last_ramp_ms);
|
||||
|
||||
- delay: !lambda 'return (uint32_t) id(last_ramp_ms);'
|
||||
- delay: !lambda "return (uint32_t) id(last_ramp_ms);"
|
||||
- light.turn_off:
|
||||
id: bulb_light
|
||||
transition_length: 150ms
|
||||
@@ -913,12 +913,12 @@ script:
|
||||
then:
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(max_on_hours) > 0;'
|
||||
lambda: "return id(max_on_hours) > 0;"
|
||||
then:
|
||||
- delay: !lambda 'return (uint32_t) (id(max_on_hours) * 3600000UL);'
|
||||
- delay: !lambda "return (uint32_t) (id(max_on_hours) * 3600000UL);"
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(bulb_light).current_values.is_on();'
|
||||
lambda: "return id(bulb_light).current_values.is_on();"
|
||||
then:
|
||||
- lambda: |-
|
||||
id(ramp_switch_target_on) = false;
|
||||
@@ -942,17 +942,17 @@ script:
|
||||
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(restore_target_pct) > 0.5f;'
|
||||
lambda: "return id(restore_target_pct) > 0.5f;"
|
||||
then:
|
||||
- lambda: |-
|
||||
id(ramp_switch_target_on) = true;
|
||||
id(suppress_slider_sync) = true;
|
||||
- script.stop: ramp_off_script
|
||||
- script.execute: ramp_to_target_script
|
||||
- delay: !lambda 'return (uint32_t) id(last_ramp_ms);'
|
||||
- lambda: 'id(suppress_slider_sync) = false;'
|
||||
- delay: !lambda "return (uint32_t) id(last_ramp_ms);"
|
||||
- lambda: "id(suppress_slider_sync) = false;"
|
||||
else:
|
||||
- lambda: 'id(ramp_switch_target_on) = false;'
|
||||
- lambda: "id(ramp_switch_target_on) = false;"
|
||||
- light.turn_off:
|
||||
id: bulb_light
|
||||
transition_length: 0s
|
||||
@@ -1013,7 +1013,7 @@ script:
|
||||
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(bulb_light).current_values.is_on();'
|
||||
lambda: "return id(bulb_light).current_values.is_on();"
|
||||
then:
|
||||
- light.turn_on:
|
||||
id: bulb_light
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-breakfastbarleds.yaml
|
||||
#:########################################################################################:#
|
||||
# VERSIONS:
|
||||
# V2.1 2026-07-20 Simplified local MQTT command and status topics to the device root
|
||||
# V2.0 2025-09-15 A bunch of fixes and made it more standard across my devices
|
||||
# V1.0 2025-08-17 First setup (and replacement of Tasmota)
|
||||
#:########################################################################################:#
|
||||
@@ -47,10 +48,10 @@
|
||||
#:########################################################################################:#
|
||||
# MQTT COMMANDS:
|
||||
# Local MQTT light control:
|
||||
# - ${mqtt_local_command_topic}/light/set -> ON,OFF
|
||||
# - ${mqtt_local_command_topic} -> ON,OFF
|
||||
#
|
||||
# Local MQTT light status:
|
||||
# - ${mqtt_local_status_topic}/light/state -> ON,OFF
|
||||
# - ${mqtt_local_status_topic} -> ON,OFF
|
||||
#:########################################################################################:#
|
||||
# OFFLINE NOTES:
|
||||
# a) Home Assistant OFFLINE, but Network and MQTT ONLINE
|
||||
@@ -80,7 +81,7 @@ substitutions:
|
||||
|
||||
# Project Naming
|
||||
project_name: "Magichome Single Colour V1.1 LED Controller.Generic ESP8266" # Manufacturer before the dot, device after the dot.
|
||||
project_version: "v2.0" # Project version denotes release of the YAML file, allowing checking of deployed vs latest version
|
||||
project_version: "v2.1" # Project version denotes release of the YAML file, allowing checking of deployed vs latest version
|
||||
|
||||
# Passwords & Secrets (Unfortunately, you can't use substitutions inside secret names)
|
||||
api_key: !secret esp-api_key
|
||||
@@ -130,8 +131,7 @@ packages:
|
||||
local_current_ip_address: "${current_ip_address}"
|
||||
|
||||
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
||||
common_api: !include
|
||||
#file: common/api_common.yaml
|
||||
common_api: !include #file: common/api_common.yaml
|
||||
file: common/api_common_noencryption.yaml
|
||||
vars:
|
||||
local_api_key: "${api_key}"
|
||||
@@ -178,32 +178,32 @@ esphome:
|
||||
# Mode 0: Fade up to full (obeys fade settings; no on/off flicker)
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(restart_mode) == 0;'
|
||||
lambda: "return id(restart_mode) == 0;"
|
||||
then:
|
||||
- lambda: 'id(ramp_switch_target_on) = true;'
|
||||
- lambda: "id(ramp_switch_target_on) = true;"
|
||||
- script.execute: ramp_on_script
|
||||
|
||||
# Mode 1: Restore Brightness (deferred to avoid races)
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(restart_mode) == 1;'
|
||||
lambda: "return id(restart_mode) == 1;"
|
||||
then:
|
||||
- script.execute: deferred_restore_brightness
|
||||
|
||||
# Mode 2: Remain Off (no blip; stays off)
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(restart_mode) == 2;'
|
||||
lambda: "return id(restart_mode) == 2;"
|
||||
then:
|
||||
- script.stop: ramp_on_script
|
||||
- script.stop: ramp_off_script
|
||||
- lambda: 'id(ramp_switch_target_on) = false;'
|
||||
- lambda: "id(ramp_switch_target_on) = false;"
|
||||
- light.turn_off:
|
||||
id: mosfet_leds
|
||||
transition_length: 0s
|
||||
|
||||
# Boot complete: allow OFF handlers again
|
||||
- lambda: 'id(booting) = false;'
|
||||
- lambda: "id(booting) = false;"
|
||||
|
||||
#:########################################################################################:#
|
||||
# ESP PLATFORM AND FRAMEWORK:
|
||||
@@ -345,13 +345,13 @@ status_led:
|
||||
mqtt:
|
||||
on_message:
|
||||
# Light control to ramp up
|
||||
- topic: "${mqtt_local_command_topic}/light/set"
|
||||
- topic: "${mqtt_local_command_topic}"
|
||||
payload: "${mqtt_local_device_command_ON}"
|
||||
then:
|
||||
- switch.turn_on: mosfet_ramp_switch
|
||||
|
||||
# Light control to ramp down
|
||||
- topic: "${mqtt_local_command_topic}/light/set"
|
||||
- topic: "${mqtt_local_command_topic}"
|
||||
payload: "${mqtt_local_device_command_OFF}"
|
||||
then:
|
||||
- switch.turn_off: mosfet_ramp_switch
|
||||
@@ -482,7 +482,7 @@ binary_sensor:
|
||||
on_press:
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(ramp_switch_target_on);'
|
||||
lambda: "return id(ramp_switch_target_on);"
|
||||
then:
|
||||
# Target is currently ON -> press should go OFF (start ramp-down)
|
||||
- lambda: |-
|
||||
@@ -584,7 +584,7 @@ light:
|
||||
on_turn_on:
|
||||
- output.turn_on: green_led_out
|
||||
- mqtt.publish:
|
||||
topic: "${mqtt_local_status_topic}/light/state"
|
||||
topic: "${mqtt_local_status_topic}"
|
||||
payload: "${mqtt_local_device_command_ON}"
|
||||
retain: true
|
||||
- lambda: |-
|
||||
@@ -595,7 +595,7 @@ light:
|
||||
- script.stop: max_on_watchdog
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(max_on_hours) > 0;'
|
||||
lambda: "return id(max_on_hours) > 0;"
|
||||
then:
|
||||
- script.execute: max_on_watchdog
|
||||
|
||||
@@ -605,13 +605,13 @@ light:
|
||||
- output.turn_off: green_led_out
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return !id(booting);'
|
||||
lambda: "return !id(booting);"
|
||||
then:
|
||||
- mqtt.publish:
|
||||
topic: "${mqtt_local_status_topic}/light/state"
|
||||
topic: "${mqtt_local_status_topic}"
|
||||
payload: "${mqtt_local_device_command_OFF}"
|
||||
retain: true
|
||||
- lambda: 'id(ramp_switch_target_on) = false;'
|
||||
- lambda: "id(ramp_switch_target_on) = false;"
|
||||
- script.stop: max_on_watchdog
|
||||
- lambda: |-
|
||||
id(last_brightness_pct) = 0.0f;
|
||||
@@ -699,9 +699,9 @@ number:
|
||||
set_action:
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return x <= 0.0f;'
|
||||
lambda: "return x <= 0.0f;"
|
||||
then:
|
||||
- lambda: 'id(suppress_slider_sync) = true;'
|
||||
- lambda: "id(suppress_slider_sync) = true;"
|
||||
- script.stop: ramp_on_script
|
||||
- script.stop: ramp_off_script
|
||||
- light.turn_off:
|
||||
@@ -713,7 +713,7 @@ number:
|
||||
id(last_brightness_pct) = 0.0f;
|
||||
id(last_set_pos) = 0;
|
||||
- delay: 400ms
|
||||
- lambda: 'id(suppress_slider_sync) = false;'
|
||||
- lambda: "id(suppress_slider_sync) = false;"
|
||||
else:
|
||||
- lambda: |-
|
||||
id(suppress_slider_sync) = true;
|
||||
@@ -744,7 +744,7 @@ number:
|
||||
if (out_pct > maxp) out_pct = maxp;
|
||||
id(last_brightness_pct) = out_pct;
|
||||
- delay: 400ms
|
||||
- lambda: 'id(suppress_slider_sync) = false;'
|
||||
- lambda: "id(suppress_slider_sync) = false;"
|
||||
|
||||
- platform: template
|
||||
id: cfg_max_on_hours
|
||||
@@ -767,12 +767,12 @@ number:
|
||||
id(cfg_max_on_hours).publish_state((float) hrs);
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(mosfet_leds).current_values.is_on();'
|
||||
lambda: "return id(mosfet_leds).current_values.is_on();"
|
||||
then:
|
||||
- script.stop: max_on_watchdog
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(max_on_hours) > 0;'
|
||||
lambda: "return id(max_on_hours) > 0;"
|
||||
then:
|
||||
- script.execute: max_on_watchdog
|
||||
|
||||
@@ -785,7 +785,7 @@ script:
|
||||
- id: ramp_on_script
|
||||
mode: restart
|
||||
then:
|
||||
- lambda: 'id(is_ramping) = true;'
|
||||
- lambda: "id(is_ramping) = true;"
|
||||
- script.stop: ramp_off_script
|
||||
|
||||
# Ensure we start at at least the floor without a visible "pop".
|
||||
@@ -798,13 +798,13 @@ script:
|
||||
then:
|
||||
- light.turn_on:
|
||||
id: mosfet_leds
|
||||
brightness: !lambda 'return id(min_brightness_pct) / 100.0f;'
|
||||
brightness: !lambda "return id(min_brightness_pct) / 100.0f;"
|
||||
transition_length: 80ms
|
||||
|
||||
# Ramp from current (>= floor) to cap over a fraction of ramp_up_ms.
|
||||
- light.turn_on:
|
||||
id: mosfet_leds
|
||||
brightness: !lambda 'return id(max_brightness_pct) / 100.0f;'
|
||||
brightness: !lambda "return id(max_brightness_pct) / 100.0f;"
|
||||
transition_length: !lambda |-
|
||||
const auto &cv = id(mosfet_leds).current_values;
|
||||
const float floor = id(min_brightness_pct) / 100.0f;
|
||||
@@ -825,7 +825,7 @@ script:
|
||||
id(last_ramp_ms) = (int) (id(ramp_up_ms) * frac);
|
||||
return (uint32_t) id(last_ramp_ms);
|
||||
|
||||
- delay: !lambda 'return (uint32_t) id(last_ramp_ms);'
|
||||
- delay: !lambda "return (uint32_t) id(last_ramp_ms);"
|
||||
- lambda: |-
|
||||
id(is_ramping) = false;
|
||||
const auto &cv = id(mosfet_leds).current_values;
|
||||
@@ -838,7 +838,7 @@ script:
|
||||
- id: ramp_to_target_script
|
||||
mode: restart
|
||||
then:
|
||||
- lambda: 'id(is_ramping) = true;'
|
||||
- lambda: "id(is_ramping) = true;"
|
||||
- script.stop: ramp_off_script
|
||||
|
||||
# Ensure we start at the floor cleanly.
|
||||
@@ -851,7 +851,7 @@ script:
|
||||
then:
|
||||
- light.turn_on:
|
||||
id: mosfet_leds
|
||||
brightness: !lambda 'return id(min_brightness_pct) / 100.0f;'
|
||||
brightness: !lambda "return id(min_brightness_pct) / 100.0f;"
|
||||
transition_length: 80ms
|
||||
|
||||
# Ramp from current (>= floor) to restore_target_pct over a fraction of ramp_up_ms.
|
||||
@@ -884,7 +884,7 @@ script:
|
||||
id(last_ramp_ms) = (int) (id(ramp_up_ms) * frac);
|
||||
return (uint32_t) id(last_ramp_ms);
|
||||
|
||||
- delay: !lambda 'return (uint32_t) id(last_ramp_ms);'
|
||||
- delay: !lambda "return (uint32_t) id(last_ramp_ms);"
|
||||
- lambda: |-
|
||||
id(is_ramping) = false;
|
||||
const auto &cv = id(mosfet_leds).current_values;
|
||||
@@ -904,7 +904,7 @@ script:
|
||||
|
||||
- light.turn_on:
|
||||
id: mosfet_leds
|
||||
brightness: !lambda 'return id(min_brightness_pct) / 100.0f;'
|
||||
brightness: !lambda "return id(min_brightness_pct) / 100.0f;"
|
||||
transition_length: !lambda |-
|
||||
const auto &cv = id(mosfet_leds).current_values;
|
||||
const float floor = id(min_brightness_pct) / 100.0f;
|
||||
@@ -918,7 +918,7 @@ script:
|
||||
id(last_ramp_ms) = (int) (id(ramp_down_ms) * frac);
|
||||
return (uint32_t) id(last_ramp_ms);
|
||||
|
||||
- delay: !lambda 'return (uint32_t) id(last_ramp_ms);'
|
||||
- delay: !lambda "return (uint32_t) id(last_ramp_ms);"
|
||||
- light.turn_off:
|
||||
id: mosfet_leds
|
||||
transition_length: 150ms
|
||||
@@ -935,12 +935,12 @@ script:
|
||||
then:
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(max_on_hours) > 0;'
|
||||
lambda: "return id(max_on_hours) > 0;"
|
||||
then:
|
||||
- delay: !lambda 'return (uint32_t) (id(max_on_hours) * 3600000UL);'
|
||||
- delay: !lambda "return (uint32_t) (id(max_on_hours) * 3600000UL);"
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(mosfet_leds).current_values.is_on();'
|
||||
lambda: "return id(mosfet_leds).current_values.is_on();"
|
||||
then:
|
||||
- lambda: |-
|
||||
id(ramp_switch_target_on) = false;
|
||||
@@ -967,18 +967,18 @@ script:
|
||||
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(restore_target_pct) > 0.5f;'
|
||||
lambda: "return id(restore_target_pct) > 0.5f;"
|
||||
then:
|
||||
- lambda: |-
|
||||
id(ramp_switch_target_on) = true;
|
||||
id(suppress_slider_sync) = true;
|
||||
- script.stop: ramp_off_script
|
||||
- script.execute: ramp_to_target_script
|
||||
- delay: !lambda 'return (uint32_t) id(last_ramp_ms);'
|
||||
- lambda: 'id(suppress_slider_sync) = false;'
|
||||
- delay: !lambda "return (uint32_t) id(last_ramp_ms);"
|
||||
- lambda: "id(suppress_slider_sync) = false;"
|
||||
else:
|
||||
# Exact last was 0 -> remain OFF
|
||||
- lambda: 'id(ramp_switch_target_on) = false;'
|
||||
- lambda: "id(ramp_switch_target_on) = false;"
|
||||
- light.turn_off:
|
||||
id: mosfet_leds
|
||||
transition_length: 0s
|
||||
@@ -6,6 +6,7 @@
|
||||
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-downstairskitchleds.yaml
|
||||
#:########################################################################################:#
|
||||
# VERSIONS:
|
||||
# v2.2 2026-07-20 Simplified local MQTT command and status topics to the device root
|
||||
# v2.1 2026-02-25 Updated yaml to zorruno layout V1.1
|
||||
# v2.0 2025-09-15 A bunch of fixes.
|
||||
# v1.5 2025-09-04 Adopt ramped "Restore Brightness" (0->last non-zero), avoid boot blip (ALWAYS_OFF + high-priority on_boot),
|
||||
@@ -60,12 +61,12 @@
|
||||
#:########################################################################################:#
|
||||
# MQTT COMMANDS:
|
||||
# - Command topic:
|
||||
# ${mqtt_local_command_topic}/light/set
|
||||
# ${mqtt_local_command_topic}
|
||||
# Payload "${mqtt_local_device_command_ON}" -> fade up (switch ON)
|
||||
# Payload "${mqtt_local_device_command_OFF}" -> fade down (switch OFF)
|
||||
#
|
||||
# - Status topic:
|
||||
# ${mqtt_local_status_topic}/light/state
|
||||
# ${mqtt_local_status_topic}
|
||||
# Payload "${mqtt_local_device_command_ON}" / "${mqtt_local_device_command_OFF}"
|
||||
#:########################################################################################:#
|
||||
# OFFLINE NOTES:
|
||||
@@ -81,7 +82,6 @@
|
||||
# - Accurate time is NOT needed (SNTP not needed)
|
||||
#:########################################################################################:#
|
||||
|
||||
|
||||
#:########################################################################################:#
|
||||
# SUBSTITUTIONS: Specific device variable substitutions
|
||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||
@@ -95,7 +95,7 @@ substitutions:
|
||||
|
||||
# Project Naming
|
||||
project_name: "Sinilink.XY-WFMS" # Project details. Manufacturer before the dot, device after the dot.
|
||||
project_version: "v2.1" # Project version denotes release of the YAML file, allowing checking of deployed vs latest version
|
||||
project_version: "v2.2" # Project version denotes release of the YAML file, allowing checking of deployed vs latest version
|
||||
|
||||
# Passwords & Secrets (Unfortunately, you can't use substitutions inside secret names)
|
||||
api_key: !secret esp-api_key
|
||||
@@ -145,8 +145,7 @@ packages:
|
||||
local_current_ip_address: "${current_ip_address}"
|
||||
|
||||
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
||||
common_api: !include
|
||||
#file: common/api_common.yaml
|
||||
common_api: !include #file: common/api_common.yaml
|
||||
file: common/api_common_noencryption.yaml
|
||||
vars:
|
||||
local_api_key: "${api_key}"
|
||||
@@ -193,32 +192,32 @@ esphome:
|
||||
# Mode 0: Fade up to full (obeys fade settings; no on/off flicker)
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(restart_mode) == 0;'
|
||||
lambda: "return id(restart_mode) == 0;"
|
||||
then:
|
||||
- lambda: 'id(ramp_switch_target_on) = true;'
|
||||
- lambda: "id(ramp_switch_target_on) = true;"
|
||||
- script.execute: ramp_on_script
|
||||
|
||||
# Mode 1: Restore Brightness (deferred to avoid races)
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(restart_mode) == 1;'
|
||||
lambda: "return id(restart_mode) == 1;"
|
||||
then:
|
||||
- script.execute: deferred_restore_brightness
|
||||
|
||||
# Mode 2: Remain Off (no blip; stays off)
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(restart_mode) == 2;'
|
||||
lambda: "return id(restart_mode) == 2;"
|
||||
then:
|
||||
- script.stop: ramp_on_script
|
||||
- script.stop: ramp_off_script
|
||||
- lambda: 'id(ramp_switch_target_on) = false;'
|
||||
- lambda: "id(ramp_switch_target_on) = false;"
|
||||
- light.turn_off:
|
||||
id: mosfet_leds
|
||||
transition_length: 0s
|
||||
|
||||
# Boot complete: allow OFF handlers again
|
||||
- lambda: 'id(booting) = false;'
|
||||
- lambda: "id(booting) = false;"
|
||||
|
||||
#:########################################################################################:#
|
||||
# ESP PLATFORM AND FRAMEWORK
|
||||
@@ -358,13 +357,13 @@ status_led:
|
||||
mqtt:
|
||||
on_message:
|
||||
# Light control to ramp up
|
||||
- topic: "${mqtt_local_command_topic}/light/set"
|
||||
- topic: "${mqtt_local_command_topic}"
|
||||
payload: "${mqtt_local_device_command_ON}"
|
||||
then:
|
||||
- switch.turn_on: mosfet_ramp_switch
|
||||
|
||||
# Light control to ramp down
|
||||
- topic: "${mqtt_local_command_topic}/light/set"
|
||||
- topic: "${mqtt_local_command_topic}"
|
||||
payload: "${mqtt_local_device_command_OFF}"
|
||||
then:
|
||||
- switch.turn_off: mosfet_ramp_switch
|
||||
@@ -492,7 +491,7 @@ binary_sensor:
|
||||
on_press:
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(ramp_switch_target_on);'
|
||||
lambda: "return id(ramp_switch_target_on);"
|
||||
then:
|
||||
- lambda: |-
|
||||
id(ramp_switch_target_on) = false;
|
||||
@@ -589,7 +588,7 @@ light:
|
||||
on_turn_on:
|
||||
- output.turn_on: green_led_out
|
||||
- mqtt.publish:
|
||||
topic: "${mqtt_local_status_topic}/light/state"
|
||||
topic: "${mqtt_local_status_topic}"
|
||||
payload: "${mqtt_local_device_command_ON}"
|
||||
retain: true
|
||||
- lambda: |-
|
||||
@@ -599,7 +598,7 @@ light:
|
||||
- script.stop: max_on_watchdog
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(max_on_hours) > 0;'
|
||||
lambda: "return id(max_on_hours) > 0;"
|
||||
then:
|
||||
- script.execute: max_on_watchdog
|
||||
|
||||
@@ -607,13 +606,13 @@ light:
|
||||
- output.turn_off: green_led_out
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return !id(booting);'
|
||||
lambda: "return !id(booting);"
|
||||
then:
|
||||
- mqtt.publish:
|
||||
topic: "${mqtt_local_status_topic}/light/state"
|
||||
topic: "${mqtt_local_status_topic}"
|
||||
payload: "${mqtt_local_device_command_OFF}"
|
||||
retain: true
|
||||
- lambda: 'id(ramp_switch_target_on) = false;'
|
||||
- lambda: "id(ramp_switch_target_on) = false;"
|
||||
- script.stop: max_on_watchdog
|
||||
- lambda: |-
|
||||
id(last_brightness_pct) = 0.0f;
|
||||
@@ -700,9 +699,9 @@ number:
|
||||
set_action:
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return x <= 0.0f;'
|
||||
lambda: "return x <= 0.0f;"
|
||||
then:
|
||||
- lambda: 'id(suppress_slider_sync) = true;'
|
||||
- lambda: "id(suppress_slider_sync) = true;"
|
||||
- script.stop: ramp_on_script
|
||||
- script.stop: ramp_off_script
|
||||
- light.turn_off:
|
||||
@@ -714,7 +713,7 @@ number:
|
||||
id(last_brightness_pct) = 0.0f;
|
||||
id(last_set_pos) = 0;
|
||||
- delay: 400ms
|
||||
- lambda: 'id(suppress_slider_sync) = false;'
|
||||
- lambda: "id(suppress_slider_sync) = false;"
|
||||
else:
|
||||
- lambda: |-
|
||||
id(suppress_slider_sync) = true;
|
||||
@@ -745,7 +744,7 @@ number:
|
||||
if (out_pct > maxp) out_pct = maxp;
|
||||
id(last_brightness_pct) = out_pct;
|
||||
- delay: 400ms
|
||||
- lambda: 'id(suppress_slider_sync) = false;'
|
||||
- lambda: "id(suppress_slider_sync) = false;"
|
||||
|
||||
- platform: template
|
||||
id: cfg_max_on_hours
|
||||
@@ -768,12 +767,12 @@ number:
|
||||
id(cfg_max_on_hours).publish_state((float) hrs);
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(mosfet_leds).current_values.is_on();'
|
||||
lambda: "return id(mosfet_leds).current_values.is_on();"
|
||||
then:
|
||||
- script.stop: max_on_watchdog
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(max_on_hours) > 0;'
|
||||
lambda: "return id(max_on_hours) > 0;"
|
||||
then:
|
||||
- script.execute: max_on_watchdog
|
||||
|
||||
@@ -785,7 +784,7 @@ script:
|
||||
- id: ramp_on_script
|
||||
mode: restart
|
||||
then:
|
||||
- lambda: 'id(is_ramping) = true;'
|
||||
- lambda: "id(is_ramping) = true;"
|
||||
- script.stop: ramp_off_script
|
||||
- if:
|
||||
condition:
|
||||
@@ -796,11 +795,11 @@ script:
|
||||
then:
|
||||
- light.turn_on:
|
||||
id: mosfet_leds
|
||||
brightness: !lambda 'return id(min_brightness_pct) / 100.0f;'
|
||||
brightness: !lambda "return id(min_brightness_pct) / 100.0f;"
|
||||
transition_length: 80ms
|
||||
- light.turn_on:
|
||||
id: mosfet_leds
|
||||
brightness: !lambda 'return id(max_brightness_pct) / 100.0f;'
|
||||
brightness: !lambda "return id(max_brightness_pct) / 100.0f;"
|
||||
transition_length: !lambda |-
|
||||
const auto &cv = id(mosfet_leds).current_values;
|
||||
const float floor = id(min_brightness_pct) / 100.0f;
|
||||
@@ -820,7 +819,7 @@ script:
|
||||
if (frac > 1.0f) frac = 1.0f;
|
||||
id(last_ramp_ms) = (int) (id(ramp_up_ms) * frac);
|
||||
return (uint32_t) id(last_ramp_ms);
|
||||
- delay: !lambda 'return (uint32_t) id(last_ramp_ms);'
|
||||
- delay: !lambda "return (uint32_t) id(last_ramp_ms);"
|
||||
- lambda: |-
|
||||
id(is_ramping) = false;
|
||||
const auto &cv = id(mosfet_leds).current_values;
|
||||
@@ -832,7 +831,7 @@ script:
|
||||
- id: ramp_to_target_script
|
||||
mode: restart
|
||||
then:
|
||||
- lambda: 'id(is_ramping) = true;'
|
||||
- lambda: "id(is_ramping) = true;"
|
||||
- script.stop: ramp_off_script
|
||||
- if:
|
||||
condition:
|
||||
@@ -843,7 +842,7 @@ script:
|
||||
then:
|
||||
- light.turn_on:
|
||||
id: mosfet_leds
|
||||
brightness: !lambda 'return id(min_brightness_pct) / 100.0f;'
|
||||
brightness: !lambda "return id(min_brightness_pct) / 100.0f;"
|
||||
transition_length: 80ms
|
||||
- light.turn_on:
|
||||
id: mosfet_leds
|
||||
@@ -873,7 +872,7 @@ script:
|
||||
if (frac > 1.0f) frac = 1.0f;
|
||||
id(last_ramp_ms) = (int) (id(ramp_up_ms) * frac);
|
||||
return (uint32_t) id(last_ramp_ms);
|
||||
- delay: !lambda 'return (uint32_t) id(last_ramp_ms);'
|
||||
- delay: !lambda "return (uint32_t) id(last_ramp_ms);"
|
||||
- lambda: |-
|
||||
id(is_ramping) = false;
|
||||
const auto &cv = id(mosfet_leds).current_values;
|
||||
@@ -891,7 +890,7 @@ script:
|
||||
- script.stop: ramp_on_script
|
||||
- light.turn_on:
|
||||
id: mosfet_leds
|
||||
brightness: !lambda 'return id(min_brightness_pct) / 100.0f;'
|
||||
brightness: !lambda "return id(min_brightness_pct) / 100.0f;"
|
||||
transition_length: !lambda |-
|
||||
const auto &cv = id(mosfet_leds).current_values;
|
||||
const float floor = id(min_brightness_pct) / 100.0f;
|
||||
@@ -904,7 +903,7 @@ script:
|
||||
if (frac > 1.0f) frac = 1.0f;
|
||||
id(last_ramp_ms) = (int) (id(ramp_down_ms) * frac);
|
||||
return (uint32_t) id(last_ramp_ms);
|
||||
- delay: !lambda 'return (uint32_t) id(last_ramp_ms);'
|
||||
- delay: !lambda "return (uint32_t) id(last_ramp_ms);"
|
||||
- light.turn_off:
|
||||
id: mosfet_leds
|
||||
transition_length: 150ms
|
||||
@@ -921,12 +920,12 @@ script:
|
||||
then:
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(max_on_hours) > 0;'
|
||||
lambda: "return id(max_on_hours) > 0;"
|
||||
then:
|
||||
- delay: !lambda 'return (uint32_t) (id(max_on_hours) * 3600000UL);'
|
||||
- delay: !lambda "return (uint32_t) (id(max_on_hours) * 3600000UL);"
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(mosfet_leds).current_values.is_on();'
|
||||
lambda: "return id(mosfet_leds).current_values.is_on();"
|
||||
then:
|
||||
- lambda: |-
|
||||
id(ramp_switch_target_on) = false;
|
||||
@@ -950,17 +949,17 @@ script:
|
||||
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(restore_target_pct) > 0.5f;'
|
||||
lambda: "return id(restore_target_pct) > 0.5f;"
|
||||
then:
|
||||
- lambda: |-
|
||||
id(ramp_switch_target_on) = true;
|
||||
id(suppress_slider_sync) = true;
|
||||
- script.stop: ramp_off_script
|
||||
- script.execute: ramp_to_target_script
|
||||
- delay: !lambda 'return (uint32_t) id(last_ramp_ms);'
|
||||
- lambda: 'id(suppress_slider_sync) = false;'
|
||||
- delay: !lambda "return (uint32_t) id(last_ramp_ms);"
|
||||
- lambda: "id(suppress_slider_sync) = false;"
|
||||
else:
|
||||
- lambda: 'id(ramp_switch_target_on) = false;'
|
||||
- lambda: "id(ramp_switch_target_on) = false;"
|
||||
- light.turn_off:
|
||||
id: mosfet_leds
|
||||
transition_length: 0s
|
||||
@@ -6,6 +6,7 @@
|
||||
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-downstkitchlights.yaml
|
||||
#:########################################################################################:#
|
||||
# VERSIONS:
|
||||
# v2.2 2026-07-20 Restored direct MQTT control of pantry LEDs using the flattened topic
|
||||
# v2.1 2026-02-25 Updated yaml to zorruno layout V1.1
|
||||
# v2.0 2025-06-05 YAML tidyups
|
||||
# v1.0 2025-03-28 Initial Version
|
||||
@@ -21,6 +22,13 @@
|
||||
# - Relay 1: Dining Light
|
||||
# - Relay 2: Kitchen Light
|
||||
# - Relay 3: Extract Fan (virtual only, no power connected to 3rd relay)
|
||||
# - Relay 2 publishes ON/OFF commands directly to the downstairs kitchen pantry LEDs.
|
||||
#:########################################################################################:#
|
||||
# MQTT COMMANDS:
|
||||
# - Remote command topic:
|
||||
# ${mqtt_remote_device_command_topic}
|
||||
# Payload "${mqtt_remote_device_command_on}" -> pantry LEDs ON
|
||||
# Payload "${mqtt_remote_device_command_off}" -> pantry LEDs OFF
|
||||
#:########################################################################################:#
|
||||
# OFFLINE NOTES:
|
||||
# a) Home Assistant OFFLINE, but Network and MQTT ONLINE
|
||||
@@ -36,7 +44,6 @@
|
||||
# - Accurate time is NOT needed (SNTP not needed)
|
||||
#:########################################################################################:#
|
||||
|
||||
|
||||
#:########################################################################################:#
|
||||
# SUBSTITUTIONS: Specific device variable substitutions
|
||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||
@@ -50,7 +57,7 @@ substitutions:
|
||||
|
||||
# Project Naming
|
||||
project_name: "Zemismart Technologies.KS-811 Triple"
|
||||
project_version: "v2.1"
|
||||
project_version: "v2.2"
|
||||
|
||||
# Passwords & Secrets
|
||||
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
||||
@@ -61,6 +68,13 @@ substitutions:
|
||||
# Don't forget to switch it back when changed.
|
||||
current_ip_address: ${static_ip_address}
|
||||
|
||||
# MQTT REMOTE Controls
|
||||
mqtt_command_main_topic: !secret mqtt_command_main_topic
|
||||
mqtt_remote_device_name: "downstairskitchen-pantryleds"
|
||||
mqtt_remote_device_command_topic: "${mqtt_command_main_topic}/${mqtt_remote_device_name}"
|
||||
mqtt_remote_device_command_on: "ON"
|
||||
mqtt_remote_device_command_off: "OFF"
|
||||
|
||||
# Device Settings
|
||||
log_level: "INFO" # NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
||||
update_interval: "60s" # update time for general sensors etc
|
||||
@@ -195,6 +209,14 @@ switch:
|
||||
name: "Relay 2: ${switch_2_name}"
|
||||
pin: GPIO12
|
||||
id: Relay_2
|
||||
on_turn_on:
|
||||
- mqtt.publish:
|
||||
topic: "${mqtt_remote_device_command_topic}"
|
||||
payload: "${mqtt_remote_device_command_on}"
|
||||
on_turn_off:
|
||||
- mqtt.publish:
|
||||
topic: "${mqtt_remote_device_command_topic}"
|
||||
payload: "${mqtt_remote_device_command_off}"
|
||||
|
||||
- platform: gpio
|
||||
name: "Relay 3: ${switch_3_name}"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-downstloungeentry.yaml
|
||||
#:########################################################################################:#
|
||||
# VERSIONS:
|
||||
# v3.8 2026-07-20 Updated remote MQTT topics for the flattened downstairs lounge main lights topic
|
||||
# v3.7 2026-02-25 Updated yaml to zorruno layout V1.1
|
||||
# v3.6 2025-07-24 YAML tidyups
|
||||
#:########################################################################################:#
|
||||
@@ -45,7 +46,6 @@
|
||||
# - Accurate time is NOT needed (SNTP not needed)
|
||||
#:########################################################################################:#
|
||||
|
||||
|
||||
#:########################################################################################:#
|
||||
# SUBSTITUTIONS: Specific device variable substitutions
|
||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||
@@ -59,7 +59,7 @@ substitutions:
|
||||
|
||||
# Project Naming
|
||||
project_name: "Zemismart Technologies.KS-811 Single"
|
||||
project_version: "v3.7"
|
||||
project_version: "v3.8"
|
||||
|
||||
# Passwords & Secrets
|
||||
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
||||
@@ -78,8 +78,8 @@ substitutions:
|
||||
|
||||
# MQTT REMOTE Controls
|
||||
mqtt_remote_device_name: "downst-lounge-main-lights"
|
||||
mqtt_remote_device_command_topic: "${mqtt_command_main_topic}/${mqtt_remote_device_name}/light1/set"
|
||||
mqtt_remote_status_topic: "${mqtt_status_main_topic}/${mqtt_remote_device_name}/light1/state"
|
||||
mqtt_remote_device_command_topic: "${mqtt_command_main_topic}/${mqtt_remote_device_name}"
|
||||
mqtt_remote_status_topic: "${mqtt_status_main_topic}/${mqtt_remote_device_name}"
|
||||
mqtt_remote_device_command_on: "On"
|
||||
mqtt_remote_device_command_off: "Off"
|
||||
|
||||
@@ -170,7 +170,7 @@ mqtt:
|
||||
- delay: 50ms
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return !id(Relay_1).state;'
|
||||
lambda: "return !id(Relay_1).state;"
|
||||
then:
|
||||
- switch.turn_on: Relay_1
|
||||
|
||||
@@ -180,7 +180,7 @@ mqtt:
|
||||
- delay: 50ms
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(Relay_1).state;'
|
||||
lambda: "return id(Relay_1).state;"
|
||||
then:
|
||||
- switch.turn_off: Relay_1
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-downstloungemain.yaml
|
||||
#:########################################################################################:#
|
||||
# VERSIONS:
|
||||
# v3.7 2026-07-20 Simplified local MQTT command and status topics to the device root
|
||||
# v3.6 2026-02-25 Updated yaml to zorruno layout V1.1
|
||||
# v3.5 2025-07-28 YAML tidyups
|
||||
#:########################################################################################:#
|
||||
@@ -23,12 +24,12 @@
|
||||
#:########################################################################################:#
|
||||
# MQTT COMMANDS:
|
||||
# - Local command topic (Main Lights):
|
||||
# ${mqtt_local_command_topic}/light1/set
|
||||
# ${mqtt_local_command_topic}
|
||||
# Payload "On" -> Relay 1 ON
|
||||
# Payload "Off" -> Relay 1 OFF
|
||||
#
|
||||
# - Local status topic (Main Lights):
|
||||
# ${mqtt_local_status_topic}/light1/state
|
||||
# ${mqtt_local_status_topic}
|
||||
# Payload "On" / "Off" published when Relay 1 changes state
|
||||
#:########################################################################################:#
|
||||
# OFFLINE NOTES:
|
||||
@@ -45,7 +46,6 @@
|
||||
# - Accurate time is NOT needed (SNTP not needed).
|
||||
#:########################################################################################:#
|
||||
|
||||
|
||||
#:########################################################################################:#
|
||||
# SUBSTITUTIONS: Specific device variable substitutions
|
||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||
@@ -59,7 +59,7 @@ substitutions:
|
||||
|
||||
# Project Naming
|
||||
project_name: "Zemismart Technologies.KS-811 Triple"
|
||||
project_version: "v3.6"
|
||||
project_version: "v3.7"
|
||||
|
||||
# Passwords & Secrets
|
||||
api_key: !secret esp-api_key
|
||||
@@ -156,11 +156,11 @@ logger:
|
||||
mqtt:
|
||||
on_message:
|
||||
# Main Lights control (Relay 1)
|
||||
- topic: "${mqtt_local_command_topic}/light1/set"
|
||||
- topic: "${mqtt_local_command_topic}"
|
||||
payload: "On"
|
||||
then:
|
||||
- switch.turn_on: relay_1
|
||||
- topic: "${mqtt_local_command_topic}/light1/set"
|
||||
- topic: "${mqtt_local_command_topic}"
|
||||
payload: "Off"
|
||||
then:
|
||||
- switch.turn_off: relay_1
|
||||
@@ -222,11 +222,11 @@ switch:
|
||||
id: relay_1
|
||||
on_turn_on:
|
||||
- mqtt.publish:
|
||||
topic: "${mqtt_local_status_topic}/light1/state"
|
||||
topic: "${mqtt_local_status_topic}"
|
||||
payload: "On"
|
||||
on_turn_off:
|
||||
- mqtt.publish:
|
||||
topic: "${mqtt_local_status_topic}/light1/state"
|
||||
topic: "${mqtt_local_status_topic}"
|
||||
payload: "Off"
|
||||
|
||||
# Relay 2 (GPIO12)
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-loungebookshelfleds.yaml
|
||||
#:########################################################################################:#
|
||||
# VERSIONS:
|
||||
# V2.2 2026-07-20 Simplified local MQTT command and status topics to the device root
|
||||
# V2.1 2026-03-11 Updated yaml to zorruno layout V1.1
|
||||
# V2.0 2025-09-15 A bunch of fixes and made it more standard across my devices
|
||||
# V1.0 2025-08-17 First setup (and replacement of Tasmota)
|
||||
@@ -48,10 +49,10 @@
|
||||
# - Maximum ON time before automatic fade-down (1-48 h, 0 = no limit)
|
||||
#
|
||||
# MQTT COMMANDS:
|
||||
# - ${mqtt_local_command_topic}/light/set = ON
|
||||
# - ${mqtt_local_command_topic}/light/set = OFF
|
||||
# - ${mqtt_local_command_topic} = ON
|
||||
# - ${mqtt_local_command_topic} = OFF
|
||||
# - State publishes to:
|
||||
# - ${mqtt_local_status_topic}/light/state
|
||||
# - ${mqtt_local_status_topic}
|
||||
#:########################################################################################:#
|
||||
# OFFLINE NOTES:
|
||||
# a) Home Assistant offline (network and MQTT online):
|
||||
@@ -84,7 +85,7 @@ substitutions:
|
||||
|
||||
# Project Naming
|
||||
project_name: "Magichome Single Colour V1.1 LED Controller.Generic ESP8266" # Project details. Manufacturer before the dot, device after the dot.
|
||||
project_version: "v2.1" # Project version denotes release of the YAML file, allowing checking of deployed vs latest version
|
||||
project_version: "v2.2" # Project version denotes release of the YAML file, allowing checking of deployed vs latest version
|
||||
|
||||
# Passwords & Secrets (Unfortunately, you can't use substitutions inside secret names)
|
||||
api_key: !secret esp-api_key # If using HA API
|
||||
@@ -132,8 +133,7 @@ packages:
|
||||
local_ota_pass: "${ota_pass}"
|
||||
|
||||
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
||||
common_api: !include
|
||||
#file: common/api_common.yaml
|
||||
common_api: !include #file: common/api_common.yaml
|
||||
file: common/api_common_noencryption.yaml
|
||||
vars:
|
||||
local_api_key: "${api_key}"
|
||||
@@ -351,12 +351,12 @@ status_led:
|
||||
mqtt:
|
||||
on_message:
|
||||
# Light control to ramp up
|
||||
- topic: "${mqtt_local_command_topic}/light/set"
|
||||
- topic: "${mqtt_local_command_topic}"
|
||||
payload: "${mqtt_local_device_command_ON}"
|
||||
then:
|
||||
- switch.turn_on: mosfet_ramp_switch
|
||||
# Light control to ramp down
|
||||
- topic: "${mqtt_local_command_topic}/light/set"
|
||||
- topic: "${mqtt_local_command_topic}"
|
||||
payload: "${mqtt_local_device_command_OFF}"
|
||||
then:
|
||||
- switch.turn_off: mosfet_ramp_switch
|
||||
@@ -593,7 +593,7 @@ light:
|
||||
on_turn_on:
|
||||
- output.turn_on: green_led_out
|
||||
- mqtt.publish:
|
||||
topic: "${mqtt_local_status_topic}/light/state"
|
||||
topic: "${mqtt_local_status_topic}"
|
||||
payload: "${mqtt_local_device_command_ON}"
|
||||
retain: true
|
||||
- lambda: |-
|
||||
@@ -617,7 +617,7 @@ light:
|
||||
lambda: "return !id(booting);"
|
||||
then:
|
||||
- mqtt.publish:
|
||||
topic: "${mqtt_local_status_topic}/light/state"
|
||||
topic: "${mqtt_local_status_topic}"
|
||||
payload: "${mqtt_local_device_command_OFF}"
|
||||
retain: true
|
||||
- lambda: "id(ramp_switch_target_on) = false;"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-loungecabinetleds.yaml
|
||||
#:########################################################################################:#
|
||||
# VERSIONS:
|
||||
# V2.2 2026-07-20 Simplified local MQTT command and status topics to the device root
|
||||
# V2.1 2026-03-11 Updated yaml to zorruno layout V1.1
|
||||
# V2.0 2025-09-15 A bunch of fixes, this is now the master for other similar mosfet controllers of mine
|
||||
# V1.5 2025-09-11 First setup (copied from another template)
|
||||
@@ -50,10 +51,10 @@
|
||||
# - Maximum ON time before automatic fade-down (1-48 h, 0 = no limit)
|
||||
#
|
||||
# MQTT COMMANDS:
|
||||
# - ${mqtt_local_command_topic}/light/set = ON
|
||||
# - ${mqtt_local_command_topic}/light/set = OFF
|
||||
# - ${mqtt_local_command_topic} = ON
|
||||
# - ${mqtt_local_command_topic} = OFF
|
||||
# - State publishes to:
|
||||
# - ${mqtt_local_status_topic}/light/state
|
||||
# - ${mqtt_local_status_topic}
|
||||
#:########################################################################################:#
|
||||
# OFFLINE NOTES:
|
||||
# a) Home Assistant offline (network and MQTT online)
|
||||
@@ -80,7 +81,7 @@ substitutions:
|
||||
|
||||
# Project Naming
|
||||
project_name: "Sinilink.XY-WFMS" # Project details. Manufacturer before the dot, device after the dot.
|
||||
project_version: "v2.1" # Project version denotes release of the YAML file, allowing checking of deployed vs latest version
|
||||
project_version: "v2.2" # Project version denotes release of the YAML file, allowing checking of deployed vs latest version
|
||||
|
||||
# Passwords & Secrets (Unfortunately, you can't use substitutions inside secret names)
|
||||
api_key: !secret esp-api_key # If using HA API
|
||||
@@ -130,8 +131,7 @@ packages:
|
||||
local_current_ip_address: "${current_ip_address}"
|
||||
|
||||
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
||||
common_api: !include
|
||||
#file: common/api_common.yaml
|
||||
common_api: !include #file: common/api_common.yaml
|
||||
file: common/api_common_noencryption.yaml
|
||||
vars:
|
||||
local_api_key: "${api_key}"
|
||||
@@ -181,32 +181,32 @@ esphome:
|
||||
# Mode 0: Fade up to full (obeys fade settings; no on/off flicker)
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(restart_mode) == 0;'
|
||||
lambda: "return id(restart_mode) == 0;"
|
||||
then:
|
||||
- lambda: 'id(ramp_switch_target_on) = true;'
|
||||
- lambda: "id(ramp_switch_target_on) = true;"
|
||||
- script.execute: ramp_on_script
|
||||
|
||||
# Mode 1: Restore Brightness (deferred to avoid races)
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(restart_mode) == 1;'
|
||||
lambda: "return id(restart_mode) == 1;"
|
||||
then:
|
||||
- script.execute: deferred_restore_brightness
|
||||
|
||||
# Mode 2: Remain Off (no blip; stays off)
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(restart_mode) == 2;'
|
||||
lambda: "return id(restart_mode) == 2;"
|
||||
then:
|
||||
- script.stop: ramp_on_script
|
||||
- script.stop: ramp_off_script
|
||||
- lambda: 'id(ramp_switch_target_on) = false;'
|
||||
- lambda: "id(ramp_switch_target_on) = false;"
|
||||
- light.turn_off:
|
||||
id: mosfet_leds
|
||||
transition_length: 0s
|
||||
|
||||
# Boot complete: allow OFF handlers again
|
||||
- lambda: 'id(booting) = false;'
|
||||
- lambda: "id(booting) = false;"
|
||||
|
||||
# NEW: force indicator OFF after boot logic
|
||||
# (Removed: output.turn_off: green_led_out)
|
||||
@@ -365,13 +365,13 @@ status_led:
|
||||
mqtt:
|
||||
on_message:
|
||||
# Light control to ramp up
|
||||
- topic: "${mqtt_local_command_topic}/light/set"
|
||||
- topic: "${mqtt_local_command_topic}"
|
||||
payload: "${mqtt_local_device_command_ON}"
|
||||
then:
|
||||
- switch.turn_on: mosfet_ramp_switch
|
||||
|
||||
# Light control to ramp down
|
||||
- topic: "${mqtt_local_command_topic}/light/set"
|
||||
- topic: "${mqtt_local_command_topic}"
|
||||
payload: "${mqtt_local_device_command_OFF}"
|
||||
then:
|
||||
- switch.turn_off: mosfet_ramp_switch
|
||||
@@ -503,7 +503,7 @@ binary_sensor:
|
||||
on_press:
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(ramp_switch_target_on);'
|
||||
lambda: "return id(ramp_switch_target_on);"
|
||||
then:
|
||||
# Target is currently ON -> press should go OFF (start ramp-down)
|
||||
- lambda: |-
|
||||
@@ -608,7 +608,7 @@ light:
|
||||
on_turn_on:
|
||||
- output.turn_on: green_led_out
|
||||
- mqtt.publish:
|
||||
topic: "${mqtt_local_status_topic}/light/state"
|
||||
topic: "${mqtt_local_status_topic}"
|
||||
payload: "${mqtt_local_device_command_ON}"
|
||||
retain: true
|
||||
- lambda: |-
|
||||
@@ -619,7 +619,7 @@ light:
|
||||
- script.stop: max_on_watchdog
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(max_on_hours) > 0;'
|
||||
lambda: "return id(max_on_hours) > 0;"
|
||||
then:
|
||||
- script.execute: max_on_watchdog
|
||||
|
||||
@@ -629,13 +629,13 @@ light:
|
||||
- output.turn_off: green_led_out
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return !id(booting);'
|
||||
lambda: "return !id(booting);"
|
||||
then:
|
||||
- mqtt.publish:
|
||||
topic: "${mqtt_local_status_topic}/light/state"
|
||||
topic: "${mqtt_local_status_topic}"
|
||||
payload: "${mqtt_local_device_command_OFF}"
|
||||
retain: true
|
||||
- lambda: 'id(ramp_switch_target_on) = false;'
|
||||
- lambda: "id(ramp_switch_target_on) = false;"
|
||||
- script.stop: max_on_watchdog
|
||||
- lambda: |-
|
||||
id(last_brightness_pct) = 0.0f;
|
||||
@@ -724,10 +724,10 @@ number:
|
||||
set_action:
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return x <= 0.0f;'
|
||||
lambda: "return x <= 0.0f;"
|
||||
then:
|
||||
# 0 means OFF
|
||||
- lambda: 'id(suppress_slider_sync) = true;'
|
||||
- lambda: "id(suppress_slider_sync) = true;"
|
||||
- script.stop: ramp_on_script
|
||||
- script.stop: ramp_off_script
|
||||
- light.turn_off:
|
||||
@@ -739,7 +739,7 @@ number:
|
||||
id(last_brightness_pct) = 0.0f; // persist OFF immediately
|
||||
id(last_set_pos) = 0;
|
||||
- delay: 400ms
|
||||
- lambda: 'id(suppress_slider_sync) = false;'
|
||||
- lambda: "id(suppress_slider_sync) = false;"
|
||||
else:
|
||||
# Map 1..100 - [min..max] and set ON
|
||||
- lambda: |-
|
||||
@@ -771,7 +771,7 @@ number:
|
||||
if (out_pct > maxp) out_pct = maxp;
|
||||
id(last_brightness_pct) = out_pct; // persist exact target now
|
||||
- delay: 400ms
|
||||
- lambda: 'id(suppress_slider_sync) = false;'
|
||||
- lambda: "id(suppress_slider_sync) = false;"
|
||||
|
||||
- platform: template
|
||||
id: cfg_max_on_hours
|
||||
@@ -794,12 +794,12 @@ number:
|
||||
id(cfg_max_on_hours).publish_state((float) hrs);
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(mosfet_leds).current_values.is_on();'
|
||||
lambda: "return id(mosfet_leds).current_values.is_on();"
|
||||
then:
|
||||
- script.stop: max_on_watchdog
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(max_on_hours) > 0;'
|
||||
lambda: "return id(max_on_hours) > 0;"
|
||||
then:
|
||||
- script.execute: max_on_watchdog
|
||||
|
||||
@@ -813,7 +813,7 @@ script:
|
||||
- id: ramp_on_script
|
||||
mode: restart
|
||||
then:
|
||||
- lambda: 'id(is_ramping) = true;'
|
||||
- lambda: "id(is_ramping) = true;"
|
||||
- script.stop: ramp_off_script
|
||||
# Ensure we start at at least the floor without a visible "pop".
|
||||
- if:
|
||||
@@ -825,12 +825,12 @@ script:
|
||||
then:
|
||||
- light.turn_on:
|
||||
id: mosfet_leds
|
||||
brightness: !lambda 'return id(min_brightness_pct) / 100.0f;'
|
||||
brightness: !lambda "return id(min_brightness_pct) / 100.0f;"
|
||||
transition_length: 80ms
|
||||
# Ramp from current (>= floor) to cap over a fraction of ramp_up_ms.
|
||||
- light.turn_on:
|
||||
id: mosfet_leds
|
||||
brightness: !lambda 'return id(max_brightness_pct) / 100.0f;'
|
||||
brightness: !lambda "return id(max_brightness_pct) / 100.0f;"
|
||||
transition_length: !lambda |-
|
||||
const auto &cv = id(mosfet_leds).current_values;
|
||||
const float floor = id(min_brightness_pct) / 100.0f;
|
||||
@@ -850,7 +850,7 @@ script:
|
||||
if (frac > 1.0f) frac = 1.0f;
|
||||
id(last_ramp_ms) = (int) (id(ramp_up_ms) * frac);
|
||||
return (uint32_t) id(last_ramp_ms);
|
||||
- delay: !lambda 'return (uint32_t) id(last_ramp_ms);'
|
||||
- delay: !lambda "return (uint32_t) id(last_ramp_ms);"
|
||||
- lambda: |-
|
||||
id(is_ramping) = false;
|
||||
const auto &cv = id(mosfet_leds).current_values;
|
||||
@@ -863,7 +863,7 @@ script:
|
||||
- id: ramp_to_target_script
|
||||
mode: restart
|
||||
then:
|
||||
- lambda: 'id(is_ramping) = true;'
|
||||
- lambda: "id(is_ramping) = true;"
|
||||
- script.stop: ramp_off_script
|
||||
# Ensure we start at the floor cleanly.
|
||||
- if:
|
||||
@@ -875,7 +875,7 @@ script:
|
||||
then:
|
||||
- light.turn_on:
|
||||
id: mosfet_leds
|
||||
brightness: !lambda 'return id(min_brightness_pct) / 100.0f;'
|
||||
brightness: !lambda "return id(min_brightness_pct) / 100.0f;"
|
||||
transition_length: 80ms
|
||||
# Ramp from current (>= floor) to restore_target_pct over a fraction of ramp_up_ms.
|
||||
- light.turn_on:
|
||||
@@ -906,7 +906,7 @@ script:
|
||||
if (frac > 1.0f) frac = 1.0f;
|
||||
id(last_ramp_ms) = (int) (id(ramp_up_ms) * frac);
|
||||
return (uint32_t) id(last_ramp_ms);
|
||||
- delay: !lambda 'return (uint32_t) id(last_ramp_ms);'
|
||||
- delay: !lambda "return (uint32_t) id(last_ramp_ms);"
|
||||
- lambda: |-
|
||||
id(is_ramping) = false;
|
||||
const auto &cv = id(mosfet_leds).current_values;
|
||||
@@ -925,7 +925,7 @@ script:
|
||||
- script.stop: ramp_on_script
|
||||
- light.turn_on:
|
||||
id: mosfet_leds
|
||||
brightness: !lambda 'return id(min_brightness_pct) / 100.0f;'
|
||||
brightness: !lambda "return id(min_brightness_pct) / 100.0f;"
|
||||
transition_length: !lambda |-
|
||||
const auto &cv = id(mosfet_leds).current_values;
|
||||
const float floor = id(min_brightness_pct) / 100.0f;
|
||||
@@ -938,7 +938,7 @@ script:
|
||||
if (frac > 1.0f) frac = 1.0f;
|
||||
id(last_ramp_ms) = (int) (id(ramp_down_ms) * frac);
|
||||
return (uint32_t) id(last_ramp_ms);
|
||||
- delay: !lambda 'return (uint32_t) id(last_ramp_ms);'
|
||||
- delay: !lambda "return (uint32_t) id(last_ramp_ms);"
|
||||
- light.turn_off:
|
||||
id: mosfet_leds
|
||||
transition_length: 150ms
|
||||
@@ -955,12 +955,12 @@ script:
|
||||
then:
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(max_on_hours) > 0;'
|
||||
lambda: "return id(max_on_hours) > 0;"
|
||||
then:
|
||||
- delay: !lambda 'return (uint32_t) (id(max_on_hours) * 3600000UL);'
|
||||
- delay: !lambda "return (uint32_t) (id(max_on_hours) * 3600000UL);"
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(mosfet_leds).current_values.is_on();'
|
||||
lambda: "return id(mosfet_leds).current_values.is_on();"
|
||||
then:
|
||||
- lambda: |-
|
||||
id(ramp_switch_target_on) = false;
|
||||
@@ -987,18 +987,18 @@ script:
|
||||
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return id(restore_target_pct) > 0.5f;'
|
||||
lambda: "return id(restore_target_pct) > 0.5f;"
|
||||
then:
|
||||
- lambda: |-
|
||||
id(ramp_switch_target_on) = true; // reflect our intent
|
||||
id(suppress_slider_sync) = true;
|
||||
- script.stop: ramp_off_script
|
||||
- script.execute: ramp_to_target_script
|
||||
- delay: !lambda 'return (uint32_t) id(last_ramp_ms);'
|
||||
- lambda: 'id(suppress_slider_sync) = false;'
|
||||
- delay: !lambda "return (uint32_t) id(last_ramp_ms);"
|
||||
- lambda: "id(suppress_slider_sync) = false;"
|
||||
else:
|
||||
# Exact last was 0 -> remain OFF
|
||||
- lambda: 'id(ramp_switch_target_on) = false;'
|
||||
- lambda: "id(ramp_switch_target_on) = false;"
|
||||
- light.turn_off:
|
||||
id: mosfet_leds
|
||||
transition_length: 0s
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-masterbdrmsouth.yaml
|
||||
#:########################################################################################:#
|
||||
# VERSIONS:
|
||||
# v1.4 2026-07-20 Flattened retained North and South MQTT status topics to the device roots.
|
||||
# v1.3 2026-06-12 Reassigned logical controls after live wiring checks.
|
||||
# Relay 1 on both switches = North Lights virtual/Tasmota control.
|
||||
# Relay 2 on both switches = South Lights control; WEST Relay 2 is physical load.
|
||||
@@ -55,7 +56,7 @@
|
||||
# NOTE: TOGGLE is intentionally not handled here to avoid double-toggle if both switches receive it.
|
||||
#
|
||||
# - North Lights retained status/sync topic:
|
||||
# ${mqtt_local_status_topic1}/state
|
||||
# ${mqtt_local_status_topic1}
|
||||
# Payload "On" / "Off" mirrors the actual North Lights state.
|
||||
#
|
||||
# - South Lights local command topic:
|
||||
@@ -65,7 +66,7 @@
|
||||
# NOTE: TOGGLE is intentionally not handled here to avoid ambiguous multi-device toggles.
|
||||
#
|
||||
# - South Lights retained status/sync topic:
|
||||
# ${mqtt_local_status_topic2}/state
|
||||
# ${mqtt_local_status_topic2}
|
||||
# Payload "On" / "Off" mirrors the actual South Lights state.
|
||||
#:########################################################################################:#
|
||||
# OFFLINE NOTES:
|
||||
@@ -87,7 +88,6 @@
|
||||
# - Accurate time is NOT needed (SNTP not needed).
|
||||
#:########################################################################################:#
|
||||
|
||||
|
||||
#:########################################################################################:#
|
||||
# SUBSTITUTIONS: Specific device variable substitutions
|
||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||
@@ -101,7 +101,7 @@ substitutions:
|
||||
|
||||
# Project Naming
|
||||
project_name: "Zemismart Technologies.KS-811 Triple"
|
||||
project_version: "v1.3"
|
||||
project_version: "v1.4"
|
||||
|
||||
# Passwords & Secrets
|
||||
api_key: !secret esp-api_key
|
||||
@@ -218,22 +218,22 @@ globals:
|
||||
- id: north_update_from_sync
|
||||
type: bool
|
||||
restore_value: false
|
||||
initial_value: 'false'
|
||||
initial_value: "false"
|
||||
|
||||
- id: south_update_from_sync
|
||||
type: bool
|
||||
restore_value: false
|
||||
initial_value: 'false'
|
||||
initial_value: "false"
|
||||
|
||||
- id: north_lights_state
|
||||
type: bool
|
||||
restore_value: false
|
||||
initial_value: 'false'
|
||||
initial_value: "false"
|
||||
|
||||
- id: south_lights_state
|
||||
type: bool
|
||||
restore_value: false
|
||||
initial_value: 'false'
|
||||
initial_value: "false"
|
||||
|
||||
#:########################################################################################:#
|
||||
# MQTT: Device-specific MQTT command + retained status/sync triggers
|
||||
@@ -275,7 +275,7 @@ mqtt:
|
||||
}
|
||||
|
||||
# Retained North status is a secondary mirror/sync path.
|
||||
- topic: "${mqtt_local_status_topic1}/state"
|
||||
- topic: "${mqtt_local_status_topic1}"
|
||||
then:
|
||||
- lambda: |-
|
||||
if (x == "On" || x == "ON" || x == "on") {
|
||||
@@ -291,7 +291,7 @@ mqtt:
|
||||
# retained status after the physical Relay 2 changes, and this switch mirrors
|
||||
# that status onto its local Relay 2.
|
||||
# -------------------------------------------------------------------------
|
||||
- topic: "${mqtt_local_status_topic2}/state"
|
||||
- topic: "${mqtt_local_status_topic2}"
|
||||
then:
|
||||
- lambda: |-
|
||||
if (x == "On" || x == "ON" || x == "on") {
|
||||
@@ -410,7 +410,7 @@ script:
|
||||
id(north_update_from_sync) = true;
|
||||
- switch.turn_on: relay_1
|
||||
- mqtt.publish:
|
||||
topic: "${mqtt_local_status_topic1}/state"
|
||||
topic: "${mqtt_local_status_topic1}"
|
||||
payload: "On"
|
||||
retain: true
|
||||
- lambda: |-
|
||||
@@ -424,7 +424,7 @@ script:
|
||||
id(north_update_from_sync) = true;
|
||||
- switch.turn_off: relay_1
|
||||
- mqtt.publish:
|
||||
topic: "${mqtt_local_status_topic1}/state"
|
||||
topic: "${mqtt_local_status_topic1}"
|
||||
payload: "Off"
|
||||
retain: true
|
||||
- lambda: |-
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-masterbdrmwest.yaml
|
||||
#:########################################################################################:#
|
||||
# VERSIONS:
|
||||
# v1.4 2026-07-20 Flattened retained North and South MQTT status topics to the device roots.
|
||||
# v1.3 2026-06-12 Reassigned logical controls after live wiring checks.
|
||||
# Relay 1 on both switches = North Lights virtual/Tasmota control.
|
||||
# Relay 2 on both switches = South Lights control; WEST Relay 2 is physical load.
|
||||
@@ -55,7 +56,7 @@
|
||||
# NOTE: TOGGLE is intentionally not handled here to avoid double-toggle if both switches receive it.
|
||||
#
|
||||
# - North Lights retained status/sync topic:
|
||||
# ${mqtt_local_status_topic1}/state
|
||||
# ${mqtt_local_status_topic1}
|
||||
# Payload "On" / "Off" mirrors the actual North Lights state.
|
||||
#
|
||||
# - South Lights local command topic:
|
||||
@@ -65,7 +66,7 @@
|
||||
# NOTE: TOGGLE is intentionally not handled here to avoid ambiguous multi-device toggles.
|
||||
#
|
||||
# - South Lights retained status/sync topic:
|
||||
# ${mqtt_local_status_topic2}/state
|
||||
# ${mqtt_local_status_topic2}
|
||||
# Payload "On" / "Off" published when Relay 2 changes state.
|
||||
#:########################################################################################:#
|
||||
# OFFLINE NOTES:
|
||||
@@ -88,7 +89,6 @@
|
||||
# - Accurate time is NOT needed (SNTP not needed).
|
||||
#:########################################################################################:#
|
||||
|
||||
|
||||
#:########################################################################################:#
|
||||
# SUBSTITUTIONS: Specific device variable substitutions
|
||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||
@@ -102,7 +102,7 @@ substitutions:
|
||||
|
||||
# Project Naming
|
||||
project_name: "Zemismart Technologies.KS-811 Triple"
|
||||
project_version: "v1.3"
|
||||
project_version: "v1.4"
|
||||
|
||||
# Passwords & Secrets
|
||||
api_key: !secret esp-api_key
|
||||
@@ -217,22 +217,22 @@ globals:
|
||||
- id: north_update_from_sync
|
||||
type: bool
|
||||
restore_value: false
|
||||
initial_value: 'false'
|
||||
initial_value: "false"
|
||||
|
||||
- id: south_update_from_sync
|
||||
type: bool
|
||||
restore_value: false
|
||||
initial_value: 'false'
|
||||
initial_value: "false"
|
||||
|
||||
- id: north_lights_state
|
||||
type: bool
|
||||
restore_value: false
|
||||
initial_value: 'false'
|
||||
initial_value: "false"
|
||||
|
||||
- id: south_lights_state
|
||||
type: bool
|
||||
restore_value: false
|
||||
initial_value: 'false'
|
||||
initial_value: "false"
|
||||
|
||||
#:########################################################################################:#
|
||||
# MQTT: Device-specific MQTT command + retained status/sync triggers
|
||||
@@ -274,7 +274,7 @@ mqtt:
|
||||
}
|
||||
|
||||
# Retained North status is a secondary mirror/sync path.
|
||||
- topic: "${mqtt_local_status_topic1}/state"
|
||||
- topic: "${mqtt_local_status_topic1}"
|
||||
then:
|
||||
- lambda: |-
|
||||
if (x == "On" || x == "ON" || x == "on") {
|
||||
@@ -296,7 +296,7 @@ mqtt:
|
||||
}
|
||||
|
||||
# Retained South status keeps this physical relay and the SOUTH mirror in step.
|
||||
- topic: "${mqtt_local_status_topic2}/state"
|
||||
- topic: "${mqtt_local_status_topic2}"
|
||||
then:
|
||||
- lambda: |-
|
||||
if (x == "On" || x == "ON" || x == "on") {
|
||||
@@ -415,7 +415,7 @@ script:
|
||||
id(north_update_from_sync) = true;
|
||||
- switch.turn_on: relay_1
|
||||
- mqtt.publish:
|
||||
topic: "${mqtt_local_status_topic1}/state"
|
||||
topic: "${mqtt_local_status_topic1}"
|
||||
payload: "On"
|
||||
retain: true
|
||||
- lambda: |-
|
||||
@@ -429,7 +429,7 @@ script:
|
||||
id(north_update_from_sync) = true;
|
||||
- switch.turn_off: relay_1
|
||||
- mqtt.publish:
|
||||
topic: "${mqtt_local_status_topic1}/state"
|
||||
topic: "${mqtt_local_status_topic1}"
|
||||
payload: "Off"
|
||||
retain: true
|
||||
- lambda: |-
|
||||
@@ -554,10 +554,10 @@ switch:
|
||||
}
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return !id(south_update_from_sync);'
|
||||
lambda: "return !id(south_update_from_sync);"
|
||||
then:
|
||||
- mqtt.publish:
|
||||
topic: "${mqtt_local_status_topic2}/state"
|
||||
topic: "${mqtt_local_status_topic2}"
|
||||
payload: "On"
|
||||
retain: true
|
||||
on_turn_off:
|
||||
@@ -568,10 +568,10 @@ switch:
|
||||
}
|
||||
- if:
|
||||
condition:
|
||||
lambda: 'return !id(south_update_from_sync);'
|
||||
lambda: "return !id(south_update_from_sync);"
|
||||
then:
|
||||
- mqtt.publish:
|
||||
topic: "${mqtt_local_status_topic2}/state"
|
||||
topic: "${mqtt_local_status_topic2}"
|
||||
payload: "Off"
|
||||
retain: true
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-officeusbhubpower.yaml
|
||||
#:########################################################################################:#
|
||||
# VERSIONS:
|
||||
# V1.2 2026-07-20 Simplified local MQTT command and status topics to the device root
|
||||
# V1.1 2026-02-25 Updated yaml to zorruno layout V1.1
|
||||
# V1.0 2025-06-14 Initial Version
|
||||
#:########################################################################################:#
|
||||
@@ -22,10 +23,10 @@
|
||||
#:########################################################################################:#
|
||||
# MQTT COMMANDS:
|
||||
# Command (set relay):
|
||||
# - ${mqtt_command_topic}/relay1/set -> ON, OFF
|
||||
# - ${mqtt_command_topic} -> ON, OFF
|
||||
#
|
||||
# Status (published from template sensor):
|
||||
# - ${mqtt_status_topic}/relay1/state -> ON, OFF
|
||||
# - ${mqtt_status_topic} -> ON, OFF
|
||||
#:########################################################################################:#
|
||||
# OFFLINE NOTES:
|
||||
# a) Home Assistant OFFLINE, but Network and MQTT ONLINE
|
||||
@@ -54,7 +55,7 @@ substitutions:
|
||||
|
||||
# Project Naming
|
||||
project_name: "Sonoff Technologies.Sonoff Basic V1"
|
||||
project_version: "v1.1"
|
||||
project_version: "v1.2"
|
||||
|
||||
# Passwords & Secrets (Unfortunately, you cannot use substitutions inside secret names)
|
||||
api_key: !secret esp-api_key
|
||||
@@ -201,12 +202,12 @@ binary_sensor:
|
||||
return id(relay1).state;
|
||||
on_press:
|
||||
- mqtt.publish:
|
||||
topic: "${mqtt_status_topic}/relay1/state"
|
||||
topic: "${mqtt_status_topic}"
|
||||
payload: "ON"
|
||||
retain: false
|
||||
on_release:
|
||||
- mqtt.publish:
|
||||
topic: "${mqtt_status_topic}/relay1/state"
|
||||
topic: "${mqtt_status_topic}"
|
||||
payload: "OFF"
|
||||
retain: false
|
||||
|
||||
@@ -227,12 +228,12 @@ status_led:
|
||||
#:########################################################################################:#
|
||||
mqtt:
|
||||
on_message:
|
||||
- topic: "${mqtt_command_topic}/relay1/set"
|
||||
- topic: "${mqtt_command_topic}"
|
||||
payload: "ON"
|
||||
then:
|
||||
- switch.turn_on: relay1
|
||||
|
||||
- topic: "${mqtt_command_topic}/relay1/set"
|
||||
- topic: "${mqtt_command_topic}"
|
||||
payload: "OFF"
|
||||
then:
|
||||
- switch.turn_off: relay1
|
||||
@@ -4,17 +4,60 @@
|
||||
# PACKAGE: 16A EV Charger Control
|
||||
###############################################################################
|
||||
#
|
||||
# FILE:
|
||||
# packages/16a_ev_charging_controls.yaml
|
||||
#
|
||||
# VERSION:
|
||||
# V1.2 2026-07-20
|
||||
# - Added structured mode, timing, and restart behavior documentation.
|
||||
#
|
||||
# V1.1 2026-05-15
|
||||
# - Reworked 1hr topup logic to use a hard deadline and watchdog.
|
||||
# - Removed dependency on timer.finished event for relay shutoff.
|
||||
# - Offpeak until charged now continues past offpeak end until charging stops.
|
||||
# - 1hr topup now now rolls into Normal Offpeak if the hour ends during
|
||||
# - 1hr topup now rolls into Normal Offpeak if the hour ends during
|
||||
# the offpeak window, without switching the relay off and back on.
|
||||
#
|
||||
# V1.0 2026-05-11
|
||||
# - Initial package for 16A EV charger offpeak and charge-until-full control.
|
||||
#
|
||||
# PURPOSE:
|
||||
# Controls the Leaf 16A charger relay using scheduled offpeak operation and
|
||||
# user-selectable immediate or charge-until-full modes.
|
||||
#
|
||||
# DEPENDENCIES:
|
||||
# - switch.garage_db_control_16a_wallcharger_operation controls charger power.
|
||||
# - binary_sensor.garage_db_control_16a_wallcharger_charging reports whether
|
||||
# the vehicle is actively charging.
|
||||
#
|
||||
# CHARGE MODES:
|
||||
# - Normal (Offpeak) turns the relay on and off at the configured offpeak
|
||||
# start and end times. Selecting this mode takes no immediate action.
|
||||
# - Offpeak until charged starts at the offpeak time, or immediately if
|
||||
# selected during offpeak, and may continue beyond offpeak end until the
|
||||
# vehicle stops charging.
|
||||
# - 1hr topup now turns the relay on immediately and records a hard deadline
|
||||
# one hour ahead.
|
||||
# - Charge now until full turns the relay on immediately and keeps it on until
|
||||
# the vehicle stops charging.
|
||||
# - Stop charging now turns the relay off immediately and returns the selector
|
||||
# to Normal (Offpeak).
|
||||
#
|
||||
# TIMING AND COMPLETION:
|
||||
# - Charge-until-full modes allow five minutes for charging to start. This
|
||||
# also handles a vehicle that is already full.
|
||||
# - Charging is considered complete after the charging sensor remains off for
|
||||
# five minutes.
|
||||
# - The one-hour topup deadline is stored in input_datetime and checked every
|
||||
# minute and when Home Assistant starts.
|
||||
# - If a topup ends during offpeak, the relay remains on and the mode returns
|
||||
# to Normal (Offpeak), avoiding an off/on relay cycle.
|
||||
# - Equal offpeak start and end times are interpreted as an all-day window.
|
||||
#
|
||||
# OPERATION NOTES:
|
||||
# - Normal offpeak start and end use exact-time triggers.
|
||||
# - There is no startup catch-up if Home Assistant is offline at either time.
|
||||
#
|
||||
# PACKAGE SETTINGS:
|
||||
# Car display name:
|
||||
# - Leaf
|
||||
|
||||
@@ -6,12 +6,16 @@
|
||||
# Pool Light Operation
|
||||
#
|
||||
# FILE:
|
||||
# packages/pool_light_boost_switch.yaml
|
||||
# packages/Pool_Controls/pool_light_operation.yaml
|
||||
#
|
||||
# VERSION:
|
||||
# V1.1 2026-06-29
|
||||
# V1.2 2026-07-20
|
||||
#
|
||||
# VERSION HISTORY:
|
||||
# V1.2 2026-07-20
|
||||
# - Corrected the documented package filename.
|
||||
# - Documented the relationship with the native ESPHome controls.
|
||||
#
|
||||
# V1.1 2026-06-29
|
||||
# - Tidied layout, comments, naming and automation IDs.
|
||||
# - Added structured package header and section comments.
|
||||
@@ -38,8 +42,15 @@
|
||||
# Operation topic:
|
||||
# viewroad-commands/poollight-timer/operation
|
||||
#
|
||||
# DEPENDENCIES:
|
||||
# - switch.esp_poollightpower2_switch provides the real output state.
|
||||
# - The ESPHome pool light device subscribes to the MQTT operation topic.
|
||||
# - Native ESPHome mode, boost, and pool-light-mode entities coexist with
|
||||
# this one-tap control.
|
||||
#
|
||||
# NOTES:
|
||||
# The input_boolean.timer_light_midnight_pending helper is internal to this package.
|
||||
# Dashboard cards currently use input_boolean.poollights_mode_switch.
|
||||
#
|
||||
#:########################################################################################:#
|
||||
|
||||
|
||||
@@ -1,10 +1,68 @@
|
||||
# packages/poolpump_operation.yaml
|
||||
#:########################################################################################:#
|
||||
# Pool Pump Operation Package #
|
||||
#:########################################################################################:#
|
||||
#
|
||||
# TITLE:
|
||||
# Pool Pump Operation
|
||||
#
|
||||
# FILE:
|
||||
# packages/Pool_Controls/pool_pump_operation.yaml
|
||||
#
|
||||
# VERSION:
|
||||
# V1.1 2026-07-20
|
||||
#
|
||||
# VERSION HISTORY:
|
||||
# V1.1 2026-07-20
|
||||
# - Added structured package documentation and section comments.
|
||||
# - Documented the relationship with the native ESPHome controls.
|
||||
#
|
||||
# V1.0
|
||||
# - Initial package.
|
||||
# - Provides a Home Assistant UI switch for pool pump BOOST / OFF behaviour.
|
||||
# - Sends TIMER mode again at midnight when required.
|
||||
#
|
||||
# PURPOSE:
|
||||
# Provides a one-tap Home Assistant UI switch for controlling the pool pump.
|
||||
#
|
||||
# Behaviour:
|
||||
# - Turning the UI switch ON sends BOOST if the real pump output is OFF.
|
||||
# - Turning the UI switch OFF sends OFF if the real pump output is ON.
|
||||
# - After OFF is requested, TIMER mode is restored at midnight.
|
||||
# - The UI switch follows the real ESPHome output without publishing MQTT.
|
||||
#
|
||||
# MQTT:
|
||||
# Operation topic:
|
||||
# viewroad-commands/poolpump-timer/operation
|
||||
#
|
||||
# Payloads used by this package:
|
||||
# BOOST
|
||||
# OFF
|
||||
# TIMER
|
||||
#
|
||||
# DEPENDENCIES:
|
||||
# - switch.esp_poolpumppower_power_output provides the real output state.
|
||||
# - The ESPHome pool pump device subscribes to the MQTT operation topic.
|
||||
# - Native ESPHome mode and boost entities coexist with this one-tap control.
|
||||
#
|
||||
# NOTES:
|
||||
# - input_boolean.timer_midnight_pending is internal to this package.
|
||||
# - Dashboard cards currently use input_boolean.poolpump_mode_switch.
|
||||
#
|
||||
#:########################################################################################:#
|
||||
|
||||
#:########################################################################################:#
|
||||
# Home Assistant Customisation #
|
||||
#:########################################################################################:#
|
||||
|
||||
homeassistant:
|
||||
customize:
|
||||
input_boolean.poolpump_mode_switch:
|
||||
icon: mdi:pump
|
||||
|
||||
#:########################################################################################:#
|
||||
# Input Booleans #
|
||||
#:########################################################################################:#
|
||||
|
||||
input_boolean:
|
||||
poolpump_mode_switch:
|
||||
name: "Pool Pump Operation"
|
||||
@@ -14,6 +72,10 @@ input_boolean:
|
||||
name: "Send TIMER at Midnight"
|
||||
initial: false
|
||||
|
||||
#:########################################################################################:#
|
||||
# Automations #
|
||||
#:########################################################################################:#
|
||||
|
||||
automation:
|
||||
- alias: "Pool Pump → send BOOST when user turns UI switch ON"
|
||||
trigger:
|
||||
|
||||
@@ -6,12 +6,16 @@
|
||||
# Pool Timer Selection
|
||||
#
|
||||
# FILE:
|
||||
# pool_timer_selection.yaml
|
||||
# packages/Pool_Controls/pool_timers_selections.yaml
|
||||
#
|
||||
# VERSION:
|
||||
# V1.0 2026-06-29
|
||||
# V1.1 2026-07-20
|
||||
#
|
||||
# VERSION HISTORY:
|
||||
# V1.1 2026-07-20
|
||||
# - Corrected the documented package filename.
|
||||
# - Documented command selectors versus ESPHome timer feedback.
|
||||
#
|
||||
# V1.0 2026-06-29
|
||||
# - Initial package.
|
||||
# - Adds Home Assistant input_select helpers for Pool Pump and Pool Light timer times.
|
||||
@@ -36,6 +40,16 @@
|
||||
#
|
||||
# Payload format is HH:MM.
|
||||
#
|
||||
# STATUS AND FEEDBACK:
|
||||
# - These input_select helpers send retained MQTT commands to ESPHome.
|
||||
# - They do not synchronize their displayed options from the ESPHome devices.
|
||||
# - The ESPHome Timeclock sensors are authoritative for the currently applied
|
||||
# timer values.
|
||||
# - A selector displaying "Default" does not prove that the device currently
|
||||
# uses its default time.
|
||||
# - Native ESPHome mode controls coexist with this package, while timer
|
||||
# schedule changes continue to use the MQTT topics above.
|
||||
#
|
||||
# IMPORTANT:
|
||||
# The current ESPHome timer logic only handles same-day timer windows:
|
||||
# current_mins >= on_time AND current_mins < off_time
|
||||
|
||||
@@ -1,5 +1,52 @@
|
||||
#:########################################################################################:#
|
||||
# Alexa TP-Link Guest Wi-Fi Package #
|
||||
#:########################################################################################:#
|
||||
#
|
||||
# TITLE:
|
||||
# Alexa TP-Link Guest Wi-Fi
|
||||
#
|
||||
# FILE:
|
||||
# packages/alexa_tplink_actions.yaml
|
||||
#
|
||||
# VERSION:
|
||||
# V1.1 2026-07-20
|
||||
#
|
||||
# VERSION HISTORY:
|
||||
# V1.1 2026-07-20
|
||||
# - Added structured documentation and automation descriptions.
|
||||
#
|
||||
# V1.0
|
||||
# - Initial Alexa-mediated TP-Link guest-network controls.
|
||||
#
|
||||
# PURPOSE:
|
||||
# Enables or disables the TP-Link guest Wi-Fi network by sending custom Alexa
|
||||
# requests through the kitchen Echo Show.
|
||||
#
|
||||
# DEPENDENCIES:
|
||||
# - input_boolean.wifi_guest_network is a UI-managed helper that represents
|
||||
# the requested guest-network state.
|
||||
# - media_player.view_rd_kitchen_echo_show must be available through the Alexa
|
||||
# Media Player integration.
|
||||
# - The Alexa account must have a working, linked TP-Link skill.
|
||||
#
|
||||
# ALEXA REQUESTS:
|
||||
# - On: ask t.p.link to enable guest network
|
||||
# - Off: ask t.p.link to disable guest network
|
||||
#
|
||||
# OPERATION NOTES:
|
||||
# - The helper records requested state; it does not confirm router state.
|
||||
# - If Alexa or the TP-Link skill fails, the helper can disagree with the
|
||||
# actual guest-network state.
|
||||
# - After the helper remains on for two hours, it is turned off. That state
|
||||
# change then sends the Alexa disable request.
|
||||
# - The two-hour state-trigger period does not persist through a Home Assistant
|
||||
# restart or automation reload.
|
||||
#
|
||||
#:########################################################################################:#
|
||||
|
||||
automation:
|
||||
- alias: "Turn on the Wifi Guest Network"
|
||||
description: "Asks the linked TP-Link Alexa skill to enable the guest Wi-Fi network."
|
||||
mode: single
|
||||
triggers:
|
||||
- trigger: state
|
||||
@@ -14,6 +61,7 @@ automation:
|
||||
media_content_id: ask t.p.link to enable guest network
|
||||
|
||||
- alias: "Turn off the Wifi Guest Network"
|
||||
description: "Asks the linked TP-Link Alexa skill to disable the guest Wi-Fi network."
|
||||
mode: single
|
||||
triggers:
|
||||
- trigger: state
|
||||
@@ -28,6 +76,7 @@ automation:
|
||||
media_content_id: ask t.p.link to disable guest network
|
||||
|
||||
- alias: "Switch guest network off after time"
|
||||
description: "Turns off the guest-network helper after it remains on for two hours."
|
||||
mode: single
|
||||
triggers:
|
||||
- trigger: state
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
###############################################################################
|
||||
# Bedroom 1 Ikea Air Filter Package
|
||||
# File: /config/packages/bedroom_1_ikea_air_filter.yaml
|
||||
# Version: 1.1
|
||||
# Date: 2026-05-08
|
||||
# Version: 1.2
|
||||
# Date: 2026-07-20
|
||||
#
|
||||
# Purpose:
|
||||
# - Creates a dropdown helper called "Bedroom 1 Ikea Fan".
|
||||
@@ -11,7 +11,7 @@
|
||||
#
|
||||
# Behaviour notes:
|
||||
# - Quiet time turning on sets fan speed to 2.
|
||||
# - Bedside lamp turning on sets fan speed to 2.
|
||||
# - Bedside lamp or Jump Fade control turning on sets fan speed to 2.
|
||||
# - Bedside lamp turning off does not change the fan speed.
|
||||
# - There is no 10-minute re-check, so the fan will not ramp back up just
|
||||
# because the bedside lamp was switched off.
|
||||
@@ -80,12 +80,16 @@ automation:
|
||||
entity_id: input_boolean.quiet_time
|
||||
to: "on"
|
||||
|
||||
# Bedside lamp only forces low when it turns on.
|
||||
# Turning the lamp off does not change the fan speed.
|
||||
# The lamp state catches direct light control.
|
||||
- trigger: state
|
||||
entity_id: light.master_bedroom_bedside_lamp_arlec_bulb_master_bedroom_bedside_lamp_arlec_bulb
|
||||
to: "on"
|
||||
|
||||
# The Jump Fade switch catches a bedside press while the lamp is already on.
|
||||
- trigger: state
|
||||
entity_id: switch.master_bedroom_bedside_lamp_arlec_bulb_master_bedroom_bedside_lamp_arlec_bulb_jump_fade_up_down
|
||||
to: "on"
|
||||
|
||||
# Main timing boundaries.
|
||||
- trigger: time
|
||||
at:
|
||||
@@ -104,9 +108,10 @@ automation:
|
||||
- variables:
|
||||
trigger_entity: "{{ trigger.entity_id | default('') }}"
|
||||
bedside_lamp_entity: light.master_bedroom_bedside_lamp_arlec_bulb_master_bedroom_bedside_lamp_arlec_bulb
|
||||
bedside_lamp_switch_entity: switch.master_bedroom_bedside_lamp_arlec_bulb_master_bedroom_bedside_lamp_arlec_bulb_jump_fade_up_down
|
||||
bedside_lamp_on_trigger: >-
|
||||
{{
|
||||
trigger_entity == bedside_lamp_entity
|
||||
trigger_entity in [bedside_lamp_entity, bedside_lamp_switch_entity]
|
||||
and trigger.to_state is defined
|
||||
and trigger.to_state.state == 'on'
|
||||
}}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
################################################################################
|
||||
# PACKAGE: Downstairs Lights Bulk Activation
|
||||
# FILE: packages/downstairs_lights_bulk_activation.yaml
|
||||
# FILE: packages/downstairs_bulk_lights_on_from_stairs.yaml
|
||||
#
|
||||
# Version: 1.0
|
||||
# Date: 2026-04-26
|
||||
# Version: 1.1
|
||||
# Date: 2026-07-20
|
||||
#
|
||||
# Notes:
|
||||
# - Uses the virtual switch:
|
||||
@@ -16,16 +16,16 @@
|
||||
# Turns OFF the listed downstairs lights, but only if each light is currently ON.
|
||||
#
|
||||
# - No action is taken unless:
|
||||
# input_boolean.downstairs_flat_occupied is ON.
|
||||
# input_boolean.downstairs_flat_occupied is OFF.
|
||||
################################################################################
|
||||
|
||||
automation:
|
||||
- id: downstairs_lights_bulk_activation
|
||||
alias: "Downstairs Lights Bulk Activation"
|
||||
description: >
|
||||
V1.0 - 2026-04-26: Bulk ON/OFF control for downstairs lights from the
|
||||
V1.1 - 2026-07-20: Bulk ON/OFF control for downstairs lights from the
|
||||
central stair lightswitch virtual switch. Only operates when the downstairs
|
||||
flat occupied input_boolean is ON.
|
||||
flat is not occupied.
|
||||
|
||||
mode: single
|
||||
|
||||
|
||||
@@ -1,3 +1,50 @@
|
||||
#:########################################################################################:#
|
||||
# Firewall Internet Control Package #
|
||||
#:########################################################################################:#
|
||||
#
|
||||
# TITLE:
|
||||
# Firewall Internet Control
|
||||
#
|
||||
# FILE:
|
||||
# packages/firewall_control.yaml
|
||||
#
|
||||
# VERSION:
|
||||
# V1.1 2026-07-20
|
||||
#
|
||||
# VERSION HISTORY:
|
||||
# V1.1 2026-07-20
|
||||
# - Added structured MQTT and external-firewall documentation.
|
||||
#
|
||||
# V1.0
|
||||
# - Initial persistent and temporary internet-blocking controls.
|
||||
#
|
||||
# PURPOSE:
|
||||
# Provides Home Assistant controls for persistent and temporary internet
|
||||
# blocking of Mollie's devices through an external MQTT firewall service.
|
||||
#
|
||||
# PERSISTENT CONTROL:
|
||||
# - Blocked enables persistent internet blocking.
|
||||
# - Unblocked disables persistent internet blocking.
|
||||
# - The switch state is reported by the external firewall service.
|
||||
#
|
||||
# TEMPORARY CONTROLS:
|
||||
# - One-hour block publishes Blocked to the temporary-block topic.
|
||||
# - 15-minute unblock publishes Unblocked to the temporary-unblock topic.
|
||||
# - One-hour unblock publishes Unblocked to its one-hour topic.
|
||||
#
|
||||
# EXTERNAL DEPENDENCY:
|
||||
# - Home Assistant only publishes command requests.
|
||||
# - The external firewall service implements temporary durations, restores the
|
||||
# appropriate state afterward, and publishes persistent switch feedback.
|
||||
#
|
||||
# MQTT NOTES:
|
||||
# - All commands are non-retained.
|
||||
# - No availability topic is configured for these entities.
|
||||
# - The persistent status topic retains the legacy device label
|
||||
# block-unblock-mollie-iphone8.
|
||||
#
|
||||
#:########################################################################################:#
|
||||
|
||||
mqtt:
|
||||
switch:
|
||||
- unique_id: mollies.internet
|
||||
|
||||
@@ -2,11 +2,54 @@
|
||||
# Home Assistant Summary Package - V2 #
|
||||
#:########################################################################################:#
|
||||
#
|
||||
# Uses V2 entity IDs to avoid stale/ghost entities from earlier versions.
|
||||
# TITLE:
|
||||
# Home Assistant Summary V2
|
||||
#
|
||||
# FILE:
|
||||
# packages/ha_summary.yaml
|
||||
#
|
||||
# VERSION:
|
||||
# V2.1 2026-07-20
|
||||
#
|
||||
# VERSION HISTORY:
|
||||
# V2.1 2026-07-20
|
||||
# - Added structured documentation for refresh behavior and counting rules.
|
||||
# - Documented heuristic classifications and their limitations.
|
||||
#
|
||||
# V2.0
|
||||
# - Introduced V2 entity IDs to avoid stale entities from earlier versions.
|
||||
#
|
||||
# PURPOSE:
|
||||
# Provides dashboard summary sensors for Home Assistant entities, devices,
|
||||
# areas, cameras, scenes, scripts, automations, add-ons, and updates.
|
||||
#
|
||||
# It also provides device and entity counts for ESPHome, Tasmota, ZHA,
|
||||
# Zigbee2MQTT, Matter, and selected cloud integrations.
|
||||
#
|
||||
# OUTPUTS:
|
||||
# Dashboard entity prefix:
|
||||
# sensor.ha_summary_v2_...
|
||||
#
|
||||
# REFRESH:
|
||||
# Sensors refresh when Home Assistant starts, when the entity, device, or area
|
||||
# registries change, when core configuration changes, and every five minutes.
|
||||
#
|
||||
# COUNTING NOTES:
|
||||
# - Total devices counts distinct device IDs associated with current entities.
|
||||
# Devices without entities are not included.
|
||||
# - Broken entities are entities whose state is unknown or unavailable.
|
||||
# - Add-ons are inferred from Supervisor update entities, excluding the Core,
|
||||
# Supervisor, and Operating System update entities.
|
||||
# - Zigbee2MQTT devices and entities are identified by searching MQTT device
|
||||
# metadata for "zigbee2mqtt".
|
||||
# - Matter Wi-Fi and Thread classifications search device metadata for known
|
||||
# transport terms. These are heuristics rather than authoritative transport
|
||||
# data, and a device can match both categories.
|
||||
# - Matter unclassified counts subtract Wi-Fi and Thread counts from totals, so
|
||||
# overlapping classifications can affect the result.
|
||||
# - Cloud counts use the explicit integration list in the final two sensors.
|
||||
# Add or remove integration domains there when maintaining cloud coverage.
|
||||
#
|
||||
|
||||
template:
|
||||
- trigger:
|
||||
|
||||
@@ -1,5 +1,57 @@
|
||||
##########################################################################################
|
||||
# heat_pump_master_bedroom_schedules.yaml
|
||||
# Master Bedroom Heat Pump Schedules
|
||||
##########################################################################################
|
||||
#
|
||||
# TITLE:
|
||||
# Master Bedroom Heat Pump Schedules
|
||||
#
|
||||
# FILE:
|
||||
# packages/heat_pump_master_bedroom_schedules.yaml
|
||||
#
|
||||
# VERSION:
|
||||
# V1.1 2026-07-20
|
||||
#
|
||||
# VERSION HISTORY:
|
||||
# V1.1 2026-07-20
|
||||
# - Added structured documentation for schedules, boost, and helper behavior.
|
||||
#
|
||||
# V1.0
|
||||
# - Initial master bedroom heat pump schedules and boost controls.
|
||||
#
|
||||
# PURPOSE:
|
||||
# Provides optional 21:00 start and midnight stop schedules, a combined Night
|
||||
# Power mode, and a manual one-hour boost for the master bedroom heat pump.
|
||||
#
|
||||
# DEPENDENCIES:
|
||||
# - climate.master_bedroom provides the Panasonic Comfort Cloud heat pump.
|
||||
# - The climate entity must support the "boost" and "none" preset modes.
|
||||
# - packages/heat_pump_master_bedroom_helpers.yaml provides companion
|
||||
# dashboard, setpoint, HVAC mode, profile, and sleep-timer controls.
|
||||
#
|
||||
# SCHEDULE MODES:
|
||||
# - Night Power Mode turns the heat pump on at 21:00, applies boost for 30
|
||||
# minutes, returns it to the normal preset, and turns it off at midnight.
|
||||
# - 9pm On turns the heat pump on at 21:00 without changing its preset.
|
||||
# - Midnight Off turns the heat pump off at midnight.
|
||||
# - Enabling Night Power disables the separate 9pm On and Midnight Off modes.
|
||||
# - Enabling either separate mode disables Night Power. The separate 9pm On
|
||||
# and Midnight Off modes may be enabled together.
|
||||
#
|
||||
# MANUAL BOOST:
|
||||
# - script.master_bedroom_boost_1hr applies boost for one hour.
|
||||
# - If the heat pump was off when boost started, it is turned off afterward.
|
||||
# - If it was already running, boost ends by restoring the normal preset and
|
||||
# leaving the heat pump running.
|
||||
#
|
||||
# INTERNAL STATE:
|
||||
# - input_boolean.master_bedroom_boost_restore_off records whether manual
|
||||
# boost should restore the heat pump to off.
|
||||
# - timer.master_bedroom_boost_timer controls manual and scheduled boost time.
|
||||
#
|
||||
# OPERATION NOTES:
|
||||
# - The 21:00 and midnight schedules use exact-time triggers.
|
||||
# - There is no startup catch-up if Home Assistant is offline at either time.
|
||||
#
|
||||
##########################################################################################
|
||||
|
||||
##########################################################################################
|
||||
|
||||
@@ -126,7 +126,7 @@ script:
|
||||
#switch.esp_loungemiddleswitch_relay_3_downlights_north: "on"
|
||||
switch.lounge_nspanel_touchscreen_lounge_stair_downlights: "on" # non dimmable pair
|
||||
light.esp_breakfastbarleds_breakfast_bar_leds: 90
|
||||
light.esp_loungecabinetleds2_lounge_cabinet_leds: 90
|
||||
light.esp_loungecabinetleds_lounge_cabinet_leds: 90
|
||||
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 90
|
||||
switch.lounge_cupboard_dual_usb_xus09_l2: "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_rafter_buttons: 40
|
||||
light.esp_breakfastbarleds_breakfast_bar_leds: 60
|
||||
light.esp_loungecabinetleds2_lounge_cabinet_leds: 60
|
||||
light.esp_loungecabinetleds_lounge_cabinet_leds: 60
|
||||
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 60
|
||||
#switch.esp_loungemiddleswitch_relay_3_downlights_north: "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_rafter_buttons: 30
|
||||
light.esp_breakfastbarleds_breakfast_bar_leds: 50
|
||||
light.esp_loungecabinetleds2_lounge_cabinet_leds: 50
|
||||
light.esp_loungecabinetleds_lounge_cabinet_leds: 50
|
||||
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 50
|
||||
#switch.esp_loungemiddleswitch_relay_3_downlights_north: "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_rafter_buttons: 0
|
||||
light.esp_breakfastbarleds_breakfast_bar_leds: 40
|
||||
light.esp_loungecabinetleds2_lounge_cabinet_leds: 40
|
||||
light.esp_loungecabinetleds_lounge_cabinet_leds: 40
|
||||
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 40
|
||||
#switch.esp_loungemiddleswitch_relay_3_downlights_north: "off"
|
||||
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_rafter_buttons: 0
|
||||
light.esp_breakfastbarleds_breakfast_bar_leds: 5
|
||||
light.esp_loungecabinetleds2_lounge_cabinet_leds: 5
|
||||
light.esp_loungecabinetleds_lounge_cabinet_leds: 5
|
||||
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 5
|
||||
#switch.esp_loungemiddleswitch_relay_3_downlights_north: "off"
|
||||
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_lounge_rafter_buttons: 15
|
||||
light.esp_breakfastbarleds_breakfast_bar_leds: 25
|
||||
light.esp_loungecabinetleds2_lounge_cabinet_leds: 30
|
||||
light.esp_loungecabinetleds_lounge_cabinet_leds: 30
|
||||
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 30
|
||||
#light.tasmo_h801_loungeled1_6180_a: 25
|
||||
#light.tasmo_h801_loungeled1_6180_b: 25
|
||||
@@ -270,7 +270,7 @@ script:
|
||||
#switch.esp_loungemiddleswitch_relay_3_downlights_north: "off"
|
||||
switch.lounge_nspanel_touchscreen_lounge_stair_downlights: "off" # non dimmable pair
|
||||
light.esp_breakfastbarleds_breakfast_bar_leds: 0
|
||||
light.esp_loungecabinetleds2_lounge_cabinet_leds: 0
|
||||
light.esp_loungecabinetleds_lounge_cabinet_leds: 0
|
||||
light.esp_loungebookshelfleds_lounge_bookshelf_leds: 0
|
||||
switch.lounge_cupboard_dual_usb_xus09_l2: "off"
|
||||
switch.esp_loungesouthleftswitch_relay_1_wall_washer_left: "off"
|
||||
|
||||
@@ -1,3 +1,40 @@
|
||||
#:########################################################################################:#
|
||||
# Low Battery Device Summary Package #
|
||||
#:########################################################################################:#
|
||||
#
|
||||
# TITLE:
|
||||
# Low Battery Device Summary
|
||||
#
|
||||
# FILE:
|
||||
# packages/low_battery_device_quantity.yaml
|
||||
#
|
||||
# VERSION:
|
||||
# V1.1 2026-07-20
|
||||
#
|
||||
# VERSION HISTORY:
|
||||
# V1.1 2026-07-20
|
||||
# - Changed the low-battery threshold from 97% to 20%.
|
||||
# - Added structured documentation for scope, exclusions, and outputs.
|
||||
#
|
||||
# V1.0
|
||||
# - Initial low-battery count and list sensors.
|
||||
#
|
||||
# PURPOSE:
|
||||
# Finds numeric sensor entities with device_class battery whose value is 20%
|
||||
# or lower, then exposes a count and a human-readable device list.
|
||||
#
|
||||
# SCOPE AND EXCLUSIONS:
|
||||
# - Only entities in the sensor domain with device_class battery are checked.
|
||||
# - Unknown, unavailable, non-numeric, and "Ok" states are excluded.
|
||||
# - Battery entities in other domains are not included.
|
||||
#
|
||||
# OUTPUTS:
|
||||
# - sensor.devices_with_low_battery reports the number of matching sensors.
|
||||
# - sensor.devices_with_low_battery_list reports names and percentages.
|
||||
# - The list sensor also exposes count, entities, and names attributes.
|
||||
#
|
||||
#:########################################################################################:#
|
||||
|
||||
template:
|
||||
- sensor:
|
||||
- name: "Devices with low battery"
|
||||
@@ -9,7 +46,7 @@ template:
|
||||
{% if s.attributes.device_class == 'battery' %}
|
||||
{% set st = s.state %}
|
||||
{% if st not in ['unknown', 'unavailable', 'Ok'] %}
|
||||
{% if st | int(-1) != -1 and (st | int(0)) <= 97 %}
|
||||
{% if st | int(-1) != -1 and (st | int(0)) <= 20 %}
|
||||
{% set ns.c = ns.c + 1 %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
@@ -37,7 +74,7 @@ template:
|
||||
{% if s.attributes.device_class == 'battery' %}
|
||||
{% set st = s.state %}
|
||||
{% if st not in ['unknown', 'unavailable', 'Ok'] %}
|
||||
{% if st | int(-1) != -1 and (st | int(0)) <= 97 %}
|
||||
{% if st | int(-1) != -1 and (st | int(0)) <= 20 %}
|
||||
{% set ns.names = ns.names + [s.name ~ ' (' ~ (st | int(0)) ~ '%)'] %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
@@ -56,7 +93,7 @@ template:
|
||||
{% if s.attributes.device_class == 'battery' %}
|
||||
{% set st = s.state %}
|
||||
{% if st not in ['unknown', 'unavailable', 'Ok'] %}
|
||||
{% if st | int(-1) != -1 and (st | int(0)) <= 97 %}
|
||||
{% if st | int(-1) != -1 and (st | int(0)) <= 20 %}
|
||||
{% set ns.e = ns.e + [s.entity_id] %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
@@ -69,7 +106,7 @@ template:
|
||||
{% if s.attributes.device_class == 'battery' %}
|
||||
{% set st = s.state %}
|
||||
{% if st not in ['unknown', 'unavailable', 'Ok'] %}
|
||||
{% if st | int(-1) != -1 and (st | int(0)) <= 97 %}
|
||||
{% if st | int(-1) != -1 and (st | int(0)) <= 20 %}
|
||||
{% set ns.n = ns.n + [s.name] %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
template:
|
||||
- sensor:
|
||||
- name: "Devices with low battery"
|
||||
unique_id: devices_with_low_battery_count
|
||||
unit_of_measurement: "devices"
|
||||
state: >
|
||||
{% set ns = namespace(c=0) %}
|
||||
{% for s in states.sensor %}
|
||||
{% if s.attributes.device_class == 'battery' %}
|
||||
{% set st = s.state %}
|
||||
{% if st not in ['unknown', 'unavailable', 'Ok'] %}
|
||||
{% if st | int(-1) != -1 and (st | int(0)) <= 97 %}
|
||||
{% set ns.c = ns.c + 1 %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{{ ns.c }}
|
||||
icon: >
|
||||
{% if this.state | int(0) == 0 %}
|
||||
mdi:check-circle
|
||||
{% else %}
|
||||
mdi:battery-alert
|
||||
{% endif %}
|
||||
|
||||
- name: "Devices with low battery list"
|
||||
unique_id: devices_with_low_battery_list
|
||||
icon: >
|
||||
{% if states('sensor.devices_with_low_battery') | int(0) == 0 %}
|
||||
mdi:check-circle
|
||||
{% else %}
|
||||
mdi:battery-alert
|
||||
{% endif %}
|
||||
state: >
|
||||
{% set ns = namespace(names=[]) %}
|
||||
{% for s in states.sensor %}
|
||||
{% if s.attributes.device_class == 'battery' %}
|
||||
{% set st = s.state %}
|
||||
{% if st not in ['unknown', 'unavailable', 'Ok'] %}
|
||||
{% if st | int(-1) != -1 and (st | int(0)) <= 97 %}
|
||||
{% set ns.names = ns.names + [s.name ~ ' (' ~ (st | int(0)) ~ '%)'] %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if ns.names | length == 0 %}
|
||||
None
|
||||
{% else %}
|
||||
{{ ns.names | join(', ') }}
|
||||
{% endif %}
|
||||
attributes:
|
||||
count: "{{ states('sensor.devices_with_low_battery') | int(0) }}"
|
||||
entities: >
|
||||
{% set ns = namespace(e=[]) %}
|
||||
{% for s in states.sensor %}
|
||||
{% if s.attributes.device_class == 'battery' %}
|
||||
{% set st = s.state %}
|
||||
{% if st not in ['unknown', 'unavailable', 'Ok'] %}
|
||||
{% if st | int(-1) != -1 and (st | int(0)) <= 97 %}
|
||||
{% set ns.e = ns.e + [s.entity_id] %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{{ ns.e }}
|
||||
names: >
|
||||
{% set ns = namespace(n=[]) %}
|
||||
{% for s in states.sensor %}
|
||||
{% if s.attributes.device_class == 'battery' %}
|
||||
{% set st = s.state %}
|
||||
{% if st not in ['unknown', 'unavailable', 'Ok'] %}
|
||||
{% if st | int(-1) != -1 and (st | int(0)) <= 97 %}
|
||||
{% set ns.n = ns.n + [s.name] %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{{ ns.n }}
|
||||
@@ -1,7 +1,52 @@
|
||||
#:########################################################################################:#
|
||||
# Main Sony TV Automations Package #
|
||||
#:########################################################################################:#
|
||||
#
|
||||
# TITLE:
|
||||
# Main Sony TV Automations
|
||||
#
|
||||
# FILE:
|
||||
# packages/main_sony_tv_automations.yaml
|
||||
#
|
||||
# VERSION:
|
||||
# V1.1 2026-07-20
|
||||
#
|
||||
# VERSION HISTORY:
|
||||
# V1.1 2026-07-20
|
||||
# - Added structured documentation and automation descriptions.
|
||||
#
|
||||
# V1.0
|
||||
# - Initial MQTT TV-off and surround-amplifier following automations.
|
||||
#
|
||||
# PURPOSE:
|
||||
# Accepts an MQTT command to turn off the lounge TV and keeps the loft
|
||||
# surround-amplifier power synchronized with the TV remote state.
|
||||
#
|
||||
# MQTT COMMAND:
|
||||
# Topic:
|
||||
# viewroad-commands/maintv/action
|
||||
#
|
||||
# Payload:
|
||||
# OFF
|
||||
#
|
||||
# The payload is uppercase and this package does not provide an MQTT ON action.
|
||||
#
|
||||
# AMPLIFIER FOLLOWING:
|
||||
# - remote.lounge_tv is the source-of-truth state for the amplifier.
|
||||
# - The remote state must remain on or off for five seconds before action.
|
||||
# - Restart mode cancels the previous wait when another state change occurs,
|
||||
# preventing brief transitions from toggling amplifier power.
|
||||
#
|
||||
# DEPENDENCIES:
|
||||
# - remote.lounge_tv controls and reports the Sony lounge TV state.
|
||||
# - switch.tv_surround_amp_power_in_loft_x27pp controls amplifier power.
|
||||
#
|
||||
#:########################################################################################:#
|
||||
|
||||
automation:
|
||||
- id: "1669966515993"
|
||||
alias: Turn off Lounge TV
|
||||
description: ""
|
||||
description: "Turns off the lounge TV when the MQTT OFF command is received."
|
||||
trigger:
|
||||
- platform: mqtt
|
||||
topic: viewroad-commands/maintv/action
|
||||
@@ -16,6 +61,7 @@ automation:
|
||||
|
||||
- id: tv_amp_follow_remote_state
|
||||
alias: Lounge surround amp follows TV remote (5s debounce)
|
||||
description: "Follows the stable lounge TV remote state after a five-second debounce."
|
||||
mode: restart
|
||||
trigger:
|
||||
- platform: state
|
||||
|
||||
@@ -1,4 +1,72 @@
|
||||
# === Add friendly names, icons, and area for printer controls ===
|
||||
#:########################################################################################:#
|
||||
# Moonraker 3D Printer Package #
|
||||
#:########################################################################################:#
|
||||
#
|
||||
# TITLE:
|
||||
# Moonraker 3D Printer
|
||||
#
|
||||
# FILE:
|
||||
# packages/moonraker_3dprinter.yaml
|
||||
#
|
||||
# VERSION:
|
||||
# V1.1 2026-07-20
|
||||
#
|
||||
# VERSION HISTORY:
|
||||
# V1.1 2026-07-20
|
||||
# - Added structured documentation for setup, polling, outputs, and safety.
|
||||
# - Recorded that the Creality printer is not currently connected.
|
||||
#
|
||||
# V1.0
|
||||
# - Initial Moonraker REST sensors, commands, and customizations.
|
||||
#
|
||||
# PURPOSE:
|
||||
# Reads Klipper and Moonraker printer data and provides Home Assistant REST
|
||||
# commands for controlling a Creality K1C 3D printer.
|
||||
#
|
||||
# CURRENT STATUS:
|
||||
# - As of 2026-07-20, this configuration no longer connects to the printer.
|
||||
# - It is retained as a reference for future reconnection work.
|
||||
# - Before reconnecting, verify the printer address, Moonraker availability,
|
||||
# queried Klipper object names, and companion template entities.
|
||||
#
|
||||
# DEPENDENCIES:
|
||||
# - A reachable Moonraker server for the Klipper printer.
|
||||
# - Current configured endpoint: http://192.168.2.31:7125
|
||||
# - Companion templates: templates/moonraker_3dprinter.yaml
|
||||
# - The queried sensors and object names must match the Klipper configuration.
|
||||
#
|
||||
# POLLING:
|
||||
# - Full printer status, printer info, and server data poll every second.
|
||||
# - Current print file metadata polls every five seconds.
|
||||
#
|
||||
# RAW REST OUTPUTS:
|
||||
# - sensor.printer_3d_sensor provides printer object status attributes.
|
||||
# - sensor.printer_3d_info provides printer state and state message.
|
||||
# - sensor.printer_3d_server provides Mainsail server configuration data.
|
||||
# - sensor.printer_3d_file_metadata provides current-file metadata.
|
||||
# - Companion templates derive user-facing sensors from these raw entities.
|
||||
#
|
||||
# CONTROLS:
|
||||
# - Emergency stop immediately halts the printer.
|
||||
# - Firmware restart restarts the Klipper firmware process.
|
||||
# - Cancel stops the current print; pause and resume control print progress.
|
||||
#
|
||||
# SAFETY AND NETWORK:
|
||||
# - Emergency stop, firmware restart, and cancel are disruptive actions and
|
||||
# should only be exposed through dashboard controls with confirmation.
|
||||
# - The configured endpoint uses unencrypted HTTP without authentication and
|
||||
# assumes Moonraker is available only on a trusted local network.
|
||||
#
|
||||
# USER CONFIGURATION:
|
||||
# - If the printer address changes, update every Moonraker URL in this file.
|
||||
# - Confirm the filament and chamber sensor object names before reconnecting.
|
||||
#
|
||||
#:########################################################################################:#
|
||||
|
||||
#:########################################################################################:#
|
||||
# Home Assistant Customizations #
|
||||
#:########################################################################################:#
|
||||
|
||||
homeassistant:
|
||||
customize:
|
||||
rest_command.3d_printer_emergency_stop:
|
||||
|
||||
@@ -1,3 +1,49 @@
|
||||
#:########################################################################################:#
|
||||
# Office Media Buttons Package #
|
||||
#:########################################################################################:#
|
||||
#
|
||||
# TITLE:
|
||||
# Office Media Buttons
|
||||
#
|
||||
# FILE:
|
||||
# packages/office_media_buttons.yaml
|
||||
#
|
||||
# VERSION:
|
||||
# V1.1 2026-07-20
|
||||
#
|
||||
# VERSION HISTORY:
|
||||
# V1.1 2026-07-20
|
||||
# - Added structured documentation and automation descriptions.
|
||||
# - Identified the active ZHA implementation and disabled alternatives.
|
||||
#
|
||||
# V1.0
|
||||
# - Initial office media-button automations.
|
||||
#
|
||||
# PURPOSE:
|
||||
# Controls office TV playback from a Zigbee media button using direct ZHA
|
||||
# click events.
|
||||
#
|
||||
# ACTIVE BUTTON MAPPING:
|
||||
# - Single press pauses playback.
|
||||
# - Double press starts or resumes playback.
|
||||
# - Triple press seeks backward by 30 seconds.
|
||||
#
|
||||
# DEPENDENCIES:
|
||||
# - ZHA event source: device IEEE 00:15:8d:00:06:79:46:c8.
|
||||
# - media_player.office_tv provides the current playback position.
|
||||
# - The media actions target the office TV device registered in Home Assistant.
|
||||
#
|
||||
# NOTES:
|
||||
# - seek_amount is not normally provided by the event and defaults to -30.
|
||||
# - Commented MQTT and entity-state implementations below are disabled
|
||||
# historical alternatives retained for reference.
|
||||
#
|
||||
#:########################################################################################:#
|
||||
|
||||
#:########################################################################################:#
|
||||
# Historical Disabled MQTT Sensor #
|
||||
#:########################################################################################:#
|
||||
|
||||
#mqtt:
|
||||
# sensor:
|
||||
# - unique_id: office_media_button_1
|
||||
@@ -6,10 +52,14 @@
|
||||
# unit_of_measurement: "Press"
|
||||
# value_template: "{{ value_json.ZbReceived.Office_Media_Button.Power }}"
|
||||
|
||||
#:########################################################################################:#
|
||||
# Active ZHA Automations #
|
||||
#:########################################################################################:#
|
||||
|
||||
automation:
|
||||
- id: pause_office_tv_on_media_button
|
||||
alias: Pause Office TV on Media Button
|
||||
description: ""
|
||||
description: "Pauses the office TV when the media button is pressed once."
|
||||
trigger:
|
||||
- platform: event
|
||||
event_type: zha_event
|
||||
@@ -26,7 +76,7 @@ automation:
|
||||
mode: single
|
||||
- id: play_office_tv_on_media_button
|
||||
alias: Play Office TV on Media Button
|
||||
description: ""
|
||||
description: "Starts or resumes office TV playback when the media button is pressed twice."
|
||||
trigger:
|
||||
- platform: event
|
||||
event_type: zha_event
|
||||
@@ -43,7 +93,7 @@ automation:
|
||||
mode: single
|
||||
- id: seek_office_tv_on_media_button
|
||||
alias: Seek Office TV on Media Button
|
||||
description: ""
|
||||
description: "Seeks office TV playback backward 30 seconds when the media button is pressed three times."
|
||||
trigger:
|
||||
- platform: event
|
||||
event_type: zha_event
|
||||
@@ -62,6 +112,8 @@ automation:
|
||||
target:
|
||||
device_id: abb6b5a6b4e4925dcb3a77ea2c293eaa
|
||||
mode: single
|
||||
|
||||
# Historical disabled MQTT and entity-state alternatives.
|
||||
# - id: "1629271273958"
|
||||
# alias: Pause office TV on MQTT
|
||||
# description: ""
|
||||
@@ -90,6 +142,7 @@ automation:
|
||||
# seek_position: 30
|
||||
# mode: single
|
||||
|
||||
# Historical disabled entity-state automation block.
|
||||
#automation:
|
||||
# - id: "1629271273952"
|
||||
# unique_id: pause_office_tv_on_media_button
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
###############################################################################
|
||||
#
|
||||
# Version:
|
||||
# 2026-07-20 v0.3
|
||||
# - Synchronized the documented Number 16 schedule with the implementation.
|
||||
#
|
||||
# 2026-05-09 v0.2
|
||||
# - Refactored scheduled control to use editable schedule lists.
|
||||
# - Switched lights now use explicit ON/OFF schedule entries instead of
|
||||
@@ -527,8 +530,8 @@ script:
|
||||
# EDIT SCHEDULE HERE
|
||||
# Format: trigger, offset_minutes/at, target_brightness, ramp_minutes
|
||||
# Current schedule:
|
||||
# - sunset -30, 80, 30
|
||||
# - 20:00, 50, 30
|
||||
# - sunset -30, 60, 30
|
||||
# - 20:00, 50, 120
|
||||
# - 01:00, 20, 120
|
||||
# - 06:00, 0, 120
|
||||
###########################################################################
|
||||
|
||||
@@ -24,3 +24,37 @@ mqtt:
|
||||
name: "Hours Since DePooped"
|
||||
state_topic: "viewroad-tele/petfeeding/hoursSinceDePooped"
|
||||
unit_of_measurement: "Hours"
|
||||
|
||||
template:
|
||||
- sensor:
|
||||
- name: "Jobs Tracker Hours Since Dog Fed"
|
||||
unique_id: "jobs_tracker_hours_since_dog_fed"
|
||||
device_class: duration
|
||||
state_class: measurement
|
||||
unit_of_measurement: "h"
|
||||
icon: "mdi:dog-side"
|
||||
availability: >-
|
||||
{{
|
||||
state_attr('sensor.jobs_tracker_dog_feeding_morning', 'hours_since_completed') is not none
|
||||
or state_attr('sensor.jobs_tracker_dog_feeding_evening', 'hours_since_completed') is not none
|
||||
}}
|
||||
state: >-
|
||||
{{
|
||||
[
|
||||
state_attr('sensor.jobs_tracker_dog_feeding_morning', 'hours_since_completed') | float(999999),
|
||||
state_attr('sensor.jobs_tracker_dog_feeding_evening', 'hours_since_completed') | float(999999)
|
||||
]
|
||||
| min
|
||||
| round(0)
|
||||
}}
|
||||
|
||||
- name: "Jobs Tracker Hours Since Dog Depooped"
|
||||
unique_id: "jobs_tracker_hours_since_dog_depooped"
|
||||
device_class: duration
|
||||
state_class: measurement
|
||||
unit_of_measurement: "h"
|
||||
icon: "mdi:emoticon-poop"
|
||||
availability: >-
|
||||
{{ state_attr('sensor.jobs_tracker_dog_depooping', 'hours_since_completed') is not none }}
|
||||
state: >-
|
||||
{{ state_attr('sensor.jobs_tracker_dog_depooping', 'hours_since_completed') | float(none) }}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
mqtt:
|
||||
sensor:
|
||||
- unique_id: dog_fed_activity
|
||||
name: "Dog Fed"
|
||||
state_topic: "viewroad-status/activityfeed/dogfed"
|
||||
icon: mdi:dog
|
||||
- unique_id: depooped_activity
|
||||
name: "DePooped"
|
||||
state_topic: "viewroad-status/activityfeed/depooped"
|
||||
icon: mdi:emoticon-poop
|
||||
- unique_id: jobs_done_activity
|
||||
name: "Jobs Done"
|
||||
state_topic: "viewroad-status/activityfeed/jobsdone"
|
||||
icon: mdi:notebook
|
||||
- unique_id: hours_since_jobs_done
|
||||
name: "Hours Since Jobs Done"
|
||||
state_topic: "viewroad-tele/petfeeding/hoursSinceJobsDone"
|
||||
unit_of_measurement: "Hours"
|
||||
- unique_id: hours_since_zorro_fed
|
||||
name: "Hours Since Zorro Fed"
|
||||
state_topic: "viewroad-tele/petfeeding/hoursSinceDogFed"
|
||||
unit_of_measurement: "Hours"
|
||||
- unique_id: hours_since_depooped
|
||||
name: "Hours Since DePooped"
|
||||
state_topic: "viewroad-tele/petfeeding/hoursSinceDePooped"
|
||||
unit_of_measurement: "Hours"
|
||||
+19
-15
@@ -5,7 +5,17 @@
|
||||
# TITLE:
|
||||
# Quiet Time
|
||||
#
|
||||
# VERSIONS:
|
||||
# FILE:
|
||||
# quiet_time.yaml
|
||||
#
|
||||
# VERSION:
|
||||
# V1.4 2026-07-20
|
||||
#
|
||||
# VERSION HISTORY:
|
||||
# V1.4 2026-07-20
|
||||
# - Updated documentation for the standalone Quiet Time actions package.
|
||||
# - Documented the current flattened MQTT status topic.
|
||||
#
|
||||
# V1.3 2026-06-07
|
||||
# - Added quiet time start and stop entity action lists.
|
||||
# - Turns the LED matrix display OFF when quiet time starts.
|
||||
@@ -13,7 +23,8 @@
|
||||
#
|
||||
# V1.2 2026-05-21
|
||||
# - Added MQTT publishing when input_boolean.quiet_time changes.
|
||||
# - Publishes quiet_time state to viewroad-status/homeassistant/quiet-time.
|
||||
# - Published quiet_time state to viewroad-status/homeassistant/quiet-time.
|
||||
# This was the historical topic; the current topic is documented below.
|
||||
#
|
||||
# V1.1 2026-05-21
|
||||
# - Reduced daily reset check frequency from every minute to every 30 minutes.
|
||||
@@ -33,20 +44,13 @@
|
||||
# will automatically be turned OFF.
|
||||
# - Default reset time is 07:00.
|
||||
# - The quiet_time state is published to MQTT whenever it changes.
|
||||
# - When quiet_time changes, editable entity lists can turn things on or off.
|
||||
# - The companion package handles local actions when quiet_time changes.
|
||||
#
|
||||
# QUIET TIME ACTION LISTS:
|
||||
# - quiet_time_start_turn_off_entities:
|
||||
# Entities to turn OFF when quiet time starts.
|
||||
#
|
||||
# - quiet_time_start_turn_on_entities:
|
||||
# Entities to turn ON when quiet time starts.
|
||||
#
|
||||
# - quiet_time_stop_turn_off_entities:
|
||||
# Entities to turn OFF when quiet time ends.
|
||||
#
|
||||
# - quiet_time_stop_turn_on_entities:
|
||||
# Entities to turn ON when quiet time ends.
|
||||
# COMPANION PACKAGE:
|
||||
# - quiet_time_on_off_actions.yaml owns the editable entity action lists and
|
||||
# other local actions that run when Quiet Time starts or ends.
|
||||
# - This package owns input_boolean.quiet_time, the daily reset behaviour,
|
||||
# and MQTT status publishing.
|
||||
#
|
||||
# MQTT STATUS:
|
||||
# - Topic:
|
||||
|
||||
@@ -1,3 +1,67 @@
|
||||
#:########################################################################################:#
|
||||
# Raspberry Pi CCTV Monitor Package #
|
||||
#:########################################################################################:#
|
||||
#
|
||||
# TITLE:
|
||||
# Raspberry Pi CCTV Monitor
|
||||
#
|
||||
# FILE:
|
||||
# packages/raspberry_pi_monitor.yaml
|
||||
#
|
||||
# VERSION:
|
||||
# V1.1 2026-07-20
|
||||
#
|
||||
# VERSION HISTORY:
|
||||
# V1.1 2026-07-20
|
||||
# - Added structured documentation for MQTT, availability, and controls.
|
||||
#
|
||||
# V1.0
|
||||
# - Initial monitoring and remote-control configuration.
|
||||
#
|
||||
# PURPOSE:
|
||||
# Monitors the cctvquad1 and cctvquad2 Raspberry Pi hosts and provides remote
|
||||
# reboot and shutdown controls through MQTT.
|
||||
#
|
||||
# EXTERNAL DEPENDENCY:
|
||||
# - Each Raspberry Pi requires an external process that publishes telemetry
|
||||
# and state, consumes command topics, and performs the requested actions.
|
||||
# - This package does not install or manage that external process.
|
||||
#
|
||||
# MQTT STATUS:
|
||||
# Topic pattern:
|
||||
# viewroad-status/rpis/<host>/<field>
|
||||
#
|
||||
# Fields:
|
||||
# cpu-temp, cpu-use, ram-use, disk-use, uptime, last-seen, ipv4-address,
|
||||
# reboot, and shutdown.
|
||||
#
|
||||
# The last-seen payload must be a timestamp that Home Assistant can parse with
|
||||
# as_timestamp().
|
||||
#
|
||||
# MQTT COMMANDS:
|
||||
# Topic pattern:
|
||||
# viewroad-commands/rpis/<host>/reboot/set
|
||||
# viewroad-commands/rpis/<host>/shutdown/set
|
||||
#
|
||||
# Commands use the default MQTT switch ON/OFF payloads, QoS 1, and are not
|
||||
# retained. The external process must publish matching switch state feedback.
|
||||
#
|
||||
# AVAILABILITY:
|
||||
# - A host is considered available when its last-seen timestamp is valid and
|
||||
# no more than 180 seconds old.
|
||||
# - The template uses now(), so Home Assistant periodically re-evaluates age.
|
||||
#
|
||||
# GROUPS:
|
||||
# - group.pi_cctvquad1_on collects Quad1 telemetry and controls.
|
||||
# - group.pi_cctvquad2_on collects Quad2 telemetry and controls.
|
||||
#
|
||||
# SAFETY:
|
||||
# - Reboot and shutdown interrupt CCTV services and host availability.
|
||||
# - Shutdown may require physical access to power the host back on.
|
||||
# - Dashboard controls should require confirmation before sending commands.
|
||||
#
|
||||
#:########################################################################################:#
|
||||
|
||||
mqtt:
|
||||
sensor:
|
||||
- unique_id: cctvquad1_cpu_temp
|
||||
|
||||
@@ -1,9 +1,55 @@
|
||||
##########################################################################################
|
||||
# MASTER BEDROOM FAN (Tasmota / Sonoff iFan02)
|
||||
# Improvements:
|
||||
# - Numeric speed entity (0-3) reflecting actual device state via MQTT
|
||||
# - Button to cycle speed 1,2,3,0
|
||||
# - Keep input_select in sync with actual FanSpeed (incl after reboots)
|
||||
# Room Fan Control
|
||||
##########################################################################################
|
||||
#
|
||||
# TITLE:
|
||||
# Room Fan Control
|
||||
#
|
||||
# FILE:
|
||||
# packages/room_fan_control.yaml
|
||||
#
|
||||
# VERSION:
|
||||
# V1.1 2026-07-20
|
||||
#
|
||||
# VERSION HISTORY:
|
||||
# V1.1 2026-07-20
|
||||
# - Added structured documentation for all three bedroom fans.
|
||||
# - Documented the master-bedroom feedback loop and command-only controls.
|
||||
#
|
||||
# V1.0
|
||||
# - Initial Tasmota and Sonoff iFan02 fan controls.
|
||||
#
|
||||
# PURPOSE:
|
||||
# Controls the master-bedroom, Bedroom 2, and Bedroom 3 ceiling-fan speeds
|
||||
# through Tasmota MQTT commands and Home Assistant dropdown helpers.
|
||||
#
|
||||
# SPEED MAPPING:
|
||||
# - 0 = Off
|
||||
# - 1 = Low
|
||||
# - 2 = Medium
|
||||
# - 3 = High
|
||||
#
|
||||
# MASTER BEDROOM:
|
||||
# - Queries FanSpeed when Home Assistant starts.
|
||||
# - Listens to Tasmota RESULT and STATE topics for device feedback.
|
||||
# - Synchronizes the numeric and dropdown helpers with actual device state.
|
||||
# - Uses optimistic local updates until MQTT feedback corrects the helpers.
|
||||
# - Provides a button that cycles through speeds 1, 2, 3, and 0.
|
||||
#
|
||||
# BEDROOMS 2 AND 3:
|
||||
# - Dropdown changes publish FanSpeed commands to each Tasmota device.
|
||||
# - These controls are command-only and do not synchronize from feedback.
|
||||
# - Their displayed dropdown state may not reflect physical or external changes.
|
||||
#
|
||||
# MQTT COMMAND TOPICS:
|
||||
# - Master bedroom: cmnd/tasmo-ifan02-3793-bedrm1-1/FanSpeed
|
||||
# - Bedroom 2: cmnd/tasmo-ifan02-7042-bedrm2/FanSpeed
|
||||
# - Bedroom 3: cmnd/tasmo-ifan02-3497-bedrm3/FanSpeed
|
||||
#
|
||||
# DEPENDENCIES:
|
||||
# - The three Tasmota devices must accept FanSpeed values from 0 through 3.
|
||||
# - Master-bedroom feedback uses its RESULT and STATE MQTT topics.
|
||||
#
|
||||
##########################################################################################
|
||||
|
||||
input_select:
|
||||
@@ -75,6 +121,7 @@ automation:
|
||||
- id: master_bedroom_fan_query_on_ha_start
|
||||
initial_state: true
|
||||
alias: Master Bedroom Fan - Query FanSpeed on HA Start
|
||||
description: "Requests the current master-bedroom FanSpeed when Home Assistant starts."
|
||||
trigger:
|
||||
- platform: homeassistant
|
||||
event: start
|
||||
@@ -90,6 +137,7 @@ automation:
|
||||
- id: master_bedroom_fan_sync_from_mqtt
|
||||
initial_state: true
|
||||
alias: Master Bedroom Fan - Sync Helpers From MQTT FanSpeed
|
||||
description: "Synchronizes the master-bedroom fan helpers from Tasmota MQTT feedback."
|
||||
trigger:
|
||||
- platform: mqtt
|
||||
topic: stat/tasmo-ifan02-3793-bedrm1-1/RESULT
|
||||
@@ -122,6 +170,7 @@ automation:
|
||||
- id: set_the_master_bedroom_fan
|
||||
initial_state: true
|
||||
alias: Set the Master Bedroom Fan
|
||||
description: "Publishes master-bedroom fan speed changes and updates the numeric helper optimistically."
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id: input_select.master_bedroom_fan_set
|
||||
@@ -145,11 +194,12 @@ automation:
|
||||
value: "{{ desired }}"
|
||||
|
||||
########################################################################################
|
||||
# BEDROOM 2 FAN - Unchanged
|
||||
# BEDROOM 2 FAN - Command Only
|
||||
########################################################################################
|
||||
- id: set_bedroom_2_fan
|
||||
initial_state: true
|
||||
alias: Set Bedroom 2 Fan Speed
|
||||
description: "Publishes Bedroom 2 fan speed dropdown changes to Tasmota."
|
||||
trigger:
|
||||
entity_id: input_select.bedroom_2_fan_set
|
||||
platform: state
|
||||
@@ -163,11 +213,12 @@ automation:
|
||||
'
|
||||
|
||||
########################################################################################
|
||||
# BEDROOM 3 FAN - Unchanged
|
||||
# BEDROOM 3 FAN - Command Only
|
||||
########################################################################################
|
||||
- id: set_bedroom_3_fan
|
||||
initial_state: true
|
||||
alias: Set Bedroom 3 Fan Speed
|
||||
description: "Publishes Bedroom 3 fan speed dropdown changes to Tasmota."
|
||||
trigger:
|
||||
entity_id: input_select.bedroom_3_fan_set
|
||||
platform: state
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
input_boolean:
|
||||
quiet_time:
|
||||
name: Quiet time for no notifications
|
||||
icon: mdi:shield-moon
|
||||
# Legacy duplicate retained temporarily for verification.
|
||||
# quiet_time:
|
||||
# name: Quiet time for no notifications
|
||||
# icon: mdi:shield-moon
|
||||
away_occupied_routine:
|
||||
name: Automation for Lights etc when away
|
||||
icon: mdi:shield-lock
|
||||
|
||||
@@ -1,3 +1,52 @@
|
||||
#:########################################################################################:#
|
||||
# Main Bathroom Shower Detection Package #
|
||||
#:########################################################################################:#
|
||||
#
|
||||
# TITLE:
|
||||
# Main Bathroom Shower Detection
|
||||
#
|
||||
# FILE:
|
||||
# packages/shower_controls.yaml
|
||||
#
|
||||
# VERSION:
|
||||
# V1.1 2026-07-20
|
||||
#
|
||||
# VERSION HISTORY:
|
||||
# V1.1 2026-07-20
|
||||
# - Added structured documentation and automation descriptions.
|
||||
# - Documented current indicator-only usage.
|
||||
#
|
||||
# V1.0
|
||||
# - Initial humidity-rate shower detection.
|
||||
#
|
||||
# PURPOSE:
|
||||
# Detects shower use from the main-bathroom humidity level and its rate of
|
||||
# change, then maintains input_boolean.main_bathroom_shower as an indicator.
|
||||
#
|
||||
# DEPENDENCY:
|
||||
# sensor.main_bathroom_environment_zth10_humidity_2 provides humidity in %.
|
||||
#
|
||||
# DERIVATIVE SENSOR:
|
||||
# - Calculates humidity change in % per minute over a 15-minute time window.
|
||||
# - Rounds the result to 0.1.
|
||||
#
|
||||
# DETECTION:
|
||||
# - Humidity change must remain above 0.6 %/min for five minutes.
|
||||
# - Current humidity must also be above 63%.
|
||||
#
|
||||
# CLEARING:
|
||||
# - Humidity change must remain below 0.2 %/min for 15 minutes.
|
||||
# - No absolute-humidity condition is required to clear the indicator.
|
||||
# - The gap between activation and clearing thresholds provides hysteresis
|
||||
# and prevents rapid toggling near one threshold.
|
||||
#
|
||||
# CURRENT USE:
|
||||
# - The package only maintains input_boolean.main_bathroom_shower.
|
||||
# - No other user-YAML automation, script, or package currently consumes it.
|
||||
# - This package does not directly control a bathroom fan or other device.
|
||||
#
|
||||
#:########################################################################################:#
|
||||
|
||||
input_boolean:
|
||||
main_bathroom_shower:
|
||||
name: Main Bathroom Shower
|
||||
@@ -14,6 +63,7 @@ sensor:
|
||||
automation:
|
||||
- id: main_bathroom_shower_detected
|
||||
alias: Main Bathroom - Shower detected (humidity rate + min humidity)
|
||||
description: "Turns on the shower indicator after a sustained humidity rise above the minimum humidity."
|
||||
mode: single
|
||||
trigger:
|
||||
- platform: numeric_state
|
||||
@@ -31,6 +81,7 @@ automation:
|
||||
|
||||
- id: main_bathroom_shower_cleared
|
||||
alias: Main Bathroom - Shower cleared (humidity rate)
|
||||
description: "Turns off the shower indicator after the humidity change rate remains low for 15 minutes."
|
||||
mode: single
|
||||
trigger:
|
||||
- platform: numeric_state
|
||||
|
||||
@@ -1,8 +1,61 @@
|
||||
#:########################################################################################:#
|
||||
# Auckland Council Waste Collection Package #
|
||||
#:########################################################################################:#
|
||||
#
|
||||
# TITLE:
|
||||
# Auckland Council Waste Collection
|
||||
#
|
||||
# FILE:
|
||||
# packages/waste_collection.yaml
|
||||
#
|
||||
# VERSION:
|
||||
# V1.1 2026-07-20
|
||||
#
|
||||
# VERSION HISTORY:
|
||||
# V1.1 2026-07-20
|
||||
# - Added source setup, schedule, MQTT, and maintenance documentation.
|
||||
#
|
||||
# V1.0
|
||||
# - Initial Auckland Council schedules and MQTT bin-status sensors.
|
||||
#
|
||||
# PURPOSE:
|
||||
# Provides Auckland Council rubbish, recycling, and food-waste collection
|
||||
# schedules, plus independent MQTT sensors indicating whether bins are out.
|
||||
#
|
||||
# DEPENDENCY:
|
||||
# Requires the Waste Collection Schedule custom integration and its
|
||||
# aucklandcouncil_govt_nz source.
|
||||
#
|
||||
# AREA NUMBER SETUP:
|
||||
# - Open the Auckland Council rubbish and recycling collection-day finder.
|
||||
# - Select the property address.
|
||||
# - Use the displayed assessment number as area_number below.
|
||||
# - Source documentation:
|
||||
# https://github.com/mampfes/hacs_waste_collection_schedule/blob/master/doc/source/aucklandcouncil_govt_nz.md
|
||||
#
|
||||
# SCHEDULE SENSORS:
|
||||
# - Types are rubbish, recycle, and food-waste.
|
||||
# - Each sensor returns one upcoming collection with a one-day lead time.
|
||||
# - details_format is upcoming and add_days_to adds relative-day text.
|
||||
#
|
||||
# MQTT BIN-OUT SENSORS:
|
||||
# - These sensors are independent of the council collection schedules.
|
||||
# - An external publisher must send status to the configured MQTT topics.
|
||||
# - Payloads remain raw sensor strings such as "true"; these are not binary
|
||||
# sensor entities and no boolean conversion is performed here.
|
||||
#
|
||||
# CURRENT STATUS:
|
||||
# - As of 2026-07-20, the rubbish schedule resolves correctly.
|
||||
# - Recycling and food-waste report unknown; review the source type names when
|
||||
# investigating those schedules.
|
||||
#
|
||||
#:########################################################################################:#
|
||||
|
||||
waste_collection_schedule:
|
||||
sources:
|
||||
- name: aucklandcouncil_govt_nz
|
||||
args:
|
||||
area_number: 12344403722 # see 'How to get the source argument below'
|
||||
area_number: 12344403722 # Auckland Council assessment number.
|
||||
|
||||
sensor:
|
||||
- platform: waste_collection_schedule
|
||||
|
||||
Reference in New Issue
Block a user