├── basis33.ttf ├── README.md └── esp32clock.yaml /basis33.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/voed/esphome_max7219_clock/HEAD/basis33.ttf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![image](https://user-images.githubusercontent.com/10352360/233438084-2bcc4734-9a6a-43cb-a728-e5152f3688c9.png) 2 | 3 | 4 | Clock configuration with max7219digit and max7219 7-segment SPI displays with brightness correction during night time. 5 | 6 | 7 | ### Night mode 8 | Night mode is used to reduce brightness during night time. It based on Home Assistant's scheduler(Settings - Devices and services - Helpers tab) 9 | ``` yaml 10 | binary_sensor: 11 | - platform: homeassistant 12 | id: clock_night_mode 13 | entity_id: schedule.clock_night_mode 14 | ``` 15 | 16 | ### Main display 17 | The main MAX7219 4-matrix display is used to display the time from SNTP server. It uses pixel font `basis33`. If you are using ESPHome dashboard as a Home Assistant addon, place it to the `config\esphome\fonts` of Home Assistant. More info in [ESPHome docs](https://esphome.io/components/display/index.html?highlight=font#fonts) 18 | ```yaml 19 | font: 20 | - file: "fonts/basis33.ttf" 21 | id: digit_font 22 | size: 16 23 | glyphs: "0123456789 " 24 | - file: "fonts/basis33.ttf" 25 | id: digit_font15 26 | size: 15 27 | glyphs: ": ." 28 | 29 | display: 30 | - platform: max7219digit 31 | cs_pin: GPIO25 32 | num_chips: 4 33 | intensity: 0 34 | rotate_chip: 180 35 | reverse_enable: true 36 | lambda: |- 37 | if(!id(time_sync_done)) 38 | { 39 | it.print(0, 5, id(digit_font15), ". . . . . . ."); 40 | it.invert_on_off(true); 41 | return; 42 | } 43 | it.invert_on_off(false); 44 | auto time = id(sntp_time).now(); 45 | bool is_night_mode = id(clock_night_mode).state; 46 | static int clock_should_blink = true; 47 | it.intensity(is_night_mode ? 0 : 5); 48 | 49 | it.strftime(0, 5, id(digit_font), TextAlign::CENTER_LEFT, "%H", time); 50 | 51 | if(is_night_mode || clock_should_blink) 52 | { 53 | it.strftime(12, 4, id(digit_font15), TextAlign::CENTER_LEFT, ":", time); 54 | } 55 | it.strftime(17, 5, id(digit_font), TextAlign::CENTER_LEFT, "%M", time); 56 | clock_should_blink = !clock_should_blink; 57 | 58 | ``` 59 | 60 | ### Secondary display 61 | 7-segment display is used to display indoor/outdoor temperatures from Home Assistant sensors 62 | 63 | ```yaml 64 | - platform: max7219 65 | cs_pin: GPIO4 66 | num_chips: 5 # 5 because it is on the same SPI bus with max7219digit 67 | intensity: 0 68 | update_interval: 1.5s 69 | lambda: |- 70 | static bool temp_outside = true; 71 | static int temp_mode_time = 0; 72 | auto sens = temp_outside ? id(outside_temp) : id(cgdk2_temperature); 73 | char text[7] = " --"; 74 | 75 | if(!isnan(sens->state)) 76 | { 77 | sprintf(text, "%5.1f", sens->state); 78 | } 79 | 80 | it.set_intensity(id(clock_night_mode).state ? 0 : 5); 81 | if(temp_outside) 82 | it.printf(0, " o%2s", text); //#show outside temp 83 | else 84 | it.printf(0, " h%2s", text); //#show room temp 85 | 86 | if(temp_mode_time > 2)//#switch to inside/outside sensor 87 | { 88 | temp_outside = !temp_outside; 89 | temp_mode_time = 0; 90 | } 91 | temp_mode_time++; 92 | 93 | ``` 94 | -------------------------------------------------------------------------------- /esp32clock.yaml: -------------------------------------------------------------------------------- 1 | substitutions: 2 | device_name: esp32clock 3 | esphome: 4 | name: ${device_name} 5 | 6 | esp32: 7 | board: wemos_d1_mini32 8 | framework: 9 | type: arduino 10 | 11 | 12 | globals: 13 | id: time_sync_done 14 | type: bool 15 | 16 | # Enable Home Assistant API 17 | api: 18 | encryption: 19 | key: !secret encryption_key 20 | 21 | ota: 22 | password: !secret ota_password 23 | 24 | wifi: 25 | ssid: !secret wifi_ssid 26 | password: !secret wifi_password 27 | fast_connect: true 28 | # Enable fallback hotspot (captive portal) in case wifi connection fails 29 | ap: 30 | ssid: ${device_name} 31 | password: !secret wifi_password 32 | 33 | captive_portal: 34 | 35 | binary_sensor: 36 | - platform: homeassistant 37 | id: clock_night_mode 38 | entity_id: schedule.clock_night_mode 39 | 40 | sensor: 41 | - platform: homeassistant 42 | id: cgdk2_temperature 43 | entity_id: "sensor.cgdk2guest_d32d_temperature" 44 | - platform: homeassistant 45 | id: outside_temp 46 | entity_id: "sensor.outside_temp" 47 | 48 | font: 49 | - file: "fonts/basis33.ttf" 50 | id: digit_font 51 | size: 16 52 | glyphs: "0123456789 " 53 | - file: "fonts/basis33.ttf" 54 | id: digit_font15 55 | size: 15 56 | glyphs: ": ." 57 | 58 | spi: 59 | clk_pin: GPIO27 60 | mosi_pin: GPIO32 61 | 62 | 63 | time: 64 | - platform: sntp 65 | id: sntp_time 66 | on_time_sync: 67 | then: 68 | lambda: |- 69 | id(time_sync_done) = true; 70 | 71 | 72 | display: 73 | - platform: max7219digit 74 | cs_pin: GPIO25 75 | num_chips: 4 76 | intensity: 0 77 | rotate_chip: 180 78 | reverse_enable: true 79 | lambda: |- 80 | if(!id(time_sync_done)) 81 | { 82 | it.print(0, 5, id(digit_font15), ". . . . . . ."); 83 | it.invert_on_off(true); 84 | return; 85 | } 86 | it.invert_on_off(false); 87 | auto time = id(sntp_time).now(); 88 | bool is_night_mode = id(clock_night_mode).state; 89 | static int clock_should_blink = true; 90 | it.intensity(is_night_mode ? 0 : 5); 91 | 92 | it.strftime(0, 5, id(digit_font), TextAlign::CENTER_LEFT, "%H", time); 93 | 94 | if(is_night_mode || clock_should_blink) 95 | { 96 | it.strftime(12, 4, id(digit_font15), TextAlign::CENTER_LEFT, ":", time); 97 | } 98 | it.strftime(17, 5, id(digit_font), TextAlign::CENTER_LEFT, "%M", time); 99 | clock_should_blink = !clock_should_blink; 100 | 101 | - platform: max7219 102 | cs_pin: GPIO4 103 | num_chips: 5 # 5 because it is on the same SPI bus with max7219digit 104 | intensity: 0 105 | update_interval: 1.5s 106 | lambda: |- 107 | static bool temp_outside = true; 108 | static int temp_mode_time = 0; 109 | auto sens = temp_outside ? id(outside_temp) : id(cgdk2_temperature); 110 | char text[7] = " --"; 111 | 112 | if(!isnan(sens->state)) 113 | { 114 | sprintf(text, "%5.1f", sens->state); 115 | } 116 | 117 | it.set_intensity(id(clock_night_mode).state ? 0 : 5); 118 | if(temp_outside) 119 | it.printf(0, " o%2s", text); //#show outside temp 120 | else 121 | it.printf(0, " h%2s", text); //#show room temp 122 | 123 | if(temp_mode_time > 2)//#switch to inside/outside sensor 124 | { 125 | temp_outside = !temp_outside; 126 | temp_mode_time = 0; 127 | } 128 | temp_mode_time++; 129 | 130 | 131 | external_components: 132 | - source: github://voed/esphome@dev 133 | components: [ max7219digit ] 134 | 135 | --------------------------------------------------------------------------------