Updates to canbus

This commit is contained in:
Chris Stuurman 2025-09-03 22:37:03 +02:00
parent da5effe922
commit d28a51602a
6 changed files with 856 additions and 492 deletions

View File

@ -1,29 +1,15 @@
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
# heartbeat messages
CB_CANBUS_ID01: 0x501
CB_CANBUS_ID02: 0x502
CB_CANBUS_ID03: 0x503
CB_CANBUS_ID04: 0x504
CB_CANBUS_ID05: 0x505
CB_CANBUS_ID06: 0x506
CB_CANBUS_ID07: 0x507
CB_CANBUS_ID08: 0x508
CB_CANBUS_ID09: 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
@ -32,3 +18,25 @@ substitutions:
CB_BATTERY_FAULT: 0x359
CB_BATTERY_REQUEST_FLAG: 0x35C
CB_BATTERY_MANUFACTURER: 0x35E
# sthome messages
# can also use CB_GEYSER_TEMPERATURES: !lambda "return esphome::solar::cbf_sthome::CB_GEYSER_TEMPERATURES;", but will fail is assigned to non-templateable config option in .yaml config file
CB_GEYSER_TEMPERATURES: 0x400
CB_GEYSER_HEATING: 0x401
CB_GEYSER_ACTIVE_SCHEDULE: 0x402
CB_POWER_MAINS: 0x403
CB_POWER_INVERTER: 0x404
CB_POWER_PLUGS: 0x405
CB_POWER_LIGHTS: 0x406
CB_POWER_GEYSER: 0x407
CB_POWER_POOL: 0x408
CB_POWER_GENERATED: 0x409
CB_ENERGY_MAINS: 0x40A
CB_ENERGY_GEYSER: 0x40B
CB_ENERGY_POOL: 0x40C
CB_ENERGY_PLUGS: 0x40D
CB_ENERGY_LIGHTS: 0x40E
CB_ENERGY_HOUSE: 0x40F
CB_ENERGY_GENERATED: 0x410
CB_ENERGY_LOSS: 0x411
CB_CONTROLLER_STATES: 0x412

View File

@ -3,6 +3,11 @@ substitutions:
HEATING_WARM: 45
HEATING_LUKE_WARM: 35
HEATING_HOT: 70
HEATING_DAY_TYPES: 4
HEATING_DAY_BLOCKS: 6
HEATING_TEMP_SCALE: 1000.0
HEATING_DAY_BLOCKS: 6
GEYSER_MODES: 5
GM_SUNDAY: 0
GM_WORKDAY: 1
GM_SATURDAY: 2
GM_PUBLIC_HOLIDAY: 3
GM_SCHOOL_HOLIDAY: 4

View File

@ -3,14 +3,14 @@ wifi:
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
# - 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

View File

@ -31,18 +31,31 @@ globals:
type: bool
restore_value: no
initial_value: '0'
- id: g_geyser_top_temperature
type: double
restore_value: yes
initial_value: '0'
- id: g_geyser_bottom_temperature
type: double
restore_value: yes
initial_value: '0'
# CAN BUS
- id: can_msgctr
type: int
restore_value: no
- id: g_cb_cache
type: solar::cbf_cache
restore_value: no
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;
esp32:
board: esp32-s3-devkitc-1
@ -58,7 +71,10 @@ psram:
# Enable logging
logger:
# level: verbose
level: very_verbose
initial_level: INFO
logs:
canbus: INFO
# Enable Home Assistant API
api:
@ -127,7 +143,9 @@ font:
glyphs: [
0123456789,.,°,a,n,
"\u0020", # space
"\u002D", # minus
"\u003A", # colon
"\u003F", # question mark
]
- file: "gfonts://Roboto"
id: roboto_192
@ -136,7 +154,9 @@ font:
glyphs: [
0123456789,.,°,a,n,
"\u0020", # space
"\u002D", # minus
"\u003A", # colon
"\u003F", # question mark
]
- file: "gfonts://Roboto"
id: geyser_temperature_font2
@ -184,13 +204,9 @@ sun:
longitude: !secret longitude
interval:
- interval: 10s
- interval: 30s
then:
- canbus.send:
canbus_id: canbus_sthome
data: [0x48, 0x45, 0x4C, 0x4C, 0x4F]
- lambda: |-
ESP_LOGI("SND:${CB_CANBUS_ID10}", "HELLO");
- script.execute: send_info_request
spi:
- id: spi_bus0
@ -217,111 +233,48 @@ canbus:
spi_id: spi_bus0
id: canbus_sthome
can_id: ${CB_CANBUS_ID10}
#mode: NORMAL #LISTENONLY
bit_rate: 500KBPS #20KBPS
bit_rate: 500KBPS
on_frame:
- can_id: 0
can_id_mask: 0
then:
- lambda: |-
std::string b(x.begin(), x.end());
ESP_LOGI("REC: 0", "%s", &b[0] );
- can_id: ${CB_GEYSER_ENERGISED}
then:
- lvgl.widget.update:
id: ind_geyser_on
hidden: !lambda |-
std::string on_state(x.begin(), x.end());
//ESP_LOGI("REC:${CB_GEYSER_ENERGISED}", "GEYSER IS: %s", on_state.c_str());
if(on_state == "ON") {
id(g_geyser_heating_on) = true;
return false; // not hidden
id(can_msgctr)++;
using namespace solar;
auto time_obj = id(time_source).now();
if(time_obj.is_valid()) {
if(can_id >= 0x350 && can_id < 0x380) {
auto cbitem = cbf_store_pylon(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());
}
else if(on_state == "OFF") {
id(g_geyser_heating_on) = false;
return true; // hidden
}
else if(can_id >= 0x400 && can_id <= 0x580) {
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());
switch (can_id) {
case cbf_sthome::CB_CONTROLLER_STATES:
if(x[1] & 0x80 == 0)
lv_obj_add_flag(id(ind_geyser_on), LV_OBJ_FLAG_HIDDEN);
else
lv_obj_clear_flag(id(ind_geyser_on), LV_OBJ_FLAG_HIDDEN);
if(x[1] & 0x10 == 0)
lv_obj_add_flag(id(ind_utility_on), LV_OBJ_FLAG_HIDDEN);
else
lv_obj_clear_flag(id(ind_utility_on), LV_OBJ_FLAG_HIDDEN);
break;
case cbf_sthome::CB_GEYSER_TEMPERATURES:
id(update_temperature_display).execute(x);
}
}
//ESP_LOGW("REC:${CB_GEYSER_ENERGISED}", "Invalid ON/OFF value: %s", on_state.c_str());
return true; // default
- can_id: ${CB_UTILITY_POWER_ON}
then:
- lvgl.widget.update:
id: ind_utility_on
hidden: !lambda |-
std::string on_state(x.begin(), x.end());
ESP_LOGI("REC:${CB_UTILITY_POWER_ON}", "UTILITY IS: %s", on_state.c_str());
if(on_state == "ON") {
id(g_utility_on) = true;
return false; // not hidden
}
else if(on_state == "OFF") {
id(g_utility_on) = false;
return true; // hidden
}
ESP_LOGW("REC:${CB_UTILITY_POWER_ON}", "Invalid ON/OFF value: %s", on_state.c_str());
return true; // default
- can_id: ${CB_GEYSER_TOP_TEMPERATURE}
then:
- lambda: |-
id(update_temperature_display).execute(x, id(g_geyser_top_temperature), rect_gtoptemp, ind_utility_on, lbl_gtoptemp);
- can_id: ${CB_GEYSER_BOTTOM_TEMPERATURE}
then:
- lambda: |-
id(update_temperature_display).execute(x, id(g_geyser_bottom_temperature) , rect_gbottemp, ind_geyser_on, lbl_gbottemp);
# - 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] );
}
else {
ESP_LOGI("WARN", "CAN ID within unhandled range: 0x%X", can_id);
}
}
display:
- platform: ili9xxx
@ -336,7 +289,7 @@ display:
auto_clear_enabled: false
update_interval: never
invert_colors: false
show_test_card: true
# show_test_card: true
transform:
swap_xy: true # landscape
# mirror_x: true # landscape
@ -1226,10 +1179,48 @@ sensor:
#
script:
- id: send_info_request
then:
- script.execute: send_request_block
- delay: 100ms
- script.execute: send_request_block
- delay: 100ms
- script.execute: send_request_block
- delay: 100ms
- script.execute: send_request_block
- delay: 100ms
- script.execute: send_request_block
- id: send_request_block
then:
- lambda: |-
using namespace solar;
id(g_cb_cache).send_request(id(canbus_sthome), cbf_sthome::CB_GEYSER_TEMPERATURES);
id(g_cb_cache).send_request(id(canbus_sthome), cbf_sthome::CB_CONTROLLER_STATES);
- id: update_temperature_display
parameters:
x: std::vector<uint8_t>&
globalvar: double&
then:
- lambda: |-
using namespace solar;
double temp_top = (x[1] == 0xFF && x[0] == 0xFF) ? std::numeric_limits<double>::quiet_NaN() : (double) static_cast<int16_t>(256 * x[1] + x[0]) / 256;
double temp_bot = (x[3] == 0xFF && x[2] == 0xFF) ? std::numeric_limits<double>::quiet_NaN() : (double) static_cast<int16_t>(256 * x[3] + x[2]) / 256;
double temp_amb = (x[5] == 0xFF && x[4] == 0xFF) ? std::numeric_limits<double>::quiet_NaN() : (double) static_cast<int16_t>(256 * x[5] + x[4]) / 256;
if(isnan(temp_top) || isnan(temp_bot)) {
// immediately request another can frame
id(g_cb_cache).send_request(id(canbus_sthome), cbf_sthome::CB_GEYSER_TEMPERATURES);
}
//ESP_LOGI("REC: ", "Geyser Temperatures: Top %.4f°C Bottom %.4f°C Ambient %.4f°C", temp_top, temp_bot, temp_amb);
if(!isnan(temp_top))
id(update_temp_display).execute(temp_top, rect_gtoptemp, ind_utility_on, lbl_gtoptemp);
if(!isnan(temp_bot))
id(update_temp_display).execute(temp_bot, rect_gbottemp, ind_geyser_on, lbl_gbottemp);
- id: update_temp_display
parameters:
value: double
rect: lv_obj_t*
indicator: lv_obj_t*
label: lv_obj_t*
@ -1237,8 +1228,6 @@ script:
- lambda: |-
char buffer [4];
buffer[0] = '\0';
double value = x[3] + ((double)((x[2] << 16) + (x[1] << 8) + x[0]))/16777216;
globalvar = value;
snprintf (buffer, 4, "%.0f", value);
auto bgcolor = lv_color_hex(0xFF0000);
auto ind_color = lv_color_hex(0xFF0000);
@ -1256,7 +1245,10 @@ script:
}
lv_obj_set_style_bg_color(rect, bgcolor, LV_PART_MAIN);
lv_obj_set_style_img_recolor(indicator, ind_color, LV_PART_MAIN);
lv_label_set_text(label, buffer);
if(isnan(value))
lv_label_set_text(label, "??");
else
lv_label_set_text(label, buffer);
# - id: time_update
# then:

View File

@ -5,18 +5,37 @@ packages:
substitutions:
name: sthome-ut3
friendly_name: "sthome-ut3"
v_ON: "{ 0x4F,0x4E }"
v_OFF: "{ 0x4F, 0x46, 0x46 }"
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
@ -29,7 +48,10 @@ esp32:
# Enable logging
logger:
level: verbose
level: VERY_VERBOSE
initial_level: INFO
logs:
canbus: INFO
# Enable Home Assistant API
api:
@ -73,60 +95,13 @@ time:
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");
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
@ -142,79 +117,25 @@ canbus:
spi_id: spi_bus0
mode: NORMAL
id: canbus_sthome
can_id: ${CB_CANBUS_ID3}
can_id: ${CB_CANBUS_ID03}
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");
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());
}
}
# - 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
@ -234,74 +155,61 @@ switch:
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%
#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
@ -336,4 +244,51 @@ text_sensor:
name: 'Last Restart'
id: device_last_restart
icon: mdi:clock
entity_category: diagnostic
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;

File diff suppressed because it is too large Load Diff