home-automation/hardware/esphome/plant_dashboard/plant_dashboard.yaml

665 lines
22 KiB
YAML

# Further reference
# https://platformio.org/lib
# SHT1x - 86 - https://platformio.org/lib/show/86/SHT1x
# MAX1704X - 5812 - https://platformio.org/lib/show/5812/MAX1704X/
# GxEPD2 - 5869 - https://platformio.org/lib/show/5869/GxEPD2
# AsyncMqttClient - 346 - https://platformio.org/lib/show/346/AsyncMqttClient/
# Adafruit GFX Library - 13 - https://platformio.org/lib/show/13/Adafruit GFX Library/
# SparkFun VEML6075 Library - 5452 - https://platformio.org/lib/show/5452/SparkFun%20VEML6075%20Arduino%20Library
# Adafruit Seesaw - 1890 - https://platformio.org/lib/show/1890/Adafruit%20seesaw%20Library
# Node Config
esphome:
name: !secret node_name
platform: ESP32
board: featheresp32
platformio_options:
upload_speed: 115200
includes:
- sht1x.h
- max1704xsensor.h
- veml6075.h
- plants.h
libraries:
- SPI
- Wire
- "346"
- "86"
- "5812"
- "5452"
- "1890"
on_boot:
- priority: 90.0 # 100 is highest where early init happens, 50.0 is where sensors come up
then:
- lambda: |-
id(early_boot) = true;
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
delay(100);
- priority: -100
then:
- lambda: |-
id(early_boot) = false;
ESP_LOGD("on_boot: -10:", "Starting sensor updates");
//////////////////////////////////////////////////
ESP_LOGD("on_boot: -10:", "WiFi");
id(sensor_wifi_signal)->update();
ESP_LOGD("on_boot: -10:", "END WiFi");
//////////////////////////////////////////////////
//ESP_LOGD("on_boot: -10:", "UV");
//id(ptr_component_veml6075)->update();
//ESP_LOGD("on_boot: -10:", "END UV");
//////////////////////////////////////////////////
//ESP_LOGD("on_boot: -10:", "delay(500)");
delay(500);
ESP_LOGD("on_boot: -10:", "END delay(500)");
//////////////////////////////////////////////////
ESP_LOGD("on_boot: -10:", "shtx1");
((SHT1xSensor*)id(ptr_component_shtx1))->update();
ESP_LOGD("on_boot: -10:", "END shtx1");
//////////////////////////////////////////////////
ESP_LOGD("on_boot: -10:", "delay(500)");
delay(500);
ESP_LOGD("on_boot: -10:", "END delay(500)");
//////////////////////////////////////////////////
ESP_LOGD("on_boot: -10:", "max1704x");
id(ptr_component_max1704x)->update();
ESP_LOGD("on_boot: -10:", "END max1704x");
//////////////////////////////////////////////////
ESP_LOGD("on_boot: -10:", "delay(500)");
delay(500);
ESP_LOGD("on_boot: -10:", "END delay(500)");
//////////////////////////////////////////////////
ESP_LOGD("on_boot: -10:", "Plants");
id(ptr_component_plants)->update();
ESP_LOGD("on_boot: -10:", "END plants");
//////////////////////////////////////////////////
ESP_LOGD("on_boot: -10:", "delay(500)");
delay(500);
ESP_LOGD("on_boot: -10:", "END delay(500)");
//////////////////////////////////////////////////
ESP_LOGD("on_boot: -10:", "Value sensor_wifi_signal: %.1f", id(sensor_wifi_signal).state);
ESP_LOGD("on_boot: -10:", "Value Temperature_C: %.1f", id(Temperature_C).state);
ESP_LOGD("on_boot: -10:", "Value Temperature_F: %.1f", id(Temperature_F).state);
ESP_LOGD("on_boot: -10:", "Value Humidity: %.1f", id(Humidity).state);
ESP_LOGD("on_boot: -10:", "Value uva: %.1f", id(uva).state);
ESP_LOGD("on_boot: -10:", "Value uvb: %.1f", id(uvb).state);
ESP_LOGD("on_boot: -10:", "Value uv_index: %.1f", id(uv_index).state);
ESP_LOGD("on_boot: -10:", "Value Plant_1_Enabled: %f", id(Plant_1_Enabled).state);
ESP_LOGD("on_boot: -10:", "Value Plant_2_Enabled: %f", id(Plant_2_Enabled).state);
ESP_LOGD("on_boot: -10:", "Value Plant_3_Enabled: %f", id(Plant_3_Enabled).state);
ESP_LOGD("on_boot: -10:", "Value Plant_4_Enabled: %f", id(Plant_4_Enabled).state);
ESP_LOGD("on_boot: -10:", "Value Plant_5_Enabled: %f", id(Plant_5_Enabled).state);
ESP_LOGD("on_boot: -10:", "Value Plant_6_Enabled: %f", id(Plant_6_Enabled).state);
ESP_LOGD("on_boot: -10:", "Value Plant_7_Enabled: %f", id(Plant_7_Enabled).state);
ESP_LOGD("on_boot: -10:", "Value Plant_8_Enabled: %f", id(Plant_8_Enabled).state);
ESP_LOGD("on_boot: -10:", "Value Plant_1: %.1f", id(Plant_1).state);
ESP_LOGD("on_boot: -10:", "Value Plant_2: %.1f", id(Plant_2).state);
ESP_LOGD("on_boot: -10:", "Value Plant_3: %.1f", id(Plant_3).state);
ESP_LOGD("on_boot: -10:", "Value Plant_4: %.1f", id(Plant_4).state);
ESP_LOGD("on_boot: -10:", "Value Plant_5: %.1f", id(Plant_5).state);
ESP_LOGD("on_boot: -10:", "Value Plant_6: %.1f", id(Plant_6).state);
ESP_LOGD("on_boot: -10:", "Value Plant_7: %.1f", id(Plant_7).state);
ESP_LOGD("on_boot: -10:", "Value Plant_8: %.1f", id(Plant_8).state);
ESP_LOGD("on_boot: -10:", "Value Plant_1_Remote_Enabled: %f", id(Plant_1_Remote_Enabled).state);
ESP_LOGD("on_boot: -10:", "Value Plant_2_Remote_Enabled: %f", id(Plant_2_Remote_Enabled).state);
ESP_LOGD("on_boot: -10:", "Value Plant_3_Remote_Enabled: %f", id(Plant_3_Remote_Enabled).state);
ESP_LOGD("on_boot: -10:", "Value Plant_4_Remote_Enabled: %f", id(Plant_4_Remote_Enabled).state);
ESP_LOGD("on_boot: -10:", "Value Plant_5_Remote_Enabled: %f", id(Plant_5_Remote_Enabled).state);
ESP_LOGD("on_boot: -10:", "Value Plant_6_Remote_Enabled: %f", id(Plant_6_Remote_Enabled).state);
ESP_LOGD("on_boot: -10:", "Value Plant_7_Remote_Enabled: %f", id(Plant_7_Remote_Enabled).state);
ESP_LOGD("on_boot: -10:", "Value Plant_8_Remote_Enabled: %f", id(Plant_8_Remote_Enabled).state);
ESP_LOGD("on_boot: -10:", "Value Battery_Voltage: %.1f", id(Battery_Voltage).state);
ESP_LOGD("on_boot: -10:", "Value Battery_Level: %.1f", id(Battery_Level).state);
ESP_LOGD("on_boot: -10:", "Value Battery_Sleeping: %.1f", id(Battery_Sleeping).state);
ESP_LOGD("on_boot: -10:", "Value Battery_Alert: %.1f", id(Battery_Alert).state);
ESP_LOGD("on_boot: -10:", "Value Battery_Threshold: %.1f", id(Battery_Threshold).state);
//////////////////////////////////////////////////
ESP_LOGD("on_boot: -10:", "Display");
id(display_main).clear();
id(display_main).update();
ESP_LOGD("on_boot: -10:", "END Display");
//////////////////////////////////////////////////
ESP_LOGD("on_boot: -10:", "END custom");
delay(500);
// Go to deep sleep if NOT in OTA mode
if (! id(ota_mode)) {
id(deep_sleep_main)->begin_sleep();
}
on_shutdown:
then:
- lambda: |-
digitalWrite(13, LOW);
# Basic status infos via blinky LED
# https://esphome.io/components/status_led.html
status_led:
pin:
number: 32
inverted: True
# WiFi config
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
domain: !secret node_domain
power_save_mode: light
# Enable I2C (Qwiic and others)
i2c:
# Enable SPI
# CLK: D5
# MOSI: D18
spi:
clk_pin: 5
mosi_pin: 18
deep_sleep:
id: deep_sleep_main
run_duration: 15min
sleep_duration: 6h
wakeup_pin_mode: INVERT_WAKEUP # stop caring and be judicious about tolerance of goofy pin modes
# Enable logging
logger:
level: DEBUG # Flip to ERROR for production deployments
baud_rate: 115200 # Disable UART logging
# Enable Home Assistant API
#api:
# password: !secret api_password
# OTA Config
ota:
password: !secret ota_password
safe_mode: true
# Web Server (DISABLE outside of testing)
#web_server:
# port: 80
# MQTT CLIENT
mqtt:
broker: !secret mqtt_client_broker
port: 8883
username: !secret mqtt_client_username
password: !secret mqtt_client_password
birth_message:
topic: 'ha/status'
payload: 'online'
will_message:
topic: 'ha/status'
payload: 'offline'
globals:
- id: ptr_component_shtx1
type: "SHT1xSensor*"
restore_value: no
- id: ptr_component_veml6075
type: "VEML6075Sensor*"
restore_value: no
- id: ptr_component_max1704x
type: "MAX1704xSensor*"
restore_value: no
- id: ptr_component_plants
type: "PlantsSensor*"
restore_value: no
- id: early_boot
type: bool
restore_value: no
- id: ota_mode
type: bool
restore_value: no
initial_value: "false"
time:
- platform: sntp
id: sntp_time
servers: 10.5.5.2
binary_sensor:
- platform: status
name: "Status"
- platform: gpio
name: "OTA Button"
id: button_ota
internal: true
pin:
number: A3
mode: INPUT_PULLDOWN
on_release:
then:
- lambda: |-
id(ota_mode) = true;
- deep_sleep.prevent: deep_sleep_main
sensor:
- platform: wifi_signal
id: sensor_wifi_signal
name: "WiFi_Signal"
update_interval: 3min
unit_of_measurement: "dB"
accuracy_decimals: 1
expire_after: 12h
- platform: custom
lambda: |-
SHT1xSensor* sht1x = new SHT1xSensor();
id(ptr_component_shtx1) = sht1x;
App.register_component(sht1x);
return {sht1x->temp_c_sensor, sht1x->temp_f_sensor, sht1x->humidity_sensor};
sensors:
- name: "Temperature_C"
id: Temperature_C
unit_of_measurement: "°C"
accuracy_decimals: 1
expire_after: 12h
- name: "Temperature_F"
id: Temperature_F
unit_of_measurement: "°F"
accuracy_decimals: 1
expire_after: 12h
- name: "Humidity"
id: Humidity
unit_of_measurement: "%"
accuracy_decimals: 1
expire_after: 12h
- platform: custom
lambda: |-
VEML6075Sensor* veml6075 = new VEML6075Sensor();
id(ptr_component_veml6075) = veml6075;
App.register_component(veml6075);
return {veml6075->uva_sensor, veml6075->uvb_sensor, veml6075->uv_index_sensor};
sensors:
- name: "UVA"
id: uva
accuracy_decimals: 2
expire_after: 12h
- name: "UVB"
id: uvb
accuracy_decimals: 2
expire_after: 12h
- name: "UV Index"
id: uv_index
accuracy_decimals: 2
expire_after: 12h
- platform: custom
lambda: |-
PlantsSensor* plants = new PlantsSensor();
id(ptr_component_plants) = plants;
App.register_component(plants);
return {plants->plant_1_enabled, plants->plant_2_enabled, plants->plant_3_enabled, plants->plant_4_enabled, plants->plant_5_enabled, plants->plant_6_enabled, plants->plant_7_enabled, plants->plant_7_enabled, plants->plant_1_sensor, plants->plant_2_sensor, plants->plant_3_sensor, plants->plant_4_sensor, plants->plant_5_sensor, plants->plant_6_sensor, plants->plant_7_sensor, plants->plant_8_sensor, plants->plant_1_remote_enabled, plants->plant_2_remote_enabled, plants->plant_3_remote_enabled, plants->plant_4_remote_enabled, plants->plant_5_remote_enabled, plants->plant_6_remote_enabled, plants->plant_7_remote_enabled, plants->plant_8_remote_enabled };
sensors:
- name: "Plant 1 - Enabled"
id: Plant_1_Enabled
expire_after: 12h
- name: "Plant 2 - Enabled"
id: Plant_2_Enabled
expire_after: 12h
- name: "Plant 3 - Enabled"
id: Plant_3_Enabled
expire_after: 12h
- name: "Plant 4 - Enabled"
id: Plant_4_Enabled
expire_after: 12h
- name: "Plant 5 - Enabled"
id: Plant_5_Enabled
expire_after: 12h
- name: "Plant 6 - Enabled"
id: Plant_6_Enabled
expire_after: 12h
- name: "Plant 7 - Enabled"
id: Plant_7_Enabled
expire_after: 12h
- name: "Plant 8 - Enabled"
id: Plant_8_Enabled
expire_after: 12h
- name: "Plant 1"
id: Plant_1
accuracy_decimals: 2
expire_after: 12h
- name: "Plant 2"
id: Plant_2
accuracy_decimals: 2
expire_after: 12h
- name: "Plant 3"
id: Plant_3
accuracy_decimals: 2
expire_after: 12h
- name: "Plant 4"
id: Plant_4
accuracy_decimals: 2
expire_after: 12h
- name: "Plant 5"
id: Plant_5
accuracy_decimals: 2
expire_after: 12h
- name: "Plant 6"
id: Plant_6
accuracy_decimals: 2
expire_after: 12h
- name: "Plant 7"
id: Plant_7
accuracy_decimals: 2
expire_after: 12h
- name: "Plant 8"
id: Plant_8
accuracy_decimals: 2
expire_after: 12h
- name: "Plant 1 - Remote - Enabled"
id: Plant_1_Remote_Enabled
expire_after: 12h
- name: "Plant 2 - Remote - Enabled"
id: Plant_2_Remote_Enabled
expire_after: 12h
- name: "Plant 3 - Remote - Enabled"
id: Plant_3_Remote_Enabled
expire_after: 12h
- name: "Plant 4 - Remote - Enabled"
id: Plant_4_Remote_Enabled
expire_after: 12h
- name: "Plant 5 - Remote - Enabled"
id: Plant_5_Remote_Enabled
expire_after: 12h
- name: "Plant 6 - Remote - Enabled"
id: Plant_6_Remote_Enabled
expire_after: 12h
- name: "Plant 7 - Remote - Enabled"
id: Plant_7_Remote_Enabled
expire_after: 12h
- name: "Plant 8 - Remote - Enabled"
id: Plant_8_Remote_Enabled
expire_after: 12h
- platform: custom
lambda: |-
MAX1704xSensor* max1704x = new MAX1704xSensor();
id(ptr_component_max1704x) = max1704x;
App.register_component(max1704x);
return {max1704x->voltageSensor, max1704x->percentSensor, max1704x->isSleepingSensor, max1704x->alertIsActiveSensor, max1704x->getThresholdSensor};
sensors:
- name: "Battery_Voltage"
id: Battery_Voltage
unit_of_measurement: "V"
accuracy_decimals: 2
expire_after: 12h
- name: "Battery_Level"
id: Battery_Level
unit_of_measurement: "%"
accuracy_decimals: 1
expire_after: 12h
- name: "Battery_Sleeping"
id: Battery_Sleeping
expire_after: 12h
- name: "Battery_Alert"
id: Battery_Alert
expire_after: 12h
- name: "Battery_Threshold"
id: Battery_Threshold
accuracy_decimals: 0
expire_after: 12h
# 2.9" Waveshare e-ink setup
# BUSY -> 21, RST -> 14, DC -> 15, CS -> 27, CLK -> SCK(5), DIN -> MOSI(18), GND -> GND, 3.3V -> 3.3V
display:
- platform: waveshare_epaper
id: display_main
cs_pin: 27
dc_pin: 15
busy_pin: 21
reset_pin: 14
model: 2.90in
rotation: 90
update_interval: 1h
lambda: |-
if (id(early_boot)) {
it.clear();
it.image(84, 0, id(rocket_ship));
}
else {
delay(60*1000);
// Clear
it.clear();
// Battery
if (id(Battery_Level).state > 90) {
it.image(0, 0, id(battery_100));
}
else if (id(Battery_Level).state > 75) {
it.image(0, 0, id(battery_75));
}
else if (id(Battery_Level).state > 50) {
it.image(0, 0, id(battery_50));
}
else if (id(Battery_Level).state > 25) {
it.image(0, 0, id(inverted_battery_25));
}
else {
it.image(0, 0, id(inverted_battery_0));
}
if (id(Battery_Alert).state != 0) {
it.image(32, 0, id(alert_filled));
}
else {
it.printf(32, 16, id(deja_vu_mono), "%.1f%%", id(Battery_Level).state);
}
// Temperature
it.image(116, 0, id(thermometer)); // 148, 0
it.printf(153, 16, id(deja_vu_mono), "%.1f°F", id(Temperature_F).state);
// OTA Mode
if (id(ota_mode)) {
it.image(259, 0, id(ota_mode_enabled));
}
// Last update
it.image(0, 32, id(last_sync_icon));
it.strftime(32, 39, id(deja_vu_mono), "%Y-%m-%d %H:%M", id(sntp_time).now());
// Plants
//if (id(Plant_1_Remote_Enabled).state) {
// it.image(0, 64, id(vase));
//}
//else {
// it.image(0, 64, id(disabled_vase));
//}
if (id(Plant_2_Remote_Enabled).state) {
it.image(37, 64, id(vase));
}
else {
it.image(37, 64, id(disabled_vase));
}
if (id(Plant_3_Remote_Enabled).state) {
it.image(74, 64, id(vase));
}
else {
it.image(74, 64, id(disabled_vase));
}
if (id(Plant_4_Remote_Enabled).state) {
it.image(111, 64, id(vase));
}
else {
it.image(111, 64, id(disabled_vase));
}
if (id(Plant_5_Remote_Enabled).state) {
it.image(148, 64, id(vase));
}
else {
it.image(148, 64, id(disabled_vase));
}
if (id(Plant_6_Remote_Enabled).state) {
it.image(185, 64, id(vase));
}
else {
it.image(185, 64, id(disabled_vase));
}
if (id(Plant_7_Remote_Enabled).state) {
it.image(222, 64, id(vase));
}
else {
it.image(222, 64, id(disabled_vase));
}
if (id(Plant_8_Remote_Enabled).state) {
it.image(259, 64, id(vase));
}
else {
it.image(259, 64, id(disabled_vase));
}
if (id(Plant_1_Enabled).state) {
if (id(Plant_1).state < 1.0) {
it.image(0, 96, id(inverted_bamboo));
}
else {
it.image(0, 96, id(bamboo));
}
}
else {
it.image(0, 96, id(disabled_tulip));
}
if (id(Plant_2_Enabled).state) {
if (id(Plant_2).state < 500.0) {
it.image(37, 96, id(inverted_cat_nip));
}
else {
it.image(37, 96, id(cat_nip));
}
}
else {
it.image(37, 96, id(disabled_tulip));
}
if (id(Plant_3_Enabled).state) {
it.image(74, 96, id(tulip));
}
else {
it.image(74, 96, id(disabled_tulip));
}
if (id(Plant_4_Enabled).state) {
it.image(111, 96, id(tulip));
}
else {
it.image(111, 96, id(disabled_tulip));
}
if (id(Plant_5_Enabled).state) {
it.image(148, 96, id(tulip));
}
else {
it.image(148, 96, id(disabled_tulip));
}
if (id(Plant_6_Enabled).state) {
it.image(185, 96, id(tulip));
}
else {
it.image(185, 96, id(disabled_tulip));
}
if (id(Plant_7_Enabled).state) {
it.image(222, 96, id(tulip));
}
else {
it.image(222, 96, id(disabled_tulip));
}
if (id(Plant_8_Enabled).state) {
it.image(259, 96, id(tulip));
}
else {
it.image(259, 96, id(disabled_tulip));
}
}
font:
- file: "fonts/DejaVuSansMono.ttf"
id: deja_vu_mono
size: 18
image:
- file: graphics/noun_Alert_2145614.png # empty
id: alert_empty
resize: 32x32
- file: graphics/noun_Alert_2490416.png # filled
id: alert_filled
resize: 32x32
- file: graphics/noun_battery indicator_1601217.png # battery 75%
id: battery_75
resize: 32x32
- file: graphics/noun_battery level_1601219.png # battery 50%
id: battery_50
resize: 32x32
- file: graphics/noun_Cactus_1197535.png # christmas cactus
id: christmas_cactus
resize: 32x32
- file: graphics/noun_empty battery_1601215.png # battery 25%
id: battery_25
resize: 32x32
- file: graphics/noun_empty battery_1601218.png # battery 0%
id: battery_0
resize: 32x32
- file: graphics/noun_Full Battery_1601214.png # battery 100%
id: battery_100
resize: 32x32
- file: graphics/noun_grass_355100.png # cat grass
id: cat_grass
resize: 32x32
- file: graphics/noun_humidity_1762738.png # temp + humidity
id: temp_humidity
resize: 32x32
- file: graphics/noun_leaf_1153077.png # catnip
id: cat_nip
resize: 32x32
- file: graphics/noun_Tarragon_499800.png # tarragon
id: tarragon
resize: 32x32
- file: graphics/noun_Thermometer_217722.png # thermometer
id: thermometer
resize: 32x32
- file: graphics/noun_update_2346502.png # last sync
id: last_sync_icon
resize: 32x32
- file: graphics/inverted_noun_Tarragon_499800.png # inverted tarragon
id: inverted_tarragon
resize: 32x32
- file: graphics/inverted_noun_leaf_1153077.png # inverted catnip
id: inverted_cat_nip
resize: 32x32
- file: graphics/inverted_noun_grass_355100.png # inverted cat grass
id: inverted_cat_grass
resize: 32x32
- file: graphics/inverted_noun_empty battery_1601218.png # inverted battery_0
id: inverted_battery_0
resize: 32x32
- file: graphics/inverted_noun_empty battery_1601215.png # inverted battery_25
id: inverted_battery_25
resize: 32x32
- file: graphics/inverted_noun_Cactus_1197535.png # inverted christmas cactus
id: inverted_christmas_cactus
resize: 32x32
- file: graphics/noun_Tulip_2510353.png # tulip
id: tulip
resize: 32x32
- file: graphics/inverted_noun_Tulip_2510353.png # inverted tulip
id: inverted_tulip
resize: 32x32
- file: graphics/noun_poinsettia_1007994.png # poinsettia
id: poinsettia
resize: 32x32
- file: graphics/inverted_noun_poinsettia_1007994.png # inverted poinsettia
id: inverted_poinsettia
resize: 32x32
- file: graphics/inverted_noun_vase_206668.png # inverted vase
id: inverted_vase
resize: 32x32
- file: graphics/inverted_noun_Bamboo_254221.png # inverted bamboo
id: inverted_bamboo
resize: 32x32
- file: graphics/noun_Bamboo_254221.png # bamboo
id: bamboo
resize: 32x32
- file: graphics/noun_vase_206668.png # vase
id: vase
resize: 32x32
- file: graphics/disabled_noun_vase_206668.png # disabled vase
id: disabled_vase
resize: 32x32
- file: graphics/disabled_noun_Tulip_2510353.png # disabled tulip
id: disabled_tulip
resize: 32x32
- file: graphics/noun_Settings Download_1854756.png # ota mode enabled
id: ota_mode_enabled
resize: 32x32
- file: graphics/noun_startup_1946229.png # rocket ship / startup
id: rocket_ship
resize: 128x128