#!/usr/bin/env python3 """ Reads temperature and humidity from an SI7021 sensor (I2C) and renders the values to a Waveshare 2.13 inch e-Paper HAT. The Waveshare EPD library (waveshare_epd) is not bundled in this repo. See README.md for setup instructions. """ import time from smbus2 import SMBus from PIL import Image, ImageDraw, ImageFont from waveshare_epd import epd2in13_V4 # adjust module name for your HAT version I2C_BUS = 1 I2C_ADDR = 0x40 POLL_INTERVAL = 120 # seconds between display refreshes def read_si7021(bus: SMBus) -> tuple[float, float]: """Return (temp_c, humidity_pct) from the SI7021 sensor.""" rh_raw = bus.read_i2c_block_data(I2C_ADDR, 0xE5, 2) # measure RH, hold master time.sleep(0.1) humidity = ((rh_raw[0] * 256 + rh_raw[1]) * 125 / 65536.0) - 6 temp_raw = bus.read_i2c_block_data(I2C_ADDR, 0xE3, 2) # measure temp, hold master time.sleep(0.1) temp_c = ((temp_raw[0] * 256 + temp_raw[1]) * 175.72 / 65536.0) - 46.85 return temp_c, humidity def render(epd: epd2in13_V4.EPD, temp_c: float, humidity: float) -> None: """Draw sensor readings on the e-paper display. The 2.13in HAT is 122×250 px (portrait). We create a landscape image (250×122) by swapping width/height, which matches the typical Waveshare example convention of passing (epd.height, epd.width) to Image.new. """ image = Image.new("1", (epd.height, epd.width), 255) # 255 = white background draw = ImageDraw.Draw(image) font_large = ImageFont.load_default(size=40) font_small = ImageFont.load_default(size=22) draw.text((10, 8), f"{temp_c:.1f} \u00b0C", font=font_large, fill=0) draw.text((10, 62), f"{humidity:.1f} % RH", font=font_small, fill=0) epd.display(epd.getbuffer(image)) def main() -> None: epd = epd2in13_V4.EPD() epd.init() epd.Clear() bus = SMBus(I2C_BUS) try: while True: temp_c, humidity = read_si7021(bus) render(epd, temp_c, humidity) time.sleep(POLL_INTERVAL) except KeyboardInterrupt: epd.sleep() if __name__ == "__main__": main()