Zeit unter Linux via GSM synchronisieren

Der RaspberryPi und viele ähnliche Einplatinencomputer haben ab Werk keine RTC aka „Real Time Clock“ und können ohne funktionierende Internetverbindung ihre Zeit nicht korrekt beibehalten. Daher nutzen die meisten RaspberryPi Linux-Distributionen NTP um die Zeit immer direkt nach dem Systemstart wieder ins Lot zu bringen. Wenn es nicht möglich ist, eine Internetverbindung aufzubauen und daher kein NTP zu nutzen, aber ein GSM-Modem oder altes Mobiltelefon sowie eine valide SIM-Karte vorhanden ist, könnte diese Anleitung eine Lösung zur Zeitsynchronisation darstellen.

Um ein GSM-Modem zu erhalten empfiehlt es sich, online nach GSM/2G/3G USB-Modems zu suchen. Ist ein 4G-Modem gewünscht, empfiehlt es sich doppelt zu prüfen, ob dieses auch wirklich GSM unterstützt. Die meisten 4G/LTE-Modems unterstützen lediglich 3G/4G und keine älteren Zugangstechnologien mehr. Am besten kann man auf Amazon oder in anderen Quellen nach alten, gebrauchten USB-Modems suchen.

Um eine kostenlose SIM-Karte zur Zeitsynchronisation, zum Empfang von SMS und mit 200 MB kostenlosem LTE-Volumen zu erhalten, kann zum Beispiel der netzclub „sponsored“ Tarif genutzt werden.

Voraussetzungen

apt install minicom dateutils

Synchronisation

Wir erstellen die Datei „gsm-timesync.minicom“ mit folgendem Inhalt:

send "AT+COPS=2"
expect {
 "OK"
}

send "AT+CTZU=1"
expect {
 "OK"
}

send "AT+COPS=0"
expect {
 "OK"
}

send "AT+CCLK?"
expect {
 "OK"
}
print ""

! killall -9 minicom

Anschließend können wir die Zeit via GSM abrufen, etwas umwandeln und mit dem „date“-Kommando setzen:

minicom -o -D /dev/ttyUSB_UMTS -S gsm-timesync.minicom | grep "+CCLK:" | sed -E 's/\+CCLK: "(.*)"/\1/' | dateutils.dconv -i "%y/%m/%d,%H:%M:%S" -f "%s" --from-zone=UTC | date -s @$(cat -)

Nicht vergessen „/dev/ttyUSB_UMTS“ mit dem TTY des jeweiligen USB-Modems zu ersetzen (in unserem Fall ein ZTE MF190 UMTS-Stick).

Fazit

Es ist immer empfehlenswerter eine Internetverbindung über GPRS, 2G/Edge, 3G/UMTS oder 4G/LTE in Kombination mit NTP zur Zeitsynchronisation zu verwenden. Wenn dies nicht möglich ist, nur GSM eine Option ist, GPRS nicht funktioniert oder vom Provider nicht unterstützt wird, man keine RTC oder einen DCF77-Empfänger (in Europa) zur Verfügung hat, kann diese Methode ein günstiger Workaround sein.

Die Methode basiert auf der Zeit, welche vom GSM-Provider als Antwort auf das AT-Kommando „AT+CCLK?“ geschickt wird. Diese Zeit ist nicht immer verlässlich. Das Modem oder der Provider können in seltenen Fällen falsche Zeiten übermitteln. In meinem Test ist es vereinzelt passiert, dass eine Zeit im Jahr 1980 zurückgegeben wurde. Der Grund hierfür ist unklar, eventuell stimmt was am Sendemast oder beim Provider nicht. Es kann daher nötig sein, eine Fehlerbehandlung nachzurüsten, welche die Zeit, wenn diese zu weit oder hinter der dem RaspberryPi zuletzt bekannten Zeit liegt, invalidiert und erneut abfragt. Dies ist nicht Teil dieses Artikels.

Um ein RTC-Modul oder einen DCF77-Empfänger zu beschaffen, können die folgenden Quellen hilfreich sein:

Extra: systemd unit

Wenn gewünscht ist, systemd für den gsm-timesync-Dienst zu verwenden, kann das folgende Unitfile hilfreich sein. Folgende Werte sollten angepasst werden:

  • WorkingDirectory
  • ExecStartPre
  • ExecStart

Die „ExecStartPre“-Einstellung verifiziert hierbei ob auf dem Gerät der NTP-Dienst mittels systemd-timesyncd inaktiv ist und sorgt, sollte dies nicht der Fall sein, dafür, dass der gsm-timesync-Dienst nicht gestartet wird. Die Umgebungsvariable „TERM“ wird hierbei gesetzt, um eine Warnung des minicom-Tools auszublenden, welche erscheint, wenn kein normales Terminal mit „cursor motion capability“ verwendet wird.

# /etc/systemd/system/gsm-timesync.service
[Unit]
Description=Sync time with GSM provider
After=syslog.target

[Service]
Type=oneshot
User=root
WorkingDirectory=/home/pi/gsm-timesync
ExecStartPre=-/bin/bash -c '(/usr/bin/timedatectl | /bin/grep "NTP service: inactive")'
ExecStart=/bin/bash gsm-timesync.sh
StandardOutput=syslog
StandardError=syslog
Environment="TERM=linux-c-nc"

[Install]
WantedBy=multi-user.target

Die „gsm-timesync.sh“ beinhaltet den zuvor erstellten Einzeiler plus Interpreter auf Zeile 1:

#!/bin/bash
minicom -o -D /dev/ttyUSB_UMTS -S gsm-timesync.minicom | grep "+CCLK:" | sed -E 's/\+CCLK: "(.*)"/\1/' | dateutils.dconv -i "%y/%m/%d,%H:%M:%S" -f "%s" --from-zone=UTC | date -s @$(cat -)

Viel Erfolg!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert