Weather and air-quality monitoring system (DIY)

As mentioned in the previous post, I got involved in the citizen science project called LeuvenAir a few months ago. This started out as simply setting up a low-cost fine-dust sensor on our terrace (following the description that can be found here) and connecting it to the LeuvenAir database. This was the first time in my life that I was connecting pieces of hardware together with jumper wires, and I found it interesting enough to want to do a bit more…

First I wanted to simply display (and log) the recorded values locally on a small screen, so I bought a Raspberry Pi 3+ (RPi) and a Sense HAT, and combining these I made a data logger that also displayed (scrolled) the recorded air pollution and weather measurements using the small led-matrix of the Sense HAT (colour-coded according to specific pollution/comfort levels). The RPi was running 24/7, while the display could be turned on and off by putting the RPi in an upright or horizontal position (using the accelerometer sensor of the Sense HAT). At this point life was easy, I got the fine dust data along with the outside temperature and humidity values from the LeuvenAir sensor (via the API of the original German project, luftdaten.info – which gave the idea to LeuvenAir -, as all LeuvenAir sensors are also sending data there), and the barometric pressure from the Sense HAT. All of this was handled by a small script that I wrote in Python.

Then I decided that I wanted better sensors outside, and that I wanted to measure inside too, preferably both in the living room and the bedroom. Of course these new units had to be wireless, and preferably everything had to work even after a power cut more-or-less automatically. Oh, and I wanted to push the data to an Internet of Things (IoT) platform and also make an only locally reachable website that displays live data and graphs for everything – a bit like the weather status page of the Mercator Telescope… This is where things became slightly more complex. Below I am going to give a description of the system as it is now, without discussing the timeline because a) you are not interested in that, b) I don’t remember all the details anymore…

Central computer

  • Hardware: Raspberry Pi 3+ [with Sense HAT]
  • Role: Data logger, data plotter, Apache web server, MQTT “server”, dot-matrix display
  • Measurements: Processor temperature, barometric pressure
  • Description: The Raspberry Pi is an extremely small (bit bigger than a card deck) computer that is running a Linux-based operating system. This is the main hub of my sensor-network. It is placed in a black Short Crust Plus case under the TV. On it there are two python scripts running continuously: 1) monitor_home.py taking care of the data logging (saving all measurements – read in from an internet API or received through the MQTT protocol – to daily .csv files once every ~2 minutes), feeding the current values to the matrix display of the Sense HAT (if it is in the on-orientation position), and publishing these to an only privately accessible IoT platform called Cloud4RPi so I can easily check the status of all sensors from anywhere. It does not use more than 1-2% of processor power, and most of the time it is simply idle – waiting for time to pass between two measurements. 2) grapher.py is responsible for an around-the-clock generation of plots that are displayed on a website that is placed on the Apache web server on the RPi (these pages automatically reload every minute in a browser). It runs in one minute intervals (using 25% of processor power when not idle) and creates daily, weekly, monthly, and yearly plots of (selected) temperature, humidity, pressure, and fine dust concentration sensor measurements. Besides these plots, it also creates a colour-coded overview table of the latest measurements. These processes are light enough that the RPi does not need any active cooling. The RPi has a preferred IP address, so if no other device on our network gets assigned this IP (after a network/power outage some devices need less time to restart/reconnect and I can not give fix IPs directly from the router of our internet provider, so in theory it can happen that by the time the RPi restarts its preferred IP is already taken), then the RPi has a practically fix IP. For full automation I would need to implement that these two scripts run automatically after reboot, but I can always reach the RPi using a virtual desktop using VNC Connect / VNC Viewer, so it is not such a burning issue right now.

2018_sensors_leuvenair4

There is a video showing how the very simple colour-coded scrolling display works on my YouTube channel, while here below there is an image of the main local webpage that shows the daily plots, and an image of the page where you land after clicking on the humidity plot (which displays the daily, weekly, monthly, and yearly plots).

2018_sensors_overview

2018_sensors_humidity

These are more than a month old screen shots, but at that time the fine-dust concentration was high, thus you could see a lot of different colours in the overview table ;) Also these were taken just 4 days after we came home from our holidays in France, so in the weekly plot you can see that while we were away the humidity in the bedroom stayed more-or-less constant throughout the day, then after we came home, it always went up during the night (we sleep with doors and windows closed most of the time, so there is not much air-circulation during the night).

LeuvenAir sensor-cluster on the edge of the terrace

  • Hardware: NodeMCU ESP8266 [with SDS011 fine-dust sensor, DHT22 temperature/humidity sensor, BME280 temperature/humidity/pressure sensor, jumper cables, transparent flexible tube, zip ties, USB power supply, plastic tube housing, netting against animals]
  • Role: Monitoring outdoor fine-dust concentrations and weather
  • Measurements: Temperature, humidity, barometric pressure, PM 10 and PM 2.5 concentrations
  • Description: This cluster controlled by the firmware of luftdaten.info does its work without me having to program anything. The three connected sensors are recognised automatically (after an initial setup). Every 2.5 minutes (it is a default setting to extend the lifetime of the fine-dust sensor) it takes a measurement using the connected sensors and uploads these to the database of luftdaten.info and LeuvenAir. I am simply using the API of luftdaten.info to get these values onto the RPi. Normally it is possible to reach the latest values locally too (using an API that runs on the ESP8266 itself), but I found this route to be very unstable, depending on the wireless connection and the processor load of the ESP8266. It would be better if I could send data using the MQTT protocol directly to the RPi, but since I can not change the firmware here (without writing my own), I have to depend on the luftdaten.info servers being online instead… Originally only the DHT22 was connected, I bought the BME280 a bit later to get more accurate values, and to have pressure measurements too. The whole system boots up and starts working without any interaction after a network/power outage.

2018_sensors_leuvenair1

2018_sensors_leuvenair2

2018_sensors_leuvenair6

Wireless indoor sensor 1 in the living room

  • Hardware: ESP32 Feather Board [with DHT22 temperature/humidity sensor, USB power supply, jumper cables]
  • Role: Indoor weather monitor
  • Measurements: Temperature and humidity
  • Description: This was my first bigger extension to the system, also the first time I had to do the whole thing from scratch. I followed the description here, almost everything is exactly as it is written there. The script that is running on the ESP32 board is written in MicroPython (a compact version of Python for microcontrollers), and it simply polls the DHT22 sensor to take a measurement every four seconds and publishes the values to the MQTT broker (the RPi). I have written the code in a way that after a network/power outage everything reconnects and starts running again automatically. (In practice this does not always work, maybe because after a power outage it takes much longer for the RPi to restart, therefore there is no MQTT broker yet to connect to when this sensor restarts, so things fail, but this only happened twice in the past two months and it is difficult to debug…) For this sensor I even built a nice housing from LEGO and placed it on a bookshelf (behind some books).

2018_sensors_leuvenair5

Wireless indoor sensor 2 in the bedroom

  • Hardware: ESP32 Feather Board [with BME680 temperature/humidity sensor, USB power supply, jumper cables]
  • Role: Indoor weather monitor
  • Measurements: Temperature, humidity, and volatile organic compounds (VOC)
  • Description: This was the last addition to the system, the setup is basically the same as for the other wireless sensor, except for some small changes in the coding and wiring due to the different sensing chip.

2018_sensors_leuvenair3

And what is the point of having this system? Nothing, I simply like gadgets data and plots :D But seriously, even though this is my number one reason (and my interest in weather), it is also quite handy that now I can see when it is worth opening windows to improve the indoor temperature/humidity. Also, it turns out, that blue-coloured haze on sunny mornings is simply high fine-dust concentration, a.k.a. air pollution :(

The spring months of 2018

It has been a while again, so it is time for another diary-style entry. My new job at TML is going well, I spent the first days reading course texts to get a bit of basic background knowledge (Traffic demand modelling, Transportation systems, Basics of transport economycs, etc.), but soon after I already started working on actual tasks. I am involved in the ClairCity project, by doing fleet models (basically mileage and emission predictions for different propulsion-type vehicle groups in cities), and mode-choice models (trying to tell what kind of transport mode a person will choose based on some input parameters, e.g., what is the chance that a young adult who has an average income and no car chooses to take the bike when she needs to take a 2 kilometer long commuting trip in the morning hours of the working week). This involves a lot of work with pretty cool statistical data bases, which I always liked. I presented some of my results already on one of our team meetings, and got to discuss with other people outside of TML on the annual ClairCity meeting in Sosnowiec (Poland) in April. I totally forgot to mention it the last time, but my brother (who is a flight attendant at Emirates) had visited me here in Leuven just a few days before I started my new job, and we had a nice burger and chat together :)

2018_spring_brothervisit

Thanks to a colleague I got involved in LeuvenAir, which is a citizen science project built on measuring fine dust concentrations using low-cost sensors in Leuven. I will write about this in more detail in a separate post, because having an air quality sensor quickly escalated into me buying a couple of more sensors, some wireless chips, and a small Raspberry Pi computer to make a complete weather and air-quality monitoring network around our apartment…

I had a pretty average early season on the bike, but average in this context is actually very positive, because the past years I always had a strong cycling spring. My “old” road bike surpassed the total mileage of my first road bike towards the end of April, becoming my highest mileage bike so far (32365 km and counting), and after waiting for almost two months for proper dry weather and clean roads, I finally got to ride my new bike during the annual Tornado Club-weekend in the Ardennes (and for already a total of 2252 km since then). The second ride during that long weekend in the Ardennes was actually my highest elevation gain ride within the borders of Belgium ever.

2018_spring_DutchLimburg

Other memorable rides from the past months were: a sunny roller-coaster in the Dutch Limburg with Hao, the first 200 km+ ride with the new bike for a slice of cake (I switched back to the Arione saddle for this already, the Aliante was not such a good fit for me), my first visit to the Oostkantons with some Instagram/Strava celebrities (where finally I was not the only one in a fancy outfit :D), my longest solo ride ever: 306 km over the highest points of Belgium and the Netherlands, two gravel rides: one short one just outside of Leuven through beautiful forests and fields, and a longer one around the top of Belgium in great company, and my first visit to the Eifel region with a group of TML colleagues.

2018_spring_Oostkantons

It is a shame that the Instagram photos taken during rides are not visible anymore on Strava (only when added manually afterwards, which I do now), because I really enjoyed that I can just look back at these there :(

2018_spring_photos1

On top of all of this, in the beginning of May we had a week of cycling between the Ardèche and the Cévennes regions in France, which was pretty nice. Those without the bike could enjoy the sunshine at our private pool, and an excursion to Nîmes on the afternoon of the rest day. In six days I biked 665 km with almost 11000 meters of elevation gain, most of the time on small, practically traffic-free roads in great weather. (The week after it was snowing there, so we were definitely a bit lucky.) All rides were great (1, 2, 3, 4, 5, 6), but the most memorable moments are from the second day and the rest day.

2018_spring_France

On the second day just after reaching the top of the climb leading up to the Plateau de Montselgues we got into a thunderstorm. I thought the best is to keep on biking, because otherwise we would just get cold and wet (since there was not much shelter around), but things got much worse really soon. The storm quickly grew into a torrential downpour containing centimeter-sized hail, water was coming from everywhere (from above, from the road, and from the side blown by strong gusts of wind), and the temperature dropped to 8 degrees Celsius. I tried to descend towards the warmer altitudes as fast as I could, but it turns out that this way I basically kept going along with the core of the storm (because the people behind me who either took the descent slower or were still on the climb on the other side of the mountain got much less extreme weather, some even made it without encountering any ice). It took me more than a half hour to get down the mountain, of which at least 20 minutes was in hail (which was not only painful but also left impact cracks on the top layer of my helmet at multiple spots). At the bottom I was shaking from the cold, so I stepped into the first open pub I saw, ordered two hot chocolates (when I actually managed to form words from shaking), and got hugged by a large middle-aged French lady while trying to warm up (which was a bit more intimacy than what I would be normally comfortable with from a stranger, but she was so warm!). It took me 20 minutes to get into a state that we could continue… Luckily as soon as I got back on the bike I managed to warm up quickly, and since it was not raining anymore, things got back to normal very fast.

2018_spring_photos2

For the rest day I included the climb to the Mont Bouquet (also known as the local wall) in the route, and if you think 4.6 km at an average 9% simply would not be enough for a recovery ride, then you might be one of the lucky few who would have honestly appreciated the 500 meters at 16-18% in the middle :D (The rest was also typically in the double digits, and only a few short flat/downhill sections pulled the average below ten percent.) That was an epic climb, but I am sure nobody will let me plan rest-day rides anymore. Besides the biking, I got a short initiation into fly-fishing from Willem, and we had a nice campfire on the last evening. Driving back was a bit less fun after a week of cycling, but there is nothing I can not handle with a liter of coffee I guess…

Since we came back Filou (our adopted cat) is much more cuddly and affectionate than he was before, he comes to sit with me in the couch every evening (he used to always lie in one of his spots before, now he chooses me most of the time), and he follows me around the apartment quite often. He also became more vocal after being almost completely silent in the first few months, so now every day after work he runs to the door when one of us arrives home and probably tells us never dare to leave his side ever again. Or that he needs more attention. He is the cutest ball of fluff ever. My parents also had their annual visit, this time we went to the Durbuy, Dinant, and Gent. They also liked Filou :)

2018_spring_Filou

And last but not least, a few words about Liverpool FC. This season was again a very good one for us, and I managed to watch almost every game. While Coutinho was sold in the winter transfer window, with the arrival of Virgil van Dijk (and with the better and better performance of our young wing-backs) our defensive line got a serious upgrade, which resulted in a significantly less conceded goals in the second half of the season. Our front three (Mane, Firmino, and Salah) played wonderful football, and Mohamed Salah (the Egyptian king, running down the wing) broke most Premier League and Liverpool goal-scoring records during his first year in a red shirt.

2018_spring_Salah

We finished comfortably in fourth position in the league, and the glorious European nights have also returned to Anfield (a.k.a. Champions League football). After going through from the group, in the quarter- and semi-finals Liverpool played exhilarating football in front of the Kop (3-0 against Manchester City, 5-2 against Roma – We’ve conquered all of Europe, We’re never gonna stop…). As a result we played our second European Cup final in three years, which really says a lot about how good Jürgen Klopp’s team really is. Unluckily Mo Salah got injured early in the game, and our goalkeeper (Karius) made two huge mistakes, so we lost against Real Madrid, but reaching the final was already an amazing achievement. I liked this season’s team and jersey so much, that I even bought a special 125th anniversary double shirt boxed set including a replica of Liverpool’s first ever jersey from 1892, a 2017-18 home shirt, and a book of 25 historical photos. It is a really nice memorabilia. I am looking forward to the next season!

Canyon Endurance CF SLX DISC 9.0 SL

After getting a new job it was time to get a new bike. With this purchase my 3-year (31000 km) old Canyon Ultimate CF SL 9.0 Di2 becomes my bad-weather road bike (because it is in a way too good shape to be sold, and I still really love it), and the new Canyon Endurance CF SLX DISC 9.0 SL takes the role of a good-weather, epic-ride machine. (While the Canyon Inflite AL SLX 8.0 Pro Race is now only for off-road riding.) It took me again quite some time to make the decision about the exact model, for a short while I even fancied getting a nice titanium frame and build up a bike myself with the SRAM RED eTap wireless electronic groupset, but maybe I am not “old enough” for that. At the end I went for a more relaxed geometry because I am definitely not going to be racing with this bike, but I want it mainly for long days in the saddle instead, and a bit more comfortable frame is definitely welcome for that purpose.

To complete the bike I got a SRAM RED DZero Power Meter, a K-EDGE Wahoo Splayd Race Mount, and Look Kéo 2 Max Carbon pedals. The total weight is ~7.8 kg with the pedals, Canyon bottle holders, and the Wahoo EDGE Bolt and its mount included. Unluckily I could not ride with the bike yet, because the winter really does not want to leave Belgium yet, which means that there is still a lot of salt on the roads, even in the rare dry periods. Hopefully this was the last cold spell this year, and soon I can have the inaugural ride of this beauty.

20180318_NewCanyon-1

20180318_NewCanyon-2

20180318_NewCanyon-3

20180318_NewCanyon-4

20180318_NewCanyon-5

20180318_NewCanyon-6

20180318_NewCanyon-7

20180318_NewCanyon-8

From saying goodbye to astronomy to finding a new job (and everything in between)

My postdoctoral contract came to an end last year at the end of September, and I had made the decision already quite a long time ago that I would not apply for an extension. I have been doing more or less the same in astronomy (namely asteroseismology) for the past ten years, and I wanted to move to a new field, where I can deal with more practical issues, and contribute to more burning problems of our society. I never regretted choosing astronomy as a profession, it was my childhood dream, and I got nice achievements in the field, but I have no regrets stopping and starting in a completely different topic. Change can be a good thing.

I had a very nice goodbye reception with more than a kilogram of M&Ms, three cakes and a lot of other snacks, so everybody was happy (with the food, not with me leaving), and I even got some presents from my colleagues (among others two Star Wars themed LEGO sets). Since I am still co-supervising a PhD student (and that is something I still really enjoy, so I don’t want to stop with it) I have kept my affiliation (and staff card) as a voluntary (unpaid) research fellow at the university (for which I am grateful to my old boss), but that changed nothing in the fact that I became unemployed in October.

Thanks to the very generous Belgian social security system (we pay those high taxes for a reason after all) I did not have to rush into a new position, so I had time to look for jobs that would really match both my skill set and my interest (and the fact that I really did not want to commute to a job outside of Leuven).

I definitely took my time. I used October to just relax and – as already mentioned before – just bike as much as possible. Luckily the weather was still great, so I could really make the most out of the month this way. By the end of October I had satisfied my biking needs to the full extent, so I started browsing the job market more actively. I got myself a job coach who helped me organise my thoughts about what kind of job I would like to do, and who also gave some useful tips on how to organise my job search and how to prepare for an interview. I set up some very specific keywords on the website of the VDAB (the Belgian unemployment office), so I would receive only relevant job offers, and of course I refined my linkedin profile too. I also attended a job fair aimed especially at people with a PhD, but that was more of a networking practice than anything else.

20180211_pastmonths

In the beginning of November we went to the Ardennes for a few days where we had the nicest Belgian hike so far (around the branches of the river Ourthe), and surprisingly we still got enough warmth from the sunshine to eat pancakes on a terrace.

Besides the job search, I still had quite some time do do other things. Of course while I was unemployed I did all the groceries, cooking (with my speciality being a delicious Pad Thai), and cleaning around the house. Whenever the weather allowed I also went cycling (for example for a nice 100 kilometre loop between Namur and Huy), and on the late evenings I played either FIFA (my biggest achievement this year is the treble with Liverpool on World Class difficulty), The Legend of Zelda: Breath of the Wild (a really great game on the Nintendo Switch), or Cities: Skylines (a city building game). Hoping to get more group rides next year I joined the Vlierbeekriders cycling club (because with Squadra Tornado people are way more racing oriented, so during the good weather months everybody is off to races on the weekends and there is nobody left to do long rides with).

I have to say that by December I started to get a bit bored at home sometimes, so I got really excited when one day I found a very exciting job opening in my mailbox. It was a junior researcher position at Transport & Mobility Leuven to contribute to both national and international research projects within the area of transport research (e.g., work out adequate solutions for critical mobility issues, making use of state-of-the-art transportation models, evaluation techniques, statistical analysis and data collection). Not only was the job-description interesting, but it was also clear to me that I am a very good match, so I immediately knew that this was the job I want. I also realised that I actually know someone at the company (from cycling), so I could use this connection to get to know more about the work and atmosphere at TML. The things I had heard made me even more interested, so I sent in my CV and motivation letter on the 19th of December.

In the meantime I attended a great Christmas lunch with a dozen of other people at my PhD student’s place (for which I made a beautiful and tasty New York cheesecake with meringue topping), and we also adopted a cat. I am so happy Clio agreed to that, it is so nice to have Filou around :)

The application deadline was at the end of the year, but I already got a reply on the 4th of January, in which I got invited for an interview. The only one I had before was for my PhD, and it was with people I already knew from my ERASMUS stay, so I did not know what to expect… So my first real “corporate” interview was on the 9th of January, and it went very well. It took 1.5 hours, and we talked about a wide range of topics (in English), ranging from what I did during my academic career to my favourite problematic traffic situation in Leuven. I even got to talk about my star atlas project. All in all I came away with a very good feeling, wanting the job even more. Ten (very long) days later I got an email that they decided to hire me! I was so happy that I wanted to go and high-five Filou (after calling Clio and telling her the good news), but he did not really understand why I am jumping around in the living room :D That evening I was official to the yearly dinner of the Institute of Astronomy, so I got to celebrate with champagne too :) I signed my contract on the 22nd, and started working already on the 1st of February (by bringing two home-made cheesecakes, since it was not only my first day but also my 33rd birthday). I have a lot to learn, but it is very interesting, so I am convinced that this is the beginning of another exciting chapter in my life!

Fluffball Filou

We were considering getting a dog/cat for a longer time already when in the beginning of December we found Filou on one of the larger Belgian pet-adoption websites. Clio is generally more of a dog person (and we both like dachshunds a lot), but living in an apartment and being away from home during the day (plus none of us being much into going for a walk multiple times a day – even if the weather is bad), we decided that it is better if we get a cat, that is more suited to our lifestyle.

Clio prefers longhaired cats, that’s why Filou caught her attention in the first place. Based on the information on the shelter’s website, we were a very good match for Filou (most importantly he lived indoors his whole life), so we arranged a meeting in Tienen (the next bigger city along the highway 20 minutes to the East) to get to know him and talk about the practical details of a possible adoption.

The meeting went well, although bot of us were quite surprised (or maybe even shocked) when we first saw Filou, because he was much bigger than we expected :) But he behaved very nicely, he went almost immediately to say hi to Clio, and he was perfectly fine with us being close to him. We were there for 1.5 hours, got to know a lot of useful information, and we agreed that if our allergy tests do not come back with very bad results, then we would take Filou home.

20180103_Filou_1

We were pretty sure that Clio would be fine, because she is not allergic to anything, but I have a history of allergies (although here in Belgium things are so much better then they were back in Hungary – for some reason), so I wanted to make sure things would be fine, because that is the responsible thing to do, even though I have pretty negative feelings towards my blood being taken. Anyway, giving the three ampules of blood was totally painless (I am liking my GP more and more), and the allergy test only showed a very minor allergy to cats (1.5-2 on a scale of 0-10), so with the blessing from the doctor, we decided to proceed with the adoption.

20180103_Filou_2

Of course this meant that we had to buy a lot of things Filou would need in a few days’ time, so we did a small tour of the pet-supply stores between Leuven and Antwerp (we found Zowizoo in Kontich the nicest of all), and had a few rushed online deliveries too to have everything ready. Then on the morning of the 24th of December we went back to the shelter, and after a bit of paperwork we drove back home with Filou. This year we gave him a new home for Christmas :)

20180103_Filou_3

Filou by the way weights ~4.3 kilograms, he is going to be 6 years old in March, and his previous human has passed away, that’s why he needed a new home. He is something very close to a Siberian cat. He behaved well beyond our expectations from the very beginning, he did not tear down our Christmas tree, he learned extremely fast which places are and which are not allowed for him, he eats and drinks well, he used the litter box without accidents already the first night, and in general he is a nice cat. He already came to sleep on our laps on the second evening, and he is watching TV with us every evening since then. He also uses his scratching post (although he still needs to discover that there are better positions available on it), and he can also chase his toys (especially the one with feathers) like a real hunter when he feels like having a bit of exercise. But in general, he just wants to chill either on the couch, in front of a window, or under the Christmas tree :) He must be also active during the night, because he eats as much between 23:00 and 08:00 as during the rest of the day, but I have not installed a GoPro to see what he is doing, yet…

20180103_Filou_4

Now it has been more than a week since he is with us, and I have had more-or-less zero issues with allergies, even without taking any medication, so things are looking good :) We hope Filou will have a great life with us. He is also on Instagram, for those of you who want to see him on a more frequent basis. (And he is not fat at all, just has a lot of extremely fluffy and soft fur :D)