blueprint: name: UPS Monitor via NUT - Status, Battery, Optional Self-Test, Optional Load (Debounced) [TEST] description: > TEST BRANCH: Adds optional UPS load monitoring to the existing UPS Monitor via NUT blueprint. Monitors a UPS exposed via the NUT integration and sends debounced notifications when: - Status code changes (status_data) - Battery charge drops by a configured step (e.g., every 10%) - Self-test result is not "Done and passed" (optional input) - UPS load stays above a configured threshold for a configured period (optional input) Debounce is useful when the NUT server briefly flaps unavailable/available. domain: automation input: battery_charge: name: Battery Charge Sensor description: Sensor showing UPS battery charge percentage (e.g. sensor.ups_battery_charge). selector: entity: domain: sensor integration: nut battery_voltage: name: Battery Voltage Sensor description: Sensor showing UPS battery voltage (e.g. sensor.ups_battery_voltage). selector: entity: domain: sensor integration: nut ups_status_data: name: UPS Status Code Sensor (e.g., OL, OB) description: > Sensor with compact status codes like OL (online), OB (on battery), LB (low battery). Typically sensor.nutdev1_status_data. Used for automation logic. selector: entity: domain: sensor integration: nut ups_status: name: UPS Human-Readable Status Sensor description: > Sensor with full text status like "Online", "On Battery". Typically sensor.nutdev1_status. Used for notifications. selector: entity: domain: sensor integration: nut enable_self_test_check: name: Enable self-test monitoring? description: Enable self-test monitoring (requires self-test entity to be selected). default: false selector: boolean: self_test_result_entity: name: Self-test Result Sensor (Optional) description: > Optional. If your UPS/NUT setup exposes a self-test result sensor, select it here. If you don't have one, leave it empty. default: [] selector: entity: domain: sensor integration: nut multiple: false report_interval: name: Battery Drop Notification Interval description: Notify when battery charge drops by this percentage step (e.g., every 10%). default: 10 selector: number: min: 1 max: 50 step: 1 mode: slider delay_seconds: name: Debounce for status/self-test notifications (seconds) description: > Require the new status/self-test value to stay stable for this many seconds before notifying. Useful for flaky NUT servers that flap unavailable briefly. default: 15 selector: number: min: 0 max: 600 step: 1 unit_of_measurement: s mode: slider battery_delay_seconds: name: Debounce for battery charge notifications (seconds) description: > Optional additional delay before sending a battery charge step notification. Default 0 (no delay). Increase if your battery charge sensor jumps around. default: 0 selector: number: min: 0 max: 600 step: 1 unit_of_measurement: s mode: slider enable_load_check: name: Enable UPS load monitoring? description: > Enable to get an alert if UPS load stays above the threshold for the debounce period. Requires a load sensor to be selected. Default is off for safe testing. default: false selector: boolean: load_sensor: name: UPS Load Sensor (Optional) description: > Select the UPS load sensor (percentage). Typical entity: sensor._load. Leave empty if your setup does not expose load. default: [] selector: entity: domain: sensor integration: nut multiple: false load_threshold: name: Load Threshold (%) description: Notify when UPS load is above this percentage for the debounce period. default: 50 selector: number: min: 1 max: 100 step: 1 unit_of_measurement: "%" mode: slider load_debounce_seconds: name: Debounce for load notifications (seconds) description: Load must stay above the threshold for this long before notifying. default: 10 selector: number: min: 0 max: 600 step: 1 unit_of_measurement: s mode: slider notify_device: name: Notification Device description: Select your mobile device for push notifications (mobile_app integration). selector: device: filter: integration: mobile_app multiple: false message_prefix: name: Notification Message Prefix description: Prepended to all messages (optional). default: "UPS Monitor:" selector: text: trigger: - id: status_change platform: state entity_id: !input ups_status_data for: seconds: !input delay_seconds - id: battery_change platform: state entity_id: !input battery_charge - id: self_test_change platform: state entity_id: !input self_test_result_entity for: seconds: !input delay_seconds # Load alert: fires only if load stays above threshold for debounce period - id: load_high platform: numeric_state entity_id: !input load_sensor above: !input load_threshold for: seconds: !input load_debounce_seconds variables: battery_charge_entity: !input battery_charge battery_voltage_entity: !input battery_voltage ups_status_data_entity: !input ups_status_data ups_status_readable_entity: !input ups_status enable_self_test_check: !input enable_self_test_check self_test_list: !input self_test_result_entity self_test_entity: "{{ (self_test_list | first) if (self_test_list | length > 0) else '' }}" report_interval: !input report_interval battery_delay_seconds: !input battery_delay_seconds enable_load_check: !input enable_load_check load_list: !input load_sensor load_entity: "{{ (load_list | first) if (load_list | length > 0) else '' }}" load_threshold: !input load_threshold message_prefix: !input message_prefix current_charge: "{{ states(battery_charge_entity) | int(default=100) }}" charge_mod: "{{ current_charge % report_interval }}" battery_voltage_val: "{{ states(battery_voltage_entity) | float(default=0) }}" status_readable: "{{ states(ups_status_readable_entity) }}" test_result: "{{ states(self_test_entity) if self_test_entity != '' else '' }}" current_load: "{{ states(load_entity) | float(default=0) if load_entity != '' else 0 }}" condition: - condition: or conditions: - condition: template value_template: "{{ trigger.id == 'status_change' }}" - condition: template value_template: > {{ trigger.id == 'battery_change' and current_charge < 100 and charge_mod == 0 }} - condition: template value_template: > {{ trigger.id == 'self_test_change' and enable_self_test_check and self_test_entity != '' and test_result != 'Done and passed' }} - condition: template value_template: > {{ trigger.id == 'load_high' and enable_load_check and load_entity != '' }} action: - choose: - conditions: - condition: template value_template: "{{ trigger.id == 'battery_change' and (battery_delay_seconds | int) > 0 }}" sequence: - delay: seconds: !input battery_delay_seconds - variables: notify_message: > {% if trigger.id == 'status_change' %} {{ message_prefix }} UPS status changed: {{ status_readable }} {% elif trigger.id == 'battery_change' %} {{ message_prefix }} Battery at {{ current_charge }}%. Voltage: {{ battery_voltage_val }} V {% elif trigger.id == 'self_test_change' %} {{ message_prefix }} Self-test result: {{ test_result }} {% elif trigger.id == 'load_high' %} {{ message_prefix }} UPS load high: {{ current_load }}% (threshold: {{ load_threshold }}%) {% else %} {{ message_prefix }} UPS alert triggered. {% endif %} - domain: mobile_app type: notify device_id: !input notify_device message: "{{ notify_message }}" mode: queued max: 10