Friday, December 05, 2025

My PiThon Project

Pardon the really terrible pun - but I'm working on a small side project on a Raspberry Pi in Python.

Ok, now that we got the Pi jokes done, here's what I'm doing:

I'm a building an station display (board) for nearby train and other public transprt stations with real-time data and more importantly potential delays. Idea is to have a brief glance at it before leaving the house, so you know whether to rush or leisurely stroll to the station.

For that I'm re-using and old PI (3B+ to be precise, not really the fastest one) with a Raspberry Touch Display 2 and a bit of Python code.

So easy do develop (in PyCharm) and test (on my PC), then "stage" it to a Raspberry OS within a virtualbox, and then deploy to a real bare metal RaspPi.

I get the data from the ÖBB online timetable (as json) and the Wiener Linien open real time data (german description here). I chose those 2 because that's really all I need in my neighborhood. ÖBB (the Austrian federal railways) timetable covers all train journeys within Austria, and as I'm living in Vienna, I only need the Vienna public transport timetable. *

For the GUI I started the tkinter but started to regret this almost immediately. It is a terrible API without proper control for tables for example - and yes, showing an online timetable needs a proper table - it's sort of in the name.

When I then first deployed this to a real Raspberry the performance was abysmal - and I'm talking about fetching the data from their soures, but presenting that data (once loaded) in a tkinter window/table.

Think of old terminals connected via a serial V.32bis modem... where you can watch the lines being popuplated - almost that bad. You could see the table being drawn... really.

So, terrible API, hardly control over table formatting, terrible performance on the target HW, lets look for a different GUI library.

PyQt to the rescue. I found the API and the constructs more familiar (from Swing, Android, even back OS/2 and Windows ;)) and it is definitely more performant.

So PyQt it is. Rewrite was done in less then an hour. No visible rendering/drawing artifacts.

Right now, the configuration of the stations is right still in the source code (yuck), but that's the next step then - one needs to fill their spare time, right?

More to follow.

---

* yes, my code is modular enough to plug-in any other transport provider as long as they have machine readable online timetable data via whatever over HTTP without logins ;)

Thursday, December 04, 2025

Note to self - SSH keys

Whenever I need to setup a new ssh client device (laptop / chromebook / PC) or target (like a raspberry, ...) I need to google around how to do my SSH key setup. For Putty, that's easy, for ssh on the chromebook the google restults are less useful (YMMV).

So here's my reminder / note for next time on a chromebook:

On the new Chromebook, (create the linux environment and) open the Linux terminal.

Generate a new SSH key pair by running the command ssh-keygen.

Copy the public key to the server by running the command: ssh-copy-id user@hostname.

Enter the password for the user on the remote server when prompted. 

Then go to the terminal app and select the ssh configuration for that hostname.

Click on import and (re-) import the id_rsa file (you might need to make sure you see hidden files first via the ⋮ menu in the upper right corner)

Wednesday, December 03, 2025

New Chromebook

Today, I upgraded my three-year-old Acer Chromebook 514 with a new model. The original served me incredibly well, but i got annoyed with serious performance issues, like login taking ages - just to enter the PIN. That with some other symptoms to me looked like not enough memory (4GB). One other thing that I regretted immediately after buying it about 3 years ago was the lack of a keyboard light.


So I got myself a newer model with 8GB and a backlit keyboard.

Installation was smooth and easy - switch it on, scan the QR code with your Android phone and it will setup everything from there. It couldn’t be more easy.

Especially when compared to setting up a brand new Windows 11 (which I did a week before for my mother) - but that’s another story which I will probably NOT write ;)

All apps (incl Android apps) are being re-installed on the new Chromebook as well. Chrome settings are synched as usual. Really nice.

Login, opening apps - even android apps - is lightning fast as expected.

Only need to clone/re-create my ssh keys - but more on that later.

So, trying it out now with writing a blog post from the couch….

Monday, December 01, 2025

On the em-dash

I guess — I’m pretty convinced actually —  that these days more 20somethings know about the em-dash than any other generation. Not because they are actively using them, but because AI uses it for them, and then have been called out on it.

Probably calls for a paper with a fancy title like “Generational Aspects of the em-dash” or “Typography – A Generational Approach”

Btw: I've been using the em-dash for years, but mainly in presentations and when it makes typographically or optically. 

Wednesday, November 26, 2025

Read the effing Docs

Yeah, not really news, but just fell into one of those traps, where you not only forget/fail to fully read the documentation, but also fall prey to premature optimization.

It probably dates back to my 8086-Assembler-4.77MHz programming times, that I want to avoid an API call whenever possible - so if their result appears invariant, I happily store if to avoid a second call.

40 years later, when working with Android RecylcerViews, this led to a terrible bug that cost me 2 days to identify and fix.

As the docs say for onBindViewHolder (for the RecyclerView.Adpater)

Note that unlike android.widget.ListView, RecyclerView will not call this method again if the position of the item changes in the data set unless the item itself is invalidated or the new position cannot be determined. For this reason, you should only use the position parameter while acquiring the related data item inside this method and should not keep a copy of it. If you need the position of an item later on (e.g. in a click listener), use getBindingAdapterPosition which will have the updated adapter position.

In order to pass the adapter position down to an onClick lambda, I even — specifically — made it final.

No wonder, that the code didn't work correctly in some — albeit very rare — circumstances, e.g. when an item further up in the list got removed from the view / adapter.

Again, reading the above would make it clear that this was not a time for premature optimization.

I think I should avoid those optimizations at all, the compiler and jvm is quite good at it anyway — especially identifying invariant function calls. Moreover, Android phones no longer run on 4.77MHz CPUs ;)

Lesson learned.

Wednesday, October 08, 2025

Maven deploy to Tomcat

 So, I'm finally moving off of NetBeans and into IntelliJ IDEA

The two main reasons for that are:

  1. NetBeans is really getting old any hardly any relevant updates
  2. All my other IDEs (PyCharm, Android Studio) are built on it
I long ago moved my projects from ant based to maven, not I struggled to get the tomcat plugin to properly deploy to my local tomcat.
Well, the re-deploy didn't work to be honest.
Reason was, that the plugin does not add the "upgrade=true" to the upload URL, and I failed to manually tweak it.

Then I found that the plugin will honor a property called maven.tomcat.update and a quick test from a command line showed that this really works.
But then, how to get it into the IDE itself. 

Took me a while, and the best way is to add it to your POM under properties, like below:

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jakartaee>10.0.0</jakartaee>
<maven.tomcat.update>true</maven.tomcat.update>
</properties>

And voila, all uploads from the deploy target will now end with "&update=true".


Monday, July 14, 2025

BeyondPod Migration despite BeyondPod being gone.

Some of you - like me - have probably relied on BeyondPod for years to get your daily dose of podcasts. It was, and arguably still is, one of the best podcast managers out there -  or I’m just too used to it to change my podcast player.

However, it has need not updated or maintained for quite a while. And when I just finished setting up my new device (OnePlus 13), I was quite surprised not to find it installed after all (almost all) other apps went through.

Quick check to verify: Indeed, no longer available in the play store


So, side loading from the old phone it is then.


I'm going to walk you through a simple, effective method to clone your existing BeyondPod installation from one Android device to another, ensuring you don't lose your meticulously curated podcast library and settings. We'll be leveraging the power of Google Files (or a similar file manager) to make this happen.


What you'll need:

  • Your old Android device with BeyondPod installed.
  • Your new Android device - duh.
  • Google Files installed on both of them.


But first:

Backup BeyondPod's Settings and Subscriptions using BeyondPod itself on the old device (not going to walk you through). And then move the backup file to a location that you can access from the new phone (or quick-share it over).


Find the APK files:

Open Google Files (or your preferred file manager, but I absolutely recommend Google Files here).

There go to the Apps category



There, find BeyondPod and BeyondPod Unlock Key entries.

Best sort the list by app name, before you scroll through the whole list... so both will be next to each other and rather at the begin of the list, them starting with "B".


Now lets transfer the Files to Your New Device:

Open Google Files on your old device. Navigate to where you saved:

  • The "BeyondPod.bak" backup file.
  • The "BeyondPod.apk" file.
  • The "BeyondPod Unlock Key.apk" file (if applicable).

You can select these files and use the "Share" option within Google Files. The easiest way to transfer them to your new device is often via "Share Nearby" or QuickShare (if both devices are close and have it enabled), or by uploading them to a cloud service like Google Drive, Dropbox, or even emailing them to yourself.


Once transferred, download these three files to your new device, preferably into your "Downloads" folder for easy access.


Prepare Your New Device for Installation:

On your new device, before installing anything, you'll need to allow installations from unknown sources. This setting's exact location can vary slightly between Android versions, but it's usually found under "Settings" > "Apps & notifications" > "Special app access" > "Install unknown apps" (or similar).  Or just open "Settings" and search for “Installation Sources”

You'll need to grant permission to the file manager app (like Google Files) that you'll use to open the APKs.

If you omit this step, Android might ask you during installation later. But if installation does not work then, go back to this step and make sure app installation is allowed from your file manager.


Install BeyondPod on Your New Device:

Using Google Files on your new device, navigate to the "Downloads" folder (or wherever you saved the transferred files).

  • First, tap on the “BeyondPod.apk” file and select "Install." You might get a warning about installing from an unknown source; confirm that you want to proceed.
  • Next, if you have a separate "BeyondPod Unlock Key.apk”, install that one as well.


And finally restore BeyondPod’ settings:

Open BeyondPod on your new device. It might start with no feeds, and that's perfectly fine. Now, go to "Settings" > "Backup and Restore" > "Restore". Browse to the location where you saved the BeyondPod ".bak" file (e.g., your "Downloads" folder) and select the latest backup. BeyondPod will import your subscriptions and settings.


And that’s it.