Idea

laurenceh avatar image
laurenceh suggested

Setting time without internet connection on Rpi Venus OS

As I will be using my Venus OS Rpi3B+ on my boat (Lady's Smock) I will not always have an internet connection when I switch the Raspberry Pi on, and the Raspberry Pi does not have an RTC.

I wonder if others have this problem in remote or mobile (motorhome/boat) installations?

In my case I will always be using GPS and should be more likely to have a GPS data fix than an internet connection.

The script here sets the data and time from the GPS data. It waits around 100 seconds for the GPS device to be found (or start up) and collects up to a hundred lines from the GPS device looking to check that

(1) It has a satellite fix

(2) It can provide the data and time

Once decoded it automatically sets the Rpi date and time according to the GPS data.

It has been tested with Venus OS 2.57 in July 2020.

I will look at adding it to /data/rc.local so that it runs at start up. I would not at this stage suggest running it continuously to provide updates as it might conflict with the NTP server system used by default in Venus OS.

The location of the GPS device "/run/serial-start/gps/ttyACM0" is hard wired at present and may need to be changed if you are using an NMEA GPS interface.

It relies on GPGGA and GPRMC data packets from my GPS device - I presume these are pretty standard across devices.

#!/bin/bash
N=0;
FILE=/run/serial-starter/gps/ttyACM0
echo "Waiting for GPS data"
while [ ! -e $FILE ] && [ $N -lt 100 ];
do
    sleep 1;
    ((N++))
    echo -n "."
done;
sleep 1;

if [ $N -ge 99 ]; then
   echo " GPS data not available is the device plugged in"
   exit 0;
fi

echo
echo "Device attached waiting for data"

input=$FILE
N=0

# check if GPS has FIX
LINE1='^\$..GGA,[0-9\.]+,[0-9\.]+,[NS],[0-9\.]+,[EW],([0-2])'
# Catch lines with date and time info
LINE2='^\$GPRMC'

FIX=""

# extract date and time from GPS packet

function extract {
[[ $1 =~ ^\$GPRMC,([0-9]{4})([0-9]{2})\.[0-9]{2},.,[0-9\.]+,[NS],[0-9\.]+,[EW],[0-9\.]*,[0-9\.]*,([0-9]{2})([0-9]{2})([0-9]{2}), ]]
  COMMAND="${BASH_REMATCH[5]}${BASH_REMATCH[4]}${BASH_REMATCH[3]}${BASH_REMATCH[1]}.${BASH_REMATCH[2]}"
  date -s $COMMAND
exit 0
}

while IFS= read -r line && [ $N -lt 100 ]
do
#  echo "$line"
  [[ $line =~ $LINE1 ]] && FIX=${BASH_REMATCH[1]} && echo "GPS device has a fix"
  [[ $line =~ $LINE2 ]] && [[ $FIX -eq 1 ]] && extract $line
  ((N++))
done < "$input"


Venus OSRaspberry PiVenus GX - VGX
2 |3000 characters needed characters left characters exceeded

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.

1 Comment

laurenceh avatar image
laurenceh commented

This now works from /data /rc.local on my Raspberry Pi.

Add the following lines to /dat/rc.local

if test -f /data/venus-rpi-setup/gps.sh; then
 /data/venus-rpi-setup/gps.sh &>/var/volatile/log/gps-time &
fi

Clearly you can change the location where you store the script and where you want the log to go.

Notes:

1) Don't forget the & at the end of the line it is important to make sure it runs as a background process otherwise it stops the rest of the initialisation.

2) You can't rely on standard output to log the output information. The standard boot output logging which goes to /var/log/boot can be shut down before the script terminates so you lose output messages.

3) I changed this line in the original script to read 200 lines as sometimes the script terminated before finding the data it needed in the GPS data stream.

while IFS= read -r line && [ $N -lt 100 ]

Change to:

while IFS= read -r line && [ $N -lt 200 ]

It would be nice if Victron added something like this into the start up sequence as they already detect cases where there in no hardware clock and should be able to detect if there is no route to an NTP server.

2 |3000 characters needed characters left characters exceeded

Up to 8 attachments (including images) can be used with a maximum of 190.8 MiB each and 286.6 MiB total.

Your Opinion Counts

Share your great idea, or help out by voting for other people's ideas.