What does a software developer do with 3 months of spare time? It’s time to reflect on the most fun part of any vacation: the software development. What did I fiddle with while I had time off?

pixelperfectpi

A panel of LEDs, displaying a UV index in the top left corner reading 2 with a small bar chart out of 10, the time 12:35, and the text Tue 2p Paris to Calgary

The first target was my LED matrix clock. There were some things that needed tweaking since I wasn’t in Calgary. The weather forecast was read from Environment Canada’s XML feeds – no good in Paris. So, I rebuilt weather based upon Home Assistant weather components, sent to an MQTT broker, and the clock reads that data. There are plenty of HA weather components for different services; easy to adapt this to any new location. Also added a UV index display.

https://github.com/mfenniak/pixelperfectpi/compare/40383af796900b3fcac19b6a15185a6da5752fd6…d05d6e39217fa17b9aa11ce8bb2a3d6e10256713

Along the way, I ripped out the usage of the dependency_injector library since it’s no longer supported upstream. I like having a DI-based design… but I will admit that for a Python app, and a small Python app at that, it’s probably not super useful.

https://github.com/mfenniak/pixelperfectpi/commit/07e3c04d06a59e8d840598ce0b6a25a555a1473a

A panel of LEDs, displaying 18 degrees in the top-left, 12:35 in the top-right, and a table of with four hourly columns 1pm, 2pm, 3pm, 4pm, and the temperatures 18 deg, 19 deg, 18 deg, 19 deg under the hour columns.

Now that I had a better source of weather data, I really wanted to display an hourly forecast. The clock is very small so I was limited in the display options… but also all the layout to-date had been shitty pixel hard-coding. So the next improvement was reimplementing the layout on the clock to use a flexbox calculator stretchable, which required touching every component and changing how they handled layout and drawing.

https://github.com/mfenniak/pixelperfectpi/compare/f7924871c88e9c5ec2c172594cee71ef9c8d1389…e51e97c1ca4b09c0f00cafbed3d4cecbd9f48878

The hourly weather output isn’t super amazing… but it’s useful enough. One last tweak to the clock was adding a display of the time at home. https://github.com/mfenniak/pixelperfectpi/commit/fbfabe331141d247c6021068989cf4607a089fd1

Crowd Control Video Game

Having my clock all settled, I started getting interested in the idea of a video game with the Bevy engine. I had built up a Godot tutorial game earlier in the year, and I rewrote that game with Bevy to learn the basics. Not really too exciting, but it set the foundation to learn how to code with Bevy’s ECS model.

Outdoor photograph of steel barricades and a pedestrian bridge.  The barricades are decorated with pink and blue "Paris 2024" signage, and people are navigating the barricades in thee background.

As we traveled around France and started to attend events during the Paris 2024 Olympics, I was exposed to good, bad, and complicated crowd control mechanisms. Barriers, volunteers, police, signage & lack of signage, security, etc. All of these contributed to holding safe events where crowds were efficiently moved from place to place with limited time & risk. And it’s all thrown into chaos if someone rides in a bike in the wrong place.

Screenshot of a cyan background, on which small character sprites are randomly distributed.  The sprites have green, blue, and red lines emanating from them towards points on the right side of the map.

Well, that sounds like it could be a video game to me.

Many of you reading this will immediately think about the complex part of building this – pathfinding. Video game pathfinding is difficult, especially if you consider that every actor in this system would have a different goal, a different level of patience, a different level of comfort getting close to others, shoving others, moving a barrier, ignoring a sign…

Anyway, I hacked away at a proof of concept with Bevy. Just enough to see, if I have a “crowd generator” on one side of a map, and a variety of “targets” on the other side of the map, can I impact the efficiency of moving people just by moving barriers? The answer is yes, but making the pathfinding efficient is hard. 😝 So, it’s a fun idea that I might revisit in the future, but I put it aside.

hyprland

At this point, I decided to sabotage my own productivity for a bit. It’s completely rational though. You see, I’ve been using a Plasma KDE 5 desktop for a few years, and I’ve become very accustom to the bismuth window tiling plugin. But, it isn’t supported in Plasma 6, and while there is an autotiler polonium for Plasma 6, I don’t find it to be nearly the same experience.

So I thought this was a good opportunity to give a solid try to hyprland, a tiling window compositor. Well… let’s say it’s a throwback to my early Linux desktop days. Other than composing windows, everything else you might want in a desktop environment is something to piece together. So, a week later, and I’ve configured hyprland, bemoji, wl-clipboard, wtype, cliphist, rofi, grimblast, waybar, dunst, hyprlock, hypridle… and I feel like I have a usable system.

Screenshot of status widgets on a desktop monitor, displaying the current battery life at 100%, currently connected bluetooth devices, volume levels, WiFi network, Discord and Signal icons, and the time.

What did I gain out of this? I’ve made the move to Wayland, and I’m not blocked on that Plasma major upgrade.

But I also love the multi-monitor support of hyprland. I have a set of workspaces dedicated to each monitor. When I disconnect the 2nd monitor, the workspaces automatically collapse back to the 1st monitor, and when I reconnect it, they pop back.

I’m not sold on this for the long term, but I’m pretty happy with it for a little over a month. We’ll see what the maintenance looks like!

Zenbook Duo Fixes

Photograph of a laptop with two displays; the second display is underneath where the keyboard normally sits.  In this photograph the keyboard is detached and sitting on a desk in front of the two fully visible displays.

Speaking of the dual-screen laptop, the Asus Zenbook Duo UX8406MA, one of my goals during the vacation was to make some Linux compatibility improvements for it. This sorta happened; I fixed two things, kinda.

Secondary Display

The first was that myself and others experienced a regression in June where the secondary display stopped working, which I reported upstream to the i915 team. In July an engineer provided a patch which fixed the problem.

However in August, the secondary display stopped working again. I started to bisect the kernel to find the issue, but made a grave error - I assumed that the current kernel was bad and my last kernel was good. This seemed to make sense - after all, it was working and then broken, right?

Each bisect required having my desktop at home build the kernel remotely, and then download it. After dozens of iterations I eventually found that the “broken commit” didn’t do anything when reverted. Whoops.

So I changed my approach to bisecting nixpkgs, and eventually found that the linux-firmware-20240811 was the true cause of the secondary display breaking. Reverting this upgrade restored the secondary display again. The fault was reverted out of linux-firmware, and the 20240909 is back to working.

So, I didn’t really fix anything here, but I did help identify some problems.

rfkill

Another problem with the UX8406MA is that connecting the keyboard to the laptop caused the wifi to shut off. I think the cause is that when the keyboard is turning off its Bluetooth on USB connect, it happens to send a wireless disable keypress? But that’s a bit guessy.

Regardless of the cause, I was able to create a kernel patch that detected and discarded these keypresses from this specific keyboard, which otherwise doesn’t have a wireless disable button.

This is the first time I’ve ever sent a Linux kernel patch upstream, and I’m very pleased that the platform maintainer integrated it in just a few days with one quick review cycle. https://github.com/torvalds/linux/commit/9286dfd5735b9cceb6a14bdf15e13400ccb60fe7 I’m a Linux kernel contributor!

This summer was great. One more stretch of hacking left…

testtrim

Screenshot showing a table and chart of testing results; the chart is a histogram indicating the percentage of tests that need to be run for every commit, and it is heavily weighted in the 0-10% bucket.

As September started to tick on, which I think is summer but my wife says is fall (and she’s technically correct, the best kind of correct), I started to experiment on a project that I’m calling testtrim.

The goal of testtrim is: run only the automated tests that are required to test the changes being made for software. The way it works is by running each test in an individually instrumented environment, and then using the code coverage map that generates to figure out what code a test runs.

I’m going to share a lot more about this when I get home and spend some more time working on it. Right now though, it looks very promising. I think it has quite a complex future in front of it… but a lot of potential value.