Guest User

Untitled

a guest
Jan 12th, 2023
1,617
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.09 KB | None | 0 0
  1. # WEATHERMAN DASHBOARD
  2. # For Home Assistant and ESPHome
  3. # Designed by Madelena Mak 2022 - https://mmak.es
  4.  
  5. # Cue "Blame it on the Weatherman" by B*Witched!
  6. esphome:
  7. name: "weatherman"
  8. on_boot:
  9. priority: 200.0
  10. then:
  11. - component.update: eink_display
  12. - wait_until:
  13. condition:
  14. lambda: 'return id(data_updated) == true;'
  15. # Wait a bit longer so all the items are received
  16. - delay: 5s
  17. - logger.log: "Initial sensor data received: Refreshing display..."
  18. - lambda: 'id(initial_data_received) = true;'
  19. - script.execute: update_screen
  20.  
  21. esp32:
  22. board: esp32dev
  23. framework:
  24. type: arduino
  25.  
  26. # Enable logging
  27. logger:
  28.  
  29. # Enable Home Assistant API
  30. api:
  31.  
  32. ota:
  33.  
  34. button:
  35. - platform: shutdown
  36. name: "Weatherman - Shutdown"
  37. - platform: restart
  38. name: "Weatherman - Restart"
  39. - platform: template
  40. name: "Weatherman - Refresh Screen"
  41. entity_category: config
  42. on_press:
  43. - script.execute: update_screen
  44.  
  45.  
  46. # Global variables for detecting if the display needs to be refreshed. (Thanks @paviro!)
  47. globals:
  48. - id: data_updated
  49. type: bool
  50. restore_value: no
  51. initial_value: 'false'
  52. - id: initial_data_received
  53. type: bool
  54. restore_value: no
  55. initial_value: 'false'
  56. - id: recorded_display_refresh
  57. type: int
  58. restore_value: yes
  59. initial_value: '0'
  60.  
  61. # Script for updating screen - Refresh display and publish refresh count and time. (Thanks @paviro!)
  62. script:
  63. - id: update_screen
  64. then:
  65. - lambda: 'id(data_updated) = false;'
  66. - component.update: eink_display
  67. - lambda: 'id(recorded_display_refresh) += 1;'
  68. - lambda: 'id(display_last_update).publish_state(id(homeassistant_time).now().timestamp);'
  69.  
  70.  
  71. # Check whether the display needs to be refreshed every minute,
  72. # based on whether new data is received or motion is detected. (Thanks @paviro!)
  73. time:
  74. - platform: homeassistant
  75. id: homeassistant_time
  76. on_time:
  77. - seconds: 0
  78. minutes: /1
  79. then:
  80. - if:
  81. condition:
  82. lambda: 'return id(data_updated) == true;'
  83. then:
  84. - if:
  85. condition:
  86. binary_sensor.is_on: motion_detected
  87. then:
  88. - logger.log: "Sensor data updated and activity in home detected: Refreshing display..."
  89. - script.execute: update_screen
  90. else:
  91. - logger.log: "Sensor data updated but no activity in home - skipping display refresh."
  92. else:
  93. - logger.log: "No sensors updated - skipping display refresh."
  94.  
  95.  
  96. # Wifi information
  97. wifi:
  98. ssid: !secret wifi_ssid
  99. password: !secret wifi_password
  100.  
  101. # Enable fallback hotspot (captive portal) in case wifi connection fails
  102. ap:
  103. ssid: "Esphome-Web-901078"
  104. password: "2JOrpBYEHQsV"
  105.  
  106.  
  107. # Include custom fonts
  108. font:
  109. - file: 'fonts/GothamRnd-Book.ttf'
  110. id: font_small_book
  111. size: 18
  112. glyphs: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'X', 'Y', 'Z', 'Å', 'Ä', 'Ö', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', '-', ' ', '°', '.']
  113. - file: 'fonts/GothamRnd-Bold.ttf'
  114. id: font_large_bold
  115. size: 108
  116. glyphs: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'X', 'Y', 'Z', 'Å', 'Ä', 'Ö', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', '-', ' ', '°', '.']
  117. - file: 'fonts/GothamRnd-Bold.ttf'
  118. id: font_title
  119. size: 54
  120. glyphs: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'X', 'Y', 'Z', 'Å', 'Ä', 'Ö', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', '-', ' ', '°', '.']
  121. - file: 'fonts/GothamRnd-Bold.ttf'
  122. id: font_medium_bold
  123. size: 30
  124. glyphs: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'X', 'Y', 'Z', 'Å', 'Ä', 'Ö', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', '-', ' ', '°', '.']
  125. - file: 'fonts/GothamRnd-Bold.ttf'
  126. id: font_small_bold
  127. size: 18
  128. glyphs: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'X', 'Y', 'Z', 'Å', 'Ä', 'Ö', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', '-', ' ', '°', '.']
  129.  
  130.  
  131. # Include Material Design Icons font
  132. # Thanks to https://community.home-assistant.io/t/display-materialdesign-icons-on-esphome-attached-to-screen/199790/16
  133. - file: 'fonts/materialdesignicons-webfont.ttf'
  134. id: font_mdi_large
  135. size: 96
  136. glyphs: &mdi-weather-glyphs
  137. - "\U000F0590" # mdi-weather-cloudy
  138. - "\U000F0F2F" # mdi-weather-cloudy-alert
  139. - "\U000F0E6E" # mdi-weather-cloudy-arrow-right
  140. - "\U000F0591" # mdi-weather-fog
  141. - "\U000F0592" # mdi-weather-hail
  142. - "\U000F0F30" # mdi-weather-hazy
  143. - "\U000F0898" # mdi-weather-hurricane
  144. - "\U000F0593" # mdi-weather-lightning
  145. - "\U000F067E" # mdi-weather-lightning-rainy
  146. - "\U000F0594" # mdi-weather-night
  147. - "\U000F0F31" # mdi-weather-night-partly-cloudy
  148. - "\U000F0595" # mdi-weather-partly-cloudy
  149. - "\U000F0F32" # mdi-weather-partly-lightning
  150. - "\U000F0F33" # mdi-weather-partly-rainy
  151. - "\U000F0F34" # mdi-weather-partly-snowy
  152. - "\U000F0F35" # mdi-weather-partly-snowy-rainy
  153. - "\U000F0596" # mdi-weather-pouring
  154. - "\U000F0597" # mdi-weather-rainy
  155. - "\U000F0598" # mdi-weather-snowy
  156. - "\U000F0F36" # mdi-weather-snowy-heavy
  157. - "\U000F067F" # mdi-weather-snowy-rainy
  158. - "\U000F0599" # mdi-weather-sunny
  159. - "\U000F0F37" # mdi-weather-sunny-alert
  160. - "\U000F14E4" # mdi-weather-sunny-off
  161. - "\U000F059A" # mdi-weather-sunset
  162. - "\U000F059B" # mdi-weather-sunset-down
  163. - "\U000F059C" # mdi-weather-sunset-up
  164. - "\U000F0F38" # mdi-weather-tornado
  165. - "\U000F059D" # mdi-weather-windy
  166. - "\U000F059E" # mdi-weather-windy-variant
  167. - "\U000F1508" # mdi-water-off-outline
  168. - "\U000F0E0A" # mdi-water-outline
  169. - "\U000F1503" # mdi-water-alert-outline
  170. - "\U000F081D" # mdi-fan-off
  171. - "\U000F1B5A" # mdi-weather-dust
  172. - "\U000F02D6" # mdi-help
  173. - "\U000F0717" # mdi-snowflake
  174. - "\U000F0F29" # mdi-snowflake-alert
  175.  
  176. - file: 'fonts/materialdesignicons-webfont.ttf'
  177. id: font_mdi_medium
  178. size: 36
  179. glyphs: *mdi-weather-glyphs
  180.  
  181.  
  182. # Include Custom Titles
  183. # image:
  184. # - file: "images/weatherman-title-train.png"
  185. # id: title_train
  186. # type: BINARY
  187. # - file: "images/weatherman-title-weather.png"
  188. # id: title_weather
  189. # type: BINARY
  190.  
  191.  
  192. # Check if motion is detected in the living room.
  193. binary_sensor:
  194. - platform: homeassistant
  195. entity_id: binary_sensor.weatherman_motion_detected
  196. id: motion_detected
  197.  
  198. sensor:
  199.  
  200. # Create sensors for monitoring Weatherman remotely.
  201. - platform: template
  202. name: "Weatherman - Display Last Update"
  203. device_class: timestamp
  204. entity_category: "diagnostic"
  205. id: display_last_update
  206.  
  207. - platform: template
  208. name: "Weatherman - Recorded Display Refresh"
  209. accuracy_decimals: 0
  210. unit_of_measurement: "Refreshes"
  211. state_class: "total_increasing"
  212. entity_category: "diagnostic"
  213. lambda: 'return id(recorded_display_refresh);'
  214.  
  215. - platform: wifi_signal
  216. name: "WiFi Signal Sensor"
  217. id: wifisignal
  218. update_interval: 60s
  219.  
  220. - platform: homeassistant
  221. entity_id: sensor.weatherman_data
  222. attribute: weather_temperature_now
  223. id: weather_temperature_now
  224. on_value:
  225. then:
  226. - lambda: 'id(data_updated) = true;'
  227.  
  228. - platform: homeassistant
  229. entity_id: sensor.weatherman_data
  230. attribute: weather_temperature_0
  231. id: weather_temperature_0
  232. on_value:
  233. then:
  234. - lambda: 'id(data_updated) = true;'
  235.  
  236. - platform: homeassistant
  237. entity_id: sensor.weatherman_data
  238. attribute: weather_temperature_1
  239. id: weather_temperature_1
  240. on_value:
  241. then:
  242. - lambda: 'id(data_updated) = true;'
  243.  
  244. - platform: homeassistant
  245. entity_id: sensor.weatherman_data
  246. attribute: weather_temperature_2
  247. id: weather_temperature_2
  248. on_value:
  249. then:
  250. - lambda: 'id(data_updated) = true;'
  251.  
  252. - platform: homeassistant
  253. entity_id: sensor.weatherman_data
  254. attribute: weather_temperature_3
  255. id: weather_temperature_3
  256. on_value:
  257. then:
  258. - lambda: 'id(data_updated) = true;'
  259.  
  260. text_sensor:
  261.  
  262. - platform: homeassistant
  263. entity_id: sensor.weatherman_data
  264. attribute: finn_mossen_arrive
  265. id: finn_mossen_arrive
  266. on_value:
  267. then:
  268. - lambda: 'id(data_updated) = true;'
  269.  
  270. - platform: homeassistant
  271. entity_id: sensor.weatherman_data
  272. attribute: finn_mossen_depart
  273. id: finn_mossen_depart
  274. on_value:
  275. then:
  276. - lambda: 'id(data_updated) = true;'
  277.  
  278. - platform: homeassistant
  279. entity_id: sensor.weatherman_data
  280. attribute: finn_mossen_weekday
  281. id: finn_mossen_weekday
  282. on_value:
  283. then:
  284. - lambda: 'id(data_updated) = true;'
  285.  
  286. - platform: homeassistant
  287. entity_id: sensor.weatherman_data
  288. attribute: weather_condition_now
  289. id: weather_condition_now
  290. on_value:
  291. then:
  292. - lambda: 'id(data_updated) = true;'
  293.  
  294. - platform: homeassistant
  295. entity_id: sensor.weatherman_data
  296. attribute: weather_wind_today
  297. id: weather_wind_today
  298. on_value:
  299. then:
  300. - lambda: 'id(data_updated) = true;'
  301.  
  302. - platform: homeassistant
  303. entity_id: sensor.weatherman_data
  304. attribute: weather_rain_today
  305. id: weather_rain_today
  306. on_value:
  307. then:
  308. - lambda: 'id(data_updated) = true;'
  309.  
  310. - platform: homeassistant
  311. entity_id: sensor.weatherman_data
  312. attribute: weather_condition_0
  313. id: weather_condition_0
  314. on_value:
  315. then:
  316. - lambda: 'id(data_updated) = true;'
  317. - platform: homeassistant
  318. entity_id: sensor.weatherman_data
  319. attribute: weather_timestamp_0
  320. id: weather_timestamp_0
  321.  
  322. - platform: homeassistant
  323. entity_id: sensor.weatherman_data
  324. attribute: weather_condition_1
  325. id: weather_condition_1
  326. on_value:
  327. then:
  328. - lambda: 'id(data_updated) = true;'
  329. - platform: homeassistant
  330. entity_id: sensor.weatherman_data
  331. attribute: weather_timestamp_1
  332. id: weather_timestamp_1
  333. on_value:
  334. then:
  335. - lambda: 'id(data_updated) = true;'
  336. - platform: homeassistant
  337. entity_id: sensor.weatherman_data
  338. attribute: weather_condition_2
  339. id: weather_condition_2
  340. on_value:
  341. then:
  342. - lambda: 'id(data_updated) = true;'
  343. - platform: homeassistant
  344. entity_id: sensor.weatherman_data
  345. attribute: weather_timestamp_2
  346. id: weather_timestamp_2
  347. on_value:
  348. then:
  349. - lambda: 'id(data_updated) = true;'
  350. - platform: homeassistant
  351. entity_id: sensor.weatherman_data
  352. attribute: weather_condition_3
  353. id: weather_condition_3
  354. on_value:
  355. then:
  356. - lambda: 'id(data_updated) = true;'
  357. - platform: homeassistant
  358. entity_id: sensor.weatherman_data
  359. attribute: weather_timestamp_3
  360. id: weather_timestamp_3
  361. on_value:
  362. then:
  363. - lambda: 'id(data_updated) = true;'
  364.  
  365. - platform: homeassistant
  366. entity_id: sensor.time
  367. id: update_time
  368.  
  369. # Pins for Waveshare ePaper ESP Board
  370. spi:
  371. clk_pin: GPIO13
  372. mosi_pin: GPIO14
  373.  
  374.  
  375. # Now render everything on the ePaper screen.
  376. display:
  377. - platform: waveshare_epaper
  378. id: eink_display
  379. cs_pin: GPIO15
  380. dc_pin: GPIO27
  381. busy_pin: GPIO25
  382. reset_pin: GPIO26
  383. reset_duration: 2ms
  384. model: 7.50inV2
  385. update_interval: never
  386. rotation: 270°
  387. lambda: |-
  388. // Map weather states to MDI characters.
  389. std::map<std::string, std::string> weather_icon_map
  390. {
  391. {"cloudy", "\U000F0590"},
  392. {"cloudy-alert", "\U000F0F2F"},
  393. {"cloudy-arrow-right", "\U000F0E6E"},
  394. {"fog", "\U000F0591"},
  395. {"hail", "\U000F0592"},
  396. {"hazy", "\U000F0F30"},
  397. {"hurricane", "\U000F0898"},
  398. {"lightning", "\U000F0593"},
  399. {"lightning-rainy", "\U000F067E"},
  400. {"night", "\U000F0594"},
  401. {"night-partly-cloudy", "\U000F0F31"},
  402. {"partlycloudy", "\U000F0595"},
  403. {"partly-lightning", "\U000F0F32"},
  404. {"partly-rainy", "\U000F0F33"},
  405. {"partly-snowy", "\U000F0F34"},
  406. {"partly-snowy-rainy", "\U000F0F35"},
  407. {"pouring", "\U000F0596"},
  408. {"rainy", "\U000F0597"},
  409. {"snowy", "\U000F0598"},
  410. {"snowy-heavy", "\U000F0F36"},
  411. {"snowy-rainy", "\U000F067F"},
  412. {"sunny", "\U000F0599"},
  413. {"sunny-alert", "\U000F0F37"},
  414. {"sunny-off", "\U000F14E4"},
  415. {"sunset", "\U000F059A"},
  416. {"sunset-down", "\U000F059B"},
  417. {"sunset-up", "\U000F059C"},
  418. {"tornado", "\U000F0F38"},
  419. {"windy", "\U000F059D"},
  420. {"windy-variant", "\U000F059E"},
  421. {"fan-off", "\U000F081D"},
  422. {"weather-windy", "\U000F059D"},
  423. {"weather-hurricane", "\U000F0898"},
  424. {"weather-dust", "\U000F1B5A"},
  425. {"help", "\U000F02D6"},
  426. {"water-off-outline", "\U000F1508"},
  427. {"water-outline", "\U000F0E0A"},
  428. {"water-alert-outline", "\U000F1503"},
  429. {"snowflake", "\U000F0717"},
  430. {"snowflake-alert", "\U000F0F29"},
  431. };
  432.  
  433. // Show loading screen before data is received.
  434. if (id(initial_data_received) == false) {
  435. it.printf(240, 390, id(font_small_bold), TextAlign::TOP_CENTER, "VÄNTAR PÅ DATA...");
  436. } else {
  437.  
  438. // Weather Section
  439. // it.image(0, 88, id(title_weather));
  440. it.printf(240, 84, id(font_title), TextAlign::TOP_CENTER, "VÄDER");
  441.  
  442. it.printf(100, 158, id(font_mdi_large), TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_now).state.c_str()].c_str());
  443.  
  444. it.printf(300, 158, id(font_large_bold), TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_now).state);
  445.  
  446. it.printf(150, 275, id(font_mdi_medium), TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_wind_today).state.c_str()].c_str());
  447. it.printf(330, 275, id(font_mdi_medium), TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_rain_today).state.c_str()].c_str());
  448.  
  449.  
  450. it.printf(105, 332, id(font_small_book), TextAlign::TOP_CENTER, "%s", id(weather_timestamp_0).state.c_str());
  451. it.printf(105, 356, id(font_mdi_medium), TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_0).state.c_str()].c_str());
  452. it.printf(105, 404, id(font_small_bold), TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_0).state);
  453.  
  454. it.printf(195, 332, id(font_small_book), TextAlign::TOP_CENTER, "%s", id(weather_timestamp_1).state.c_str());
  455. it.printf(195, 356, id(font_mdi_medium), TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_1).state.c_str()].c_str());
  456. it.printf(195, 404, id(font_small_bold), TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_1).state);
  457.  
  458. it.printf(285, 332, id(font_small_book), TextAlign::TOP_CENTER, "%s", id(weather_timestamp_2).state.c_str());
  459. it.printf(285, 356, id(font_mdi_medium), TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_2).state.c_str()].c_str());
  460. it.printf(285, 404, id(font_small_bold), TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_2).state);
  461.  
  462. it.printf(375, 332, id(font_small_book), TextAlign::TOP_CENTER, "%s", id(weather_timestamp_3).state.c_str());
  463. it.printf(375, 356, id(font_mdi_medium), TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_3).state.c_str()].c_str());
  464. it.printf(375, 404, id(font_small_bold), TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_3).state);
  465.  
  466. // Train Service Section
  467. // it.image(0, 470, id(title_train));
  468. it.printf(240, 458, id(font_title), TextAlign::TOP_CENTER, "FINN");
  469. it.printf(240, 532, id(font_small_bold), TextAlign::TOP_CENTER, "%s", id(finn_mossen_weekday).state.c_str());
  470.  
  471. it.print(150, 558, id(font_small_bold), TextAlign::TOP_CENTER, "LÄMNA");
  472. it.printf(150, 584, id(font_small_book), TextAlign::TOP_CENTER, "%s", id(finn_mossen_arrive).state.c_str());
  473. it.print(330, 558, id(font_small_bold), TextAlign::TOP_CENTER, "HÄMTA");
  474. it.printf(330, 584, id(font_small_book), TextAlign::TOP_CENTER, "%s", id(finn_mossen_depart).state.c_str());
  475.  
  476.  
  477. it.printf(240, 665, id(font_small_book), TextAlign::TOP_CENTER, "SENAST UPPDATERAD:", id(update_time).state.c_str());
  478. }
  479.  
  480. captive_portal:
  481.  
Advertisement
Add Comment
Please, Sign In to add comment