#!/bin/bsh ################################################################################ NAME=Event_Logger VERSION="6.4" DATE="2006-7-25" AUTHOR="Amacri " # # http://web.tiscali.it/macri/Event_Logger # # This file is part of Event_Logger, author Amacri # # Permission is hereby granted, without written agreement and without # license or royalty fees, to use, copy, modify, and distribute this # software and to distribute modified versions of this software for any # purpose, provided that the above notice and the following two paragraphs # appear in all copies of this software. # # In no event shall Amacri or the Event_Logger Development Group be liable # to any party for direct, indirect, special, incidental, or consequential # damages arising out of the use of this software and its documentation, # even if Amacri and the Event_Logger Development Group have been advised of # the possibility of such damage. # # Amacri and the Event_Logger Development Group specifically disclaim any # warranties, including, but not limited to, the implied warranties of # merchantability and fitness for a particular purpose. The software # provided hereunder is on an "as is" basis, and Amacri or the Event_Logger # Development Group have no obligation to provide maintenance, # support, updates, enhancements, or modifications. # # Contribs: # Even Lægreid [lageve@enivest.net], Norwegian translation # VinceLP [roussillat@webazar.org], French and German translation # ################################################################################ # Full trace settings: export PS4=" ($$) %k:%M:%S " # set the trace prompt export ERRORSTRING="{_Event_Logger_Script_ERROR_} " # This will allow fast searching for script errors inside the logs LoggerGpsData=${LoggerGpsData:-/dev/gpsdata} LoggerRootDir=${LoggerRootDir:-/mnt/sdcard} # Uncomment to trace (e.g., when the script does not run and the log file is not created) #exec 1>>$LoggerRootDir/BootLog.txt 2>&1;set -x;echo -e "\n\nEvent_Logger START - \c" >&2;zdate >&2;echo -e "\n\n" >&2;set # Alternative tracing method (search for "option B" inside the code to activate it): #exec 1>>/var/run/TtnLog.txt 2>&1;set -x;echo -e "\n\n - ttn START\n\n";set # option B ############## START OF CONFIGURATION VARIALBES ################################ # Notice that for all numeric values decimal point is dot. # Time synchronization: LinuxTimeIsUTC=yes # Mean time used in Linux (e.g., this influences the dates of the files created by TomTom: if yes, dates will be affected # by a time shift when analyzing them through a connected PC). # Must be set to yes (use UTC time) with TomTom version 6; can be unset (use local time) with previous versions. TIMEZONE='+0200' # IMPORTANT: set this to your current time zone. Format: +/-hhmm # E.g., +0000 for GMT (or UTC), -0700 for US & Canada Mountain Time (GMT-07:00), +0100 for WEST (GMT+01:00), +0200 for WEDT (GMT+01:00+01:00), etc. SyncTime=no # Set to yes if you want to keep Linux time in sync with GPS time MinSecToChDate=20 # seconds. Minimum interval to automatically change the date DateCalibration=1 # seconds # NMEA settings: FastGpsFetch= # Set to yes in order to speed up GPS retrieval, but reducing date sync chances ReadNMEA=yes # Unset to speed-up the script execution, but disabling altitude retrieval and date sync SpeedNotAvailable= # Set to yes to avoid waiting for NMEA VTG (in this case speed has to be fetched through the TTGO GetCurrentPosition SDK API) GeoidHeight=0 # Tune here the height in meters of the geoid above the WGS84 earth ellipsoid. # It allows producing MSL (mean sea level) altitude; similar to the unsupported Geoid Separation of NMEA GGA message. # (In case GPS provides it, the GPS value is automatically used instead of GeoidHeight.) This parameter cannot be unset. AddGeoidheight= # if yes, use in GPX files instead of compensating fields. Notice that most GPX applications do not manage this. SpeedUnit="km/h" # can be changed to e.g. miles per hour if kmhToMilesh=yes AltitudeUnit="m" # can be changed to e.g. feet if mToFeet=yes kmhToMilesh= # Set to yes in order to convert km/h to miles/h for Speed mToFeet= # Set to yes in order to convert meters to feet for Altitude MaxSpeedToShowPoint=40 # Km/h. Above this speed, any decimal value is rounded to integer in screen msgs and ITN files LANGUAGE=DE # IT|FR|EN|DE|NO (if unset, it defaults to EN) EnglishWords=(January February March April May June July August September October November December Monday Tuesday Wednesday Thursday Friday Saturday Sunday) # Strings to discard in address geodecoding (sensible to the TTGO used locale) and date strings case "$LANGUAGE" in FR) # French UnnamedRoadString1='(Route sans nom)' UnnamedRoadString2='Route sans nom' TargetWords=(janvier fevrier mars avril mai juin juillet aout septembre octobre novembre decembre lundi mardi mercredi jeudi vendredi samedi dimanche) ;; IT) # Italian UnnamedRoadString1='(Senza nome posizione)' UnnamedRoadString2='Strada senza nome' TargetWords=(gennaio febbraio marzo aprile maggio giugno luglio agosto settembre ottobre novembre dicembre lunedì martedì mercoledì giovedì venerdì sabato domenica) ;; DE) # German UnnamedRoadString1='(Strasse ohne name)' UnnamedRoadString2='Strasse ohne name' TargetWords=(Januar Februar März April Mai Juni Juli August September Oktober November Dezember Montag Dienstag Mittwoch Donnerstag Freitag Samstag Sonntag) ;; NO) # Norsk UnnamedRoadString1='(Lokalitet uten navn)' UnnamedRoadString2='Gate uten navn' TargetWords=(Januar Februar Mars April Mai Juni Juli August September Oktober November Desember Mandag Tirsdag Onsdag Torsdag Fredag Lørdag Søndag) ;; *) # English UnnamedRoadString1='(Unnamed location)' UnnamedRoadString2='Unnamed road' TargetWords=($EnglishWords) ;; esac DoSplashTxt=minimal # (never|always|minimal) Set to never to avoid any splash message. # Set to minimal in order to produce the splash text in case of LOG/POI/... events. # Set to always in order to produce the splash text also in case of BOOT, SUSPEND, RESUME events. AddIntervals=yes # (yes|no/unset) calculate and report the duration of each journey # Tracing and logging Debug=2 # trace level setting # -1: no error logging, no stdout and stderr redirection # 0: no debug, no stdout and stderr redirection (only error logging) # 1: trace startup messages and errors # 2: trace startup messages and errors also including the GPX Tracker # 3: trace startup messages, errors, DebugLog and fbprint # 4: full trace # 5: full also including the GPX Tracker (very verbose) # Log timings: DumpDate=yes # Unset to avoid logging date changes inside the Itinerary file, default=yes: log MaxSilentDateInterval=300 # seconds needed for a date change to be logged. MaxItnLines=48 # max number of lines in an itinerary file. # Note: TTGO truncates Itinerary files with more than 48 lines. ShortInterval=6 # Minutes. More events are aggregated into one if happening within this # timeframe in minutes. Set ShortInterval=-1 to disable this feature. GpsMaxLines=25 # Max number of lines to read (and wait for) from the GPS device GpsTimeout=8 # Max number of seconds to wait for valid data from the GPS device GpsMinBytes=300 # Min number of bytes to read (and wait for) from the GPS device before processing GPS data Rounding=31 # Rounding of seconds to the nearest minute in date calculations (including computation delays) # Symbols: AggregSeparatorSymbol='-' # used in aggregated records as header of the aggregation interval (in minutes) LessThanOneMinuteSymbol="'" # used to identify aggregate records less than one minute; they should be # reported as "-0", but this is forced to "-1" + LessThanOneMinuteSymbol (can be also set to null) LogSymbol=' *' # used to identify intermediate marks (shown as asterisk by TTGO; can be set to null) DaySeparatorSymbol='-' # used for the duration strings covering more days LogRotationSymbol='<' # header of Today date string for Itineray files rotated because > than MaxItnLines OutdatedRecordSymbol=' use outdated:' # Used to identify a fix produced by TTGO and not directly fetched from the GPS device PreviousRecordSymbol=' use previous:' # Used to identify records with outdated fix (neither GPS nor TTGO data available) NoInfo="no information available" # missing GPS, missing cached data and missing $ITNOK (LastLog.itn file) ResetString="RESET" IntOS='{' IntCS='}' IntOR='[' IntCR=']' DateFormat="%H:%M" # Date for records with current, valid fix LongDateFormat="%d/%m %H:%M" # Date included in description records Today="%A %e %B %Y" # Date included in the new day notifications # Usage of the SDK DoSdkShowMessage=yes FlashMessageDuration=5 # seconds DoSdkGeodecode=yes DoSdkPosition=yes DoSdkAddPoi=yes # Set to yes in order to add POIs to file $PoiFileName upon events described in PoiEventFilter (otherwise unset) PoiEventFilter='POI' # Quoted list of events separated by '|' generating a Poi if DoSdkAddPoi=yes (e.g.: 'RESUME|POI|LOG' or '*') PoiFileName=_Tracker # File to be created in the current "Map" directory, hosting the POIs added through $DoSdkAddPoi and # $PoiEventFilter. Full Filename is $PoiFileName.ov2; e.g., POI_Tracker.ov2 (An icon file $PoiFileName.bmp # can be manually saved there if needed.) DoSdkChSet=yes # Undefine to disable automatic change between day and night colours depending on time and position. MaxSunElevation=-4 # Maximum elevation of the sun in degrees (signed floating) delimiting nighttime from # daytime. A negative value means sun below the horizon. Set to -0.833 degrees for sunrise/sunset, -6 # degrees for civil twilight, -12 degrees for nautical twilight and -18 degrees for astronomical twilight. DNChangeCounter=9 # number of checks to change night and day (DNChangeCounter decremented on each check) DNChangeFactor=3 # on each check, the night/day change is performed when DNChangeCounter is multiple of DNChangeFactor # NOTE: avoid using spaces in any filename # GPX path and itinerary file name for TTGO: ITNPath="$LoggerRootDir/itn" # Used also to save GPX files (not only ITN ones) ITNName=_Latest_Events.itn # Initial underscore ensures to stay first in the TTGO file list ITNOHeader=Log ITNExtension=itn ITN="$ITNPath/$ITNName" # Actual Itinerary pathname OldLogFileFormat="%y-%m-%d_%H.%M" HourToStartItnRotation="03:30:00" # Hour:minute:second of the current day # Set this to the less probable driving hour: if the Itinerary file is found older # than this hour and a new record is being added, an archiving is performed first # and the event is stored in a new Itinerary file. # GPX Tracking System control variables: DoSdkTracking=yes # if set to yes, a specific daemon starts in background, tracking samples periodically fetched from TTGO. DoBreakTracks=yes # GPX tracks are broken if DoBreakTracks is set to yes and when the same fix (latitude,longitude)... TrackingGranularity=10 # Sampling period in seconds to retrieve positioning data from GPS via NMEA or from TTGO via SDK. DelayToBreakTracks=9 # [Seconds]. ...does not change for more than $((TrackingGranularity+DelayToBreakTracks)) seconds AllowDuplicatedCoords= # this controls the process used to break tracks; if set to yes, only TTGO suspend delays are used. AddGpxCounter=yes # Set to add sequence numbers in the field of each GPX GpxAuthor='amacri' # Any string (XML escapes are needed if special characters are used) GpxEmail='amacri@tiscali.it' # Any valid e-mail (XML escapes are needed if special characters like "<" and ">" are used) GpxUrl='http://web.tiscali.it/macri/Event_Logger' # Any valid URL (XML escapes are needed if special characters are used) GpxUrlName="Event_Logger $VERSION" # Any string (XML escapes are needed if special characters are used) DoGpxWpt=yes # Add waypoints to GPX (ref. to events logging: poweroff, poweron, boot and menu buttons) DoTrackWpt=yes # track waypoints (duplicate data to in GPX files) NewGpxWhenDateChanges= # Start a new Gpx file as soon as the date changes NewGpxWhenDayChanges=yes # New Gpx file as soon as the day changes NewGpxWhenNewItinerary=yes # New Gpx file if the itinerary file is missing, renamed or deleted. NewGpxWhenBooting= # New Gpx file upon each boot NewGpxWhenNewTravel= # New Gpx file as soon as a new travel is identified (long interval) CR1= #'\n' # set CR1='\n' if more linefeed separators are needed in GPX files to improve readability of and CR2= #'\n' # set CR2='\n' if more linefeed separators are needed in GPX files to further improve readability after each TTGOtoGPX=yes # if set to yes, GPX tracks fetch data from the TomTom GO application NMEAtoGPX=no # if set to yes, GPX tracks fetch data first from the GPS receiver (NMEA protocol), then (in case of failure and if # TTGOtoGPX is set) from the TomTom GO application SecsToRefreshConfig=10 # Seconds to refresh configuration after an external modification of $OEXEC # Archives for GPX and old Itinerary files (with zip compression) OldItnToKeepOnline=2 # set to 0 to disable this feature OldGpxToKeepOnline=5 # set to 0 to disable this feature ItnArchive="$ITNPath/ItnArchive.zip" # ITN Archive path GpxArchive="$ITNPath/GpxArchive.zip" # GPX Archive path RemoveNullItnFiles=yes RemoveNullGpxFiles=yes #Log files: TmpDir="/var/run" MAINDIR="$LoggerRootDir/Tracer" LOGFILE="$TmpDir/elg_TtnLog.txt" LogfileSD="$MAINDIR/TtnLog.txt" # Temporary files: ITNOK="$MAINDIR/LastLog.itn" # This is the only one which goes to the SD card (other than ITNs and logs) MountLog="$TmpDir/elg_MntLog" # mount logging and flag ShortIntervalSkipFlag="$TmpDir/elg_EvLogSkipFlag.txt" # If existing, next ShortInterval is ignored WptCounter="$TmpDir/WaypointCounter.txt" # Stores the next trackpoint number # dates to be shared among subsequent script instances are stored # as temporary files and read with zstat '%Y' LastGpsDate="$TmpDir/elg_LastGpsDate" # Event and date of the last (current) GPS retrieval ShortIntervalPermanentDate="$TmpDir/elg_EvLogIntDate" # First aggregated record (last master record before aggregation) MasterEventDate="$TmpDir/elg_MasterEventDate" # Date and event of the valid master record PrevMasterEventDate="$TmpDir/elg_PrevMstrEvtDate" # Date and event of the previous valid master record TripSeconds="$TmpDir/elg_TripSeconds" # Last track start date and duration of the previous tracks of a route TextForNextItem="$TmpDir/elg_TextNextItem" # Includes a string to be added to each next item (ref. next scripts) WptFile="$MAINDIR/Wpt.gpx" # Used by the GPX Tracking System to store Wpt records TrkptFile="$MAINDIR/Trk.gpx" # Used by the GPX Tracking System to store Trkpt records TrkptFileTemp="$MAINDIR/Trk-tmp.gpx" # Used by the GPX Tracking System. LatestGpx="$ITNPath/Trk_Last_Path.gpx" # Latest GPX track file created while powering-off (suspend). DaemonPid="$TmpDir/elg_DaemonPid" # When existing, includes pid of running trkptDaemon GPX daemon # Commands: OEXEC="$MAINDIR/Event_Logger.txt" EXEC="/bin/Event_Logger" RealTtn="/bin/ttn" # this is the real TTGO application ############### END OF CONFIGURATION VARIALBES ################################# let GeoidHeight=$GeoidHeight+0.005; GeoidHeight=${GeoidHeight%????} # round the value to the nearest two-digit floating number # Management of the debugging flags if test "$Debug" -ge 1 -a "$Debug" -le 3 then alias DebugLog=DoLog FMTrailer=" $Debug" else alias DebugLog="false LOG" FMTrailer=' .' test "$Debug" -ge 4 && FMTrailer=" $Debug" fi alias scalar="typeset +i" # inverse of "integer" # Date settings zdate -S TzShift "%s" "1970/01/02 00:00:00 $TIMEZONE" if test "$LinuxTimeIsUTC" = yes then TMZ="+0000" # TIMEZONE to subtract to a local time in order to get an UTC time TzSecs=$((86400-$TzShift)) # seconds to add to a UTC time in order to get a local time TzShift=0 # seconds to add to a Linux time in order to get a UTC time else TMZ="$TIMEZONE" # TIMEZONE to subtract to a local time in order to get an UTC time TzSecs=0 # seconds to add to a UTC time in order to get a local time TzShift=$(($TzShift-86400)) # seconds to add to a Linux time in order to get a UTC time fi TheEpoch="1970/1/1 0:0:0 +0000" zstat -S SecondsLastMod '%Y' "$OEXEC" 2>/dev/null zdate -S ExecDate "%Y-%m-%d" "$TheEpoch $SecondsLastMod seconds" SecondsLastMod=$((SecondsLastMod-TzSecs)) zstat -S ExecSize '%s' "$OEXEC" 2>/dev/null ### Procedures ### GpxSettings() { Descr="Sample=$TrackingGranularity NMEA=${NMEAtoGPX-no} Breaks=$DelayToBreakTracks" case "${TrackingGranularity:-0}_${NMEAtoGPX:-no}" in 10_no) ShortDescr="standard snap-to-road driving";; 5_yes) ShortDescr="off road trekking and racing";; 5_no) ShortDescr="accurate snap-to-road";; 10_yes) ShortDescr="off road driving and sailing";; *) ShortDescr="custom settings";; esac } Cat() { unset ReadBuffer while read -u0 -k 8000 ReadBuffer do echo "$ReadBuffer\c" done test "$ReadBuffer" && echo "$ReadBuffer\c" && unset ReadBuffer && return 0 DebugLog 1 "Cat: no data" >&1 unset ReadBuffer return 1 } colour() { # $1=red $2=green $3=blue return $(( (($1 >> 3) << 11) | (($2 >> 2) << 5) | (($3 >> 3) << 0) )) } fbprint() { { test "$Debug" -le 3 -o "$DoSplashTxt" = never && return FB_COL=$1 fb_print "$2" #FB_COL=$c_green fb_print "." } 2>/dev/null # do not trace this function } DoLog() { { DoLogCmd= DoLogDate= DoLogFile= test "$Debug" -le $1 && return 1 shift if test "$1" = -exec then DoLogCmd=$2 shift 2 fi if test "$1" = -date then DoLogDate=$2 shift 2 fi if test "$1" = -cat then DoLogFile=$2 shift 2 fi getpid MyPid zdate -S CDate "%c" "now $TzSecs seconds" test $# -gt 0 && echo -e "${CDate}-${Application}-${Event}-${MyPid}: $*" test "$DoLogCmd" && eval "$DoLogCmd" if test "$DoLogDate" then zstat -S DoLogADate '%Y' "$DoLogDate" zdate "%c" "$TheEpoch $((DoLogADate+TzSecs)) seconds" fi if test "$DoLogFile" then Cat<"$DoLogFile" fi return 0 } 2>/dev/null # do not trace this function } # of DoLog ConvertDate() { # Returns variable LDate including translation of the current date with format string and ref. passed as args. # Okay, using locale should be a better alternative, but provided that it is first # set up in the Linux/busybox environment of TTGO. Who is willing to perform this? # NOTE: typeset -i ensures that calculation results are always truncated to integers typeset -i Wtt zdate -S LDate "$1" "$2" LDate=${LDate:gs/ / /} let Wtt=1 while test $Wtt -le ${#EnglishWords} do eval 'LDate=${LDate:gs/'"$EnglishWords[$Wtt]/$TargetWords[$Wtt]/}" let Wtt+=1 done LDate=${LDate[1]:u}${LDate[2,-1]} } # of ConvertDate ###################### # Used IDs in trkptDaemon: #7 (GetLocationInfoEx) #1 (flash) #9 (GetCurrentPosition) #3 (ChangeSetting) trkptDaemon() { if test "$1" = "" then setopt BG_NICE # This sets the (fixed) degradation of the GPX daemon priority trkptDaemon daemon & return 1 fi getpid MyPid export PS4=" [$MyPid] %k:%M:%S " # set the trace prompt ([pid]=trkptDaemon) echo "$MyPid" > "$DaemonPid" StartDebug $0 $* zstat -S PrevCfgSeconds '%Y' "$EXEC" 2>/dev/null StopFlag= trap 'StopFlag=yes' 2 GpxSettings if test "$WriteBreakRestart" = yes then ( sleep 5 if test "$DoSdkShowMessage" then #zrm -f "/var/run/SDK.TomTomNavigationServer."*(N.) "/var/run/TomTomNavigationServer.SDK."*(N.) echo -e "FlashMessageV01| GPX Tracker startup completed. [${ShortDescr}] ${Descr}${FMTrailer}|6000|\0\c" > "/var/run/SDK.TomTomNavigationServer.$MyPid.31.message" echo finish > "/var/run/SDK.TomTomNavigationServer.$MyPid.31.finished" fi ) & else sleep 20 # Tune here the GPX daemon startup delay (in seconds) after a TTGO boot fi echo -e "EnableRawGPSOutputV01|\0\c" > "/var/run/SDK.TomTomNavigationServer.$MyPid.93.message" echo finish > "/var/run/SDK.TomTomNavigationServer.$MyPid.93.finished" scalar LatitudeU scalar LongitudeU OldLatitude= OldLongitude= OldLatitudeU= LatitudeU= OldLongitudeU= LongitudeU= OldStrings= GpxFix= PrevTime=$HSECONDS SameCoords= RsunaO=-$DNChangeCounter #trap '' 2 #infinite loop SECONDS=2 # Tune here the wait time for the first GetCurrentPosition query test "$NMEAtoGPX" = yes && SECONDS=$TrackingGranularity while true do # Refresh configuration when "$EXEC" changes NewCfgSeconds=0 zstat -S NewCfgSeconds '%Y' "$EXEC" 2>/dev/null if test "$NewCfgSeconds" -gt "${PrevCfgSeconds:-$NewCfgSeconds}" -a $((HSECONDS-NewCfgSeconds)) -gt $((SecsToRefreshConfig+TrackingGranularity)) then . $EXEC return # read all the Event_Logger configuration variables StartDebug $0 $* GpxSettings PrevCfgSeconds=$NewCfgSeconds if test "$DoSdkShowMessage" then echo -e "FlashMessageV01| New settings: [${ShortDescr}] ${Descr}${FMTrailer}|10000|\0\c" > "/var/run/SDK.TomTomNavigationServer.$MyPid.41.message" echo finish > "/var/run/SDK.TomTomNavigationServer.$MyPid.41.finished" fi fi DebugLog 3 || zrm -f "/var/run/TomTomNavigationServer.SDK.$MyPid."[139].*(N.) "/var/run/SDK.TomTomNavigationServer.$MyPid."[9].*(N.) test "$StopFlag" = yes -o ! -f "$DaemonPid" && break ClearNmeaData EleGpx= GpxDate= GpxCourse= GpxSpeed= GpxGeoidSep= GpxSat= #query TTGO if test "$TTGOtoGPX" = yes then echo -e "GetCurrentPosition|\0\c">"/var/run/SDK.TomTomNavigationServer.$MyPid.9.message" echo finish>"/var/run/SDK.TomTomNavigationServer.$MyPid.9.finished" fi #wait #trap 'StopFlag=yes' 2 sleep $((TrackingGranularity-SECONDS)) test $? -lt 0 && sleep $((Debug+0.5)) # avoid eating the CPU in case TrackingGranularity is too low; Debug>0 takes additional resources. SECONDS=0 #trap '' 2 #query & fetch directly from GPS (NMEA) test "$NMEAtoGPX" = yes && SyncTime=yes LoggerDoNotChangeDate=yes DoSdkGeodecode= FastGpsFetch=yes Debug=0 DoSplashTxt=never GetGpsData LOG #fetch from TTGO SdkRetCode= SdkGCPUpdate= SdkGCPLongitude= SdkGCPLatitude= SdkGCPSpeed= SdkGCPDirection= SdkGCPOther= test "$TTGOtoGPX" = yes -a \( ! "$GpxDate" -o ! "$Longitude" -o ! "$Latitude" \) && for i in 0.5 0.5 -1 # Tune here the wait duration of the ".9." API response (GetCurrentPosition) # args indicate the delay between loops. 0 means no delay; -1 must always be the last one do if test -s "/var/run/TomTomNavigationServer.SDK.$MyPid.9.finished" then # Fetch data from the SDK response GpxDate= zstat -S GpxSecs '%Y' "/var/run/TomTomNavigationServer.SDK.$MyPid.9.message" && zdate -S GpxDate "%Y-%m-%dT%H:%M:%S" "1970/1/1 0:0:0 $TMZ $GpxSecs seconds" test "$GpxSecs" -eq -1 && continue test "$GpxDate" || continue { IFS='|' read SdkRetCode SdkGCPUpdate Longitude Latitude SdkGCPSpeed SdkGCPDirection SdkGCPOther <"/var/run/TomTomNavigationServer.SDK.$MyPid.9.message"; } >/dev/null 2>&1 test "$SdkRetCode" && break fi case $i in *[1-9])sleep $i;;esac done test "$Debug" -le 0 && zrm -f "/var/run/TomTomNavigationServer.SDK.$MyPid.9."*(N.) "/var/run/SDK.TomTomNavigationServer.$MyPid.9."*(N.) #calculate Lat and Lon scalar Lat scalar Lon Lat= Lon= let Lat=${Latitude:-0}/100000 let Lon=${Longitude:-0}/100000 test $Lat[-1] = 0 && Lat=$Lat[1,-2] # remove the last decimal digit in case it is 0 test $Lon[-1] = 0 && Lon=$Lon[1,-2] # remove the last decimal digit in case it is 0 Time=$HSECONDS #change night and day (only limited filtering of invalid records here) if test "$DoSdkChSet" = yes -a "$Longitude" -a "$Latitude" -a \( "$Lon" -ne 0 -o "$Lat" -ne 0 \) then suna $(($Time+($TzShift))) $Lat $Lon "${MaxSunElevation}" $((TzSecs-($TzShift))) # is now night-time? Rsuna=$? # 0=night, 1=day; other values are errors if test "$Rsuna" -ne "$RsunaO" -a \( "$Rsuna" -eq 0 -o "$Rsuna" -eq 1 \) # Rsuna must be valid and different from RsunaO then if test $((RsunaO%DNChangeFactor)) -eq 0 -o $RsunaO -eq 1 -o $RsunaO -eq -1 # accepted RsunaO values: -1, 0, 1, multiples of $DNChangeFactor then echo -e "ChangeSetting|$((Rsuna+2))|\0\c" > "/var/run/SDK.TomTomNavigationServer.$MyPid.83.message" # use night(=2)/day(=3) colours echo finish > "/var/run/SDK.TomTomNavigationServer.$MyPid.83.finished" fi if test $RsunaO -lt -1 then let RsunaO++ elif test $RsunaO -gt -1 then let RsunaO=-$DNChangeCounter+1 else test $RsunaO -eq -1 && RsunaO=$Rsuna fi fi fi #skip invalid records if ! test "$SdkRetCode" -ge 0 >/dev/null 2>&1 then test "$SameCoords" = yes || PrevTime=$HSECONDS continue fi test "$Longitude" -a "$Latitude" -a \( "$Longitude" -gt 0 -o "$Longitude" -le 0 \) -a \( "$Latitude" -gt 0 -o "$Latitude" -le 0 \) -a \( "$Longitude" -ne 0 -o "$Latitude" -ne 0 \) || { test "$SameCoords" = yes || PrevTime=$HSECONDS OldFix=none continue } if test ! "$AllowDuplicatedCoords" = yes -a "$Longitude" = "${OldLongitude:-$Longitude}" -a "$Latitude" = "${OldLatitude:-$Latitude}" then if test "$DoSdkGeodecode" -a ! "$SameCoords" = yes then zrm -f /var/run/TomTomNavigationServer.SDK.$MyPid.7.finished /var/run/TomTomNavigationServer.SDK.$MyPid.7.message /var/run/SDK.TomTomNavigationServer.$MyPid.7.finished /var/run/SDK.TomTomNavigationServer.$MyPid.7.message echo -e "GetLocationInfoEx|$Longitude|$Latitude|\0\c">"/var/run/SDK.TomTomNavigationServer.$MyPid.7.message" echo finish>"/var/run/SDK.TomTomNavigationServer.$MyPid.7.finished" fi SameCoords=yes test "$OldLongitude" -o "$OldLatitude" && continue # this variables are not valued only during the first loop (start/restart) sleep 2 # fall here in case of start/restart; allow GetLocationInfoEx to be processed so that GetGeodecode will return a valid $GeoDecode fi SameCoords= #prepare OldLatitude="$Latitude" OldLongitude="$Longitude" OldLatitudeU="${LatitudeU}" OldLongitudeU="${LongitudeU}" OldStrings="$GpxCourse$GpxSpeed$GpxGeoidSep$GpxFix$GpxSat" LatitudeU=$Lat LongitudeU=$Lon test "$SdkGCPDirection" && GpxCourse="${SdkGCPDirection}.0" test "$NMEAtoGPX" = yes -a "$Course" && GpxCourse="${Course}" #Speed="$SdkGCPSpeed${SdkGCPSpeed:+.0}" test ! "$SdkGCPSpeed" -a "$Speed" -a "$NMEAtoGPX" = yes && SdkGCPSpeed=$Speed if [ "$SdkGCPSpeed" ] then # Convert km/h to m/sec scalar SpeedMs # Define a string variable in orther to enable the 6-decimals math calculator let SpeedMs=$SdkGCPSpeed/3.6+0.005 GpxSpeed="${SpeedMs%????}" fi GpxFix='none' test "$SdkGCPUpdate" -gt 0 && GpxFix='2d' test "$NMEAtoGPX" = yes && ManageAltitude #write Name= if test "$AddGpxCounter" = yes then { read Counter < "$WptCounter"; } 2>/dev/null Counter=$((${Counter:-0}+1)) echo "$Counter" > "$WptCounter" Name='Point '"$Counter"'' fi ConvertDate "$Today %H:%M:%S" "now $TzSecs seconds" 2>/dev/null # no traces Space= GeoDecode= SdkRGRetCode= SdkRGLongitude= SdkRGLatitude= SdkRGType= SdkRGStreet= SdkRGHouseNumber1= SdkRGHouseNumber2= SdkRGCity= SdkRGOther= GetGeodecode "$MyPid.7" && Space=' -' # return $GeoDecode zrm -f /var/run/TomTomNavigationServer.SDK.$MyPid.7.finished /var/run/TomTomNavigationServer.SDK.$MyPid.7.message /var/run/SDK.TomTomNavigationServer.$MyPid.7.finished /var/run/SDK.TomTomNavigationServer.$MyPid.7.message if test -s "$TrkptFile" then if test "$WriteBreakRestart" = yes then echo -e ''"${CR1}"''"${CR2}"'Restarted on '"${LDate}${Space}${GeoDecode}"''"${CR1}"''"${CR1}" >> "$TrkptFile" WriteBreakRestart= fi else echo -e ''"${LDate}${Space}${GeoDecode}"''"${CR1}"''"${CR1}" >> "$TrkptFile" 2>/dev/null fi if test "$DoBreakTracks" = yes -a ! "$OldLatitudeU" = "." -a ! "$OldLongitudeU" = "." -a $((${Time:-0}-${PrevTime:-0}-${TrackingGranularity:-0})) -gt $DelayToBreakTracks then echo -e ''"${CR1}"''"${CR2}"''"${LDate}${Space}${GeoDecode}"''"${CR1}"''"${CR1}"\ ''"${EleGpx}"''"$Name$OldStrings"'' >> "$TrkptFile" if test "$AddGpxCounter" = yes then Counter=$((${Counter:-0}+1)) echo "$Counter" > "$WptCounter" Name='Point '"$Counter"'' fi fi echo ''"${EleGpx}"''"$Name$GpxCourse$GpxSpeed$GpxGeoidSep$GpxFix$GpxSat"'' >> "$TrkptFile" 2>/dev/null PrevTime="$Time" done #sleep 1 zrm -f "/var/run/TomTomNavigationServer.SDK.$MyPid."*(N.) "/var/run/SDK.TomTomNavigationServer.$MyPid."*(N.) #sleep 1 GpxSettings if test "$DoSdkShowMessage" then echo -e "FlashMessageV01| GPX Tracker shutdown completed. [${ShortDescr}] ${Descr}${FMTrailer}|6000|\0\c" > "/var/run/SDK.TomTomNavigationServer.$MyPid.14.message" echo finish > "/var/run/SDK.TomTomNavigationServer.$MyPid.14.finished" fi echo "STOP" > "$DaemonPid" } # of trkptDaemon ###################### StartDebug() { if test "$Debug" -eq 2 -o "$Debug" -ge 5 then exec 1>>"$MAINDIR/TrxLog.txt" 2>&1 echo -e "\nStarted $* - Event=$Event, Application=$NAME - Version $VERSION.$ExecSize $ExecDate($DATE)\n $AUTHOR, BSH Version: $ZSH_VERSION, Trace Level $Debug, \c" zdate "%c" "now $TzSecs seconds" test "$Debug" -ge 5 && set -x fi } WptTrkPoi() { if test "$SecondsMasterEvent" -gt 0 then ConvertDate "$Today %H:%M:%S" "$TheEpoch $((SecondsMasterEvent+TzSecs)) seconds" 2>/dev/null # no traces else ConvertDate "$Today %H:%M:%S" "now $TzSecs seconds" 2>/dev/null # no traces fi SymType="Dot$1" case "$1" in RESUME|SUSPEND|BOOT)SymType="Waypoint$1";;esac if test "$DoGpxWpt" = yes then test -f "$WptFile" || echo 'BEGIN '"${LDate}"' '"${GpxAuthor:+}$GpxAuthor${GpxAuthor:+}${GpxEmail:+}$GpxEmail${GpxEmail:+} ${GpxUrl:+}$GpxUrl${GpxUrl:+}${GpxUrlName:+}$GpxUrlName${GpxUrlName:+}" >> "$WptFile" echo "" >> "$WptFile" fi if test "$DoTrackWpt" = yes then test -s "$TrkptFile" || echo -e ''"${LDate}${Space}${GeoDecode}"''"${CR1}"''"${CR1}" >> "$TrkptFile" Name= if test "$AddGpxCounter" = yes then { read Counter < "$WptCounter"; } 2>/dev/null Counter=$((${Counter:-0}+1)) echo "$Counter" > "$WptCounter" Name='Point '"$Counter"'' fi echo "" >> "$TrkptFile" fi if [ "$DoSdkAddPoi" = yes ] then eval 'case "$1" in '"$PoiEventFilter"');;*) return;;esac' echo -e "AddPoi|$1$PoiFileName|$2|\0\c">"/var/run/SDK.TomTomNavigationServer.$ProcessId.8.message" echo finish>"/var/run/SDK.TomTomNavigationServer.$ProcessId.8.finished" fi } GpxEnveloper() { test "$1" -eq 0 -a "$AddGpxCounter" = yes && echo "0" > "$WptCounter" GpxSecs1=0 GpxSecs=0 test -s "$WptFile" && zstat -S GpxSecs '%Y' "$WptFile" test -s "$TrkptFile" && zstat -S GpxSecs1 '%Y' "$TrkptFile" test $GpxSecs1 -gt $GpxSecs && GpxSecs=$GpxSecs1 test $GpxSecs -le 0 && return GpxFile="$LatestGpx" zrm -f "$GpxFile" LDate= test "$1" -eq 0 && zdate -S GpxFile "$ITNPath/Trk_%y-%m-%d_%H-%M-%S.gpx" "$TheEpoch $((GpxSecs+TzSecs)) seconds" ConvertDate "$Today %H:%M:%S" "$TheEpoch $((GpxSecs+TzSecs)) seconds" 2>/dev/null # no traces # GPX Header echo ' END '"${LDate}"'' > "$GpxFile" test -s "$WptFile" && Cat <"$WptFile" >>"$GpxFile" local InFile="$TrkptFile" if test -s "$InFile" then test "$1" -eq 0 && zmv "$InFile" "$TrkptFileTemp" 2>/dev/null && InFile="$TrkptFileTemp" Cat <"$InFile" >>"$GpxFile" 2>/dev/null # no traces echo -e ''"${CR1}"''"${CR2}\c" >> "$GpxFile" # Track footer fi # GPX Footer echo '' >> "$GpxFile" if test "$1" -eq 0 then zrm -f "$WptFile" "$InFile" MakeOldGpxArchive fi } # of GpxEnveloper GetGeodecode() { # Fetch location data from the SDK response to GeoDecode variable test -s "/var/run/TomTomNavigationServer.SDK.$1.finished" || return 1 { IFS='|' read SdkRGRetCode SdkRGLongitude SdkRGLatitude SdkRGType SdkRGStreet SdkRGHouseNumber1 SdkRGHouseNumber2 SdkRGCity SdkRGOther <"/var/run/TomTomNavigationServer.SDK.$1.message"; } >/dev/null 2>&1 DebugLog 3 "SdkRGRetCode=$SdkRetCode SdkRGLongitude=$SdkRGLongitude SdkRGLatitude=$SdkRGLatitude SdkRGType=$SdkRGType SdkRGStreet=$SdkRGStreet SdkRGHouseNumber1=$SdkRGHouseNumber1 SdkRGHouseNumber2=$SdkRGHouseNumber2 SdkRGCity=$SdkRGCity SdkRGOther=$SdkRGOther" if test "$SdkRGRetCode" -ge 0 2>/dev/null then GeoDecode= Sep=" " SepC="" test "$SdkRGStreet" -a ! "$SdkRGStreet" = "$UnnamedRoadString1" -a ! "$SdkRGStreet" = "$UnnamedRoadString2" && GeoDecode=" $SdkRGStreet" SepC=',' test "$SdkRGHouseNumber1" -a ! "$SdkRGHouseNumber1" = 0 && GeoDecode="$GeoDecode $SdkRGHouseNumber1" Sep='-' SepC=',' test "$SdkRGHouseNumber2" -a ! "$SdkRGHouseNumber2" = 0 && GeoDecode="$GeoDecode$Sep$SdkRGHouseNumber2" SepC=',' test "$SdkRGCity" && GeoDecode="$GeoDecode$SepC $SdkRGCity" fi return 0 } GetLocation() { getpid MyPid export PS4=" <$MyPid> %k:%M:%S " # set the trace prompt FB_X=2 FB_Y=$((y_start+5+16+FB_FontY*3)) fbprint $c_orange "Background GetCurrentPosition: " echo -e "GetCurrentPosition|\0\c" > "/var/run/SDK.TomTomNavigationServer.$ProcessId.1.message" echo finish > "/var/run/SDK.TomTomNavigationServer.$ProcessId.1.finished" fbprint $c_black "BEGIN " SdkRetCode= SdkGCPUpdate= SdkGCPLongitude= SdkGCPLatitude= SdkGCPSpeed= SdkGCPDirection= SdkGCPOther= # amacri 11-26-05: the following line has been tuned for TTGO version 5.420, a bit slowler than the previous ones let LoopCount=0 for i in 0.5 0.5 0.5 0.5 ${=AdditionalLoops} -1 # Tune here the wait duration of the ".1." API response (GetCurrentPosition) # args indicate the delay between loops. 0 means no delay; -1 must always be the last one do test -s "/var/run/SDK.TomTomNavigationServer.$ProcessId.3.finished" && break # GetLocationInfoEx query already existing if test -s "/var/run/TomTomNavigationServer.SDK.$ProcessId.1.finished" # GetCurrentPosition response available then # Fetch data from the SDK response GpxDate= zstat -S GpxSecs '%Y' "/var/run/TomTomNavigationServer.SDK.$ProcessId.1.message" && zdate -S GpxDate "%Y-%m-%dT%H:%M:%S" "1970/1/1 0:0:0 $TMZ $GpxSecs seconds" { IFS='|' read SdkRetCode SdkGCPUpdate SdkGCPLongitude SdkGCPLatitude SdkGCPSpeed SdkGCPDirection SdkGCPOther <"/var/run/TomTomNavigationServer.SDK.$ProcessId.1.message"; } >/dev/null 2>&1 if test "$DoSdkGeodecode" = yes -a "$SdkRetCode" -ge 0 -a "$SdkGCPLongitude" -a "$SdkGCPLatitude" 2>/dev/null then echo -e "GetLocationInfoEx|$SdkGCPLongitude|$SdkGCPLatitude|\0\c">"/var/run/SDK.TomTomNavigationServer.$ProcessId.3.message" echo finish>"/var/run/SDK.TomTomNavigationServer.$ProcessId.3.finished" fi break fi fbprint $c_black $(($i)) #let LoopCount+=1; fbprint $c_cyan $(($LoopCount)) LoopCount=$((LoopCount+1)); fbprint $c_cyan $(($LoopCount)) case $i in *[1-9])sleep $i;; -2) zrm -f "/var/run/SDK.TomTomNavigationServer.$ProcessId.1.message" "/var/run/SDK.TomTomNavigationServer.$ProcessId.1.finished" sleep 3 echo -e "GetCurrentPosition|\0\c">"/var/run/SDK.TomTomNavigationServer.$ProcessId.1.message" echo finish>"/var/run/SDK.TomTomNavigationServer.$ProcessId.1.finished" ;; esac done fbprint $c_black " END" } # of GetLocation MakeOldItnArchive() { test "$RemoveNullItnFiles" = yes && zrm -f "$ITNPath/"Log-*.itn(N.L0) # Move old Itinerary files to a "$ItnArchive" zip archive, # always leaving "$OldItnToKeepOnline" files online (e.g., not archived). test "$OldItnToKeepOnline" -lt 1 && return DebugLog 1 "ITN archiving" FileList=("$ITNPath/"Log-*.itn(N.om)) NFiles=${#FileList} DirList=(*(N.om)) if test ${OldItnToKeepOnline} -lt $NFiles then shift ${OldItnToKeepOnline} FileList test ${#FileList} -gt 0 && echo -e "$NAME $VERSION for TomTom GO.\nCompressed archive of old itinerary files. ${LDate}." | $MAINDIR/zip -Xqojzum9 "$ItnArchive" ${=FileList} & BgPid="$BgPid $!" fi #DebugLog 1 "Generation of $ItnArchive successfully completed" return 0 } # of MakeOldItnArchive MakeOldGpxArchive() { test "$RemoveNullGpxFiles" = yes && zrm -f "$ITNPath/"Trk_*.gpx(N.L0) # Move old GPX files to a "$GpxArchive" zip archive, # always leaving "$OldGpxToKeepOnline" files online (e.g., not archived). test "$OldGpxToKeepOnline" -lt 1 && return DebugLog 1 "GPX archiving" FileList=("$ITNPath/"Trk_*.gpx(N.om)) NFiles=${#FileList} DirList=(*(N.om)) if test ${OldGpxToKeepOnline} -lt $NFiles then shift ${OldGpxToKeepOnline} FileList test ${#FileList} -gt 0 && echo -e "$NAME $VERSION for TomTom GO.\nCompressed archive of old GPX tracks. ${LDate}." | $MAINDIR/zip -Xqojzum9 "$GpxArchive" ${=FileList} & BgPid="$BgPid $!" fi #DebugLog 1 "Generation of $GpxArchive successfully completed" return 0 } # of MakeOldGpxArchive ProcessCoords() { if [ "$LatitudeS" -a "$LatitudeSign" -a "$LongitudeS" -a "$LongitudeSign" ] then ## STEP A1: extract Latitude PMinutes=${LatitudeS#??} MinToDeg=0000000$(((${PMinutes%.*}${LatitudeS#*.}00/60+5)/10)) Deg=0${LatitudeS%??.*} PadsD=${Deg%%[1-9]*} PadsM=${MinToDeg%?????} Latitude=${Deg#$PadsD}${MinToDeg#$PadsM} && test "$LatitudeSign" = N || Latitude=-${Deg#$PadsD}${MinToDeg#$PadsM} DebugLog 3 "Target Latitude: $Latitude" ## STEP A2: extract Longitude PMinutes=${LongitudeS#???} MinToDeg=0000000$(((${PMinutes%.*}${LongitudeS#*.}00/60+5)/10)) Deg=0${LongitudeS%??.*} PadsD=${Deg%%[1-9]*} PadsM=${MinToDeg%?????} Longitude=${Deg#$PadsD}${MinToDeg#$PadsM} && test "$LongitudeSign" = E || Longitude=-${Deg#$PadsD}${MinToDeg#$PadsM} DebugLog 3 "Target Longitude: $Longitude" else DebugLog 2 "No valid data from GPS" fi } ClearNmeaData() { NewDate= Latitude= Longitude= DateHms= DateDmy= Speed= Course= Altitude= SatellitesUsed= HDOP= PDOP= VDOP= MagneticVariation= GeoidSeparation= PosFixInd= SatellitesInView= Dimension= } GetGpsData() # Notice this function must not use the SD card { # This function includes a trivial NMEA interpreter and syncs the date # not Y2K comp., e.g., will not work for if year < 2000 # $1: Event: RESUME|SUSPEND|BOOT #Control variables: SpeedNotAvailable (skip Speed), FastGpsFetch (accept unaccurate dates and missing altitude), DoSdkGeodecode (geodecode # the retrieved coords), SyncTime (calc. NewDate), DoSplashTxt (do fbprint), LoggerDoNotChangeDate (sync), Debug (DebugLog) #SECONDS is used (reset at the beginning) #Output: Latitude, Longitude, Speed, NewDate (and GpxDate), Course (and DateHms, DateDma) #Return codes: 1 (DateHms and DateDma missing) Ldncd=yes # do not sync date unless an accurate value is fetched fbprint $c_black "-" ClearNmeaData SECONDS=0 NumLines=0 GpsArray=() GpsArrayIndex=1 while test \( \( $NumLines -lt $GpsMaxLines \) -o \( $GpsArrayIndex -le ${#GpsArray} \) \) -a $SECONDS -le $GpsTimeout do if test $GpsArrayIndex -gt ${#GpsArray} then GpsFeed= read -u0 -k $GpsMinBytes GpsFeed EndFeed <"$LoggerGpsData" || sleep 0.1 fbprint $c_black "a" GpsFeed=${GpsFeed%$LF*} GpsArray=(${(f)GpsFeed}) DebugLog 3 "GPSDATA=\n${(F)GpsArray}" test ${#GpsArray} -lt 1 && continue GpsArrayIndex=1 fi fbprint $c_green "b" OIFS=$IFS IFS=",*$CR" GpsCmd=(${=GpsArray[$GpsArrayIndex]}) IFS=$OIFS DebugLog 3 "GPSLINE=$GpsArray[$GpsArrayIndex] GPSCMD=$GpsCmd" let GpsArrayIndex+=1 let NumLines+=1 test "$GpsCmd[1]" || continue case "$GpsCmd[1]" in \$GPGGA) PosFixInd="${GpsCmd[7]:--1}" # Position Fix Indicator; -1=missing. 0=Fix not available or invalid. 1(SPS),2(DGPS SPS),3(PPS),4(RTK)=fix valid if [ "$PosFixInd" -gt 0 -a ! "$Altitude" ] # (Position Fix Indicator)=0: Fix not available or invalid then fbprint $c_red "C" # coords if test "$FastGpsFetch" = yes -a ! "$DateHms" then zdate -S DateDmy "%d%m%y" "now $TzShift seconds" DateHms=$(($GpsCmd[2]+0.5)) Ldncd=yes # here date is not precise enough to drive a sync fi LatitudeS="$GpsCmd[3]" # ddmm.mmmm LatitudeSign="$GpsCmd[4]" # N/S Indicator LongitudeS="$GpsCmd[5]" # dddmm.mmmm LongitudeSign="$GpsCmd[6]" # E/W Indicator ProcessCoords SatellitesUsed="$GpsCmd[8]" # Satellites used; es., range 0 to SatellitesInView HDOP="$GpsCmd[9]" # Horizontal Dilution of Precision test "$GpsCmd[11]" = M && Altitude="$GpsCmd[10]" # altitude in meters test "$GpsCmd[13]" = M && GeoidSeparation="$GpsCmd[12]" # not valued in Sirf2 fi;; \$GPRMC) fbprint $c_red "D" # date test "$GpsCmd[9]" && Course="$GpsCmd[9]" # Measured heading over ground in degrees if test "$GpsCmd[3]" = A # A=data valid, V=data not valid then DateHms=$(($GpsCmd[2]+0.5)) DateDmy="$GpsCmd[10]" Ldncd=$LoggerDoNotChangeDate # here date is accurate and can drive a sync MagneticVariation="$GpsCmd[11]" # degrees, E=east or W=west if test ! "$Latitude" -o ! "$Longitude" then LatitudeS="$GpsCmd[4]" # ddmm.mmmm LatitudeSign="$GpsCmd[5]" # N/S Indicator LongitudeS="$GpsCmd[6]" # dddmm.mmmm LongitudeSign="$GpsCmd[7]" # E/W Indicator ProcessCoords fi fi;; \$GPGSA) Dimension="$GpsCmd[3]" # 1=no fix, 2=2d, 3=3d test "$Dimension" -gt 1 || continue PDOP="$GpsCmd[16]" # Position Dilution of Precision test ! "$HDOP" -a "$GpsCmd[17]" && HDOP="$GpsCmd[17]" # Horizontal Dilution of Precision VDOP="$GpsCmd[18]" # Vertical Dilution of Precision ;; \$GPGSV) SatellitesInView="$GpsCmd[4]" # Satellites in View; es., range 0 to 12 ;; \$GPVTG) test ! "$Course" -a "$GpsCmd[2]" && Course="$GpsCmd[2]" # Measured heading in degrees test "$GpsCmd[9]" = K -a "$GpsCmd[8]" || continue fbprint $c_red "S" # speed Speed="$GpsCmd[8]" # Measured horizontal speed in kilometers per hour test "$Speed" -gt $MaxSpeedToShowPoint && Speed=$((GpsCmd[8]+0.5)) # rounded to the nearest integer ;; *) continue;; esac test "$Latitude" -a "$Longitude" -a "$DateHms" -a "$DateDmy" -a \( "$Speed" -o "$SpeedNotAvailable" = yes \) -a \( "$FastGpsFetch" = yes -o "$Altitude" \) && break done fbprint $c_black "f" DebugLog 3 "GPSPARMS: LatitudeS=$LatitudeS LatitudeSign=$LatitudeSign LongitudeS=$LongitudeS LongitudeSign=$LongitudeSign Altitude=$Altitude DateHms=$DateHms DateDmy=$DateDmy Speed=$Speed" PadsD=${SatellitesUsed%%[1-9]*} SatellitesUsed="${SatellitesUsed#$PadsD}" # Remove trailing 0's from SatellitesUsed if test "$Latitude" -a "$Longitude" -a ! -s "/var/run/TomTomNavigationServer.SDK.$ProcessId.3.finished" -a "$DoSdkGeodecode" then echo -e "GetLocationInfoEx|$Longitude|$Latitude|\0\c">"/var/run/SDK.TomTomNavigationServer.$ProcessId.3.message" echo finish>"/var/run/SDK.TomTomNavigationServer.$ProcessId.3.finished" fi test "$DateHms" -a "$DateDmy" || return 1 # Date management (if env. $LoggerDoNotChangeDate ($Ldncd) is set to yes, it allows testing without changing the date) if test "$SyncTime" = yes -a ! "$1" = BOOT -a ! "$1" = RESUME then DateHms=0000$DateHms DateHms=${DateHms#${DateHms%??????}} dtmp1=${DateDmy#??} dtmp2=${DateHms#??} dtmp3=${DateHms#????} zdate -S NewDate "%s" "20${DateDmy#????}/${dtmp1%??}/${DateDmy%????} ${DateHms%????}:${dtmp2%??}:${dtmp3%} +0000" zdate -S GpxDate "%Y-%m-%dT%H:%M:%S" "20${DateDmy#????}/${dtmp1%??}/${DateDmy%????} ${DateHms%????}:${dtmp2%??}:${dtmp3%} +0000" if test ! "$Ldncd" -a $NewDate -gt 0 -a \( $((NewDate-(TzShift)-HSECONDS)) -gt $MinSecToChDate -o $((HSECONDS-NewDate+(TzShift))) -gt $MinSecToChDate \) then HSECONDS=$((NewDate-(TzShift)+(DateCalibration))) fbprint $c_red "H" zdate -S Ndate "$LongDateFormat" "now $TzSecs seconds" DebugLog 3 "date changed to $Ndate = $NewDate seconds." FastGpsFetch=yes fi fi fbprint $c_black "h" return 0 } # of GetGpsData WaitForBackgroundPids() { # if $1=command, $2=0.5 and $3=pid, repeats the loop one time # if $1=command, $2=60 and $3=pid, time limit to wait for is 60x1=60 seconds scalar Progr Progr=0.5 let LoopCount=0 while test $2 -ge $Progr do FoundPid= CurrentPid=${3:gs/_//} pushd /proc for Pid in [0-9]* do fbprint $c_green "@" test $Pid = $CurrentPid && continue CmdLine1= CmdLine2= { read CmdLine1 CmdLine2<$Pid/cmdline;} >/dev/null 2>&1 DebugLog 3 "PsLine=$CmdLine1 $CmdLine2" 2>&1 case "$CmdLine1 $CmdLine2" in *$3*) continue;; *trkptDaemon*) continue;; *WriteBreakRestart*) continue;; *$EXEC*)exec 2>&1;FoundPid=yes;exec 2>/dev/null;; # include this in the traces esac done popd test "$FoundPid" = yes || return 0 let Progr=$Progr+0.5 fbprint $c_black "$" let LoopCount+=1; fbprint $c_cyan $(($LoopCount)) sleep 0.5 done 2>/dev/null # no traces DebugLog 1 "probes timed out with still existing pid!" return 1 } PsTop() { echo _______________________________________________________ >> /mnt/sdcard/top.txt 2>&1 echo $$ >> /mnt/sdcard/top.txt 2>&1 echo _______________________________________________________ >> /mnt/sdcard/top.txt 2>&1 while true do top -d 20 >> /mnt/sdcard/top.txt 2>&1 & ps -ef >> /mnt/sdcard/top.txt 2>&1 sleep 20 # Tune here the delay between probes done } ManageAltitude() { # control variables: Altitude, GeoidHeight, mToFeet # return EleGpx and GpxFix EleGpx= if test "$Altitude" then if test "$AddGeoidheight" = yes then GpxGeoidSep="${GeoidSeparation:-$GeoidHeight}" test "${Altitude#*.}" -eq $Altitude && Altitude=${Altitude}.0 EleGpx=''${Altitude}'' if test "$mToFeet" = yes then Altitude=$(((${Altitude}*100000/3048+5)/10)) else Altitude=$((${Altitude}+0.5)) # round to the nearest integer fi else if test "$GeoidSeparation" # Corrected altitude (MSL) rounded to the nearest integer then if test "$mToFeet" = yes then Altitude=$((((${Altitude}+${GeoidSeparation})*100000/3048+5)/10)) else Altitude=$((${Altitude}+${GeoidSeparation}+0.5)) # New GPS should return GeoidSeparation fi else if test "$mToFeet" = yes then Altitude=$((((${Altitude}+${GeoidHeight})*100000/3048+5)/10)) else Altitude=$(((${Altitude%.*}${Altitude#*.}+5-${GeoidHeight}*10)/10)) # int ( (Altitude*10+GeoidHeight*10+5)/10 ) fi fi EleGpx=''${Altitude}'.0' # Added ".0" to support GPX parsing fi GpxFix='3d' Altitude=" ${Altitude}${AltitudeUnit}" else test ! "$GpxFix" = 'none' && GpxFix='2d' fi case "$Dimension" in 1) GpxFix='none';; 2) GpxFix='2d';; 3) GpxFix='3d';; esac GpxSat=${SatellitesUsed:+${SatellitesUsed}}${HDOP:+${HDOP}}${VDOP:+${VDOP}}${PDOP:+${PDOP}} } ################################################################################ GpsLogger() { # $1: Event: RESUME|SUSPEND|BOOT # $2: Flag: 0=grey start, 1=start, 2=grey stop, 3=stop, 4=first Flag="$2" FB_X=2 FB_Y=$((y_start+5+16+FB_FontY*FB_FontX)) fbprint $c_orange "GpsLogger: " ##### ## STEP H1: report date change DiffSecs=$((${SecondsNow:-0}-${OSecondsNow:-0})) if [ ! "$1" = n -a "$DumpDate" = yes -a \( $DiffSecs -gt 30 -o $DiffSecs -lt -30 \) ] then DebugLog 1 "date was changed (old one: $Odate; new one: $Ndate)" echo -e "0|0|Old date $Odate|0|\n0|1|New date $Ndate|1|" >>"$ITN" DenyAggregation=yes test "$NewGpxWhenDateChanges" = yes && GpxEnveloper 0 fi fbprint $c_black "j" ## STEP H2: while resuming, leave background processes terminate first test "$1" = "RESUME" -a "$3" && WaitForBackgroundPids $1 30 $3 # Tune here (second arg) the wait time in seconds fbprint $c_black "k" ## STEP H3: Manage log rotation DoItnArchive= SecondsItn= ConvertDate "$Today" "now $TzSecs seconds" 2>/dev/null # no traces if test -f "$ITN" then zstat -S SecondsItn '%Y' "$ITN" zdate -S DateToStartItnRotation "%s" "$HourToStartItnRotation" DateToStartItnRotation=$((DateToStartItnRotation-TzSecs)) test $DateToStartItnRotation -gt $SecondsNow 2>/dev/null && DateToStartItnRotation=$((${DateToStartItnRotation:-0}-86400)) # go back one day # do not break logging if a change of day occurs before a LOG type or SUSPEND event # anyway, always break when exceeding $MaxItnLines read -u0 -k 65000 ItnFile <"$ITN" ItnLines=${(Wf)#ItnFile} if test \( \( "$1" = "RESUME" -o "$1" = "BOOT" \) -a $DateToStartItnRotation -gt $SecondsItn \) -o $ItnLines -ge $MaxItnLines then OldItn=error zstat -S GpxSecs '%Y' "$ITN" && zdate -S OldItn "$ITNOHeader-$OldLogFileFormat.$ITNExtension" "$TheEpoch $GpxSecs seconds" # log name corresponds to the date of the last event while test -f "$ITNPath/$OldItn" do test "$Counter" || Counter=1 zdate -S OldItn "$ITNOHeader-$OldLogFileFormat-$Counter.$ITNExtension" "$TheEpoch $GpxSecs seconds" Counter=$((${Counter:-0}+1)) done test "$NewGpxWhenDayChanges" = yes -a $DateToStartItnRotation -gt $SecondsItn && GpxEnveloper 0 echo "0|0|Rotated on $Ndate|2|" >>"$ITN" zmv "$ITN" "$ITNPath/$OldItn" LogRotationSym="$LogRotationSymbol" && test $DateToStartItnRotation -gt $SecondsItn && LogRotationSym= # Here rotate ITN because of new day (no LogRotationSymbol mark) or exceeding items (mark with LogRotationSymbol) echo "0|0|${LogRotationSym}From $OldItn|1|" >>"$ITN" echo "0|0|${LDate}|1|" >>"$ITN" test $Flag -gt 0 && Flag=$(($Flag-1)) # show comments in grey DenyAggregation=yes DoItnArchive=yes fi else # Here initialize a new $ITN test "$NewGpxWhenNewItinerary" = yes && GpxEnveloper 0 echo "0|0|${LDate}|1|" >>"$ITN" test $Flag -gt 0 && Flag=$(($Flag-1)) # show comments in grey DenyAggregation=yes DoItnArchive=yes fi ##### fbprint $c_black "l" # STEP B1: manage a boot record and Flag field if [ "$1" = "BOOT" ] then Flag=0 DebugLog 3 "Boot record is: 0|0|Boot $Ndate|3|" echo "0|0|Boot $Ndate|2|" >>"$ITN" DenyAggregation=yes test "$NewGpxWhenBooting" = yes && GpxEnveloper 0 fi test -f "$ITN" || Flag=4 DebugLog 3 "Flag=$Flag" fbprint $c_black "m" # STEP B2: manage aggregate records # Use DenyAggregation to avoid aggregation within this script (e.g. when last $ITN record includes a # comment which must not be deleted); use ShortIntervalSkipFlag to signal next script to avoid # aggregation (e.g., next event is a LOG type or there are comments in $ITN made by a previous script) # Master records are RESUME or SUSPEND event logs not replacing a previous event (so, not involved in aggregation). # Aggregate records are non LOG type events which occur within ShortInterval from a previous non LOG type event. # Delta are calculated as time differences from the first deleted record of repeated adiacent removals. # Intervals are calculated as time differences from the master record occurrence. # each BOOT event will update both PrevMasterEventDate and MasterEventDate if [ "$1" = "BOOT" ] then zcp -p "$LastGpsDate" "$PrevMasterEventDate" 2>/dev/null || echo "$1" > "$PrevMasterEventDate" zcp -p "$LastGpsDate" "$MasterEventDate" 2>/dev/null || echo "$1" > "$MasterEventDate" DebugLog 3 -date "$MasterEventDate" "BOOT event: new MasterEventDate=\c" DebugLog 3 -date "$PrevMasterEventDate" "BOOT event: new PrevMasterEventDate=\c" zcp -p "$LastGpsDate" "$TripSeconds" fi fbprint $c_black "n" Delta= zrm "$ShortIntervalSkipFlag" 2>/dev/null && DenyAggregation=yes # If ShortIntervalSkipFlag exists, reset to avoid aggregation # Comment out the following line if events of type LOG shall also be part of aggregations case "$1" in RESUME|SUSPEND|BOOT);;*)echo "$SecondsPreviousEvent" > "$ShortIntervalSkipFlag";;esac # Do not aggregate after a LOG type event MasterEvent= test "$1" = "SUSPEND" -o "$1" = "RESUME" && MasterEvent=yes DiffDate=$((($Rounding+${SecondsNow:-0}-${SecondsPreviousEvent:-0})/60)) DebugLog 3 "DiffDate=$DiffDate ShortInterval=$ShortInterval" if test ! "$DenyAggregation" = yes -a \( "$1" = "SUSPEND" -o "$1" = "RESUME" \) -a $DiffDate -lt $ShortInterval then if test -f "$ShortIntervalPermanentDate" then DSecs=0 zstat -S DSecs '%Y' "$ShortIntervalPermanentDate" DiffDate=$((($Rounding+${SecondsNow:-0}-$DSecs)/60)) else zcp -p "$MasterEventDate" "$ShortIntervalPermanentDate" || zcp -p "$LastGpsDate" "$ShortIntervalPermanentDate" || >"$ShortIntervalPermanentDate" fi Delta=$AggregSeparatorSymbol$DiffDate test $DiffDate -lt 0 && Delta=" $ResetString" test "$Delta" = '-0' && Delta="-1$LessThanOneMinuteSymbol" if DebugLog 3 then echo -e "0|0|^^ Delete!! ^^|1|" >>"$ITN" else # Delete the last record of the itinerary file OldLine= ItnContent= while read Line do ItnContent="${ItnContent:+$ItnContent\\n$OldLine}" ItnContent="${ItnContent:-$OldLine}" OldLine="$Line" done<"$ITN" 2>/dev/null case "$OldLine" in 0\|0\|*) ItnContent="${ItnContent:+$ItnContent\\n$OldLine}" ItnContent="${ItnContent:-$OldLine}" ;; esac echo -e "$ItnContent">"$ITN" fi grep -v '^0|0|' "$ITN" >/dev/null 2>&1 # returns 1 if $ITN only includes comments test $? -ne 0 -a $Flag -gt 0 -a $Flag -lt 4 && Flag=$(($Flag-1)) # show comments in grey MasterEvent= # this is an aggregate record, not a master event # If a SUSPEND event has been removed, also the related MasterEventDate shall be deleted, by restoring the previous value. if [ "$TypePreviousEvent" = SUSPEND ] then zcp -p "$PrevMasterEventDate" "$MasterEventDate" 2>/dev/null # restore the previous master date if any DebugLog 3 -date "$MasterEventDate" "(aggregate record) SUSPEND event removed: MasterEventDate restored to \c" fi else zrm -f "$ShortIntervalPermanentDate" "$TextForNextItem" DebugLog 3 "ShortInterval exceeded: no Delta, $ShortIntervalPermanentDate removed" fi fbprint $c_black "o" # STEP B3: if AddIntervals=yes, calculate Interval (including RealInterval) DSecs=0 zstat -S DSecs '%Y' "$TripSeconds" TripFile= { read -u0 -k 65000 TripFile <"$TripSeconds"; } 2>/dev/null TripArray=(${(f)TripFile}) LastTripLine=$TripArray[${#TripArray}] LastTripLine=${LastTripLine##[!0-9]*};LastTripLine=${LastTripLine%%[!0-9]*} TripTime=$((${SecondsNow:-0}-${DSecs:-0}+${LastTripLine:-0})) test $TripTime -lt 0 && TripTime=0 TripHours=$(((${TripTime:-0}+$Rounding)/3600)) TripMinutes=$(((${TripTime:-0}-${TripHours:-0}*3600+$Rounding)/60)) LapInterval= SecondsMasterEvent=0 if test -f "$MasterEventDate" -a "$AddIntervals" = yes then SecondsMasterEvent=0 zstat -S SecondsMasterEvent '%Y' "$MasterEventDate" days=$(((${SecondsNow:-0}-${SecondsMasterEvent:-0}+$Rounding)/86400)) test $days = -1 && days=0 hours=$(((${SecondsNow:-0}-${SecondsMasterEvent:-0}-$days*86400+$Rounding)/3600)) test $hours = -1 && hours=0 minutes=$(((${SecondsNow:-0}-${SecondsMasterEvent:-0}-$days*86400-$hours*3600+$Rounding)/60)) test $minutes = -1 && minutes=0 #minutesNotRounded=$((($SecondsNow-$SecondsMasterEvent-$days*86400-$hours*3600)/60)) #secs=$(($SecondsNow-$SecondsMasterEvent-$days*86400-$hours*3600-$minutesA*60)) case "$days" in 0) ;; -*|$ResetString) LapInterval="$ResetString" echo "$1" > "$MasterEventDate" ;; *) test "$minutes" -ge 0 -a "$minutes" -lt 10 && minutes="0$minutes" LapInterval="${days}${DaySeparatorSymbol}${hours}:${minutes}" ;; esac case "${hours}${LapInterval}" in -*|$ResetString) LapInterval="$ResetString" echo "$1" > "$MasterEventDate" ;; 0) ;; [0-9]|[0-9][0-9]) test "$minutes" -ge 0 -a "$minutes" -lt 10 && minutes="0$minutes" LapInterval="$hours:$minutes" ;; esac case "${minutes}${LapInterval}" in -*|$ResetString) LapInterval="$ResetString" echo "$1" > "$MasterEventDate" ;; 0) ;; [0-9]|[0-9][0-9]) LapInterval="$minutes'";; esac fi fbprint $c_black "p" # A non (or not yet) aggregated RESUME following a SUSPEND sets the LapInterval symbol to stop and updates PrevMasterEventDate and MasterEventDate if [ "$MasterEvent" -a "$TypePreviousEvent" = "SUSPEND" -a "$1" = "RESUME" ] then zcp -p "$LastGpsDate" "$MasterEventDate" 2>/dev/null || echo "$1" > "$MasterEventDate" zcp -p "$MasterEventDate" "$PrevMasterEventDate" DebugLog 3 -date "$MasterEventDate" "NEW TRIP; new MasterEventDate=\c" DebugLog 3 -date "$PrevMasterEventDate" "NEW TRIP; new PrevMasterEventDate=\c" DefaultInterval="1'" echo "${LapInterval:-$DefaultInterval}" > "$TextForNextItem" test "$AddIntervals" = yes && LapInterval=" ${IntOS}${LapInterval:-$DefaultInterval}${IntCS}" zcp -p "$LastGpsDate" "$TripSeconds" test "$NewGpxWhenNewTravel" = yes && GpxEnveloper 0 else RealInterval= if [ ${TripHours:-0} -gt 0 ] then test "$TripMinutes" -ge 0 -a "$TripMinutes" -lt 10 && TripMinutes="0$TripMinutes" RealInterval="${TripHours}:${TripMinutes}" else RealInterval="${TripMinutes}'" fi test "$RealInterval" = "$LapInterval" && RealInterval= IntO="${IntOR}" IntC="${IntCR}" { read PrevInterval <"$TextForNextItem"; } 2>/dev/null && LapInterval="$PrevInterval" IntO="${IntOS}" IntC="${IntCS}" test "$AddIntervals" = yes && if [ $TripTime -gt 30 -a "$RealInterval" ] then LapInterval=" ${IntO}$LapInterval,$RealInterval${IntC}" else test "$LapInterval" && LapInterval=" ${IntO}$LapInterval${IntC}" fi fi # All SUSPEND events will update MasterEventDate (but not PrevMasterEventDate) if [ "$1" = "SUSPEND" ] then zcp -p "$LastGpsDate" "$MasterEventDate" 2>/dev/null || echo "$1" > "$MasterEventDate" DebugLog 3 -date "$MasterEventDate" "SUSPEND event: New MasterEventDate=\c" # Now MasterEventDate (e.g., PrevMasterEventDate of the next event) also includes the SUSPEND event echo "$TripTime" >> "$TripSeconds" DebugLog 3 -cat "$TripSeconds" "TripSeconds=" fi case "$1" in RESUME|SUSPEND|BOOT);;*)LapInterval="$LogSymbol$LapInterval";;esac # set LapInterval only for LOG type events fbprint $c_black "q" # STEP B4: create the final records GpxFix='3d' SdkRetCode= SdkGCPUpdate= SdkGCPLongitude= SdkGCPLatitude= SdkGCPSpeed= SdkGCPDirection= SdkGCPOther= if test \( ! "$Longitude" -o ! "$Latitude" -o ! "$Speed" \) -a -s "/var/run/TomTomNavigationServer.SDK.$ProcessId.1.finished" -a "$DoSdkPosition" then # Fetch data from the SDK response GpxDate= zstat -S GpxSecs '%Y' "/var/run/TomTomNavigationServer.SDK.$ProcessId.1.message" && zdate -S GpxDate "%Y-%m-%dT%H:%M:%S" "1970/1/1 0:0:0 $TMZ $GpxSecs seconds" { IFS='|' read SdkRetCode SdkGCPUpdate SdkGCPLongitude SdkGCPLatitude SdkGCPSpeed SdkGCPDirection SdkGCPOther <"/var/run/TomTomNavigationServer.SDK.$ProcessId.1.message"; } >/dev/null 2>&1 DebugLog 3 "SdkRetCode=$SdkRetCode SdkGCPUpdate=$SdkGCPUpdate SdkGCPLongitude=$SdkGCPLongitude SdkGCPLatitude=$SdkGCPLatitude SdkGCPSpeed=$SdkGCPSpeed SdkGCPDirection=$SdkGCPDirection SdkGCPOther=$SdkGCPOther" if test "$SdkRetCode" -ge 0 -a "$SdkGCPLongitude" -a "$SdkGCPLatitude" 2>/dev/null then Longitude="$SdkGCPLongitude" Latitude="$SdkGCPLatitude" #Speed="$SdkGCPSpeed${SdkGCPSpeed:+.0}" Speed="$SdkGCPSpeed" GpxFix='2d' fi fi fbprint $c_orange " Geodecode: " GeoDecode= SdkRGRetCode= SdkRGLongitude= SdkRGLatitude= SdkRGType= SdkRGStreet= SdkRGHouseNumber1= SdkRGHouseNumber2= SdkRGCity= SdkRGOther= # amacri 11-26-05: the following line has been tuned for TTGO version 5.420, a bit slowler than the previous ones let LoopCount=0 Space= test "$DoSdkGeodecode" && for SleepTime in 0.5 ${=AdditionalLoops} -1 # Tune here the time needed to catch the .3. API response (GetLocationInfoEx) # args indicate the delay between loops. 0 means no delay; -1 must always be the last one do if GetGeodecode "$ProcessId.3" then Space=' -' test "$Longitude" || Longitude="$SdkRGLongitude" SdkRetCode=0 SdkGCPUpdate=0 test "$Latitude" || Latitude="$SdkRGLatitude" SdkRetCode=0 SdkGCPUpdate=0 break fi fbprint $c_black $(($SleepTime)) LoopCount=$((LoopCount+1)); fbprint $c_cyan $(($LoopCount)) # let LoopCount+=1; fbprint $c_cyan $(($LoopCount)) case $SleepTime in *[1-9])sleep $SleepTime;;esac done fbprint $c_black "s" # STEP B5: prepare data # Generate null positioning fields if the retrieved data are invalid. ManageAltitude test "$Longitude" || Longitude="0" Latitude="0" GpxFix='none' test "$Latitude" || Longitude="0" Latitude="0" GpxFix='none' GpxCourse= if test "$SdkGCPDirection" then GpxCourse="${SdkGCPDirection}.0" else test "$Course" && GpxCourse="${Course}" fi GpxSpeed= if test "$Speed" then # Convert km/h to m/sec SpeedMs= # Define a string variable in orther to enable the 6-decimals math calculator let SpeedMs=$Speed/3.6 GpxSpeed="${SpeedMs%????}" if [ "$Speed" -le 1 ] then Speed= # Log speed only if > 1 else if test "$kmhToMilesh" = yes then scalar Ms # string variable let Ms=$Speed/1.609+0.005 Speed="${Ms%?????}" fi Speed=" ${Speed}${SpeedUnit}" fi fi if test "$SdkRetCode" -ge 0 -a "$SdkGCPUpdate" = 0 # if no error and EGpsStatus=KGpsStatusGeneral then Delta="${OutdatedRecordSymbol}${Delta}" GpxFix='none' fi # both Latitude and Longitude must be valid signed integers. Latitude==0 & Longitude==0 represent no coords available test \( "$Longitude" -gt 0 -o "$Longitude" -le 0 \) -a \( "$Latitude" -gt 0 -o "$Latitude" -le 0 \) 2>/dev/null || Longitude="0" Latitude="0" GpxFix='none' RecordOk="$Longitude|$Latitude|_REPLACE_${Altitude}${Speed}${GeoDecode}" scalar LatitudeU scalar LongitudeU let LatitudeU=$Latitude/100000 let LongitudeU=$Longitude/100000 test $LatitudeU[-1] = 0 && LatitudeU=$LatitudeU[1,-2] # remove the last decimal digit in case it is 0 test $LongitudeU[-1] = 0 && LongitudeU=$LongitudeU[1,-2] # remove the last decimal digit in case it is 0 fbprint $c_black "t" # STEP B6: save the final records to the SD card FlashMsg="${LapInterval}${Delta}${Altitude}${Speed}${GeoDecode}" if [ "$Longitude" -ne 0 -a "$Latitude" -ne 0 ] then echo "$RecordOk" >"$ITNOK" echo "$Longitude|$Latitude|${CurrentDate}${FlashMsg}|$Flag|" >>"$ITN" WptTrkPoi "$1"\ "$Longitude|$Latitude|${CurrentDate}${FlashMsg}|"\ 'lat="'"${LatitudeU}"'" lon="'"${LongitudeU}"'">'"${EleGpx}"'' \ "$GpxCourse$GpxSpeed$GpxGeoidSep$GpxFix$GpxSat" \ ''"${CurrentDate}:${SecondsNow#????????}"''"${Delta}${GeoDecode}${LapInterval}"'' else # Both Latitude and Longitude are set to 0 (meaning no coords available) if { read ItnOk < "$ITNOK"; } 2>/dev/null then FlashMsg="${PreviousRecordSymbol}${LapInterval}${Delta}${ItnOk#*_REPLACE_}" echo "${ItnOk%_REPLACE_*}${CurrentDate}${FlashMsg}|$Flag|" >>"$ITN" else FlashMsg="${LapInterval}${Delta} ${NoInfo}" echo "$Longitude|$Latitude|${CurrentDate}${FlashMsg}|$Flag|" >>"$ITN" fi fi DebugLog 3 -exec 'tail -2 "$ITN"' "last two stored records are:\n" if [ "$DoItnArchive" = yes -a \( "$1" = "BOOT" -o "$1" = "RESUME" \) ] then MakeOldItnArchive $1 test $? -ne 0 && DebugLog 1 "archiving failed" fi DebugLog 3 || zrm -f "/var/run/TomTomNavigationServer.SDK.$ProcessId."*(N.) if test ! "$1" = "SUSPEND" -a "${Delta}${Altitude}${Speed}${LapInterval}" -a "$DoSdkShowMessage" then echo -e "FlashMessageV01|${FlashMsg}${FMTrailer}|${FlashMessageDuration}000|\0\c" > "/var/run/SDK.TomTomNavigationServer.$ProcessId.2.message" echo finish > "/var/run/SDK.TomTomNavigationServer.$ProcessId.2.finished" fi DebugLog 5 && { for i in /var/run/TomTomNavigationServer.*(N.) do DebugLog 3 "SDK Dump:" echo "<<>>" for i in /var/run/TomTomNavigationServer.* do echo "<<<$i>>>" echo Cat <"$i" echo done echo "<<>>" done 2>/dev/null # no traces } fbprint $c_blue "u" FB_X=2 FB_Y=225 fbprint $c_red "Press the touchscreen to continue..." } # of GpsLogger AstronomicalCalendar() { SdkGCPLatitude= SdkGCPLongitude= export ProcessId=$$ GetLocation if test "${SdkGCPLongitude}" -eq 0 -a "${SdkGCPLatitude}" -eq 0 then y_start=190 fb_rect 0 $y_start $((FB_MaxX-1)) $((FB_MaxY-1)) $c_white fb_rect 0 $y_start $((FB_MaxX-1)) $((y_start+1)) $c_darkblue fb_printxy 2 $((y_start+8)) $c_black "$NAME Version $VERSION - [$Event]: " FB_BOLD=1 fb_print "no GPS data" if test "$Debug" -gt 3 then FB_NUMINK=$c_red fb_print ".${LF}${LF}$LDate - ${SdkGCPLatitude} - ${SdkGCPLongitude}" else fb_print ".${LF}${LF}$LDate" fi ts_press 5 TsPressTimeout=0 return fi scalar LatitudeU scalar LongitudeU let LatitudeU=$SdkGCPLatitude/100000 let LongitudeU=$SdkGCPLongitude/100000 test $LatitudeU[-1] = 0 && LatitudeU=$LatitudeU[1,-2] # remove the last decimal digit in case it is 0 test $LongitudeU[-1] = 0 && LongitudeU=$LongitudeU[1,-2] # remove the last decimal digit in case it is 0 TsPressTimeout=0 i=0 while test $i -le 60 do "$MAINDIR/acal" -a -m $(($HSECONDS+($TzShift))) "${LatitudeU}" "${LongitudeU}" $((TzSecs-($TzShift))) if suna $(($HSECONDS+($TzShift))) "${LatitudeU}" "${LongitudeU}" -0.833 $((TzSecs-($TzShift))) # is now night-time? then if suna $(($HSECONDS+($TzShift))) "${LatitudeU}" "${LongitudeU}" -6 $((TzSecs-($TzShift))) # is now night-time? then Period="[Nighttime]" else Period="[Twilight]" fi else Period="[Daytime]" fi fb_printxy 2 227 $c_black "$Period" FB_COL=$c_blue FB_NUMINK=$c_red fb_print " La=${LatitudeU} Lo=${LongitudeU} " FB_COL=$c_darkblue FB_BOLD=1 fb_print " Press to quit." ts_press 2 && break let i+=1 done } # of AstronomicalCalendar ManageEvents() { test \( "$Debug" -le 0 -o "$Debug" -gt 3 \) -a "$1" = "RESUME" && zrm -f "/var/run/SDK.TomTomNavigationServer."*(N.) "/var/run/TomTomNavigationServer.SDK."*(N.) export ProcessId=$$ AdditionalLoops="0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5" case "$1" in # RESUME) AdditionalLoops="$AdditionalLoops 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1";; RESUME) AdditionalLoops="$AdditionalLoops 1 1 1 1 1 1 1 1 1 1 1 1";; SUSPEND) AdditionalLoops="";; esac unsetopt BG_NICE test "$DoSdkPosition" = yes && GetLocation & DenyAggregation= SecondsPreviousEvent=0 zstat -S SecondsPreviousEvent '%Y' "$LastGpsDate" 2>/dev/null { read TypePreviousEvent <"$LastGpsDate"; } 2>/dev/null DebugLog 3 -exec 'ls -l \"$LastGpsDate\" 2>/dev/null' "SecondsPreviousEvent=$SecondsPreviousEvent\n" # start of commands updating time flags (must be in foreground to avoid being suspended) fbprint $c_black "y" zdate -S Odate "$LongDateFormat" "now $TzSecs seconds" Ndate="$Odate" OSecondsNow=$HSECONDS if test "$1" = "BOOT" then # In case of reset, the date is set to default; in this case, # try at least to sync the date with the modification time of this script test $OSecondsNow -lt $SecondsLastMod 2>/dev/null && HSECONDS=$SecondsLastMod && DebugLog 1 "date changed following $OEXEC modification time" else test "$ReadNMEA" = yes && GetGpsData $* fi case "$1" in RESUME|SUSPEND|BOOT)echo "$1">"$LastGpsDate";;esac test "$1" = "RESUME" && touch "$TripSeconds" zdate -S CurrentDate "$DateFormat" "now $TzSecs seconds" zdate -S GpxDate "%Y-%m-%dT%H:%M:%S" "now $TzShift seconds" SecondsNow=$HSECONDS # end of commands updating time flags fbprint $c_black "z" case "$1" in SUSPEND) GpsLogger $* GpxEnveloper 1 ;; # Fast suspend and fast boot are not so important (while a supend is running, TTGO can be actually considered switched off) BOOT) GpsLogger $*;; # next case option involves RESUME and LOG events *) unsetopt BG_NICE GpsLogger $* & #test $? -eq 0 -a $! -gt 1 && renice 3 $! # Tune here the improvement to the priority of the GpsLogger function when processed in background # Notice that the background part will not produce any date mark (so that it can be possibly suspended and resumed after some time) FB_X=2 FB_Y=$((y_start+5+16+FB_FontY*9)) fbprint $c_orange "Returned to main: " ;; esac fbprint $c_blue "+" } # of ManageEvents ## MAIN ######################################################################## chr -S CR 13 # Ascii 13=0x0D=0015 chr -S LF 10 # Ascii 10=0x0A=0012 colour 255 0 0;c_red=$? # red colour 0 255 0;c_green=$? # green colour 0 0 255;c_blue=$? # blue colour 255 255 255;c_white=$? # white colour 0 0 0;c_black=$? # black colour 255 255 0;c_yellow=$? # yellow colour 255 0 255;c_purple=$? # purple colour 0 255 255;c_cyan=$? # cyan colour 255 128 0;c_orange=$? # orange colour 255 255 128;c_wyellow=$? # light yellow colour 0 0 128;c_darkblue=$? # dark blue fb_dump FB_MaxX=$FB_SCRDATA[8] # 320 FB_MaxY=$FB_SCRDATA[9] # 240 FB_FontX=$FB_SCRDATA[10] # 6 FB_FontY=$FB_SCRDATA[11] # 11 Event=BOOTSTRAP # for DebugLog Application=Default # for DebugLog if test ! "$1" = GpsLogger -a $# -gt 0 then eval $* # test a specific command or function exit fi test $# -eq 0 -a $0 = /bin/Event_Logger && set -- GpsLogger LOG 1 test $# -eq 0 -a $0 = /bin/addpoi && set -- GpsLogger POI 1 test $# -eq 0 -a $0 = /bin/ACal && set -- GpsLogger ACAL 1 ## Falls here when $1=GpsLogger $2=Event $3=PPID Event=$2 # for DebugLog Application=$1 # for DebugLog shift y_start=203 test "$Debug" -ge 3 && y_start=89 if test \( "$Debug" -gt 0 -o \( ! "$1" = "BOOT" -a ! "$1" = "SUSPEND" -a ! "$1" = "RESUME" \) -o "$DoSplashTxt" = always \) -a ! "$DoSplashTxt" = never then fb_rect 0 $y_start $((FB_MaxX-1)) $((FB_MaxY-1)) $c_white fb_rect 0 $y_start $((FB_MaxX-1)) $((y_start+1)) $c_darkblue fb_printxy 2 $((y_start+8)) $c_black "Running $NAME Version $VERSION - [$Event]" # >/dev/null 2>&1 ConvertDate "$Today %H:%M:%S" "now $TzSecs seconds" 2>/dev/null # no traces fb_printxy 2 $((y_start+8+1+FB_FontY)) $c_black "$LDate (UTC$TIMEZONE)" fi FB_X=2 FB_Y=$((y_start+5+16+FB_FontY)) fbprint $c_orange "Main: " fbprint $c_blue "v" if test "$1" = "BOOT" then test -f "$WptCounter" -a "$AddGpxCounter" = yes && echo "0" > "$WptCounter" zdate -S FDate "$OldLogFileFormat.%S" "now $TzSecs seconds" zmv "$LogfileSD" "$MAINDIR/ttnlog-$FDate.txt" 2>/dev/null # Rotate old logs (needed for log option A) test "$Debug" -ge 1 && exec 1>>"$LOGFILE" 2>&1 test "$DoSdkTracking" -a "$DoSdkPosition" && $EXEC "trkptDaemon;exit" #PsTop & fi BgPid= TsPressTimeout=20 test "$1" = "SUSPEND" -o "$1" = "BOOT" -o "$1" = "RESUME" && TsPressTimeout=2 fbprint $c_black "w" # Mount the SD card if test -f "$MountLog" then zstat -S SecsMountLog '%Y' "$MountLog" zdate -S DateMountLog "$OldLogFileFormat.%S" "$TheEpoch $((SecsMountLog+TzSecs)) seconds" echo "0|0|Last mount failed: $DateMountLog|1|" >>"$ITN" DebugLog 2 "Last mount failed: $DateMountLog:" DebugLog 2 -cat "$MountLog" "MountLog:" zrm -f "$MountLog" fi MountSd= # Mounting the SD card is needed for SUSPEND events, while already done for the other event types. #DEBUG!! # test ! -f ${OEXEC} -a -f "$RealTtn" && if mount -n -t vfat -orw,sync,noatime,nodiratime,nosuid,nodev /dev/sdcard0 "$LoggerRootDir" >"$MountLog" 2>&1 test ! -f ${OEXEC} -a -f "$RealTtn" && if mount -n -t vfat -orw,noatime,nodiratime,nosuid,nodev /dev/sdcard0 "$LoggerRootDir" >"$MountLog" 2>&1 then MountSd=yes zrm -f "$MountLog" else test ! "$DoSplashTxt" = never && ts_press $TsPressTimeout fb_done exit 1 fi let LoopCount=0 for i in 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 -1 # locks the SD (check until the SD is available). Tune here the lock timeout # args indicate the delay between loops. 0 means no delay; -1 must always be the last one do exec 6<"$MAINDIR" && break fbprint $c_black $(($i)) let LoopCount+=1; fbprint $c_cyan $(($LoopCount)) case $i in *[1-9])sleep $i;;esac done fbprint $c_black "x" if test "$Debug" -ge 1 then exec 1>>"$LOGFILE" 2>&1 echo -e "\nStarted $NAME Version $VERSION.$ExecSize $ExecDate($DATE) $AUTHOR - BSH Version: $ZSH_VERSION" echo -e "Trace Level $Debug, EVENT $Event, Program=$0, Args=$*, \c" && zdate "%c" "now $TzSecs seconds" # echo -e "\n hw_cputype=$hw_cputype, hw_harddisk=$hw_harddisk, hw_lowbutton=$hw_lowbutton, hw_modelid=$hw_modelid, hw_modelname=$hw_modelname\n hw_sdcard=$hw_sdcard, hw_tfttype=$hw_tfttype, hw_tsfets=$hw_tsfets" fi #test "$Debug" -ge 5 && set #for i in $signals # do # test $i = ZERR && continue # test $i = DEBUG && continue # trap "echo \"RECEIVED SIGNAL $i\"" $i #done # TEST signal handling DebugLog 3 -exec 'ls -la /proc/$$/fd/*(N)' "LS-FD:\n" DebugLog 3 -exec set "SET:\n" test "$Debug" -ge 4 && echo -e "\nEXTENDED TRACE - $1 EVENT - \c" && zdate "%c" "now $TzSecs seconds" && echo && set -x # Start of the actual process case "$1" in ACAL) AstronomicalCalendar $*;; *) ManageEvents $*;; esac DebugLog 3 "ended" # End of the actual process test "$Debug" -ge 4 && fb_dump -v test "$BgPid" && wait $BgPid 2>/dev/null # Note: unfinished processes will go on after resuming, so just notify them. Tune here (second arg) the wait time in seconds if test "$1" = "SUSPEND" -a "$3" && ! WaitForBackgroundPids $1 10 $3 && test "$Debug" -ge 1 then echo -e "some background process still running:\n$Cmd" echo "0|0|Process still running!|1|" >>"$ITN" echo > "$ShortIntervalSkipFlag" # This is because now TTN lasts with a comment fi DebugLog 3 MountSd=$MountSd test -f "$LOGFILE" && zcp "$LOGFILE" "$LogfileSD" # Log option A #test -f "$LOGFILE" && zcp "$LOGFILE" "$MAINDIR/TtnLog-$1-`date \"$OldLogFileFormat\"`.txt" # Log option B fbprint $c_black "[" #sync fbprint $c_black "?" exec 6<&- # Free the SD lock exec 1>/dev/null 2>&1 #sync fbprint $c_black "*" let LoopCount=0 if test "$MountSd" = yes then for i in 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 -1 do fbprint $c_black "." umount "$LoggerRootDir" && break fbprint $c_black $(($i)) let LoopCount+=1; fbprint $c_cyan $(($LoopCount)) case $i in *[1-9])sleep $i;;esac done fi fbprint $c_blue "]" test ! "$DoSplashTxt" = never -a "$Debug" -ge 3 -a $TsPressTimeout -gt 0 && ts_press $TsPressTimeout fb_done exit 0