LED Panel (2019-08-04)

The finished LED Panel with Layout

I built this panel as a project during the summer holidays. This is a small writeup so you can build your own. The entire thing ran me about 200.- CHF, but you could probably find some of the parts for cheaper.


The panel displays the current time/date and temperature, and the current weather as an icon. Different icons are used depending on the time of day. It’s fairly extensible, thanks to the layouts mechanic I built (more below).

Parts List

I followed the Adafruit guide for the hardware side of things.


Below a quick sketch of how I built this. My woodworking skills aren’t the best, so this is built to be easy. Sketch of the frame

Software (on my Gitlab)

To drive the matrix I used hzellers’s python bindings, which I wrapped in classes to draw images and text for easier usage.


I built some classes for the display. You can create DisplayComponents and draw them into areas (ex. vertical_top={'x': 0, 'y': 0, 'w': 32, 'h': 16})
Each component then draws itself to the matrix.

Possible Layout

A Layout is made of multiple areas and the display switches between different layouts every minute, to avoid unevenly stressing the LEDs.


For real-time weather data aswell as forecasts I used OpenWeatherMap’s API.

Document Workflow (2019-04-21)

Workflow in action

I use Markdown (md) for preparing my documents, presentations, and notes. Thanks to md files being plain-text, they can be easily versioned using Git.

There are several tools involved in this workflow:

The general concept is that you write your document in md, then Pandoc compiles it to LaTeX, then finally to a PDF.

For this workflow, I prefer installing Pandoc locally and using an auto-refreshing PDF-viewer (I like Zathura with the MuPDF backend). I use a script which runs Pandoc when the md file is saved.

Severin Kaderli has written a great template for usage with this workflow. He’s also created a small docker image which includes all the necessary depencencies.

When working with others, we usually also use it in a continuous integration with GitLab-CI.
As an example, you can look at this repository with documents for a databases class.


Markdown is simple enough to use and the Pandoc Manual is a great resource. You can mix in LaTeX with your md for things like math and advanced layouting.

Check out this document for some example usage.

To use Severin’s excellent templates check out the repo as a submodule in a .latex folder.
You can then compile the document using this:

.latex/ ./

This command will create a Document.pdf.

You can also use the beamer argument:

.latex/ ./ beamer

Which will use the Beamer-Template and create a Presentation.pdf.

Using CI

Using the Gitlab-CI might look like this:


  - Build


  stage: Build
    - .latex/ ./
      - "*.pdf"

Breaking Audbile DRM (2018-12-29)

I wanted to to listen to Skunk Works with a free audible trial.

Pleasantly surprised, I notice that you can download the audbiobook. However, I quickly realised that it’s an .aax file. Try to play it using mpv; “Error decoding audio.”.
It turns out that AAX is an encrypted audible format.

Authcode / Activation Bytes

Fortunately, someone created audible-activator, a python script which opens audible in a browser and extracts your personal DRM key.

This key is unique to you, but you can decrypt all your books using it. To get the code, run the script, log in, and wait a second You’ll get an output like this:

$ ./
[*] Player ID is jrzt34fl3gS34z/p9KLLIw/ugaf=
activation_bytes: c0ffeed00d

I recommend saving the activation bytes to a file called .authcode in your home directory.


Once you’ve extracted the activation bytes, you can use another tool, AAXtoMP3, to convert the AAX to a useable format, like MP3.

$ AAXtoMP3 -s -- audiobook.aax

This will create a directory structure based on the metadata in the AAX, containing the audiobook MP3. -s makes sure, only one file is generated. Otherwise, a file for each chapter will be generated, which you might like better.

How it’s built (2018-06-09)

To build this website, I employ three bash scripts, which together fill in the “dynamic” content into the index.html. One generates blog content from markdown files, one generates a list of my GitLab projects from their API, and the last one fills in the actual html.

The files can be found here: blog generator, project generator, page filler.

The blog generator

The generator works as follows:

  1. reads in a directory of markdown files
  2. sorts them by modify date
  3. generates html from them using pandoc
  4. sticks all the posts together with an <hr> separator
  5. outputs to stdout

The project generator

The projects are generated as follows: It first gets all the necessary info in JSON format from the GitLab API, the uses pcregrep to extract the URLs, names, and description of my public projects.

curlout=$(curl -s "<userID>/projects")
urls=$( echo "$curlout" | pcregrep -o2 '("http_url_to_repo":"(.*?)")')
names=$(echo "$curlout" | pcregrep -o2 '("name":"(.*?)")')
descs=$(echo "$curlout" | pcregrep -o2 '("description":"(.*?)")')

Then, they’re filled into an html template using sed:

while read name; do
  projects[$i]="$(echo "${projects[$i]}" | sed "s|<++name++>|$name|g")"
done <<<"$names"

The filler

In the end, the filler appends all the generated content to the index.html file, using:

echo "$content" >> index.html

While this isn’t the most sophisticated system, it’s adaptable and it’s very easy to write new blog content in markdown.