Bunch of updates from the last year or so (#47)

This commit is contained in:
Chris Nussbaum 2024-07-22 18:34:02 -05:00 committed by GitHub
parent f1df2b3c0c
commit f00cbd65db
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
43 changed files with 317 additions and 292 deletions

View File

@ -11,7 +11,6 @@ Home Assistant is open source home automation that puts local control and privac
## Folder Structure ## Folder Structure
* `/` - Yaml files for my devices and other core files * `/` - Yaml files for my devices and other core files
* `/build` - Technically not included in the repo but all of my devices are configured with this as their build path
* `/components` - Custom components * `/components` - Custom components
* `/custom` - Other custom code that are not components * `/custom` - Other custom code that are not components
* `/images` - Pictures of some of my devices * `/images` - Pictures of some of my devices

View File

@ -2,10 +2,9 @@ substitutions:
device_id: basement-bath-shower-light-heat device_id: basement-bath-shower-light-heat
device_name: Basement Bathroom Shower Light and Heater device_name: Basement Bathroom Shower Light and Heater
board: esp01_1m board: esp01_1m
ip_address: !secret basement-bathroom-shower-light-heat-ip ip_address: !secret basement_bathroom_shower_light_heat_ip
ota_pwd: !secret basement-bathroom-shower-light-heat-ota-pwd api_key: !secret basement_bathroom_shower_light_heat_key
api_key: !secret basement-bathroom-shower-light-heat-key pwd: !secret basement_bathroom_shower_light_heat_pwd
ap_wifi_pwd: !secret basement-bathroom-shower-light-heat-ap-pwd
packages: packages:
device_base: !include ./packages/device_base_esp8266.yaml device_base: !include ./packages/device_base_esp8266.yaml

View File

@ -2,10 +2,9 @@ substitutions:
device_id: basement-bathroom-light-fan device_id: basement-bathroom-light-fan
device_name: Basement Bathroom Light and Fan device_name: Basement Bathroom Light and Fan
board: esp01_1m board: esp01_1m
ip_address: !secret basement-bathroom-light-fan-ip ip_address: !secret basement_bathroom_light_fan_ip
ota_pwd: !secret basement-bathroom-light-fan-ota-pwd api_key: !secret basement_bathroom_light_fan_key
api_key: !secret basement-bathroom-light-fan-key pwd: !secret basement_bathroom_light_fan_pwd
ap_wifi_pwd: !secret basement-bathroom-light-fan-ap-pwd
packages: packages:
device_base: !include ./packages/device_base_esp8266.yaml device_base: !include ./packages/device_base_esp8266.yaml

View File

@ -2,10 +2,9 @@ substitutions:
device_id: basement-bathroom-sensor device_id: basement-bathroom-sensor
device_name: Basement Bathroom Sensor device_name: Basement Bathroom Sensor
board: d1_mini board: d1_mini
ip_address: !secret basement-bathroom-sensor-ip ip_address: !secret basement_bathroom_sensor_ip
ota_pwd: !secret basement-bathroom-sensor-ota-pwd api_key: !secret basement_bathroom_sensor_key
api_key: !secret basement-bathroom-sensor-key pwd: !secret basement_bathroom_sensor_pwd
ap_wifi_pwd: !secret basement-bathroom-sensor-ap-pwd
packages: packages:
device_base: !include ./packages/device_base_esp8266.yaml device_base: !include ./packages/device_base_esp8266.yaml
@ -166,7 +165,7 @@ output:
id: door_gnd id: door_gnd
sensor: sensor:
- platform: bme280 - platform: bme280_i2c
temperature: temperature:
id: temperature id: temperature
name: "Basement Bathroom Temperature" name: "Basement Bathroom Temperature"

View File

@ -1,10 +1,9 @@
substitutions: substitutions:
device_id: basement-fridge device_id: basement-fridge
device_name: Basement Fridge device_name: Basement Fridge
ip_address: !secret basement-fridge-ip ip_address: !secret basement_fridge_ip
ota_pwd: !secret basement-fridge-ota-pwd api_key: !secret basement_fridge_key
api_key: !secret basement-fridge-key pwd: !secret basement_fridge_pwd
ap_wifi_pwd: !secret basement-fridge-ap-pwd
packages: packages:
feit_dimmer: !include ./packages/topgreener_smart_plug.yaml feit_dimmer: !include ./packages/topgreener_smart_plug.yaml

View File

@ -1,10 +1,9 @@
substitutions: substitutions:
device_id: basement-tv device_id: basement-tv
device_name: Basement TV device_name: Basement TV
ip_address: !secret basement-tv-ip ip_address: !secret basement_tv_ip
ota_pwd: !secret basement-tv-ota-pwd api_key: !secret basement_tv_key
api_key: !secret basement-tv-key pwd: !secret basement_tv_pwd
ap_wifi_pwd: !secret basement-tv-ap-pwd
packages: packages:
feit_dimmer: !include ./packages/topgreener_smart_plug.yaml feit_dimmer: !include ./packages/topgreener_smart_plug.yaml

View File

@ -2,10 +2,9 @@ substitutions:
device_id: coffee-maker device_id: coffee-maker
device_name: Coffee Maker device_name: Coffee Maker
board: nodemcuv2 board: nodemcuv2
ip_address: !secret coffee-maker-ip ip_address: !secret coffee_maker_ip
ota_pwd: !secret coffee-maker-ota-pwd api_key: !secret coffee_maker_key
api_key: !secret coffee-maker-key pwd: !secret coffee_maker_pwd
ap_wifi_pwd: !secret coffee-maker-ap-pwd
packages: packages:
device_base: !include ./packages/device_base_esp8266.yaml device_base: !include ./packages/device_base_esp8266.yaml

View File

@ -7,7 +7,7 @@ This an enhanced version of the standard [binary light](https://esphome.io/compo
Using the [External Components](https://esphome.io/components/external_components.html) feature in ESPHome you can add this component to your devices directly from my GitHub repo. Using the [External Components](https://esphome.io/components/external_components.html) feature in ESPHome you can add this component to your devices directly from my GitHub repo.
```yaml ```yaml
external_components: external_components:
- source: github://nuttytree/esphome - source: github://nuttytree/ESPHome-Devices
components: [ binary_light_with_power ] components: [ binary_light_with_power ]
``` ```

View File

@ -82,7 +82,7 @@ class GarageDoorLock : public lock::Lock, public Component
class GarageDoor : public cover::Cover, public Component, public api::CustomAPIDevice { class GarageDoor : public cover::Cover, public Component, public api::CustomAPIDevice {
public: public:
GarageDoor(); GarageDoor();
void set_name(const std::string &name) { Cover::set_name(name); this->lock_comp_->set_name(name); } void set_name(const char *name) { Cover::set_name(name); this->lock_comp_->set_name(name); }
void set_open_duration(uint32_t open_duration) { this->open_duration_ = open_duration; } void set_open_duration(uint32_t open_duration) { this->open_duration_ = open_duration; }
void set_close_duration(uint32_t close_duration) { this->close_duration_ = close_duration; } void set_close_duration(uint32_t close_duration) { this->close_duration_ = close_duration; }
void set_control_output(output::BinaryOutput *control_output) { this->control_output_ = control_output; } void set_control_output(output::BinaryOutput *control_output) { this->control_output_ = control_output; }

View File

@ -7,7 +7,7 @@ This an enhanced version of the standard [gpio switch](https://esphome.io/compon
Using the [External Components](https://esphome.io/components/external_components.html) feature in ESPHome you can add this component to your devices directly from my GitHub repo. Using the [External Components](https://esphome.io/components/external_components.html) feature in ESPHome you can add this component to your devices directly from my GitHub repo.
```yaml ```yaml
external_components: external_components:
- source: github://nuttytree/esphome - source: github://nuttytree/ESPHome-Devices
components: [ gpio_switch_with_power ] components: [ gpio_switch_with_power ]
``` ```

View File

@ -14,7 +14,7 @@ This is component is curently running on a [Shelly 2.5 Double Relay Switch](http
Using the [External Components](https://esphome.io/components/external_components.html) feature in ESPHome you can add this component to your devices directly from my GitHub repo. Using the [External Components](https://esphome.io/components/external_components.html) feature in ESPHome you can add this component to your devices directly from my GitHub repo.
```yaml ```yaml
external_components: external_components:
- source: github://nuttytree/esphome - source: github://nuttytree/ESPHome-Devices
components: [ pool_controller ] components: [ pool_controller ]
``` ```

View File

@ -1,13 +1,9 @@
import esphome.codegen as cg import esphome.codegen as cg
import esphome.config_validation as cv import esphome.config_validation as cv
from esphome.components import time, select, sensor, switch from esphome.components import time, sensor, switch
from esphome.const import ( from esphome.const import (
CONF_ID, CONF_ID,
CONF_TIME_ID, CONF_TIME_ID,
CONF_NAME,
CONF_ICON,
ICON_THERMOMETER,
CONF_DISABLED_BY_DEFAULT,
CONF_MAX_CURRENT, CONF_MAX_CURRENT,
) )
@ -19,6 +15,7 @@ PoolController = pool_controller_ns.class_("PoolController", cg.PollingComponent
CONF_PUMP = "pump" CONF_PUMP = "pump"
CONF_CLEANER = "cleaner" CONF_CLEANER = "cleaner"
CONF_PUMP_SELECT = "pump_select"
CONF_SWITCH_ID = "switch_id" CONF_SWITCH_ID = "switch_id"
CONF_CURRENT_ID = "current_id" CONF_CURRENT_ID = "current_id"
CONF_MIN_CURRENT = "min_current" CONF_MIN_CURRENT = "min_current"

View File

@ -3,11 +3,12 @@
#include "esphome/core/application.h" #include "esphome/core/application.h"
#include "esphome/core/base_automation.h" #include "esphome/core/base_automation.h"
#include "esphome/core/log.h" #include "esphome/core/log.h"
#include "esphome/core/time.h"
namespace esphome { namespace esphome {
namespace pool_controller { namespace pool_controller {
static const char *const TAG = "pool_controller"; static const char *const TAG = "pool.controller";
static const uint32_t RUNTIME_30_MINUTES_PER_HALF_HOUR = UINT32_MAX; static const uint32_t RUNTIME_30_MINUTES_PER_HALF_HOUR = UINT32_MAX;
static const uint32_t RUNTIME_15_MINUTES_PER_HALF_HOUR = 900000; static const uint32_t RUNTIME_15_MINUTES_PER_HALF_HOUR = 900000;
@ -20,24 +21,30 @@ static const uint32_t MINIMUM_AUTOMATION_PUMP_OFF_TIME = 300000;
static const uint32_t MINIMUM_AUTOMATION_PUMP_ON_TIME = 300000; static const uint32_t MINIMUM_AUTOMATION_PUMP_ON_TIME = 300000;
PoolController::PoolController() { PoolController::PoolController() {
ESP_LOGD(TAG, "Creating pump mode select component"); ESP_LOGCONFIG(TAG, "Creating pump mode select component");
this->pump_select_ = new PoolSelect(); this->pump_select_ = new PoolSelect();
App.register_component(this->pump_select_); App.register_component(this->pump_select_);
App.register_select(this->pump_select_); App.register_select(this->pump_select_);
this->pump_select_->set_name("Pool Pump Mode"); this->pump_select_->set_name("Pool Pump Mode");
this->pump_select_->set_object_id("pump_select");
this->pump_select_->set_icon("mdi:pump"); this->pump_select_->set_icon("mdi:pump");
this->pump_select_->set_disabled_by_default(false);
this->pump_select_->traits.set_options({"Off", "Normal", "Always Except Peak", "Always"}); this->pump_select_->traits.set_options({"Off", "Normal", "Always Except Peak", "Always"});
this->pump_select_->set_initial_option("Off");
this->pump_select_->add_on_state_callback([this](const std::string &value, size_t index) { this->pump_select_->add_on_state_callback([this](const std::string &value, size_t index) {
this->pump_mode_ = static_cast<PumpMode>(index); this->pump_mode_ = static_cast<PumpMode>(index);
}); });
ESP_LOGD(TAG, "Creating cleaner mode select component"); ESP_LOGCONFIG(TAG, "Creating cleaner mode select component");
this->cleaner_select_ = new PoolSelect(); this->cleaner_select_ = new PoolSelect();
App.register_component(this->cleaner_select_); App.register_component(this->cleaner_select_);
App.register_select(this->cleaner_select_); App.register_select(this->cleaner_select_);
this->cleaner_select_->set_name("Pool Cleaner Mode"); this->cleaner_select_->set_name("Pool Cleaner Mode");
this->cleaner_select_->set_object_id("cleaner_select");
this->cleaner_select_->set_icon("mdi:robot-vacuum"); this->cleaner_select_->set_icon("mdi:robot-vacuum");
this->cleaner_select_->set_disabled_by_default(false);
this->cleaner_select_->traits.set_options({"Off", "Normal", "When Pump Is On"}); this->cleaner_select_->traits.set_options({"Off", "Normal", "When Pump Is On"});
this->cleaner_select_->set_initial_option("Off");
this->cleaner_select_->add_on_state_callback([this](const std::string &value, size_t index) { this->cleaner_select_->add_on_state_callback([this](const std::string &value, size_t index) {
this->cleaner_mode_ = static_cast<CleanerMode>(index); this->cleaner_mode_ = static_cast<CleanerMode>(index);
}); });
@ -72,8 +79,10 @@ void PoolController::set_time(time::RealTimeClock *time) {
void PoolController::set_pump_switch(switch_::Switch *pump_switch) { void PoolController::set_pump_switch(switch_::Switch *pump_switch) {
this->pump_switch_ = new PumpSwitch(pump_switch); this->pump_switch_ = new PumpSwitch(pump_switch);
App.register_component(this->pump_switch_);
App.register_switch(this->pump_switch_); App.register_switch(this->pump_switch_);
this->pump_switch_->set_name("Pool Pump");
this->pump_switch_->set_object_id("controller_managed_pump_switch");
this->pump_switch_->set_icon("mdi:pump");
this->pump_switch_->add_turn_off_check([this]() -> bool { this->pump_switch_->add_turn_off_check([this]() -> bool {
ESP_LOGD(TAG, "Pump switch turn off check is checking the state of the pool cleaner"); ESP_LOGD(TAG, "Pump switch turn off check is checking the state of the pool cleaner");
if (this->cleaner_switch_->state) { if (this->cleaner_switch_->state) {
@ -81,12 +90,15 @@ void PoolController::set_pump_switch(switch_::Switch *pump_switch) {
} }
return this->cleaner_switch_->get_current_off_time() > 5000; return this->cleaner_switch_->get_current_off_time() > 5000;
}); });
App.register_component(this->pump_switch_);
} }
void PoolController::set_cleaner_switch(switch_::Switch *cleaner_switch) { void PoolController::set_cleaner_switch(switch_::Switch *cleaner_switch) {
this->cleaner_switch_ = new PumpSwitch(cleaner_switch); this->cleaner_switch_ = new PumpSwitch(cleaner_switch);
App.register_component(this->cleaner_switch_);
App.register_switch(this->cleaner_switch_); App.register_switch(this->cleaner_switch_);
this->cleaner_switch_->set_name("Pool Cleaner");
this->cleaner_switch_->set_object_id("controller_managed_cleaner_switch");
this->cleaner_switch_->set_icon("mdi:robot-vacuum");
this->cleaner_switch_->add_turn_on_check([this]() { this->cleaner_switch_->add_turn_on_check([this]() {
ESP_LOGD(TAG, "Cleaner switch turn on check is checking the state of the pool pump"); ESP_LOGD(TAG, "Cleaner switch turn on check is checking the state of the pool pump");
if (!this->pump_switch_->state) { if (!this->pump_switch_->state) {
@ -94,6 +106,7 @@ void PoolController::set_cleaner_switch(switch_::Switch *cleaner_switch) {
} }
return this->pump_switch_->get_current_on_time() > 5000; return this->pump_switch_->get_current_on_time() > 5000;
}); });
App.register_component(this->cleaner_switch_);
} }
void PoolController::setup() { void PoolController::setup() {
@ -107,7 +120,7 @@ void PoolController::loop() {
void PoolController::manage_pump_() { void PoolController::manage_pump_() {
uint32_t desired_runtime = 0; uint32_t desired_runtime = 0;
time::ESPTime now = this->time_->now(); ESPTime now = this->time_->now();
uint8_t hour = now.hour; uint8_t hour = now.hour;
uint8_t day_of_week = now.day_of_week; uint8_t day_of_week = now.day_of_week;
switch (this->pump_mode_) { switch (this->pump_mode_) {
@ -122,7 +135,7 @@ void PoolController::manage_pump_() {
desired_runtime = RUNTIME_30_MINUTES_PER_HALF_HOUR; // normal cleaner run time desired_runtime = RUNTIME_30_MINUTES_PER_HALF_HOUR; // normal cleaner run time
} else if (day_of_week > 1 && day_of_week < 7 && hour >= 15 && hour < 20 ) { } else if (day_of_week > 1 && day_of_week < 7 && hour >= 15 && hour < 20 ) {
desired_runtime = RUNTIME_10_MINUTES_PER_HALF_HOUR; // peak electric rate desired_runtime = RUNTIME_10_MINUTES_PER_HALF_HOUR; // peak electric rate
} else if (hour >= 6 && hour < 20) { } else if (hour >= 6 && hour < 22) {
desired_runtime = RUNTIME_15_MINUTES_PER_HALF_HOUR; desired_runtime = RUNTIME_15_MINUTES_PER_HALF_HOUR;
} }
break; break;

View File

@ -1,12 +1,11 @@
#pragma once #pragma once
#include "esphome/components/select/select.h"
#include "esphome/components/switch/switch.h" #include "esphome/components/switch/switch.h"
#include "esphome/components/time/real_time_clock.h" #include "esphome/components/time/real_time_clock.h"
#include "esphome/core/component.h" #include "esphome/core/component.h"
#include "esphome/core/preferences.h" #include "esphome/core/preferences.h"
#include "pool_select.h"
#include "pump_switch.h" #include "pump_switch.h"
#include "pool_select.h"
namespace esphome { namespace esphome {
namespace pool_controller { namespace pool_controller {
@ -36,7 +35,7 @@ class PoolController : public Component {
void set_cleaner_current_monitoring(sensor::Sensor *sensor, float min_current, float max_current, uint32_t max_out_of_range_time) { void set_cleaner_current_monitoring(sensor::Sensor *sensor, float min_current, float max_current, uint32_t max_out_of_range_time) {
this->cleaner_switch_->set_current_monitoring(sensor, min_current, max_current, max_out_of_range_time); this->cleaner_switch_->set_current_monitoring(sensor, min_current, max_current, max_out_of_range_time);
} }
float get_setup_priority() const override { return setup_priority::HARDWARE; } float get_setup_priority() const override { return setup_priority::LATE; }
void setup() override; void setup() override;
void loop() override; void loop() override;

View File

@ -4,29 +4,33 @@
namespace esphome { namespace esphome {
namespace pool_controller { namespace pool_controller {
static const char *const TAG = "pool_select"; static const char *const SELECT_TAG = "pool.select";
void PoolSelect::setup() { void PoolSelect::setup() {
std::string value; std::string value;
ESP_LOGCONFIG(SELECT_TAG, "Setting up Pool Select");
size_t index; size_t index;
this->pref_ = global_preferences->make_preference<size_t>(this->get_object_id_hash()); this->pref_ = global_preferences->make_preference<size_t>(this->get_object_id_hash());
if (!this->pref_.load(&index)) { if (!this->pref_.load(&index)) {
value = "Off"; value = this->initial_option_;
ESP_LOGD(TAG, "State from initial (could not load): %s", value.c_str()); ESP_LOGCONFIG(SELECT_TAG, "State from initial (could not load stored index): %s", value.c_str());
} else if (!this->has_index(index)) {
value = this->initial_option_;
ESP_LOGCONFIG(SELECT_TAG, "State from initial (restored index %d out of bounds): %s", index, value.c_str());
} else { } else {
value = this->traits.get_options().at(index); value = this->at(index).value();
ESP_LOGD(TAG, "State from restore: %s", value.c_str()); ESP_LOGCONFIG(SELECT_TAG, "State from restore: %s", value.c_str());
} }
this->publish_state(value); this->publish_state(value);
} }
void PoolSelect::control(const std::string &value) { void PoolSelect::control(const std::string &value) {
ESP_LOGD(TAG, "%s changed to option %s", this->get_name().c_str(), value.c_str()); ESP_LOGD(SELECT_TAG, "%s changed to option %s", this->get_name().c_str(), value.c_str());
this->publish_state(value); this->publish_state(value);
auto options = this->traits.get_options(); auto index = this->index_of(value);
size_t index = std::find(options.begin(), options.end(), value) - options.begin(); this->pref_.save(&index.value());
this->pref_.save(&index);
} }
} // namespace pool_controller } // namespace pool_controller

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "esphome/components/select/select.h" #include "esphome/components/select/select.h"
#include "esphome/core/automation.h"
#include "esphome/core/component.h" #include "esphome/core/component.h"
#include "esphome/core/preferences.h" #include "esphome/core/preferences.h"
@ -11,9 +12,12 @@ class PoolSelect : public select::Select, public Component {
public: public:
float get_setup_priority() const override { return setup_priority::HARDWARE; } float get_setup_priority() const override { return setup_priority::HARDWARE; }
void setup() override; void setup() override;
void set_initial_option(const std::string &initial_option) { this->initial_option_ = initial_option; }
protected: protected:
void control(const std::string &value) override; void control(const std::string &value) override;
std::string initial_option_;
ESPPreferenceObject pref_; ESPPreferenceObject pref_;
}; };

View File

@ -3,6 +3,8 @@
namespace esphome { namespace esphome {
namespace pool_controller { namespace pool_controller {
static const char *const PUMP_SWITCH_TAG = "pool.pump.switch";
// Minimum time the pump needs to be on, turning off before this will result in a delayed turn off (10000 = 10 seconds) // Minimum time the pump needs to be on, turning off before this will result in a delayed turn off (10000 = 10 seconds)
static const uint32_t MINIMUM_PUMP_ON_TIME = 10000; static const uint32_t MINIMUM_PUMP_ON_TIME = 10000;
@ -12,50 +14,21 @@ static const uint32_t MINIMUM_PUMP_OFF_TIME = 10000;
static const uint32_t FORTY_EIGHT_HOURS = 172800000; static const uint32_t FORTY_EIGHT_HOURS = 172800000;
PumpSwitch::PumpSwitch(switch_::Switch *physical_switch) { PumpSwitch::PumpSwitch(switch_::Switch *physical_switch) {
this->set_name(physical_switch->get_name()); this->set_update_interval(1000);
this->set_icon(physical_switch->get_icon()); this->set_restore_mode(switch_::SWITCH_ALWAYS_OFF);
this->set_update_interval(10000);
physical_switch->set_internal(true);
physical_switch->add_on_state_callback([this](bool state) -> void { physical_switch->add_on_state_callback([this](bool state) -> void {
if (state) { this->on_physical_switch_state_change_(state);
uint32_t now = millis();
this->turned_on_at_ = now;
this->last_runtime_update_ = now;
if (!this->state) {
this->physical_switch_->turn_off();
}
} else {
uint32_t now = millis();
this->turned_off_at_ = now;
this->runtime_ += now - this->last_runtime_update_;
this->last_runtime_update_ = now;
if (this->state) {
this->turn_off();
}
}
}); });
this->physical_switch_ = physical_switch; this->physical_switch_ = physical_switch;
} }
void PumpSwitch::setup() { void PumpSwitch::update() {
this->turn_off(); this->update_runtime_();
this->physical_switch_->turn_off();
}
void PumpSwitch::loop() {
this->update_physical_switch_(); this->update_physical_switch_();
//this->check_current_(); //this->check_current_();
} }
void PumpSwitch::update() {
if (this->physical_switch_->state) {
uint32_t now = millis();
this->runtime_ += now - this->last_runtime_update_;
this->last_runtime_update_ = now;
}
}
uint32_t PumpSwitch::get_current_on_time() { uint32_t PumpSwitch::get_current_on_time() {
if (!this->physical_switch_->state) { if (!this->physical_switch_->state) {
return 0; return 0;
@ -85,13 +58,31 @@ void PumpSwitch::emergency_stop() {
} }
void PumpSwitch::write_state(bool state) { void PumpSwitch::write_state(bool state) {
if (state && this->is_disabled_) { state = state && !this->is_disabled_;
state = false;
}
this->state = state; this->state = state;
this->publish_state(state); this->publish_state(state);
this->update_physical_switch_(); }
void PumpSwitch::on_physical_switch_state_change_(bool state) {
if (state) {
uint32_t now = millis();
this->turned_on_at_ = now;
this->last_runtime_update_ = now;
ESP_LOGW(PUMP_SWITCH_TAG, "'%s': Physical switch turned on", this->get_name().c_str());
} else {
uint32_t now = millis();
this->turned_off_at_ = now;
this->runtime_ += now - this->last_runtime_update_;
ESP_LOGW(PUMP_SWITCH_TAG, "'%s': Physical switch turned off", this->get_name().c_str());
}
}
void PumpSwitch::update_runtime_() {
if (this->physical_switch_->state) {
uint32_t now = millis();
this->runtime_ += now - this->last_runtime_update_;
this->last_runtime_update_ = now;
}
} }
void PumpSwitch::update_physical_switch_() { void PumpSwitch::update_physical_switch_() {

View File

@ -1,12 +1,10 @@
#pragma once #pragma once
#include "esphome/components/select/select.h"
#include "esphome/components/sensor/sensor.h" #include "esphome/components/sensor/sensor.h"
#include "esphome/components/switch/switch.h" #include "esphome/components/switch/switch.h"
#include "esphome/components/time/real_time_clock.h" #include "esphome/components/time/real_time_clock.h"
#include "esphome/core/component.h" #include "esphome/core/component.h"
#include "esphome/core/hal.h" #include "esphome/core/hal.h"
#include "esphome/core/preferences.h"
namespace esphome { namespace esphome {
namespace pool_controller { namespace pool_controller {
@ -19,9 +17,7 @@ class PumpSwitch : public switch_::Switch, public PollingComponent {
void set_current_monitoring(sensor::Sensor *sensor, float min_current, float max_current, uint32_t max_out_of_range_time) { void set_current_monitoring(sensor::Sensor *sensor, float min_current, float max_current, uint32_t max_out_of_range_time) {
this->current_sensor_ = sensor; this->min_current_ = min_current; this->max_current_ = max_current; this->max_current_out_of_range_time_ = max_out_of_range_time; this->current_sensor_ = sensor; this->min_current_ = min_current; this->max_current_ = max_current; this->max_current_out_of_range_time_ = max_out_of_range_time;
} }
float get_setup_priority() const override { return setup_priority::HARDWARE; } float get_setup_priority() const override { return setup_priority::DATA; }
void setup() override;
void loop() override;
void update() override; void update() override;
uint32_t get_current_on_time(); uint32_t get_current_on_time();
@ -34,6 +30,8 @@ class PumpSwitch : public switch_::Switch, public PollingComponent {
protected: protected:
void write_state(bool state) override; void write_state(bool state) override;
void on_physical_switch_state_change_(bool state);
void update_runtime_();
void update_physical_switch_(); void update_physical_switch_();
void check_current_(); void check_current_();

View File

@ -7,7 +7,7 @@ This is a custom light component that works with [TREO LED Pool Lights](https://
Using the [External Components](https://esphome.io/components/external_components.html) feature in ESPHome you can add this component to your devices directly from my GitHub repo. Using the [External Components](https://esphome.io/components/external_components.html) feature in ESPHome you can add this component to your devices directly from my GitHub repo.
```yaml ```yaml
external_components: external_components:
- source: github://nuttytree/esphome - source: github://nuttytree/ESPHome-Devices
components: [ treo_led_pool_light ] components: [ treo_led_pool_light ]
``` ```

View File

@ -10,7 +10,7 @@ This a modified version of the [Tuya fan](https://esphome.io/components/fan/tuya
Using the [External Components](https://esphome.io/components/external_components.html) feature in ESPHome you can add this component to your devices directly from my GitHub repo. Using the [External Components](https://esphome.io/components/external_components.html) feature in ESPHome you can add this component to your devices directly from my GitHub repo.
```yaml ```yaml
external_components: external_components:
- source: github://nuttytree/esphome - source: github://nuttytree/ESPHome-Devices
components: [ tuya_dimmer_as_fan ] components: [ tuya_dimmer_as_fan ]
``` ```

View File

@ -18,7 +18,7 @@ This an enhanced version of the standard [Tuya light](https://esphome.io/compone
Using the [External Components](https://esphome.io/components/external_components.html) feature in ESPHome you can add this component to your devices directly from my GitHub repo. Using the [External Components](https://esphome.io/components/external_components.html) feature in ESPHome you can add this component to your devices directly from my GitHub repo.
```yaml ```yaml
external_components: external_components:
- source: github://nuttytree/esphome - source: github://nuttytree/ESPHome-Devices
components: [ tuya_light_plus ] components: [ tuya_light_plus ]
``` ```

View File

@ -2,19 +2,27 @@ substitutions:
device_id: emporia-vue2 device_id: emporia-vue2
device_name: Emporia Vue2 Power Monitor device_name: Emporia Vue2 Power Monitor
board: esp32dev board: esp32dev
ip_address: !secret emporia-vue2-ip ip_address: !secret emporia_vue2_ip
ota_pwd: !secret emporia-vue2-ota-pwd api_key: !secret emporia_vue2_key
api_key: !secret emporia-vue2-key pwd: !secret emporia_vue2_pwd
ap_wifi_pwd: !secret emporia-vue2-ap-pwd
packages: packages:
device_base: !include ./packages/device_base_esp32.yaml device_base: !include ./packages/device_base_esp32.yaml
wifi: api:
power_save_mode: light services:
- service: play_rtttl
variables:
song_str: string
then:
- rtttl.play:
rtttl: !lambda 'return song_str;'
preferences:
flash_write_interval: "48h"
external_components: external_components:
- source: github://flaviut/esphome@emporia-vue-2022.4.0 - source: github://emporia-vue-local/esphome@dev
components: [ emporia_vue ] components: [ emporia_vue ]
i2c: i2c:
@ -24,6 +32,17 @@ i2c:
frequency: 200kHz frequency: 200kHz
id: i2c_a id: i2c_a
output:
- platform: ledc
pin: GPIO12
id: buzzer
- platform: gpio
pin: GPIO27
id: buzzer_gnd
rtttl:
output: buzzer
# these are called references in YAML. They allow you to reuse # these are called references in YAML. They allow you to reuse
# this configuration in each sensor, while only defining it once # this configuration in each sensor, while only defining it once
.defaultfilters: .defaultfilters:
@ -35,6 +54,12 @@ i2c:
window_size: 12 window_size: 12
# we push a new value every 1.44 seconds # we push a new value every 1.44 seconds
send_every: 6 send_every: 6
- &throttle_avg
# average all raw readings together over a 5 second span before publishing
throttle_average: 5s
- &throttle_time
# only send the most recent measurement every 60 seconds
throttle: 60s
- &invert - &invert
# invert and filter out any values below 0. # invert and filter out any values below 0.
lambda: 'return max(-x, 0.0f);' lambda: 'return max(-x, 0.0f);'
@ -55,69 +80,116 @@ sensor:
# To calculate new calibration value use the formula <in-use calibration value> * <accurate voltage> / <reporting voltage> # To calculate new calibration value use the formula <in-use calibration value> * <accurate voltage> / <reporting voltage>
voltage: voltage:
name: "Phase A Voltage" name: "Phase A Voltage"
filters: [*moving_avg, *pos] filters: [*throttle_avg, *pos]
frequency:
name: "Power Frequency"
filters: [*throttle_avg, *pos]
- id: phase_b # Verify that this specific phase/leg is connected to correct input wire color on device listed below - id: phase_b # Verify that this specific phase/leg is connected to correct input wire color on device listed below
input: RED # Vue device wire color input: RED # Vue device wire color
calibration: 0.022 # 0.022 is used as the default as starting point but may need adjusted to ensure accuracy calibration: 0.022 # 0.022 is used as the default as starting point but may need adjusted to ensure accuracy
# To calculate new calibration value use the formula <in-use calibration value> * <accurate voltage> / <reporting voltage> # To calculate new calibration value use the formula <in-use calibration value> * <accurate voltage> / <reporting voltage>
voltage: voltage:
name: "Phase B Voltage" name: "Phase B Voltage"
filters: [*moving_avg, *pos] filters: [*throttle_avg, *pos]
ct_clamps: ct_clamps:
# Do not specify a name for any of the power sensors here, only an id. This leaves the power sensors internal to ESPHome.
# Copy sensors will filter and then send power measurements to HA
# These non-throttled power sensors are used for accurately calculating energy
- phase_id: phase_a - phase_id: phase_a
input: "A" # Verify the CT going to this device input also matches the phase/leg input: "A" # Verify the CT going to this device input also matches the phase/leg
power: power:
name: "Phase A Power"
id: phase_a_power id: phase_a_power
device_class: power filters: [*pos]
filters: [*moving_avg, *pos]
- phase_id: phase_b - phase_id: phase_b
input: "B" # Verify the CT going to this device input also matches the phase/leg input: "B" # Verify the CT going to this device input also matches the phase/leg
power: power:
name: "Phase B Power"
id: phase_b_power id: phase_b_power
device_class: power filters: [*pos]
filters: [*moving_avg, *pos]
# Pay close attention to set the phase_id for each breaker by matching it to the phase/leg it connects to in the panel # Pay close attention to set the phase_id for each breaker by matching it to the phase/leg it connects to in the panel
- { phase_id: phase_b, input: "1", power: { name: "Furnace Power", id: cir1, filters: [ *moving_avg, *pos ] } } - { phase_id: phase_b, input: "1", power: { id: cir1, filters: [*pos] } }
- { phase_id: phase_b, input: "2", power: { name: "Dryer Power", id: cir2, filters: [ *moving_avg, *pos, multiply: 2 ] } } - { phase_id: phase_b, input: "2", power: { id: cir2, filters: [*pos, multiply: 2] } }
- { phase_id: phase_b, input: "3", power: { name: "Garage 1 Power", id: cir3, filters: [ *moving_avg, *pos ] } } - { phase_id: phase_b, input: "3", power: { id: cir3, filters: [*pos] } }
- { phase_id: phase_b, input: "4", power: { name: "Hot Water Heater Power", id: cir4, filters: [ *moving_avg, *pos, multiply: 2 ] } } - { phase_id: phase_b, input: "4", power: { id: cir4, filters: [*pos, multiply: 2] } }
# - { phase_id: phase_a, input: "5", power: { name: "Circuit 5 Power", id: cir5, filters: [ *moving_avg, *pos ] } } # - { phase_id: phase_a, input: "5", power: { id: cir5, filters: [*pos] } }
# - { phase_id: phase_a, input: "6", power: { name: "Circuit 6 Power", id: cir6, filters: [ *moving_avg, *pos ] } } # - { phase_id: phase_a, input: "6", power: { id: cir6, filters: [*pos] } }
# - { phase_id: phase_a, input: "7", power: { name: "Circuit 7 Power", id: cir7, filters: [ *moving_avg, *pos ] } } # - { phase_id: phase_a, input: "7", power: { id: cir7, filters: [*pos] } }
# - { phase_id: phase_b, input: "8", power: { name: "Circuit 8 Power", id: cir8, filters: [ *moving_avg, *pos ] } } # - { phase_id: phase_b, input: "8", power: { id: cir8, filters: [*pos] } }
- { phase_id: phase_a, input: "9", power: { name: "Fire Pit/Fountain Power", id: cir9, filters: [ *moving_avg, *pos ] } } - { phase_id: phase_a, input: "9", power: { id: cir9, filters: [*pos] } }
- { phase_id: phase_a, input: "10", power: { name: "Pool Accessories Total Power", id: cir10, filters: [ *moving_avg, *pos ] } } - { phase_id: phase_a, input: "10", power: { id: cir10, filters: [*pos] } }
- { phase_id: phase_a, input: "11", power: { name: "Garage 2 Power", id: cir11, filters: [ *moving_avg, *pos ] } } - { phase_id: phase_a, input: "11", power: { id: cir11, filters: [*pos] } }
- { phase_id: phase_a, input: "12", power: { name: "Air Conditioner Power", id: cir12, filters: [ *moving_avg, *pos, multiply: 2 ] } } - { phase_id: phase_a, input: "12", power: { id: cir12, filters: [*pos, multiply: 2] } }
- { phase_id: phase_a, input: "13", power: { name: "Dish Washer Power", id: cir13, filters: [ *moving_avg, *pos ] } } - { phase_id: phase_a, input: "13", power: { id: cir13, filters: [*pos] } }
- { phase_id: phase_b, input: "14", power: { name: "Garbage Disposal Power", id: cir14, filters: [ *moving_avg, *pos ] } } - { phase_id: phase_b, input: "14", power: { id: cir14, filters: [*pos] } }
- { phase_id: phase_b, input: "15", power: { name: "Kitchen 1 Power", id: cir15, filters: [ *moving_avg, *pos ] } } - { phase_id: phase_b, input: "15", power: { id: cir15, filters: [*pos] } }
- { phase_id: phase_a, input: "16", power: { name: "Kitchen 2 Power", id: cir16, filters: [ *moving_avg, *pos ] } } - { phase_id: phase_a, input: "16", power: { id: cir16, filters: [*pos] } }
on_update:
then:
- component.update: total_power
- component.update: balance_power
- platform: template - platform: template
name: "Total Power"
lambda: return id(phase_a_power).state + id(phase_b_power).state; lambda: return id(phase_a_power).state + id(phase_b_power).state;
update_interval: 1s update_interval: never # will be updated after all power sensors update via on_update trigger
id: total_power id: total_power
device_class: power
state_class: measurement
unit_of_measurement: "W" unit_of_measurement: "W"
- platform: total_daily_energy - platform: template
name: "Total Daily Energy" lambda: !lambda |-
power_id: total_power return max(0.0f, id(total_power).state -
accuracy_decimals: 0 id( cir1).state -
- { power_id: cir1, platform: total_daily_energy, accuracy_decimals: 0, name: "Furnace" } id( cir2).state -
- { power_id: cir2, platform: total_daily_energy, accuracy_decimals: 0, name: "Dryer" } id( cir3).state -
- { power_id: cir3, platform: total_daily_energy, accuracy_decimals: 0, name: "Garage 1" } id( cir4).state -
- { power_id: cir4, platform: total_daily_energy, accuracy_decimals: 0, name: "Hot Water Heater" } id( cir9).state -
# - { power_id: cir5, platform: total_daily_energy, accuracy_decimals: 0, name: "Circuit 5 Daily Energy" } id(cir10).state -
# - { power_id: cir6, platform: total_daily_energy, accuracy_decimals: 0, name: "Circuit 6 Daily Energy" } id(cir11).state -
# - { power_id: cir7, platform: total_daily_energy, accuracy_decimals: 0, name: "Circuit 7 Daily Energy" } id(cir12).state -
# - { power_id: cir8, platform: total_daily_energy, accuracy_decimals: 0, name: "Circuit 8 Daily Energy" } id(cir13).state -
- { power_id: cir9, platform: total_daily_energy, accuracy_decimals: 0, name: "Fire Pit/Fountain" } id(cir14).state -
- { power_id: cir10, platform: total_daily_energy, accuracy_decimals: 0, name: "Pool Accessories Total" } id(cir15).state -
- { power_id: cir11, platform: total_daily_energy, accuracy_decimals: 0, name: "Garage 2" } id(cir16).state);
- { power_id: cir12, platform: total_daily_energy, accuracy_decimals: 0, name: "Air Conditioner" } update_interval: never # will be updated after all power sensors update via on_update trigger
- { power_id: cir13, platform: total_daily_energy, accuracy_decimals: 0, name: "Dish Washer" } id: balance_power
- { power_id: cir14, platform: total_daily_energy, accuracy_decimals: 0, name: "Garbage Disposal" } device_class: power
- { power_id: cir15, platform: total_daily_energy, accuracy_decimals: 0, name: "Kitchen 1" } state_class: measurement
- { power_id: cir16, platform: total_daily_energy, accuracy_decimals: 0, name: "Kitchen 2" } unit_of_measurement: "W"
# The copy sensors filter and send the power state to HA
- { platform: copy, source_id: phase_a_power, name: "Phase A Power", filters: *throttle_avg }
- { platform: copy, source_id: phase_b_power, name: "Phase B Power", filters: *throttle_avg }
- { platform: copy, source_id: total_power, name: "Total Power", filters: *throttle_avg }
- { platform: copy, source_id: balance_power, name: "Balance Power", filters: *throttle_avg }
- { platform: copy, source_id: cir1, name: "Furnace Power", filters: *throttle_avg }
- { platform: copy, source_id: cir2, name: "Dryer Power", filters: *throttle_avg }
- { platform: copy, source_id: cir3, name: "Garage 1 Power", filters: *throttle_avg }
- { platform: copy, source_id: cir4, name: "Hot Water Heater Power", filters: *throttle_avg }
# - { platform: copy, source_id: cir5, name: " Power", filters: *throttle_avg }
# - { platform: copy, source_id: cir6, name: " Power", filters: *throttle_avg }
# - { platform: copy, source_id: cir7, name: " Power", filters: *throttle_avg }
# - { platform: copy, source_id: cir8, name: " Power", filters: *throttle_avg }
- { platform: copy, source_id: cir9, name: "Fire Pit/Fountain Power", filters: *throttle_avg }
- { platform: copy, source_id: cir10, name: "Pool Accessories Total Power", filters: *throttle_avg }
- { platform: copy, source_id: cir11, name: "Garage 2 Power", filters: *throttle_avg }
- { platform: copy, source_id: cir12, name: "Air Conditioner Power", filters: *throttle_avg }
- { platform: copy, source_id: cir13, name: "Dish Washer Power", filters: *throttle_avg }
- { platform: copy, source_id: cir14, name: "Garbage Disposal Power", filters: *throttle_avg }
- { platform: copy, source_id: cir15, name: "Kitchen 1 Power", filters: *throttle_avg }
- { platform: copy, source_id: cir16, name: "Kitchen 2 Power", filters: *throttle_avg }
- { platform: total_daily_energy, power_id: total_power, accuracy_decimals: 0, restore: false, name: "Total Daily Energy", filters: *throttle_time }
- { platform: total_daily_energy, power_id: balance_power, accuracy_decimals: 0, restore: false, name: "Balance Daily Energy", filters: *throttle_time }
- { platform: total_daily_energy, power_id: cir1, accuracy_decimals: 0, restore: false, name: "Furnace", filters: *throttle_time }
- { platform: total_daily_energy, power_id: cir2, accuracy_decimals: 0, restore: false, name: "Dryer", filters: *throttle_time }
- { platform: total_daily_energy, power_id: cir3, accuracy_decimals: 0, restore: false, name: "Garage 1", filters: *throttle_time }
- { platform: total_daily_energy, power_id: cir4, accuracy_decimals: 0, restore: false, name: "Hot Water Heater", filters: *throttle_time }
# - { platform: total_daily_energy, power_id: cir5, accuracy_decimals: 0, restore: false, name: "", filters: *throttle_time }
# - { platform: total_daily_energy, power_id: cir6, accuracy_decimals: 0, restore: false, name: "", filters: *throttle_time }
# - { platform: total_daily_energy, power_id: cir7, accuracy_decimals: 0, restore: false, name: "", filters: *throttle_time }
# - { platform: total_daily_energy, power_id: cir8, accuracy_decimals: 0, restore: false, name: "", filters: *throttle_time }
- { platform: total_daily_energy, power_id: cir9, accuracy_decimals: 0, restore: false, name: "Fire Pit/Fountain", filters: *throttle_time }
- { platform: total_daily_energy, power_id: cir10, accuracy_decimals: 0, restore: false, name: "Pool Accessories Total", filters: *throttle_time }
- { platform: total_daily_energy, power_id: cir11, accuracy_decimals: 0, restore: false, name: "Garage 2", filters: *throttle_time }
- { platform: total_daily_energy, power_id: cir12, accuracy_decimals: 0, restore: false, name: "Air Conditioner", filters: *throttle_time }
- { platform: total_daily_energy, power_id: cir13, accuracy_decimals: 0, restore: false, name: "Dish Washer", filters: *throttle_time }
- { platform: total_daily_energy, power_id: cir14, accuracy_decimals: 0, restore: false, name: "Garbage Disposal", filters: *throttle_time }
- { platform: total_daily_energy, power_id: cir15, accuracy_decimals: 0, restore: false, name: "Kitchen 1", filters: *throttle_time }
- { platform: total_daily_energy, power_id: cir16, accuracy_decimals: 0, restore: false, name: "Kitchen 2", filters: *throttle_time }

View File

@ -1,10 +1,9 @@
substitutions: substitutions:
device_id: family-room-tv device_id: family-room-tv
device_name: Family Room TV device_name: Family Room TV
ip_address: !secret family-room-tv-ip ip_address: !secret family_room_tv_ip
ota_pwd: !secret family-room-tv-ota-pwd api_key: !secret family_room_tv_key
api_key: !secret family-room-tv-key pwd: !secret family_room_tv_pwd
ap_wifi_pwd: !secret family-room-tv-ap-pwd
packages: packages:
feit_dimmer: !include ./packages/topgreener_smart_plug.yaml feit_dimmer: !include ./packages/topgreener_smart_plug.yaml

View File

@ -2,10 +2,9 @@ substitutions:
device_id: fire-pit-fountain device_id: fire-pit-fountain
device_name: Fire Pit and Fountain device_name: Fire Pit and Fountain
board: d1_mini board: d1_mini
ip_address: !secret fire-pit-fountain-ip ip_address: !secret fire_pit_fountain_ip
ota_pwd: !secret fire-pit-fountain-ota-pwd api_key: !secret fire_pit_fountain_key
api_key: !secret fire-pit-fountain-key pwd: !secret fire_pit_fountain_pwd
ap_wifi_pwd: !secret fire-pit-fountain-ap-pwd
packages: packages:
device_base: !include ./packages/device_base_esp8266.yaml device_base: !include ./packages/device_base_esp8266.yaml
@ -17,6 +16,8 @@ binary_sensor:
number: D6 number: D6
mode: INPUT_PULLUP mode: INPUT_PULLUP
inverted: True inverted: True
filters:
- delayed_on: 100ms
on_press: on_press:
then: then:
- switch.toggle: fountain - switch.toggle: fountain
@ -26,6 +27,8 @@ binary_sensor:
number: D7 number: D7
mode: INPUT_PULLUP mode: INPUT_PULLUP
inverted: True inverted: True
filters:
- delayed_on: 100ms
on_multi_click: on_multi_click:
- timing: - timing:
- ON for at least 3s - ON for at least 3s

View File

@ -2,10 +2,9 @@ substitutions:
device_id: garage-fridge device_id: garage-fridge
device_name: Garage Fridge device_name: Garage Fridge
board: m5stack-atom board: m5stack-atom
ip_address: !secret garage-fridge-ip ip_address: !secret garage_fridge_ip
ota_pwd: !secret garage-fridge-ota-pwd api_key: !secret garage_fridge_key
api_pwd: !secret garage-fridge-api-pwd pwd: !secret garage_fridge_pwd
ap_wifi_pwd: !secret garage-fridge-ap-pwd
log_baud_rate: '0' log_baud_rate: '0'
packages: packages:
@ -34,9 +33,6 @@ climate:
max_integral: 0.5 max_integral: 0.5
esp32_ble_tracker: esp32_ble_tracker:
scan_parameters:
interval: 1100ms
window: 1100ms
modbus: modbus:
@ -67,6 +63,9 @@ sensor:
name: Garage Freezer Humidity name: Garage Freezer Humidity
battery_level: battery_level:
name: Garage Freezer Sensor Battery Level name: Garage Freezer Sensor Battery Level
- platform: internal_temperature
name: "Garage Controller Temperature"
entity_category: diagnostic
- platform: pzemac - platform: pzemac
id: pzem id: pzem
update_interval: 2s update_interval: 2s

View File

@ -1,10 +1,9 @@
substitutions: substitutions:
device_id: garage-lights device_id: garage-lights
device_name: Garage Lights device_name: Garage Lights
ip_address: !secret garage-lights-ip ip_address: !secret garage_lights_ip
ota_pwd: !secret garage-lights-ota-pwd api_key: !secret garage_lights_key
api_key: !secret garage-lights-key pwd: !secret garage_lights_pwd
ap_wifi_pwd: !secret garage-lights-ap-pwd
light_wattage: '378' light_wattage: '378'
packages: packages:

View File

@ -1,10 +1,9 @@
substitutions: substitutions:
device_id: kitchen-fridge device_id: kitchen-fridge
device_name: Kitchen Fridge device_name: Kitchen Fridge
ip_address: !secret kitchen-fridge-ip ip_address: !secret kitchen_fridge_ip
ota_pwd: !secret kitchen-fridge-ota-pwd api_key: !secret kitchen_fridge_key
api_key: !secret kitchen-fridge-key pwd: !secret kitchen_fridge_pwd
ap_wifi_pwd: !secret kitchen-fridge-ap-pwd
packages: packages:
feit_dimmer: !include ./packages/topgreener_smart_plug.yaml feit_dimmer: !include ./packages/topgreener_smart_plug.yaml

14
main-garage-door.yaml Normal file
View File

@ -0,0 +1,14 @@
substitutions:
device_id: "main-garage-door"
device_name: Main Garage Door
board: d1_mini
ip_address: !secret main_garage_door_ip
api_key: !secret main_garage_door_key
pwd: !secret main_garage_door_pwd
flash_write_interval: 5s
packages:
ratgdo.esphome: github://ratgdo/esphome-ratgdo/v25iboard.yaml@main
base: !include ./packages/device_base_esp8266.yaml
web_server: !remove

View File

@ -1,59 +0,0 @@
substitutions:
device_id: master-bath-hum-temp-sensor
device_name: Master Bathroom Humidity and Temperature Sensor
board: d1_mini
ip_address: !secret master-bath-hum-temp-sensor-ip
ota_pwd: !secret master-bath-hum-temp-sensor-ota-pwd
api_pwd: !secret master-bath-hum-temp-sensor-api-pwd
ap_wifi_pwd: !secret master-bath-hum-temp-sensor-ap-pwd
packages:
device_base: !include ./packages/device_base_esp8266.yaml
binary_sensor:
- platform: template
id: trigger_humidity
lambda: return (id(humidity).state - id(median_humidity).state) > 5;
filters:
- delayed_off: 5min
i2c:
sda: D2
scl: D1
scan: true
output:
- platform: gpio
pin: D3
id: bme_gnd
sensor:
- platform: bme280
temperature:
id: temperature
name: "Master Bathroom Temperature"
pressure:
id: pressure
name: "Master Bathroom Pressure"
humidity:
id: humidity
name: "Master Bathroom Humidity"
address: 0x76
update_interval: 15s
- platform: template
name: "Master Bathroom Median Humidity"
id: median_humidity
unit_of_measurement: '%'
icon: mdi:water-percent
lambda: return id(humidity).state;
update_interval: 60s
filters:
- median:
window_size: 360
send_every: 2
send_first_at: 2
status_led:
pin:
number: D4
inverted: true

View File

@ -2,10 +2,9 @@ substitutions:
device_id: master-bed device_id: master-bed
device_name: Master Bed device_name: Master Bed
board: nodemcuv2 board: nodemcuv2
ip_address: !secret master-bed-ip ip_address: !secret master_bed_ip
ota_pwd: !secret master-bed-ota-pwd api_key: !secret master_bed_key
api_key: !secret master-bed-key pwd: !secret master_bed_pwd
ap_wifi_pwd: !secret master-bed-ap-pwd
packages: packages:
device_base: !include ./packages/device_base_esp8266.yaml device_base: !include ./packages/device_base_esp8266.yaml

View File

@ -1,10 +1,9 @@
substitutions: substitutions:
device_id: network-equipment device_id: network-equipment
device_name: Network Equipment device_name: Network Equipment
ip_address: !secret network-equipment-ip ip_address: !secret network_equipment_ip
ota_pwd: !secret network-equipment-ota-pwd api_key: !secret network_equipment_key
api_key: !secret network-equipment-key pwd: !secret network_equipment_pwd
ap_wifi_pwd: !secret network-equipment-ap-pwd
packages: packages:
feit_dimmer: !include ./packages/topgreener_smart_plug.yaml feit_dimmer: !include ./packages/topgreener_smart_plug.yaml

View File

@ -3,7 +3,7 @@ substitutions:
device_name: Dining Room Light device_name: Dining Room Light
ip_address: !secret dining-room-light-ip ip_address: !secret dining-room-light-ip
ota_pwd: !secret dining-room-light-ota-pwd ota_pwd: !secret dining-room-light-ota-pwd
api_pwd: !secret dining-room-light-api-pwd api_key: !secret dining-room-light-key
ap_wifi_pwd: !secret dining-room-light-ap-pwd ap_wifi_pwd: !secret dining-room-light-ap-pwd
packages: packages:

View File

@ -3,7 +3,7 @@ substitutions:
device_name: Living Room Lights device_name: Living Room Lights
ip_address: !secret living-room-lights-ip ip_address: !secret living-room-lights-ip
ota_pwd: !secret living-room-lights-ota-pwd ota_pwd: !secret living-room-lights-ota-pwd
api_pwd: !secret living-room-lights-api-pwd api_key: !secret living-room-lights-key
ap_wifi_pwd: !secret living-room-lights-ap-pwd ap_wifi_pwd: !secret living-room-lights-ap-pwd
packages: packages:

View File

@ -3,7 +3,7 @@ substitutions:
device_name: Office Light device_name: Office Light
ip_address: !secret office-light-ip ip_address: !secret office-light-ip
ota_pwd: !secret office-light-ota-pwd ota_pwd: !secret office-light-ota-pwd
api_pwd: !secret office-light-api-pwd api_key: !secret office-light-key
ap_wifi_pwd: !secret office-light-ap-pwd ap_wifi_pwd: !secret office-light-ap-pwd
packages: packages:

View File

@ -1,14 +1,16 @@
substitutions: substitutions:
log_level: none log_level: none
log_baud_rate: '115200' log_baud_rate: '115200'
wifi_ssid: !secret wifi-ssid wifi_ssid: !secret wifi_ssid
wifi_password: !secret wifi-password wifi_password: !secret wifi_password
ip_subnet: !secret ip-subnet ip_subnet: !secret ip_subnet
ip_gateway: !secret ip-gateway ip_gateway: !secret ip_gateway
flash_write_interval: 10min flash_write_interval: 10min
esphome: esphome:
name: ${device_id} name: ${device_id}
friendly_name: ${device_name}
name_add_mac_suffix: false
build_path: ./build/${device_id} build_path: ./build/${device_id}
${platform}: ${platform}:

View File

@ -1,2 +1,3 @@
ota: ota:
password: ${ota_pwd} platform: esphome
password: ${pwd}

View File

@ -1,14 +1,15 @@
wifi: wifi:
ssid: ${wifi_ssid} ssid: ${wifi_ssid}
password: ${wifi_password} password: ${wifi_password}
fast_connect: false fast_connect: true
power_save_mode: none power_save_mode: none
manual_ip: manual_ip:
static_ip: ${ip_address} static_ip: ${ip_address}
subnet: ${ip_subnet} subnet: ${ip_subnet}
gateway: ${ip_gateway} gateway: ${ip_gateway}
# ap: ap:
# ssid: ${device_id} ssid: ${device_id}
# password: ${ap_wifi_pwd} password: ${pwd}
ap_timeout: 5min
#captive_portal: captive_portal:

View File

@ -2,10 +2,9 @@ substitutions:
device_id: patio-lights device_id: patio-lights
device_name: Patio Lights device_name: Patio Lights
board: d1_mini board: d1_mini
ip_address: !secret patio-lights-ip ip_address: !secret patio_lights_ip
ota_pwd: !secret patio-lights-ota-pwd api_key: !secret patio_lights_key
api_key: !secret patio-lights-key pwd: !secret patio_lights_pwd
ap_wifi_pwd: !secret patio-lights-ap-pwd
packages: packages:
device_base: !include ./packages/device_base_esp8266.yaml device_base: !include ./packages/device_base_esp8266.yaml

View File

@ -2,10 +2,9 @@ substitutions:
device_id: pool-and-patio-lights device_id: pool-and-patio-lights
device_name: Pool and Patio Lights device_name: Pool and Patio Lights
board: esp01_1m board: esp01_1m
ip_address: !secret pool-and-patio-lights-ip ip_address: !secret pool_and_patio_lights_ip
ota_pwd: !secret pool-and-patio-lights-ota-pwd api_key: !secret pool_and_patio_lights_key
api_key: !secret pool-and-patio-lights-key pwd: !secret pool_and_patio_lights_pwd
ap_wifi_pwd: !secret pool-and-patio-lights-ap-pwd
packages: packages:
device_base: !include ./packages/device_base_esp8266.yaml device_base: !include ./packages/device_base_esp8266.yaml

View File

@ -2,10 +2,10 @@ substitutions:
device_id: pool-pumps device_id: pool-pumps
device_name: Pool Pumps device_name: Pool Pumps
board: modwifi board: modwifi
ip_address: !secret pool-pumps-ip ip_address: !secret pool_pumps_ip
ota_pwd: !secret pool-pumps-ota-pwd api_key: !secret pool_pumps_key
api_pwd: !secret pool-pumps-api-pwd pwd: !secret pool_pumps_pwd
ap_wifi_pwd: !secret pool-pumps-ap-pwd log_level: warn
packages: packages:
device_base: !include ./packages/device_base_esp8266.yaml device_base: !include ./packages/device_base_esp8266.yaml
@ -16,6 +16,14 @@ external_components:
path: ./components path: ./components
components: [ pool_controller ] components: [ pool_controller ]
binary_sensor:
# Prevent short circuit with "floating" pin!
- platform: gpio
pin: GPIO16
name: "ade7953 IRQ pin"
internal: true
i2c: i2c:
sda: GPIO12 sda: GPIO12
scl: GPIO14 scl: GPIO14
@ -35,7 +43,7 @@ pool_controller:
max_out_of_range_duration: 10s max_out_of_range_duration: 10s
sensor: sensor:
- platform: ade7953 - platform: ade7953_i2c
voltage: voltage:
name: ${device_name} Voltage name: ${device_name} Voltage
id: voltage id: voltage
@ -106,11 +114,11 @@ switch:
pin: GPIO4 pin: GPIO4
name: "Pool Pump" name: "Pool Pump"
id: pool_pump id: pool_pump
icon: mdi:pump
restore_mode: Always Off restore_mode: Always Off
internal: true
- platform: gpio - platform: gpio
pin: GPIO15 pin: GPIO15
name: "Pool Cleaner" name: "Pool Cleaner"
id: pool_cleaner id: pool_cleaner
icon: mdi:robot-vacuum
restore_mode: Always Off restore_mode: Always Off
internal: true

View File

@ -2,19 +2,17 @@ substitutions:
device_id: second-garage-door device_id: second-garage-door
device_name: Second Garage Door device_name: Second Garage Door
board: d1_mini board: d1_mini
ip_address: !secret second-garage-door-ip ip_address: !secret second_garage_door_ip
ota_pwd: !secret second-garage-door-ota-pwd api_key: !secret second_garage_door_key
api_pwd: !secret second-garage-door-api-pwd pwd: !secret second_garage_door_pwd
ap_wifi_pwd: !secret second-garage-door-ap-pwd
log_level: debug
packages: packages:
device_base: !include ../packages/device_base_esp8266.yaml device_base: !include ./packages/device_base_esp8266.yaml
external_components: external_components:
- source: - source:
type: local type: local
path: ../components path: ./components
components: [ garage_door ] components: [ garage_door ]
binary_sensor: binary_sensor:
@ -78,10 +76,6 @@ cover:
last_close_time_sensor: last_close_time_sensor:
name: ${device_name} Last Close Time name: ${device_name} Last Close Time
logger:
logs:
sensor: NONE
output: output:
- platform: gpio - platform: gpio
id: control_out id: control_out
@ -99,7 +93,7 @@ sensor:
id: button_in id: button_in
pin: A0 pin: A0
raw: true raw: true
update_interval: 75ms update_interval: 100ms
status_led: status_led:
pin: pin:

View File

@ -1,10 +1,9 @@
substitutions: substitutions:
device_id: sump-pump device_id: sump-pump
device_name: Sump Pump device_name: Sump Pump
ip_address: !secret sump-pump-ip ip_address: !secret sump_pump_ip
ota_pwd: !secret sump-pump-ota-pwd api_key: !secret sump_pump_key
api_key: !secret sump-pump-key pwd: !secret sump_pump_pwd
ap_wifi_pwd: !secret sump-pump-ap-pwd
packages: packages:
feit_dimmer: !include ./packages/topgreener_smart_plug.yaml feit_dimmer: !include ./packages/topgreener_smart_plug.yaml

View File

@ -1,10 +1,9 @@
substitutions: substitutions:
device_id: washing-machine device_id: washing-machine
device_name: Washing Machine device_name: Washing Machine
ip_address: !secret washing-machine-ip ip_address: !secret washing_machine_ip
ota_pwd: !secret washing-machine-ota-pwd api_key: !secret washing_machine_key
api_key: !secret washing-machine-key pwd: !secret washing_machine_pwd
ap_wifi_pwd: !secret washing-machine-ap-pwd
packages: packages:
feit_dimmer: !include ./packages/topgreener_smart_plug.yaml feit_dimmer: !include ./packages/topgreener_smart_plug.yaml