ESPhome covers mostly everything and you just need to write less code. ==> ready to go
What it does:
- Read and some items from OH via REST-API and displays it at the display
- Write some items to OH via REST-API
- OH can control ESPhome variables by sending HTTP requests to ESPhome
Here is my code
esp32:
board: nodemcu-32s
framework:
version: recommended # = stabile version
substitutions:
openhab_ip: "xxx"
debughost_ip: "xxx"
debughost_port: "xx"
wifi_password: "xxx"
wifi_ssid: "xxx"
code_version: "1.26"
esphome:
name: esp32eink
comment: esp32eink
on_boot:
- priority: 700
then:
- delay: 2sec
- component.update: epaper
- delay: 100ms
- component.update: epaper
- delay: 100ms
- component.update: epaper
- delay: 100ms
- component.update: epaper
- delay: 100ms
- lambda: |-
id(st_openhabmessage02).publish_state( " ");
id(st_openhabmessage03).publish_state( " ");
id(st_openhabmessage04).publish_state( " ");
id(st_openhabmessage05).publish_state( " ");
id(st_openhabescalation).publish_state(" ");
- button.press: bu_openhabquerydata
- button.press: bu_openhabupdatelastevent
# Enable logging
logger:
level: DEBUG
logs:
text_sensor: ERROR
ultrasonic.sensor: ERROR
sensor: INFO
button: ERROR
ledc.output: ERROR
rtttl: ERROR
http_request: ERROR
# Enable Home Assistant API
api:
reboot_timeout: 0s
ota:
password: "xxx"
wifi:
ssid: $wifi_ssid
password: $wifi_password
#fast_connect: on
#power_save_mode: none
manual_ip:
static_ip: xx
gateway: xx
subnet: xx
dns1: xx
dns2: xx
web_server:
port: 80
# NTP sync
time:
- platform: sntp
id: sntp_time
timezone: xxx
servers:
- xxx
on_time:
- seconds: 5
minutes: /5
then:
#- logger.log: "every 5min task started"
- button.press: bu_openhabquerydata
- seconds: 0
minutes: /1
then:
#- logger.log: "every 1min task started"
- component.update: epaper
- seconds: 30
minutes: 30
hours: 0
then:
- switch.turn_on: sw_DeviceRestart
- seconds: 30
minutes: 30
hours: 12
then:
- switch.turn_on: sw_DeviceRestart
http_request:
useragent: esphome/device
timeout: 2s
id: http_request_data
# Example button configuration
button:
- platform: template
name: openhabquerydata
id: bu_openhabquerydata
on_press:
then:
- logger.log: "bu_openhabquerydata pressed"
- http_request.get:
url: http://OH-IP:8080/rest/items/nuTempForecast_Max
headers:
Content-Type: application/json
verify_ssl: false
on_response:
then:
- lambda: |-
json::parse_json(id(http_request_data).get_string(), [](JsonObject root) {
id(se_statustemperaturmax).publish_state(root["state"]);
});
- http_request.get:
url: http://OH-IP:8080/rest/items/DoorSensor08_Temperature
headers:
Content-Type: application/json
verify_ssl: false
on_response:
then:
- lambda: |-
json::parse_json(id(http_request_data).get_string(), [](JsonObject root) {
id(se_statustemperaturcurrent).publish_state(root["state"]);
});
- http_request.get:
url: http://OH-IP:8080/rest/items/swBriefkastenPostvorhanden
headers:
Content-Type: application/json
verify_ssl: false
on_response:
then:
- lambda: |-
json::parse_json(id(http_request_data).get_string(), [](JsonObject root) {
if(root["state"] == "OFF") {
id(bs_statuspostbox).publish_state(false);
} else {
id(bs_statuspostbox).publish_state(true);
}
});
- http_request.get:
url: http://OH-IP:8080/rest/items/ADAM6050_01_DI11
headers:
Content-Type: application/json
verify_ssl: false
on_response:
then:
- lambda: |-
json::parse_json(id(http_request_data).get_string(), [](JsonObject root) {
if(root["state"] == "CLOSED") {
id(bs_statusbathwindow).publish_state(false);
} else {
id(bs_statusbathwindow).publish_state(true);
}
});
- http_request.get:
url: http://OH-IP:8080/rest/items/swRainSensor01_State
headers:
Content-Type: application/json
verify_ssl: false
on_response:
then:
- lambda: |-
json::parse_json(id(http_request_data).get_string(), [](JsonObject root) {
if(root["state"] == "OFF") {
id(bs_statusrain).publish_state(false);
} else {
id(bs_statusrain).publish_state(true);
}
});
- http_request.get:
url: http://OH-IP:8080/rest/items/swSchattenUltraHot
headers:
Content-Type: application/json
verify_ssl: false
on_response:
then:
- lambda: |-
json::parse_json(id(http_request_data).get_string(), [](JsonObject root) {
if(root["state"] == "OFF") {
id(bs_statusultrahot).publish_state(false);
} else {
id(bs_statusultrahot).publish_state(true);
}
});
- http_request.get:
url: http://OH-IP:8080/rest/items/swSchattenGaragenseiteRunter
headers:
Content-Type: application/json
verify_ssl: false
on_response:
then:
- lambda: |-
json::parse_json(id(http_request_data).get_string(), [](JsonObject root) {
if(root["state"] == "OFF") {
id(bs_statusschattengaragerunter).publish_state(false);
} else {
id(bs_statusschattengaragerunter).publish_state(true);
}
});
- http_request.get:
url: http://OH-IP:8080/rest/items/swSchattenGaragenseiteHoch
headers:
Content-Type: application/json
verify_ssl: false
on_response:
then:
- lambda: |-
json::parse_json(id(http_request_data).get_string(), [](JsonObject root) {
if(root["state"] == "OFF") {
id(bs_statusschattengaragehoch).publish_state(false);
} else {
id(bs_statusschattengaragehoch).publish_state(true);
}
});
- http_request.get:
url: http://OH-IP:8080/rest/items/swSchattenStrassenseiteRunter
headers:
Content-Type: application/json
verify_ssl: false
on_response:
then:
- lambda: |-
json::parse_json(id(http_request_data).get_string(), [](JsonObject root) {
if(root["state"] == "OFF") {
id(bs_statusschattenstrasserunter).publish_state(false);
} else {
id(bs_statusschattenstrasserunter).publish_state(true);
}
});
- http_request.get:
url: http://OH-IP:8080/rest/items/swSchattenStrassenseiteHoch
headers:
Content-Type: application/json
verify_ssl: false
on_response:
then:
- lambda: |-
json::parse_json(id(http_request_data).get_string(), [](JsonObject root) {
if(root["state"] == "OFF") {
id(bs_statusschattenstrassehoch).publish_state(false);
} else {
id(bs_statusschattenstrassehoch).publish_state(true);
}
});
- http_request.get:
url: http://OH-IP:8080/rest/items/swSchattenTerrassenseiteRunter
headers:
Content-Type: application/json
verify_ssl: false
on_response:
then:
- lambda: |-
json::parse_json(id(http_request_data).get_string(), [](JsonObject root) {
if(root["state"] == "OFF") {
id(bs_statusschattenterrasserunter).publish_state(false);
} else {
id(bs_statusschattenterrasserunter).publish_state(true);
}
});
- http_request.get:
url: http://OH-IP:8080/rest/items/swSchattenTerrassenseiteHoch
headers:
Content-Type: application/json
verify_ssl: false
on_response:
then:
- lambda: |-
json::parse_json(id(http_request_data).get_string(), [](JsonObject root) {
if(root["state"] == "OFF") {
id(bs_statusschattenterrassehoch).publish_state(false);
} else {
id(bs_statusschattenterrassehoch).publish_state(true);
}
});
- http_request.get:
url: http://OH-IP:8080/rest/items/swTrashRestmuellICAL_Alert
headers:
Content-Type: application/json
verify_ssl: false
on_response:
then:
- lambda: |-
json::parse_json(id(http_request_data).get_string(), [](JsonObject root) {
if(root["state"] == "OFF") {
id(bs_statusmuellrest).publish_state(false);
} else {
id(bs_statusmuellrest).publish_state(true);
}
});
- http_request.get:
url: http://OH-IP:8080/rest/items/swTrashBiomuellICAL_Alert
headers:
Content-Type: application/json
verify_ssl: false
on_response:
then:
- lambda: |-
json::parse_json(id(http_request_data).get_string(), [](JsonObject root) {
if(root["state"] == "OFF") {
id(bs_statusmuellbio).publish_state(false);
} else {
id(bs_statusmuellbio).publish_state(true);
}
});
- http_request.get:
url: http://OH-IP:8080/rest/items/swTrashGelbersackICAL_Alert
headers:
Content-Type: application/json
verify_ssl: false
on_response:
then:
- lambda: |-
json::parse_json(id(http_request_data).get_string(), [](JsonObject root) {
if(root["state"] == "OFF") {
id(bs_statusmuellgelbsack).publish_state(false);
} else {
id(bs_statusmuellgelbsack).publish_state(true);
}
});
- http_request.get:
url: http://OH-IP:8080/rest/items/swTrashPapiertonneICAL_Alert
headers:
Content-Type: application/json
verify_ssl: false
on_response:
then:
- lambda: |-
json::parse_json(id(http_request_data).get_string(), [](JsonObject root) {
if(root["state"] == "OFF") {
id(bs_statusmuellpapier).publish_state(false);
} else {
id(bs_statusmuellpapier).publish_state(true);
}
});
- component.update: epaper
- platform: template
name: openhabupdatelastevent
id: bu_openhabupdatelastevent
on_press:
then:
- logger.log: "bu_openhabupdatelastevent pressed"
- http_request.get:
url: http://OH-IP:8080/rest/items/stLastEventTriggered
headers:
Content-Type: application/json
verify_ssl: false
on_response:
then:
- lambda: |-
id(st_openhabmessage05).publish_state(id(st_openhabmessage04).state.c_str());
id(st_openhabmessage04).publish_state(id(st_openhabmessage03).state.c_str());
id(st_openhabmessage03).publish_state(id(st_openhabmessage02).state.c_str());
id(st_openhabmessage02).publish_state(id(st_openhabmessage01).state.c_str());
json::parse_json(id(http_request_data).get_string(), [](JsonObject root) {
id(st_openhabmessage01).publish_state(root["state"]);
});
- component.update: epaper
- platform: template
name: openhabupdateescalation_start
id: bu_openhabupdateescalation_start
on_press:
then:
- logger.log: "bu_openhabupdateescalation_start pressed"
- http_request.get:
url: http://OH-IP:8080/rest/items/stEskalationMessage
headers:
Content-Type: application/json
verify_ssl: false
on_response:
then:
- lambda: |-
json::parse_json(id(http_request_data).get_string(), [](JsonObject root) {
id(st_openhabescalation).publish_state(root["state"]);
});
- component.update: epaper
- rtttl.play: 'siren:d=8,o=5,b=100:d,e,d,e'
- platform: template
name: openhabupdateescalation_end
id: bu_openhabupdateescalation_end
on_press:
then:
- logger.log: "bu_openhabupdateescalation_end pressed"
- lambda: |-
id(st_openhabescalation).publish_state(" ");
- component.update: epaper
#- rtttl.play: 'oneshort:d=4,o=5,b=100:8e6'
- platform: template
name: openhabplaysound
id: openhabplaysound
on_press:
then:
- rtttl.play: 'oneshort:d=4,o=5,b=100:8e6'
binary_sensor:
- platform: template
name: statuspostbox
id: bs_statuspostbox
- platform: template
name: statusbathwindow
id: bs_statusbathwindow
- platform: template
name: statusrain
id: bs_statusrain
- platform: template
name: statusultrahot
id: bs_statusultrahot
- platform: template
name: statusschattengaragerunter
id: bs_statusschattengaragerunter
- platform: template
name: statusschattengaragehoch
id: bs_statusschattengaragehoch
- platform: template
name: statusschattenstrasserunter
id: bs_statusschattenstrasserunter
- platform: template
name: statusschattenstrassehoch
id: bs_statusschattenstrassehoch
- platform: template
name: statusschattenterrasserunter
id: bs_statusschattenterrasserunter
- platform: template
name: statusschattenterrassehoch
id: bs_statusschattenterrassehoch
- platform: template
name: statusmuellbio
id: bs_statusmuellbio
- platform: template
name: statusmuellrest
id: bs_statusmuellrest
- platform: template
name: statusmuellpapier
id: bs_statusmuellpapier
- platform: template
name: statusmuellgelbsack
id: bs_statusmuellgelbsack
switch:
- platform: restart
name: "Device Restart"
id: sw_DeviceRestart
output:
- platform: ledc
pin: GPIO19
id: rtttl_out
rtttl:
output: rtttl_out
sensor:
- platform: wifi_signal
name: "WiFi-Signal"
id: wifisignal
update_interval: 60s
# Uptime sensor
- platform: uptime
id: uptime_s
update_interval: 1s
accuracy_decimals: 0
- platform: template
name: "statustemperaturcurrent"
id: se_statustemperaturcurrent
- platform: template
name: "statustemperaturmax"
id: se_statustemperaturmax
text_sensor:
- platform: version
name: "Firmware Version"
- platform: template
name: "Code-Version:"
id: CodeVersion
lambda: |-
return {"$code_version"};
- platform: template
name: "ESP-Uptime"
id: Uptime_ID
lambda: |-
uint32_t dur = id(uptime_s).state;
int dys = 0;
int hrs = 0;
int mnts = 0;
if (dur > 86399) {
dys = trunc(dur / 86400);
dur = dur - (dys * 86400);
}
if (dur > 3599) {
hrs = trunc(dur / 3600);
dur = dur - (hrs * 3600);
}
if (dur > 59) {
mnts = trunc(dur / 60);
dur = dur - (mnts * 60);
}
char buffer[38];
sprintf(buffer, "%ud %02uh %02um %02us", dys, hrs, mnts, dur);
return {buffer};
update_interval: 1s
- platform: template
name: "openhabescalation"
id: st_openhabescalation
- platform: template
name: "openhabmessage01"
id: st_openhabmessage01
- platform: template
name: "openhabmessage02"
id: st_openhabmessage02
- platform: template
name: "openhabmessage03"
id: st_openhabmessage03
- platform: template
name: "openhabmessage04"
id: st_openhabmessage04
- platform: template
name: "openhabmessage05"
id: st_openhabmessage05
font:
#https://fontdrop.info/
- file: ".fonts/arial.ttf"
id: arial_font_14
size: 14
- file: ".fonts/arialbd.ttf"
id: arialbd_font_14
size: 14
- file: ".fonts/arial.ttf"
id: arial_font_20
size: 20
- file: ".fonts/materialdesignicons-webfont.ttf"
# https://community.home-assistant.io/t/display-materialdesign-icons-on-esphome-attached-to-screen/199790
# https://cdn.jsdelivr.net/npm/@mdi/font@6.7.96/fonts/
# https://pictogrammers.github.io/@mdi/font/6.7.96/
# https://github.com/Templarian/MaterialDesign/issues/6682
# it.print(32, 24, id(icon_font), TextAlign::CENTER, "\U000F0599");
id: material_font_24
size: 24
glyphs:
# Briefkasten
- "\U000F01EE" # mdi-email
# Wifi
- "\U000F0783" # mdi-signal-off
- "\U000F08BF" # mdi-signal-cellular-outline
- "\U000F08BC" # mdi-signal-cellular-1
- "\U000F08BD" # mdi-signal-cellular-2
- "\U000F08BE" # mdi-signal-cellular-3
# Rollo
- "\U000F111C" # mdi-window-shutter
- "\U000F111E" # mdi-window-shutter-open
- "\U000F12E5" # mdi-hydro-power
# Sonstiges
- "\U000F05AF" # window open
- "\U000F0596" # mdi-weather-pouring
- " " # Leerzeichen
spi:
clk_pin: GPIO18
mosi_pin: GPIO23
id: epaper_display
display:
# 296 (x) x 128 (y) pixel, black and white, SPI-Interface, 3.3V/5V
# x = 0 - 127
# y = 0 - 295
# main.cpp
- platform: waveshare_epaper
id: epaper
cs_pin: GPIO5
busy_pin: GPIO16
reset_pin: GPIO21
dc_pin: GPIO22
rotation: 90°
model: 2.90inv2
update_interval: never
#full_update_every: 1
reset_duration: 2ms
lambda: |-
//ESP_LOGI("display", "Updating display ...");
it.printf( 0, 0, id(arial_font_14), TextAlign::TOP_LEFT, "%s", id(st_openhabmessage01).state.c_str());
it.printf( 0, 16, id(arial_font_14), TextAlign::TOP_LEFT, "%s", id(st_openhabmessage02).state.c_str());
it.printf( 0, 32, id(arial_font_14), TextAlign::TOP_LEFT, "%s", id(st_openhabmessage03).state.c_str());
it.printf( 0, 48, id(arial_font_14), TextAlign::TOP_LEFT, "%s", id(st_openhabmessage04).state.c_str());
it.printf( 0, 64, id(arial_font_14), TextAlign::TOP_LEFT, "%s", id(st_openhabmessage05).state.c_str());
it.printf( 0, 80, id(arialbd_font_14), TextAlign::TOP_LEFT, "%s", id(st_openhabescalation).state.c_str());
//######################################################################################################################
if(id(bs_statusmuellbio).state == true) {
it.printf( 145, 112, id(arial_font_14), TextAlign::BOTTOM_RIGHT, "%s", "B");
} else {
it.printf( 145, 112, id(arial_font_14), TextAlign::BOTTOM_RIGHT, "%s", " ");
}
if(id(bs_statusmuellgelbsack).state == true) {
it.printf( 157, 112, id(arial_font_14), TextAlign::BOTTOM_RIGHT, "%s", "G");
} else {
it.printf( 157, 112, id(arial_font_14), TextAlign::BOTTOM_RIGHT, "%s", " ");
}
if(id(bs_statusmuellpapier).state == true) {
it.printf( 167, 112, id(arial_font_14), TextAlign::BOTTOM_RIGHT, "%s", "P");
} else {
it.printf( 167, 112, id(arial_font_14), TextAlign::BOTTOM_RIGHT, "%s", " ");
}
if(id(bs_statusmuellrest).state == true) {
it.printf( 178, 112, id(arial_font_14), TextAlign::BOTTOM_RIGHT, "%s", "R");
} else {
it.printf( 178, 112, id(arial_font_14), TextAlign::BOTTOM_RIGHT, "%s", " ");
}
it.strftime(296, 112, id(arial_font_14), TextAlign::BOTTOM_RIGHT, "%H:%M/%d.%m.%Y", id(sntp_time).now());
//######################################################################################################################
it.printf( 0, 131, id(arial_font_14), TextAlign::BOTTOM_LEFT, "%s", id(CodeVersion).state.c_str());
if((id(bs_statusschattengaragerunter).state == true) && ((id(bs_statusschattengaragehoch).state == false) || (id(bs_statusultrahot).state == true))){
it.print( 30, 133, id(material_font_24), TextAlign::BOTTOM_LEFT, "\U000F111C");
} else {
it.print( 30, 133, id(material_font_24), TextAlign::BOTTOM_LEFT, "\U000F111E");
}
if((id(bs_statusschattenstrasserunter).state == true) && ((id(bs_statusschattenstrassehoch).state == false) || (id(bs_statusultrahot).state == true))){
it.print( 50, 133, id(material_font_24), TextAlign::BOTTOM_LEFT, "\U000F111C");
} else {
it.print( 50, 133, id(material_font_24), TextAlign::BOTTOM_LEFT, "\U000F111E");
}
if((id(bs_statusschattenterrasserunter).state == true) && ((id(bs_statusschattenterrassehoch).state == false) || (id(bs_statusultrahot).state == true))){
it.print( 70, 133, id(material_font_24), TextAlign::BOTTOM_LEFT, "\U000F111C");
} else {
it.print( 70, 133, id(material_font_24), TextAlign::BOTTOM_LEFT, "\U000F111E");
}
if(id(bs_statusultrahot).state == true) {
it.print( 90, 132, id(material_font_24), TextAlign::BOTTOM_LEFT, "\U000F12E5");
} else {
it.print( 90, 132, id(material_font_24), TextAlign::BOTTOM_LEFT, " ");
}
if(id(bs_statusrain).state == true) {
it.print( 138, 133, id(material_font_24), TextAlign::BOTTOM_RIGHT, "\U000F0596");
} else {
it.print( 138, 133, id(material_font_24), TextAlign::BOTTOM_RIGHT, " ");
}
if(id(bs_statusbathwindow).state == true) {
it.print( 161, 133, id(material_font_24), TextAlign::BOTTOM_RIGHT, "\U000F05AF");
} else {
it.print( 161, 133, id(material_font_24), TextAlign::BOTTOM_RIGHT, " ");
}
// WiFi Signal Strenght
// https://www.screenbeam.com/wifihelp/wifibooster/wi-fi-signal-strength-what-is-a-good-signal/
if(id(wifisignal).has_state()) {
if(id(wifisignal).state >= -60) {
// mdi-signal-cellular-3
it.print(185, 133, id(material_font_24), TextAlign::BOTTOM_RIGHT, "\U000F08BE");
} else if (id(wifisignal).state >= -66) {
// mdi-signal-cellular-2
it.print(185, 133, id(material_font_24), TextAlign::BOTTOM_RIGHT, "\U000F08BD");
} else if (id(wifisignal).state >= -72) {
// mdi-signal-cellular-1
it.print(185, 133, id(material_font_24), TextAlign::BOTTOM_RIGHT, "\U000F08BC");
} else if (id(wifisignal).state >= -75) {
// mdi-signal-cellular-outline
it.print(185, 133, id(material_font_24), TextAlign::BOTTOM_RIGHT, "\U000F08BF");
} else {
// mdi-signal-off
it.print(185, 133, id(material_font_24), TextAlign::BOTTOM_RIGHT, "\U000F0783");
}
}
if(id(bs_statuspostbox).state == true) {
it.print( 210, 133, id(material_font_24), TextAlign::BOTTOM_RIGHT, "\U000F01EE");
} else {
it.print( 210, 133, id(material_font_24), TextAlign::BOTTOM_RIGHT, " ");
}
it.printf( 296, 133, id(arial_font_20), TextAlign::BOTTOM_RIGHT, "%.1f/%.1f", id(se_statustemperaturcurrent).state, id(se_statustemperaturmax).state);
Sorry, long listing
Sorry for some german OH-ITEM-names
It looks like this:
Upper part: log what the house does
Lower part: Roller shutter status, Wifi strenght, date/time, outside temp and max temp./trash bin needs to be brought to outside (not seen at the screenshot), rain status, emegency notification (buzzer is played in parallel)
Next thing to do from my side:
Put some hardware buttons to acknowledge some status and send back to OH