first commit

This commit is contained in:
Chris Stuurman 2025-08-23 17:02:53 +02:00
commit da5effe922
14 changed files with 7556 additions and 0 deletions

0
README.md Normal file
View File

34
common/canbus.yaml Normal file
View File

@ -0,0 +1,34 @@
substitutions:
CB_CANBUS_ID1: 0x501
CB_CANBUS_ID2: 0x502
CB_CANBUS_ID3: 0x503
CB_CANBUS_ID4: 0x504
CB_CANBUS_ID5: 0x505
CB_CANBUS_ID6: 0x506
CB_CANBUS_ID7: 0x507
CB_CANBUS_ID8: 0x508
CB_CANBUS_ID9: 0x509
CB_CANBUS_ID10: 0x50A
CB_GEYSER_ENERGISED: 0x400
CB_UTILITY_POWER_ON: 0x401
CB_GEYSER_TOP_TEMPERATURE: 0x410
CB_GEYSER_BOTTOM_TEMPERATURE: 0x411
CB_AMBIENT_TEMPERATURE: 0x412
CB_MAINS_VOLTAGE: 0x420
CB_INVERTER_OUTPUT_VOLTAGE: 0x421
CB_MAINS_CURRENT: 0x430
CB_INVERTER_OUTPUT_CURRENT: 0x431
CB_GEYSER_CURRENT: 0x432
CB_POOL_CURRENT: 0x433
CB_MAINS_POWER: 0x440
CB_INVERTER_POWER: 0x441
CB_GEYSER_POWER: 0x442
CB_POOL_POWER: 0x443
# battery messages
CB_BATTERY_LIMITS: 0x351
CB_BATTERY_STATE: 0x355
CB_BATTERY_STATUS: 0x356
CB_BATTERY_FAULT: 0x359
CB_BATTERY_REQUEST_FLAG: 0x35C
CB_BATTERY_MANUFACTURER: 0x35E

8
common/geyser.yaml Normal file
View File

@ -0,0 +1,8 @@
substitutions:
HEATING_IDLE: 30
HEATING_WARM: 45
HEATING_LUKE_WARM: 35
HEATING_HOT: 70
HEATING_DAY_TYPES: 4
HEATING_DAY_BLOCKS: 6
HEATING_TEMP_SCALE: 1000.0

21
common/wifi.yaml Normal file
View File

@ -0,0 +1,21 @@
wifi:
domain: .sthome.org
networks:
- ssid: !secret wifi_ssid1
password: !secret wifi_password1
- ssid: !secret wifi_ssid2
password: !secret wifi_password2
- ssid: !secret wifi_ssid3
password: !secret wifi_password3
- ssid: !secret wifi_ssid4
password: !secret wifi_password4
- ssid: !secret wifi_ssid5
password: !secret wifi_password5
manual_ip:
# For faster connection startup,
# NB! set a static IP address in main config file
gateway: 10.0.0.2
subnet: 255.255.240.0
# we will use local dns server for local dns resolution
dns1: 10.0.0.1
dns2: 10.0.0.2

20
secrets.yaml Normal file
View File

@ -0,0 +1,20 @@
# Wi-Fi SSID and password (default - used with new device setups)
# for multi network
wifi_ssid1: "sthome-2.4G1"
wifi_ssid2: "sthome-2.4G2"
wifi_ssid3: "sthome-2.4G3"
wifi_ssid4: "sthome-2.4G4"
wifi_ssid5: "sthome-2.4G5"
wifi_password1: "053d53f24e88d8618b618a2fa4c1d9"
wifi_password2: "053d53f24e88d8618b618a2fa4c1d9"
wifi_password3: "053d53f24e88d8618b618a2fa4c1d9"
wifi_password4: "053d53f24e88d8618b618a2fa4c1d9"
wifi_password5: "053d53f24e88d8618b618a2fa4c1d9"
# default Wi-Fi SSID and password
wifi_ssid: "sthome-2.4G1"
wifi_password: "053d53f24e88d8618b618a2fa4c1d9"
# latitude & longitude
latitude: -25.711340
longitude: 28.118370

178
sthome-ut1.yaml Normal file
View File

@ -0,0 +1,178 @@
esphome:
name: sthome-ut1
friendly_name: sthome-ut1
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
level: INFO
# Enable Home Assistant API
api:
encryption:
key: "0Ki4j7JX8Y1IkMGh1fBBu2Dg6DgrnUq8GEXKZvkzeSY="
ota:
- platform: esphome
password: "37f546590fcc15e1323d273540eb623a"
wifi:
#ssid: !secret wifi_ssid
#password: !secret wifi_password
# we will use local dns server for local dns resolution
domain: ".sthome.org"
networks:
- ssid: !secret wifi_ssid1
password: !secret wifi_password1
- ssid: !secret wifi_ssid2
password: !secret wifi_password2
- ssid: !secret wifi_ssid3
password: !secret wifi_password3
- ssid: !secret wifi_ssid4
password: !secret wifi_password4
- ssid: !secret wifi_ssid5
password: !secret wifi_password5
manual_ip:
# For faster connection startup, set a static IP address
# Set this to the IP of the ESP
static_ip: 10.0.2.1
gateway: 10.0.0.2
subnet: 255.255.240.0
dns1: 10.0.0.1
dns2: 10.0.0.2
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "sthome-ut1 Fallback Hotspot"
password: "7SglIlgdkpAD"
captive_portal:
#preferences:
# flash_write_interval: 30s
sun:
id: sun_sensor
latitude: !secret latitude
longitude: !secret longitude
time:
- platform: homeassistant
#define OUTPUT_R1 16
#define OUTPUT_R2 17
#define OUTPUT_R3 18
#define OUTPUT_R4 19
switch:
- platform: gpio
pin:
number: GPIO16
inverted: true
id: relay1
name: "Floodlights Backyard"
icon: "mdi:light-flood-down"
restore_mode: RESTORE_DEFAULT_OFF
# the backyard floodlight auto turns off in 4min 14 sec. So we need to switch relay off just before or at this time
# TODO: remove or extend auto turn off to >= 10min
on_turn_on:
- delay: 250s
- switch.turn_off: relay1
- platform: gpio
pin:
number: GPIO17
inverted: true
id: relay2
name: "Relay 2"
icon: "mdi:run-fast"
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
- delay: 1000ms
- switch.turn_off: relay2
- platform: gpio
pin:
number: GPIO18
inverted: true
id: relay3
name: "Relay 3"
icon: "mdi:run-fast"
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
- delay: 1000ms
- switch.turn_off: relay3
- platform: gpio
pin:
number: GPIO19
inverted: true
id: relay4
name: "Alarm Zone 4"
icon: "mdi:alarm-light-outline"
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
- if:
condition:
- lambda: |-
double sun_elevation = id(sun_sensor).elevation();
return (sun_elevation <= -6); // -6° = civil twilight, -12° = nautical twilight, -18° = astronomical twilight
#- sun.is_below_horizon:
then:
- switch.turn_on: relay1
- if:
condition:
- binary_sensor.is_on: floodlight_test
then:
- switch.turn_on: relay1
- delay: 30s
- switch.turn_off: relay4
# define DIGITAL_D1 04
binary_sensor:
- platform: gpio
# device_class: light
id: floodlight_test
pin:
number: GPIO04
mode:
input: true
pullup: true
filters:
- delayed_off: 100ms
name: "Floodlights Test Mode"
icon: "mdi:lightbulb-on-outline"
#define ANALOG_A1 33
#define ANALOG_A2 32
#define ANALOG_A3 35
#define ANALOG_A4 34
#define ANALOG_A5 39
#define ANALOG_A6 36
sensor:
- platform: adc
pin: 35
name: "Alarm Signal"
id: alarm_signal
update_interval: 2000ms
attenuation: 12db
sampling_mode: avg
filters:
- lambda:
if (x >= 3.11) {
return x * 1.60256;
} else if (x <= 0.25) {
return 0;
} else {
return x * 1.51;
}
on_value:
then:
# switch on floodlights
lambda: |-
if (id(alarm_signal).state > 1.5) {
id(relay1).turn_on();
}

1456
sthome-ut10.yaml Normal file

File diff suppressed because it is too large Load Diff

394
sthome-ut2.yaml Normal file
View File

@ -0,0 +1,394 @@
substitutions:
name: sthome-ut2
friendly_name: "sthome-ut2"
esphome:
name: "${name}"
friendly_name: "${friendly_name}"
# - priority: 200 # Network connections like MQTT/native API are set up at this priority.
# then:
# - lambda: |-
esp32:
board: esp32dev
framework:
type: arduino
#type: esp-idf
#debug:
# update_interval: 5s
# Enable logging
logger:
level: DEBUG
# Enable Home Assistant API
api:
encryption:
key: "o+fgr4qh0rTegCxXE3jbfJ/0si8+W9wxgnnYX9Xucqw="
ota:
- platform: esphome
password: "cb8a82d04c2f4dcf9bd273f903c7c378"
wifi:
#ssid: !secret wifi_ssid
#password: !secret wifi_password
# we will use local dns server for local dns resolution
power_save_mode: none
domain: ".sthome.org"
networks:
- ssid: !secret wifi_ssid1
password: !secret wifi_password1
- ssid: !secret wifi_ssid2
password: !secret wifi_password2
- ssid: !secret wifi_ssid3
password: !secret wifi_password3
- ssid: !secret wifi_ssid4
password: !secret wifi_password4
- ssid: !secret wifi_ssid5
password: !secret wifi_password5
manual_ip:
# For faster connection startup, set a static IP address
# Set this to the IP of the ESP
static_ip: 10.0.2.2
gateway: 10.0.0.2
subnet: 255.255.240.0
dns1: 10.0.0.1
dns2: 1.1.1.1
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "${name} Fallback Hotspot"
password: "geuZrJgQo7cg"
captive_portal:
one_wire:
- platform: gpio
pin: GPIO4
id: temperature_sensors
#i2c:
# sda: GPIO21
# scl: GPIO22
font:
- file: "fonts/Windows/comic.ttf"
id: my_font
size: 20
bpp: 2
- file: "fonts/misc/tom-thumb.bdf"
id: tomthumb
# gfonts://family[@weight]
- file: "gfonts://Roboto"
id: roboto_20
size: 20
- file:
type: gfonts
family: Roboto
weight: 900
id: roboto_16
size: 16
- file: "fonts/Windows/arial.ttf"
id: arial_14
size: 14
# gfonts://family[@weight]
- file: "gfonts://Roboto"
id: roboto
size: 20
- file: "gfonts://Carrois Gothic"
id: Carrois_Gothic
size: 20
- file: "gfonts://Kdam Thmor Pro"
id: Kdam_Thmor_Pro
size: 40
- file: "gfonts://Merriweather"
id: Merriweather
size: 30
- file: "gfonts://Material+Symbols+Outlined"
id: icons_50
size: 50
glyphs: ["\U0000e425"] # mdi-timer
- file: "fonts/roboto/Roboto-Condensed.ttf"
id: roboto_special_28
size: 28
bpp: 4
glyphs: [
0123456789aAáÁeEéÉ,
(,),+,-,_,.,°,•,µ,
"\u0020", # space
"\u002C", # ,
"\u0021", # !
"\u0022", # "
"\u0027", # '
"\u003A", # :
]
- file: "fonts/roboto/Roboto-Condensed.ttf"
id: roboto_special_32
size: 32
bpp: 4
glyphs: [
0123456789aAáÁeEéÉ,
(,),+,-,_,.,°,•,µ,
"\u0020", # space
"\u002C", # ,
"\u0021", # !
"\u0022", # "
"\u0027", # '
"\u003A", # :
]
- file: "fonts/roboto/Roboto-Condensed.ttf"
id: roboto_special_36
size: 36
bpp: 4
glyphs: [
0123456789aAáÁeEéÉ,
(,),+,-,_,.,°,•,µ,
"\u0020", # space
"\u002C", # ,
"\u0021", # !
"\u0022", # "
"\u0027", # '
"\u003A", # :
]
# - file: "fonts/RobotoCondensed-Regular.ttf"
# id: my_font_with_icons
# size: 20
# bpp: 4
# extras:
# - file: "fonts/misc/materialdesignicons-webfont.ttf"
# glyphs: [
# "\U000F02D1", # mdi-heart
# "\U000F05D4", # mdi-airplane-landing
# ]
- file:
type: gfonts
family: Roboto
id: roboto_european_core
size: 16
glyphsets:
- GF_Latin_Core
- GF_Greek_Core
- GF_Cyrillic_Core
- file: "https://github.com/IdreesInc/Monocraft/releases/download/v3.0/Monocraft.ttf"
id: web_font
size: 20
- file:
url: "https://github.com/IdreesInc/Monocraft/releases/download/v3.0/Monocraft.ttf"
type: web
id: web_font2
size: 24
#ads1115:
# - address: 0x48
# id: ads1115_48
# continuous_mode: true
# - address: 0x49
# id: ads1115_49
# continuous_mode: true
# - address: 0x4A
# id: ads1115_4A
# continuous_mode: true
# # - address: 0x4B
# # id: ads1115_4B
spi:
- id: spi_bus0
clk_pin: GPIO18
mosi_pin: GPIO23
miso_pin: GPIO19
interface: any
psram:
sun:
id: sun_sensor
latitude: !secret latitude
longitude: !secret longitude
time:
# - platform: sntp
# timezone: Africa/Johannesburg
# servers:
# - ntp1.meraka.csir.co.za # 146.64.24.58
# - ntp.as3741.net # 196.4.160.4
# - ntp1.inx.net.za # 196.10.52.57
- platform: homeassistant
id: time_source
# on_time_sync:
# - lambda: |-
# id(time_synched) = true;
# id(init_holidays).execute(); // we need valid time to calculate holidays
# - logger.log: "Synchronized system clock"#
display:
- platform: ili9xxx
model: ili9341
id: tft_display
color_palette: 8BIT
data_rate: 40MHz
#dc_pin: GPIO02
#reset_pin: GPIO27
#cs_pin: GPIO15
reset_pin: GPIO32
dc_pin: GPIO27
invert_colors: false
show_test_card: true
dimensions:
width: 480
height: 320
# - platform: ssd1306_i2c
# model: "SSD1306 128x64"
## reset_pin: GPIO32
# address: 0x3C
# id: oled_display
# pages:
# - id: page1
# lambda: |-
# auto time_obj = id(time_source).now();
# auto date = time_obj.strftime("%Y-%m-%d");
# auto time = time_obj.strftime("%H:%M:%S");
# it.print(0, 0, id(roboto_16), date.c_str());
# it.print(0, 20, id(roboto_special_36), time.c_str());
# - id: page2
# lambda: |-
# // Print WiFi Signal
# it.printf(0, 26, id(arial_14), "Wi-Fi: %.1fdBm", id(wifi_sig).state);
# // Print time in HH:MM format
# it.strftime(0, 0, id(roboto), TextAlign::TOP_LEFT, "%H:%M", id(time_source).now());
# //// Print Room humidity"(from xiaomi sensor)
# //if (id(room_humidity).has_state()) {
# // it.printf(127,62, id(roboto), TextAlign::BOTTOM_RIGHT, "%.1f%%", id(room_humidity).state);
# //}
# // Print Study temperature(from dallas sensor)
# if (id(study_temperature).has_state()) {
# it.printf(127, 0, id(Carrois_Gothic), TextAlign::TOP_RIGHT, "%.1f°C", id(study_temperature).state);
# }
# - id: page3
# lambda: |-
# // Print 29Gal temperature(from dallas sensor)
# if (id(study_temperature).has_state()) {
# it.printf(64, 10, id(Kdam_Thmor_Pro), TextAlign::CENTER_HORIZONTAL, "%.1f°C", id(study_temperature).state);
# }
# - id: page4
# lambda: |-
# // Print time in HH:MM format
# it.strftime(64, 10, id(Kdam_Thmor_Pro), TextAlign::CENTER_HORIZONTAL, "%H:%M", id(time_source).now());
#interval:
#- interval: 5s
# then:
# - display.page.show_next: oled_display
# - component.update: oled_display
switch:
- platform: restart
name: "${name} Restart"
id: "restart_switch"
sensor:
- platform: dallas_temp
address: 0xfe00000037b3d528
name: "Study Temperature"
id: study_temperature
update_interval: "60s"
resolution: 12
one_wire_id: temperature_sensors
unit_of_measurement: "°C"
#icon: "mdi:water-thermometer"
device_class: "temperature"
state_class: "measurement"
accuracy_decimals: 1
filters:
- filter_out: nan
# - sliding_window_moving_average:
# window_size: 120 # averages over 120 update intervals
# send_every: 60 # reports every 60 update intervals
# Report wifi signal strength every 5 min if changed
- platform: wifi_signal
name: WiFi Signal
id: wifi_sig
update_interval: 300s
filters:
- delta: 10%
# human readable uptime sensor output to the text sensor above
- platform: uptime
name: Uptime in Days
id: uptime_sensor_days
update_interval: 10s
on_raw_value:
then:
- text_sensor.template.publish:
id: uptime_human
state: !lambda |-
int seconds = round(id(uptime_sensor_days).raw_state);
int days = seconds / (24 * 3600);
seconds = seconds % (24 * 3600);
int hours = seconds / 3600;
seconds = seconds % 3600;
int minutes = seconds / 60;
seconds = seconds % 60;
auto days_str = std::to_string(days);
auto hours_str = std::to_string(hours);
auto minutes_str = std::to_string(minutes);
auto seconds_str = std::to_string(seconds);
return (
(days ? days_str + "d " : "") +
(hours ? hours_str + "h " : "") +
(minutes ? minutes_str + "m " : "") +
(seconds_str + "s")
).c_str();
# number of seconds since midnight
- platform: template
id: time_of_day
name: "Time of day"
accuracy_decimals: 0
unit_of_measurement: "s"
lambda: |-
auto currenttime = id(time_source).now();
ESPTime time_obj = currenttime;
time_obj.second = 0;
time_obj.minute = 0;
time_obj.hour = 0;
time_obj.recalc_timestamp_local();
return currenttime.timestamp - time_obj.timestamp;
update_interval: 10s
text_sensor:
- platform: template
id: module_time
name: "Module time"
icon: mdi:clock
lambda: |-
auto time_obj = id(time_source).now();
return time_obj.strftime("%Y-%m-%d %H:%M:%S");
update_interval: 1s
# Expose WiFi information as sensors
- platform: wifi_info
ip_address:
name: IP
mac_address:
name: Mac Address
# human readable update text sensor from sensor:uptime
- platform: template
name: Uptime
id: uptime_human
icon: mdi:clock-start

339
sthome-ut3.yaml Normal file
View File

@ -0,0 +1,339 @@
packages:
- !include common/wifi.yaml
- !include common/canbus.yaml
substitutions:
name: sthome-ut3
friendly_name: "sthome-ut3"
v_ON: "{ 0x4F,0x4E }"
v_OFF: "{ 0x4F, 0x46, 0x46 }"
esphome:
name: "${name}"
friendly_name: "${friendly_name}"
globals:
- id: geyser_relay_status
type: bool
restore_value: yes
initial_value: 'false'
esp32:
board: nodemcu-32s #esp32dev
framework:
type: arduino
# Example configuration entry
#debug:
# update_interval: 5s
# Enable logging
logger:
level: verbose
# Enable Home Assistant API
api:
encryption:
key: "AIoquKPjpcHa2pcJ0aKxvtpM3mwgZuZhpCPtdVitP2Q="
ota:
- platform: esphome
password: "879012af7180c8700cee65fbf18704d1"
wifi:
manual_ip:
static_ip: 10.0.2.3
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "${name} Fallback Hotspot"
password: "cGXb2DqkwaOr"
captive_portal:
sun:
id: sun_sensor
latitude: !secret latitude
longitude: !secret longitude
time:
- platform: homeassistant
id: time_source
update_interval: 360min # Change sync interval from default 5min to 6 hours
on_time_sync:
then:
- if: # Publish the time the device was last restarted, but only once.
condition:
lambda: 'return id(device_last_restart).state == "";'
then:
- text_sensor.template.publish:
id: device_last_restart
state: !lambda 'return id(time_source).now().strftime("%a %d %b %Y - %I:%M:%S %p");'
interval:
- interval: 30s
then:
- if:
condition:
lambda: 'return !isnan(id(geyser_top_temperature).raw_state);'
then:
- canbus.send:
canbus_id: canbus_sthome
can_id: ${CB_GEYSER_TOP_TEMPERATURE}
data: !lambda |-
double temp = id(geyser_top_temperature).raw_state;
int value = (int) (temp * 16777216);
std::vector<uint8_t> byte_stream(sizeof(value));
memcpy(byte_stream.data(), &value, sizeof(value));
ESP_LOGI("SND:${CB_GEYSER_TOP_TEMPERATURE}", "Geyser TOP temp: %d (%f)", value, temp);
//ESP_LOGI("SND:0x400", "Geyser TOP temp: %f, x3: %d, x2: %d, x1: %d, x0: %d, xSize: %d", temp, byte_stream[3],byte_stream[2], byte_stream[1], byte_stream[0], byte_stream.size());
return byte_stream;
- delay: 1s
- if:
condition:
lambda: 'return !isnan(id(geyser_bottom_temperature).raw_state);'
then:
- canbus.send:
canbus_id: canbus_sthome
can_id: ${CB_GEYSER_BOTTOM_TEMPERATURE}
data: !lambda |-
double temp = id(geyser_bottom_temperature).raw_state;
int value = (int) (temp * 16777216);
std::vector<uint8_t> byte_stream(sizeof(value));
memcpy(byte_stream.data(), &value, sizeof(value));
ESP_LOGI("SND:${CB_GEYSER_BOTTOM_TEMPERATURE}", "Geyser BOTTOM temp: %d (%f)", value, temp);
//ESP_LOGI("SND:0x401", "Geyser BOTTOM temp: %f", temp, byte_stream[3],byte_stream[2], byte_stream[1], byte_stream[0], byte_stream.size());
return byte_stream;
- delay: 1s
- canbus.send:
canbus_id: canbus_sthome
can_id: ${CB_GEYSER_ENERGISED}
data: !lambda |-
if (id(geyser_heating).state) {
std::vector<uint8_t> byte_stream = ${v_ON};
ESP_LOGI("SND:${CB_GEYSER_ENERGISED}", "Geyser state: %c%c", byte_stream[0], byte_stream[1]);
return byte_stream;
}
else {
std::vector<uint8_t> byte_stream = ${v_OFF};
ESP_LOGI("SND:${CB_GEYSER_ENERGISED}", "Geyser state: %c%c%c", byte_stream[0], byte_stream[1], byte_stream[2]);
return byte_stream;
}
- interval: 10s
then:
- canbus.send:
canbus_id: canbus_sthome
data: [0x48, 0x45, 0x4C, 0x4C, 0x4F]
- lambda: |-
ESP_LOGI("SND:${CB_CANBUS_ID3}", "HELLO");
spi:
- id: spi_bus0
clk_pin: GPIO18
mosi_pin: GPIO23
miso_pin: GPIO19
interface: any
# CAN BUS
canbus:
- platform: mcp2515
cs_pin: GPIO16
spi_id: spi_bus0
mode: NORMAL
id: canbus_sthome
can_id: ${CB_CANBUS_ID3}
bit_rate: 500KBPS #20KBPS
on_frame:
# - can_id: 0
# can_id_mask: 0
# then:
# - logger.log:
# format: "ID: 0x%03X -> %s"
# args: [ id, x ]
# tag: "canbus"
- can_id: 0
can_id_mask: 0
then:
- lambda: |-
std::string b(x.begin(), x.end());
ESP_LOGI("REC: 0", "%s", &b[0] );
//ESP_LOGI("canbus", "REC: ID: %d, data: %s, rtr: %s",
// x.can_id,
// x.data.c_str(),
// x.remote_transmission_request ? "true" : "false");
# - can_id: ${CB_CANBUS_ID1}
# then:
# - lambda: |-
# std::string b(x.begin(), x.end());
# ESP_LOGI("REC:${CB_CANBUS_ID1}", "%s", &b[0] );
# - can_id: ${CB_CANBUS_ID2}
# then:
# - lambda: |-
# std::string b(x.begin(), x.end());
# ESP_LOGI("REC:${CB_CANBUS_ID2}", "%s", &b[0] );
# - can_id: ${CB_CANBUS_ID3}
# then:
# - lambda: |-
# std::string b(x.begin(), x.end());
# ESP_LOGI("REC:${CB_CANBUS_ID3}", "%s", &b[0] );
# - can_id: ${CB_CANBUS_ID4}
# then:
# - lambda: |-
# std::string b(x.begin(), x.end());
# ESP_LOGI("REC:${CB_CANBUS_ID4}", "%s", &b[0] );
# - can_id: ${CB_CANBUS_ID5}
# then:
# - lambda: |-
# std::string b(x.begin(), x.end());
# ESP_LOGI("REC:${CB_CANBUS_ID5}", "%s", &b[0] );
# - can_id: ${CB_CANBUS_ID6}
# then:
# - lambda: |-
# std::string b(x.begin(), x.end());
# ESP_LOGI("REC:${CB_CANBUS_ID6}", "%s", &b[0] );
# - can_id: ${CB_CANBUS_ID7}
# then:
# - lambda: |-
# std::string b(x.begin(), x.end());
# ESP_LOGI("REC:${CB_CANBUS_ID7}", "%s", &b[0] );
# - can_id: ${CB_CANBUS_ID8}
# then:
# - lambda: |-
# std::string b(x.begin(), x.end());
# ESP_LOGI("REC:${CB_CANBUS_ID8}", "%s", &b[0] );
# - can_id: ${CB_CANBUS_ID9}
# then:
# - lambda: |-
# std::string b(x.begin(), x.end());
# ESP_LOGI("REC:${CB_CANBUS_ID9}", "%s", &b[0] );
# - can_id: ${CB_CANBUS_ID10}
# then:
# - lambda: |-
# std::string b(x.begin(), x.end());
# ESP_LOGI("REC:${CB_CANBUS_ID10}", "%s", &b[0] );
# Define a PWM output on the ESP32
output:
- platform: ledc
pin: GPIO26
id: backlight_pwm
# Define a monochromatic, dimmable light for the backlight
light:
- platform: monochromatic
output: backlight_pwm
name: "Display Backlight"
id: back_light
restore_mode: ALWAYS_ON
switch:
- platform: restart
name: "${name} Restart"
id: "restart_switch"
binary_sensor:
- platform: homeassistant
name: "Geyser Heating"
entity_id: binary_sensor.sthome_ut8_heating
id: geyser_heating
on_press:
then:
- canbus.send:
canbus_id: canbus_sthome
can_id: ${CB_GEYSER_ENERGISED}
data: !lambda |-
std::vector<uint8_t> byte_stream = ${v_ON};
ESP_LOGI("SND:${CB_GEYSER_ENERGISED}", "Geyser state: %c%c", byte_stream[0], byte_stream[1]);
return byte_stream;
on_release:
then:
- canbus.send:
canbus_id: canbus_sthome
can_id: ${CB_GEYSER_ENERGISED}
data: !lambda |-
std::vector<uint8_t> byte_stream = ${v_OFF};
ESP_LOGI("SND:${CB_GEYSER_ENERGISED}", "Geyser state: %c%c%c", byte_stream[0], byte_stream[1], byte_stream[2]);
return byte_stream;
sensor:
- platform: homeassistant
name: "Geyser Top Temperature"
entity_id: sensor.sthome_ut8_geyser_top_temperature
id: geyser_top_temperature
on_raw_value:
then:
- canbus.send:
canbus_id: canbus_sthome
can_id: ${CB_GEYSER_TOP_TEMPERATURE}
data: !lambda |-
double temp = id(geyser_top_temperature).raw_state;
int value = (int) (temp * 16777216);
std::vector<uint8_t> byte_stream(sizeof(value));
memcpy(byte_stream.data(), &value, sizeof(value));
ESP_LOGI("SND:${CB_GEYSER_TOP_TEMPERATURE}", "Geyser TOP temp: %d (%f)", value, temp);
//ESP_LOGI("SND:0x400", "Geyser TOP temp: %f, x3: %d, x2: %d, x1: %d, x0: %d, xSize: %d", temp, byte_stream[3],byte_stream[2], byte_stream[1], byte_stream[0], byte_stream.size());
return byte_stream;
- platform: homeassistant
name: "Geyser Bottom Temperature"
entity_id: sensor.sthome_ut8_geyser_bottom_temperature
id: geyser_bottom_temperature
on_raw_value:
then:
- canbus.send:
canbus_id: canbus_sthome
can_id: ${CB_GEYSER_BOTTOM_TEMPERATURE}
data: !lambda |-
double temp = id(geyser_bottom_temperature).raw_state;
int value = (int) (temp * 16777216);
std::vector<uint8_t> byte_stream(sizeof(value));
memcpy(byte_stream.data(), &value, sizeof(value));
ESP_LOGI("SND:${CB_GEYSER_BOTTOM_TEMPERATURE}", "Geyser BOTTOM temp: %d (%f)", value, temp);
//ESP_LOGI("SND:0x401", "Geyser BOTTOM temp: %f", temp, byte_stream[3],byte_stream[2], byte_stream[1], byte_stream[0], byte_stream.size());
return byte_stream;
# Report wifi signal strength every 5 min if changed
- platform: wifi_signal
name: WiFi Signal
id: wifi_sig
update_interval: 300s
filters:
- delta: 10%
text_sensor:
# - platform: template
# id: module_time
# name: "Module time"
# icon: mdi:clock
# lambda: |-
# auto time_obj = id(time_source).now();
# return time_obj.strftime("%Y-%m-%d %H:%M:%S");
# update_interval: 60s
# Expose WiFi information as sensors
- platform: wifi_info
ip_address:
name: IP
update_interval: 10s
mac_address:
name: Mac Address
entity_category: diagnostic
ssid:
name: "Connected SSID"
id: ssid
entity_category: diagnostic
# human readable update text sensor from sensor:uptime
- platform: template
name: Uptime
id: uptime_human
icon: mdi:clock-start
- platform: template
name: 'Last Restart'
id: device_last_restart
icon: mdi:clock
entity_category: diagnostic

90
sthome-ut4.yaml Normal file
View File

@ -0,0 +1,90 @@
substitutions:
name: sthome-ut4
friendly_name: "sthome-ut4"
esphome:
name: "${name}"
friendly_name: "${friendly_name}"
esp32:
board: esp32-c3-devkitm-1
variant: ESP32C3
framework:
type: esp-idf
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "qmfAFWSynz6VhvR5oBrtx2wnNP8n1yZKslVGNDMTWMc="
ota:
- platform: esphome
password: "2144396ae4f6a829dc7fe7de88c5887b"
wifi:
#ssid: !secret wifi_ssid
#password: !secret wifi_password
output_power: 8.5dB
# we will use local dns server for local dns resolution
domain: ".sthome.org"
networks:
- ssid: !secret wifi_ssid1
password: !secret wifi_password1
- ssid: !secret wifi_ssid2
password: !secret wifi_password2
- ssid: !secret wifi_ssid3
password: !secret wifi_password3
- ssid: !secret wifi_ssid4
password: !secret wifi_password4
- ssid: !secret wifi_ssid5
password: !secret wifi_password5
manual_ip:
# For faster connection startup, set a static IP address
# Set this to the IP of the ESP
static_ip: 10.0.2.4
gateway: 10.0.0.2
subnet: 255.255.240.0
dns1: 10.0.0.1
dns2: 10.0.0.2
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "${name} Fallback Hotspot"
password: "FtGGLAU7OFPx"
captive_portal:
sun:
id: sun_sensor
latitude: !secret latitude
longitude: !secret longitude
time:
platform: sntp
switch:
- platform: gpio
pin:
number: GPIO10
inverted: true
id: relay5
name: "Relay 5"
icon: "mdi:lock-outline"
restore_mode: RESTORE_DEFAULT_OFF
#on_turn_on:
# - delay: 1000ms
# - switch.turn_off: relay5
- platform: gpio
pin:
number: GPIO0
inverted: true
id: relay6
name: "Relay 6"
icon: "mdi:gate"
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
- delay: 500ms
- switch.turn_off: relay6

235
sthome-ut6.yaml Normal file
View File

@ -0,0 +1,235 @@
substitutions:
name: sthome-ut6
friendly_name: "sthome-ut6"
esphome:
name: "${name}"
friendly_name: "${friendly_name}"
on_boot:
- priority: 600
then:
- lambda: |-
id(restore_remote_lock).execute();
globals:
- id: remote_lock_status
type: bool
restore_value: yes
initial_value: 'false'
esp8266:
board: esp01_1m
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "K3yXQthpXVNknD4RCLZX66gglNgDEFtj3H0r85VLBNs="
ota:
- platform: esphome
password: "5956a60f6cf40cf4b6b172e23f236572"
wifi:
#ssid: !secret wifi_ssid
#password: !secret wifi_password
# we will use local dns server for local dns resolution
domain: ".sthome.org"
networks:
- ssid: !secret wifi_ssid1
password: !secret wifi_password1
- ssid: !secret wifi_ssid2
password: !secret wifi_password2
- ssid: !secret wifi_ssid3
password: !secret wifi_password3
- ssid: !secret wifi_ssid4
password: !secret wifi_password4
- ssid: !secret wifi_ssid5
password: !secret wifi_password5
manual_ip:
# For faster connection startup, set a static IP address
# Set this to the IP of the ESP
static_ip: 10.0.2.6
gateway: 10.0.0.2
subnet: 255.255.240.0
dns1: 10.0.0.1
dns2: 10.0.0.2
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "${name} Fallback Hotspot"
password: "HIjEc5P2BJhz"
captive_portal:
#####################################################################################
# Minimal flash writes, once per hour
preferences:
flash_write_interval: 60min
sun:
id: sun_sensor
latitude: !secret latitude
longitude: !secret longitude
# Sync time with Home Assistant
time:
- platform: homeassistant
id: homeassistant_time
# Blink LED for status, and also expose to HA as switch
#light:
# - platform: status_led
# name: "${friendly_name} status light"
# id: blueled
# pin:
# number: GPIO2
# inverted: yes
# restore_mode: RESTORE_DEFAULT_OFF
#
#script:
# - id: heartbeat
# mode: single
# then:
# - light.toggle: blueled
# - delay: 20 ms
# - light.toggle: blueled
#
# Heartbeat while connected to HA
#interval:
# - interval: 5s
# then:
# if:
# condition:
# api.connected:
# then:
# - script.execute: heartbeat
#
switch:
# Switch to restart the ESP
- platform: restart
name: ${friendly_name} Restart
# depending on current state of gate, it will open, close or stop closing / opening
- platform: gpio
pin: GPIO0
name: "Gate Remote Trigger"
inverted: false
id: gate_remote_trigger
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
- delay: 1000ms
- switch.turn_off: gate_remote_trigger
# this is a latching relay, so each pulse toggles the state of the relay
- platform: gpio
pin: GPIO1
name: "Gate Remote Lock Toggle"
inverted: false
id: gate_remote_lock_toggle
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
# - lambda: |-
# ESP_LOGD("info", "1: Remote lock status: %d [%d]", id(remote_lock_status), id(gate_remote_lock_sensor).state);
- delay: 200ms
- switch.turn_off: gate_remote_lock_toggle
- delay: 100ms
- lambda: |-
id(remote_lock_status) = id(gate_remote_lock_sensor).state;
// ESP_LOGD("info", "2: Remote lock status: %d [%d]", id(remote_lock_status), id(gate_remote_lock_sensor).state);
binary_sensor:
- platform: status
# Status platform provides a connectivity sensor
name: "${friendly_name} Status"
device_class: connectivity
- platform: gpio
pin:
number: GPIO3
inverted: false
id: gate_remote_lock_sensor
name: Gate Remote Lock Sensor
device_class: lock
sensor:
# Report wifi signal strength every 5 min if changed
- platform: wifi_signal
name: ${friendly_name} WiFi Signal
update_interval: 300s
filters:
- delta: 10%
# human readable uptime sensor output to the text sensor above
- platform: uptime
name: ${friendly_name} Uptime in Days
id: uptime_sensor_days
update_interval: 60s
on_raw_value:
then:
- text_sensor.template.publish:
id: uptime_human
state: !lambda |-
int seconds = round(id(uptime_sensor_days).raw_state);
int days = seconds / (24 * 3600);
seconds = seconds % (24 * 3600);
int hours = seconds / 3600;
seconds = seconds % 3600;
int minutes = seconds / 60;
seconds = seconds % 60;
return (
(days ? String(days) + "d " : "") +
(hours ? String(hours) + "h " : "") +
(minutes ? String(minutes) + "m " : "") +
(String(seconds) + "s")
).c_str();
text_sensor:
# Expose WiFi information as sensors
- platform: wifi_info
ip_address:
name: ${friendly_name} IP
mac_address:
name: ${friendly_name} Mac Address
# human readable update text sensor from sensor:uptime
- platform: template
name: Uptime
id: uptime_human
icon: mdi:clock-start
script:
- id: restore_remote_lock
then:
- lambda: |-
bool restore_value = id(remote_lock_status);
id(set_remote_lock).execute(restore_value);
- delay: 250ms
# make double sure after delay
- lambda: |-
bool restore_value = id(remote_lock_status);
id(set_remote_lock).execute(restore_value);
- id: set_remote_lock
parameters:
on_state: bool
then:
- lambda: |-
bool lockstate = id(gate_remote_lock_sensor).state;
// next statement is XOR; causes a skip if states are the same
if((on_state && !lockstate) || (!on_state && lockstate)) {
// toggle
id(gate_remote_lock_toggle).turn_on();
}
# Pin assignments for ESP-01
# https://randomnerdtutorials.com/esp8266-pinout-reference-gpios/
# 3v3 | | RX/GPIO3 - high at boot
# RST | | GPIO0 - pulled up, flash if low on boot
# EN | | GPIO2 - pulled up, blue led on if pulled down, must be high at boot
# TX | | GND
# ^ TX/GPIO1 - high at boot

177
sthome-ut7.yaml Normal file
View File

@ -0,0 +1,177 @@
substitutions:
name: sthome-ut7
friendly_name: "sthome-ut7"
esphome:
name: "${name}"
friendly_name: "${friendly_name}"
#esphome:
# name: sthome-ut7
# friendly_name: sthome-ut7
esp8266:
board: esp01_1m
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "0H1KvuIcSV11klUG1MB8wyalPSNhlk40jkfEzBK95WU="
ota:
- platform: esphome
password: "be731abfa319b072b199a257af6e9527"
wifi:
#ssid: !secret wifi_ssid
#password: !secret wifi_password
# we will use local dns server for local dns resolution
domain: ".sthome.org"
networks:
- ssid: !secret wifi_ssid1
password: !secret wifi_password1
- ssid: !secret wifi_ssid2
password: !secret wifi_password2
- ssid: !secret wifi_ssid3
password: !secret wifi_password3
- ssid: !secret wifi_ssid4
password: !secret wifi_password4
- ssid: !secret wifi_ssid5
password: !secret wifi_password5
manual_ip:
# For faster connection startup, set a static IP address
# Set this to the IP of the ESP
static_ip: 10.0.2.7
gateway: 10.0.0.2
subnet: 255.255.240.0
dns1: 10.0.0.1
dns2: 10.0.0.2
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "${friendly_name} Fallback Hotspot"
password: "0JNEPN1Q7GZ4"
captive_portal:
#####################################################################################
# Minimal flash writes, once per hour
preferences:
flash_write_interval: 60min
sun:
id: sun_sensor
latitude: !secret latitude
longitude: !secret longitude
# Sync time with Home Assistant
time:
- platform: homeassistant
id: homeassistant_time
switch:
# Switch to restart the ESP
- platform: restart
name: ${friendly_name} Restart
- platform: gpio
pin: GPIO0
name: "Relay1"
inverted: false
id: relay1
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
- delay: 2500ms
- switch.turn_off: relay1
- platform: gpio
pin: GPIO1
name: "Relay2"
inverted: true
id: relay2
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
- delay: 1000ms
- switch.turn_off: relay2
- platform: gpio
pin: GPIO2
name: "Relay3"
inverted: true
id: relay3
restore_mode: RESTORE_DEFAULT_OFF
on_turn_on:
- delay: 1000ms
- switch.turn_off: relay3
binary_sensor:
- platform: status
# Status platform provides a connectivity sensor
name: "${friendly_name} - Status"
device_class: connectivity
- platform: gpio
pin:
number: GPIO3
inverted: false
id: gpio3_sensor
name: GPIO3 Sensor
device_class: problem
sensor:
# Report wifi signal strength every 5 min if changed
- platform: wifi_signal
name: ${friendly_name} WiFi Signal
update_interval: 300s
filters:
- delta: 10%
# human readable uptime sensor output to the text sensor above
- platform: uptime
name: ${friendly_name} Uptime in Days
id: uptime_sensor_days
update_interval: 60s
on_raw_value:
then:
- text_sensor.template.publish:
id: uptime_human
state: !lambda |-
int seconds = round(id(uptime_sensor_days).raw_state);
int days = seconds / (24 * 3600);
seconds = seconds % (24 * 3600);
int hours = seconds / 3600;
seconds = seconds % 3600;
int minutes = seconds / 60;
seconds = seconds % 60;
return (
(days ? String(days) + "d " : "") +
(hours ? String(hours) + "h " : "") +
(minutes ? String(minutes) + "m " : "") +
(String(seconds) + "s")
).c_str();
text_sensor:
# Expose WiFi information as sensors
- platform: wifi_info
ip_address:
name: ${friendly_name} IP
mac_address:
name: ${friendly_name} Mac Address
# human readable update text sensor from sensor:uptime
- platform: template
name: Uptime
id: uptime_human
icon: mdi:clock-start
# Pin assignments for ESP-01
# https://randomnerdtutorials.com/esp8266-pinout-reference-gpios/
# 3v3 | | RX/GPIO3 - high at boot
# RST | | GPIO0 - pulled up, flash if low on boot
# EN | | GPIO2 - pulled up, blue led on if pulled down, must be high at boot
# TX | | GND
# ^ TX/GPIO1 - high at boot

2795
sthome-ut8.yaml Normal file

File diff suppressed because it is too large Load Diff

1809
sthome-ut9.yaml Normal file

File diff suppressed because it is too large Load Diff