Now that I’m commuting regularly again using UK public transport, given the occasional (at least so far for me on the days I commute!) delays and cancellations
to services that tend to happen, I was looking for a simple iOS app or website that would allow me to very easily see at a glance what the trains
for the next hour or so looked like in terms of possible delays or cancellations.
There are a plethora of train and transport apps out there for iOS - and similarly there are many websites which technically provide that information -
but unfortunately, at least for the ones I’ve looked at, they seem to either have adverts, large banners requiring scrolling to see the results,
repeated cookie popups, or no ability to bookmark a ‘favourite’ journey and jump straight to that without selecting the ‘favourite’ destination
first and running a search.
It’s very likely there probably is a perfect app / website providing what I want out there that I just haven’t found yet, but I thought
“How hard can this be?”, on the assumption that if the raw train data is available for free, it should be trivial to knock something basic up.
National Rail provides https://raildata.org.uk/, which includes several HTTPS APIs for querying live data of various things,
including departure board information, which can be further filtered down with parameters (i.e. stations being stopped at). You have to register and sign up to access
the API endpoint, but it’s free otherwise, and while some of the spec / documentation for some of the APIs is arguably sometimes a little different to what is
actually needed and returned (the schema seems to vary a little on occasion! - sometimes platform information is totally missing at the schema level), I did
manage to get the information I wanted from it, which does seem to (almost always) effectively be as live as the train departure boards in the stations, and
contains estimated arrival times when trains are delayed.
So I’ve now got an incredibly simple setup where a GET request to my page triggers a direct synchronous request internally to the raildata.org.uk API endpoint
to fetch the data (which is a bit unorthodox, but as I’m the only user and the response time of the API is generally < 300 ms, it works well enough),
the data is extracted from the JSON response and put into an HTML table response and returned to the user agent, essentially providing me with live train data
in a format I completely control.
I’ve also tailored the layout for my iPhone 13 mini screen size, and built in the station pair (as I only need one), which automatically switches over
at lunchtime ready for the journey home later in the day. So I can just use a single constant URL to always get the train information I need for my next
commute journey.
In the future I may decide to architect things a bit more sensibly if there are additional features or (very unlikely) other users of the page,
and I may look into bus time information as well to see if free live data is available for that, but for the moment this works perfectly for my use-case,
and I’m very happy with it, despite its simplicity.
Since I got back to the UK, I’ve been trying to understand and take more of an interest in what’s going on here again (although unfortunately, that’s often somewhat depressing across the political spectrum), and one area I’ve been looking into is Electricity generation (and prices!) for Great Britain.
There’s a large amount of renewable electricity generation from Solar and Wind these days, but it’s obviously highly variable with the weather,
the time of year (i.e. day length for Solar) and cloud cover, so Natural Gas generation is still used to “top up” demand (often to very significant proportions), but these days Coal and Oil don’t appear to be used any more (Gas is the cleaner alternative and can be spooled up very quickly
when needed).
There are a number of nice live dashboards people have made showing the data summary - National Grid: Live and
Live GB Electricity Generation being two good ones, and there are free data feeds from a variety of
different sources (although some of the values are estimates for certain things).
Very few of the existing dashboard sites appear to have detailed long-term historical chart data - they seem to either approximate it with daily averages further back in time,
or just limit the history duration - and the fidelity of some of the charts is often quite limited due to filtering (somewhat understandably given some of the
limitations of the source data), so I decided to try setting up a data storage and chart generation setup to scratch this itch for myself.
Stacked area chart:
Line plot chart:
Given I also wanted high-fidelity charts (non-interactive for the moment), I decided to use Python for this given how nice matplotlib
charts are (especially when using seaborn styling), as I had also been meaning to dust some of the cobwebs off my Python
skills that I hadn’t seriously used for almost two years, and I was similarly keen to play around with some of the newer Python tooling like
uv, which is a more recent Python package and project management tool, which is written in Rust and is much
faster than PIP.
There’s no single central source for a complete breakdown of electricity generation source data in Great Britain - the closest to that seems to
be Elexon who provide regular snapshots (every 5 minutes) via data APIs of various different aspects of
electricity generation and interconnect transfers, however there’s no single API that returns all generation sources, and some data sets
are non-complete, in that they don’t include full Wind power numbers and don’t have any Solar power numbers. There are forecast APIs which
estimate these numbers more accurately, but they’re only updated every 30 mins, so in the end I decided to use a different source for the Solar (PV) generation
which is Sheffield Solar which is also an estimate, but seems to be updated more regularly.
For the moment, I’m using those two data sources for all generation types - note however this does mean
that the numbers for Wind generation are lower (often by around 15%-20% I think) than the actual true Wind generation values, as the source data
doesn’t included “embedded” wind farms. I’m also not including any of the Interconnector transfer amounts (which can be positive or negative depending
on the direction of transfer) to neighbouring countries, which means the charts aren’t an accurate display of Demand of electricity generation in Great Britain.
So I now have an application setup where data is gathered every 5 minutes from the data source APIs, stored in an SQLite DB, and then
I can query the data from a FastAPI-implemented API, which is then fed into matplotlib to plot the above charts locally. The
server is running in a Podman container.
I think the stacked area chart looks nice, but obviously suffers from the typical read-ability issues stacked charts can suffer from in terms
of gauging absolute magnitude, especially when offsets to lower data series happen significantly in a short space of time, and distort or squeeze
the rest of the chart, but it does allow to roughly see overall trends during the day and through a week.
I am tempted to in the future try and additionally store some weather data (temperature and wind speed) for a variety of different locations around
the country to see if plotting those against the Generation values (Demand values would arguably be better) would show likely correlations,
i.e. more electricity use when it’s colder for heating (probably not that much AC in the UK) and more wind generation when it’s windier.
I’d also like to play around a bit with interactive JS/Canvas charts and see if it’s possible to have something that’s close to the presentation
and fidelity of the matplotlib charts.
This is mostly a post to try and get me to start blogging a bit more again, but I will try and make it potentially useful…
When I returned to the United Kingdom from New Zealand last year, I had four laptops (and some other smaller electronic gear) in total I ideally
wanted to bring back with me in some way or another.
One of the laptops was my then-replaced and barely-used older Intel MacBook Pro 15 - which I had replaced with an M2 Pro in 2023 - but I did
still occasionally use as it could run some old x86 Mac software (although the machine itself barely ran due to fans not working), and I didn’t really want to install Rosetta 2 on my M2 Pro.
The other older laptop was my very-regularly-used ThinkPad T480s, which I got in 2019 and generally liked a lot for Linux, but was quite anemic on the CPU-performance front, so I had been tempted anyway to replace it with a newer version.
When I looked into shipping my “stuff” back to the UK, several shipping companies mentioned I couldn’t ship electronics with Lithium-ion
batteries in for safety reasons, which I had envisaged doing for these two older laptops (and then I’d just take the other two newer laptops
with me on the plane back). I enquired with several other companies and the situation was a bit ambiguous, as some companies at first said
it wouldn’t be an issue to send them back, but when I asked someone else at the same company they then said it was an issue,
so I decided it wasn’t worth risking it using this method of getting them back.
I did also look into shipping them back with DHL or something, just as an individual isolated shipment of the two laptops (and other smaller
devices), which while technically possible was expensive and was also a bit complicated, as if I wanted it to get through customs
on the UK side, I seemed to need to address the shipment to myself and not a third-party, which was a bit impractical, as I was planning on
stopping off in Vancouver for a week, and didn’t really want to get relatives to pretend to be me or something.
So I decided to just dispose of the older two laptops, and only bring the two newer ones back with me on the plane, and then I’d get a new ThinkPad
for Linux use when I was back in the UK.
Once back in the UK, I decided to get a ThinkPad T14s AMD, but wasn’t quite sure whether to risk going with the newer Gen 6 version, which didn’t
seem to have as-good Linux kernel compatibility, or stick with the older Gen 5 one which had better compatibility at the time. I also noted in
reviews that there was mention of fans running quite a bit with the Gen 6 AMD. I decided to risk going for the Gen 6 version in the end though.
Once it arrived towards the end of July, I couldn’t easily get Linux Mint or Ubuntu to run on it, as the stock distro kernel was too old for the newer
AMD hardware (I think support had only landed in the kernel in around April). It looked like Linux Mint would within a couple of months release a
newer kernel with better hardware compatibility, so I temporarily installed Fedora on the laptop and used it with that distro for a while.
That experience with the laptop was reasonably good: compared to the T480s, the screen was a lot nicer (a bit brighter and also 16:10 aspect
ratio!) while still being matte, the machine in general was a lot more powerful (CPU and GPU) and the speakers were noticeably better.
Waking from sleep was also faster than the T480s was (still not as quick as the MacBook Pros though!).
On the downsides, the keyboard wasn’t quite as good - there was less key travel, and Lenovo had decided to swap the position of the Ctrl and Fn keys,
which was quite frustrating due to muscle memory (there’s an option to swap them in the BIOS), and the lack of the built-in Ethernet port was
mildly annoying (especially at first with Wifi support not existing in earlier Linux kernels), but is somewhat understandable. Another minor irritation
was that the hinge is quite a bit stiffer to open than on the T480s, which in practice means it’s a lot more difficult to open the lid one-handed when
it’s closed on a desk for example: you end up lifting up the entire front of the laptop instead of the screen just opening.
But the biggest annoyance was the fans: compared to the T480s - where to my knowledge I didn’t have to install or configure anything to get the fans to
behave “normally” - i.e. no air movement or noise when the machine is idle and fans ramp up when the thermal temp increases - it seems with the T14s
Gen 6 AMD, the fans are always on “medium”, even with the machine at idle with temps in the 45 degC range (i.e. even in the BIOS), and the fans speed
up even more as the temps increase when the CPU/GPU is used heavily (understandably).
When Linux Mint 22.2 was released in September (and moved to kernel 6.14 which included better support for the newer AMD chipsets), I re-installed
the machine with that distro from that point on. Unfortunately, it turns out that with this new setup of Linux Mint and kernel 6.14, XOrg would randomly
lock up (although the mouse cursor would still move), although the machine was still running okay in the background, but Xorg/UI-started applications
would crash/close.
This was quite frustrating, as the issue would generally happen every ten minutes or so, and normally happened when I was trying to select text with the
mouse or scroll with the trackpad. If I just left the machine running a UI terminal session doing nothing else, or didn’t use the mouse as much
it seemed far less prone to happening.
I eventually discovered the cause and a work-around for this issue: it turns out that AMD made a GPU driver change with Kernel 6.14 which turned a
feature called Panel Self Refresh (PSR) on, and there was a bug in the implementation with this kernel version which was causing the GPU driver
to lock-up.
A forum post regarding the issue and work-arounds for it can be found on the Framework community forum here.
Implementing the amdgpu.dcdebugmask=0x12 kernel boot parameter mitigation to turn PSR off again solves the issue for me completely.
I had hoped (given the kernel fix for the PSR issue was submitted upstream back in August 2025) that kernel 6.17 (which Linux Mint has just started supporting)
would have included the full fix, meaning the above kernel boot parameter work-around wouldn’t be needed any more, but today I’ve tested that theory
by commenting out the work-around and rebooting, but unfortunately even with kernel 6.17 active the issue still happens, so I still need the
work-around by the looks of things.
All in all though, other than the issue with the fans being persistent and overly-enthusiastic, the laptop’s pretty good, although I do miss the fact
that the T480s “just worked” from my perspective, and I didn’t need to configure anything with the older machine. Battery life on this new T14s Gen 6
also isn’t great - partly I think due to the fans always running, and possibly due a tiny bit to the PSR-disabling work-around. I can get just over
four hours of use with low-CPU usage and medium display brightness (this is after tuning things a bit with powertop), which is worse than my older T480s could do even with a 5-year-old battery.
In terms of the fans, I have tried messing around with thinkfan to try and control the fans a bit more and slow them down when not needed,
and while that sort of works to a limited degree, thinkfan doesn’t seem that stable in practice and often seems to crash or get stuck after
awakening from sleep, so for the moment I’m just putting up with the fans always being on.
Another attempt of my spin on a map visualisation I spotted online.
This early iteration is pretty basic, and is a visualisation of lighthouse positions in the United Kingdom and Ireland as light points illuminating the surface underneath them.
It’s not the most accurate map of the lighthouses, because the projection is a bit squished, and I decided to remove some of the inland (canals and other waterways) lighthouses that
are mostly no longer functional, and I also tried to remove one lighthouse when pairs of lighthouses were very close together (i.e. when
there were ‘High’ and ‘Low’ or ‘Front’ and ‘Rear’ pairings within 500m or so).
I did however decide to include some of the lighthouses on the Isle of Man, which some of the other visualisations I’d seen online didn’t seem to feature. I left out the Channel Islands for the moment though, mostly for composition reasons, but I might re-visit that in a future version.
I rendered it in my Imagine renderer in a somewhat brute-force fashion, however it would have been fairly easy to recreate it fully as a 2D
rasterisation in this basic version, but I might try aligning the positions with 3D geometric terrain as a shaded relief rendering to see how well that works in the future, so I wrote a bit of
infrastructure in Imagine to process lat/lon positions and create objects based on those and used that to generate the scene.