Add CO2 alert blueprint
This commit is contained in:
@@ -0,0 +1,397 @@
|
|||||||
|
blueprint:
|
||||||
|
name: CO₂ ventilation alert – Apollo R PRO-1 (LED + buzzer)
|
||||||
|
description: >-
|
||||||
|
Visual and audible CO₂ alerts on an Apollo R PRO-1.
|
||||||
|
|
||||||
|
|
||||||
|
**LED**: off below the "ventilation recommended" level. From that level
|
||||||
|
it turns yellow and fades towards red as CO₂ approaches the "ventilation
|
||||||
|
needed" level; at or above it, it is solid red.
|
||||||
|
|
||||||
|
|
||||||
|
**Buzzer**: at or above the "start beeping" level the beep action is
|
||||||
|
repeated at the chosen interval, but only while CO₂ is NOT dropping.
|
||||||
|
"Dropping" means the newest CO₂ reading is lower than the reading about
|
||||||
|
one minute earlier (taken from a Statistics helper, see the
|
||||||
|
"CO₂ change" input). Beeping stops as soon as CO₂ is falling, at any level.
|
||||||
|
domain: automation
|
||||||
|
input:
|
||||||
|
co2_sensor:
|
||||||
|
name: CO₂ sensor
|
||||||
|
description: The R PRO-1 CO₂ sensor (ppm).
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
filter:
|
||||||
|
- domain: sensor
|
||||||
|
device_class: carbon_dioxide
|
||||||
|
change_sensor:
|
||||||
|
name: CO₂ change over the last minute
|
||||||
|
description: >-
|
||||||
|
A Statistics helper based on the CO₂ sensor above. Settings: State
|
||||||
|
characteristic = "Change", Max age = 1 minute (use 90 s if your
|
||||||
|
sensor reports slower than every ~20 s). Its state is newest reading
|
||||||
|
minus oldest reading in the window, so a negative value means CO₂ is
|
||||||
|
dropping.
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
filter:
|
||||||
|
- domain: sensor
|
||||||
|
led:
|
||||||
|
name: R PRO-1 RGB LED
|
||||||
|
description: The light entity of the R PRO-1 RGB LED.
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
filter:
|
||||||
|
- domain: light
|
||||||
|
beep_action:
|
||||||
|
name: Beep action
|
||||||
|
description: >-
|
||||||
|
Action(s) that make the R PRO-1 beep. Use the ESPHome action of your
|
||||||
|
device, for example `esphome.<your_device>_play_buzzer` with data
|
||||||
|
`song_str: "co2:d=8,o=6,b=180:c,p,c"`. Keep the tune short, it is
|
||||||
|
repeated at the beep interval.
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
recommended_level:
|
||||||
|
name: Ventilation recommended (ppm)
|
||||||
|
description: LED turns on (yellow) at this level.
|
||||||
|
default: 1000
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 400
|
||||||
|
max: 5000
|
||||||
|
step: 50
|
||||||
|
unit_of_measurement: ppm
|
||||||
|
mode: box
|
||||||
|
needed_level:
|
||||||
|
name: Ventilation needed (ppm)
|
||||||
|
description: LED is fully red at this level.
|
||||||
|
default: 1500
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 400
|
||||||
|
max: 5000
|
||||||
|
step: 50
|
||||||
|
unit_of_measurement: ppm
|
||||||
|
mode: box
|
||||||
|
beep_level:
|
||||||
|
name: Start beeping (ppm)
|
||||||
|
description: Beeping starts at this level (unless CO₂ is dropping).
|
||||||
|
default: 2000
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 400
|
||||||
|
max: 10000
|
||||||
|
step: 50
|
||||||
|
unit_of_measurement: ppm
|
||||||
|
mode: box
|
||||||
|
min_drop:
|
||||||
|
name: Minimum drop to count as "dropping" (ppm)
|
||||||
|
description: >-
|
||||||
|
0 = any decrease stops the beeping. Raise to 5–10 if sensor jitter
|
||||||
|
makes the beeping stop and start at a plateau.
|
||||||
|
default: 0
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 0
|
||||||
|
max: 100
|
||||||
|
step: 1
|
||||||
|
unit_of_measurement: ppm
|
||||||
|
mode: box
|
||||||
|
beep_interval:
|
||||||
|
name: Beep repeat interval
|
||||||
|
default: "/30"
|
||||||
|
selector:
|
||||||
|
select:
|
||||||
|
options:
|
||||||
|
- label: Every 10 seconds
|
||||||
|
value: "/10"
|
||||||
|
- label: Every 15 seconds
|
||||||
|
value: "/15"
|
||||||
|
- label: Every 20 seconds
|
||||||
|
value: "/20"
|
||||||
|
- label: Every 30 seconds
|
||||||
|
value: "/30"
|
||||||
|
brightness:
|
||||||
|
name: LED brightness (%)
|
||||||
|
default: 60
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 1
|
||||||
|
max: 100
|
||||||
|
step: 1
|
||||||
|
unit_of_measurement: "%"
|
||||||
|
mode: slider
|
||||||
|
led_off_when_ok:
|
||||||
|
name: Turn LED off below "recommended"
|
||||||
|
description: >-
|
||||||
|
If enabled, the LED is switched off when CO₂ is below the
|
||||||
|
recommended level. Disable if you use the LED for other things.
|
||||||
|
default: true
|
||||||
|
selector:
|
||||||
|
boolean: {}
|
||||||
|
|
||||||
|
mode: queued
|
||||||
|
max: 10
|
||||||
|
max_exceeded: silent
|
||||||
|
|
||||||
|
variables:
|
||||||
|
co2_sensor: !input co2_sensor
|
||||||
|
change_sensor: !input change_sensor
|
||||||
|
rec_level: !input recommended_level
|
||||||
|
need_level: !input needed_level
|
||||||
|
beep_level: !input beep_level
|
||||||
|
min_drop: !input min_drop
|
||||||
|
led_brightness: !input brightness
|
||||||
|
led_off_when_ok: !input led_off_when_ok
|
||||||
|
|
||||||
|
triggers:
|
||||||
|
- trigger: state
|
||||||
|
entity_id: !input co2_sensor
|
||||||
|
id: reading
|
||||||
|
- trigger: time_pattern
|
||||||
|
seconds: !input beep_interval
|
||||||
|
id: beep_tick
|
||||||
|
|
||||||
|
actions:
|
||||||
|
- variables:
|
||||||
|
co2: "{{ states(co2_sensor) | float(none) }}"
|
||||||
|
change: "{{ states(change_sensor) | float(0) }}"
|
||||||
|
dropping: "{{ change < -(min_drop | float(0)) }}"
|
||||||
|
span: "{{ [need_level - rec_level, 1] | max }}"
|
||||||
|
frac: >-
|
||||||
|
{{ ([[(co2 - rec_level) / span, 0] | max, 1] | min)
|
||||||
|
if co2 is not none else 0 }}
|
||||||
|
hue: "{{ (60 * (1 - frac)) | round(0) | int }}"
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ co2 is not none }}"
|
||||||
|
- choose:
|
||||||
|
# --- LED: update on every new CO2 reading -------------------------
|
||||||
|
- conditions:
|
||||||
|
- condition: trigger
|
||||||
|
id: reading
|
||||||
|
sequence:
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ co2 >= rec_level }}"
|
||||||
|
sequence:
|
||||||
|
- action: light.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: !input led
|
||||||
|
data:
|
||||||
|
hs_color: "{{ [hue, 100] }}"
|
||||||
|
brightness_pct: "{{ led_brightness | int }}"
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ led_off_when_ok }}"
|
||||||
|
sequence:
|
||||||
|
- action: light.turn_off
|
||||||
|
target:
|
||||||
|
entity_id: !input led
|
||||||
|
# --- Buzzer: repeat while high AND not dropping -------------------
|
||||||
|
- conditions:
|
||||||
|
- condition: trigger
|
||||||
|
id: beep_tick
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ co2 >= beep_level and not dropping }}"
|
||||||
|
sequence: !input beep_actionblueprint:
|
||||||
|
name: CO₂ ventilation alert – Apollo R PRO-1 (LED + buzzer)
|
||||||
|
description: >-
|
||||||
|
Visual and audible CO₂ alerts on an Apollo R PRO-1.
|
||||||
|
|
||||||
|
|
||||||
|
**LED**: off below the "ventilation recommended" level. From that level
|
||||||
|
it turns yellow and fades towards red as CO₂ approaches the "ventilation
|
||||||
|
needed" level; at or above it, it is solid red.
|
||||||
|
|
||||||
|
|
||||||
|
**Buzzer**: at or above the "start beeping" level the beep action is
|
||||||
|
repeated at the chosen interval, but only while CO₂ is NOT dropping.
|
||||||
|
"Dropping" means the newest CO₂ reading is lower than the reading about
|
||||||
|
one minute earlier (taken from a Statistics helper, see the
|
||||||
|
"CO₂ change" input). Beeping stops as soon as CO₂ is falling, at any level.
|
||||||
|
domain: automation
|
||||||
|
input:
|
||||||
|
co2_sensor:
|
||||||
|
name: CO₂ sensor
|
||||||
|
description: The R PRO-1 CO₂ sensor (ppm).
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
filter:
|
||||||
|
- domain: sensor
|
||||||
|
device_class: carbon_dioxide
|
||||||
|
change_sensor:
|
||||||
|
name: CO₂ change over the last minute
|
||||||
|
description: >-
|
||||||
|
A Statistics helper based on the CO₂ sensor above. Settings: State
|
||||||
|
characteristic = "Change", Max age = 1 minute (use 90 s if your
|
||||||
|
sensor reports slower than every ~20 s). Its state is newest reading
|
||||||
|
minus oldest reading in the window, so a negative value means CO₂ is
|
||||||
|
dropping.
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
filter:
|
||||||
|
- domain: sensor
|
||||||
|
led:
|
||||||
|
name: R PRO-1 RGB LED
|
||||||
|
description: The light entity of the R PRO-1 RGB LED.
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
filter:
|
||||||
|
- domain: light
|
||||||
|
beep_action:
|
||||||
|
name: Beep action
|
||||||
|
description: >-
|
||||||
|
Action(s) that make the R PRO-1 beep. Use the ESPHome action of your
|
||||||
|
device, for example `esphome.<your_device>_play_buzzer` with data
|
||||||
|
`song_str: "co2:d=8,o=6,b=180:c,p,c"`. Keep the tune short, it is
|
||||||
|
repeated at the beep interval.
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
recommended_level:
|
||||||
|
name: Ventilation recommended (ppm)
|
||||||
|
description: LED turns on (yellow) at this level.
|
||||||
|
default: 1000
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 400
|
||||||
|
max: 5000
|
||||||
|
step: 50
|
||||||
|
unit_of_measurement: ppm
|
||||||
|
mode: box
|
||||||
|
needed_level:
|
||||||
|
name: Ventilation needed (ppm)
|
||||||
|
description: LED is fully red at this level.
|
||||||
|
default: 1500
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 400
|
||||||
|
max: 5000
|
||||||
|
step: 50
|
||||||
|
unit_of_measurement: ppm
|
||||||
|
mode: box
|
||||||
|
beep_level:
|
||||||
|
name: Start beeping (ppm)
|
||||||
|
description: Beeping starts at this level (unless CO₂ is dropping).
|
||||||
|
default: 2000
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 400
|
||||||
|
max: 10000
|
||||||
|
step: 50
|
||||||
|
unit_of_measurement: ppm
|
||||||
|
mode: box
|
||||||
|
min_drop:
|
||||||
|
name: Minimum drop to count as "dropping" (ppm)
|
||||||
|
description: >-
|
||||||
|
0 = any decrease stops the beeping. Raise to 5–10 if sensor jitter
|
||||||
|
makes the beeping stop and start at a plateau.
|
||||||
|
default: 0
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 0
|
||||||
|
max: 100
|
||||||
|
step: 1
|
||||||
|
unit_of_measurement: ppm
|
||||||
|
mode: box
|
||||||
|
beep_interval:
|
||||||
|
name: Beep repeat interval
|
||||||
|
default: "/30"
|
||||||
|
selector:
|
||||||
|
select:
|
||||||
|
options:
|
||||||
|
- label: Every 10 seconds
|
||||||
|
value: "/10"
|
||||||
|
- label: Every 15 seconds
|
||||||
|
value: "/15"
|
||||||
|
- label: Every 20 seconds
|
||||||
|
value: "/20"
|
||||||
|
- label: Every 30 seconds
|
||||||
|
value: "/30"
|
||||||
|
brightness:
|
||||||
|
name: LED brightness (%)
|
||||||
|
default: 60
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 1
|
||||||
|
max: 100
|
||||||
|
step: 1
|
||||||
|
unit_of_measurement: "%"
|
||||||
|
mode: slider
|
||||||
|
led_off_when_ok:
|
||||||
|
name: Turn LED off below "recommended"
|
||||||
|
description: >-
|
||||||
|
If enabled, the LED is switched off when CO₂ is below the
|
||||||
|
recommended level. Disable if you use the LED for other things.
|
||||||
|
default: true
|
||||||
|
selector:
|
||||||
|
boolean: {}
|
||||||
|
|
||||||
|
mode: queued
|
||||||
|
max: 10
|
||||||
|
max_exceeded: silent
|
||||||
|
|
||||||
|
variables:
|
||||||
|
co2_sensor: !input co2_sensor
|
||||||
|
change_sensor: !input change_sensor
|
||||||
|
rec_level: !input recommended_level
|
||||||
|
need_level: !input needed_level
|
||||||
|
beep_level: !input beep_level
|
||||||
|
min_drop: !input min_drop
|
||||||
|
led_brightness: !input brightness
|
||||||
|
led_off_when_ok: !input led_off_when_ok
|
||||||
|
|
||||||
|
triggers:
|
||||||
|
- trigger: state
|
||||||
|
entity_id: !input co2_sensor
|
||||||
|
id: reading
|
||||||
|
- trigger: time_pattern
|
||||||
|
seconds: !input beep_interval
|
||||||
|
id: beep_tick
|
||||||
|
|
||||||
|
actions:
|
||||||
|
- variables:
|
||||||
|
co2: "{{ states(co2_sensor) | float(none) }}"
|
||||||
|
change: "{{ states(change_sensor) | float(0) }}"
|
||||||
|
dropping: "{{ change < -(min_drop | float(0)) }}"
|
||||||
|
span: "{{ [need_level - rec_level, 1] | max }}"
|
||||||
|
frac: >-
|
||||||
|
{{ ([[(co2 - rec_level) / span, 0] | max, 1] | min)
|
||||||
|
if co2 is not none else 0 }}
|
||||||
|
hue: "{{ (60 * (1 - frac)) | round(0) | int }}"
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ co2 is not none }}"
|
||||||
|
- choose:
|
||||||
|
# --- LED: update on every new CO2 reading -------------------------
|
||||||
|
- conditions:
|
||||||
|
- condition: trigger
|
||||||
|
id: reading
|
||||||
|
sequence:
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ co2 >= rec_level }}"
|
||||||
|
sequence:
|
||||||
|
- action: light.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: !input led
|
||||||
|
data:
|
||||||
|
hs_color: "{{ [hue, 100] }}"
|
||||||
|
brightness_pct: "{{ led_brightness | int }}"
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ led_off_when_ok }}"
|
||||||
|
sequence:
|
||||||
|
- action: light.turn_off
|
||||||
|
target:
|
||||||
|
entity_id: !input led
|
||||||
|
# --- Buzzer: repeat while high AND not dropping -------------------
|
||||||
|
- conditions:
|
||||||
|
- condition: trigger
|
||||||
|
id: beep_tick
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ co2 >= beep_level and not dropping }}"
|
||||||
|
sequence: !input beep_action
|
||||||
Reference in New Issue
Block a user