Florian Wesch

The 34C3 info beamer setup

Posted Jan 04 2018 by Florian Wesch

I've been running an installation at the yearly chaos communication congress again. Here's how it worked.

A quick recap

I've been running the info-beamer screens on the chaos communication congress for the last six events. Back in 2012, info-beamer pi didn't even exist and we used the desktop version on small Intel machines (this is also where this funny video was captured). Since then info-beamer got its own "cloud based" solution which makes deploying the now Raspberry Pi based devices incredibly simple. The development of info-beamer hosted was in also motivated by seeing how much work is required to even set up and synchronize five Raspberry Pis during such an event.

Congress has also always been an opportunity to try out new ideas. Since I created the info-beamer software almost 6 years ago, the main problem has always been: how to make it simple to use all the features available. If you're able to program, you always had the chance to build almost any content imaginable, thanks to the info-beamer Lua API. If you don't know how to program, things get more complicated. You'll have to rely on existing solutions or example code. It was rarely possible to combine such solutions without diving into code.

As a result, this year I've been working on an info-beamer package that allows users to create more complicated content through a web interface, without the need to code anything. Going forward this package is probably going to end up as a default package for new info-beamer hosted users.

The 34c3 setup

The 34c3 setup for the screens running in the halls looked like the screenshot above. On the left side you see the Scheduled playlist package and two additional packages for dynamic content: The Twitter tile and the 34c3 self-service packages. In previous years, all devices polled the twitter API on their own. This year I decided to run a central poller on some server every minute that would then sync the twitter package. Basically a cronjob would fetch new tweets, add the linked media files and put all of them in a single directory. Additionally it would create a file named package.links with content like this:

node.json https://<host>/twitter-export/node.json
node.png https://<host>/twitter-export/node.png
package.json https://<host>/twitter-export/package.json
package.png https://<host>/twitter-export/package.png
tile.lua https://<host>/twitter-export/tile.lua
tweets.json https://<host>/twitter-export/tweets.json
node.lua https://<host>/twitter-export/node.lua
cache-image-479bda5a071b38.png https://<host>/twitter-export/cache-image-479bda5a071b38.png
cache-image-eb1f75a30bd75f.png https://<host>/twitter-export/cache-image-eb1f75a30bd75f.png
cache-image-98c9d9cc6bd703.jpg https://<host>/twitter-export/cache-image-98c9d9cc6bd703.jpg
cache-image-87385d129e9267.png https://<host>/twitter-export/cache-image-87385d129e9267.png

It would then trigger the info-beamer hosted sync process which would update the twitter package with all newly added files and distribute them automatically to all devices where they could be displayed.

Deciding how the content is shown is up to the Scheduled playlist package. Its user interface (everything on the right side in the screenshot) is build with the recently added custom configuration interface feature of info-beamer hosted. It allows a package to provide its own HTML/JS based "single page app" interface. That way a package configuration package can be as complicated as it needs to be and use features that a traditional configuration page can't use.

(A small technical intermission: These custom user interfaces are included in the info-beamer hosted configuration page through an iframe that loads its content from a different domain. That way such interfaces can't access authentication cookies and can't directly interact with the info-beamer API. They can only access information relevant for their configuration task and can't mess with the rest of your account)

The scheduled playlist package

This package manages playlists and their content. In the above screenshot you see the "Content cycle" tab. Six different lists have been created. Let's have a look at the Logos list. It's responsible for showing one of six different Congress logos.

Each playlist can have multiple pages. For the Logos playlist, I've added six different pages, each showing one of the six logos since I've selected the One Random page option in the dropdown menu.

Each page can consist of different content like images, videos, etc.. For the logos, each page only uses an image and the plugins addon that is responsible for overlaying the scroller. Clicking on the image (1.png) reveals additional configuration options that decide how to show this content. In this example I'm using a rotating entry/exit effect and a fade. Many more additional effects will be added in the future.

Here's the image from the very top of this blog post again. It shows the Next talk slide:

And here is how its configuration looked like:

The nice thing about all of this is, that I didn't have to program anything during the event. I could easily add new pages or modify their layout just by using this web configuration interface. Compared to the package from 2 years ago, where I had to do everything through code, this was definitely an improvement.

User content website and process

This year I also did show user submitted content. I've used the same content management system as last year. 155 different slides promoting projects, events or other interesting information were uploaded in total. You can download a ZIP file containing all of them here (57MB).

Content gets uploaded on the website and is synced to the running devices pretty much the same way as the twitter package above. You can see the url endpoint doing the export. The result is the 34c3 self service package you can see in the screenshot above.

This year one of the Congress visitors asked, if it is possible to show that slide was just visible on the screen. I quickly put together that feature. Here's now it looked like:

For that to work I had to create a backchannel from each Pi in each hall back to the management website. Fortunately that was pretty simple:

Inside the running info-beamer code I added this snippet:

local clients = {}

node.event("connect", function(client)
    clients[client] = true

node.event("disconnect", function(client)
    clients[client] = nil

local function send(line)
    for client, _ in pairs(clients) do
        node.client_write(client, line)

This snippet keeps a table of all connected TCP clients in clients and adds a send function that uses node.client_write to send a string to all connected clients. This function is called later before the image/video gets displayed:

local function show_user_image(starts, ends, file, x1, y1, x2, y2)
    api.wait_t(starts - 2)

    local img = resource.load_image(file.asset:copy())

    send(string.format("%s,%s,%s", serial, file.asset_id, file.asset_name))

    for now in api.frame_between(starts, ends) do
        util.draw_correct(img, x1, y1, x2, y2)


So who are we sending this data to? In theory you might open up the info-beamer port and connect from an external source but that's a bad idea for several reasons:

  • The device must be reachable from the requesting service. In the case of the 34c3 installation, the Pis were behind a firewall (I think?), so the content management website didn't have a way to reach them directly.
  • Exposing the info-beamer service directly might allows denial of service by flooding it with connections.
  • While I don't think info-beamer has any vulnerabilities through its remote interface, using it from trusted clients is generally a good idea.

So instead I wrote a small package service in the form of a python script. It uses the ibquery.py module to create a TCP connection to the locally running info-beamer process and waits for lines sent with the above send function. For each line it forwards them as an HTTPS request to the content management website running on 34c3.infobeamer.com. Here's the script:

import ibquery, requests
ib = ibquery.InfoBeamerQuery("")
s = ib.node('root').io(raw=True)
while 1:
    line = s.readline()
    if not line:
    requests.get("https://34c3.infobeamer.com/now/update", params=dict(
        now = line.strip(),
    ), timeout=5)

A more serious Proof Of Play system, the Python script might queue and persist each event to ensure that they end up on the content management website eventually, even if the connection temporarily doesn't work.

The remaining piece was to verify the submitted data, putting it in a redis list and using that information to render the page upon request. All pretty simple as info-beamer provides most of the pieces already and I just had to put them together.

User owned info-beamer devices

Due to the lack of screens all over the place, I had to improvise. This year I've made it trivial for Congress visitors to build their own info-beamer powered display during the conference. More than 10 did that (that has to improve next year!).

Installation was as simple as downloading the info-beamer hosted installation ZIP file and adding a provided device connect key file to the /config file on the SD card. The device would boot and is automatically assigned to the info-beamer account used during Congress. Each account can also select a default setup that will automatically be installed on newly added devices. Together that meant that installing a new info-beamer device was really easy to do.

I've also played around with the idea of setting up a special info-beamer powered device that would "infect" every SD card connected to it. That way visitors could walk to this Pi, insert their (hopefully blank) SD card and walk away with and SD card that is ready to boot in their own Pi. Here's the screen I put together:

The process would be visible (e.g. "Formatting SD card", "Writing info-beamer OS", etc) in the bottom area. While the system worked, it didn't really get used as I didn't find a good spot to put it up and I used my own screen to run info-beamer for my Assembly. Maybe next year...

The package itself will probably end up on the package store soon, so info-beamer users can install new devices more rapidly.

Next year

I hope to get access to the screens in the congress center building next year. This year the facility management didn't allow this and the only way to put content on those screens was to carry a USB stick to them every time you wanted to change something. Which I wasn't really interested in doing. I hope next year we find a better solution.

Other than that I think info-beamer provided a great service again and the user content hopefully provided some interesting information to all visitors.

See you next year!

Try it out

If you want, you can install the schedule player package into your account and play around with it. Feedback is always welcome.

A proper source code release of a first official version will hopefully be out by the end of this month. Stay tuned!


info-beamer.com offers the most advanced digital signage platform for the Raspberry Pi. Fully hosted, programmable and easy to use. Learn more...

Get started for free!

Trying out the best digital signage solution for the Raspberry Pi is totally free: Use one device and 1GB of storage completely free of charge. No credit card required.

Follow @infobeamer on twitter to get notified of new blog posts and other related info-beamer news. It's very low traffic so just give it a try.

You can also subscribe to the RSS Feed RSS feed.

Share this post:

Share using Twitter

Questions or comments?
Get in contact!