configs/sthome-ut3.yaml
2025-09-03 22:37:03 +02:00

294 lines
9.5 KiB
YAML

packages:
- !include common/wifi.yaml
- !include common/canbus.yaml
substitutions:
name: sthome-ut3
friendly_name: "sthome-ut3"
esphome:
name: "${name}"
friendly_name: "${friendly_name}"
includes:
- source # copies folder with files to relevant to be included in esphome compile
- <source/solar/cb_frame.h> # angle brackets ensure file is included above globals in main.cpp. Make sure to use include GUARDS in the file to prevent double inclusion
- <source/solar/cbf_store.h>
- <source/solar/cbf_pylon.h>
- <source/solar/cbf_store_pylon.h>
- <source/solar/cbf_sthome.h>
- <source/solar/cbf_store_sthome.h>
- <source/solar/cbf_cache.h>
on_boot:
- priority: 600 # This is where most sensors are set up (higher number means higher priority)
then:
- lambda: |-
id(can_msgctr) = 0;
globals:
- id: geyser_relay_status
type: bool
restore_value: yes
initial_value: 'false'
# CANBUS
- id: can_msgctr
type: int
restore_value: no
- id: g_cb_cache
type: solar::cbf_cache
restore_value: no
esp32:
board: nodemcu-32s #esp32dev
framework:
type: arduino
# Example configuration entry
#debug:
# update_interval: 5s
# Enable logging
logger:
level: VERY_VERBOSE
initial_level: INFO
logs:
canbus: INFO
# 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:
- lambda: |-
using namespace solar;
std::vector<uint8_t> data(cbf_sthome::heartbeat.begin(), cbf_sthome::heartbeat.end());
for (int i = 0; i < 5; i++) {
id(canbus_sthome)->send_data(cbf_sthome::CB_CANBUS_ID03, false, data);
}
ESP_LOGI("SND:${CB_CANBUS_ID03}", "%s", cbf_sthome::heartbeat.c_str());
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_ID03}
bit_rate: 500KBPS #20KBPS
on_frame:
- can_id: 0
can_id_mask: 0
then:
- lambda: |-
id(can_msgctr)++;
using namespace solar;
auto time_obj = id(time_source).now();
if(time_obj.is_valid()) {
auto cbitem = cbf_store_sthome(id(can_msgctr), can_id, x, remote_transmission_request, time_obj.timestamp);
bool publish = id(g_cb_cache).additem(cbitem);
if(publish) {
ESP_LOGI(cbitem.tag().c_str(), "%s", cbitem.to_string().c_str());
}
}
# 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"
#sensor:
# - platform: homeassistant
# name: "Geyser Top Temperature"
# entity_id: sensor.sthome_ut8_geyser_top_temperature
# id: geyser_top_temperature
# on_raw_value:
# then:
# - script.execute: canbus_send_temperatures
## - 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:
# - script.execute: canbus_send_temperatures
## - 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;
#
# - platform: homeassistant
# name: "Ambient Temperature"
# entity_id: sensor.sthome_ut8_ambient_temperature
# id: ambient_temperature
# on_raw_value:
# then:
# - script.execute: canbus_send_temperatures
#
# # 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
#script:
# - id: canbus_send_data
# then:
# - script.execute: canbus_send_temperatures
# - 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;
# }
#
# - id: canbus_send_temperatures
# then:
# - if:
# condition:
# lambda: 'return !isnan(id(geyser_top_temperature).raw_state) || !isnan(id(geyser_bottom_temperature).raw_state) || !isnan(id(ambient_temperature).raw_state);'
# then:
# - canbus.send:
# canbus_id: canbus_sthome
# can_id: ${CB_GEYSER_TEMPERATURES}
# data: !lambda |-
# double temp_top = isnan(id(geyser_top_temperature).raw_state) ? 0 : id(geyser_top_temperature).raw_state;
# double temp_bot = isnan(id(geyser_bottom_temperature).raw_state) ? 0 : id(geyser_bottom_temperature).raw_state;
# double temp_amb = isnan(id(ambient_temperature).raw_state) ? 0 : id(ambient_temperature).raw_state;
# int temp_top_int = (int)(temp_top * 256);
# int temp_bot_int = (int)(temp_bot * 256);
# int temp_amb_int = (int)(temp_amb * 256);
# std::vector<uint8_t> byte_stream(8, 0);
# byte_stream[0] = temp_top_int % 256;
# byte_stream[1] = (temp_top_int >> 8) % 256;
# byte_stream[2] = temp_bot_int % 256;
# byte_stream[3] = (temp_bot_int >> 8) % 256;
# byte_stream[4] = temp_amb_int % 256;
# byte_stream[5] = (temp_amb_int >> 8) % 256;
# ESP_LOGI("SND:${CB_GEYSER_TEMPERATURES}", "Geyser temps: %04X %04X %04X (%f, %f, %f)", byte_stream[0] + 256 * byte_stream[1], byte_stream[2] + 256 * byte_stream[3], byte_stream[4] + 256 * byte_stream[5], temp_top, temp_bot, temp_amb);
# return byte_stream;