ePhotoFrame Project

January 19, 2026 8:31 pm

Curious about the current state of consumer-available, color-eInk screens I found that WaveShare is selling this device: RPi-Zero2W-PhotoPainter. It’s not quite a product by itself, but it’s a considerable step towards “product” from when I used a 3-color display to build my “Home Board” back in 2018. The “PhotoPainter” is a 7.3-inch, 6-color, 800×480 pixel, ePaper screen which can be ordered with a pre-installed RPi Zero2 W (with microSD card). It’s connected to a custom PCB with battery leads, power switch, and a UART serial lead. The screen is mounted in a wood frame with integrated table stand. I say “product” because it doesn’t _do_ anything out of the box. You need to bring some programming capability to the table and make it do something useful. But, unlike when I built the Home Board, I don’t have to do all the physical assembly and can focus on the software.

I wiped the provided SD card and loaded a fresh install of Raspbian which allowed me to pre-configure the device for my Wi-Fi network and enable SSH access.

From there I dissected the provided example code and wrote a custom script to drive the display. My code is available on GitHub: https://github.com/kdickerson/ePhotoFrame.

My set up uses nextcloudcmd to synchronize photos from the family NextCloud instance to the frame. Every 10 minutes the frame selects an image randomly and displays it. But, images need some processing before going to the display. When an image is prepared we save the prepared version and when selecting an image we check if we’ve prepared it previously and use that instead of duplicating the work.

The preparation resizes and crops the image to fill the display. To target where to crop it runs a face-detection neural network and targets the location of the weighted average of the detected, high-confidence faces. If no faces are detected, it instead calculates the location of highest “saliency” (a measure intended to identify “interesting” parts of an image based on information density).

Once the image is resized and cropped it needs to be dithered into the 6 colors displayable by the screen. This is the prepared version stored for future re-use. There’s still one more step of processing before sending the image to the screen, but I store this version because it’s still human viewable as a regular image file. The final step is to repack the bits. The display uses 4 bits per pixel to select which of the 6 colors to use and then packs each pair of pixels into one byte.

The final bit buffer is pushed to the display using WaveShare’s provided driver package.

The final effect of the dithering can vary quite a bit depending on the specific scene and colors involved, but generally it looks decent from >4 feet (closer than that and the dithering is incredibly obvious). The colors are fairly muted, which is common in ePaper displays currently. But the ePaper display is critical for my biggest criteria: no glowing screen.

I decided to hang it up in the kitchen to cover an old telephone jack. But I needed a hook somehow. So I quickly designed and printed a hook to slip behind the wall plate and held in place by the screw. 3D printers are super handy for those little things that otherwise don’t exist.

The Danger is Immense

January 10, 2026 2:37 pm

Since the end of World War II the United States has attempted to establish a world order based on common consent, economic interdependence, and democratic rule. Yes, our fidelity to these aims has often fallen woefully short. That’s undeniable. We’ve been hypocritical on many egregious occasions. But even so, there was generally a shared thread amongst those we elected that these were the right ideals even when we failed to live up to them.

After September 11, we brought together a “coalition of the willing” to take military action around the world. Poorly thought through and supported by lies–but, a coalition nonetheless. We asked our allies to send their children to die for our cause in a desert on the other side of the planet. And they answered our call. Action taken by common consent–not unilateral declaration.

In the aftermath of WWII the United States engaged Japan and Western Europe in aggressive stabilization and rebuilding campaigns. We wanted to thwart the perceived dangers of communism and believed that this was the solution. The theoretical basis of these efforts was that democratic nations with interconnected economies don’t start wars and don’t become desperate enough to heed the calls of communist revolution.

Nations were to air their grievances in the United Nations, rally others to their cause, and exert social and economic pressure rather than take military action. Through this venue the Cuban Missile Crisis was resolved without bloodshed. Through humanitarian programs the United States exerted soft power throughout the world showing the benefits of being our friend while using economic sanctions to warn of the danger of being our enemy.

Again, we failed many times to meet these ideals, but they were a shared sentiment even so.

This is no longer true.

The United States has now placed in charge a group of people for whom the saying “might makes right” is the furthest extent of their moral reasoning.

They assassinated a general of an adversary’s army because they could. They kidnapped a foreign head of state because they could. They are threatening to conquer Greenland because “no one’s going to fight us over it”. They use missiles to blow up civilian boats in the ocean because they can.

They act unilaterally, insult our allies, and spit in the faces of common consent, economic interdependence, and democratic rule. This matters possibly more deeply than the rest of the abhorrent, degenerate, destructive behaviors they engage in.

If the foundational principles of the world order we’ve existed in for the past 50+ years fall then the world will enter a spiral of destruction. “Might makes right,” so the US takes Greenland and goes to war with Europe. “Might makes right”, so, while the US is distracted, China takes Taiwan. “Might makes right”, so with Europe distracted, Russia finally succeeds conquering Ukraine and moves on to the Baltics. Every country with the means begins a crash program to build, buy, or steal nuclear or biological weapons because it’s the only language still understood in a “might makes right” world. And we will leave the world in ashes.

We know how this plays out because WWII was heavily documented and has been studied for decades. When demagogues seize power and believe themselves above consequence they endlessly grasp for more. After all, until someone stops them, they have the right to take more. That’s the way the world works–that’s the way the world they want to live in works.

Common consent is gone as far as the United States’ international actions are concerned. We’ve withdrawn from dozens of cooperative international agencies and taken unilateral action whenever it pleases us–enemies or allies be damned. Our new policy on international relations is, “Who’s going to stop us?”.

Economic interdependence is under assault from isolationist tariffs and trade wars. If we no longer buy anything from Mexico, then it won’t hurt our economy to bomb Mexico into oblivion.

Democratic rule is hanging by a thread. The president already incited a violent coup once, was impeached for it, and for some insane reason this country elected him again. He and his cabal have been laying the groundwork for months to normalize the idea of violating the Constitution so he can remain in power when his term ends.

The danger is immense. And I don’t know what to do about it.

Games December 2025

December 31, 2025 3:08 pm

Made it to one board game meet up. Played a round of The Guild of Merchant Explorers. I won.

While waiting for other games to wrap up we played a quick game of L’Oaf. I lost.

And I rounded out the evening with a game of Forest Shuffle: Dartmoor. This game is about laying out an ecosystem (in this version, within a moor) and placing animals in your environment. I filled my moor with dragonflies and newts, but didn’t win.

By quick count, I played ~63 games this year. (I counted unique games in each monthly post I made, so if we played “Cat Fluxx” 4 times in one session I only counted that as 1).

Books December 2025

2:59 pm

The Witcher: Baptism of Fire by Andrzej Sapkowski

The saga of Geralt and Ciri continues. Geralt recovers in Brokolin and begins anew his search for Ciri. Ciri joins up with the Rats.

A lot of people die throughout.

50 Years of Text Games by Aaron Reed

The most recent book-group pick at work. This is a history of text games–where the concept of “game” evolves with time and mostly becomes what is now called “interactive fiction.” It was interesting, well researched.

The Witcher: The Tower of Swallows by Andrzej Sapkowski

Ciri is nursed back to health by Vysogota. Geralt searches for the druids in hopes they can provide information about Ciri. There’s a reformed vampire. Yennefer is seen again.

A lot of people die throughout.

Starter Villain by John Scalzi

This was the girls’ pick as my Christmas present this year. It’s an odd book. Take the tropes of supervillainy; mix them with whimsy, sarcasm, and quotidian life; add a dash of sentient cats and dolphins–you’ll end up somewhere in the vicinity of this book.

Easy reading; enjoyably humorous.

That’s 35 books completed in 2025, one of which in French, and several of which were really long. I also played two text-heavy video games entirely in French: Syberia and Spiritfarer. My French has a long way to go (especially aurally), but it’s nice to see that I can muddle through content and not get totally lost.

Migrating to Home Assistant Green with ZBT-2

December 30, 2025 3:12 pm

I have been running Home Assistant from a RPi 3B with a Conbee II stick for Zigbee (using ZHA) for years now. Finally decided to upgrade and directly support the Home Assistant project by migrating to a Home Assistant Green device with the Home Assistant Connect ZBT-2 Zigbee adapter.

I wasn’t sure how painful the process was going to be, so now that I’ve done it, I wanted to document it. It went quite smoothly with really only one tiny hiccup.

I made a backup of my existing system and shut it down. I moved the Conbee II stick to the HA Green, connected the network cable, and plugged it in. It showed up on the network without issue. When I connected to it, it said it was “starting up” or something similar. Expanding the details didn’t show anything happening. After a few minutes I started to get concerned that perhaps there was an issue, but shortly thereafter it finished and showed me the setup page. I restored from the backup and waited a bit for that to complete (it would be a nice improvement to have a progress bar for the restoration process).

When the restoration completed, I logged in as expected and saw that the Zigbee system (via ZHA) was grumpy about something and that HA detected updates to install. I installed the updates first before tackling the ZHA issue. It was complaining about the current configuration not matching the last backup. I had thought moving over the existing Conbee II dongle and doing the restore would go more smoothly than trying to jump directly to the ZBT-2 while doing the hardware upgrade, but that seems to have been a mistaken assumption. I clicked on the gear icon for ZHA and it asked if I wanted to reinitialize the existing adapter or migrate to a new one. At this point, I suspect I could have migrated to the ZBT-2, but I wanted to get things functioning with known-good hardware to minimize variables so I opted to reinitialize the existing adapter and that seemed to work fine. ZHA stopped complaining and my Zigbee devices started re-establishing communications with Home Assistant.

Next I plugged in the ZBT-2 and followed the instructions it came with to add the device. It performed the firmware update to configure the adapter for Zigbee, but then the onboarding flow stopped. But I simply clicked the “Add” button on the automatically-detected ZBT-2 device again and everything completed without issue. I unplugged the old Conbee II dongle after the migration completed (when HA says you can do that) and verified that my Zigbee devices were still functioning with the new adapter.

But some of my Zigbee devices fell off the network during the migration. All of which were battery-powered devices: two water-leak sensors (a third one stayed connected), a vibration sensor, and a button (a second one stayed connected). Not sure why some stayed of and some fell off. I believe the three water-leak sensors are the same make/model. Same for the two buttons.

Overall, pleasantly low friction in this migration.