CODE64 Raspberry Pi Stepcounter – Version 2

#hacks #raspberry #technik

Wenn sich der Marketing-Club München in den Räumlichkeiten von CODE64 trifft, dann darf der Raspberry Pi Stepcounter aus den CODE64 Labs natürlich nicht fehlen.

Raspberry Pi

 

Da wir den Raspberry Pi Stepcounter bereits bei der MCBW erfolgreich eingesetzt haben, wollten wir auf der Grundlage der gesammelten Erfahrungen aufbauen und mit einer optimierten Version an den Start gehen. Unerwarteterweise sahen wir uns bei dem Update jedoch zuerst mit einem völlig anderen Problem konfrontiert:

 

Google ClientLogin

ClientLogin is a deprecated authentication protocol and is being turned down on April 20, 2015. At that time, ClientLogin requests will no longer be answered.

Die von uns verwendete Bibliothek (Gdata Python Client) nutzt das völlig überholte ClientLogin Protokoll, welches Google nun vollständig deaktiviert hat.

Schnell ist klar, dass wir auf OAuth 2.0 umstellen müssen, denn auch OAuth 1.0 ist keine Alternative:

OAuth 1.0 is no longer supported and will be disabled on May 5, 2015. If your application uses OAuth 1.0, you must migrate to OAuth 2.0 or your application will cease functioning.

OAuth 2.0 is a new, simplified authorization protocol for all Google APIs. OAuth 2.0 relies on SSL for security instead of requiring your application to do cryptographic signing directly. This protocol allows your application to request access to data associated with a user’s Google Account.

 

Von Gdata zu Gspread

Da Gdata schon lange Zeit nicht weiterentwickelt wird, OAuth 2.0 nun aber von Google erzwungen wird, wechseln wir zur Google Spreadsheets Python API: Gspread

Gspread wird aktiv entwickelt und bietet neben OAuth 2.0 auch Support für Zwei-Faktor-Authentifizierung sowie eine ausführliche Dokumentation.

 

Installation von Gspread

Die Installation erfolgt via pip install gspread oder alternativ direkt über python setup.py install.

Bei folgender Fehlermeldung muss via apt-get install python-openssl noch OpenSSL für Python nachgerüstet werden:

oauth2client.client.CryptoUnavailableError: No crypto library available

 

Service API mit JSON und OAuth

Im nächsten Schritt muss in der Google Developer Console ein neues Projekt angelegt werden, um unter APIs & Authentifizierung » Zugangsdaten eine OAuth Client-ID erstellen zu können. Über ›Neue Client-ID erstellen‹ kann ein Dienstkonto inkl. JSON-Schlüssel angelegt werden.

Google Dienstkonto Client-ID erstellen

Google Dienstkonto Client-ID erstellen

Anschließend wird automatisch eine JSON-Datei heruntergeladen, die alle Infos zur Authentifizierung wie private_key_id, private_key, client_email, client_id und type beihaltet.

Im jeweiligen Google Spreadsheet muss nun noch die client_email aus der JSON-Datei hinterlegt werden, um darüber Änderungen vornehmen zu können. Fehlt diese Zugriffsberechtigung, wird die Fehlermeldung SpreadsheetNotFound ausgegeben.

Freigabeeinstellungen für Google Spreadsheet

Freigabeeinstellungen für Google Spreadsheet

Ob die Authentifizierung klappt, testen wir vorab mit einem kurzen Test-Script. Dabei greifen wir auf die Daten in der JSON-Datei zu, um die Infos zur Authentifizierung zu erhalten. Anschließend wählen wir über die Spreadsheet-ID das entsprechende Dokument sowie die Seite aus und fügen am Ende über append_row eine neue Zeile hinzu:

import json
import time
import gspread
from oauth2client.client import SignedJwtAssertionCredentials

# OAuth
json_key = json.load(open('######.json')) # SERVICE ACCOUNT KEY
scope = ['https://spreadsheets.google.com/feeds']

credentials = SignedJwtAssertionCredentials(json_key['client_email'], json_key['private_key'], scope)
gc = gspread.authorize(credentials)

# Spreadsheet
wks = gc.open_by_key('######') # SPREADSHEET KEY
ws = wks.get_worksheet(0)

# Append row: time, date, event, visitor
ws.append_row([time.strftime('%H:%M:%S'), time.strftime('%d/%m/%Y'), 'MC', '1'])

Wichtig: Die Zeile wird tatsächlich am Ende des Dokuments, nicht in die letzte leere Zeile, hinzugefügt. Über Rechtsklick » Zeilen löschen können die überflüssigen leeren Zeilen entfernt werden.

Anschließend können wir die Schnittstelle zur Hardware (in unserem Fall Pin 18) im Code hinterlegen und auf das Feedback des Sensors warten:

pin = 18
GPIO.setmode(GPIO.BCM)
GPIO.setup(pin, GPIO.IN)
try:
    while True:
        if GPIO.input(pin) == True:
            log_visitor()
except KeyboardInterrupt:
    GPIO.cleanup()

Das finale Skript kann in der Datei logger.py auf GitHub eingesehen werden.

 

Autostart

Um das System möglichst schnell neu starten zu können, haben wir einen Cronjob beim Boot-Prozess eingerichtet. Dadurch ist der Sensor inkl. Logger automatisch direkt nach dem Bootvorgang aktiv und einsatzbereit.

Wie der Cronjob im Detail eingerichtet wird, kann auf Instructables nachgelesen werden; in unserem Fall starten wir den Logger über die Datei launcher.sh, wobei mit den Zusatz 2>&1 eventuelle Fehler direkt in ein Logfile unter logs/cronlog gespeichert werden.

@reboot sh /home/pi/logger/launcher.sh >/home/pi/logger/logs/cronlog 2>&1

Das Skript für den Launch kann in der Datei launcher.sh auf GitHub eingesehen werden.

 

Fehleranalyse & Debugging

Manchmal kommt es zum Fehler oauth2client.client.AccessTokenRefreshError: invalid_grant wenn der Zertifikatfingerabdruck zuerst unter OS X und dann unter Linux genutzt wird. In diesem Fall reicht es einen neuen, weiteren Fingerabdruck (siehe Neuen JSON-Schlüssel generieren) über die Google Developer Console zu erstellen und die aktualisierte JSON-Datei zu hinterlegen. An den Freigaben im Spreadsheet etc. muss an dieser Stelle nichts mehr geändert werden.

Google Dienstkonto OAuth Zugangsdaten

Google Dienstkonto OAuth Zugangsdaten

 

Fazit

Die zweite Version des Stepcounters lief deutlich besser und stabiler als die erste Version. Durch den Launcher musste zudem niemand per SSH auf den Raspberry Pi zugreifen, um das Script zu starten, was das Starten & Stoppen deutlich vereinfacht hat.

Community  
Wer sich inspiriert fühlt, selbst ein ähnliches Projekt umzusetzen, kann gerne einen Blick auf den Quellcode auf GitHub werfen.
Fragen, Anregungen oder weiteren Gedanken zum Projekt können gerne als Kommentar unter diesem Beitrag ergänzt werden.

 

Ihr Kommentar