在 OLED 显示屏上显示时间与温度

Image

在这个示例中,我使用了 通过 I²C 的 SSD1306 OLED 显示屏 来显示当前时间和从 Home Assistant 获取的两个不同的温度值。

ESPHome 支持多种不同类型的显示屏。这里使用的显示屏是 1.3 英寸,具有 128x64 单色像素(SH1106 128x64)。

硬件配置

硬件很简单!只需要四个连接:

  • VCC - 电源(我的显示屏可以使用 3.3V 或 5V)
  • GND - 接地
  • SDA - 串行数据
  • SCL - 串行时钟

⚠️ Warning

如果使用 5V,请确保您的显示屏可以处理 5V。

软件配置

获取时间

从 Home Assistant 获取时间以同步板载实时时钟。

time:
  - platform: homeassistant
    id: esptime

获取温度

接下来,我们希望获取一个温度传感器和从 Home Assistant 导入的 天气预报

我将它们命名为 inside_temperatureoutside_temperature。稍后您将使用这些引用。

通过在传感器中添加 internal: true,它们将不会被发布回 Home Assistant。

sensor:
  - platform: homeassistant
    id: inside_temperature
    entity_id: REPLACEME
    internal: true

  - platform: homeassistant
    id: outside_temperature
    entity_id: REPLACEME
    internal: true

text_sensor:
  - platform: homeassistant
    id: outside_temperature_unit
    entity_id: REPLACEME
    attribute: temperature_unit
    internal: true

定义字体

  • 使用 TrueType 字体。如果您曾经在小控制器上使用过字体,您将爱上这个!
  • 将字体文件保存在 /config/esphome 文件夹中,您的 ESPHome 配置存储在此处。
  • .ttf 后缀必须是小写的,当然,必须与您的文件名匹配。
  • 对于小尺寸的字体选择可能会有些棘手,看起来好看。尝试并分享您的发现到下面的评论中!
font:
  - file: 'slkscr.ttf'
    id: small
    size: 8

  - file: 'BebasNeue-Regular.ttf'
    id: medium
    size: 48

  - file: 'arial.ttf'
    id: large
    size: 14
  • (可选)您也可以使用 Google 字体,而不是包含字体文件,使用 gfonts:// 方案。
  • 更多信息请参考 Font Renderer Component 文档。
font:
  - file: "gfonts://Silkscreen"
    id: small
    size: 10
  - file: "gfonts://Roboto"
    id: large
    size: 24
  - file: "gfonts://Silkscreen"
    id: medium
    size: 15

显示屏定义

现在设置与显示屏的通信,并开始用实时数据填充屏幕!

在我的硬件配置中未使用 reset_pin,因为显示屏没有暴露这个引脚。

注意您的 addressmodel 可能不同,使用扫描选项来找到您的显示屏的地址。

i2c:
  sda: GPIOXX
  scl: GPIOXX
  scan: false
  # 手动设置更高的频率可以避免长组件更新
  # frequency: 300kHz

display:
  - platform: ssd1306_i2c
    model: "SH1106 128x64"
    reset_pin: GPIOXX
    address: 0x3C
    lambda: |-
      it.printf(0, 0, id(small), TextAlign::TOP_LEFT, "Time and");
      it.printf(0, 12, id(small), TextAlign::TOP_LEFT, "Temperature");

      // 以 HH:MM 格式打印时间
      it.strftime(0, 60, id(large), TextAlign::BASELINE_LEFT, "%H:%M", id(esptime).now());

      // 打印室内温度(来自 Home Assistant 传感器)
      if (id(inside_temperature).has_state()) {
        it.printf(127, 23, id(medium), TextAlign::TOP_RIGHT , "%.1f", id(inside_temperature).state);
      }

      // 打印室外温度(来自 Home Assistant 天气)
      if (id(outside_temperature).has_state()) {
        it.printf(127, 60, id(medium), TextAlign::BASELINE_RIGHT , "%.1f%s",
                  id(outside_temperature).state, id(outside_temperature_unit).state.c_str());
      }      

渲染

  • 文本对齐可以使用不同的参考点,例如 TOP_RIGHTBASELINE_LEFT,这些都定义在 API Reference 中。

  • 传感器上的 has_state() 属性很有用,因为它可能需要几秒钟才能从 Home Assistant 获取数据,并且您可能不希望显示 Nan

  • 参考 显示渲染引擎 以获取更多功能(它也可以绘制线条和圆圈!)。

添加基于文本的传感器

以下是一个示例,它用 Home Assistant 中的警报组件的警报状态替换了“时间与温度”顶部的打印输出。

text_sensor:
  - platform: homeassistant
    entity_id: alarm_control_panel.my_alarm_system
    name: "Alarm State"
    id: alarm_state

display:
  - platform: ssd1306_i2c
    model: "SH1106 128x64"
    reset_pin: GPIOXX
    address: 0x3C
    lambda: |-
      // 在顶部居中打印 "Alarm State: <state>"
      it.printf(64, 0, id(small), TextAlign::TOP_CENTER, "Alarm State: %s", id(alarm_state).state.c_str());      

参考文档