Vorgeschlagener Eintrag

Willkommen auf meinem Blog!

Hier veröffentliche ich unregelmäßig Artikel über Dinge, mit denen ich mich beschäftige, oder die ich so nützlich finde, dass ich sie später nachschlagen will.

Neuen Besuchern möchte ich eine handvoll Beiträge empfehlen, anstatt chronologisch herunterzuscrollen:

Neuste Einträge

Schneckenkragen

Besonders in diesem Jahr, aber zumindest in meinem Garten jedes Jahr, sind Schnecken ein großes Problem für Hobbygärtner. Man setzt die liebevoll vorgezogenen Pflanzen von der Fenterbank in das Beet, nur um am nächsten Tag zu sehen, dass außer Schleimspuren nichts geblieben ist. Es gibt eine Reihe Hausmittel, die helfen sollen. Praktischerweise im Wikipedia-Artikel zur Schneckenbekämpfung zusammengefasst:

  • Bannkreise aus Eierschalen oder Kaffeepulver
  • Bierfallen, die alle Schnecken aus der Nachbarschaft einladen
  • Kupfer, das nicht nur für Schnecken giftig ist
  • Laufenten — immerhin werden die Pflanzen dann nicht mehr von Schnecken gefressen

Drei dieser vier Strategien haben außerdem den Nachteil, dass sie nicht nur die Wegschnecken bekämpfen, die für die meisten Fraßschäden verantwortlich sind, sondern alle Schnecken. Tatsächlich sind Schnecken mit Gehäuse keine Gefahr für die Nutzpflanzen — im Gegenteil: laut des Wikipedia-Artikels gibt es anscheindend eher den Zusammenhang, dass eine große Weinbergschneckenpopulation mit eher kleinen Populationen der schädlichen Wegschnecke korreliert ist. Und auch nicht alle Nacktschnecken sind schädlich! Meine Lieblingsnacktschnecke, der Tigerschnegel, frisst nicht nur Schneckeneier, sondern sogar ausgewachsene Exemplare.

Der Schneckenkragen

In meinem Garten hat sich der Schneckenkragen bewährt. Das ist ein hohler Zylinder mit Widerhaken nach außen. Einfacher an einem Bild zu zeigen als zu beschreiben.

Schneckenkragen

Dort, wo die 3D-gedruckte Schnecke abgebildet ist, sollte keine Schnecke mehr hingelangen können.

Man steckt ihn einfach mit einer leicht drehenden Bewegung etwa 2 cm tief in den Boden.

Dabei ist unbedingt zu beachten, dass andere Pflanzen nicht zu dicht am Kragen stehen dürfen, da die Schnecken sie ansonsten als Brücken nutzen können.

Und natürlich sollte man sicherstellen, dass sich keine Schnecke im Inneren des Schneckenkragens befindet. Sie verstecken sich gerne unter Steinchen oder Ästen. Am besten lockert man den Boden innerhalb des Scheckenkragens daher einmal auf und befördert dabei zutage tretende Schnecken heraus.

Auch wenn man alles beachtet, kann es sein, dass in der Erde noch Schneckeneier sind, die innerhalb des Kragens schlüpfen.

Man muss also dennoch regelmäßig nachschauen. Aber zumindest in meinem Garten, ist der Unterschied zwischen geschützten und ungeschützten Pflanzen gewaltig.

Die Funktionsweise ist anscheinend nicht ganz klar. Erklärungsansätze, die ich finden konnte, sind, dass der Wechsel von „senkrecht nach oben“ zu „45° nach unten“ nicht im Verhaltensrepertoire von Schnecken enthalten ist. Und dass der Kragen dazu führt, dass die Schnecken auf dem Weg nach oben den Geruch der Pflanzen verlieren und dann verwirrt wieder nach unten kriechen.

Upgrade

Nach meinen (leidvollen) Erfahrungen finden in besonders schneckenreichen Beeten bei feuchtem Wetter einige Schnecken dennoch in den Kragen. Das scheint daran zu liegen, dass sich Schnecken in den Knick verkriechen. Von da aus kriechen sie dann später in eine zufällige Richtung — entweder in den Kragen hinein oder wieder herunter. Zumindest vermute ich, dass dies der Mechanismus ist.

Schnecken im Knick des Kragens

Wenn die Annahme richtig ist, müssen wir also nur verhindern, dass die Schnecken es sich in dem Knick gemütlich machen. In der Einleitung hatte ich kurz erwähnt, dass Schnecken Kupfer vermeiden, denn Kupfer ist giftig für Weichtiere (sowie Einzeller und viele Wassertiere). Der Mechanismus ist anscheinend, dass Schneckenschleim leicht sauer ist und bei Kontakt leicht Kupferionen löst, die für die Schnecke giftig und unangenehm sind. Dafür muss die Schnecke allerdings ausreichend lange Kontakt mit dem Kupfer haben, sodass ein Kupferdraht, der um das Beet liegt, keine Schnecken abschreckt.

Wir können aber das Kupfer nutzen, um die Schnecken davon abzuhalten, sich in dem Knick aufzuhalten, indem wir einen Streifen Kupferfolie möglichst weit oben um den Kragen kleben. Gleichzeitig ist das Kupfer dort unter dem „Dach“ vor Regen geschützt, sodass die Exposition der Umgebung minimiert wird.

Schneckenkragen mit Kupferring

Upgrade 2 — Electric Boogaloo

Wenn dies immer noch nicht ausreicht, um die Pflanzen hinreichend zu schützen, gibt es noch die Möglichkeit den Kragen zu einem Elektrozaun zu modifizieren. Dazu klebt man zwei Streifen Kupferband um den Kragen, sodass sie sich nicht berühren und schließt sie an eine 9 V Batterie an. Um die 9 V Batterie zu halten, habe ich eine Variante des Kragens mit einer Halterung und einer Öffnung für die Kabel erstellt. Damit die Batterie nicht nass wird, sollte man die Oberseite der Öffnung mit Silikonkleber abdichten.

Schneckenkragen mit Batteriefach

Schneckenkragen mit Elektrozaun

Wenn Schnecken nun hochkriechen, schließen sie den Stromkreis und bekommen einen Stromschlag. In der Regel sollten sie sich zurückziehen oder betäubt werden und herunterfallen. Falls diese Methode zu lethal für die Schnecken ist, kann noch ein Widerstand in Reihe an einen der Pole gelötet werden.

Fertigung

Die Fertigung gelingt mit einem 3D-Drucker. Ich habe hierfür ein einfaches Modell designt. Leider benötigt ein hinreichend großer Schneckenkragen, der stabil genug ist, um ihn in den Boden drücken zu können, relativ viel Filament. Bei dem Filament sollte man darauf achten, dass es UV-beständig ist, wie PETG oder ASA. Das sorgt dafür, dass er in der Sonne nicht spröde wird und man ihn viele Jahre nutzen kann.

Osteralbtraum

Ostern ist ein Feiertag, dessen Zeitpunkt mit einer Regel festgelegt wird, die unnötig kompliziert scheint. Der erste Sonntag nach dem ersten Vollmond im Frühling. Den meisten bleibt da als Lösung nicht viel mehr übrig als in einem Kalender nachzusehen welches Datum es denn wohl ist und sich auf den Kalenderhersteller zu verlassen. Aber nicht mit mir! Ich werde es Big-Calendar zeigen und hier die geheime Formel veröffentlichen, mit der man das Osterdatum berechnet!

from datetime import date

def easter(year: int) -> date:
    y = year
    g = y % 19 + 1                    # golden number
    c = y // 100 + 1                  # century
    x = (3 * c) // 4 - 12             # correction: dropped leap years
    z = (8 * c + 5) // 25 - 5         # correction: synchronize with moon's orbit
    d = (5 * y) // 4 - x - 10         # find sunday
    e = (11 * g + 20 + z - x) % 30    # epact
    if e == 25 and g > 11 or e == 24:
        e += 1
    n = 44 - e                        # full moon in march
    if n < 21:
        n += 30
    n = n + 7 - (d + n) % 7           # advance to next sunday
    month, day = (4, n - 31) if n > 31 else (3, n)

    return date(year, month, day)

Mir persönlich gefällt besonders gut, dass jede Zeile schlimmer ist als die vorherige.

Dieser Algorithmus ist übrigens von Lilius und Clavius Ende des 16. Jahrunderts entwickelt worden. Ich bin durch eine Erwähnung in einer Übungsaufgabe in Donald Knuths The Art of Computer Programming 1 (Third edition, S. 159f) darauf gestoßen.

pirShow

Alte Monitore sind zu Schade zum Entsorgen. Als Upcycling habe ich deshalb einen alten Monitor zu einem digitalen Bilderrahmen in meinem Flur umfunktioniert. Sinnvollerweise sollte er natürlich nur dann ein Bild zeigen, wenn auch jemand da ist, der es betrachten kann. Hier möchte ich einmal kurz beschreiben, wie ich einen Raspberry Pi, einen passiven Bewegungssensor und etwas Python-Code zu diesem Zweck benutze.

Bildquellen definieren

Die Hauptfunktionalität eines digitalen Bilderrahmens ist es natürlich Bilder anzuzeigen. Diese Bilder sollen aus mehreren Quellen zufällig ausgewählt werden. Dabei habe ich mir einige Flickr-Accounts über Raumfahrt und meine Twitter-Bots ausgesucht. Zuerst brauchen wir also etwas Code, um die Bilder herunterzuladen.

def flickr(user_id):
    import flickrapi
    from keys_and_secrets import keys_and_secrets

    url_template = 'http://farm%(farm_id)s.staticflickr.com/%(server_id)s/%(photo_id)s_%(secret)s_b.jpg'

    def url_for_photo(p):
        return url_template % {
            'server_id': p.get('server'),
            'farm_id': p.get('farm'),
            'photo_id': p.get('id'),
            'secret': p.get('secret'),
        }

    flickr = flickrapi.FlickrAPI(keys_and_secrets["flickr_key"], keys_and_secrets["flickr_secret"])

    photo = random.choice(flickr.photos.search(user_id=user_id, per_page=500)[0])
    purl = url_for_photo(photo)
    title = photo.get('title')

    fname = save_image(purl, title)

    return fname


def twitter(atname):
    import tweepy
    from keys_and_secrets import keys_and_secrets

    auth = tweepy.OAuthHandler(keys_and_secrets["consumer_key"], keys_and_secrets["consumer_secret"])
    auth.set_access_token(keys_and_secrets["access_token_key"], keys_and_secrets["access_token_secret"])

    api = tweepy.API(auth)
    tweets = api.user_timeline(atname, count=30)

    urls = []
    for i in tweets:
        if "media" in i.entities:
            for j in i.entities["media"]:
                url = j["media_url"]
                if "thumb" not in url:
                    urls.append((url, i.id_str))

    purl, title = random.choice(urls)

    fname = save_image(purl, title)

    return fname

Dann bauen wir uns einen praktischen Decorator, den wir nutzen, um unterschiedliche Accounts als Bildquellen zu registrieren.

sources = {}

def source(source_name):
    def source_decorator(func):
        sources[source_name] = func

        @wraps(func)
        def func_wrapper(*args, **kwargs):
            return func(*args, **kwargs)
        return func_wrapper
    return source_decorator


@source("apollo")
def apollo():
    return flickr("projectapolloarchive")


@source("randomGraphs")
def randomGraphs():
    return twitter("@randomGraphs")


@source("AFractalADay")
def AFractalADay():
    return twitter("@AFractalADay")

Dies ermöglicht es dann sehr komfortabel zufällige Bilder herunterzuladen und anzuzeigen.

def random_image():
    image_getter = random.choice(list(sources.values()))
    fname = image_getter()
    # show image
    # skipped terminating old instance of feh and aquiring a mutex
    env = os.environ
    env["DISPLAY"] = ":0"
    VIEWER = subprocess.Popen(
        ["feh", "-FZYx", fname],
        env=env,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE
    )

Monitor ein- und ausschalten

Jetzt, da wir Bilder zum Anzeigen haben, müssen wir den Monitor ein- und ausschalten, damit man sie sieht bzw. damit wir nicht sinnlos Strom verbrauchen. Hier rufen wir wieder Kommandozeilen-Werkzeuge auf: tvservice schaltet den Standby-Modus des Monitors um und chvt wechselt einmal vom X-Server weg und wieder zurück, was den Bildschirmschoner beendet.

from threading import Timer, Lock

MUTEX = Lock()
STATE = False

def monitor(status):
    global STATE
    # needs to run as root
    # make sure that sudo will not ask for a password for these commands
    # e.g. use visudo to add
    # piruser ALL=(ALL) NOPASSWD: /usr/bin/tvservice, /bin/chvt
    with MUTEX:
        if status:
            if not STATE:
                os.system("sudo tvservice -p; sleep 0.5; sudo chvt 6; sleep 0.5; sudo chvt 7")
            STATE = True
        else:
            if STATE:
                os.system("sudo tvservice -o")
                # download and show the next image
                random_image()
            STATE = False

PIR

Jetzt müssen wir diese Funktionalität nur noch durch einen Bewegungssensor auslösen. Dazu schließen wir einfach einen Pyroelektrischen Infrarot Sensor (PIR) an beispielsweise Pin 23 und sagen dem Raspberry, dass er dort horchen soll, ob ein Signal anliegt.

Ein PIR Bewegungsensor, der an einen Raspberry Pi angeschlossen ist

import RPi.GPIO as GPIO

SENSOR_PIN = 23

GPIO.setmode(GPIO.BCM)
GPIO.setup(SENSOR_PIN, GPIO.IN)

if __name__ == "__main__":
    GPIO.add_event_detect(SENSOR_PIN, GPIO.RISING, callback=pir_callback)

Der pir_callback schaltet dann einfach den Monitor an und startet einen Timer, der den Monitor wieder ausstellt (dieser Timer wird abgebrochen sobald der Callback erneut aufgerufen wird, damit der Monitor an bleibt, solange jemand das Bild betrachtet.)

Der pir_callback sendet außerdem auch eine MQTT-Nachricht, um die Bewegungsmeldung auch für Home-Assistant-Automatisierungen zu nutzen, sodass die Beleuchtung im Flur nach Sonnenuntergang nun auch durch Bewegungen ausgelöst wird.