Small update on some mini projects I've been working on
Published on
Hello all, in keeping with my goal to write more to my blog, here I am summarizing my January progress on some miniature projects. This is objectively the best way to keep myself accountable for fulfilling my January goal of trying to close out as many unfinished projects as possible.
I have a very old Kindle generation 3 that has ultimately been collecting dust for the ten-something years I’ve had it. I used to be an avid book reader on the Kindle, but it strongly lacked something like backlight support, so it started to wear on me. Then I started buying more physical books, because I have a strong dislike of Amazon itself. There may be a point in time I buy something like a Kobo e-Reader, but I’ve not reached that point just yet.
Anyways, something I’ve wanted to do with this Kindle for a long time was turn it into a rotating picture display I could hang somewhere. I’ve reached about 50% towards completing this goal, the other 50% is a bit of Kindle hacking I have not put the time into quite yet.
The gist of it is that since Amazon doesn’t really care about this generation of Kindles anymore, I’ve decided to jailbreak it to extend it’s lifespan. The process is pretty simple, following this guide here on how to do the jailbreak. This jailbreak comes with some extensions, notably one on customizing the pictures that are displayed by the Kindle when it is put to sleep.
My goal would be for this picture to rotate every 10–15 minutes or so, and change between a picture I provide and put onto the Kindle’s storage space myself. There are a lot crazier things you can do, but ultimately I just want a picture being rotated and shown, so I can hang it in my living space somewhere as a cool little gizmo, so it can live out the rest of it’s days having utility.
Ultimately, the custom screensaver is a nice feature. However, it’s not quite a rotating gallery just yet. The picture rotates when the Kindle is put to sleep, and when it’s in sleep mode, it won’t wake up unless the user prompts it to do so. Therein lies the problem, I need a way to wake it up via something like a cron job, but since it’s asleep, cron
won’t work.
There are some scripts I’ve seen online about manipulating the power governor feature in the Linux kernel to create a wake-up timer to this effect. If I had a script that could wake up every so often then immediately go back to sleep, then it would satisfy my goal of being a cool little gallery. That’s one thing.
The next thing is making sure pictures I upload onto the Kindle are an appropriate resolution and aren’t large enough to create a noticeable gap in the picture loading process. I’ve observed that larger quality pictures are slower to be drawn to the screen, most likely because the Kindle is doing internal image resizing of image files to make sure it’s appropriate for the screen. To solve this, I need to gather the resolution and figure out some best-fit options between performance and DPI of pictures I store. Maybe I’ll take a ditherpunk approach? Not sure just yet.
I’ll hopefully have this more solved by the end of the month after a bit of experimentation via ssh
.
I recently came into possession of a Raspberry Pi 4 micro computing device, and it unfortunately puts my Raspberry Pi 2 to shame. I’ve had my RPI2 for years now, and I’ve used it for dumb things like tweeting Mandelbrot/Julia fractals, but I shuttered that a while back because:
I used my RPI2 for various things inbetween the last few years, but the one thing that annoyed me was it’s very annoying SD card corruption on power loss issue that was nearly impossible to resolve. Each time the power would go out, whether it’s due to a storm or a minor trip in the current, if it lacked power, the RPI2 would effectively be turned off, but that would interrupt proper calls to make sure the SD card was safe from bad writes. In turn, each time the power was turned off on the device, the SD card would in turn, get corrupted.
The number of times I’ve tried reflashing corrupt cards and somehow coming out unscathed with minimal damage was too high, and I got sick of having to plug my SD card into my Android phone to reflash the damn thing. Even that didn’t work in some odd cases. I wanted to hard-boot from a USB device, but that does not exist on RPI2 boards. This is a flaw, and without some fancy settings or tricks, I think I just have to accept the flaw and move on.
Still, in favor of trying to keep things alive, I decided this time to delegate my RPI2 unit to become a Pi-Hole. Pi-Hole in short, is a DNS server for the Raspberry Pi that can take block lists from the many adblock lists publicly out there and block bad URLs before they hit other devices on your network, most likely by absorbing the requests and “nulling” them out.
The benefit from this is that people who don’t run adblock plugins on their devices can benefit from the Pi-Hole simply existing on the network. The devices connecting to your network will use the Pi-Hole as a DNS, requiring no change on end-users part to get instant results. For my partner, who has an iPhone, this is a good thing, because iPhones have very few options for adblocks. Safari is not very good, but it is saving her countless ads now on her web experience, which is great.
Pi-Hole works, and was not difficult to set up. I plugged in my SD card, used the Raspberry Pi imager tool (rpi-imager
on AUR), wrote in the details to use to SSH into the device, and I had a working Raspberry Pi. Then the Pi-Hole instructions was a simple nearly one-click script with detailed instructions on what I had to do to get it up and running on the network, involving turning it into a static IP on the DHCP settings of the router, as well as setting it’s static IP to be the DNS used on the entire network.
After that, it’s just business as usual. The Pi-Hole has it’s upstream DNS set to be Cloudflare’s 1.1.1.1
DNS service, giving me more granular control over my network requests. I’m free to hop to another DNS service should my mind change, but having DNSSEC
for everyone on the network is nice, and a better start than what I was doing before… which was nothing.
Once upon a time, I had a Steam Machine and resurrected it from the dead. This model was known as the Alienware Alpha, produced by Dell at the height of the Steam Machine “frenzy” (there was none). I didn’t buy this, I came into it second hand.
The process was almost two years ago, and I’ve had some use for it since then. My goal was turning it into a Nextcloud server, using Docker Compose to run the entire stack virtually and hopefully making it slightly easier to maintain. Then by exposing it through a Cloudflare Tunnel, it could be accessed anywhere on the web (as scary as that sounds).
Eventually, I left the Alienware/Nextcloud stack in the dust, as I was trying to upgrade from nextcloud
to nextcloud:fpm
, which would have offered performance benefits due to possible PHP machine code JIT’ing. However, I had to switch to a separate HTTP service, namely nginx
, and that threw a wrench into my Docker Compose file, and largely involved a lot of trial and error that never succeeded.
Since then, the Alienware has been collecting dust, and I’ve not paid much attention to it since. However, I’m changing that now. I started using Guix a lot more, and I’m getting more familiar with it. To say that I’m a Guix pro, is far from the truth, but I feel comfortable enough to build an operating system with Guix and maintain it. Using Guix as a package manager, well… I’m working on it.
Reproducing an installer is as easy as doing the following command:
guix system image --image-size=7.2GiB nongnu/system/install.scm
What is nongnu
? It’s the non-free Guix files maintained by a team called Nonguix, who maintain all the Guix source files for code that is not free software. This also means the Linux kernel. To get nonguix
to appear as a channel in your Guix manager, you need to append it to your ~/.config/guix/channels.scm
in some capacity and run a guix pull
. You can find more instructions on their GitLab.
The image gets put in /gnu/store
by default, but it can be burnt onto a USB flash device and then installed onto a host computer. The complicated part is that the Guix installer does not take into account using the non-free Linux kernel by default. You have to get to the part that a config is written to /etc/config.scm
, then manually edit it yourself to include non-free sources, then run the build command manually. Otherwise you will install a computer that won’t have wireless drivers at all.
{{ authors_note(text="This process is pretty delicate; doing modifications to Guix may overwrite what is actually on the installation media. If you have a direct ethernet cable, you can install non-free Linux kernels after doing a regular install, but if you don’t, then you have to make sure to do all the steps correctly, else you’ll have to re-flash the install image onto your disk/USB drive again.") }}
Once you install Guix (free or non-free), do a guix pull
, check your settings, make sure your ~/.bash_profile
is set to use your Guix profile, and now you can do whatever you wish. In my instance, I didn’t want a desktop, I wanted a sitting server that can host applications. To get it from desktop mode to basic dumb computer server, we have to change the services in our configuration.
;; My current Alienware Guix configuration
(use-modules (gnu)
(nongnu packages linux)
(nongnu system linux-initrd))
(use-service-modules cups desktop networking ssh)
(operating-system
(kernel linux)
(initrd microcode-initrd)
(firmware (list linux-firmware))
(locale "en_US.utf8")
(timezone "America/New_York")
(keyboard-layout (keyboard-layout "US"))
(host-name "alienguix")
; stub your user info here
(users (cons* (user-account
;...
)))
; put needed packages here
(packages
(append (list
(specification->package "nss-certs"))
%base-packages))
; services to run this as a general computer server
(services
(append
(list
(service network-manager-service-type)
(service wpa-supplicant-service-type)
(service openssh-service-type)
(service cups-service-type)
; put more as needed
)
; base services is a thinner service variable
; containing the bare minimum, not even networking
%base-services))
; bootloader/disks/swap/etc
(bootloader ...)
(swap-devices ...)
(file-systems ...)
)
This is what my system resembles after a fresh install with non-free drivers and firmware properly seated and working. The default %desktop-services
can be modified should you wish, but building on top of %base-services
is easier in my eyes if you want to get a home server started right away.
Having a dedicated Guix operating system is a lot different than simply using it as a package manager, so I hope to learn a lot in the process about Guix and it’s different aspects by doing so. I’ll hopefully be posting about it more in the future and what I can come up with, probably just doing more Nextcloud-related stuff. Over time, I will put more of my Guix configuration scripts on my personal Guix repo here.
Beginning next month, I will be focusing more on one project at a time and trying my best to “finish” things before moving on. Between juggling work and home life, I want to have a keen and sharp focus on one project, and only one project at a time, at least until completion. I can complete a project in a day and that’d make me just as happy as spending a whole month working on something, but I don’t think I’ll be satisfied until I close out as many unfinished projects as possible.
My Guix server will transition into a home server for experimentation and transitioning through a tricky future of muddied cloud services. The Kindle picture frame project will come slowly. And I have some music-related projects I desperately need to get back to.
I will be spending some time with Like A Dragon: Infinite Wealth for a good chunk of time until I beat it.