yaml tidyups and warning removals
This commit is contained in:
+1
-1
@@ -1 +1 @@
|
||||
{"pid": 67, "version": 1, "ha_version": "2026.1.2", "start_ts": 1768726150.935691}
|
||||
{"pid": 67, "version": 1, "ha_version": "2026.1.3", "start_ts": 1769216420.8243344}
|
||||
@@ -59,12 +59,12 @@ wifi:
|
||||
# Allow rapid re-connection to previously connect WiFi SSID, skipping scan of all SSID
|
||||
fast_connect: ${wifi_fast_connect}
|
||||
# Define dns domain / suffix to add to hostname
|
||||
domain: "${dns_domain}"
|
||||
#min_auth_mode: WPA2
|
||||
domain: ${dns_domain}
|
||||
min_auth_mode: WPA2
|
||||
# Reboot eventually when Wi-Fi is down (default is 15min)
|
||||
reboot_timeout: 56h
|
||||
|
||||
#captive_portal: # extra fallback mechanism for when connecting if the configured WiFi fails
|
||||
captive_portal: # extra fallback mechanism for when connecting if the configured WiFi fails
|
||||
|
||||
###########################################################################################
|
||||
# Enable Over the Air Update Capability
|
||||
|
||||
@@ -11,6 +11,33 @@ substitutions:
|
||||
sntp_server_2: !secret ntp_server_2
|
||||
sntp_server_3: !secret ntp_server_3
|
||||
|
||||
###########################################################################################
|
||||
# Internal clock fallback support
|
||||
# If SNTP is invalid, we fall back to a simple internal minute counter
|
||||
# We assume user powers on the device at 12:00 noon
|
||||
# => 12 * 60 = 720 minutes from midnight.
|
||||
# Not restored, so it resets each boot.
|
||||
# Therefore, if no network and you still need timing functions, switch on ay noon.
|
||||
###########################################################################################
|
||||
globals:
|
||||
- id: current_mins
|
||||
type: int
|
||||
restore_value: no
|
||||
initial_value: "720" # 720 is 12:00 Noon
|
||||
|
||||
interval:
|
||||
- interval: 60s
|
||||
then:
|
||||
- lambda: |-
|
||||
// If SNTP valid, store minutes since midnight.
|
||||
auto now = id(sntp_time).now();
|
||||
if (now.is_valid()) {
|
||||
id(current_mins) = (now.hour * 60) + now.minute;
|
||||
} else {
|
||||
// Fallback: minutes since boot.
|
||||
id(current_mins) = (int)(millis() / 60000UL);
|
||||
}
|
||||
|
||||
###########################################################################################
|
||||
# Real time clock time source for ESPHome
|
||||
# If it's invalid, we fall back to an internal clock
|
||||
@@ -72,7 +99,6 @@ text_sensor:
|
||||
}
|
||||
|
||||
// Fallback: show internal clock based on current_mins (minutes from midnight).
|
||||
// NOTE: current_mins is expected to be a global defined in the main device YAML.
|
||||
int mins = id(current_mins);
|
||||
if (mins < 0) mins = 0;
|
||||
if (mins >= 1440) mins = mins % 1440;
|
||||
|
||||
@@ -360,6 +360,7 @@ status_led:
|
||||
pin:
|
||||
number: GPIO2
|
||||
inverted: yes
|
||||
ignore_strapping_warning: true # GPIO2: This just supresses a warning, we know what we are doing
|
||||
|
||||
##########################################################################################
|
||||
# SCRIPT COMPONENT
|
||||
@@ -478,6 +479,7 @@ binary_sensor:
|
||||
number: GPIO05
|
||||
mode: INPUT
|
||||
inverted: true
|
||||
ignore_strapping_warning: true # GPIO05: This just supresses a warning, we know what we are doing
|
||||
name: "Button 3: ${switch_3_name}"
|
||||
filters:
|
||||
- delayed_on: 50ms
|
||||
@@ -864,7 +866,7 @@ sensor:
|
||||
pin: GPIO36
|
||||
id: dimmer_raw
|
||||
name: "${variable_1_name} Raw"
|
||||
attenuation: 11db
|
||||
attenuation: 12db
|
||||
update_interval: 0.5s
|
||||
on_value:
|
||||
then:
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
##########################################################################################
|
||||
##########################################################################################
|
||||
#
|
||||
##########################################################################################
|
||||
##########################################################################################
|
||||
|
||||
|
||||
##########################################################################################
|
||||
# SPECIFIC DEVICE VARIABLE SUBSTITUTIONS
|
||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||
##########################################################################################
|
||||
substitutions:
|
||||
# Device Naming
|
||||
device_name: "esp-arcademachine1"
|
||||
friendly_name: "Arcade Cabinet 1"
|
||||
description_comment: "MAME Arcade 1 (Defender) machine power :: Athom Smart Plug Power V1"
|
||||
device_area: "Downstairs Flat" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
||||
|
||||
# Project Naming
|
||||
project_name: "Athom Technology.Smart Plug V1" # Project Details
|
||||
project_version: "v1.0" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
||||
|
||||
# Passwords
|
||||
api_key: !secret esp-api_key # unfortunately you can't use substitutions inside secrets names
|
||||
ota_pass: !secret esp-ota_pass # unfortunately you can't use substitutions inside secrets names
|
||||
static_ip_address: !secret esp-arcademachine1_ip
|
||||
|
||||
# Device Settings
|
||||
log_level: "NONE" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
||||
update_interval: "10s" # update time for for general sensors etc
|
||||
|
||||
# Device Settings
|
||||
relay_icon: "mdi:power-socket-au"
|
||||
current_limit : "10" # Current Limit in Amps. AU Plug = 10. IL, BR, EU, UK, US Plug = 16.
|
||||
|
||||
##########################################################################################
|
||||
# PACKAGES: Included Common Packages
|
||||
# https://esphome.io/components/packages.html
|
||||
##########################################################################################
|
||||
packages:
|
||||
##################################################
|
||||
# MANDATORY packages (won't compile without them!)
|
||||
##################################################
|
||||
|
||||
#### WIFI, Network (Static/DHCP/IPV6 etc), Fallback AP, Safemode ####
|
||||
common_wifi: !include
|
||||
file: common/network_common.yaml
|
||||
vars:
|
||||
local_device_name: "${device_name}"
|
||||
local_static_ip_address: "${static_ip_address}"
|
||||
local_ota_pass: "${ota_pass}"
|
||||
|
||||
##################################################
|
||||
# OPTIONAL packages (comment if you don't want them)
|
||||
##################################################
|
||||
|
||||
#### HOME ASSISTANT API (choose encryption or no encryption options) ####
|
||||
common_api: !include
|
||||
file: common/api_common.yaml
|
||||
#file: common/api_common_noencryption.yaml
|
||||
vars:
|
||||
local_api_key: "${api_key}"
|
||||
|
||||
#### WEB PORTAL ####
|
||||
#common_webportal: !include
|
||||
# file: common/webportal_common.yaml
|
||||
|
||||
#### MQTT ####
|
||||
common_mqtt: !include
|
||||
file: common/mqtt_common.yaml
|
||||
vars:
|
||||
local_device_name: "${device_name}"
|
||||
|
||||
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
||||
common_sntp: !include
|
||||
file: common/sntp_common.yaml
|
||||
|
||||
#### DIAGNOSTICS Lite Sensors ####
|
||||
common_lite_sensors: !include
|
||||
file: common/sensors_common_lite.yaml
|
||||
|
||||
#### DIAGNOSTICS General Sensors ####
|
||||
common_general_sensors: !include
|
||||
file: common/sensors_common.yaml
|
||||
|
||||
#### DEBUGGING Sensors ####
|
||||
# A count of various resets
|
||||
#common_resetcount_debugging: !include
|
||||
# file: common/resetcount_common.yaml
|
||||
|
||||
# Device Specific included packages
|
||||
common_athompowermonV1: !include
|
||||
file: common/athompowermonv1_common.yaml
|
||||
vars:
|
||||
local_friendly_name: "${friendly_name}"
|
||||
local_current_limit: "${current_limit}"
|
||||
|
||||
##########################################################################################
|
||||
# ESPHome
|
||||
# https://esphome.io/components/esphome.html
|
||||
##########################################################################################
|
||||
esphome:
|
||||
name: "${device_name}"
|
||||
friendly_name: "${friendly_name}"
|
||||
comment: "${description_comment}" #Appears on the esphome page in HA
|
||||
area: "${device_area}"
|
||||
name_add_mac_suffix: False
|
||||
min_version: 2024.6.0
|
||||
project:
|
||||
name: "${project_name}"
|
||||
version: "${project_version}"
|
||||
|
||||
|
||||
##########################################################################################
|
||||
# ESP Platform and Framework
|
||||
# https://esphome.io/components/esp32.html
|
||||
##########################################################################################
|
||||
esp8266:
|
||||
board: esp8285
|
||||
restore_from_flash: true # mainly for calculating cumulative energy, but not that important here
|
||||
#framework:
|
||||
# version: 2.7.4
|
||||
|
||||
preferences:
|
||||
flash_write_interval: 10min
|
||||
|
||||
#mdns:
|
||||
# disabled: True # binary size saving
|
||||
|
||||
##########################################################################################
|
||||
# ESPHome Logging Enable
|
||||
# https://esphome.io/components/logger.html
|
||||
##########################################################################################
|
||||
logger:
|
||||
level: "${log_level}" #INFO Level suggested, or DEBUG for testing
|
||||
baud_rate: 0 #set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
||||
#esp8266_store_log_strings_in_flash: false
|
||||
#tx_buffer_size: 64
|
||||
|
||||
##########################################################################################
|
||||
# Global Variables for use in automations etc
|
||||
# https://esphome.io/guides/automations.html?highlight=globals#global-variables
|
||||
##########################################################################################
|
||||
globals:
|
||||
|
||||
# Tracks the time (in seconds from midnight) at the previous boot
|
||||
- id: last_boot_time_s
|
||||
type: int
|
||||
restore_value: true
|
||||
initial_value: "0"
|
||||
|
||||
# Counts how many consecutive boots have occurred (within X seconds)
|
||||
- id: boot_count
|
||||
type: int
|
||||
restore_value: true
|
||||
initial_value: "0"
|
||||
|
||||
####################################################
|
||||
# boost_timer: counts minutes in BOOST mode
|
||||
# After 'boost_duration' minutes, revert to TIMER.
|
||||
####################################################
|
||||
- id: boost_timer
|
||||
type: int
|
||||
restore_value: true
|
||||
initial_value: "0"
|
||||
|
||||
##########################################################################################
|
||||
# BINARY SENSORS
|
||||
# https://esphome.io/components/binary_sensor/
|
||||
##########################################################################################
|
||||
binary_sensor:
|
||||
- platform: gpio
|
||||
pin:
|
||||
number: GPIO03
|
||||
mode: INPUT_PULLUP
|
||||
inverted: true
|
||||
name: "Power Button"
|
||||
id: power_button
|
||||
filters:
|
||||
- delayed_on: 20ms
|
||||
on_click:
|
||||
- min_length: 20ms
|
||||
max_length: 500ms
|
||||
then:
|
||||
- lambda: |-
|
||||
if (id(relay).state) {
|
||||
// Relay is ON: turn it OFF and set mode to 2 (TIMER)
|
||||
id(relay).turn_off();
|
||||
} else {
|
||||
// Relay is OFF: turn it ON and set mode to 3 (BOOST)
|
||||
id(relay).turn_on();
|
||||
}
|
||||
|
||||
- platform: template
|
||||
name: "Relay Status"
|
||||
lambda: |-
|
||||
return id(relay).state;
|
||||
|
||||
#################################################################################################
|
||||
# SWITCH COMPONENT
|
||||
# https://esphome.io/components/switch/
|
||||
#################################################################################################
|
||||
switch:
|
||||
- platform: gpio
|
||||
name: "Power Output"
|
||||
pin: GPIO14
|
||||
id: relay
|
||||
restore_mode: RESTORE_DEFAULT_OFF # Ensures the relay is restored (or off) at boot
|
||||
#internal: true # Hides the switch from Home Assistant
|
||||
icon: "${relay_icon}"
|
||||
|
||||
@@ -141,6 +141,7 @@ wifi:
|
||||
ssid: ${devicename} AP
|
||||
password: ${fallback_ap_password}
|
||||
ap_timeout: 30min # Time until it brings up fallback AP. default is 1min
|
||||
min_auth_mode: WPA2
|
||||
|
||||
captive_portal: # extra fallback mechanism for when connecting if the configured WiFi fails
|
||||
|
||||
|
||||
@@ -168,6 +168,7 @@ binary_sensor:
|
||||
number: GPIO16
|
||||
mode: INPUT
|
||||
inverted: True
|
||||
use_interrupt: false # This pin doesn't support interrupts so use polling. Only supresses a warning.
|
||||
name: "Button 1: ${switch_1_name}"
|
||||
on_press:
|
||||
- mqtt.publish:
|
||||
|
||||
@@ -144,6 +144,7 @@ binary_sensor:
|
||||
number: GPIO16
|
||||
mode: INPUT
|
||||
inverted: True
|
||||
use_interrupt: false # GPIO16 pin doesn't support interrupts so use polling. Only supresses a warning.
|
||||
name: "Button 1: ${switch_1_name}"
|
||||
on_press:
|
||||
- switch.toggle: Relay_1
|
||||
|
||||
@@ -121,8 +121,8 @@ esphome:
|
||||
build_flags:
|
||||
- "-Os" # optimize for size
|
||||
- "-Wl,--gc-sections" # drop unused code/data
|
||||
- "-fno-exceptions" # strip C++ exceptions
|
||||
- "-fno-rtti" # strip C++ RTTI
|
||||
#- "-fno-exceptions" # strip C++ exceptions
|
||||
#- "-fno-rtti" # strip C++ RTTI
|
||||
# on_boot:
|
||||
# priority: 200
|
||||
# then:
|
||||
@@ -170,6 +170,7 @@ binary_sensor:
|
||||
number: GPIO16
|
||||
mode: INPUT
|
||||
inverted: True
|
||||
use_interrupt: false # GPO16 pin doesn't support interrupts so use polling. Only supresses a warning.
|
||||
name: "Button 1: ${switch_1_name}"
|
||||
on_press:
|
||||
- mqtt.publish:
|
||||
|
||||
@@ -168,6 +168,7 @@ binary_sensor:
|
||||
input: true
|
||||
pullup: false # set to true if you need an internal pull-up
|
||||
inverted: true
|
||||
use_interrupt: false # GPIO16 pin doesn't support interrupts so use polling. Only supresses a warning.
|
||||
name: "Button 1: ${switch_1_name}"
|
||||
filters:
|
||||
- delayed_on: 30ms
|
||||
|
||||
@@ -341,7 +341,7 @@ switch:
|
||||
# Ramp-aware ON/OFF for HA (asymmetric, eased; no bounce)
|
||||
- platform: template
|
||||
id: mosfet_ramp_switch
|
||||
name: "${friendly_name} Fade Up/Down"
|
||||
name: "${friendly_name} Fade Up-Down"
|
||||
icon: mdi:led-strip-variant
|
||||
lambda: |-
|
||||
return id(ramp_switch_target_on);
|
||||
|
||||
@@ -218,6 +218,7 @@ binary_sensor:
|
||||
number: GPIO16
|
||||
mode: INPUT
|
||||
inverted: True
|
||||
use_interrupt: false # GPIO16 pin doesn't support interrupts so use polling. Only supresses a warning.
|
||||
filters:
|
||||
- delayed_on: 30ms
|
||||
- delayed_off: 30ms
|
||||
|
||||
@@ -218,6 +218,7 @@ binary_sensor:
|
||||
number: GPIO16
|
||||
mode: INPUT
|
||||
inverted: True
|
||||
use_interrupt: false # GPIO16 pin doesn't support interrupts so use polling. Only supresses a warning.
|
||||
filters:
|
||||
- delayed_on: 30ms
|
||||
- delayed_off: 30ms
|
||||
|
||||
@@ -108,16 +108,18 @@ esphome:
|
||||
# Restore "Last Trip" text from persisted epoch (if any)
|
||||
- lambda: |-
|
||||
if (id(last_trip_epoch) > 0) {
|
||||
auto t = time::ESPTime::from_epoch_local(id(last_trip_epoch));
|
||||
time_t tt = (time_t) id(last_trip_epoch);
|
||||
struct tm tm;
|
||||
localtime_r(&tt, &tm);
|
||||
char buf[24];
|
||||
t.strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S");
|
||||
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm);
|
||||
id(ts_last_trip).publish_state(buf);
|
||||
} else {
|
||||
id(ts_last_trip).publish_state("Never");
|
||||
}
|
||||
# Apply Power Restore Mode selector (Always ON / Always OFF / Previous State)
|
||||
- lambda: |-
|
||||
std::string mode = id(sel_restore_mode).state;
|
||||
std::string mode = id(sel_restore_mode).current_option();
|
||||
if (mode == "Always ON") {
|
||||
id(relay_virtual).turn_on();
|
||||
} else if (mode == "Always OFF") {
|
||||
@@ -151,6 +153,7 @@ status_led:
|
||||
pin:
|
||||
number: GPIO8
|
||||
inverted: true
|
||||
ignore_strapping_warning: true # GPIO08: This just supresses a warning, we know what we are doing
|
||||
|
||||
##########################################################################################
|
||||
# UART BUS
|
||||
@@ -550,6 +553,7 @@ binary_sensor:
|
||||
number: GPIO9
|
||||
mode: INPUT_PULLUP
|
||||
inverted: true
|
||||
ignore_strapping_warning: true # GPIO09: This just supresses a warning, we know what we are doing
|
||||
name: "${button_1_name}"
|
||||
on_press:
|
||||
- switch.toggle: relay_virtual
|
||||
@@ -743,7 +747,7 @@ script:
|
||||
if (f > 1.0f) f = 1.0f;
|
||||
int slow_ms = ${led_flash_slow_ms};
|
||||
int fast_ms = ${led_flash_fast_ms};
|
||||
if (slow_ms < fast_ms) { int t = slow_ms; slow_ms = fast_ms; fast_ms = t; } # ensure slow >= fast
|
||||
if (slow_ms < fast_ms) { int t = slow_ms; slow_ms = fast_ms; fast_ms = t; } // ensure slow >= fast
|
||||
int period = slow_ms - (int)((slow_ms - fast_ms) * f);
|
||||
id(_blink_period_ms) = period;
|
||||
# Blink with 50% duty cycle at the computed period
|
||||
|
||||
@@ -352,7 +352,7 @@ switch:
|
||||
# Ramp-aware ON/OFF for HA (asymmetric, eased; no bounce)
|
||||
- platform: template
|
||||
id: mosfet_ramp_switch
|
||||
name: "${friendly_name} Fade Up/Down"
|
||||
name: "${friendly_name} Fade Up-Down"
|
||||
icon: mdi:led-strip-variant
|
||||
lambda: |-
|
||||
return id(ramp_switch_target_on);
|
||||
|
||||
@@ -127,6 +127,7 @@ binary_sensor:
|
||||
number: GPIO16
|
||||
mode: INPUT
|
||||
inverted: True
|
||||
use_interrupt: false # This pin doesn't support interrupts so use polling. Only supresses a warning.
|
||||
name: "Button 1: ${switch_1_name}"
|
||||
on_press:
|
||||
- switch.toggle: Relay_1
|
||||
|
||||
@@ -131,8 +131,8 @@ esphome:
|
||||
build_flags:
|
||||
- "-Os" # optimize for size
|
||||
- "-Wl,--gc-sections" # drop unused code/data
|
||||
- "-fno-exceptions" # strip C++ exceptions
|
||||
- "-fno-rtti" # strip C++ RTTI
|
||||
#- "-fno-exceptions" # strip C++ exceptions
|
||||
#- "-fno-rtti" # strip C++ RTTI
|
||||
on_boot:
|
||||
priority: 900 # High priority to run after globals are initialized
|
||||
then:
|
||||
@@ -274,17 +274,6 @@ globals:
|
||||
restore_value: true
|
||||
initial_value: "2"
|
||||
|
||||
####################################################
|
||||
# current_mins is set if SNTP is invalid.
|
||||
# We assume user powers on the device at 12:00 noon
|
||||
# => 12 * 60 = 720 minutes from midnight.
|
||||
# Not restored, so it resets each boot.
|
||||
####################################################
|
||||
- id: current_mins
|
||||
type: int
|
||||
restore_value: false
|
||||
initial_value: "720" # 720 is 12:00 Noon
|
||||
|
||||
####################################################
|
||||
# boost_timer: counts minutes in BOOST mode
|
||||
# After 'boost_duration' minutes, revert to TIMER.
|
||||
|
||||
@@ -124,6 +124,7 @@ binary_sensor:
|
||||
number: GPIO16
|
||||
mode: INPUT
|
||||
inverted: True
|
||||
use_interrupt: false # This pin doesn't support interrupts so use polling. Only supresses a warning.
|
||||
name: "Button 1: ${switch_1_name}"
|
||||
on_press:
|
||||
- switch.toggle: Relay_1
|
||||
|
||||
@@ -161,6 +161,7 @@ binary_sensor:
|
||||
number: GPIO16
|
||||
mode: INPUT
|
||||
inverted: True
|
||||
use_interrupt: false # This pin doesn't support interrupts so use polling. Only supresses a warning.
|
||||
name: "Button 1: ${switch_1_name}"
|
||||
on_press:
|
||||
- switch.toggle: Relay_1
|
||||
|
||||
@@ -145,6 +145,7 @@ binary_sensor:
|
||||
number: GPIO16
|
||||
mode: INPUT
|
||||
inverted: True
|
||||
use_interrupt: false # GPIO16 pin doesn't support interrupts so use polling. Only supresses a warning.
|
||||
name: "Button 1: ${switch_1_name}"
|
||||
on_press:
|
||||
- switch.toggle: Relay_1
|
||||
|
||||
@@ -147,6 +147,7 @@ binary_sensor:
|
||||
number: GPIO16
|
||||
mode: INPUT
|
||||
inverted: True
|
||||
use_interrupt: false # GPIO16 pin doesn't support interrupts so use polling. Only supresses a warning.
|
||||
name: "Button 1: ${switch_1_name}"
|
||||
on_press:
|
||||
- switch.toggle: Relay_1
|
||||
|
||||
@@ -438,6 +438,7 @@ binary_sensor:
|
||||
mode:
|
||||
input: true
|
||||
pullup: true
|
||||
ignore_strapping_warning: true # GPIO15: This just supresses a warning, we know what we are doing
|
||||
inverted: True
|
||||
filters:
|
||||
- delayed_on: 20ms
|
||||
|
||||
@@ -142,6 +142,7 @@ binary_sensor:
|
||||
number: GPIO16
|
||||
mode: INPUT
|
||||
inverted: True
|
||||
use_interrupt: false # GPIO16 pin doesn't support interrupts so use polling. Only supresses a warning.
|
||||
name: "Button 1: ${switch_1_name}"
|
||||
on_press:
|
||||
- switch.toggle: Relay_1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
##########################################################################################
|
||||
##########################################################################################
|
||||
# FLY SPRAYER – Sinilink XY-WFUSB (ESP8266/ESP8285) – ESPHome
|
||||
# FLY SPRAYER - Sinilink XY-WFUSB (ESP8266/ESP8285) - ESPHome
|
||||
#
|
||||
# V1.0 2025-05-30 Initial Version
|
||||
#
|
||||
@@ -12,7 +12,7 @@
|
||||
# - Sprayer has its own timers, but it fires whenever it is started up, which we utilise here.
|
||||
# - Enforce a cooldown so it never double-fires too quickly (Sprayer has some memory)
|
||||
# - Operation window select: Night only / Day only / 24 Hours / On / Off.
|
||||
# - Randomize each interval by ± a percentage to avoid a perfectly regular pattern.
|
||||
# - Randomize each interval by +- a percentage to avoid a perfectly regular pattern.
|
||||
# - Red LED (GPIO14, inverted) pulses slowly when idle; goes solid ON during spray.
|
||||
# - Green LED (GPIO16) as standard ESPHome status LED.
|
||||
# - Has a resettable total spray count, and a daily spray count
|
||||
@@ -26,14 +26,14 @@
|
||||
# If NOT using a secrets file, just replace these with the passwords etc (in quotes)
|
||||
##########################################################################################
|
||||
substitutions:
|
||||
# Device Naming
|
||||
# Device Naming
|
||||
device_name: "esp-flysprayer1"
|
||||
friendly_name: "Fly Sprayer"
|
||||
description_comment: "Control of generic automatic fly sprayer on a configurable interval"
|
||||
device_area: "Lounge" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
||||
device_area: "Lounge" # Allows ESP device to be automatically linked to an 'Area' in Home Assistant.
|
||||
|
||||
# Project Naming
|
||||
project_name: "Generic ESP8266.XY-WFUSB" # Project Details
|
||||
project_name: "Generic ESP8266.XY-WFUSB" # Project Details
|
||||
project_version: "v1.0" # Project V denotes release of yaml file, allowing checking of deployed vs latest version
|
||||
|
||||
# Passwords & Secrets
|
||||
@@ -67,8 +67,8 @@ substitutions:
|
||||
night_start_h: 21 # 21:00 (9pm)
|
||||
night_end_h: 7 # 07:00 (7am)
|
||||
|
||||
# Interval jitter (± percent of selected interval)
|
||||
interval_jitter_pct: 10 # Default ±10%
|
||||
# Interval jitter (+- percent of selected interval)
|
||||
interval_jitter_pct: 10 # Default +-10%
|
||||
|
||||
#########################################################################################
|
||||
# PACKAGES: Included Common Packages
|
||||
@@ -95,7 +95,7 @@ packages:
|
||||
file: common/mqtt_common.yaml
|
||||
vars:
|
||||
local_device_name: "${device_name}"
|
||||
|
||||
|
||||
#### WEB PORTAL ####
|
||||
#common_webportal: !include common/webportal_common.yaml
|
||||
#### SNTP (Only use if you want/need accurate timeclocks) ####
|
||||
@@ -142,7 +142,6 @@ esphome:
|
||||
id(next_spray_in_text).publish_state("Ready");
|
||||
- script.execute: spray_loop
|
||||
|
||||
|
||||
##########################################################################################
|
||||
# ESP PLATFORM AND FRAMEWORK
|
||||
# https://esphome.io/components/esp8266.html
|
||||
@@ -162,7 +161,7 @@ preferences:
|
||||
##########################################################################################
|
||||
globals:
|
||||
# millisecond tick when we last fired successfully
|
||||
- id: last_fire_ms
|
||||
- id: last_fire_ms
|
||||
type: uint32_t
|
||||
restore_value: no
|
||||
initial_value: '0'
|
||||
@@ -178,34 +177,34 @@ globals:
|
||||
initial_value: 'false'
|
||||
|
||||
# absolute millis() when the next spray countdown ends
|
||||
- id: next_target_ms
|
||||
- id: next_target_ms
|
||||
type: uint32_t
|
||||
restore_value: no
|
||||
initial_value: '0'
|
||||
|
||||
# total successful sprays (persists across reboots)
|
||||
- id: spray_count
|
||||
- id: spray_count
|
||||
type: uint32_t
|
||||
restore_value: yes
|
||||
initial_value: '0'
|
||||
|
||||
# total sprays since local midnight
|
||||
- id: spray_count_today
|
||||
- id: spray_count_today
|
||||
type: uint32_t
|
||||
restore_value: yes
|
||||
initial_value: '0'
|
||||
|
||||
# day-of-month snapshot to detect midnight rollover
|
||||
- id: last_day
|
||||
- id: last_day
|
||||
type: int
|
||||
restore_value: yes
|
||||
initial_value: '-1'
|
||||
|
||||
##########################################################################################
|
||||
##########################################################################################
|
||||
# LOGGER COMPONENT
|
||||
# https://esphome.io/components/logger.html
|
||||
# Logs all log messages through the serial port and through MQTT topics.
|
||||
##########################################################################################
|
||||
##########################################################################################
|
||||
logger:
|
||||
level: "${log_level}" #INFO Level suggested, or DEBUG for testing
|
||||
#baud_rate: 0 #set to 0 for no logging via UART, needed if you are using it for other serial things (eg PZEM)
|
||||
@@ -286,7 +285,7 @@ button:
|
||||
- lambda: |-
|
||||
id(spray_count) = 0;
|
||||
id(spray_count_sensor).publish_state(0);
|
||||
|
||||
|
||||
#########################################################################################
|
||||
# SELECT COMPONENT
|
||||
# https://esphome.io/components/select/index.html
|
||||
@@ -310,8 +309,8 @@ select:
|
||||
on_value:
|
||||
then:
|
||||
- logger.log:
|
||||
format: "Spray Interval changed to %s — rescheduling"
|
||||
args: [ 'id(spray_interval).state.c_str()' ]
|
||||
format: "Spray Interval changed to %s - rescheduling"
|
||||
args: [ 'id(spray_interval).current_option().c_str()' ]
|
||||
- script.execute: spray_loop
|
||||
|
||||
- platform: template
|
||||
@@ -330,8 +329,8 @@ select:
|
||||
on_value:
|
||||
then:
|
||||
- logger.log:
|
||||
format: "Operation changed to %s — rescheduling"
|
||||
args: [ 'id(spray_operation).state.c_str()' ]
|
||||
format: "Operation changed to %s - rescheduling"
|
||||
args: [ 'id(spray_operation).current_option().c_str()' ]
|
||||
- script.execute: spray_loop
|
||||
|
||||
##########################################################################################
|
||||
@@ -339,7 +338,7 @@ select:
|
||||
# https://esphome.io/components/binary_sensor/
|
||||
##########################################################################################
|
||||
binary_sensor:
|
||||
# Front panel/local button (GPIO4) – single press triggers a Spray Now (honors cooldown)
|
||||
# Front panel/local button (GPIO4) - single press triggers a Spray Now (honors cooldown)
|
||||
- platform: gpio
|
||||
id: btn_local
|
||||
pin:
|
||||
@@ -441,20 +440,12 @@ light:
|
||||
# https://esphome.io/components/number/
|
||||
##########################################################################################
|
||||
|
||||
|
||||
##########################################################################################
|
||||
# SCRIPT COMPONENT
|
||||
# https://esphome.io/components/script.html
|
||||
# Scripts can be executed nearly anywhere in your device configuration with a single call.
|
||||
##########################################################################################
|
||||
# SCRIPTS – main loop, cooldown-safe trigger, and actual spray action
|
||||
##########################################################################################
|
||||
##########################################################################################
|
||||
# SCRIPT COMPONENT
|
||||
# https://esphome.io/components/script.html
|
||||
# Scripts can be executed nearly anywhere in your device configuration with a single call.
|
||||
##########################################################################################
|
||||
# SCRIPTS – main loop, cooldown-safe trigger, and actual spray action
|
||||
# SCRIPTS - main loop, cooldown-safe trigger, and actual spray action
|
||||
##########################################################################################
|
||||
script:
|
||||
# Cooldown-checked "Spray Now"
|
||||
@@ -495,7 +486,7 @@ script:
|
||||
brightness: 50%
|
||||
effect: red_idle_pulse
|
||||
|
||||
# Scheduler loop – waits a randomized interval, updates countdown text, checks window, then tries to spray
|
||||
# Scheduler loop - waits a randomized interval, updates countdown text, checks window, then tries to spray
|
||||
- id: spray_loop
|
||||
mode: restart
|
||||
then:
|
||||
@@ -505,7 +496,7 @@ script:
|
||||
then:
|
||||
# 1) Compute the base interval and randomized wait
|
||||
- lambda: |-
|
||||
auto s = id(spray_interval).state;
|
||||
auto s = id(spray_interval).current_option();
|
||||
uint32_t base_sec = 3600; // default 1 hour
|
||||
if (s == "5 minutes") base_sec = 5 * 60;
|
||||
else if (s == "10 minutes") base_sec = 10 * 60;
|
||||
@@ -515,13 +506,13 @@ script:
|
||||
else if (s == "2 hours") base_sec = 2 * 60 * 60;
|
||||
else if (s == "4 hours") base_sec = 4 * 60 * 60;
|
||||
|
||||
// Jitter ±pct
|
||||
// Jitter +-pct
|
||||
const uint32_t pct = ${interval_jitter_pct};
|
||||
const uint32_t jitter = (base_sec * pct) / 100;
|
||||
const uint32_t span = (jitter * 2u) + 1u;
|
||||
const uint32_t rnd = random_uint32() % span; // 0..(2*jitter)
|
||||
const int32_t delta = (int32_t)rnd - (int32_t)jitter; // -jitter..+jitter
|
||||
int32_t next_sec = (int32_t)base_sec + delta;
|
||||
const uint32_t rnd = random_uint32() % span; // 0..(2*jitter)
|
||||
const int32_t delta = (int32_t) rnd - (int32_t) jitter; // -jitter..+jitter
|
||||
int32_t next_sec = (int32_t) base_sec + delta;
|
||||
if (next_sec < 1) next_sec = 1;
|
||||
|
||||
ESP_LOGI("spray", "Next interval: base=%u s, jitter=%u%%, wait=%ld s",
|
||||
@@ -536,11 +527,11 @@ script:
|
||||
id(next_spray_seconds).publish_state(sec);
|
||||
uint32_t min = (sec + 59u) / 60u; // minutes, ceiling
|
||||
char buf[16];
|
||||
snprintf(buf, sizeof(buf), "%u min", (unsigned)min);
|
||||
snprintf(buf, sizeof(buf), "%u min", (unsigned) min);
|
||||
std::string countdown_txt(buf);
|
||||
|
||||
// Override text for specific modes
|
||||
auto op = id(spray_operation).state;
|
||||
auto op = id(spray_operation).current_option();
|
||||
char await_buf[16];
|
||||
|
||||
if (op == "Off") {
|
||||
@@ -594,11 +585,11 @@ script:
|
||||
id(next_spray_seconds).publish_state(sec);
|
||||
uint32_t min = (sec + 59u) / 60u; // minutes, ceiling
|
||||
char buf[16];
|
||||
snprintf(buf, sizeof(buf), "%u min", (unsigned)min);
|
||||
snprintf(buf, sizeof(buf), "%u min", (unsigned) min);
|
||||
std::string countdown_txt(buf);
|
||||
|
||||
// Override text for specific modes
|
||||
auto op = id(spray_operation).state;
|
||||
auto op = id(spray_operation).current_option();
|
||||
char await_buf[16];
|
||||
|
||||
if (op == "Off") {
|
||||
@@ -659,7 +650,7 @@ script:
|
||||
|
||||
# 3) Check operation window; if allowed, attempt spray (cooldown enforced inside)
|
||||
- lambda: |-
|
||||
auto op = id(spray_operation).state;
|
||||
auto op = id(spray_operation).current_option();
|
||||
bool allowed = false;
|
||||
|
||||
if (op == "Off") {
|
||||
@@ -699,6 +690,3 @@ script:
|
||||
- script.execute: try_spray_now
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -323,7 +323,12 @@ globals:
|
||||
- id: ev_energy_yesterday_kwh
|
||||
type: float
|
||||
restore_value: true
|
||||
initial_value: "0.0"
|
||||
initial_value: "0.0"
|
||||
# Track last day-of-year we snapped so it only happens once per day
|
||||
- id: ev_last_snapshot_doy
|
||||
type: int
|
||||
restore_value: no
|
||||
initial_value: '-1'
|
||||
|
||||
# Teleperiod = 60s: publish JSON and advance the window
|
||||
interval:
|
||||
@@ -351,21 +356,25 @@ interval:
|
||||
snprintf(buf, sizeof(buf), "{\"EVChargerWhCount\":%.3f}", delta_wh);
|
||||
return std::string(buf);
|
||||
|
||||
##########################################################################################
|
||||
# YESTERDAY ENERGY (device-side snapshot of today's total at 23:59:59)
|
||||
##########################################################################################
|
||||
time:
|
||||
- platform: sntp
|
||||
id: ev_time_for_ev_snap
|
||||
on_time:
|
||||
- seconds: 59
|
||||
minutes: 59
|
||||
hours: 23
|
||||
then:
|
||||
- lambda: |-
|
||||
// Snapshot today's kWh just before midnight reset
|
||||
if (isfinite(id(ev_energy_today_kwh).state)) {
|
||||
id(ev_energy_yesterday_kwh) = id(ev_energy_today_kwh).state;
|
||||
}
|
||||
# YESTERDAY ENERGY (device-side snapshot of today's total at end-of-day)
|
||||
# Uses existing time id(sntp_time) from sntp_common.yaml
|
||||
- interval: 60s
|
||||
then:
|
||||
- lambda: |-
|
||||
auto now = id(sntp_time).now();
|
||||
if (!now.is_valid()) return;
|
||||
|
||||
// Snapshot once per day at 23:59 (minute precision)
|
||||
if (now.hour != 23 || now.minute != 59) return;
|
||||
|
||||
// Prevent repeats if this runs multiple times during 23:59
|
||||
if (id(ev_last_snapshot_doy) == now.day_of_year) return;
|
||||
|
||||
if (isfinite(id(ev_energy_today_kwh).state)) {
|
||||
id(ev_energy_yesterday_kwh) = id(ev_energy_today_kwh).state;
|
||||
}
|
||||
|
||||
id(ev_last_snapshot_doy) = now.day_of_year;
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ substitutions:
|
||||
static_ip_address: !secret esp-garageentrylights_ip
|
||||
|
||||
# Device Settings
|
||||
log_level: "INFO" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
||||
log_level: "NONE" # Define logging level: NONE, ERROR, WARN, INFO, DEBUG (Default), VERBOSE, VERY_VERBOSE
|
||||
update_interval: "60s" # update time for for general sensors etc
|
||||
|
||||
# Default relay restore mode
|
||||
@@ -82,6 +82,15 @@ packages:
|
||||
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
||||
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
||||
|
||||
# Package item removals
|
||||
wifi:
|
||||
min_auth_mode: !remove # The WPA2 only works on esp32/8266
|
||||
reboot_timeout: 15min # override the selection from from the common package
|
||||
fast_connect: false # (optional) force off, in case package vars change
|
||||
|
||||
mqtt:
|
||||
keepalive: 15s # overriding the value from the common package
|
||||
|
||||
#############################################
|
||||
# ESPHome
|
||||
# https://esphome.io/components/esphome.html
|
||||
@@ -99,6 +108,9 @@ esphome:
|
||||
# then:
|
||||
# - switch.turn_on: Relay_3
|
||||
|
||||
mdns:
|
||||
disabled: true
|
||||
|
||||
#############################################
|
||||
# BUILD FOR BK CHIPSET
|
||||
# bk72xx
|
||||
|
||||
@@ -82,6 +82,15 @@ packages:
|
||||
#diag_debug: !include common/include_debug_diag_sensors.yaml
|
||||
#diag_resetcount: !include common/include_resetcount_diag_sensors.yaml
|
||||
|
||||
# Package item removals
|
||||
wifi:
|
||||
min_auth_mode: !remove # The WPA2 only works on esp32/8266
|
||||
reboot_timeout: 15min # override the selection from from the common package
|
||||
fast_connect: false # (optional) force off, in case package vars change
|
||||
|
||||
mqtt:
|
||||
keepalive: 15s # overriding the value from the common package
|
||||
|
||||
#############################################
|
||||
# ESPHome
|
||||
# https://esphome.io/components/esphome.html
|
||||
|
||||
@@ -341,7 +341,7 @@ switch:
|
||||
# Ramp-aware ON/OFF for HA (asymmetric, eased; no bounce)
|
||||
- platform: template
|
||||
id: mosfet_ramp_switch
|
||||
name: "${friendly_name} Fade Up/Down"
|
||||
name: "${friendly_name} Fade Up-Down"
|
||||
icon: mdi:led-strip-variant
|
||||
lambda: |-
|
||||
return id(ramp_switch_target_on);
|
||||
|
||||
@@ -346,7 +346,7 @@ switch:
|
||||
# Ramp-aware ON/OFF for HA (asymmetric, eased; no bounce)
|
||||
- platform: template
|
||||
id: mosfet_ramp_switch
|
||||
name: "${friendly_name} Fade Up/Down"
|
||||
name: "${friendly_name} Fade Up-Down"
|
||||
icon: mdi:led-strip-variant
|
||||
lambda: |-
|
||||
return id(ramp_switch_target_on);
|
||||
|
||||
@@ -164,6 +164,7 @@ binary_sensor:
|
||||
number: GPIO16
|
||||
mode: INPUT
|
||||
inverted: True
|
||||
use_interrupt: false # This pin doesn't support interrupts so use polling. Only supresses a warning.
|
||||
name: "Button 1: ${switch_1_name}"
|
||||
on_multi_click:
|
||||
|
||||
|
||||
@@ -77,6 +77,15 @@ packages:
|
||||
local_friendly_name: "${friendly_name}"
|
||||
local_update_interval: "${update_interval}"
|
||||
|
||||
# Package item removals
|
||||
wifi:
|
||||
min_auth_mode: !remove # The WPA2 only works on esp32/8266
|
||||
reboot_timeout: 15min # override the selection from from the common package
|
||||
fast_connect: false # (optional) force off, in case package vars change
|
||||
|
||||
mqtt:
|
||||
keepalive: 15s # overriding the value from the common package
|
||||
|
||||
#########################################################################################
|
||||
# ESPHome
|
||||
# https://esphome.io/components/esphome.html
|
||||
|
||||
@@ -385,7 +385,7 @@ logger:
|
||||
switch:
|
||||
- platform: template
|
||||
id: mosfet_ramp_switch_a
|
||||
name: "${friendly_name} A Fade Up/Down"
|
||||
name: "${friendly_name} A Fade Up-Down"
|
||||
icon: mdi:led-strip-variant
|
||||
lambda: |-
|
||||
return id(ramp_switch_target_on_A);
|
||||
@@ -402,7 +402,7 @@ switch:
|
||||
|
||||
- platform: template
|
||||
id: mosfet_ramp_switch_b
|
||||
name: "${friendly_name} B Fade Up/Down"
|
||||
name: "${friendly_name} B Fade Up-Down"
|
||||
icon: mdi:led-strip-variant
|
||||
lambda: |-
|
||||
return id(ramp_switch_target_on_B);
|
||||
|
||||
@@ -145,6 +145,7 @@ binary_sensor:
|
||||
number: GPIO16
|
||||
mode: INPUT
|
||||
inverted: True
|
||||
use_interrupt: false # This pin doesn't support interrupts so use polling. Only supresses a warning.
|
||||
name: "Button 1: ${switch_1_name}"
|
||||
on_press:
|
||||
- switch.toggle: Relay_1
|
||||
|
||||
@@ -158,6 +158,7 @@ binary_sensor:
|
||||
number: GPIO16
|
||||
mode: INPUT
|
||||
inverted: True
|
||||
use_interrupt: false # GPO16 pin doesn't support interrupts so use polling. Only supresses a warning.
|
||||
name: "Button 1: ${switch_1_name}"
|
||||
on_press:
|
||||
- switch.toggle: Relay_1
|
||||
|
||||
@@ -100,8 +100,8 @@ esphome:
|
||||
build_flags:
|
||||
- "-Os" # optimize for size
|
||||
- "-Wl,--gc-sections" # drop unused code/data
|
||||
- "-fno-exceptions" # strip C++ exceptions
|
||||
- "-fno-rtti" # strip C++ RTTI
|
||||
#- "-fno-exceptions" # strip C++ exceptions
|
||||
#- "-fno-rtti" # strip C++ RTTI
|
||||
# on_boot:
|
||||
# priority: 200
|
||||
# then:
|
||||
@@ -149,6 +149,7 @@ binary_sensor:
|
||||
number: GPIO16
|
||||
mode: INPUT
|
||||
inverted: True
|
||||
use_interrupt: false # GPO16 pin doesn't support interrupts so use polling. Only supresses a warning.
|
||||
name: "Button 1: Extract Fan"
|
||||
on_press:
|
||||
- switch.toggle: "Relay_1"
|
||||
|
||||
@@ -271,16 +271,6 @@ globals:
|
||||
restore_value: true
|
||||
initial_value: "2"
|
||||
|
||||
####################################################
|
||||
# current_mins is set if SNTP is invalid.
|
||||
# We assume user powers on the device at 12:00 noon
|
||||
# => 12 * 60 = 720 minutes from midnight.
|
||||
####################################################
|
||||
- id: current_mins
|
||||
type: int
|
||||
restore_value: false
|
||||
initial_value: "720" # 720 is 12:00 Noon
|
||||
|
||||
####################################################
|
||||
# boost_timer: counts minutes in BOOST mode
|
||||
# After 'boost_duration' minutes, revert to TIMER.
|
||||
|
||||
@@ -135,6 +135,7 @@ binary_sensor:
|
||||
number: GPIO16
|
||||
mode: INPUT
|
||||
inverted: True
|
||||
use_interrupt: False # GPIO16 pin doesn't support interrupts so use polling. Only supresses a warning.
|
||||
name: "Button 1: ${switch_1_name}"
|
||||
on_press:
|
||||
- switch.toggle: Relay_1
|
||||
@@ -135,6 +135,7 @@ binary_sensor:
|
||||
number: GPIO16
|
||||
mode: INPUT
|
||||
inverted: True
|
||||
use_interrupt: False # GPIO16 pin doesn't support interrupts so use polling. Only supresses a warning.
|
||||
name: "Button 1: ${switch_1_name}"
|
||||
on_press:
|
||||
- switch.toggle: Relay_1
|
||||
|
||||
@@ -272,16 +272,6 @@ globals:
|
||||
restore_value: true
|
||||
initial_value: "2"
|
||||
|
||||
####################################################
|
||||
# current_mins is set if SNTP is invalid.
|
||||
# We assume user powers on the device at 12:00 noon
|
||||
# => 12 * 60 = 720 minutes from midnight.
|
||||
####################################################
|
||||
- id: current_mins
|
||||
type: int
|
||||
restore_value: true
|
||||
initial_value: "720" # 720 is 12:00 Noon
|
||||
|
||||
####################################################
|
||||
# boost_timer: counts minutes in BOOST mode
|
||||
# After 'boost_duration' minutes, revert to TIMER.
|
||||
|
||||
@@ -219,11 +219,21 @@ template:
|
||||
unique_id: ha_summary_addons
|
||||
icon: mdi:puzzle
|
||||
state: >-
|
||||
{% set a = states.update | selectattr('entity_id','in', integration_entities('hassio')) | list %}
|
||||
{% set b = states.update | selectattr('attributes.attribution','search','Supervisor') | list %}
|
||||
{{ (a + b) | unique | list
|
||||
| rejectattr('entity_id','search','^update\\.home_assistant_(core|supervisor|operating_system)_update$')
|
||||
| list | length }}
|
||||
{% set hassio_updates = (integration_entities('hassio') | list) %}
|
||||
{% set a = states.update
|
||||
| selectattr('entity_id','in', hassio_updates)
|
||||
| map(attribute='entity_id')
|
||||
| list %}
|
||||
{% set b = states.update
|
||||
| selectattr('attributes.attribution','defined')
|
||||
| selectattr('attributes.attribution','search','Supervisor')
|
||||
| map(attribute='entity_id')
|
||||
| list %}
|
||||
{% set ids = (a + b)
|
||||
| unique
|
||||
| reject('search','^update\\.home_assistant_(core|supervisor|operating_system)_update$')
|
||||
| list %}
|
||||
{{ ids | length }}
|
||||
|
||||
# ---------- HACS updates available (proxy only) ----------
|
||||
- name: HA Summary - hacs updates
|
||||
|
||||
@@ -61,7 +61,6 @@ template:
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{{ ns.e }}
|
||||
names: >
|
||||
@@ -75,6 +74,5 @@ template:
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{{ ns.n }}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
sensor:
|
||||
- platform: derivative
|
||||
name: Main Bathroom Humidity Change Rate
|
||||
source: sensor.main_bathroom_environment_zth04_humidity
|
||||
source: sensor.main_bathroom_environment_zth10_humidity_2
|
||||
round: 1
|
||||
unit_time: s # the resulting "unit_of_measurement" will be %H/s if the sensor.temperate has set %H as its unit
|
||||
time_window: "00:00:10" # we look at the change over the last 10 seconds
|
||||
|
||||
Reference in New Issue
Block a user