This commit is contained in:
2024-04-10 14:49:07 +02:00
parent 956236ca8d
commit 523d1143f3
111 changed files with 41255 additions and 98061 deletions

View File

@@ -10,6 +10,7 @@ substitutions:
gateway: !secret ip_gateway
subnet: !secret ip_subnet
ip: !secret air_quality_woonkamer_ip
update_interval: 30s
pin_status: GPIO2
pin_sda: GPIO21
pin_scl: GPIO22

View File

@@ -10,6 +10,7 @@ substitutions:
gateway: !secret ip_gateway
subnet: !secret ip_subnet
ip: !secret air_quality_zolder_ip
update_interval: 1s
pin_pir: GPIO23
pin_status: GPIO2
pin_sda: GPIO21

View File

@@ -0,0 +1,77 @@
substitutions:
device_name: "badkamerradfan"
friendly_name: "badkamerradfan"
comment: "esp32-c3"
location: "badkamer"
api_password: !secret badkamerradfan_api
ota_password: !secret ota_password
wifi_ssid: !secret wifi_ssid
wifi_password: !secret wifi_password
gateway: !secret ip_gateway
subnet: !secret ip_subnet
ip: !secret badkamerradfan_ip
pin_temp: GPIO3
pin_pwm: GPIO4
pin_tach: GPIO2
pin_status: GPIO8
ledc_freq: "16000"
packages:
board: !include boards/esp32-C3.yaml
device_base: !include common/common.yaml
connection: !include common/wifi.yaml
status: !include templates/status.yaml
logger: !include templates/logger.yaml
output:
- platform: ledc
pin: ${pin_pwm}
id: pwm1
frequency: ${ledc_freq}
fan:
- platform: speed
output: pwm1
name: "Badkamer radiator Fan"
id: badkamerfan
restore_mode: RESTORE_DEFAULT_ON
# Example configuration entry
dallas:
- pin: ${pin_temp}
# Individual sensors
sensor:
- platform: dallas
address: 0x59800000081fd028
name: "Radiataor Temperature"
id: radtemperature
on_value_range:
- above: !lambda return id(TemperatureOn).state;
then:
- fan.turn_on: badkamerfan
- below: !lambda return id(TemperatureOff).state;
then:
- fan.turn_off: badkamerfan
number:
- platform: template
name: "Fan on temp"
id: TemperatureOn
optimistic: true
min_value: 15
max_value: 65
restore_value: True
initial_value: 28
step: 1
- platform: template
name: "Fan off temp"
id: TemperatureOff
optimistic: true
min_value: 15
max_value: 65
restore_value: True
initial_value: 24
step: 1

165
esphome/blinds.yaml Normal file
View File

@@ -0,0 +1,165 @@
substitutions:
device_name: "blinds-speelkamer"
friendly_name: "blinds speelkamer"
comment: "esp32c3, motor, encoder"
location: "speelkamer"
api_password: !secret blinds_api
ota_password: !secret ota_password
wifi_ssid: !secret wifi_ssid
wifi_password: !secret wifi_password
gateway: !secret ip_gateway
subnet: !secret ip_subnet
ip: !secret blinds_ip
update_interval: 30s
pin_mot1: GPIO3
pin_mot2: GPIO2
pin_enc1: GPIO7
pin_enc2: GPIO8
pin_sw1: GPIO9
pin_sw2: GPIO10
packages:
board: !include boards/esp32-C3.yaml
device_base: !include common/common.yaml
connection: !include common/wifi.yaml
logger: !include templates/logger.yaml
binary_sensor:
- platform: gpio
id: endstop1
name: endstop1
pin:
number: ${pin_sw1}
mode:
input: true
pullup: true
inverted: true
on_press:
then:
- sensor.rotary_encoder.set_value:
id: encoder1
value: 0
- platform: gpio
id: endstop2
name: endstop2
pin:
number: ${pin_sw2}
mode:
input: true
pullup: true
inverted: true
globals:
- id: min_tilt
type: int
restore_value: true
initial_value: "0"
- id: max_tilt
type: int
restore_value: true
initial_value: "2328"
script:
- id: tilt_left
then:
- switch.turn_off: positive
- switch.turn_on: negative
- id: tilt_right
then:
- switch.turn_off: negative
- switch.turn_on: positive
- id: tilt_stop
then:
- switch.turn_off: negative
- switch.turn_off: positive
sensor:
- platform: rotary_encoder
name: "Rotary Encoder"
id: 'encoder1'
pin_a: ${pin_enc1}
pin_b: ${pin_enc2}
publish_initial_value: True
#restore_mode: RESTORE_DEFAULT_ZERO
# on_value:
# then:
# - lambda: |-
# id(blind).position = x / (id(max_tilt)-id(min_tilt));
# id(blind).publish_state();
# Exposed switches.
switch:
- platform: template
id: resetc
name: Reset count
turn_on_action:
then:
- sensor.rotary_encoder.set_value:
id: encoder1
value: 0
- switch.turn_off: resetc
- platform: restart
name: restart
- platform: output
name: "shade1"
output: 'shade1'
internal: true
id: negative
- platform: output
name: "shade2"
output: 'shade2'
internal: true
id: positive
output:
- platform: gpio
id: 'shade1'
pin: ${pin_mot1}
- platform: gpio
id: 'shade2'
pin: ${pin_mot2}
cover:
- platform: endstop
device_class: blind
name: "speelkamer blind"
#optimistic: TRUE
id: blind
#has_position: true
# lambda: |-
# if(id(endstop1).state & id(blind).current_operation == CoverOperation::COVER_OPERATION_CLOSING)
# {
# id(tilt_stop).execute();
# return COVER_CLOSED;
# }
# else if(id(endstop2).state & id(blind).current_operation == CoverOperation::COVER_OPERATION_OPENING)
# {
# id(tilt_stop).execute();
# return COVER_OPEN;
# }
# return {};
open_endstop: endstop2
open_duration: 5s
close_endstop: endstop1
close_duration: 5s
stop_action:
then:
- script.execute: tilt_stop
open_action:
then:
- script.execute: tilt_right
close_action:
then:
- script.execute: tilt_left
# on_open:
# - logger.log: "Cover is Open!"
# on_closed:
# - logger.log: "Cover is Closed!"

View File

@@ -0,0 +1,14 @@
esp32:
board: esp32-s3-devkitc-1
flash_size: 16MB
framework:
type: esp-idf
sdkconfig_options:
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240: "y"
CONFIG_ESP32S3_DATA_CACHE_64KB: "y"
CONFIG_ESP32S3_DATA_CACHE_LINE_64B: "y"
CONFIG_AUDIO_BOARD_CUSTOM: "y"
psram:
mode: octal
speed: 80MHz

View File

@@ -0,0 +1,4 @@
esp32:
board: esp-wrover-kit
framework:
type: arduino

View File

@@ -0,0 +1,100 @@
substitutions:
device_name: "wekker"
friendly_name: "wekker"
comment: "esp32, lcd wt32-sc01"
location: "slaaplamer"
api_password: !secret wekker_api
ota_password: !secret ota_password
wifi_ssid: !secret wifi_ssid
wifi_password: !secret wifi_password
gateway: !secret ip_gateway
subnet: !secret ip_subnet
ip: !secret wekker_ip
# pin_bl: GPIO23
# pin_clk: GPIO14
# pin_mosi: GPIO13
# pin_miso: GPIO12
# pin_cs: GPIO15
# pin_dc: GPIO21
# pin_lcdrst: GPIO22
# pin_sda: GPIO18
# pin_scl: GPIO19
esphome:
name: ${device_name}
esp32:
board: esp-wrover-kit
framework:
type: arduino
# packages:
# device_base: !include includes/common_settings.yaml
#esp32_ble_tracker:
#bluetooth_proxy:
# active: true
# time:
# - platform: homeassistant
# id: homeassistant_time
# output:
# - platform: gpio
# pin: GPIO23
# id: tst_Backlight
# light:
# - platform: binary
# name: "${friendly_name} Back Light"
# output: tst_Backlight
# id: ${id_prefix}_backlight
# restore_mode: ALWAYS_ON
# spi:
# clk_pin: GPIO14
# mosi_pin: GPIO13
# miso_pin: GPIO12
# display:
# - platform: ili9xxx
# id: ${id_prefix}_display
# model: ST7796
# cs_pin: GPIO15
# dc_pin: GPIO21
# reset_pin: GPIO22
# rotation: 270
# pages:
# - id: page1
# lambda: |-
# it.printf(64,0, id(my_font), TextAlign::TOP_CENTER, "WT32-SC01");
# it.strftime(64, 40, id(my_font), TextAlign::BASELINE_CENTER, "%I:%M:%S %p", id(homeassistant_time).now());
# it.printf(64, 60, id(my_font), TextAlign::BOTTOM_CENTER, "Time");
# - id: page2
# lambda: |-
# it.printf(64,0, id(my_font), TextAlign::TOP_CENTER, "WT32-SC01");
# it.printf(64, 40, id(my_font), TextAlign::BASELINE_CENTER, "Hello Loryan!");
# it.printf(64, 60, id(my_font), TextAlign::BOTTOM_CENTER, "Hi from down here");
# font:
# - file:
# type: gfonts
# family: "Open Sans"
# id: my_font
# size: 20
# color:
# - id: my_red
# red: 100%
# green: 3%
# blue: 5%
# - id: my_white
# red: 100%
# green: 100%
# blue: 100%
# interval:
# - interval: 5s
# then:
# - display.page.show_next: wt32_sc01_display
# - component.update: wt32_sc01_display

View File

@@ -0,0 +1,199 @@
substitutions:
device_name: "wekker"
friendly_name: "wekker"
comment: "esp32, lcd wt32-sc01"
location: "slaaplamer"
api_password: !secret wekker_api
ota_password: !secret ota_password
wifi_ssid: !secret wifi_ssid
wifi_password: !secret wifi_password
ip: !secret wekker_ip
gateway: !secret ip_gateway
subnet: !secret ip_subnet
id_prefix: wekker
pin_lcd_bl: GPIO23
pin_clk: GPIO14
pin_mosi: GPIO13
pin_miso: GPIO12
pin_cs: GPIO15
pin_dc: GPIO21
pin_lcdrst: GPIO22
pin_sda: GPIO18
pin_scl: GPIO19
pin_rotsw: GPIO33
pin_rotA: GPIO32
pin_rotB: GPIO27
#datasheet: https://files.seeedstudio.com/products/102991455/WT32-SC01-datasheet.pdf
packages:
board: !include boards/esp32_wrover.yaml
i2c: !include interfaces/i2c_a.yaml
spi: !include interfaces/spi.yaml
connection: !include common/wifi.yaml
device_base: !include common/common.yaml
time: !include templates/time.yaml
logger: !include templates/logger.yaml
backlight: !include templates/backlight.yaml
color: !include templates/color.yaml
touch: !include templates/touchscreen_ft63x6.yaml
sensor:
- platform: rotary_encoder
name: "Rotary Encoder"
id: rotary
pin_a: ${pin_rotA}
pin_b: ${pin_rotB}
on_anticlockwise:
- if:
condition:
display.is_displaying_page: menu
then:
- display_menu.down: menu_disp
else:
- number.increment:
id: num_bright
cycle: false
on_clockwise:
- if:
condition:
display.is_displaying_page: menu
then:
- display_menu.up: menu_disp
else:
- number.decrement:
id: num_bright
cycle: false
image:
- file: "include/4dir.jpg"
id: multidir
resize: 150x150
number:
- platform: template
id: num_bright
optimistic: true
min_value: 0.05
max_value: 1
step: 0.05
on_value:
then:
# lambda: |-
# ESP_LOGI("number", "new brightness value: %f", x);
- light.control:
id: backlight
brightness: !lambda "return x;"
transition_length: 0.1s
binary_sensor:
- platform: gpio
pin:
number: ${pin_rotsw}
inverted: true
name: "rotary select"
id: rotary_button
filters:
- delayed_on: 10ms
- delayed_off: 30ms
on_press:
- if:
condition:
display.is_displaying_page: menu
then:
- if:
condition:
display_menu.is_active: menu_disp
then:
- display_menu.enter: menu_disp
else:
- display_menu.show: menu_disp
on_double_click:
then:
- display.page.show: flipclock
- platform: touchscreen
name: menu
x_min: 380
x_max: 480
y_min: 280
y_max: 320
page_id: flipclock
on_click:
then:
- display.page.show: menu
- display_menu.show:
font:
- file: 'fonts/Solari.ttf'
id: flipper
size: 160
glyphs: ['-',' ', '°', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'C',':']
- file:
type: gfonts
family: Roboto
size: 40
id: menu_font
# - file:
# type: gfonts
# family: Roboto
# size: 30
# id: dir_font
# glyphs: ['U','p', 'D', 'o', 'w', 'n', 'L', 'e', 'f', 't', 'R', 'i', 'g', 'h']
display:
- platform: ili9xxx
id: ${id_prefix}_display
model: ST7796
cs_pin: ${pin_cs}
dc_pin: ${pin_dc}
reset_pin: ${pin_lcdrst}
rotation: 270
pages:
- id: flipclock
lambda: |-
it.strftime(0, 80, id(flipper), TextAlign::TOP_LEFT, "%H:%M", id(homeassistant_time).now());
// it.filled_rectangle(360, 250, 470, 310, id(green));
// it.printf(365,255, id(menu_font), id(black), TextAlign::TOP_LEFT, "Menu");
// it.image(210,370, id(multidir));
- id: menu
lambda: |-
const auto display_width = it.get_width();
const auto display_height = it.get_height();
//it.filled_rectangle(360, 250, 470, 310, id(green));
//it.printf(365,255, id(menu_font), id(black), TextAlign::TOP_LEFT, "Exit");
// Arguments: it.menu(x, y, menu, width, height);
it.menu(0, 60, id(menu_disp), display_width/2, 150);
#https://www.esphome.io/components/display_menu/graphical_display_menu.html?highlight=graphical_display_menu
graphical_display_menu:
id: menu_disp
font: menu_font
display: ${id_prefix}_display
on_redraw:
then:
component.update: ${id_prefix}_display
on_leave:
then:
- display.page.show: flipclock
- lambda: 'ESP_LOGI("display_menu", "switch leave: %s, %s", it->get_text().c_str(), it->get_value_text().c_str());'
active: false
mode: rotary
items:
- type: number
text: Brightness
number: num_bright
- type: Label
text: Alarm
- type: back
text: Back

View File

@@ -14,7 +14,7 @@ substitutions:
pin_led1: GPIO3
pin_led2: GPIO4
pin_led3: GPIO1
ledc_freq: "19531Hz"
ledc_freq: "1220Hz"
packages:
board: !include boards/esp32-C3.yaml

View File

@@ -1,8 +1,8 @@
# Enable Home Assistant API
api:
encryption:
key: ${api_password}
encryption:
key: ${api_password}
ota:
password: ${ota_password}
@@ -17,7 +17,7 @@ wifi:
subnet: ${subnet}
dns1: 192.169.2.15
dns2: 1.1.1.1
# use_address: 192.168.2.63 #when changing fixed IP
# use_address: 192.168.2.63 #when changing fixed IP
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
@@ -33,6 +33,10 @@ sensor:
text_sensor:
- platform: wifi_info
ip_address:
name: IP Address
icon: mdi:wifi-strength-2
id: ipaddr
ssid:
name: "Connected SSID"
id: ssid

View File

@@ -19,10 +19,14 @@ wifi:
dns2: 1.1.1.1
# use_address: 192.168.2.63 #when changing fixed IP
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: ${device_name}
password: ${wifi_password}
on_connect:
- delay: 5s # Gives time for improv results to be transmitted
- ble.disable:
on_disconnect:
- ble.enable:
sensor:

View File

@@ -0,0 +1,48 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import light
from esphome.const import (
CONF_OUTPUT_ID,
CONF_NUM_LEDS,
CONF_RGB_ORDER,
CONF_MAX_REFRESH_RATE,
)
CODEOWNERS = ["@OttoWinter"]
fastled_base_ns = cg.esphome_ns.namespace("fastled_base")
FastLEDLightOutput = fastled_base_ns.class_(
"FastLEDLightOutput", light.AddressableLight
)
RGB_ORDERS = [
"RGB",
"RBG",
"GRB",
"GBR",
"BRG",
"BGR",
]
BASE_SCHEMA = light.ADDRESSABLE_LIGHT_SCHEMA.extend(
{
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(FastLEDLightOutput),
cv.Required(CONF_NUM_LEDS): cv.positive_not_null_int,
cv.Optional(CONF_RGB_ORDER): cv.one_of(*RGB_ORDERS, upper=True),
cv.Optional(CONF_MAX_REFRESH_RATE): cv.positive_time_period_microseconds,
}
).extend(cv.COMPONENT_SCHEMA)
async def new_fastled_light(config):
var = cg.new_Pvariable(config[CONF_OUTPUT_ID])
await cg.register_component(var, config)
if CONF_MAX_REFRESH_RATE in config:
cg.add(var.set_max_refresh_rate(config[CONF_MAX_REFRESH_RATE]))
await light.register_light(var, config)
# https://github.com/FastLED/FastLED/blob/master/library.json
# 3.3.3 has an issue on ESP32 with RMT and fastled_clockless:
# https://github.com/esphome/issues/issues/1375
cg.add_library("fastled/FastLED", "3.5.0")
return var

View File

@@ -0,0 +1,43 @@
#ifdef USE_ARDUINO
#include "fastled_light.h"
#include "esphome/core/log.h"
namespace esphome {
namespace fastled_base {
static const char *const TAG = "fastled";
void FastLEDLightOutput::setup() {
ESP_LOGCONFIG(TAG, "Setting up FastLED light...");
this->controller_->init();
this->controller_->setLeds(this->leds_, this->num_leds_);
this->effect_data_ = new uint8_t[this->num_leds_]; // NOLINT
if (!this->max_refresh_rate_.has_value()) {
this->set_max_refresh_rate(this->controller_->getMaxRefreshRate());
}
}
void FastLEDLightOutput::dump_config() {
ESP_LOGCONFIG(TAG, "FastLED light:");
ESP_LOGCONFIG(TAG, " Num LEDs: %u", this->num_leds_);
ESP_LOGCONFIG(TAG, " Max refresh rate: %u", *this->max_refresh_rate_);
}
void FastLEDLightOutput::write_state(light::LightState *state) {
// protect from refreshing too often
uint32_t now = micros();
if (*this->max_refresh_rate_ != 0 && (now - this->last_refresh_) < *this->max_refresh_rate_) {
// try again next loop iteration, so that this change won't get lost
this->schedule_show();
return;
}
this->last_refresh_ = now;
this->mark_shown_();
ESP_LOGVV(TAG, "Writing RGB values to bus...");
this->controller_->showLeds();
}
} // namespace fastled_base
} // namespace esphome
#endif // USE_ARDUINO

View File

@@ -0,0 +1,243 @@
#pragma once
#ifdef USE_ARDUINO
#include "esphome/core/component.h"
#include "esphome/core/helpers.h"
#include "esphome/components/light/addressable_light.h"
#define FASTLED_ESP8266_RAW_PIN_ORDER
#define FASTLED_ESP32_RAW_PIN_ORDER
#define FASTLED_RMT_BUILTIN_DRIVER true
// Avoid annoying compiler messages
#define FASTLED_INTERNAL
#include "FastLED.h"
namespace esphome {
namespace fastled_base {
class FastLEDLightOutput : public light::AddressableLight {
public:
/// Only for custom effects: Get the internal controller.
CLEDController *get_controller() const { return this->controller_; }
inline int32_t size() const override { return this->num_leds_; }
/// Set a maximum refresh rate in µs as some lights do not like being updated too often.
void set_max_refresh_rate(uint32_t interval_us) { this->max_refresh_rate_ = interval_us; }
/// Add some LEDS, can only be called once.
CLEDController &add_leds(CLEDController *controller, int num_leds) {
this->controller_ = controller;
this->num_leds_ = num_leds;
this->leds_ = new CRGB[num_leds]; // NOLINT
for (int i = 0; i < this->num_leds_; i++)
this->leds_[i] = CRGB::Black;
return *this->controller_;
}
template<ESPIChipsets CHIPSET, uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER, uint32_t SPI_DATA_RATE>
CLEDController &add_leds(int num_leds) {
switch (CHIPSET) {
case LPD8806: {
static LPD8806Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> controller;
return add_leds(&controller, num_leds);
}
case WS2801: {
static WS2801Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> controller;
return add_leds(&controller, num_leds);
}
case WS2803: {
static WS2803Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> controller;
return add_leds(&controller, num_leds);
}
case SM16716: {
static SM16716Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> controller;
return add_leds(&controller, num_leds);
}
case P9813: {
static P9813Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> controller;
return add_leds(&controller, num_leds);
}
case DOTSTAR:
case APA102: {
static APA102Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> controller;
return add_leds(&controller, num_leds);
}
case SK9822: {
static SK9822Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER, SPI_DATA_RATE> controller;
return add_leds(&controller, num_leds);
}
}
}
template<ESPIChipsets CHIPSET, uint8_t DATA_PIN, uint8_t CLOCK_PIN> CLEDController &add_leds(int num_leds) {
switch (CHIPSET) {
case LPD8806: {
static LPD8806Controller<DATA_PIN, CLOCK_PIN> controller;
return add_leds(&controller, num_leds);
}
case WS2801: {
static WS2801Controller<DATA_PIN, CLOCK_PIN> controller;
return add_leds(&controller, num_leds);
}
case WS2803: {
static WS2803Controller<DATA_PIN, CLOCK_PIN> controller;
return add_leds(&controller, num_leds);
}
case SM16716: {
static SM16716Controller<DATA_PIN, CLOCK_PIN> controller;
return add_leds(&controller, num_leds);
}
case P9813: {
static P9813Controller<DATA_PIN, CLOCK_PIN> controller;
return add_leds(&controller, num_leds);
}
case DOTSTAR:
case APA102: {
static APA102Controller<DATA_PIN, CLOCK_PIN> controller;
return add_leds(&controller, num_leds);
}
case SK9822: {
static SK9822Controller<DATA_PIN, CLOCK_PIN> controller;
return add_leds(&controller, num_leds);
}
}
}
template<ESPIChipsets CHIPSET, uint8_t DATA_PIN, uint8_t CLOCK_PIN, EOrder RGB_ORDER>
CLEDController &add_leds(int num_leds) {
switch (CHIPSET) {
case LPD8806: {
static LPD8806Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> controller;
return add_leds(&controller, num_leds);
}
case WS2801: {
static WS2801Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> controller;
return add_leds(&controller, num_leds);
}
case WS2803: {
static WS2803Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> controller;
return add_leds(&controller, num_leds);
}
case SM16716: {
static SM16716Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> controller;
return add_leds(&controller, num_leds);
}
case P9813: {
static P9813Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> controller;
return add_leds(&controller, num_leds);
}
case DOTSTAR:
case APA102: {
static APA102Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> controller;
return add_leds(&controller, num_leds);
}
case SK9822: {
static SK9822Controller<DATA_PIN, CLOCK_PIN, RGB_ORDER> controller;
return add_leds(&controller, num_leds);
}
}
}
#ifdef FASTLED_HAS_CLOCKLESS
template<template<uint8_t DATA_PIN, EOrder RGB_ORDER> class CHIPSET, uint8_t DATA_PIN, EOrder RGB_ORDER>
CLEDController &add_leds(int num_leds) {
static CHIPSET<DATA_PIN, RGB_ORDER> controller;
return add_leds(&controller, num_leds);
}
template<template<uint8_t DATA_PIN, EOrder RGB_ORDER> class CHIPSET, uint8_t DATA_PIN>
CLEDController &add_leds(int num_leds) {
static CHIPSET<DATA_PIN, RGB> controller;
return add_leds(&controller, num_leds);
}
template<template<uint8_t DATA_PIN> class CHIPSET, uint8_t DATA_PIN> CLEDController &add_leds(int num_leds) {
static CHIPSET<DATA_PIN> controller;
return add_leds(&controller, num_leds);
}
#endif
template<template<EOrder RGB_ORDER> class CHIPSET, EOrder RGB_ORDER> CLEDController &add_leds(int num_leds) {
static CHIPSET<RGB_ORDER> controller;
return add_leds(&controller, num_leds);
}
template<template<EOrder RGB_ORDER> class CHIPSET> CLEDController &add_leds(int num_leds) {
static CHIPSET<RGB> controller;
return add_leds(&controller, num_leds);
}
#ifdef FASTLED_HAS_BLOCKLESS
template<EBlockChipsets CHIPSET, int NUM_LANES, EOrder RGB_ORDER> CLEDController &add_leds(int num_leds) {
switch (CHIPSET) {
#ifdef PORTA_FIRST_PIN
case WS2811_PORTA:
return add_leds(
new InlineBlockClocklessController<NUM_LANES, PORTA_FIRST_PIN, NS(320), NS(320), NS(640), RGB_ORDER>(),
num_leds);
case WS2811_400_PORTA:
return add_leds(
new InlineBlockClocklessController<NUM_LANES, PORTA_FIRST_PIN, NS(800), NS(800), NS(900), RGB_ORDER>(),
num_leds);
case WS2813_PORTA:
return add_leds(new InlineBlockClocklessController<NUM_LANES, PORTA_FIRST_PIN, NS(320), NS(320), NS(640),
RGB_ORDER, 0, false, 300>(),
num_leds);
case TM1803_PORTA:
return add_leds(
new InlineBlockClocklessController<NUM_LANES, PORTA_FIRST_PIN, NS(700), NS(1100), NS(700), RGB_ORDER>(),
num_leds);
case UCS1903_PORTA:
return add_leds(
new InlineBlockClocklessController<NUM_LANES, PORTA_FIRST_PIN, NS(500), NS(1500), NS(500), RGB_ORDER>(),
num_leds);
#endif
}
}
template<EBlockChipsets CHIPSET, int NUM_LANES> CLEDController &add_leds(int num_leds) {
return add_leds<CHIPSET, NUM_LANES, GRB>(num_leds);
}
#endif
// ========== INTERNAL METHODS ==========
// (In most use cases you won't need these)
light::LightTraits get_traits() override {
auto traits = light::LightTraits();
traits.set_supported_color_modes({light::ColorMode::RGB});
return traits;
}
void setup() override;
void dump_config() override;
void write_state(light::LightState *state) override;
float get_setup_priority() const override { return setup_priority::HARDWARE; }
void clear_effect_data() override {
for (int i = 0; i < this->size(); i++)
this->effect_data_[i] = 0;
}
protected:
light::ESPColorView get_view_internal(int32_t index) const override {
return {&this->leds_[index].r, &this->leds_[index].g, &this->leds_[index].b, nullptr,
&this->effect_data_[index], &this->correction_};
}
CLEDController *controller_{nullptr};
CRGB *leds_{nullptr};
uint8_t *effect_data_{nullptr};
int num_leds_{0};
uint32_t last_refresh_{0};
optional<uint32_t> max_refresh_rate_{};
};
} // namespace fastled_base
} // namespace esphome
#endif // USE_ARDUINO

View File

@@ -0,0 +1,67 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import pins
from esphome.components import fastled_base
from esphome.const import (
CONF_CHIPSET,
CONF_CLOCK_PIN,
CONF_DATA_PIN,
CONF_DATA_RATE,
CONF_NUM_LEDS,
CONF_RGB_ORDER,
)
AUTO_LOAD = ["fastled_base"]
CHIPSETS = [
"LPD8806",
"WS2801",
"WS2803",
"SM16716",
"P9813",
"APA102",
"SK9822",
"DOTSTAR",
]
CONFIG_SCHEMA = cv.All(
fastled_base.BASE_SCHEMA.extend(
{
cv.Required(CONF_CHIPSET): cv.one_of(*CHIPSETS, upper=True),
cv.Required(CONF_DATA_PIN): pins.internal_gpio_output_pin_number,
cv.Required(CONF_CLOCK_PIN): pins.internal_gpio_output_pin_number,
cv.Optional(CONF_DATA_RATE): cv.frequency,
}
),
cv.require_framework_version(
esp8266_arduino=cv.Version(2, 7, 4),
esp32_arduino=cv.Version(99, 0, 0),
max_version=True,
extra_message="Please see note on documentation for FastLED",
),
)
async def to_code(config):
var = await fastled_base.new_fastled_light(config)
rgb_order = cg.RawExpression(
config[CONF_RGB_ORDER] if CONF_RGB_ORDER in config else "RGB"
)
data_rate = None
if CONF_DATA_RATE in config:
data_rate_khz = int(config[CONF_DATA_RATE] / 1000)
if data_rate_khz < 1000:
data_rate = cg.RawExpression(f"DATA_RATE_KHZ({data_rate_khz})")
else:
data_rate_mhz = int(data_rate_khz / 1000)
data_rate = cg.RawExpression(f"DATA_RATE_MHZ({data_rate_mhz})")
template_args = cg.TemplateArguments(
cg.RawExpression(config[CONF_CHIPSET]),
config[CONF_DATA_PIN],
config[CONF_CLOCK_PIN],
rgb_order,
data_rate,
)
cg.add(var.add_leds(template_args, config[CONF_NUM_LEDS]))

View File

@@ -29,6 +29,7 @@ WaveshareEPaper2P7In = waveshare_epaper_ns.class_(
WaveshareEPaper2P9InB = waveshare_epaper_ns.class_(
"WaveshareEPaper2P9InB", WaveshareEPaper
)
GDEY029T94 = waveshare_epaper_ns.class_("GDEY029T94", WaveshareEPaper)
WaveshareEPaper4P2In = waveshare_epaper_ns.class_(
"WaveshareEPaper4P2In", WaveshareEPaper
)
@@ -38,6 +39,9 @@ WaveshareEPaper4P2InBV2 = waveshare_epaper_ns.class_(
WaveshareEPaper5P8In = waveshare_epaper_ns.class_(
"WaveshareEPaper5P8In", WaveshareEPaper
)
WaveshareEPaper5P8InV2 = waveshare_epaper_ns.class_(
"WaveshareEPaper5P8InV2", WaveshareEPaper
)
WaveshareEPaper7P5In = waveshare_epaper_ns.class_(
"WaveshareEPaper7P5In", WaveshareEPaper
)
@@ -47,6 +51,9 @@ WaveshareEPaper7P5InBC = waveshare_epaper_ns.class_(
WaveshareEPaper7P5InBV2 = waveshare_epaper_ns.class_(
"WaveshareEPaper7P5InBV2", WaveshareEPaper
)
WaveshareEPaper7P5InBV3 = waveshare_epaper_ns.class_(
"WaveshareEPaper7P5InBV3", WaveshareEPaper
)
WaveshareEPaper7P5InV2 = waveshare_epaper_ns.class_(
"WaveshareEPaper7P5InV2", WaveshareEPaper
)
@@ -59,6 +66,7 @@ WaveshareEPaper7P5InHDB = waveshare_epaper_ns.class_(
WaveshareEPaper2P13InDKE = waveshare_epaper_ns.class_(
"WaveshareEPaper2P13InDKE", WaveshareEPaper
)
GDEW0154M09 = waveshare_epaper_ns.class_("GDEW0154M09", WaveshareEPaper)
WaveshareEPaperTypeAModel = waveshare_epaper_ns.enum("WaveshareEPaperTypeAModel")
WaveshareEPaperTypeBModel = waveshare_epaper_ns.enum("WaveshareEPaperTypeBModel")
@@ -73,28 +81,36 @@ MODELS = {
"2.13in-ttgo-b74": ("a", WaveshareEPaperTypeAModel.TTGO_EPAPER_2_13_IN_B74),
"2.90in": ("a", WaveshareEPaperTypeAModel.WAVESHARE_EPAPER_2_9_IN),
"2.90inv2": ("a", WaveshareEPaperTypeAModel.WAVESHARE_EPAPER_2_9_IN_V2),
"gdey029t94": ("c", GDEY029T94),
"2.70in": ("b", WaveshareEPaper2P7In),
"2.90in-b": ("b", WaveshareEPaper2P9InB),
"4.20in": ("b", WaveshareEPaper4P2In),
"4.20in-bv2": ("b", WaveshareEPaper4P2InBV2),
"5.83in": ("b", WaveshareEPaper5P8In),
"5.83inv2": ("b", WaveshareEPaper5P8InV2),
"7.50in": ("b", WaveshareEPaper7P5In),
"7.50in-bv2": ("b", WaveshareEPaper7P5InBV2),
"7.50in-bv3": ("b", WaveshareEPaper7P5InBV3),
"7.50in-bc": ("b", WaveshareEPaper7P5InBC),
"7.50inv2": ("b", WaveshareEPaper7P5InV2),
"7.50inv2alt": ("b", WaveshareEPaper7P5InV2alt),
"7.50in-hd-b": ("b", WaveshareEPaper7P5InHDB),
"2.13in-ttgo-dke": ("c", WaveshareEPaper2P13InDKE),
"1.54in-m5coreink-m09": ("c", GDEW0154M09),
}
def validate_full_update_every_only_type_a(value):
def validate_full_update_every_only_types_ac(value):
if CONF_FULL_UPDATE_EVERY not in value:
return value
if MODELS[value[CONF_MODEL]][0] == "b":
full_models = []
for key, val in sorted(MODELS.items()):
if val[0] != "b":
full_models.append(key)
raise cv.Invalid(
"The 'full_update_every' option is only available for models "
"'1.54in', '1.54inV2', '2.13in', '2.90in', and '2.90inV2'."
+ ", ".join(full_models)
)
return value
@@ -116,7 +132,7 @@ CONFIG_SCHEMA = cv.All(
)
.extend(cv.polling_component_schema("1s"))
.extend(spi.spi_device_schema()),
validate_full_update_every_only_type_a,
validate_full_update_every_only_types_ac,
cv.has_at_most_one_key(CONF_PAGES, CONF_LAMBDA),
)
@@ -132,7 +148,6 @@ async def to_code(config):
else:
raise NotImplementedError()
await cg.register_component(var, config)
await display.register_display(var, config)
await spi.register_spi_device(var, config)

View File

@@ -0,0 +1,156 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import core, pins
from esphome.components import display, spi
from esphome.const import (
CONF_BUSY_PIN,
CONF_DC_PIN,
CONF_FULL_UPDATE_EVERY,
CONF_ID,
CONF_LAMBDA,
CONF_MODEL,
CONF_PAGES,
CONF_RESET_DURATION,
CONF_RESET_PIN,
)
DEPENDENCIES = ["spi"]
waveshare_epaper_ns = cg.esphome_ns.namespace("waveshare_epaper")
WaveshareEPaper = waveshare_epaper_ns.class_(
"WaveshareEPaper", cg.PollingComponent, spi.SPIDevice, display.DisplayBuffer
)
WaveshareEPaperTypeA = waveshare_epaper_ns.class_(
"WaveshareEPaperTypeA", WaveshareEPaper
)
WaveshareEPaper2P7In = waveshare_epaper_ns.class_(
"WaveshareEPaper2P7In", WaveshareEPaper
)
WaveshareEPaper2P9InB = waveshare_epaper_ns.class_(
"WaveshareEPaper2P9InB", WaveshareEPaper
)
WaveshareEPaper4P2In = waveshare_epaper_ns.class_(
"WaveshareEPaper4P2In", WaveshareEPaper
)
WaveshareEPaper4P2InBV2 = waveshare_epaper_ns.class_(
"WaveshareEPaper4P2InBV2", WaveshareEPaper
)
WaveshareEPaper5P8In = waveshare_epaper_ns.class_(
"WaveshareEPaper5P8In", WaveshareEPaper
)
WaveshareEPaper7P5In = waveshare_epaper_ns.class_(
"WaveshareEPaper7P5In", WaveshareEPaper
)
WaveshareEPaper7P5InBC = waveshare_epaper_ns.class_(
"WaveshareEPaper7P5InBC", WaveshareEPaper
)
WaveshareEPaper7P5InBV2 = waveshare_epaper_ns.class_(
"WaveshareEPaper7P5InBV2", WaveshareEPaper
)
WaveshareEPaper7P5InV2 = waveshare_epaper_ns.class_(
"WaveshareEPaper7P5InV2", WaveshareEPaper
)
WaveshareEPaper7P5InV2alt = waveshare_epaper_ns.class_(
"WaveshareEPaper7P5InV2alt", WaveshareEPaper
)
WaveshareEPaper7P5InHDB = waveshare_epaper_ns.class_(
"WaveshareEPaper7P5InHDB", WaveshareEPaper
)
WaveshareEPaper2P13InDKE = waveshare_epaper_ns.class_(
"WaveshareEPaper2P13InDKE", WaveshareEPaper
)
WaveshareEPaperTypeAModel = waveshare_epaper_ns.enum("WaveshareEPaperTypeAModel")
WaveshareEPaperTypeBModel = waveshare_epaper_ns.enum("WaveshareEPaperTypeBModel")
MODELS = {
"1.54in": ("a", WaveshareEPaperTypeAModel.WAVESHARE_EPAPER_1_54_IN),
"1.54inv2": ("a", WaveshareEPaperTypeAModel.WAVESHARE_EPAPER_1_54_IN_V2),
"2.13in": ("a", WaveshareEPaperTypeAModel.WAVESHARE_EPAPER_2_13_IN),
"2.13in-ttgo": ("a", WaveshareEPaperTypeAModel.TTGO_EPAPER_2_13_IN),
"2.13in-ttgo-b1": ("a", WaveshareEPaperTypeAModel.TTGO_EPAPER_2_13_IN_B1),
"2.13in-ttgo-b73": ("a", WaveshareEPaperTypeAModel.TTGO_EPAPER_2_13_IN_B73),
"2.13in-ttgo-b74": ("a", WaveshareEPaperTypeAModel.TTGO_EPAPER_2_13_IN_B74),
"2.90in": ("a", WaveshareEPaperTypeAModel.WAVESHARE_EPAPER_2_9_IN),
"2.90inv2": ("a", WaveshareEPaperTypeAModel.WAVESHARE_EPAPER_2_9_IN_V2),
"2.70in": ("b", WaveshareEPaper2P7In),
"2.90in-b": ("b", WaveshareEPaper2P9InB),
"4.20in": ("b", WaveshareEPaper4P2In),
"4.20in-bv2": ("b", WaveshareEPaper4P2InBV2),
"5.83in": ("b", WaveshareEPaper5P8In),
"7.50in": ("b", WaveshareEPaper7P5In),
"7.50in-bv2": ("b", WaveshareEPaper7P5InBV2),
"7.50in-bc": ("b", WaveshareEPaper7P5InBC),
"7.50inv2": ("b", WaveshareEPaper7P5InV2),
"7.50inv2alt": ("b", WaveshareEPaper7P5InV2alt),
"7.50in-hd-b": ("b", WaveshareEPaper7P5InHDB),
"2.13in-ttgo-dke": ("c", WaveshareEPaper2P13InDKE),
}
def validate_full_update_every_only_type_a(value):
if CONF_FULL_UPDATE_EVERY not in value:
return value
if MODELS[value[CONF_MODEL]][0] == "b":
raise cv.Invalid(
"The 'full_update_every' option is only available for models "
"'1.54in', '1.54inV2', '2.13in', '2.90in', and '2.90inV2'."
)
return value
CONFIG_SCHEMA = cv.All(
display.FULL_DISPLAY_SCHEMA.extend(
{
cv.GenerateID(): cv.declare_id(WaveshareEPaper),
cv.Required(CONF_DC_PIN): pins.gpio_output_pin_schema,
cv.Required(CONF_MODEL): cv.one_of(*MODELS, lower=True),
cv.Optional(CONF_RESET_PIN): pins.gpio_output_pin_schema,
cv.Optional(CONF_BUSY_PIN): pins.gpio_input_pin_schema,
cv.Optional(CONF_FULL_UPDATE_EVERY): cv.uint32_t,
cv.Optional(CONF_RESET_DURATION): cv.All(
cv.positive_time_period_milliseconds,
cv.Range(max=core.TimePeriod(milliseconds=500)),
),
}
)
.extend(cv.polling_component_schema("1s"))
.extend(spi.spi_device_schema()),
validate_full_update_every_only_type_a,
cv.has_at_most_one_key(CONF_PAGES, CONF_LAMBDA),
)
async def to_code(config):
model_type, model = MODELS[config[CONF_MODEL]]
if model_type == "a":
rhs = WaveshareEPaperTypeA.new(model)
var = cg.Pvariable(config[CONF_ID], rhs, WaveshareEPaperTypeA)
elif model_type in ("b", "c"):
rhs = model.new()
var = cg.Pvariable(config[CONF_ID], rhs, model)
else:
raise NotImplementedError()
await cg.register_component(var, config)
await display.register_display(var, config)
await spi.register_spi_device(var, config)
dc = await cg.gpio_pin_expression(config[CONF_DC_PIN])
cg.add(var.set_dc_pin(dc))
if CONF_LAMBDA in config:
lambda_ = await cg.process_lambda(
config[CONF_LAMBDA], [(display.DisplayRef, "it")], return_type=cg.void
)
cg.add(var.set_writer(lambda_))
if CONF_RESET_PIN in config:
reset = await cg.gpio_pin_expression(config[CONF_RESET_PIN])
cg.add(var.set_reset_pin(reset))
if CONF_BUSY_PIN in config:
reset = await cg.gpio_pin_expression(config[CONF_BUSY_PIN])
cg.add(var.set_busy_pin(reset))
if CONF_FULL_UPDATE_EVERY in config:
cg.add(var.set_full_update_every(config[CONF_FULL_UPDATE_EVERY]))
if CONF_RESET_DURATION in config:
cg.add(var.set_reset_duration(config[CONF_RESET_DURATION]))

View File

@@ -6,11 +6,16 @@
namespace esphome {
namespace waveshare_epaper {
class WaveshareEPaper : public PollingComponent,
public display::DisplayBuffer,
public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW,
spi::CLOCK_PHASE_LEADING, spi::DATA_RATE_2MHZ> {
//for esphome < 2023.12
// class WaveshareEPaper : public PollingComponent,
// public display::DisplayBuffer,
// public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW,
// spi::CLOCK_PHASE_LEADING, spi::DATA_RATE_2MHZ>
//for esphome > 2023.12
class WaveshareEPaper : public display::DisplayBuffer,
public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW,
spi::CLOCK_PHASE_LEADING, spi::DATA_RATE_2MHZ>
{
public:
void set_dc_pin(GPIOPin *dc_pin) { dc_pin_ = dc_pin; }
float get_setup_priority() const override;

View File

@@ -13,14 +13,12 @@ substitutions:
packages:
board: !include boards/esp32_wroom_arduino.yaml
device_base: !include common/common.yaml
connection: !include common/wifi_nosens.yaml
logger: !include templates/logger.yaml
#bt_proxy: !include common/bluetooth.yaml #no space
#add include
esphome:
name: ${device_name}
comment: ${comment}
friendly_name: ${friendly_name}
includes:
- include/epaper75.h
@@ -30,7 +28,12 @@ external_components:
# url: https://github.com/atomicmike/esphome.git
# ref: waveshare-color-2022.6
# components: [waveshare_epaper]
- source: components/waveshare-epaper-c
- source:
type: git
url: https://github.com/twisterss/esphome-dev.git
ref: waveshare-red-black
components: [ waveshare_epaper ]
#- source: components/waveshare-epaper-c
sun:
latitude: !secret home_latitude

View File

@@ -0,0 +1,17 @@
substitutions:
name: ep1_woonkamer
friendly_name: ep1_woonkamer
packages:
Everything_Smart_Technology.Everything_Presence_One: github://everythingsmarthome/presence-one/everything-presence-one.yaml@main
esphome:
name: ${name}
name_add_mac_suffix: false
friendly_name: ${friendly_name}
api:
encryption:
key: HgmOLIIf74ks6M3tpyU4CrafOdY/f6nFUuPCdtI8vJE=
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password

View File

@@ -0,0 +1,281 @@
substitutions:
device_name: "steppertest"
friendly_name: "stepper"
comment: "esp32-S2, motor"
location: "zolder"
api_password: !secret stepper_api
ota_password: !secret ota_password
wifi_ssid: !secret wifi_ssid
wifi_password: !secret wifi_password
gateway: !secret ip_gateway
subnet: !secret ip_subnet
ip: !secret stepper_ip
update_interval: 30s
pin_mot_rst: GPIO18
pin_mot_slp: GPIO21
pin_mot_dir: GPIO17
pin_mot_stp: GPIO16
blinds_name: speelkamer
packages:
board: !include boards/esp32_s2_arduino.yaml
device_base: !include common/common.yaml
connection: !include common/wifi.yaml
logger: !include templates/logger.yaml
api:
services:
- service: control_stepper
variables:
target: int
then:
- stepper.set_target:
id: stepper_motor
target: !lambda 'return target;'
esphome:
on_boot:
- priority: -200.0
then:
- stepper.report_position: # Set stepper to global variable
id: stepper_motor
position: !lambda return id(stepper_motor_global);
- stepper.set_target: # Set stepper to global variable
id: stepper_motor
target: !lambda return id(stepper_motor_global);
- if: # If blind is Closed
condition:
- lambda: 'return id(stepper_motor_global) == 0;'
then: # Publish state etc.
- cover.template.publish:
id: ${blinds_name}
state: CLOSED
current_operation: IDLE
- if: # If blind is Open
condition:
- lambda: 'return id(stepper_motor_global) == id(endstop).state;'
then: # Publish state etc.
- cover.template.publish:
id: ${blinds_name}
state: OPEN
current_operation: IDLE
- if: # If blind is Neither
condition:
- lambda: 'return (id(stepper_motor_global) != 0) && (id(stepper_motor_global) != id(endstop).state);'
then: # # Publish state etc.
- cover.template.publish:
id: ${blinds_name}
position: !lambda 'return (float(float(id(stepper_motor).current_position) / float(id(endstop).state)));'
current_operation: IDLE
globals:
- id: stepper_motor_global # Integer for storing the stepper position in case of reboot
type: int
restore_value: True
initial_value: '0'
- id: openclosed # Boolean to store OPEN/CLOSED state
type: bool
restore_value: True
initial_value: '0'
# - id: endstop # Variable for storing ENDSTOP (how far to move stepper)
# type: int
# restore_value: True
# initial_value: '750' # this is the max value # this is the max value
sensor:
- platform: template
name: steppe_pos
id: stepper_pos
number:
- platform: template
name: endstop Control
id: endstop
min_value: 0
max_value: 2000
step: 1
mode: slider
unit_of_measurement: steps
restore_value: True
optimistic: True
# set_action:
# then:
# - globals.set:
# id: endstop
# value: !lambda 'return x;'
stepper:
- platform: a4988
id: stepper_motor
step_pin: ${pin_mot_stp}
dir_pin: ${pin_mot_dir}
max_speed: 250
# Optional:
sleep_pin: ${pin_mot_slp}
acceleration: inf
deceleration: inf
cover:
- platform: template
name: Dining Room Blinds
id: ${blinds_name}
open_action:
then:
- logger.log: "Opening"
- stepper.set_target:
id: stepper_motor
target: 750
- while:
condition:
lambda: 'return id(stepper_motor).current_position < id(endstop).state;'
then:
- cover.template.publish:
id: ${blinds_name}
position: !lambda 'return (float(float(id(stepper_motor).current_position) / float(id(endstop).state)));'
current_operation: OPENING
- delay: 1000 ms
- globals.set: # Set global to current position
id: stepper_motor_global
value: !lambda return id(stepper_motor).current_position;
- sensor.template.publish:
id: stepper_pos
state: !lambda return id(stepper_motor).current_position;
- globals.set: # Set toggle to OPEN (No need for 'optimistic mode')
id: openclosed
value: '1'
- cover.template.publish:
id: ${blinds_name}
state: OPEN
current_operation: IDLE
close_action:
then:
- logger.log: "Closing"
- stepper.set_target: # Send stepper to 0
id: stepper_motor
target: '0'
- while:
condition:
lambda: 'return id(stepper_motor).current_position > 0;'
then:
- cover.template.publish:
id: ${blinds_name}
position: !lambda 'return (float(float(id(stepper_motor).current_position) / float(id(endstop).state)));'
current_operation: CLOSING
- delay: 1000 ms
- globals.set: # Set global to current position
id: stepper_motor_global
value: !lambda return id(stepper_motor).current_position;
- sensor.template.publish:
id: stepper_pos
state: !lambda return id(stepper_motor).current_position;
- globals.set: # Set toggle to CLOSED (No need for 'optimistic mode')
id: openclosed
value: '0'
- cover.template.publish:
id: ${blinds_name}
state: CLOSED
current_operation: IDLE
position_action:
then:
- stepper.set_target:
id: stepper_motor
target: !lambda return int(id(endstop).state * pos);
- while:
condition:
lambda: 'return id(stepper_motor).current_position != int(id(endstop).state * pos);'
then:
- cover.template.publish:
id: ${blinds_name}
position: !lambda 'return (float(float(id(stepper_motor).current_position) / float(id(endstop).state)));'
- delay: 1000 ms
- globals.set: # Set global to current position
id: stepper_motor_global
value: !lambda return id(stepper_motor).current_position;
- sensor.template.publish:
id: stepper_pos
state: !lambda return id(stepper_motor).current_position;
- cover.template.publish:
id: ${blinds_name}
position: !lambda 'return (float(float(id(stepper_motor).current_position) / float(id(endstop).state)));'
current_operation: IDLE
stop_action:
then:
- stepper.set_target:
id: stepper_motor
target: !lambda return id(stepper_motor).current_position;
- globals.set: # Set global to current position
id: stepper_motor_global
value: !lambda return id(stepper_motor).current_position;
- sensor.template.publish:
id: stepper_pos
state: !lambda return id(stepper_motor).current_position;
- cover.template.publish:
id: ${blinds_name}
position: !lambda 'return (float(float(id(stepper_motor).current_position) / float(id(endstop).state)));'
current_operation: IDLE
has_position: true
device_class: blind
switch:
- platform: template
name: Reset Dining Room Blinds
id: reset
turn_on_action:
- stepper.set_target:
id: stepper_motor
target: !lambda 'return id(endstop).state * 2;'
- wait_until:
lambda: 'return id(stepper_motor).current_position == id(endstop).state*2;'
- delay: 1s
- stepper.set_target:
id: stepper_motor
target: '0'
- globals.set: # Set global to current position
id: stepper_motor_global
value: !lambda return id(stepper_motor).current_position;
- sensor.template.publish:
id: stepper_pos
state: !lambda return id(stepper_motor).current_position;
- globals.set: # Set toggle to CLOSED (No need for 'optimistic mode')
id: openclosed
value: '0'
- cover.template.publish:
id: ${blinds_name}
state: CLOSED
current_operation: IDLE
- switch.turn_off: reset
# - platform: output
# name: "A4988 reset"
# output: 'A4988reset'
# internal: false
# id: swreset
output:
- platform: gpio
id: 'A4988reset'
pin: ${pin_mot_rst}
inverted: True
# cover:
# - platform: template
# name: "Template Cover"
# lambda: |-
# open_action:
# - switch.turn_on: open_cover_switch
# close_action:
# - switch.turn_on: close_cover_switch
# stop_action:
# - switch.turn_on: stop_cover_switch
# optimistic: true

BIN
esphome/fonts/Solari.ttf Executable file

Binary file not shown.

View File

@@ -15,7 +15,7 @@ substitutions:
pin_ir_rx: GPIO5
pin_button: GPIO13
pin_leds: GPIO03
pin_status: GPIO4
#pin_status: GPIO4
pin_sda: GPIO4
pin_scl: GPIO0
@@ -26,7 +26,7 @@ packages:
connection: !include common/wifi.yaml
device_base: !include common/common.yaml
climate: !include templates/climate_sens.yaml
status: !include templates/status.yaml
#status: !include templates/status.yaml
logger: !include templates/logger.yaml
sht3x: !include sensors/sht3x.yaml

BIN
esphome/include/4dir.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

View File

@@ -0,0 +1,18 @@
i2s_audio:
i2s_lrclk_pin: ${pin_lrclk}
i2s_bclk_pin: ${pin_bclk}
microphone:
- platform: i2s_audio
id: mic
i2s_din_pin: ${pin_i2sdin}
adc_type: external
pdm: false
speaker:
- platform: i2s_audio
id: big_speaker
i2s_dout_pin: ${pin_i2sdout}
dac_type: external
mode: mono

View File

@@ -0,0 +1,25 @@
---
i2s_audio:
- id: i2s_es7210
i2s_lrclk_pin: ${pin_es7210_lrck}
i2s_bclk_pin: ${pin_es7210_blck}
- id: i2s_maxspk
i2s_lrclk_pin: ${pin_i2slrclk}
i2s_bclk_pin: ${pin_i2sbclk}
i2s_mclk_pin: ${pin_es7210_mclk}
microphone:
- platform: i2s_audio
id: mic
i2s_audio_id: i2s_es7210
i2s_din_pin: ${pin_es7210_din}
adc_type: external
pdm: false
speaker:
- platform: i2s_audio
i2s_audio_id: i2s_maxspk
id: big_speaker
i2s_dout_pin: ${pin_i2sdout}
dac_type: external
mode: mono

4
esphome/interfaces/spi.yaml Executable file
View File

@@ -0,0 +1,4 @@
spi:
clk_pin: ${pin_clk}
mosi_pin: ${pin_mosi}
miso_pin: ${pin_miso}

Submodule esphome/sensors/.esphome/external_components/1e6970f9 deleted from e995883d66

Submodule esphome/sensors/.esphome/external_components/9cb05fac deleted from 94b3200604

View File

@@ -1,23 +1,23 @@
---
sensor:
# Batterie volt
- platform: adc
pin: ${pin_vbatt}
name: 'Battery Voltage'
id: 'Battery_voltage'
attenuation: 11db
unit_of_measurement: 'V'
icon: 'mdi:battery-high'
device_class: 'voltage'
state_class: 'measurement'
accuracy_decimals: 2
filters:
- multiply: 2
- calibrate_linear:
# Map 0.0 (from sensor) to 0.0 (true value)
- 0.0 -> 0.0
- 4.0 -> 4.0
update_interval: ${update_interval}
# - platform: adc
# pin: ${pin_vbatt}
# name: 'Battery Voltage'
# id: 'Battery_voltage'
# attenuation: 11db
# unit_of_measurement: 'V'
# icon: 'mdi:battery-high'
# device_class: 'voltage'
# state_class: 'measurement'
# accuracy_decimals: 2
# filters:
# - multiply: 2
# - calibrate_linear:
# # Map 0.0 (from sensor) to 0.0 (true value)
# - 0.0 -> 0.0
# - 4.0 -> 4.0
# update_interval: ${update_interval}
# Battery %
- platform: adc

View File

@@ -1,6 +1,6 @@
---
sensor:
- platform: bme280
- platform: bme280_i2c
i2c_id: bus_a
temperature:
name: 'Temperature (BME280)'

View File

@@ -0,0 +1,14 @@
---
sensor:
- platform: rotary_encoder
internal: False
name: "Rotary Encoder"
pin_a: ${pin_encode_a}
pin_b: ${pin_encode_b}
binary_sensor:
- platform: gpio
pin:
number: ${pin_encode_btn}
inverted: True
name: "Rotary Button"

View File

@@ -0,0 +1,23 @@
---
sensor:
- platform: tsl2591
name: "light sensor"
id: "tls2591"
address: 0x29
update_interval: 60s
gain: auto
device_factor: 53
glass_attenuation_factor: 14.4
visible:
name: "visible light"
infrared:
name: "infrared light"
full_spectrum:
name: "full spectrum light"
calculated_lux:
id: i_lux
name: "Lux"
actual_gain:
id: "actual_gain"
name: "actual gain"

View File

@@ -11,4 +11,4 @@ sensor:
name: Particulate Matter 2.5µm Concentration
pm_10_0:
name: Particulate Matter 10µm Concentration
update_interval: 30000ms
update_interval: ${update_interval}

View File

@@ -11,4 +11,24 @@ sensor:
accuracy_decimals: 1
temperature_offset: 1.5 °C
address: 0x61
update_interval: 5s
update_interval: 1s
button:
- platform: template
name: "SCD30 Force manual calibration"
entity_category: "config"
on_press:
then:
- scd30.force_recalibration_with_reference:
value: !lambda 'return id(co2_cal).state;'
number:
- platform: template
name: "CO2 calibration value"
optimistic: true
min_value: 350
max_value: 4500
step: 1
id: co2_cal
icon: "mdi:molecule-co2"
entity_category: "config"

View File

@@ -8,5 +8,5 @@ sensor:
humidity:
name: Humidity
address: 0x44
update_interval: 60s
update_interval: ${update_interval}

178
esphome/t-embed.yaml Normal file
View File

@@ -0,0 +1,178 @@
substitutions:
device_name: "t-embed"
friendly_name: "t-embed"
comment: "esp32-s3, lcd, rotary, leds, mic, spk"
location: "zolder"
api_password: !secret t-embed_api
ota_password: !secret ota_password
wifi_ssid: !secret wifi_ssid
wifi_password: !secret wifi_password
gateway: !secret ip_gateway
subnet: !secret ip_subnet
ip: !secret t-embed_ip
update_interval: 30s
num_leds: "7"
led_chipset: APA102
#t-embed pins
pin_i2slrclk: GPIO05
pin_i2sbclk: GPIO07
pin_i2sdout: GPIO06
pin_es7210_blck: GPIO47
pin_es7210_lrck: GPIO21
pin_es7210_din: GPIO14
pin_es7210_mclk: GPIO48
pin_sd_cs: GPIO39
pin_sd_sck: GPIO40
pin_sd_mosi: GPIO41
pin_sd_miso: GPIO38
pin_power: GPIO46
pin_led_data: GPIO42
pin_led_clk: GPIO45
pin_encode_a: GPIO02
pin_encode_b: GPIO01
pin_encode_btn: GPIO00
pin_sda: GPIO44
pin_scl: GPIO43
pin_lcd_bl: GPIO15
pin_lcd_dc: GPIO13
pin_lcd_cs: GPIO10
pin_lcd_clk: GPIO12
pin_lcd_mosi: GPIO11
pin_lcd_res: GPIO09
pin_vbat: GPIO4
packages:
board: !include boards/esp32-s3-voice.yaml
spkmic: !include interfaces/SpkMicVoiceTembed.yaml
#leds: !include templates/light_fastled_spi.yaml
connection: !include common/wifi.yaml
logger: !include templates/logger.yaml
backlight: !include templates/backlight.yaml
#i2c: !include interfaces/i2c_a.yaml
#lightsens: !include sensors/light_tsl2591.yaml
encoder: !include sensors/encoder.yaml
esphome:
name: ${device_name}
platformio_options:
# build_flags: |-
# -DARDUINO_USB_CDC_ON_BOOT=1 -DLV_CONF_INCLUDE_SIMPLE
board_build.mcu: esp32s3
board_build.name: "LilyGO T-Embed ESP32-S3"
board_build.upload.flash_size: "16MB"
board_build.upload.maximum_size: 16777216
board_build.vendor: "LilyGO"
on_boot:
priority: 800
then:
# - lambda: |-
# id(disp).enable();
# id(disp).transfer_byte(0x11);
# id(disp).disable();
- switch.turn_on: power_on
button:
- platform: restart
name: 'Restart'
api:
on_client_connected:
then:
- delay: 50ms
- micro_wake_word.start:
on_client_disconnected:
then:
- voice_assistant.stop:
switch:
- platform: template
id: mute
name: mute
optimistic: true
on_turn_on:
- micro_wake_word.stop:
- voice_assistant.stop:
on_turn_off:
- micro_wake_word.start:
- platform: gpio
pin:
number: ${pin_power}
mode:
output: True
restore_mode: RESTORE_DEFAULT_ON
name: "Power On"
id: power_on
# time:
# - platform: homeassistant
# id: home_time
voice_assistant:
id: va
microphone: mic
noise_suppression_level: 2.0
volume_multiplier: 4.0
on_error:
- micro_wake_word.start:
on_end:
then:
- wait_until:
not:
voice_assistant.is_running:
- micro_wake_word.start:
micro_wake_word:
on_wake_word_detected:
- voice_assistant.start:
model: okay_nabu
spi:
id: ledbus
mosi_pin: ${pin_led_data}
clk_pin: ${pin_led_clk}
light:
- platform: spi_led_strip
num_leds: 30
spi_id: "ledbus"
color_correct: [80%, 60%, 100%]
id: rgb_led
name: "RGB LED Strip"
data_rate: 1MHz
# font:
# - file: "gfonts://Roboto"
# id: roboto
# size: 96
# spi:
# - id: spi_display
# clk_pin: ${pin_lcd_clk}
# mosi_pin: ${pin_lcd_mosi}
# display:
# - platform: st7789v
# model: CUSTOM
# eightbitcolor: False
# rotation: 270
# width: 170
# height: 320
# offset_width: 0
# offset_height: 35
# #backlight_pin: ${pin_lcd_bl}
# cs_pin: ${pin_lcd_cs}
# dc_pin: ${pin_lcd_dc}
# reset_pin: ${pin_lcd_res}
# update_interval: 5s
# id: disp
# lambda: |-
# it.strftime(10, 20, id(roboto), "%H:%M", id(home_time).now());

View File

@@ -0,0 +1,12 @@
output:
- platform: ledc
pin: ${pin_lcd_bl}
id: out_backlight
light:
- platform: monochromatic
name: "${friendly_name} Back Light"
output: out_backlight
id: backlight
restore_mode: Restore_and_on

17
esphome/templates/color.yaml Executable file
View File

@@ -0,0 +1,17 @@
color:
- id: red
red: 100%
green: 3%
blue: 5%
- id: white
red: 100%
green: 100%
blue: 100%
- id: green
red: 0%
green: 100%
blue: 0%
- id: black
red: 0%
green: 0%
blue: 0%

View File

@@ -0,0 +1,23 @@
---
external_components:
- source:
type: local
path: components
light:
- platform: fastled_spi
id: led_lights
data_pin: ${pin_led_data}
clock_pin: ${pin_led_clk}
restore_mode: RESTORE_DEFAULT_ON
name: ${device_name}_leds
chipset: ${led_chipset}
rgb_order: BGR
num_leds: ${num_leds}
effects:
- flicker:
name: "Flicker"
alpha: 95%
intensity: 1.5%
- addressable_rainbow:
- addressable_scan:

View File

@@ -8,7 +8,7 @@ light:
name: ${device_name}_leds
chipset: ${chipset}
rgb_order: GRB
num_leds: 2 #${num_leds}
num_leds: ${num_leds}
pin: ${pin_led1}
effects:
- flicker:

View File

@@ -1,3 +1,8 @@
# logging
logger:
baud_rate: 115200
baud_rate: 115200
logs:
display: ERROR
sensor: ERROR
cover: ERROR
switch: ERROR

View File

@@ -0,0 +1,11 @@
touchscreen:
- platform: ft63x6
id: ${id_prefix}_touch
i2c_id: bus_a
transform:
mirror_y: true
swap_xy: true
on_touch:
- logger.log:
format: Touch at (%d, %d)
args: [touch.x, touch.y]

100
esphome/trash/wekker.yaml Normal file
View File

@@ -0,0 +1,100 @@
substitutions:
device_name: "wekker"
friendly_name: "wekker"
comment: "esp32, lcd wt32-sc01"
location: "slaaplamer"
api_password: !secret wekker_api
ota_password: !secret ota_password
wifi_ssid: !secret wifi_ssid
wifi_password: !secret wifi_password
gateway: !secret ip_gateway
subnet: !secret ip_subnet
ip: !secret wekker_ip
# pin_bl: GPIO23
# pin_clk: GPIO14
# pin_mosi: GPIO13
# pin_miso: GPIO12
# pin_cs: GPIO15
# pin_dc: GPIO21
# pin_lcdrst: GPIO22
# pin_sda: GPIO18
# pin_scl: GPIO19
esphome:
name: ${device_name}
esp32:
board: esp-wrover-kit
framework:
type: arduino
# packages:
# device_base: !include includes/common_settings.yaml
#esp32_ble_tracker:
#bluetooth_proxy:
# active: true
# time:
# - platform: homeassistant
# id: homeassistant_time
# output:
# - platform: gpio
# pin: GPIO23
# id: tst_Backlight
# light:
# - platform: binary
# name: "${friendly_name} Back Light"
# output: tst_Backlight
# id: ${id_prefix}_backlight
# restore_mode: ALWAYS_ON
# spi:
# clk_pin: GPIO14
# mosi_pin: GPIO13
# miso_pin: GPIO12
# display:
# - platform: ili9xxx
# id: ${id_prefix}_display
# model: ST7796
# cs_pin: GPIO15
# dc_pin: GPIO21
# reset_pin: GPIO22
# rotation: 270
# pages:
# - id: page1
# lambda: |-
# it.printf(64,0, id(my_font), TextAlign::TOP_CENTER, "WT32-SC01");
# it.strftime(64, 40, id(my_font), TextAlign::BASELINE_CENTER, "%I:%M:%S %p", id(homeassistant_time).now());
# it.printf(64, 60, id(my_font), TextAlign::BOTTOM_CENTER, "Time");
# - id: page2
# lambda: |-
# it.printf(64,0, id(my_font), TextAlign::TOP_CENTER, "WT32-SC01");
# it.printf(64, 40, id(my_font), TextAlign::BASELINE_CENTER, "Hello Loryan!");
# it.printf(64, 60, id(my_font), TextAlign::BOTTOM_CENTER, "Hi from down here");
# font:
# - file:
# type: gfonts
# family: "Open Sans"
# id: my_font
# size: 20
# color:
# - id: my_red
# red: 100%
# green: 3%
# blue: 5%
# - id: my_white
# red: 100%
# green: 100%
# blue: 100%
# interval:
# - interval: 5s
# then:
# - display.page.show_next: wt32_sc01_display
# - component.update: wt32_sc01_display

View File

@@ -0,0 +1,55 @@
substitutions:
device_name: "tuyaplug001"
friendly_name: "tuya plug 001"
comment: "eps-02S, tuya-hack"
location: "zolder"
api_password: !secret tuya_plug_api
ota_password: !secret ota_password
wifi_ssid: !secret wifi_ssid
wifi_password: !secret wifi_password
gateway: !secret ip_gateway
subnet: !secret ip_subnet
ip: !secret tuya_plug_001_ip
pin_relay: GPIO12
pin_button: GPIO14
pin_status: GPIO04
packages:
board: !include boards/esp12f.yaml
connection: !include common/wifi.yaml
device_base: !include common/common.yaml
status: !include templates/status.yaml
logger: !include templates/logger.yaml
binary_sensor:
- platform: gpio
pin:
number: ${pin_button}
mode:
input: true
pullup: true
inverted: true
name: "Button"
on_press:
- light.toggle: lamp_relay
# switch:
# - platform: gpio
# name: "Sonoff Basic Relay"
# pin: ${pin_relay}
# id: relay
# device_class: light
output:
- platform: gpio
pin: ${pin_relay}
id: relay
light:
- platform: binary
name: "light"
output: relay
id: lamp_relay
restore_mode: RESTORE_DEFAULT_ON

320
esphome/voiceassistS3.yaml Normal file
View File

@@ -0,0 +1,320 @@
substitutions:
device_name: "voiceassist1"
friendly_name: "ESP32 voice Assist 2"
comment: "esp32-s3, mic, dac, RGB"
api_password: !secret voiceassist1_api
ota_password: !secret ota_password
wifi_ssid: !secret wifi_ssid
wifi_password: !secret wifi_password
gateway: !secret ip_gateway
subnet: !secret ip_subnet
ip: !secret voiceassist1_ip
pin_lrclk: GPIO18
pin_bclk: GPIO6
pin_i2sdin: GPIO16
pin_i2sdout: GPIO17
#pin_button: GPIO14
pin_led1: GPIO48
num_leds: "1"
chipset: ws2812
micro_wake_word_model: okay_nabu
voice_assist_idle_phase_id: "1"
voice_assist_listening_phase_id: "2"
voice_assist_thinking_phase_id: "3"
voice_assist_replying_phase_id: "4"
voice_assist_not_ready_phase_id: "10"
voice_assist_error_phase_id: "11"
voice_assist_muted_phase_id: "12"
packages:
board: !include boards/esp32-s3-voice.yaml
spkmic: !include interfaces/SpkMicVoice.yaml
leds: !include templates/light_rgbw_rmt.yaml
connection: !include common/wifi.yaml
logger: !include templates/logger.yaml
esphome:
name: ${device_name}
friendly_name: ${friendly_name}
name_add_mac_suffix: true
platformio_options:
board_build.flash_mode: dio
min_version: 2023.11.5
project:
name: esphome.voice-assistant
version: "2.0"
on_boot:
priority: 600
then:
- delay: 30s
- if:
condition:
lambda: return id(init_in_progress);
then:
- lambda: id(init_in_progress) = false;
- light.turn_on:
id: led_lights
brightness: 30%
red: 0%
green: 50%
blue: 50%
effect: pulse
dashboard_import:
package_import_url: github://esphome/firmware/wake-word-voice-assistant/esp32-s3-box.yaml@main
button:
- platform: factory_reset
id: factory_reset_btn
name: Factory reset
esp32_improv:
authorizer: none
binary_sensor:
- platform: gpio
pin:
number: GPIO1
inverted: true
name: "Mute"
disabled_by_default: true
entity_category: diagnostic
micro_wake_word:
model: ${micro_wake_word_model}
on_wake_word_detected:
- voice_assistant.start
voice_assistant:
id: va
microphone: mic
use_wake_word: true
noise_suppression_level: 2
auto_gain: 31dBFS
volume_multiplier: 2.0
speaker: big_speaker
on_client_connected:
- if:
condition:
switch.is_off: mute
then:
- wait_until:
not: ble.enabled
- if:
condition:
lambda: return id(wake_word_engine_location).state == "In Home Assistant";
then:
- lambda: id(va).set_use_wake_word(true);
- voice_assistant.start_continuous:
- if:
condition:
lambda: return id(wake_word_engine_location).state == "On device";
then:
- micro_wake_word.start
- lambda: id(voice_assistant_phase) = ${voice_assist_idle_phase_id};
else:
- lambda: id(voice_assistant_phase) = ${voice_assist_muted_phase_id};
- lambda: id(init_in_progress) = false;
- light.turn_on:
id: led_lights
brightness: 30%
red: 0%
green: 100%
blue: 0%
effect: none
on_listening:
- lambda: id(voice_assistant_phase) = ${voice_assist_listening_phase_id};
- light.turn_on:
id: led_lights
brightness: 30%
red: 0%
green: 100%
blue: 0%
effect: pulse
on_stt_vad_end:
- lambda: id(voice_assistant_phase) = ${voice_assist_thinking_phase_id};
- light.turn_on:
id: led_lights
brightness: 30%
red: 0%
green: 100%
blue: 100%
effect: Pulse
on_tts_stream_start:
- lambda: id(voice_assistant_phase) = ${voice_assist_replying_phase_id};
- light.turn_on:
id: led_lights
brightness: 30%
red: 0%
green: 100%
blue: 100%
effect: none
on_tts_stream_end:
- lambda: id(voice_assistant_phase) = ${voice_assist_idle_phase_id};
- light.turn_on:
id: led_lights
brightness: 30%
red: 0%
green: 0%
blue: 100%
effect: Pulse
on_error:
- if:
condition:
lambda: return !id(init_in_progress);
then:
- lambda: id(voice_assistant_phase) = ${voice_assist_error_phase_id};
- delay: 1s
- if:
condition:
switch.is_off: mute
then:
- lambda: id(voice_assistant_phase) = ${voice_assist_idle_phase_id};
else:
- lambda: id(voice_assistant_phase) = ${voice_assist_muted_phase_id};
- light.turn_on:
id: led_lights
brightness: 30%
red: 100%
green: 0%
blue: 0%
effect: Pulse
- delay: 4s
- light.turn_off:
id: led_lights
on_client_disconnected:
- if:
condition:
lambda: return id(wake_word_engine_location).state == "In Home Assistant";
then:
- lambda: id(va).set_use_wake_word(false);
- voice_assistant.stop:
- if:
condition:
lambda: return id(wake_word_engine_location).state == "On device";
then:
- micro_wake_word.stop
- lambda: id(voice_assistant_phase) = ${voice_assist_not_ready_phase_id};
- light.turn_on:
id: led_lights
brightness: 30%
red: 100%
green: 0%
blue: 0%
effect: none
on_end:
- if:
condition:
and:
- switch.is_off: mute
- lambda: return id(wake_word_engine_location).state == "On device";
then:
- wait_until:
not:
voice_assistant.is_running:
- micro_wake_word.start:
switch:
# - platform: template
# name: Use wake word
# id: use_wake_word
# optimistic: true
# restore_mode: RESTORE_DEFAULT_ON
# entity_category: config
# on_turn_on:
# - lambda: id(assist).set_use_wake_word(true);
# - if:
# condition:
# not:
# - voice_assistant.is_running
# then:
# - voice_assistant.start_continuous
# on_turn_off:
# - voice_assistant.stop
# - lambda: id(assist).set_use_wake_word(false);
- platform: template
name: Mute
id: mute
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
entity_category: config
on_turn_off:
- if:
condition:
lambda: return !id(init_in_progress);
then:
- lambda: id(voice_assistant_phase) = ${voice_assist_idle_phase_id};
- if:
condition:
not:
- voice_assistant.is_running
then:
- if:
condition:
lambda: return id(wake_word_engine_location).state == "In Home Assistant";
then:
- lambda: id(va).set_use_wake_word(true);
- voice_assistant.start_continuous
- if:
condition:
lambda: return id(wake_word_engine_location).state == "On device";
then:
- micro_wake_word.start
on_turn_on:
- if:
condition:
lambda: return !id(init_in_progress);
then:
- lambda: id(va).set_use_wake_word(false);
- voice_assistant.stop
- micro_wake_word.stop
- lambda: id(voice_assistant_phase) = ${voice_assist_muted_phase_id};
select:
- platform: template
entity_category: config
name: Wake word engine location
id: wake_word_engine_location
optimistic: true
restore_value: true
options:
- In Home Assistant
- On device
initial_option: On device
on_value:
- wait_until:
lambda: return id(voice_assistant_phase) == ${voice_assist_muted_phase_id} || id(voice_assistant_phase) == ${voice_assist_idle_phase_id};
- if:
condition:
lambda: return x == "In Home Assistant";
then:
- micro_wake_word.stop
- delay: 500ms
- if:
condition:
switch.is_off: mute
then:
- lambda: id(va).set_use_wake_word(true);
- voice_assistant.start_continuous:
- if:
condition:
lambda: return x == "On device";
then:
- lambda: id(va).set_use_wake_word(false);
- voice_assistant.stop
- delay: 500ms
- micro_wake_word.start
globals:
- id: init_in_progress
type: bool
restore_value: false
initial_value: "true"
- id: voice_assistant_phase
type: int
restore_value: false
initial_value: ${voice_assist_not_ready_phase_id}