Year of the X Festival: IoT in less than a day!

Today I attended the Year of the X Innovation Festival and happened to sit in a workshop run by Iteratec titled IoT in less than a day. What I love about Year of the X festivals is, that there is a general you can touch this attitude to the workshops and demos. This workshop was no exception! The company sent a team of over five developers and designers. They brought all kind of sensors ranging from a motion detector to an ultra-sonic distance sensor. There were also plenty of actors, for example, a self-built matrix display and an Internet-connected blender (mixing smoothies in the company colors). πŸ˜‚

During the workshop, attendees were invited to throw some IoT ideas into an online collaboration tool challenging the team to build a few of those in less than a day. An IoT challenge? I re-arranged my agenda to make some room! A couple of minutes later I found myself in the back office were the friendly Iteratec guys helped me to get started.

The Idea

I have a DHT22 temperature and humidity sensor connected to a RaspberryPi in my lab at home. The data is pulled once a minute by Prometheus (a time series database) and occasionally visualized using Grafana (a graphing frontend for monitoring data).

A very different approach was shown in the workshop. All sensors published their data to a central message broker and actors (or other sensors) could subscribe to the messages. I wanted to learn that and decided to connect a DHT22 sensor to a message broker via a NodeMCU. A platform I had my struggles with before. 😩

The Approach

The NodeMCU Platform can conveniently be programmed using the standard Arduino IDE which makes it easy to get started. There are libraries for all the common tasks. In fact, the hardest part was to get the UART interface working with macOS. πŸ™ˆ After that, the plan was as follows:

  • Connect to the wifi
  • Connect to the message broker
  • Read DHT22 sensor
  • Publish sensor data to message broker
  • Wait a couple of seconds and go back to Read DHT22 sensor

With a little help here and there (snprintf() on Arduino ignores the %f pattern and ignores floats!) I got everything working in a couple of hours. It was really great that the workshop organizers had brought almost an entire lab in boxes. πŸ‘

As message broker I used, a free message broker that has a nice visualization. It was very helpful to see if and what messages were send from where to where. I can recommend this service!

The Result

Serial console output of the NodeMCU:

Message broker visualization:

The NodeMCU and connected DHT22 sensor.

The Code

#include <ESP8266WiFi.h>
#include <MQTTClient.h>
#include "DHT.h"

const char *wifi_ssid     = "wifi";
const char *wifi_password = "secret";

const char *mqtt_server   = "";
const char *mqtt_id       = "my_first_node";
const char *mqtt_user     = "login";
const char *mqtt_password = "secret";

const int  dht_pin        = D6;

WiFiClient net;
MQTTClient client;
DHT dht(dht_pin, DHT22);

void setup() {

  // wifi
  Serial.print("wifi: ssid=");
  Serial.print("wifi: password=");
  Serial.print("wifi: connecting");
  WiFi.begin(wifi_ssid, wifi_password);
  while (WiFi.status() != WL_CONNECTED) {
  Serial.print("wifi: ip_addr=");
  Serial.println("wifi: done!");

  // message broker connection
  client.begin(mqtt_server, net);

void connect() {
  Serial.print("mqtt: server=");
  Serial.print("mqtt: id=");
  Serial.print("mqtt: user=");
  Serial.print("mqtt: password=");
  Serial.print("mqtt: connecting");
  while (!client.connect(mqtt_id, mqtt_user, mqtt_password)) {
  Serial.println("mqtt: done!");

void loop() {
  // vars
  float temperature = 0.0;
  float humidity = 0.0;
  String message;

  delay(10); // stability fix
  if(!client.connected()) {

  temperature = dht.readTemperature();
  humidity = dht.readHumidity();
  message  = "temperature=";
  message += String(temperature, 1);
  message += " ";
  message += "humidity=";
  message += String(humidity, 1);  Serial.print("message_out: ");
  client.publish("sensors", message);


void messageReceived(String topic, String payload, char * bytes, unsigned int length) {
  Serial.print("message_in: topic=");
  Serial.print(" payload='");

My Design Jam Experiences

Yesterday, I joined the Munich Design Jam for the second time. Last time, hosted at IXDS Munich, I created an Alexa skill prototype for social and educational cooking with a team of strangers. This time the topic was Microsoft Hololens-assisted furniture assembly for millennials. Organized and lead by Rachel and Johannes and their team, it was once again an enriching and fun experience. The event was kindly hosted by Vectorform’s Munich office.

A Design What?

What the heck is a Design Jam you ask? Here is the official definition from the organizer’s website:

A Design Jam is a one-day event that brings together Designers, Developers and Entrepreneurs, to solve a problem and build a prototype in just 10 hours (or so). Each Jam’s theme will be announced on the morning of, for maximum excitement.

Unlike last time, I knew most of my team. It consisted of my brother Thies, my fiance Tina, and Yuliya who joined our team as a second designer.

Eight Minutes, Eight Ideas

A Design Jam is run on a tight schedule. Every task has a time limit, and those limits are challenging! After all, you have about 8 to 10 hours to create a presentation and a prototype, involving a technology you may have never heard of or touched before.

Our first task was to come up with eight different ideas regarding the problem of furniture assembly in eight minutes. That sounds harder than it is, once you started the flow, new ideas won’t stop coming to mind. Maybe that’s the reason for the time limit. πŸ€”

Once we had our ideas noted down, we explained them to each other in our group and voted on them using sticker dots.

Everyone then had to pick one idea and spend a couple of minutes elaborating it. Most of us picked an idea that wasn’t our own but from another team member and that we have found interesting.

We presented our elaborated ideas to each other and totally blew the two-minute time limit we had for that. 😜

Categorizing Ideas

Then we had to place our ideas on a value and effort matrix, which invoked some discussion and took as slightly longer than expected. The most interesting quarter of the matrix is the target quarter. That are ideas which are expected to provide the customer with high value and require little effort to develop or implement. We voted once again, this time on all ideas from within the target quarter. To make things more challenging, we landed a tie between an idea involving QR codes and an augmented reality disassembly guide. We could not break the tie, so we went with combining these two ideas into one, which gladly worked out. πŸ‘

Earn Your Pizza

The host ordered plenty of pizzas for everyone and just as they were delivered we finished with our tagline. It reads QRreconstruct - sustainable furniture that follows you! You can read from the tagline that we are (a) not native English speakers and (b) were starving. I wish we had found a better tagline but on the other hand, we were really exhausted by the work we had done so far. Funny, how easy it is to compromise when the smell of delicious pizza is in the air! πŸ˜‚


After lunch and networking, we started prototyping and creating our presentation. Johannes used the afternoon to go from team to team and give everyone the chance to experience the Hololens themselves. He and the other organizers also checked our progress regularly and advised us when needed.

Our team decided to shoot a video explaining the app and a typical use case. Although scratching on the upper end of the definition of millennial, I was chosen to star in our awesome video. 😬

Here is the video:

Presentation And Party!

In the late afternoon, it was time for all teams to wrap it up and deliver their presentations. This is usually the best part of a Design Jam and this time was no exception. The creativity level in the room was cranked up to 11 πŸ˜‰and we had some good fun with the entertaining and convincing presentations that were delivered.

We spent the rest of the evening having some beer and interesting conversations about this and that and of course technology.

I recommend attending a Design Jam to everyone who likes designing and prototyping!

How to configure WireGuard on OpenWrt/LEDE using LuCi

A while ago, I simplified the way WireGuard interfaces are configured with in-tunnel IP addresses.

So here is a new step-by-step guide on how to configure a WireGuard tunnel on OpenWrt/LEDE. WireGuard is a cryptokey routing protocol, or, as many refer to it a VPN.


For this guide I assume you run the latest snapshot of, let’s say LEDE. I will also assume that you have a basic understanding of WireGuard.

First step is to create the WireGuard interface. Go to the Interfaces page and create a new interface. Select WireGuard VPN in the dropdown menu. If this option does not show up, then you are missing luci-proto-wireguard πŸ’©. Head over to Software and install it.

Think of good name for the interface, in this article we will proceed using foo 😬 Next thing you will see is the interface configuration page. I tried to make it as self-explanatory as possible by including helpful hints below the options. Most important configuration data are the Private Key of the interface and the Public Key of at least one peer. Also, don’t forget to add one or more Addresses and the network or address of the other end of the tunnel to Allowed IPs. Otherwise the tunnel won’t work as expected.

If you like to add some post-quantum resistance, you can do so in the advanced tab.

Click Save and Apply once you are satisfied.

Now you should have a WireGuard tunnel interface

I also created a monitoring module. It is called luci-app-wireguard and should be available in all major repositories. Why not give it a shot while you are at it?

You can also check on your WireGuard interface(s) using wg on the command line.

If you find any bugs, please report them. Thanks for reading and happy cryptokey routing everyone!

Hint On some devices it may be necessary to restart the device after after installing luci-proto-wireguard, so that the netifd daemon correctly loads the helper script that comes with wireguard-tools.


The former approach required an static interface on top of the WireGuard tunnel interface. Unfortunately, this was introduced to address concerns that were raised in the merging discussion on luci-proto-wireguard. I never was a big fan, but saw it as a necessary evil to get the change merged in time. #politics It’s all history now πŸ™ƒ