Sync time on Linux via GSM

The RaspberryPi and many similar single-board computers do not have an RTC or “Real Time Clock” and without internet connectivity cannot retain their time setting. Therefore most RaspberryPi Linux-distributions employ NTP to sync the time right after boot. If you are not able to use an internet connection and therefore no NTP, but have a GSM modem or phone and a valid sim card at hand, this guide may be suitable for your needs.

To obtain a GSM modem, you may search online for GSM/2G/3G modems. Mostly they are connected via USB. If you want to get a 4G modem, make double sure it really supports GSM, as most of the 4G/LTE modems will only have 3G/4G capability due to the age of former technologies. The best bet is to search Amazon or other sources for your USB modem.

To obtain a free SIM card for free time sync, SMS receiving and 200 MB internet volume and you live in Germany, you may want to use a netzclub “sponsored” plan.

Requirements

apt install minicom dateutils

Sync

Create the file “gsm-timesync.minicom” with the following content:

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

Get the date via GSM and set it via the date-command:

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 -)

Remember to replace “/dev/ttyUSB_UMTS” with the TTY of your GSM module (in our case a ZTE MF190 UMTS stick).

Conclusion

It is always recommended to use an internet connection using GPRS, 2G/EDGE, 3G/UMTS or 4G/LTE in combination with NTP for time synchronization. If you are unable to use anything above GSM and are unable to use GPRS, do not want to, or can’t use an RTC or DCF77/WWVB-receiver (Europe/North America), this time sync method may be suitable for your needs.

It relies on the time sent by your GSM provider in response to the “AT+CCLK?”-command. The time received via GSM is not always reliable. The modem or the provider may, in some cases, report the wrong time. In my testing case, it sometimes occurred, that a time in the year 1980 was set for unknown reasons. It may be required to adjust the error handling and if the time is drifted too far off the last known time on your RaspberryPi or computer, redo the time sync. This is not part of this article.

To obtain an RTC module or DCF77/WWVB-receiver, make sure to check the following sources:

Europe (Germany)

North America

Extra: systemd unit

If you would like to use systemd to manage your new gsm-timesync service, you may use the following unit file. Adjust the settings

  • WorkingDirectory
  • ExecStartPre
  • ExecStart

to your needs. The “ExecStartPre” directive verifies if your NTP service using systemd-timesyncd is disabled and if not, will not start the gsm-timesync service. The “TERM” environment variable is required to work around a warning thrown by minicom when not using a proper terminal interface with cursor motion capability.

# /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

The “gsm-timesync.sh” contains the oneliner mentioned above with the interpreter mentioned in the first line, like this:

#!/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 -)

Good luck!

Leave a Reply

Your email address will not be published. Required fields are marked *