Raspberry Pi - CO2 Sensor SCD30

I got a Sensirion SCD30 and wanted to use the sensor on a Raspberry Pi with Archlinuxarm.

The sensor is using I2C so it should be easy. But there is a catch: I2C clock stretching.

I used i2c1_set_clkt_tout from https://github.com/raspihats/raspihats to set the clock speed to 20000. The clock speed is set in the same systemd config that starts the data reading. But running once on system start should be enough.

To read the data from the sensor I use the scd30_i2c library. My code is run via systemd and the main part of the Python script looks like this:

scd30 = SCD30()
while True:
    if scd30.get_data_ready():
        m = scd30.read_measurement()
        if m is not None:

The push_data is a function that sends the data to my own custom HTTP api. Instead of my own api this could be a csv logger or a push to influxdb/graphite/you-name-it.

Git scraping with Github Actions

Using Github and Github Actions is the best way to scrape a website and get a timeseries of the changes. A good description how to do this is by Simon Willison in his post about Git Scraping.

My first attempt on using this pattern is by scraping the "Gelbe Karten" from the Stuttgart website. The code is on Github: https://github.com/mfa/gelbekarten_stuttgart.

Github Actions can be triggered by a cron schedule, for example:

    - cron:  '23 * * * *'

This yaml triggers every hour on minute 23. An important note here: the Actions don't run exactly on that minute. The Action is scheduled and runs when there are enough workers available. The full code of the Action: https://github.com/mfa/gelbekarten_stuttgart/blob/main/.github/workflows/scrape.yml.

The git log shows the updates of the website as commits on the csv file: https://github.com/mfa/gelbekarten_stuttgart/commits/main/data/gelbe_karten_stuttgart.csv.

Google Cloud Run as message queue for AX Webhooks


In the evaluation phase of a new hobby project I built a Google Cloud Run service that accepts and validates webhooks from AX Semantics.

The current version uses Google Cloud Datastore to store the texts. The advantage of saving to Datastore is speed and low costs. Processing the texts can be done later by a cronjob as described in the next section.

An example for a cronjob processing

First: Authentication!

If the cron is run in the Google Cloud everything is set. When not in the Google Cloud (locally or elsewhere), see Google Auth Api Documentation.

For this example I chose the service account with json keyfile option.

The snippet gets all texts for the collection 12345 and prints them:

from google.cloud import datastore
client = datastore.Client()

query = client.query(kind="AX-NLG-Text")
query.add_filter("collection_id", "=", 12345)

for item in query.fetch():
    print(item.get("uid"), " -- ", item.get("data").get("text"))
A cronjob would probably delete the item after processing it, to prohibit another processing on the next cronjob run.
To delete an item use client.delete(item).