Created
November 13, 2024 22:01
-
-
Save greghesp/c77dd40fb8644297012882c263a38370 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
substitutions: | |
room_name: 'Living Room' | |
device_name: 'living-room-esp32' | |
friendly_name: 'Living Room ESP32' | |
description: 'Living Room Touch LCD with MQTT Room, Glucose Levels and Fireplace Temperature' | |
static_ip: 192.168.1.25 | |
esp32: | |
board: esp32dev | |
framework: | |
type: arduino | |
esphome: | |
name: $device_name | |
friendly_name: $friendly_name | |
comment: $description | |
# logger: | |
# level: DEBUG | |
# Enable Home Assistant API | |
api: | |
ota: | |
- platform: esphome | |
# captive_portal: | |
mqtt: | |
broker: !secret mqtt_broker | |
username: !secret mqtt_username | |
password: !secret mqtt_password | |
discovery: false # Only if you use the HA API usually | |
id: mqtt_client | |
wifi: | |
ssid: !secret wifi_ssid | |
password: !secret wifi_password | |
manual_ip: | |
static_ip: $static_ip | |
gateway: 192.168.1.1 | |
subnet: 255.255.255.0 | |
# Enable fallback hotspot (captive portal) in case wifi connection fails | |
ap: | |
ssid: $device_name | |
time: | |
- platform: homeassistant | |
id: esptime | |
globals: | |
- id: is_glucose_hidden | |
type: bool | |
restore_value: no | |
initial_value: "false" | |
- id: last_update_timestamp | |
type: uint32_t | |
- id: last_update_seconds | |
type: uint32_t | |
- id: room_topic | |
type: std::string | |
initial_value: '"esphome-presence/${room_name}"' | |
sensor: | |
- platform: homeassistant | |
id: glucose_level | |
entity_id: sensor.dexcom_glucose_value | |
on_value: | |
- lambda: |- | |
id(last_update_timestamp) = millis(); | |
- platform: homeassistant | |
id: linnea_temperature | |
entity_id: climate.linnea_heater | |
attribute: temperature | |
- platform: homeassistant | |
id: linnea_current_temperature | |
entity_id: climate.linnea_heater | |
attribute: current_temperature | |
text_sensor: | |
- platform: homeassistant | |
id: glucose_trend | |
entity_id: sensor.dexcom_glucose_trend | |
- platform: homeassistant | |
id: linnea | |
entity_id: climate.linnea_heater | |
- platform: homeassistant | |
id: glucose_range | |
entity_id: input_select.diabetes_glucose_threshold | |
color: | |
- id: my_red | |
red: 100% | |
green: 0% | |
blue: 0% | |
- id: my_orange | |
red: 100% | |
green: 50% | |
blue: 0% | |
- id: my_green | |
hex: 42BF73 | |
- id: my_grey | |
hex: A0A0A0 | |
- id: my_white | |
hex: FFFFFF | |
- id: my_blue | |
hex: 2977D3 | |
font: | |
- file: | |
type: gfonts | |
family: Roboto+Slab | |
weight: 500 | |
id: font_value | |
size: 48 | |
- file: | |
type: gfonts | |
family: Roboto+Slab | |
weight: 500 | |
id: temp_symbol | |
size: 18 | |
- file: | |
type: gfonts | |
family: Roboto | |
weight: 300 | |
id: font_mmol | |
size: 16 | |
- file: | |
type: gfonts | |
family: Roboto | |
weight: 300 | |
id: font_12 | |
size: 12 | |
- file: "gfonts://Roboto" | |
id: font_range | |
size: 16 | |
image: | |
- file: mdi:fire | |
id: flame | |
resize: 70x70 | |
- file: mdi:arrow-collapse-up | |
id: rising_quickly | |
resize: 30x30 | |
- file: mdi:arrow-up | |
id: rising | |
resize: 30x30 | |
- file: mdi:arrow-top-right | |
id: rising_slightly | |
resize: 30x30 | |
- file: mdi:arrow-right | |
id: steady | |
resize: 30x30 | |
- file: mdi:arrow-bottom-right | |
id: falling_slightly | |
resize: 30x30 | |
- file: mdi:arrow-down | |
id: falling | |
resize: 30x30 | |
- file: mdi:arrow-collapse-down | |
id: falling_quickly | |
resize: 30x30 | |
- file: mdi:help | |
id: unknown | |
resize: 30x30 | |
- file: mdi:arrow-up | |
id: up | |
resize: 20x20 | |
- file: mdi:arrow-down | |
id: down | |
resize: 20x20 | |
- file: mdi:eye | |
id: eye | |
resize: 20x20 | |
- file: mdi:eye-off | |
id: eye_off | |
resize: 20x20 | |
spi: | |
- id: lcd | |
clk_pin: GPIO14 | |
mosi_pin: GPIO13 | |
miso_pin: GPIO12 | |
- id: touch | |
clk_pin: GPIO25 | |
mosi_pin: GPIO32 | |
miso_pin: GPIO39 | |
i2c: | |
sda: GPIO27 | |
scl: GPIO22 | |
scan: true | |
id: bus_a | |
frequency: 400kHz | |
output: | |
- platform: ledc | |
pin: GPIO21 | |
id: former_led_pin | |
- platform: ledc | |
id: output_red | |
pin: GPIO4 | |
inverted: true | |
- platform: ledc | |
id: output_green | |
pin: GPIO16 | |
inverted: true | |
- platform: ledc | |
id: output_blue | |
pin: GPIO17 | |
inverted: true | |
display: | |
- platform: ili9xxx | |
invert_colors: false | |
model: ILI9341 | |
spi_id: lcd | |
cs_pin: 15 | |
dc_pin: 2 | |
id: my_display | |
pages: | |
- id: glucose_fire | |
lambda: |- | |
int hs = it.get_width() / 2; // Horizontal Spacing = text data horizontal center point | |
int hq = it.get_width() / 4; // text data horizontal center for two vertical lines | |
int vs = it.get_height() / 8; // Vertical Center = text data vertical center point = how many lines | |
int hv = it.get_height() / 2; | |
int padding = 2; | |
int centre_gap = padding / 2; | |
// ***** Glucose Information ***** // | |
it.line(padding, padding, it.get_width() - padding, padding, id(my_green)); // Top Box Top Line | |
it.line(padding, padding, padding, hv - centre_gap, id(my_green)); // Top Box Left Line | |
it.line(it.get_width() - padding, padding, it.get_width() - padding, hv - centre_gap, id(my_green)); // Top Box Right Line | |
it.line(padding, hv - centre_gap, it.get_width() - padding, hv - centre_gap, id(my_green)); // Top Box Bottom Line | |
it.printf(padding + 5, padding + 5, id(font_12), "Last Updated: %i minutes ago", id(last_update_seconds)/60); // Last updated | |
it.image(it.get_width() - padding - 25 , padding + 5, id(eye_off), id(my_grey)); | |
// Trend Circle Background | |
if (id(glucose_range).state == "Urgent High" || id(glucose_range).state == "Urgent Low") { | |
it.filled_circle(80, 75, 24, my_red); | |
} else if (id(glucose_range).state == "High" || id(glucose_range).state == "Low") { | |
it.filled_circle(80, 75, 24, my_orange); | |
} else { | |
it.filled_circle(80, 75, 24, my_green); | |
} | |
// Arrow Logic | |
if (id(glucose_trend).state == "rising_quickly") { | |
it.image(65, 60, id(rising_quickly), id(my_white)); | |
} else if (id(glucose_trend).state == "rising") { | |
it.image(66, 60, id(rising), id(my_white)); | |
} else if (id(glucose_trend).state == "rising_slightly") { | |
it.image(66, 60, id(rising_slightly), id(my_white)); | |
} else if (id(glucose_trend).state == "steady") { | |
it.image(66, 60, id(steady), id(my_white)); | |
} else if (id(glucose_trend).state == "falling_slightly") { | |
it.image(65, 60, id(falling_slightly), id(my_white)); | |
} else if (id(glucose_trend).state == "falling") { | |
it.image(65, 60, id(falling), id(my_white)); | |
} else if (id(glucose_trend).state == "falling_quickly") { | |
it.image(65, 60, id(falling_quickly), id(my_white)); | |
} else { | |
it.image(65, 60, id(unknown), id(my_white)); | |
} | |
it.printf(117, 39, id(font_value), "%.1f", id(glucose_level).state); // Glucose Value | |
it.print(117, 90, id(font_mmol), "mmol/L"); // mmol/L line | |
it.printf(hs, hv - centre_gap - 30, id(font_range), TextAlign::CENTER, "Glucose %s", id(glucose_trend).state.c_str()); // Glucose Trend String | |
// ***** Fireplace Information ***** // | |
it.line(padding, hv + centre_gap, it.get_width() - padding, hv + centre_gap, id(my_grey)); // Bottom Box Top Line | |
it.line(padding, hv + centre_gap, padding, it.get_height() - padding, id(my_grey)); // Bottom Box Left Line | |
it.line(it.get_width() - padding, hv + centre_gap, it.get_width() - padding, it.get_height() - padding, id(my_grey)); // Bottom Box Right Line | |
it.line(padding, it.get_height() - padding, it.get_width() - padding, it.get_height() - padding, id(my_grey)); // Top Box Bottom Line | |
if(id(linnea).state == "off") { | |
it.image(9, 205, id(flame), id(my_grey)); | |
} else { | |
it.image(9, 205, id(flame), id(my_orange)); | |
} | |
it.printf(85, 195, id(font_value), "%.0f", id(linnea_temperature).state); // Fireplace Temp Setting | |
it.print(135, 205, id(temp_symbol), "°C"); // Fireplace Temp Setting | |
it.printf(85, 250, id(font_mmol), "Now %.0f°C", id(linnea_current_temperature).state); // Current temp | |
it.filled_circle(200, 200, 20, my_red); // Up Circle Background | |
it.image(190, 190, id(up), id(my_white)); | |
it.filled_circle(200, 270, 20, my_blue); // Down Circle Background | |
it.image(190, 262, id(down), id(my_white)); | |
touchscreen: | |
platform: xpt2046 | |
id: my_touchscreen | |
spi_id: touch | |
cs_pin: 33 | |
interrupt_pin: 36 | |
update_interval: 50ms | |
threshold: 400 | |
calibration: | |
x_min: 3860 | |
x_max: 280 | |
y_min: 340 | |
y_max: 3860 | |
binary_sensor: | |
- platform: touchscreen | |
name: glucose_hide | |
id: glucose_hide | |
x_min: 200 | |
x_max: 240 | |
y_min: 0 | |
y_max: 30 | |
on_press: | |
- lambda: |- | |
if (id(is_glucose_hidden)) { | |
id(is_glucose_hidden) = false; | |
} else { | |
id(is_glucose_hidden) = true; | |
} | |
- platform: touchscreen | |
name: linnea_toggle | |
id: linnea_toggle | |
x_min: 5 | |
x_max: 80 | |
y_min: 200 | |
y_max: 280 | |
on_press: | |
- if: | |
condition: | |
text_sensor.state: | |
id: linnea | |
state: 'off' | |
then: | |
- homeassistant.service: | |
service: climate.turn_on | |
data: | |
entity_id: climate.linnea_heater | |
else: | |
- homeassistant.service: | |
service: climate.turn_off | |
data: | |
entity_id: climate.linnea_heater | |
- platform: touchscreen | |
name: linnea_up | |
id: linnea_up | |
x_min: 180 | |
x_max: 220 | |
y_min: 180 | |
y_max: 220 | |
on_press: | |
- homeassistant.service: | |
service: climate.set_temperature | |
data: | |
entity_id: climate.linnea_heater | |
data_template: | |
temperature: '{{ my_variable }}' | |
variables: | |
my_variable: |- | |
return id(linnea_temperature).state + 1; | |
- platform: touchscreen | |
name: linnea_down | |
id: linnea_down | |
x_min: 180 | |
x_max: 220 | |
y_min: 250 | |
y_max: 290 | |
on_press: | |
- homeassistant.service: | |
service: climate.set_temperature | |
data: | |
entity_id: climate.linnea_heater | |
data_template: | |
temperature: '{{ my_variable }}' | |
variables: | |
my_variable: |- | |
return id(linnea_temperature).state - 1; | |
light: | |
- platform: monochromatic | |
output: former_led_pin | |
name: "Display Backlight" | |
id: back_light | |
restore_mode: ALWAYS_ON | |
- platform: rgb | |
name: LED | |
red: output_red | |
id: led | |
green: output_green | |
blue: output_blue | |
restore_mode: ALWAYS_OFF | |
bluetooth_proxy: | |
active: true | |
esp32_ble_tracker: | |
on_ble_advertise: | |
- then: | |
- lambda: |- | |
if (x.get_ibeacon().has_value()) { | |
std::string uuid; | |
esp_bt_uuid_t raw_uuid = x.get_ibeacon().value().get_uuid().get_uuid(); | |
char sbuf[64]; | |
char *bpos = sbuf; | |
uuid = x.get_ibeacon().value().get_uuid().to_string(); | |
std::transform(uuid.begin(), uuid.end(), uuid.begin(), [](unsigned char c){ return std::tolower(c); }); | |
char mbuf[32] = {0}; | |
sprintf(mbuf, "-%hu-%hu", x.get_ibeacon().value().get_major(), x.get_ibeacon().value().get_minor()); | |
uuid.append(mbuf); | |
int8_t tx_power = -69; | |
float dist = pow(10, (float)(tx_power - x.get_rssi()) / (10 * 2)); | |
ESP_LOGD("ble_adv", "Sending MQTT room update for '%s' (%s): %.03fm (%d rssi)", | |
x.get_name().c_str(), uuid.c_str(), dist, x.get_rssi()); | |
id(mqtt_client).publish_json(id(room_topic), [=](JsonObject root) { | |
root["id"] = uuid; | |
root["name"] = x.get_name(); | |
root["distance"] = dist; | |
}); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment