Does it sometimes feel like software is getting a bit, well… out of hand? No? OK, fair enough, it’s probably just me!
To calm our thoughts, in a sort of weird technophile version of mindfulness, I offer you this picture of a small computer on a squishy rubber brain. This will all make sense later, hopefully.

Now, if you’ll excuse me for a moment, I just have to update my Node.js app’s dependencies.

You could be forgiven for thinking that we don’t really know what is in all this code we’re running, but that couldn’t possibly be the case, could it? I mean, if it comes from a reputable source then it’s surely fine? This is a local host for local code. We’ll have no data exfiltration here!
But imagine your surprise on discovering that the super duper modern Go library (or maybe its Ruby equivalent) you are using for processing Exif metadata from images is actually a wrapper around ExifTool, which is a <whispers> Perl script. One must be careful where the Elder Gods are concerned, so we’ll say no more of this - for now.
And this is where the fashion part comes in…

We’re increasingly using techniques like GitOps to magically orchestrate spinning up whole clusters and virtual data centres, conveniently and efficiently installing software from <shrugs> who knows where? Maybe it’s worth us taking a step back and spending a little time using tools like Grype to understand our software supply chain a little better.
And maybe, just maybe, it’s also worth us taking a long hard look at our computing environment. Do we really need all those Pods and Containers? How many of the workloads we’re running could easily fit on a Fez, or a squishy brain? Perhaps it’s time to normalise the Fez Unit of Computing. After all, the acronym works so well.
Now, has anyone seen my data centre? It was by the window earlier on…
PS What’s that? You too have made a hat-centric Pi Zero-oriented data centre using the Waveshare INA219 UPS HAT and the Inky pHAT from Pimoroni, Sheffield’s Popular Peddlars of Preposterous Packages? How exciting! In that case you might find this awkwardly adapted Python code useful - it queries the UPS module and then displays the battery percentage and a bunch of other stats on the unit’s e-Ink screen.
1import os
2import re
3import argparse
4import platform
5import subprocess
6
7import math
8import time
9import colorsys
10
11# INA219 comes from the Waveshare Wiki - https://www.waveshare.com/wiki/UPS_HAT_(C)
12from INA219 import INA219
13from datetime import datetime
14from PIL import Image, ImageFont, ImageDraw
15from font_hanken_grotesk import HankenGroteskBold, HankenGroteskMedium
16from inky.auto import auto
17
18inky_display = auto(ask_user=True, verbose=True)
19img = Image.new("P", inky_display.resolution)
20draw = ImageDraw.Draw(img)
21
22hanken_bold_font = ImageFont.truetype(HankenGroteskBold, 22)
23hanken_medium_font = ImageFont.truetype(HankenGroteskMedium, 18)
24
25ina219 = INA219(addr=0x43)
26bus_voltage = ina219.getBusVoltage_V() # voltage on V- (load side)
27shunt_voltage = ina219.getShuntVoltage_mV() / 1000 # voltage between V+ and V- across the shunt
28current = ina219.getCurrent_mA() # current in mA
29power = ina219.getPower_W() # power in W
30p = (bus_voltage - 3)/1.2*100
31if(p > 100):p = 100
32if(p < 0):p = 0
33
34# INA219 measure bus voltage on the load side. So PSU voltage = bus_voltage + shunt_voltage
35ups_load_voltage = "{:6.3f} V".format(bus_voltage)
36ups_current = "{:6.3f} A".format(current/1000)
37ups_power = "{:6.3f} W".format(power)
38ups_percent = "{:3.1f}%".format(p)
39
40hostname = platform.node()
41now = datetime.now()
42date_time = now.strftime("%Y-%m-%d %H:%M")
43ssid = subprocess.check_output(["/sbin/iwgetid", "-r"]).strip().decode("utf-8")
44ip_addr_info = subprocess.check_output(["/bin/hostname", "--all-ip-addresses"]).strip().decode("utf-8")
45ip_addr = re.sub(' .*', '', str(ip_addr_info))
46
47draw.rectangle((0,0,80,inky_display.HEIGHT), fill=inky_display.RED, outline=inky_display.RED)
48draw.rectangle((5,30,80,31), fill=inky_display.WHITE, outline=inky_display.WHITE)
49draw.rectangle((81,30,(inky_display.WIDTH-5),31), fill=inky_display.BLACK, outline=inky_display.BLACK)
50
51draw.text((10, 5), "Host", inky_display.WHITE, font=hanken_bold_font)
52draw.text((10, 35), "Time", inky_display.WHITE, font=hanken_medium_font)
53draw.text((10, 55), "SSID", inky_display.WHITE, font=hanken_medium_font)
54draw.text((10, 75), "IP addr", inky_display.WHITE, font=hanken_medium_font)
55draw.text((10, 95), "Battery", inky_display.WHITE, font=hanken_medium_font)
56
57draw.text((90, 5), hostname, inky_display.BLACK, font=hanken_bold_font)
58draw.text((90, 35), date_time, inky_display.BLACK, font=hanken_medium_font)
59draw.text((90, 55), ssid, inky_display.BLACK, font=hanken_medium_font)
60draw.text((90, 75), ip_addr, inky_display.BLACK, font=hanken_medium_font)
61draw.text((90, 95), str(ups_percent), inky_display.BLACK, font=hanken_medium_font)
62
63inky_display.set_image(img)
64inky_display.show()