|
@ -3,7 +3,7 @@ font: |
|
|
- file: 'fonts/Vera.ttf' |
|
|
- file: 'fonts/Vera.ttf' |
|
|
id: font1 |
|
|
id: font1 |
|
|
size: 10 |
|
|
size: 10 |
|
|
glyphs: '!"%()+=,-_.:°0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz/²³µΩ' |
|
|
glyphs: '!"%()[]+=,-_.:°0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz/²³µΩ' |
|
|
- file: 'fonts/Vera.ttf' |
|
|
- file: 'fonts/Vera.ttf' |
|
|
id: font2 |
|
|
id: font2 |
|
|
size: 20 |
|
|
size: 20 |
|
@ -61,56 +61,102 @@ display: |
|
|
it.print(10, 50, id(font2), "esp32weatherstation2"); |
|
|
it.print(10, 50, id(font2), "esp32weatherstation2"); |
|
|
- id: page2 |
|
|
- id: page2 |
|
|
lambda: |- |
|
|
lambda: |- |
|
|
it.print(5, 6, id(font1), "${node_name}"); |
|
|
// Title |
|
|
it.strftime(150, 6, id(font1), "%Y-%m-%d %H:%M", id(sntp_time).now()); |
|
|
it.filled_rectangle(0,0,250,20, COLOR_ON); |
|
|
it.line(0, 20, 250, 20); |
|
|
it.print(5, 6, id(font1), COLOR_OFF, "${node_name}"); |
|
|
it.filled_rectangle(0, 20, 70, 122, COLOR_ON); |
|
|
it.strftime(150, 6, id(font1), COLOR_OFF, "%Y-%m-%d %H:%M", id(sntp_time).now()); |
|
|
it.line(0, 56, 70, 56, COLOR_OFF); |
|
|
// Weather icon |
|
|
it.line(0, 92, 70, 92, COLOR_OFF); |
|
|
|
|
|
if (id(temperature).state) { |
|
|
|
|
|
it.printf(2, 21+4, id(font2), COLOR_OFF, "%.1f", id(temperature).state); it.printf(55, 21+4, id(font1), COLOR_OFF, "°C"); |
|
|
|
|
|
it.printf(2, 57+4, id(font2), COLOR_OFF, "%.1f", id(humidity).state); it.printf(55, 57+4, id(font1), COLOR_OFF, "%%"); |
|
|
|
|
|
if (id(humidity).state < 30) { |
|
|
|
|
|
it.printf(30, 80, id(font1), COLOR_OFF, "low"); |
|
|
|
|
|
} else if (id(humidity).state < 60) { |
|
|
|
|
|
it.printf(30, 80, id(font1), COLOR_OFF, "comfort"); |
|
|
|
|
|
} else { |
|
|
|
|
|
it.printf(30, 80, id(font1), COLOR_OFF, "high"); |
|
|
|
|
|
} |
|
|
|
|
|
it.printf(2, 93+4, id(font2), COLOR_OFF, "%.0f", id(pressure_sealevel).state); it.printf(55, 93+4, id(font1), COLOR_OFF, "hPa"); |
|
|
|
|
|
it.graph(70, 21, id(temperature_graph)); |
|
|
|
|
|
it.graph(70, 57, id(humidity_graph)); |
|
|
|
|
|
it.graph(70, 93, id(pressure_graph)); |
|
|
|
|
|
} |
|
|
|
|
|
if (id(weather_icon).has_state()) { |
|
|
if (id(weather_icon).has_state()) { |
|
|
it.printf(133, 51, id(icon_font), weather_icon_map[id(weather_icon).state.c_str()].c_str()); |
|
|
it.printf(0, 18, id(icon_font), weather_icon_map[id(weather_icon).state.c_str()].c_str()); |
|
|
|
|
|
} |
|
|
|
|
|
it.printf(55, 25, id(font1), "T: %.1f°C", id(temperature_outside).state); |
|
|
|
|
|
it.printf(55, 35, id(font1), "H: %.1f%%", id(humidity_outside).state); |
|
|
|
|
|
it.printf(55, 45, id(font1), "%s", id(weather_icon).state.c_str()); |
|
|
|
|
|
// own measurements |
|
|
|
|
|
it.filled_rectangle(0, 65, 59, 33, COLOR_ON); |
|
|
|
|
|
it.printf(2, 65+4, id(font2), COLOR_OFF, "%.1f", id(temperature).state); it.printf(45, 65+4, id(font1), COLOR_OFF, "°C"); |
|
|
|
|
|
it.filled_rectangle(60, 65, 59, 33, COLOR_ON); |
|
|
|
|
|
it.printf(62, 65+4, id(font2), COLOR_OFF, "%.1f", id(humidity).state); it.printf(105, 65+4, id(font1), COLOR_OFF, "%%"); |
|
|
|
|
|
it.filled_rectangle(120, 65, 59, 33, COLOR_ON); |
|
|
|
|
|
it.printf(122, 65+4, id(font2), COLOR_OFF, "%.0f", id(pressure_sealevel).state); it.printf(178, 87, id(font1), COLOR_OFF, TextAlign::TOP_RIGHT, "hPa"); |
|
|
|
|
|
// humidity human readable |
|
|
|
|
|
if (id(humidity).state < 30) { |
|
|
|
|
|
it.printf(116, 87, id(font1), COLOR_OFF, TextAlign::TOP_RIGHT, "low"); |
|
|
|
|
|
} else if (id(humidity).state < 60) { |
|
|
|
|
|
it.printf(116, 87, id(font1), COLOR_OFF, TextAlign::TOP_RIGHT, "comfort"); |
|
|
|
|
|
} else { |
|
|
|
|
|
it.printf(116, 87, id(font1), COLOR_OFF, TextAlign::TOP_RIGHT, "high"); |
|
|
} |
|
|
} |
|
|
it.printf(133, 21, id(font1), "Temp Out: %.1f°C", id(temperature_outside).state); |
|
|
// graphs |
|
|
if (id(iaq_accuracy).state == 3) { |
|
|
it.graph(0, 98, id(temperature_graph)); |
|
|
it.printf(133, 31, id(font1), "IAQ : %.0f ", id(iaq).state); |
|
|
it.graph(60, 98, id(humidity_graph)); |
|
|
if (id(iaq).state < 50) { |
|
|
it.graph(120, 98, id(pressure_graph)); |
|
|
it.printf(133, 41, id(font1), "excellent"); |
|
|
// voc |
|
|
} else if (id(iaq).state < 100) { |
|
|
it.circle(130, 42, 20); |
|
|
it.printf(133, 41, id(font1), "fine"); |
|
|
it.line(115, 42, 145, 42); |
|
|
} else if (id(iaq).state < 150) { |
|
|
it.filled_rectangle(130-10, 21, 20, 10, COLOR_OFF); |
|
|
it.printf(133, 41, id(font1), "moderate"); |
|
|
it.print(130, 26, id(font1), TextAlign::CENTER, "WZ"); |
|
|
} else if (id(iaq).state < 200) { |
|
|
if (id(iaq_accuracy_wz).state == 3) { |
|
|
it.printf(133, 41, id(font1), "poor"); |
|
|
it.printf(130, 41, id(font1), "%.0f ", id(iaq_wz).state); |
|
|
} else if (id(iaq).state < 300) { |
|
|
if (id(iaq_wz).state < 50) { |
|
|
it.printf(133, 41, id(font1), "very poor"); |
|
|
it.printf(130, 43, id(font1), TextAlign::TOP_CENTER, "excellent"); |
|
|
} else if (id(iaq).state < 500) { |
|
|
} else if (id(iaq_wz).state < 100) { |
|
|
it.printf(133, 41, id(font1), "severe"); |
|
|
it.printf(130, 43, id(font1), TextAlign::TOP_CENTER, "fine"); |
|
|
|
|
|
} else if (id(iaq_wz).state < 150) { |
|
|
|
|
|
it.printf(130, 43, id(font1), TextAlign::TOP_CENTER, "moderate"); |
|
|
|
|
|
} else if (id(iaq_wz).state < 200) { |
|
|
|
|
|
it.printf(130, 43, id(font1), TextAlign::TOP_CENTER, "poor"); |
|
|
|
|
|
} else if (id(iaq_wz).state < 300) { |
|
|
|
|
|
it.printf(130, 43, id(font1), TextAlign::TOP_CENTER, "very poor"); |
|
|
|
|
|
} else if (id(iaq_wz).state < 500) { |
|
|
|
|
|
it.printf(130, 43, id(font1), TextAlign::TOP_CENTER, "severe"); |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
it.printf(133, 31, id(font1), "VOC : %.1f k\u03A9", id(voc).state); |
|
|
it.printf(130, 41, id(font1), TextAlign::BASELINE_CENTER, "%.0f \u03A9", id(voc_wz).state); |
|
|
|
|
|
it.printf(130, 43, id(font1), TextAlign::TOP_CENTER, "VOC"); |
|
|
} |
|
|
} |
|
|
# it.printf(133, 21, id(font1), "PM2.5: %.1f", id(pm2).state); |
|
|
// voc2 |
|
|
# it.printf(133, 31, id(font1), "PM10 : %.1f", id(pm10).state); |
|
|
it.circle(175, 42, 20); |
|
|
# it.printf(133, 51, id(font1), "Lux : %.1f lx", id(lux).state); |
|
|
it.line(160, 42, 190, 42); |
|
|
# it.printf(133, 61, id(font1), "UVI : %.1f", id(uva).state); |
|
|
it.filled_rectangle(175-10, 21, 20, 10, COLOR_OFF); |
|
|
# it.printf(133, 71, id(font1), "UVA : %.1f", id(uva).state); |
|
|
it.print(175, 26, id(font1), TextAlign::CENTER, "SZ"); |
|
|
# it.printf(133, 81, id(font1), "UVB : %.1f", id(uvb).state); |
|
|
if (id(iaq_accuracy_sz).state == 3) { |
|
|
|
|
|
it.printf(175, 41, id(font1), "%.0f ", id(iaq_sz).state); |
|
|
|
|
|
if (id(iaq_sz).state < 50) { |
|
|
|
|
|
it.printf(175, 43, id(font1), TextAlign::TOP_CENTER, "excellent"); |
|
|
|
|
|
} else if (id(iaq_sz).state < 100) { |
|
|
|
|
|
it.printf(175, 43, id(font1), TextAlign::TOP_CENTER, "fine"); |
|
|
|
|
|
} else if (id(iaq_sz).state < 150) { |
|
|
|
|
|
it.printf(175, 43, id(font1), TextAlign::TOP_CENTER, "moderate"); |
|
|
|
|
|
} else if (id(iaq_sz).state < 200) { |
|
|
|
|
|
it.printf(175, 43, id(font1), TextAlign::TOP_CENTER, "poor"); |
|
|
|
|
|
} else if (id(iaq_sz).state < 300) { |
|
|
|
|
|
it.printf(175, 43, id(font1), TextAlign::TOP_CENTER, "very poor"); |
|
|
|
|
|
} else if (id(iaq_sz).state < 500) { |
|
|
|
|
|
it.printf(175, 43, id(font1), TextAlign::TOP_CENTER, "severe"); |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
it.printf(175, 41, id(font1), TextAlign::BASELINE_CENTER, "%.0f \u03A9", id(voc_sz).state); |
|
|
|
|
|
it.printf(175, 43, id(font1), TextAlign::TOP_CENTER, "VOC"); |
|
|
|
|
|
} |
|
|
|
|
|
// Particulate Matter Sensor |
|
|
|
|
|
it.circle(220, 42, 20); |
|
|
|
|
|
it.line(205, 42, 235, 42); |
|
|
|
|
|
it.filled_rectangle(220-10, 21, 20, 10, COLOR_OFF); |
|
|
|
|
|
it.print(220, 26, id(font1), TextAlign::CENTER, "PM"); |
|
|
|
|
|
it.printf(220, 41, id(font1), TextAlign::BASELINE_CENTER, "%.0f", id(pm2_outdoor).state); |
|
|
|
|
|
it.printf(220, 43, id(font1), TextAlign::TOP_CENTER, "%.0f", id(pm10_outdoor).state); |
|
|
|
|
|
// other values |
|
|
|
|
|
it.print(184, 65, id(font1), "Lux:"); it.printf(248, 65, id(font1), TextAlign::TOP_RIGHT, "%.0f lx", id(lux_outdoor).state); |
|
|
|
|
|
it.print(184, 75, id(font1), "UVI:"); it.printf(248, 75, id(font1), TextAlign::TOP_RIGHT, "%.0f", id(uvi_outdoor).state); |
|
|
|
|
|
it.print(184, 85, id(font1), "UVA:"); it.printf(248, 85, id(font1), TextAlign::TOP_RIGHT, "%.0f", id(uva_outdoor).state); |
|
|
|
|
|
it.print(184, 95, id(font1), "UVB:"); it.printf(248, 95, id(font1), TextAlign::TOP_RIGHT, "%.0f", id(uvb_outdoor).state); |
|
|
|
|
|
// Springer |
|
|
|
|
|
it.print(184, 105, id(font1), "Springer"); |
|
|
|
|
|
if (id(battery_springer).state >=0 && id(battery_springer).state <= 100) { |
|
|
|
|
|
it.printf(248, 105, id(font1), TextAlign::TOP_RIGHT, "%.0f%%", id(battery_springer).state); |
|
|
|
|
|
} |
|
|
|
|
|
it.printf(184,115, id(font1), "%.1f°C, %.1f%%H, %.0fhPa", id(temperature_springer).state, id(humidity_springer).state, id(pressure_springer).state); |
|
|
interval: |
|
|
interval: |
|
|
- interval: 30s |
|
|
- interval: 30s |
|
|
then: |
|
|
then: |
|
@ -125,33 +171,118 @@ graph: |
|
|
# Show bare-minimum auto-ranged graph |
|
|
# Show bare-minimum auto-ranged graph |
|
|
- id: temperature_graph |
|
|
- id: temperature_graph |
|
|
duration: 1h |
|
|
duration: 1h |
|
|
width: 60 |
|
|
width: 59 |
|
|
height: 35 |
|
|
height: 31 |
|
|
traces: |
|
|
traces: |
|
|
- sensor: temperature |
|
|
- sensor: temperature |
|
|
line_type: SOLID |
|
|
line_type: SOLID |
|
|
line_thickness: 2 |
|
|
line_thickness: 2 |
|
|
- sensor: temperature_outside |
|
|
# - sensor: temperature_outside |
|
|
line_type: DASHED |
|
|
# line_type: DASHED |
|
|
line_thickness: 1 |
|
|
# line_thickness: 1 |
|
|
- id: humidity_graph |
|
|
- id: humidity_graph |
|
|
sensor: humidity |
|
|
sensor: humidity |
|
|
duration: 1h |
|
|
duration: 1h |
|
|
width: 60 |
|
|
width: 59 |
|
|
height: 35 |
|
|
height: 31 |
|
|
- id: pressure_graph |
|
|
- id: pressure_graph |
|
|
sensor: pressure |
|
|
sensor: pressure |
|
|
duration: 1h |
|
|
duration: 1h |
|
|
width: 60 |
|
|
width: 59 |
|
|
height: 35 |
|
|
height: 31 |
|
|
|
|
|
|
|
|
# Example configuration entry |
|
|
# Example configuration entry |
|
|
sensor: |
|
|
sensor: |
|
|
- platform: homeassistant |
|
|
- platform: homeassistant |
|
|
name: "Temperature OpenWeatherMap" |
|
|
name: "Temperature Outdoor" |
|
|
internal: true |
|
|
internal: true |
|
|
entity_id: sensor.openweathermap_temperature |
|
|
entity_id: sensor.sensor_outdoor_temperature |
|
|
id: temperature_outside |
|
|
id: temperature_outside |
|
|
|
|
|
- platform: homeassistant |
|
|
|
|
|
name: "Humidity Outdoor" |
|
|
|
|
|
internal: true |
|
|
|
|
|
entity_id: sensor.sensor_outdoor_humidity |
|
|
|
|
|
id: humidity_outside |
|
|
|
|
|
- platform: homeassistant |
|
|
|
|
|
name: "WZ VOC" |
|
|
|
|
|
internal: true |
|
|
|
|
|
entity_id: sensor.sensor_wz_gas_resistance |
|
|
|
|
|
id: voc_wz |
|
|
|
|
|
- platform: homeassistant |
|
|
|
|
|
name: "SZ VOC" |
|
|
|
|
|
internal: true |
|
|
|
|
|
entity_id: sensor.sensor_sz_gas_resistance |
|
|
|
|
|
id: voc_sz |
|
|
|
|
|
- platform: homeassistant |
|
|
|
|
|
name: "WZ IAQ" |
|
|
|
|
|
internal: true |
|
|
|
|
|
entity_id: sensor.sensor_wz_iaq |
|
|
|
|
|
id: iaq_wz |
|
|
|
|
|
- platform: homeassistant |
|
|
|
|
|
name: "SZ IAQ" |
|
|
|
|
|
internal: true |
|
|
|
|
|
entity_id: sensor.sensor_sz_iaq |
|
|
|
|
|
id: iaq_sz |
|
|
|
|
|
- platform: homeassistant |
|
|
|
|
|
name: "WZ IAQ Accuracy" |
|
|
|
|
|
internal: true |
|
|
|
|
|
entity_id: sensor.sensor_wz_iaq_accuracy |
|
|
|
|
|
id: iaq_accuracy_wz |
|
|
|
|
|
- platform: homeassistant |
|
|
|
|
|
name: "SZ IAQ Accuracy" |
|
|
|
|
|
internal: true |
|
|
|
|
|
entity_id: sensor.sensor_sz_iaq_accuracy |
|
|
|
|
|
id: iaq_accuracy_sz |
|
|
|
|
|
- platform: homeassistant |
|
|
|
|
|
name: "PM2.5 Outdoor" |
|
|
|
|
|
internal: true |
|
|
|
|
|
entity_id: sensor.sensor_outdoor_particulate_matter_2_5um_concentration |
|
|
|
|
|
id: pm2_outdoor |
|
|
|
|
|
- platform: homeassistant |
|
|
|
|
|
name: "PM10 Outdoor" |
|
|
|
|
|
internal: true |
|
|
|
|
|
entity_id: sensor.sensor_outdoor_particulate_matter_10_0um_concentration |
|
|
|
|
|
id: pm10_outdoor |
|
|
|
|
|
- platform: homeassistant |
|
|
|
|
|
name: "UVI Outdoor" |
|
|
|
|
|
internal: true |
|
|
|
|
|
entity_id: sensor.sensor_outdoor_uvi |
|
|
|
|
|
id: uvi_outdoor |
|
|
|
|
|
- platform: homeassistant |
|
|
|
|
|
name: "UVA Outdoor" |
|
|
|
|
|
internal: true |
|
|
|
|
|
entity_id: sensor.sensor_outdoor_uva |
|
|
|
|
|
id: uva_outdoor |
|
|
|
|
|
- platform: homeassistant |
|
|
|
|
|
name: "UVB Outdoor" |
|
|
|
|
|
internal: true |
|
|
|
|
|
entity_id: sensor.sensor_outdoor_uvb |
|
|
|
|
|
id: uvb_outdoor |
|
|
|
|
|
- platform: homeassistant |
|
|
|
|
|
name: "Illuminance Outdoor" |
|
|
|
|
|
internal: true |
|
|
|
|
|
entity_id: sensor.sensor_outdoor_illuminance |
|
|
|
|
|
id: lux_outdoor |
|
|
|
|
|
- platform: homeassistant |
|
|
|
|
|
name: "Temperature Springer" |
|
|
|
|
|
internal: true |
|
|
|
|
|
entity_id: sensor.sensor_springer_temperature |
|
|
|
|
|
id: temperature_springer |
|
|
|
|
|
- platform: homeassistant |
|
|
|
|
|
name: "Humidity Springer" |
|
|
|
|
|
internal: true |
|
|
|
|
|
entity_id: sensor.sensor_springer_humidity |
|
|
|
|
|
id: humidity_springer |
|
|
|
|
|
- platform: homeassistant |
|
|
|
|
|
name: "Pressure Springer" |
|
|
|
|
|
internal: true |
|
|
|
|
|
entity_id: sensor.sensor_springer_equivalent_sea_level_pressure |
|
|
|
|
|
id: pressure_springer |
|
|
|
|
|
- platform: homeassistant |
|
|
|
|
|
name: "Battery Springer" |
|
|
|
|
|
internal: true |
|
|
|
|
|
entity_id: sensor.sensor_springer_battery_level |
|
|
|
|
|
id: battery_springer |
|
|
|
|
|
|
|
|
text_sensor: |
|
|
text_sensor: |
|
|
- platform: homeassistant |
|
|
- platform: homeassistant |
|
|