Files
zorruno-homeassistant/esphome/esp-weatherstation.yaml
2024-05-27 22:20:04 +12:00

856 lines
29 KiB
YAML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#############################################
#############################################
# Opengreen energy weather station board, with ESP8266 D1 Mini
# https://www.opengreenenergy.com/solar-powered-wifi-weather-station-v2-0/
# zorruno 2024-05-04 V0.0 Untested
# zorruno 2024-05-23 V1.0 Tidied up sensor info and added BMP280
# zorruno 2024-05-24 V1.1 Tested ok and added some V calibration for mine
# zorruno 2024-05-25 V2 A bunch more sensors added (wind direction not yet sorted)
#############################################
#############################################
#############################################
# SENSORS INCLUDED
# 
# TESTED WORKING
# status_led:
# uptime:
# wifi_signal:
# battery voltage (adc A0)
#
# ads1115: 4 Channel A->D (0x48 i2c)
# dht: DHT22 Temp/Humidity, Remote (GPIO15)
# bmp280: Temp/pressure on the board (0x76 i2c)
# pulse_meter: Wind Speed (GPIO13)
#
# text_sensor: Beaufort Wind Scale Labelling
# text:sensor: Temp (av) Average of all temps
# 
# TO TEST (HAVE SENSOR or doesn't need one)
# tsl2561: Ambient Light sensor (0x39 i2c)
# ads1115 A1_GND: UV Index
# ads1115 A0_GND: Wind Direction
# pulse_meter: Rainfall (GPIO??)
# battery life: Time from battery starting to drop (retain)
#
# ORDERED BUT DON'T HAVE YET
# ltr390: Ambient Light and UV sensor (0x53 i2c)
# pmsx003: PM Particulate Filter (UART)
#
# NOT USED (code commented)
# bme280_i2c: Temp/humid/press (not used)
#
# POSSIBLY ADD
# Analogue for Solar V?
# Lightning?
# ground movement/earthquake?
# water sensor (rain now)
#
#############################################
#############################################
# WIND SENSOR
# looks like this one
# https://www.sparkfun.com/datasheets/Sensors/Weather/Weather%20Sensor%20Assembly..pdf
#############################################
#############################################
# USEFUL LINKS
# Wind Sensing
# https://community.home-assistant.io/t/measuring-wind-speed/395693/20
# https://community.home-assistant.io/t/measuring-wind-speed/395693/21
#############################################
#############################################
# Pulse Meter Issues 202405
# https://github.com/esphome/issues/issues/4807
# https://github.com/esphome/issues/issues/3143
#############################################
external_components:
- source: github://TrentHouliston/esphome@loop_pulse_isr
components: [ pulse_meter ]
#############################################
# Variable Substitutions
# Give this a useful name & description here
# and change values accordingly
#############################################
substitutions:
devicename: "esp-weatherstation"
friendly_name: "Weather Station"
description_comment: "Opengreen energy board, with BME280 Temp/Hum/Pres Sensor on an ESP8266 D1 Mini"
api_key: !secret esp-weatherstation_api_key #unfortunately you can't use substitutions in secrets names
ota_pass: !secret esp-weatherstation_ota_pass #unfortunately you can't use substitutions in secrets names
wifi_ssid: !secret wifi_ssid
wifi_pass: !secret wifi_password
mqtt_server: 192.168.3.200
mqtt_topic: "esphome" #main topic for the mqtt server, call it what you like
update_time: 30s #update time for for temp sensors etc
#############################################
# ESPHome
# https://esphome.io/components/esphome.html
#############################################
esphome:
name: ${devicename}
comment: ${description_comment} #appears on the esphome page in HA
#on_boot: #Initial Setting stuff
#priority: -200
#then:
#############################################
# ESP Platform and Framework
# https://esphome.io/components/esp32.html OR
# https://esphome.io/components/esp8266.html
#############################################
#esp32:
# board:
# framework:
# type: arduino
# #type: esp-idf #Suggested Use ESP-IDF Framework for ESP32, or unplugging the UART Cable Might Cause ESP32 Hang.
# version: recommended #recommended, latest or dev
esp8266:
board: d1_mini
#############################################
# i2c bus
# https://esphome.io/components/i2c.html
# Put the relevant pins here, 4/5 are default for ESP8266
# and 21/22 for esp32 (although esp32 can have two buses)
#############################################
i2c:
sda: GPIO4
scl: GPIO5
scan: True
#frequency: 100kHz #10, 50, 100, 200, 800 are possible settings, 100kHz was reliable for me for ESP32, default is 50kHz
#############################################
# ESPHome Logging Enable
# https://esphome.io/components/logger.html
#############################################
logger:
level: DEBUG #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
#############################################
# Enable the Home Assistant API
# https://esphome.io/components/api.html
#############################################
api:
encryption:
key: ${api_key}
#############################################
# Enable Over the Air Update Capability
# https://esphome.io/components/ota.html?highlight=ota
#############################################
ota:
safe_mode: true #Safe mode will detect boot loops
password: ${ota_pass}
#############################################
# Wifi Settings
# https://esphome.io/components/wifi.html
#############################################
wifi:
ssid: ${wifi_ssid}
password: ${wifi_pass}
#power_save_mode: LIGHT #https://esphome.io/components/wifi.html#wifi-power-save-mode
#manual_ip: #optional static IP address
#static_ip: 192.168.x.x
#gateway: 192.168.X.x
#subnet: 255.255.255.0
ap: #Details for fallback hotspot (captive portal) in case wifi connection fails https://esphome.io/components/wifi.html#access-point-mode
ssid: $devicename fallback AP
password: !secret fallback_ap_password
ap_timeout: 5min #default is 1min
#############################################
# Web Portal for display and monitoring
# Turning this off if you don't really need it
# is probably a good idea to save resources.
# Also, don't use it with other big ESP32 components
# such as Bluetooth proxy (it will run out of flash
# and not compile, or it will crash occasionally)
# https://esphome.io/components/web_server.html
#############################################
#web_server:
# port: 80
# version: 1 #V1 occasionally works better, V2 The nicer page
# username: !secret web_server_username #probably a good idea to secure it
# password: !secret web_server_password
#############################################
# MQTT Monitoring
# https://esphome.io/components/mqtt.html?highlight=mqtt
# MUST also have api enabled if you enable MQTT
#############################################
mqtt:
broker: ${mqtt_server}
topic_prefix: ${mqtt_topic}/${devicename}
#username: !secret mqtt_username
#password: !secret mqtt_password
#A way to prevent deep sleep using MQTT command
#on_message:
#- topic: ${mqtt_topic}/${devicename}/deepsleepoff
#payload: 'ON'
#then:
#- deep_sleep.prevent: deep_sleep_1
#- topic: ${mqtt_topic}/${devicename}/deepsleepon
#payload: 'ON'
#then:
#- deep_sleep.enter: deep_sleep_1
########################################
# Deep Sleep
# https://esphome.io/components/deep_sleep.html
########################################
#deep_sleep:
# run_duration: 20s
# sleep_duration: 10min
# id: deep_sleep_1
#############################################
# General espHome status LED
# Not needed, but can be useful to see issues
# https://esphome.io/components/status_led.html
#############################################
status_led:
pin:
number: GPIO2 #Wemos ESP32 and ESP8266 Onboard LEDs use GPIO2
inverted: false
#ignore_strapping_warning: True #https://esphome.io/guides/faq.html#why-am-i-getting-a-warning-about-strapping-pins
################################
# 4 Input A->D sensor
# Analog sensor for voltage reading
# https://esphome.io/components/sensor/ads1115.html
################################
ads1115:
- address: 0x48 #On the ADS1115 pull address pin to VCC for 0x49. Default is 0x48
#############################################
# Text Sensors
# https://esphome.io/components/text_sensor/index.html
#############################################
text_sensor:
- platform: template
name: ${friendly_name} Beaufort Wind Scale
icon: "mdi:tailwind"
id: wind_scale
update_interval: never
- platform: template
name: ${friendly_name} Wind Direction
icon: "mdi:tailwind"
id: wind_dir
update_interval: never
#############################################
# General Sensors
# https://esphome.io/components/sensor/index.html
#############################################
sensor:
################################
# BMP280 temp/pressure
# https://esphome.io/components/sensor/bmp280.html
################################
- platform: bmp280
address: 0x76
iir_filter: 16X
update_interval: ${update_time}
temperature:
name: ${friendly_name} BMP280 Temperature
id: bmp280_temp
unit_of_measurement: "°C"
oversampling: 16x
#retain: true #MQTT retain useful if sleeping
pressure:
name: ${friendly_name} BMP280 Pressure
unit_of_measurement: "hPa"
oversampling: 16X
#retain: true #MQTT retain useful if sleeping
################################
# BME280 temp/humidity/pressure
# https://esphome.io/cookbook/bme280_environment.html
################################
#- platform: bme280_i2c
# address: 0x76
# update_interval: ${update_time}
# temperature:
# name: ${friendly_name} BME280 Temp
# accuracy_decimals: 1
# oversampling: 2x
# unit_of_measurement: "°C"
# #retain: true #MQTT retain useful if sleeping
# pressure:
# name: ${friendly_name} BME280 Pressure
# oversampling: 2x
# unit_of_measurement: "hPa"
# #retain: true #MQTT retain useful if sleeping
# humidity:
# name: ${friendly_name} BME280 Humidity
# accuracy_decimals: 1
# oversampling: 2x
# unit_of_measurement: "%"
# #retain: true #MQTT retain useful if sleeping
################################
# DHT temp/humidity
# https://esphome.io/components/sensor/dht.html
################################
- platform: dht
pin: GPIO15 #D8 on the D1 Mini ESP8266
update_interval: ${update_time}
temperature:
name: ${friendly_name} DHT22 Temperature
id: dht_temp
unit_of_measurement: "°C"
#retain: true #retain useful if sleeping
humidity:
name: ${friendly_name} DHT22 Humidity
unit_of_measurement: "%"
#retain: true #retain useful if sleeping
################################
# TSL2561 ambient light sensor
# https://esphome.io/components/sensor/tsl2561.html
################################
#- platform: tsl2561
# name: ${friendly_name} Ambient Light
# address: 0x39
# update_interval: 60s
################################
# LTR390 Ambient Light and UV Sensor
# https://esphome.io/components/sensor/ltr390.html
################################
#- platform: ltr390
# address: 0x35
# uv_index:
# name: ${friendly_name} 390 UV Index
# uv:
# name: ${friendly_name} 390 UV Sensor Counts
# light:
# name: ${friendly_name} 390 Light
# ambient_light:
# name: ${friendly_name} 390 UV Sensor Counts
# update_interval: 60s
################################
# PMSX003 Particulate sensor
# NEEDS UART SET FIRST
# https://esphome.io/components/sensor/pmsx003.html
################################
#- platform: pmsx003
# type: PMSX003
# pm_1_0:
# name: ${friendly_name} Particulate Matter <1.0µm
# pm_2_5:
# name: ${friendly_name} <2.5µm
# pm_10_0:
# name: ${friendly_name} <10.0µm Concentration
################################
# Device uptime info
# https://esphome.io/components/sensor/uptime.html
################################
- platform: uptime
name: ${friendly_name} Uptime
################################
# Quality of Wifi in dBm
# https://esphome.io/components/sensor/wifi_signal.html
################################
- platform: wifi_signal
name: ${friendly_name} WiFi Signal
update_interval: ${update_time}
#retain: true #retain useful if sleeping
################################
# Analog sensor for voltage reading
# (A0 on esp8266)
# https://esphome.io/components/sensor/adc.html
################################
- platform: adc
name: ${friendly_name} Battery Voltage
id: battery_voltage
pin: A0
unit_of_measurement: "V"
accuracy_decimals: 5
update_interval: ${update_time}
#retain: true #retain useful if sleeping
filters:
- multiply: 5.223 # tested with multimeter
- calibrate_linear:
- 3.89 -> 3.90
- 3.85 -> 3.92
- 4.09 -> 4.14
- platform: template
name: ${friendly_name} Av Battery Voltage over 5 mins
id: battery_voltage_5minav
unit_of_measurement: "V"
accuracy_decimals: 5
update_interval: 30s #updates every 30s
lambda: >
return id(battery_voltage).state; //grabs values from the battery_voltage
filters:
- sliding_window_moving_average:
window_size: 20 #20x 30s = 10 mins
send_every: 1
send_first_at: 1
- platform: duty_time
id: battery_discharge_time
name: ${friendly_name} Time battery is discharging
unit_of_measurement: "Mins"
retain: true #retain this as when device dies, we still want the value
# Support logical sources (optional): 'binary_sensor'
accuracy_decimals: 0
filters:
- multiply: 0.01666666
- round: 0
lambda: >
return { id(battery_voltage).state <= id(battery_voltage_5minav).state };
################################
# Wind Direction, Analogue on ADS115
# Analog sensor for voltage reading
# https://esphome.io/components/sensor/ads1115.html
################################
# Using a analog wind direction sensor that has an output
# of 0 - 5 V for 360° representing the position of the arrow
# from the north pole. This is 5V divided by 8 resistor
# values giving the output voltage value for each azimuth.
# We could also report a compass direction.
################################
- platform: ads1115
multiplexer: 'A0_GND'
gain: 6.144
name: ${friendly_name} Wind Direction
id: wind_direction
update_interval: 5s
# filters:
# lambda: |-
# if( (x * (360.0/5.0)) >= 10.0 && (x * (360.0/5.0)) <= 70.0 ) { return x = 45 };
# else if( (x * (360.0/5.0)) > 70.0 && (x * (360.0/5.0)) <= 120.0 ) { return x = 90 };
# else if( (x * (360.0/5.0)) > 120.0 && (x * (360.0/5.0)) <= 170.0 ) { return x = 135 };
# else if( (x * (360.0/5.0)) > 170.0 && (x * (360.0/5.0)) <= 215.0 ) { return x = 180 };
# else if( (x * (360.0/5.0)) > 215.0 && (x * (360.0/5.0)) <= 262.0 ) { return x = 225 };
# else if( (x * (360.0/5.0)) > 262.0 && (x * (360.0/5.0)) <= 330.0 ) { return x = 270 };
# else if( (x * (360.0/5.0)) > 330.0 && (x * (360.0/5.0)) <= 355.0 ) { return x = 315 };
# else if(((x * (360.0/5.0)) > 355.0 && (x * (360.0/5.0)) <= 360.0) || ((x * (360.0/5.0)) >= 0.0 && (x * (360.0/5.0)) <= 10.0)) { return x = 0 };
# - platform: template
# name: ${friendly_name} Winddirection Degrees
# id: wind_direction_voltage
# lambda: return id(wind_direction_voltage).state;
# unit_of_measurement: "degrees"
# update_interval: 5s
# filters:
# - throttle_average: 5s
# on_value:
# lambda: |-
# if (id(wind_direction_voltage).state * (360.0/5.0) >= 10.0 && id(wind_direction_voltage).state * (360.0/5.0) <= 70.0) {
# id(wind_dir).publish_state("45");
# } else if (id(wind_direction_voltage).state * (360.0/5.0) = 70.0 && id(wind_direction_voltage).state * (360.0/5.0) <= 120.0) {
# id(wind_dir).publish_state("90");
# } else if (id(wind_direction_voltage).state * (360.0/5.0) = 120.0 && id(wind_direction_voltage).state * (360.0/5.0) <= 170.0) {
# id(wind_dir).publish_state("135");
# } else if (id(wind_direction_voltage).state * (360.0/5.0) = 170.0 && id(wind_direction_voltage).state * (360.0/5.0) <= 215.0) {
# id(wind_dir).publish_state("180");
# } else if (id(wind_direction_voltage).state * (360.0/5.0) = 215.0 && id(wind_direction_voltage).state * (360.0/5.0) <= 262.0) {
# id(wind_dir).publish_state("225");
# } else if (id(wind_direction_voltage).state * (360.0/5.0) = 262.0 && id(wind_direction_voltage).state * (360.0/5.0) <= 330.0) {
# id(wind_dir).publish_state("270");
# } else if (id(wind_direction_voltage).state * (360.0/5.0) = 330.0 && id(wind_direction_voltage).state * (360.0/5.0) <= 355.0) {
# id(wind_dir).publish_state("315");
# } else if (id(wind_direction_voltage).state * (360.0/5.0) = 355.0 && id(wind_direction_voltage).state * (360.0/5.0) <= 360.0) {
# id(wind_dir).publish_state("0");
# } else {
# id(wind_dir).publish_state("0");
# }
# - platform: ads1115
# multiplexer: "A1_GND"
# gain: 6.144
# name: ${friendly_name} UV Index
# update_interval: 10s
# unit_of_measurement: "mW/cm2"
# accuracy_decimals: 1
# - platform: pulse_meter
# pin:
# number: GPIO13 #This is Pin D7 on the D1 Mini ESP8266
# mode:
# input: true
# pullup: true
# name: ${friendly_name} Wind speed
# id: wind_meter
# unit_of_measurement: m/s
# accuracy_decimals: 1
# timeout: 5s
# internal_filter_mode: EDGE
# internal_filter: 10ms
# A wind speed of 2.4km/h (1.492mph) causes the switch to close once per second.
# that is 0.667m/s.
# Switch closes twice per revolution
# rotations_per_sec = pulses / 2 / 60
# circ_m = 0.09 * 2 * 3.14 = 0.5652
# mps = 1.18 * circ_m * rotations_per_sec
# mps = 1.18 * (0.5652 / 2 / 60) = 0.0055578
#
# filters:
# # - multiply: 0.0055578 #use for m/s
# # - multiply: 2.237 #m/s to mph
# # - multiply: 0.0124327986 #m/s * mph conversion
# # - multiply: ? #m/s to kph
# - multiply: 0.0055578
# - sliding_window_moving_average: # Helps prevent too many datapoints
# window_size: 10
# send_every: 10
################################
# Pulse Meter for measuring wind speed
# Analog sensor for voltage reading
# https://esphome.io/components/sensor/pulse_meter.html
#
# This Anenometer https://www.sparkfun.com/datasheets/Sensors/Weather/Weather%20Sensor%20Assembly..pdf
#
# The cup-type anemometer measures wind speed by closing a contact
# as a magnet moves past a reed switch. A wind speed of 1.492mph (2.4km/h) (0.667m/s)
# causes the switch to close once per second. The reed switch closes twice per revolution.
# 1rps = 60rpm = 2.4kmh
# 1pulse/min = 2.4kmh/60 = 0.04kmh
# Pulse meter component measures the time between rising edges on a pin,
# for each pulse it outputs the frequency in pulses/min.
################################
- platform: pulse_meter # https://community.home-assistant.io/t/measuring-wind-speed/395693
id: wind_meter
pin:
number: GPIO13
mode:
input: true
pullup: true
#internal: true # If true, don't send to HA/MQTT etc
internal_filter_mode: EDGE
internal_filter: 10ms
name: ${friendly_name} Wind speed
icon: "mdi:weather-windy"
unit_of_measurement: "km/h"
accuracy_decimals: 1
timeout: 5s
filters:
- timeout:
timeout: "5s" #after 5 seconds, if no pulses received....
value: 0 #make the value = 0
- multiply: 0.04 #kmh
- sliding_window_moving_average: # Moving average to prevent too many data points
window_size: 10
send_every: 10
- clamp:
min_value: 0
max_value: 250 #if anything over that, we have debounce issues or are going to die
ignore_out_of_range: true
# on_value:
# lambda: |-
# if(x > id(g_WindGust_10min)) {
# id(g_WindGust_10min) = x;
# id(id_wind_gust_10min).publish_state(id(g_WindGust_10min));
# };
# //id(g_wind_run) += (x>0) ? 0.000666982 : 0;
# if(x > id(g_WindGust_10s)) {
# id(g_WindGust_10s) = x;
# id(id_wind_gust_10s).publish_state(id(g_WindGust_10s));
# };
# if(x > id(g_WindGust_60s)) {
# id(g_WindGust_60s) = x;
# id(id_wind_gust_60s).publish_state(id(g_WindGust_60s));
# };
# if(id(g_WindSpeedMin_Reset)){
# id(g_WindSpeedMin_10s) = x;
# id(g_WindSpeedMin_Reset) = false;
# } else {
# if(x < id(g_WindSpeedMin_10s)) {id(g_WindSpeedMin_10s) = x;};
# }
# total:
# name: "Roof Wind Run daily"
# id: id_wind_run_daily
# internal: false
# unit_of_measurement: "km"
# accuracy_decimals: 3
# filters:
# - multiply: 0.000666982
# - throttle: 30s
- platform: template
name: ${friendly_name} Windspeed Gust (Max last 10m)
unit_of_measurement: "km/h"
update_interval: 2s #updates every 2s
lambda: >
return id(wind_meter).state; //grabs values from the wind_sensor
filters:
- filter_out: nan #in case there is no value
- max:
window_size: 300 #10 Min window as 2s update x 300 = 10min
send_every: 1 #updates on the 1st 2s check
send_first_at: 1 #on restart, send after first 10s
# https://www.reddit.com/r/Esphome/comments/kndues/take_max_value_over_time/
# - platform: template
# name: ${friendly_name} Windspeed last 10min max
# #id: ${node_name}_pm_1_0_rolling_30_minute_average
# unit_of_measurement: "km/h"
# update_interval: 60s
# lambda: |-
# const size_t window_size_ = 10;
# const size_t send_every_ = 10;
# static size_t send_at_ = 0;
# static std::deque<float> queue_;
# if (!isnan(x)) {
# if (queue_.size() >= window_size_) {
# queue_.pop_front();
# }
# queue_.push_back(x);
# }
# if (++send_at_ >= send_every_) {
# send_at_ = 0;
# if (!queue_.empty()) {
# std::deque<float>::iterator it = std::max_element(queue_.begin(), queue_.end());
# return *it;
# }
# return 0.0f;
# }
# return {};
# - platform: template
# name: "Roof Wind Run daily"
# icon: "mdi:weather-windy"
# unit_of_measurement: "km"
# accuracy_decimals: 3
# update_interval: 30s
# internal: true
# lambda: |-
# return id(g_wind_run_count)*0.000666982;
# id: id_wind_run_daily_g
# - platform: template
# name: "Roof Wind gust 10s"
# unit_of_measurement: 'km/h'
# update_interval: 10s
# id: id_wind_gust_10s
# lambda: return id(g_WindGust_10s);
#
# - platform: template
# name: "Roof Wind gust 60s"
# unit_of_measurement: 'km/h'
# state_class: "measurement"
# update_interval: 60s
# id: id_wind_gust_60s
# lambda: return id(g_WindGust_60s);
# - platform: template
# name: "Roof Wind gust 10min"
# unit_of_measurement: 'km/h'
# state_class: "measurement"
# update_interval: 10min
# id: id_wind_gust_10min
# lambda: return id(g_WindGust_10min);
# - platform: template
# name: "Roof Wind speed avg 1s"
# unit_of_measurement: 'km/h'
# update_interval: 333ms
# lambda: |-
# return id(id_wind_speed).state;
# filters:
# throttle_average: 1s
# id: id_wind_speed_avg_1s
#
# - platform: template
# name: "Roof Wind speed avg 10s"
# unit_of_measurement: 'km/h'
# update_interval: 333ms
# lambda: |-
# return id(id_wind_speed).state;
# filters:
# throttle_average: 10s
# id: id_wind_speed_avg_10s
#
# - platform: template
# name: "Roof Wind Speed Min 10s"
# unit_of_measurement: 'km/h'
# id: id_wind_speed_min_10s
#
# - platform: template
# name: "Roof Wind speed avg 1min"
# unit_of_measurement: 'km/h'
# state_class: "measurement"
# update_interval: '1s'
# lambda: |-
# return id(id_wind_speed).state;
# filters:
# - throttle_average: 1min
# id: id_wind_speed_avg_1min
#
# - platform: template
# name: "Roof Wind speed avg 10min"
# unit_of_measurement: 'km/h'
# state_class: "measurement"
# update_interval: 1s
# lambda: |-
# return id(id_wind_speed).state;
# filters:
# - throttle_average: 10min
# id: id_wind_speed_avg_10min
################################
# Averaging for the various temp sensors on board
################################
- platform: template
name: ${friendly_name} Temp (av)
icon: "mdi:thermometer"
unit_of_measurement: "°C"
lambda: |-
return (
id(bmp280_temp).state
+
id(dht_temp).state
) / 2;
################################
# Template for Beaufort for measuring wind speed
# https://windy.app/blog/wind-speed-beaufort-scale.html
################################
# - platform: template
# name: ${friendly_name} Windspeed Scale
# icon: "mdi:weather-windy"
# id: wind_meter_scale
# lambda: return id(wind_meter).state;
# unit_of_measurement: "m/s"
# update_interval: 5s
# filters:
# - throttle_average: 5s
# on_value:
# lambda: |-
# if (id(wind_meter_scale).state < 0.1) {
# id(wind_scale).publish_state("Calm");
# } else if (id(wind_meter_scale).state > 0 && id(wind_meter_scale).state < 2) {
# id(wind_scale).publish_state("Light Air");
# } else if (id(wind_meter_scale).state >= 2 && id(wind_meter_scale).state < 3) {
# id(wind_scale).publish_state("Light Breeze");
# } else if (id(wind_meter_scale).state >= 3 && id(wind_meter_scale).state < 5) {
# id(wind_scale).publish_state("Gentle Breeze");
# } else if (id(wind_meter_scale).state >= 5 && id(wind_meter_scale).state < 8) {
# id(wind_scale).publish_state("Moderate Breeze");
# } else if (id(wind_meter_scale).state >= 8 && id(wind_meter_scale).state < 11) {
# id(wind_scale).publish_state("Fresh Breeze");
# } else if (id(wind_meter_scale).state >= 11 && id(wind_meter_scale).state < 14) {
# id(wind_scale).publish_state("Strong Breeze");
# } else if (id(wind_meter_scale).state >= 14 && id(wind_meter_scale).state < 17) {
# id(wind_scale).publish_state("Near Gale");
# } else if (id(wind_meter_scale).state >= 17 && id(wind_meter_scale).state < 21) {
# id(wind_scale).publish_state("Gale");
# } else if (id(wind_meter_scale).state >= 21 && id(wind_meter_scale).state < 24) {
# id(wind_scale).publish_state("Severe Gale");
# } else if (id(wind_meter_scale).state >= 24 && id(wind_meter_scale).state < 28) {
# id(wind_scale).publish_state("Storm");
# } else if (id(wind_meter_scale).state >= 28 && id(wind_meter_scale).state < 33) {
# id(wind_scale).publish_state("Violent Storm");
# } else if (id(wind_meter_scale).state >= 33) {
# id(wind_scale).publish_state("Hurricane Force");
# } else {
# id(wind_scale).publish_state("");
# }
#switch:
# - platform: template
# optimistic: true
# name: switch
# #internal: True
# id: g_WindSpeedMin_Reset
#interval:
# - interval: 10s
# then:
# - lambda: |-
# id(g_WindSpeedMin_Reset).state == true;
# //id(id_wind_gust_10s).publish_state(id(g_WindGust_10s));
# id(id_wind_speed_min_10s).publish_state(id(g_WindSpeedMin_10s));
# //id(id_wind_gust_60s).publish_state(id(g_WindGust_60s));
# //id(id_wind_gust_10min).publish_state(id(g_WindGust_10min));
# id(g_WindGust_10s) = 0;
# // id(g_WindSpeedMin_10s) = 9999.9;
# id(g_WindSpeedMin_Reset) = true;
# - interval: 60s
# then:
# - lambda: |-
# id(g_WindGust_60s) = 0;
# //maintain rain
# //if (++id(g_minute) > 59) id(g_minute) = 0;
# //id(gt_rain_hour)[id(g_minute)] = 0;
# - interval: 10min
# then:
# - lambda: |-
# id(g_WindGust_10min) = 0;
#globals:
# global variables for wind/rain sensors
# - id: g_WindGust_10min
# type: float
# restore_value: no
# initial_value: '0.0'
# - id: g_wind_run_count
# type: int
# restore_value: no
# initial_value: '0'
# - id: g_rain_count
# type: int
# restore_value: no
# initial_value: '0'
# - id: gt_rain_hour
# type: byte[60]
# restore_value: no
# - id: g_minute
# type: byte
# restore_value: no
# initial_value: '0'
# - id: g_WindGust_10s
# type: float
# restore_value: no
# initial_value: '0.0'
# - id: g_WindSpeedMin_10s
# type: float
# restore_value: no
# initial_value: '9999.9'
# - id: g_WindGust_60s
# type: float
# restore_value: no
# initial_value: '0.0'