git-cola

Im Linux-Magazin 04/2019 ist ein Artikel über abgedruckt. Dort werden 4 GUIs für Git vorgestellt und verglichen. Behandelt werden Gitk, Gitg, Git-Gui und Gitahead. Leider fehlt in diesem Vergleich meine Lieblings GUI für Git. Es handelt sich um Git Cola.

Git Cola ist in Python geschrieben und verwendet als GUI Toolkit Qt über QtPy. Sowohl Python 2.6 also Python 3 werden unterstützt.

Unter Debian 9 (stable) liegt das Paket git-cola in Version 2.10 vor. Diese wurde Januar 2017 veröffentlicht und liegt damit relativ weit hinter dem aktuellen Stand der Entwicklung (Version 3.3 wurde am 3. Februar 2019 veröffentlicht). Im Zweig testing liegt auch für Debian die Version 3.3 vor.

Werden Dateien außerhalb von git-cola verändert, so wird dies erkannt und die Liste der Dateien entsprechend umgehend aktualisiert. Eine Rechtschreibprüfung für englische Texte ist ebenfalls vorhanden. Lokalisierungen liegen ein einigen Sprachen vor, unter anderem auch in Deutsch. Teilweise fehlen noch einzelne Übersetzungen aber die Community freut sich über entsprechende Pull Requests auf Github.

3d gedruckter iPad Halter

Für mein iPad wäre ein Halter für zum Aufstellen auf dem Tisch manchmal sehr praktisch. Kaufen wäre zu banal. Aus Holz basteln? Steht diesmal nicht zur Debatte. Also druckt man lieber etwas mit dem 3d Drucker.

Aktuell erstelle ich die zu druckenden Objekte mit OpenSCAD. Folgender Quellcode erstellt einen aus 2 Teilen bestehenden Halter:

difference() {
union(){
// linker Teil
translate([0,0,0])
union() {
translate([0, -5, -5])
cube([10,100,10]);
translate([0,-5, 5])
rotate([0,90,0])
cylinder(r=10, h=15);
};
// rechter Teil
translate([225,0,0])
union() {
translate([5, -5, -5])
cube([10,100,10]);
translate([0,-5, 5])
rotate([0,90,0])
cylinder(r=10, h=15);
};
}
// iPad
#rotate([45,0,0])
cube([240,170,7.5]);
};

Als 3d Rendering sieht das Ergebnis wie folgt aus:

Ca. 1,5h später waren die beiden Teile fertig und das iPad passt perfekt in die Halterung.

QR-Code mit Linux erzeugen

QR-Codes sind diese 2-dimensionalen Muster aus schwarzen und weißen Punkten, die man gerne per Handy ausliest und dann eine URL oder andere Informationen nicht mehr abtippen muss.

Wie erzeugt man diese QR-Codes? Im Internet kann man entsprechende Seiten suchen. Allerdings hinterlässt man die Daten, die in den QR-Code sollen, dabei natürlich im Internet. Will man dies nicht, so kann man unter Linux mit dem Programm qrencode QR-Codes auf der Kommandozeile erzeugen.

Der einfachste Aufruf erfordert lediglich die Angabe einer Zieldatei und der auszugebenden Daten:

qrencode -o $DATEI "Hallo QR-Code!"

Das Ergebnis ist eine PNG-Datei. Weitere mögliche Formate sind PNG, EPS, SVG, ANSI, ANSI256, ASCII, ASCIIi, UTF8, ANSIUTF8. Die Formate ANSI, ANSI256, ASCII, ASCIIi, UTF8, ANSIUTF8 sind hilfreich, wenn der QR-Code direkt in der Kommandozeile ausgegeben werden soll:

qrencode -o - -t ANSI -m2  "Sehr informatives Blog!"

Man erhält:

Das sieht gut aus und kann auch mit der iPhone Kamera direkt ausgelesen werden. Somit ist kein Umweg über eine Datei notwendig.

Fazit: wieder ein typisches Unix-Tool, was genau eine Aufgabe gut erfüllt. Sehr schön!

OSRAM Smart+ Classic E27 Multicolor für Apple HomeKit zurücksetzen

Als weiteres Testobjekt neben dem Koogeek DW1 besitze ich seit heute eine OSRAM Smart+ Classic E27 Multicolor für mein Projekt homekit_python.

Aus Erfahrung weiß ich, wie wichtig es ist, ein HomeKit Accessory während der Entwicklung auf Werkseinstellungen zurück setzen zu können.

Beim Koogeek DW1 drückt man dazu eine Taste für 10s, das Gerät quittiert es mit einer grünen LED und man ist fertig. Diese Information steht auch so im beigelegten Handbüchlein.

Bei der OSRAM Smart+ Classic E27 Multicolor hingegen liegt keine Dokumentation außer einem Zettel mit einigen Grafiken und dem Pairing Code bei. Kein Hinweis auf das Prozedere zum Zurücksetzen. Dieses findet man nur im Internet, leider an unterschiedlichen Stellen und in unterschiedlichen Sprachen (Deutsch und Englisch). Folgendes sagt die deutsche Seite und funktioniert (siehe Link Deutsch Punkt 3.4.b):

schalte sie fünfmal hintereinander für jeweils 3 Sekunden EIN und für 5 Sekunden AUS

Klingt kompliziert, man will aber auch nicht, dass die Lampe aus versehen auf Werkseinstellungen zurück gesetzt wird. Allerdings ist das für Experimente beim Ansteuern via Python eher hinderlich. Gut das wir das über eine vorhandene HomeKit-fähige Schaltsteckdose (Koogeek P1EU) erledigen können:

#!/usr/bin/env bash

python3 -m homekit.put_characteristic -f controller.json\
  -a koogeek -c 1.8 Off
sleep 5

python3 -m homekit.put_characteristic -f controller.json\
  -a koogeek -c 1.8 On
sleep 3

python3 -m homekit.put_characteristic -f controller.json\
  -a koogeek -c 1.8 Off
sleep 5

python3 -m homekit.put_characteristic -f controller.json\
  -a koogeek -c 1.8 On
sleep 3

python3 -m homekit.put_characteristic -f controller.json\
  -a koogeek -c 1.8 Off
sleep 5

python3 -m homekit.put_characteristic -f controller.json\
  -a koogeek -c 1.8 On
sleep 3

python3 -m homekit.put_characteristic -f controller.json\
  -a koogeek -c 1.8 Off
sleep 5

python3 -m homekit.put_characteristic -f controller.json\
  -a koogeek -c 1.8 On
sleep 3

python3 -m homekit.put_characteristic -f controller.json\
  -a koogeek -c 1.8 Off
sleep 5

python3 -m homekit.put_characteristic -f controller.json\
  -a koogeek -c 1.8 On
sleep 3

Schon ist auch diese Aufgabe erledigt und das Testen geht weiter…

Eigener Server für Kalender und Kontakte

Kalender und Kontakte sollten auf allen Geräten, sei es mobil oder stationär, abrufbar und synchron sein. Das spricht dafür, dass sie über Netzwerk oder sogar das Internet abgeglichen werden. Müssen diese sensiblen Daten aber gleich in der Cloud eines großen Anbieters wie Google und Co landen?

Wenn man dies nicht will, bieten sich Lösungen auf CalDav– und CardDav-Technologie an. Beide Protokolle setzen auf WebDAV nach RFC 4918 auf. CalDAV synchronisiert Kalenderdaten nach RFC 4791, CardDav hingegen Kontakte nach RFC 6352.

Bei der Auswahl des Servers für beide Protokolle hat man viel Auswahl. Die Wikipedia bietet eine Aufstellung von Möglichkeiten.

Server einrichten

Für den Server habe ich ich mich für Radicale entschieden. Zusätzlich soll als Frontend InfCloud verwendet werden um auch mit dem Browser von beliebigen Endgeräten auf die Kalender und Adressen zugreifen zu können.

Thomas Queste hat mit dem Docker Image tomsquest/docker-radicale eine einfache Möglichkeit geschaffen, diese Software zu verwenden.

Zunächst legt man Verzeichnisse an:

  • /data/cal/config – für die Konfigurationsdatei und die Datei mit den Nutzern
  • /data/cal/data – für die eigentlichen Kalender- und Adress-Daten

An Konfigurationsdateien benötigt man die Datei /data/cal/config/config mit folgendem Inhalt:

[server]
hosts = 0.0.0.0:5232

[encoding]

[auth]
type = htpasswd
htpasswd_filename = /config/users
htpasswd_encryption = bcrypt

[rights]

[storage]
filesystem_folder = /data/collections

[web]
type = radicale_infcloud

[logging]

[headers]

Die Datei /data/cal/config/users wird mit den üblichen Tools zur Verwaltung von .htaccess-Dateien modifiziert: htpasswd. Wichtig ist mit der obigen Konfiguration der Parameter -B zur Aktivierung der bcrypt-Verschlüsselung:

htpasswd -B /data/cal/config/users $username

Anschließend muss der Docker-Container angelegt und ausgeführt werden:

docker run \
    -d \
    --name radicale \
    -p 5323:5232 \
    -v ~/tmp/cal_data:/data \
    -v ~/tmp/cal_config:/config:ro \
    tomsquest/docker-radicale

Natürlich sollte man im produktiven Einsatz eine TLS-gesicherte Verbindung auf Port 443 verwenden!

Wenn alles funktioniert sollte man unter http://localhost:5232/.web auf die Weboberfläche von Radicale zugreifen können. Als Logins dienen die Accounts, die in der Datei users angelegt wurden. Dort kann man nun alle benötigten Collections, wie Adressbücher, Kalender und Aufgabenlisten anlegen.

Clients

Clients wurden für eine möglichst große Anzahl von Plattformen untersucht.

Browser

InfCloud (in Version 0.13.1) läuft laut Hersteller in allen HTML5 fähigen Browsern wie Safari/Mobile Safari, allen Webkit-basierten, iCab, Firefox, Opera (15+) und Chrome. Zugegriffen werden kann auf InfCloud unter http://localhost:5232/.web/infcloud/.

iOS

Funktioniert direkt ohne weitere Software, was mich positiv überraschte.

Unter EinstellungenAccounts & Passwörter → Account hinzufügen → Andere → CalDAV-Account hinzufügen konfiguriert man den Zugriff auf die Kalender:

Server ist hier der Hostname, unter der Radicale zu erreichen ist. Benutzername und Passwort sind wie in der Users-Datei angegeben und die Beschreibung ist ein beliebiger Text.

Analog verfährt man mit dem Einbinden der Adressbücher. Unter EinstellungenAccounts & Passwörter → Account hinzufügen → Andere → CardDAV-Account hinzufügen konfiguriert man den Zugriff auf die Adressbücher. Die Werte sind analog zu denen bei den Kalendern.

Android

Google macht es uns bei Android etwas schwerer, man will wohl die eigene Cloud mal wieder pushen.

Aber mit CalDAV Sync Free Beta erhält man eine Open-Source Software, die weiterhilft. Ist die Software installiert, so kann man unter EinstellungenKonten → Konto hinzufügen mit der Option CalDav Sync Adapter den Zugang zu den Kalendern einrichten.

Der Benutzer und das Passwort sind die Werte, die auch für das Login in InfCloud verwendet werden. Die URL findet man in der Web-UI von Radicale und sollte einfach per Mail auf das Android Gerät kopiert werden. Anschließend findet man unter EinstellungenKonten → CalDav Sync Adapter den neu eingerichteten Kalender und muss bei diesen noch die Synchronisierung aktivieren:

Jetzt sollte der eingerichtete Kalender in der Kalender App eingebunden sein.

Kontaktdaten via CardDav können ebenso nur mit Zusatzsoftware eingebunden werden. Hier CardDAV-Sync free eine kostenlose Option, die leider nicht frei (wie in freier Software) ist. Auch hier muss man wieder die komplette URL aus der Radicale Web-UI verwenden (analog zur Lösung für CalDAV-Daten). Anschließend können Kontakte zwischen Radicale synchronisiert werden und auch auf dem Android Gerät wie gewohnt erstellt werden.

Desktop

macOS

Unter macOS gibt es, wie unter iOS auch, die Möglichkeit direkt mit Bordmitteln auf Adress- und Kalenderdaten zuzugreifen. In den Einstellungen gibt es Optionen sowohl für CalDAV als auch für CardDAV.

Die Einrichtung findet analog zu iOS statt (hier sieht man inwieweit iOS und macOS sich gleichen).

Linux/Windows

Hier kann Thunderbird mit den beiden Add-ons Lightning (getestet in Version 6.2) und CardBook (getestet in Version 31.2) alle notwendigen Funktionen bereitstellen.

Lightning konfigurieren

Hier wählt man beim Anlegen eines neuen Kalenders die Option Im Netzwerk und als Format CalDAV. Auch hier muss man die URL des Kalenders aus der Web-UI von Radicale entnehmen und einfügen. Anschließend definiert man einen lokalen Namen und legt eine Farbe fest. Im Authentifizierungsdialog trägt man Nutzernamen und Passwort ein. Die Authentifizierung muss pro Server nur einmal vorgenommen werden.

CardBook konfigurieren

Beim Anlegen eines neuen Adressbuches wiederum die Option Im Netzwerk und als Format CardDAV. Dann kopiert man erneut die URL des Adressbuchs und authentifiziert sich. Wichtig das vCard-Format muss auf 3.0 geändert werden! Ansonsten können die erstellten vCards nicht auf allen Clients (z.B. InfCloud) bearbeitet werden.

Windows 10

Unter Windows 10 kann man sich mit folgendem Trick behelfen: https://www.ctrl.blog/entry/how-to-win10-webdav-syncengine (Allerdings ohne Garantie für zukünftige Updates).

 

TinkerForge: Einstieg mit Master Brick 2.1, WIFI Master Extension 2.0 und Voltage/Current Bricklet 2.0

TinkerForge ist eine deutsche Firma aus Schloß Holte-Stukenbrock, die sich seit 2011 bemüht, die Arbeit mit eingebetteten Systemen zu vereinfachen. Ein Stecksystem erübrigt den Griff zum Lötkolben und  detaillierte Kenntnisse in Elektronik werden überflüssig. In diesem Artikel möchte ich testen, in wie weit dies gelungen ist und meine persönliche Erfahrung beschreiben.

Einführung

TinkerForge setzt konsequent auf den Open Source Gedanken und veröffentlicht den Quellcode und weitere Informationen zu den einzelnen Produkten im Firmenaccount auf Github in aktuell 178 Repositories.

Um das Ziel der Vereinfachung zu erreichen, setzt TinkerForge auf ein Baukastensystem aus Bricks, Bricklets und Master Extensions.

Bricks und Master Extensions besitzen eine einheitliche Grundfläche von 4x4cm und werden über den Stack Connector zu Stapeln verbunden. Der wichtigste Brick ist dabei der Master Brick, dieser erfüllt mehrere Aufgaben. Zum einen ermöglicht er den Anschluss von bis zu 4 Bricklets,  bietet die direkte Kommunikation via USB zu einem PC und dienst als Master der Kontrolle des Stapels (nur der Master Brick, um unteren Ende des Stapels dient als tatsächlicher Master, die anderen bieten dann nur  den Anschluss von weiteren maximal 4  Bricklets). Weitere Bricks erlauben den direkten Anschluss von Gleichstrommotoren, Modellbauservos und Schrittmotoren oder dienen als 9-Achsen Lagesensor (IMU Brick). In der Dokumentation findet sich eine Liste der Bricks neben einer Liste der Master Extension.

Bei den Bricklets wird bewusst auf ein einheitliches Format verzichtet, da so ganz unterschiedliche Sensoren, Aktoren, Konverter zu anderen Bussystemen und verschiedenen Mensch-Maschine-Schnittstellen verbunden werden können. Eine vollumfängliche Liste der Bricklets findet man sich in der Bricklet-Dokumentation. Verbunden werden die Bricklets mit vorkonfektionierten Kabeln unterschiedlicher Längen von 6cm bis zu 2m.

Allen Modulen gemein ist ein Raster der Befestigungslöcher von 5mm, zur Befestigung bietet Tinkerforge Montageplatten für den schnellen Aufbau auf dem Schreibtisch an.

Tinkerforge bietet aktuell für 14 Sprachen (davon 3 als spezielle Ausprägungen für mobile Geräte) fertig APIs an. Diese basieren alle auf dem TCP/IP Protokoll, deshalb sollte eine Adaption für weitere Sprachen durchführbar sein (Swift fehlt zum Beispiel in der Liste der unterstützten Sprachen bisher).

Persönliche Erfahrung

Für den Einstieg entschied ich mich für folgende 3 Module:

Das Ziel ist die kombinierte Messung der von einer Solarzelle gelieferten Spannungs- und Stromwerte und der Transfer in ein Grafana.

Bestellt habe ich direkt bei TinkerForge, geliefert wurde ohne Aufschlag bereits am nächsten Tag.

Installation des Brick Daemon (brickd)

Der Brick Daemon abstrahiert als Systemdienst die Kommunikation zwischen den APIs und dem Master Brick über USB. Den Quellcode findet man im brickd-Repository und Pakete für Debian-artige Distributionen zum Download auf tinkerforge.com.

Allerdings ist die Standardkonfiguration des suboptimal, da auf allen IP Adressen des Rechners ohne Authentifizierung gelauscht wird. Hier sollte man sich doch eher auf localhost 127.0.0.1 beschränken. Dies kann nachträglich in der Datei /etc/brickd.conf mit der Option listen.address angepasst werden. Zusaetzlich habe ich einen Pull-Request erstellt, der das Default anpasst.

Nach der Einrichtung der WIFI Master Extension kann jedoch direkt deren IP Verbindung genutzt werden und der brickd wird obsolet.

Installation des Brick Viewer (brickv)

Der Brick Viewer ermöglicht den Zugriff auf auf lokal angeschlossene Bricks über USB und auch per IP auf entfernte Bricks. Auch hier ist der Quellcode im entsprechenden brickv-Repository zu finden, deb-Pakete finden sich als Downloads auf tinkerforge.com.

Leerer Master Brick
Setup-Reiter eines Master Brick ohne weitere Module

Der Brick Viewer zeigt bei einem einzelnen Master Brick natürlich noch nicht viele Informationen an:

Update Dialog
Dialog zum Aktualisieren der Firmwares

Allerdings ist schon jetzt eine Verbindung via USB möglich und es kann zum Beispiel ein Update der Firmware vorgenommen werden (Changelog).

Schließt man nun den Voltage/Current Bricklet 2.0 an einen beliebigen Port des Master Bricks an, so wird dieser automatisch erkannt.

Master Brick mit Voltage/Current Bricklet 2.0
Setup-Reiter eines Master Brick mit angeschlossenem Voltage/Current Bricklet 2.0

Hat man nun der Beschriftung des Bricklets entsprechend die Stromquelle und den Verbraucher angeschlossen, so kann man auf dem entsprechendem Reiter sofort mit der Messung beginnen.

Erste Messung
Einfache Graphen im Brick Viewer

Über die Funktion “Data Logger” im Setup-Reiter kann bereits jetzt mit einer dauerhaften Aufzeichnung von Daten in eine CSV-Datei begonnen werden. Allerdings ist eine USB Verbindung für eine Messung am Fenster (mit der Solarzelle) nicht praktikabel.

Eine Möglichkeit wäre eine der vielen Bastelplatinen mit USB und WLAN zu verwenden oder man greift zur WIFI Master Extension 2.0. Diese ersetzt die USB-Verbindung und den lokalen Brick Daemon durch ein WLAN Modul.

Aufbau des Stapels

Die Bricks und Master Extensions werden über die mitbestellten Befestigungskits verschraubt, nachdem die Module korrekt ausgerichtet worden (man beachte die weiß markierten Ecken!).

Master Brick und WIFI Master Extension 2.0
Stapel aus Master Brick und WIFI Master Extension 2.0

Auch die WIFI Master Extension wird direkt im Brick Viewer erkannt:

WIFI Konfiguration
Konfiguration der WIFI Master Extension 2.0 im Brick Viewer

Nach der Konfiguration als WLAN-Client (General und Mode) muss noch das richtige WLAN ausgewählt werden. Anschließend kann über “Show Status” geprüft werden, ob die WLAN Einrichtung erfolgreich war und welche IP der Stapel bekommen hat. Die kann man dann zur Kommunikation zwischen Brick Viewer und dem Stapel verwenden.

Nutzung der Python API

Das Modul installiert man einfach mit pip:

pip install --user tinkerforge

Folgendes Skript öffnet zunächst eine IPConnection zu dem aufgebauten Stapel über die WIFI Master Extension. Anschließend wird auf das angeschlossene Bricklet zugegriffen und sekündlich die Werte für Spannung, Stromstärke und Leistung ausgegeben.

HOST = "192.168.178.203"
PORT = 4223
UID = "FKC"

from tinkerforge.ip_connection \
    import IPConnection
from tinkerforge.bricklet_voltage_current_v2 \
    import BrickletVoltageCurrentV2
from time import sleep

if __name__ == "__main__":
    ipcon = IPConnection() 
    ipcon.connect(HOST, PORT) 

    vc = BrickletVoltageCurrentV2(UID, ipcon) 

    while True:
        voltage = vc.get_voltage()/1000.
        current = vc.get_current()/1000.
        power = vc.get_power()/1000.

        print(str(voltage) + " V " + \
              str(current) + " A " + \
              str(power) + " W")
        sleep(1)

Weitere Dokumentation zur API findet sich auf der Webseite von Tinkerforge.

Fazit

Mit den Bricks und Bricklets von TinkerForge erhält man ein einfach zu verwendendes Modulsystem. Die Verarbeitung der Module wirkt qualitativ hochwertig. Dies und die einfache Handhabung durch die unterstützende Software rechtfertig in meinen Augen den leicht höheren Preis. Auch die Auswahl der bereits jetzt existierenden Module lädt zu weiteren Experimenten ein.

‘git grep’ oder wie finde ich nochmal, was ich noch tun muss?

In meinem laufenden Projekt homekit_python haben sich inzwischen doch 2 oder 3 TODOs angesammelt. Wie findet man am schnellsten die TODOs die sich in Dateien befinden, die von git verwaltet werden?

Die Antwort ist einfacher, wie ich zunächst annahm: git bietet mit dem Kommando git grep bereits alles was ich benötige:

git grep TODO

Die Ausgabe umfasst in dieser einfachsten Form wie von grep gewohnt alle Treffer:

Weitere git-Kommandos findet man im git Reference Manual.

Python 3: Profiling von Skripten

Auf GitHub habe ich in einem Issue die Anfrage bekommen, die Software sei langsam. Ja, gefühlt ist die Software nicht die schnellste. Aber wie langsam genau? Und für die Optimierung wichtiger,  wo geht die Zeit verloren?

Das kann mit Profiling herausfinden. Ich will hier eine Lösung beschreiben, die ich für elegant und schnell halte, wobei es sich besseres/schöneres/… gibt.

Zunächst installiert man gprof2dot und dot:

pip3 install --user gprof2dot
sudo apt install dot

python3 bietet mit cProfile bereits ein Modul an, welches das Profiling eines Python-Skripts übernimmt. Mit folgendem Kommando startet man das Profilen des Skripts put_characteristic.py (mit dessen Parametern). Für das Module cProfile wird nur der Parameter -o genutzt, der die Ausgabedatei festlegt.

python3 -m cProfile -o profile.pstats \
        homekit/put_characteristic.py -f koogeek.json -c 1.8 -v false

Anschließend verwendet man gprof2dot und dot um eine mehr oder weniger übersichtliche Grafik zu erzeugen, welche aufzeigt, wo die meiste Zeit “liegen bleibt”. Das Ergebnis sieht in unserem Beispiel wie folgt aus:

Ergebnis eines Profilinglaufs

Allerdings muss man auch hier berücksichtigen, dass die Ergebnisse eines einzelnen Laufs nicht repräsentativ sind. Hier sollten mehrere Durchläufe hintereinander geprofiled werden. Allerdings kann man auch bei einem Durchlauf erkennen, das hier Zeroconf zum Auffinden des HomeKit Geräts und das Erstellen der Sessionkeys viel Zeit verbrauchen.