Esphome based Immich digital photo frame https://jtenniswood.github.io/espframe/
  • C 61.4%
  • Python 19.3%
  • C++ 15.4%
  • JavaScript 3.8%
Find a file
James Tenniswood 5442af2fcf
Fix release RAM overflow and local budget checks (#204)
## What changes when merged

- Fix the v1.14.0 OTA build's 137,060-byte RAM usage exceeding the
unchanged 137,000-byte limit. Store slideshow queue slot indices in
signed bytes, saving 96 bytes across the existing queues without
changing capacities, delays, priorities, or valid slot values.
- Make local release readiness capture ESPHome output and enforce RAM
and flash budgets as well as binary sizes, matching CI. Failed compiles
skip checks against stale binaries.

## Automated checks

- [x] `npm run check:pr` passed
- [x] CI passed: [Validate PR
Gate](https://github.com/jtenniswood/espframe/actions/runs/34694181143)
- Regression coverage checks queue capacity, wraparound, signed sentinel
slots, priority ordering, compile stderr capture, compile failures, and
rejection of the exact 137,060-byte RAM report.
- Full ESPHome 2026.8.2 Docker factory and OTA builds passed for both
models, using the updated `compile_firmware()` gate. Factory RAM:
136,900 bytes; OTA RAM: 136,964 bytes on each model. All RAM, flash, and
binary-size checks passed.

## Device testing

- [x] Not needed for this change
- [ ] PR Validation artifact flashed to device
- [ ] Needs device testing before merge

PR Validation workflow run/artifact: all four local Docker builds
passed; no manual workflow dispatched.

Firmware artifact (`firmware-test-<device>`): not generated by a manual
workflow.

Device tested: none.

Result/notes: queue storage layout only; host tests cover unchanged
behavior. No device was flashed.

## Notes for reviewers

- Firmware budgets, saved settings, entity names, and public
configuration remain unchanged. OTA static RAM has 36 bytes of headroom
under the existing budget; future additions must continue to pass the
gate.
- The failed v1.14.0 release remains published without firmware assets.
This PR must be merged and a new release authorized before fixed release
assets can be published; the existing tag is unchanged.
2026-09-12 13:54:42 +01:00
.agents/skills Accelerate image rendering and Immich selection (#176) 2026-08-30 20:25:15 +01:00
.github Migrate trusted CI jobs to the Espframe runner (#180) 2026-08-30 20:19:09 +01:00
builds fix(esphome): migrate build flags from platformio options (#200) 2026-09-08 10:26:20 +01:00
common/addon perf(firmware): reduce internal heap pressure during photo loading (#198) 2026-09-08 07:55:41 +01:00
components Fix release RAM overflow and local budget checks (#204) 2026-09-12 13:54:42 +01:00
devices fix(esphome): migrate build flags from platformio options (#200) 2026-09-08 10:26:20 +01:00
docs Refresh web configuration layout and action styling (#203) 2026-09-12 10:39:14 +01:00
product Add persistent frame names and network hostnames (#202) 2026-09-12 10:38:33 +01:00
scripts Fix release RAM overflow and local budget checks (#204) 2026-09-12 13:54:42 +01:00
tests Fix release RAM overflow and local budget checks (#204) 2026-09-12 13:54:42 +01:00
.gitignore Support both JC8012P4A1 panel revisions (#131) 2026-08-04 22:26:19 +01:00
AGENTS.md Require pull requests for agent changes (#178) 2026-08-30 11:25:51 +01:00
LICENSE Add non-commercial license 2026-05-13 14:28:11 +01:00
NOTICE Rebuild Espframe around an offline-first architecture (#136) 2026-07-14 17:43:00 +01:00
package-lock.json Update dependency esbuild to v0.28.2 (#158) 2026-08-10 21:09:13 +01:00
package.json Add persistent frame names and network hostnames (#202) 2026-09-12 10:38:33 +01:00
README.md Pin ESPHome 2026.8.2 (#185) 2026-09-01 10:31:51 +01:00
renovate.json Fix release build integrity and pin ESPHome Docker image 2026-04-15 11:58:48 +01:00

Espframe for Immich

Turn a supported Guition ESP32-P4 touchscreen into a private digital photo frame for your Immich photo library.

Espframe is for people who want their photos out in the room, not hidden on a phone, and do not want to run another server, cloud account, or subscription just to make that happen. Flash the frame from a browser, connect it to WiFi, point it at Immich, and it starts showing your photos.

Espframe displaying Immich photos on a Guition ESP32-P4 touchscreen

What Espframe Lets You Do

  • Make a real photo frame from your Immich library
    Show photos from the Immich server you already run, without needing a tablet, Raspberry Pi, Home Assistant, or a separate slideshow service.

  • Keep your photos private
    The frame connects directly to your Immich server over your own network. There is no Espframe cloud service and no extra account to trust with your pictures.

  • Choose what appears on the frame
    Combine albums, people, tags, favorites, ratings, dates, locations, exclusions, and orientation in one smart playlist.

  • Make portrait photos look better on a wide screen
    Espframe can pair portrait photos from a configurable nearby-day range side-by-side, so the display feels more like a composed frame and less like a single narrow image with empty space. You can also hide portraits when a complete pair is not available.

  • Tune the screen for your room
    Adjust brightness, warm up a panel that looks too blue, use a softer night tone after sunset, and schedule the display to turn off overnight.

  • Control it from the frame or a browser
    Use simple touch gestures to wake, sleep, or advance to the next photo, and swipe between image sets. Open the built-in web page on your phone or computer to change the photo filter, timing, brightness, Immich settings, and display options.

  • Use Home Assistant if you want to, but it is not required
    Espframe works by itself. If you already use Home Assistant, it can also appear there as an ESPHome device for dashboard controls, automations, and updates.

Who This Is For

Espframe is a good fit if:

  • You already use, or plan to use, Immich for your photo library.
  • You want a dedicated photo frame instead of leaving a tablet permanently awake.
  • You prefer local, self-hosted tools over cloud photo-frame services.
  • You are comfortable following a step-by-step browser installer and copying an Immich API key.

It is not a general-purpose tablet app. It is firmware for specific ESP32-P4 touchscreen hardware.

Hardware

Currently documented hardware:

Item Link
10" Guition ESP32-P4 panel (JC8012P4A1), original (2627 or lower) and new (2628 or higher) revisions AliExpress
10" printable stand MakerWorld

The two panel revisions look nearly identical but need different firmware. Choose the installer profile using the four-digit rear-case marking; the new panel may not be labelled V2.

Getting Started

The easiest way to install Espframe is with the web installer. You do not need to install developer tools or build firmware yourself.

Open the Web Installer

You will need:

  • A supported Guition ESP32-P4 touchscreen
  • A USB-C data cable, not a charge-only cable
  • Chrome or Edge on a desktop computer
  • Your Immich server address
  • An Immich API key

The full setup guide is here:

jtenniswood.github.io/espframe

Everyday Controls

Once installed, the frame has two main control surfaces:

  • On the touchscreen: tap to wake, double-tap to advance to the next photo, swipe left for the next image set, swipe right for the previous image set, and press-and-hold to sleep.
  • In the web settings page: change the smart photo filter, slideshow speed, brightness, screen tone, rotation, WiFi, Immich connection, and firmware update options.

Development

Most people do not need this section. It is here for contributors or anyone who wants to build the docs or firmware locally.

# Docs site (live reload)
npm ci
npm run docs:dev

# Compile firmware locally
docker run --rm -v "${PWD}:/config" ghcr.io/esphome/esphome:2026.8.2 compile /config/builds/guition-esp32-p4-jc8012p4a1.factory.yaml
docker run --rm -v "${PWD}:/config" ghcr.io/esphome/esphome:2026.8.2 compile /config/builds/guition-esp32-p4-jc8012p4a1-v2.factory.yaml

In-Development Firmware Features

In-progress firmware experiences are built into normal firmware, but must stay off unless the hidden developer setting is enabled. Open the device web UI with ?developer=experimental, for example http://<device-ip>/?developer=experimental, then use the Developer panel to turn them on for that device.

Firmware code should check id(developer_features_enabled).state before running anything experimental. The switch defaults off and persists only when deliberately enabled.

License

Espframe's project-owned code and documentation are source-available under the PolyForm Noncommercial License 1.0.0. You can use, change, and share it for non-commercial purposes. Commercial use needs separate permission from the project owner.

This is not an OSI-approved open source license because formal open source licenses must allow commercial use. Third-party components keep their own licenses.

Support This Project

If you find this project useful, consider buying me a coffee to support ongoing development.

Buy Me A Coffee