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