Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
- id: bedroom_ac_adaptive_fan_speed
alias: Bedroom AC - Adaptive Fan Speed
description: >
Automatically adjusts bedroom AC fan speed based on how quickly the room's
temperature distance to target is shrinking.
mode: single
Comment on lines +1 to +6

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for definitions of the required helper entities in the repository
echo "=== Searching for input_datetime.bedroom_ac_fan_last_adjusted ==="
rg -n "bedroom_ac_fan_last_adjusted" --type yaml --type nix

echo "=== Searching for input_number.target_temperature ==="
rg -n "target_temperature" --type yaml --type nix

echo "=== Searching for bedroom_ac_distance_change sensors ==="
rg -n "bedroom_ac_distance_change" --type yaml --type nix

Repository: DaRacci/nix-config

Length of output: 1493


🏁 Script executed:

# Check the directory structure and list files in the home-assistant configuration
find hosts/server/nixcloud/home-assistant -type f -name "*.yaml" -o -name "*.yml" | head -20

Repository: DaRacci/nix-config

Length of output: 195


🏁 Script executed:

# Search more broadly for helper entity definitions
# Look for 'input_datetime' or 'input_number' definitions (not just references)
rg -n "input_datetime|input_number" --type yaml | grep -E "(input_datetime|input_number):" | head -20

Repository: DaRacci/nix-config

Length of output: 44


🏁 Script executed:

# Check if there's a helpers.yaml or automations index file
find hosts/server/nixcloud -type f \( -name "*helper*" -o -name "*input*" \)

Repository: DaRacci/nix-config

Length of output: 44


🏁 Script executed:

# Verify the repository structure matches the guideline
# Check if the file path follows the pattern: hosts/server/<hostname>/
ls -la hosts/server/ 2>/dev/null || echo "hosts/server/ not found"

Repository: DaRacci/nix-config

Length of output: 694


Automation depends on several helper entities that must be defined separately.

This automation references helper entities that are not defined in the repository:

  • input_datetime.bedroom_ac_fan_last_adjusted (cooldown tracking)
  • input_number.target_temperature (target temperature setting)
  • sensor.bedroom_ac_distance_change_5m, sensor.bedroom_ac_distance_change_10m, sensor.bedroom_ac_distance_change_15m (statistics sensors)

Ensure these entities are configured in Home Assistant or the automation will fail silently with default/zero values.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@hosts/server/nixcloud/home-assistant/automations/bedroom_ac_adaptive_fan_speed.yaml`
around lines 1 - 6, The automation references missing helper entities so it will
behave incorrectly; add and configure the required helpers: create an
input_datetime named input_datetime.bedroom_ac_fan_last_adjusted for cooldown
tracking, create an input_number named input_number.target_temperature with
appropriate min/max/step and units for the desired target, and define the three
sensors sensor.bedroom_ac_distance_change_5m,
sensor.bedroom_ac_distance_change_10m, and sensor.bedroom_ac_distance_change_15m
(e.g. as template or statistics sensors) so they report the distance-change
values used by the automation; ensure each entity ID exactly matches the names
used in the automation and set sensible initial values/units to avoid
zero/default behavior.


trigger:
- platform: time_pattern
minutes: "/5"
- platform: state
entity_id: sensor.bedroom_ac_temperature
- platform: state
entity_id: climate.bedroom_ac
attribute: current_temperature

condition:
# Only run while the AC is actively heating or cooling.
- condition: template
value_template: "{{ states('climate.bedroom_ac') in ['cool', 'heat'] }}"

# Cooldown: if this automation changed fan speed in the last 5 minutes, stop.
- condition: template
value_template: >
{% set ts = as_timestamp(states('input_datetime.bedroom_ac_fan_last_adjusted')) %}
{{ ts is none or (as_timestamp(now()) - ts) >= 300 }}

action:
- variables:
current_temp: "{{ state_attr('climate.bedroom_ac', 'current_temperature') | float(0) }}"
target_temp: "{{ states('input_number.target_temperature') | float(0) }}"
current_distance: "{{ (current_temp - target_temp) | abs }}"

elapsed_minutes: >
{% set ts = as_timestamp(states('input_datetime.bedroom_ac_fan_last_adjusted')) %}
{% if ts is none %}
15
{% else %}
{{ ((as_timestamp(now()) - ts) / 60) | float(0) }}
{% endif %}

# Use the shorter window: time since last fan adjustment or 15 minutes.
# Implemented as 5/10/15 minute buckets (automation cadence is 5 minutes).
window_minutes: >
{% set e = elapsed_minutes | float(15) %}
{% if e < 10 %}
5
{% elif e < 15 %}
10
{% else %}
15
{% endif %}

selected_change_sensor: >
{% if (window_minutes | int) == 5 %}
sensor.bedroom_ac_distance_change_5m
{% elif (window_minutes | int) == 10 %}
sensor.bedroom_ac_distance_change_10m
{% else %}
sensor.bedroom_ac_distance_change_15m
{% endif %}

# Statistics change sensor is newest - oldest.
# If distance to target is reducing, this value is negative.
distance_change: "{{ states(selected_change_sensor) | float(0) }}"
distance_reduced_by: "{{ (0 - distance_change) | float(0) }}"
Comment on lines +54 to +66

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Potential division by zero when calculating progress bar percentage.

In the distance_change calculation on line 65-66, if the statistics sensor returns an unexpected value or the sensor is unavailable, the float conversion defaults to 0. While this won't cause a runtime error, it may lead to unexpected fan adjustments. Consider adding a condition to skip adjustment when distance_change is 0 (no data).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@hosts/server/nixcloud/home-assistant/automations/bedroom_ac_adaptive_fan_speed.yaml`
around lines 54 - 66, The template for selected_change_sensor/distance_change
may yield 0 when the sensor is missing or returns non-numeric, leading to
spurious fan adjustments; update the template logic around
selected_change_sensor, distance_change, and distance_reduced_by to first detect
unavailable/unknown states (or non-numeric values) and short-circuit the
automation (skip adjustment) when distance_change is zero or not a valid number;
specifically, add a guard check that ensures selected_change_sensor's state is
numeric and non-zero before computing distance_reduced_by or proceeding with
fan-speed calculations in the automation that uses distance_change and
distance_reduced_by.


fan_modes:
- quiet
- low
- medium_low
- medium
- medium_high
- high

current_fan_mode: "{{ state_attr('climate.bedroom_ac', 'fan_mode') | default('medium', true) }}"
current_index: >
{% if current_fan_mode in fan_modes %}
{{ fan_modes.index(current_fan_mode) }}
{% else %}
{{ fan_modes.index('medium') }}
{% endif %}

increase_fan_mode: >
{% if (current_index | int) < (fan_modes | count - 1) %}
{{ fan_modes[current_index | int + 1] }}
{% else %}
{{ current_fan_mode }}
{% endif %}

decrease_fan_mode: >
{% if (current_index | int) > 0 %}
{{ fan_modes[current_index | int - 1] }}
{% else %}
{{ current_fan_mode }}
{% endif %}

- choose:
# If we're reducing distance fast (>0.4) and we're already close (<2.0), reduce fan speed.
- conditions:
- condition: template
value_template: "{{ distance_reduced_by > 0.4 and current_distance < 2 }}"
- condition: template
value_template: "{{ decrease_fan_mode != current_fan_mode }}"
sequence:
- service: climate.set_fan_mode
target:
entity_id: climate.bedroom_ac
data:
fan_mode: "{{ decrease_fan_mode }}"
- service: input_datetime.set_datetime
target:
entity_id: input_datetime.bedroom_ac_fan_last_adjusted
data:
datetime: "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"

# If distance has not reduced by at least 0.2, increase fan speed.
- conditions:
- condition: template
value_template: "{{ distance_reduced_by < 0.2 }}"
- condition: template
value_template: "{{ increase_fan_mode != current_fan_mode }}"
sequence:
- service: climate.set_fan_mode
target:
entity_id: climate.bedroom_ac
data:
fan_mode: "{{ increase_fan_mode }}"
- service: input_datetime.set_datetime
target:
entity_id: input_datetime.bedroom_ac_fan_last_adjusted
data:
datetime: "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"
2 changes: 1 addition & 1 deletion hosts/server/nixcloud/home-assistant/dashboard.nix
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@
];

lovelace = {
mode = "yaml";
resource_mode = "yaml";
resources = [
{
url = "/local/nixos-lovelace-modules/bubble-pop-up-fix.js";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
{ lib }:
let
dashLib = import ../lib.nix { inherit lib; };
inherit (dashLib) entities ids;
in
{
type = "vertical-stack";
cards = [
Expand All @@ -13,11 +18,11 @@
badges = [
{
type = "entity";
entity = "switch.adguard_home_protection";
entity = entities.adguardProtection;
}
{
type = "entity";
entity = "sensor.adguard_home_average_processing_speed";
entity = entities.adguardSpeed;
}
];
}
Expand All @@ -30,10 +35,10 @@
conditions = [ ];
card = {
type = "custom:button-card";
entity = "sensor.uptimekuma_uptime_racci_dev";
entity = entities.sensors.uptimekuma;
icon = "mdi:devices";
name = "Monitored";
label = "[[[return states[\"sensor.uptimekuma_uptime_racci_dev\"].attributes.monitored]]]";
label = "[[[return states[\"${entities.sensors.uptimekuma}\"].attributes.monitored]]]";
template = "nav_button_state_small";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Template nav_button_state_small may be missing from button_card_templates.

This card references template = "nav_button_state_small" (line 42) and template = "nav_button_small" (line 61), but the current button-cards/default.nix only exports media-player. These templates need to be added to the button-cards export.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@hosts/server/nixcloud/home-assistant/dashboard/components/admin-panel.nix` at
line 42, The dashboard admin-panel references templates "nav_button_state_small"
and "nav_button_small" but button-cards/default.nix currently only exports
"media-player"; update button-cards/default.nix to export both
"nav_button_state_small" and "nav_button_small" (and ensure their template
definitions exist in the button card templates file), so the templates used by
admin-panel.nix are available at import time.

variables = {
navigation_path = "server#monitored";
Expand All @@ -49,10 +54,10 @@
conditions = [ ];
card = {
type = "custom:button-card";
entity = "sensor.uptimekuma_uptime_racci_dev";
entity = entities.sensors.uptimekuma;
icon = "mdi:sort-clock-descending-outline";
name = "Uptime Kuma";
label = "[[[return states[\"sensor.uptimekuma_uptime_racci_dev\"].attributes.monitors]]]";
label = "[[[return states[\"${entities.sensors.uptimekuma}\"].attributes.monitors]]]";
template = "nav_button_small";
variables = {
navigation_path = "#uptime";
Expand All @@ -71,7 +76,7 @@
{
condition = "user";
users = [
"3eea636aa3de4c7f9c662ad29c6e92e0"
ids.james
"c82f30a396fb42a9a10514fd63d5aac7"
];
}
Expand Down
Loading
Loading