Διαχείριση ιστορικού γεωγραφικής τοποθεσίας

traccar

Open source διαχείριση ιστορικού τοποθεσίας από κινητές συσκευές (κυρίως) aka Traccar

Το traccar ένας server αποθήκευσης, διαχείρισης και εμφάνισης στο χάρτη του Ιστορικού τοποθεσίας κινητών συσκευών και GPS trackers

Το κίνητρο μου ηταν η αντικατάσταση της λειτουργίας απο τους χάρτες google με μια selfhosted open source υπηρεσία

Ανώτερη υπηρεσία απο αρκετές απόψεις σε σύγκριση με την ίσως πιο δημοφιλή λύση του owntracks .
Δεν εχει battery drain και εχει και πιο πλούσιο ui

Το παρόν είναι αναδιατύπωση του μπλογκ ποστ μου εδώ

και διάφορων channel ποστ μου εδώ

Dockerfile for raspberrypi aarch

Η ακόλουθη διαδικασία με το custom Dockerfile δεν απαιτείται στο raspberry
Δοκίμασα το debian atm64 image στο raspberry400
Digest:sha256:f09791c90dbfe9ea5adeb5c5c1f657cfdb1eccaf56bda2194f2a84abfb4b6412
και λειτουργεί κανονικοτατα
Υπάρχουν αρκετές επίσημες εκδόσεις για όλες τις αρχιτεκτονικές στο dockerhub
Αν όμως για κάποιο λόγω δε σου δουλεύουν

nano Dockerfile

paste

FROM debian:latest

ENV TRACCAR_VERSION 4.10

WORKDIR /opt/traccar

RUN set -ex && \
    apt-get update &&\
    TERM=xterm DEBIAN_FRONTEND=noninteractive apt-get install --yes --no-install-recommends unzip wget default-jre && \
    wget -qO /tmp/traccar.zip https://github.com/traccar/traccar/releases/download/v$TRACCAR_VERSION/traccar-other-$TRACCAR_VERSION.zip && \
    unzip -qo /tmp/traccar.zip -d /opt/traccar && \
    apt-get autoremove --yes unzip wget && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* /tmp/*

ENTRYPOINT ["java", "-Xms512m", "-Xmx512m", "-Djava.net.preferIPv4Stack=true"]

CMD ["-jar", "tracker-server.jar", "conf/traccar.xml"]

Κάνουμε build το Dockerfile

docker build -t debian-traccar-nginx .

Δημιουργούμε το volume

docker volume create traccar_raspberry

Τρέχουμε το container

Ο android client στέλνει στην tcp 5055 port οπότε αν δε σκοπεύεις να χρησιμοποιήσεις κάποιο συμβατό hardware gps tracker (η λίστα είναι μεγάλη) οι άλλες θύρες δεν απαιτούνται
Χρειαζόμαστε μόνο την 5055 για τα events και την 8082 για να έχουμε Απομακρυσμένη πρόσβαση στο webui

docker run -d \
  --name Traccar \
  -p 5002:5002/tcp \
  -p 5002:5002/udp \
  -p 5055:5055/tcp \
  -p 5093:5093/tcp \
  -p 5093:5093/udp \
  -p 82:8082 \
  --mount source=traccar_raspberry,target=/opt/traccar \
  --restart=unless-stopped \
  debian-traccar-nginx:latest

docker-compose file

Αν υποθέσουμε οτι έχουμε εναν εξωτερικό σκληρό δίσκο mounted στο /run/media/ippo/TOSHIBA και το username μας είναι ippo

δημιουργούμε ενα default trackar.xml configuration file απο το image που κάναμε build

docker run --rm --entrypoint cat debian-traccar-nginx:latest /opt/traccar/conf/traccar.xml > /run/media/ippo/TOSHIBA/traccar/conf/traccar.xml

the actual yml

version: '2'
services:
    web:
        image: 'debian-traccar-nginx:latest'
        restart: unless-stopped
        hostname: 'my.ddns.provider.com'
        container_name: traccar
        ports:
            - '8082:8082'
            - '5055:5055/tcp'
        volumes:
            - '/etc/localtime:/etc/localtime:ro'
            - '/run/media/ippo/TOSHIBA/traccar/logs:/opt/traccar/logs:rw'
            - '/run/media/ippo/TOSHIBA/traccar/conf/traccar.xml:/opt/traccar/conf/traccar.xml:ro'
            - '/run/media/ippo/TOSHIBA/traccar/data:/opt/traccar/data:rw'

run the container

doker-cmpose up -d

Τα παραπάνω docker run ή docker-compose θα δημιουργήσουν τον traccar server με την default embended H2 database την οποία την έχουμε κάνει mount στο host οπότε θα επιβιώσει στα container restarts
Το συγκεκριμένο setup είναι οκ για δοκιμές όχι όμως για long run μιας και η h2 database δεν ειναι φιλική στα backup και στην περίπτωση που γίνει corrupt δεν υπάρχει τρόπος να την επαναφέρουμε
Δοκίμασα να αντιγράψω την h2 και να δοκιμάσω αν τρέχει με το αντίγραφο
δυστυχώς δεν

Ο προτεινόμενος τρόπος είναι η χρήση MySQL η postgres

Την postgres δεν έχω καταφέρει να την λειτουργήσω με το traccar
Παρόλο που τα container ξεκινάν κανονικά το traccar εξακολουθεί να χρησιμοποιεί μια h2 database μέσα στο container ενω στο mounted folder (αν επιλέξω να κάνω mount το var/lib/postgresql/data στο host) δεν εμφανίζει τίποτα

traccar mysql

version: "3"
services:
    traccar-db:
        image: yobasystems/alpine-mariadb
        container_name: traccar-db
        command: --default-authentication-plugin=mysql_native_password
        restart: always
        volumes:
            - /run/media/ippo/TOSHIBA/traccar/mysql-data:/var/lib/mysql
            - /run/media/ippo/TOSHIBA/traccar/mysql:/etc/mysql/conf.d
        ports:
            - "3306:3306"
        environment:
            - MYSQL_ROOT_PASSWORD=pass
            - MYSQL_DATABASE=traccar-db
            - MYSQL_USER=user
            - MYSQL_PASSWORD=pass
        networks:
            - trc


    traccar:
        image: traccar/traccar:debian
        hostname:my.ddns.domain.com
        container_name: traccar
        depends_on:
           - traccar-db
        restart: always
        volumes:
            - /run/media/ippo/TOSHIBA/traccar/conf/traccar.xml:/opt/traccar/conf/traccar.xml:ro
            - /run/media/ippo/TOSHIBA/traccar/logs:/opt/traccar/logs:rw
        ports:
            - "5055:5055"
            - "82:8082"
         networks:
            - trc
networks:
  trc:
    driver: bridge
    enable_ipv6: false
    ipam:
      config:
        - subnet: 192.168.112.0/20

Το image είναι της yobasystems λόγο μεγέθους αλλά και λόγω του οτι δεν διαμαρτύρεται στα rebuild για innodb generic errors οταν τα mounted dirs δεν ειναι άδεια όπως το official mariadb image

Έχουμε ορίσει το default native password ως authentication plug in για καλύτερη συμβατότητα με παλιούς driver

Πιθανόν να μην απαιτείται μιας και είναι το default author plugin της mariadb

Restart πολιτική μπορείς να βάλεις κ unless-stop πάντως χρειάζεται μια πολίτικη επανεκκίνησης του container

Κάναμε mount τα /var/lib/mysql και /etc/mysql/conf.d στο host

Port κρατήσαμε την 3306 (υποτίθεται για να μπορούμε να επιλέξουμε lan ip στο url της database αλλά δε μου δούλεψε με αυτόν τον τρόπο)

Στο enviroment της db ορίσαμε root password, database, user & user password

Ορίσαμε ένα network και το ονομάσαμε

Traccar χρησιμοποιήσαμε το Debian image το οποίο είναι απροβλημάτιστο στο raspberry

Ονομάζαμε το container

Ορίσαμε το hostname απο το οποίο θα έχουμε πρόσβαση στο ui και θα στέλνουμε τα location updates

Κάναμε mount το opt/traccar/conf/traccar.xml και τα logs στο host

Και ορίσαμε της port στον host γη ία την 5055 και 8082

Στο network section ορίσαμε τον τύπο του network ως bridge και το subnet του

Το συγκεκριμένο το βρίσκουμε κάνοντας inspect το network μαζί με την ipv4 address που θα βάλουμε στο config του traccar

network inspect

docker.network ls

docker network inspect 'network_name

Στο section του “Name”: “network_name”,χρειαζόμαστε το
“Subnet”: “192.168.112.0/20”

Ενω στο section του “db_name”,
Χρειαζόμαστε το “IPv4Address”: “192.168.112.2/20”,

Το subnet το εισάγουμε στο

config:
        - subnet: 192.168.112.0/20

στο docker-compose

Και το IPv4 Address το εισάγουμε στο jdbc:mysql://192.168.112.2:3306/traccar-db στο
/opt/traccar/conf/traccar.xml:ro (/run/media/ippo/TOSHIBA/traccar/conf/traccar.xml στο παραδειγμα)

Το template για mariadb database στο config του traccar ειναι

<entry key='database.driver'>com.mysql.cj.jdbc.Driver</entry>
<entry key='database.url'>jdbc:mysql://[HOST]:3306/[DATABASE]?serverTimezone=UTC&amp;allowPublicKeyRetrieval=true&amp;useSSL=false&amp;allowMultiQueries=true&amp;autoReconnect=true&amp;useUnicode=yes&amp;characterEncoding=UTF-8&amp;sessionVariables=sql_mode=''</entry>
<entry key='database.user'>[USER]</entry>
<entry key='database.password'>[PASSWORD]</entry>

Αντικαθιστούμε τα αντίστοιχα entry keys για h2 db

Πέραν των entry keys για την mysql αλλα και του notification που θα δουμε πιο κατω το travcar config δέχεται παρα πολλές παραμετρους
Configuration File - Traccar

Δημιουργία της database και του charset καθώς και του priviledget user

Αν και το docker-compose θα έπρεπε να δημιουργεί το χρήστη και την dB χρειάστηκε να το κάνω χειροκίνητα

Ανοίγουμε ενα root mysql shell

docker exec -it traccar-db mysql -u root -p

Εισάγουμε το root passowrd απο το docker-compose password (pass στο παράδειγμα)

Δημιουργούμε την db

CREATE DATABASE IF NOT EXISTS traccar-db

enter

Αν το username μας ειναι user, το password ειναι pass και το ονομα της dB ειναι traccar-db

grant all privileges on traccar-db.* TO user'@'% identified by pass

enter

flush privileges

enter

ALTER DATABASE traccar CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci

enter

\q

enter

docker-compose up -d

Caddyfile

Αν χρησιμοποιείς caddy για reverse proxy και ssl θα κανεις reverse το dynamic dns domain σου στη localhost στη θύρα που ακούει το webui

nano /etc/caddy/Caddyfile

#traccar
a.random.ddns.name.duckdns.org {
    reverse_proxy localhost:82
}

Δημιουργία admin και απενεργοποίηση νέων χρηστών

Αρχικά θα πρέπει να κάνουμε register σαν normal user.

Από την login page λοιπόν κάνουν register με email και password

έπειτα μπορείς να κάνεις login με τα συγκεκριμένα στοιχειά

Συνδεόμαστε ως τον default admin

Username =admin
Password = admin

Στην top left corner

Settings

Users

Επιλέγουμε τον Users που δημιουργήσαμε

Πατάμε το μολύβι

Από το permissions tab ενεργοποιούμε το admin για τον συγκεκριμένο χρήστη

Από τα settings

Server

Στο permissions tab απενεργοποιούμε το registration

Log out και re-login με τον created user

Από settings

Users

Μπορούμε να αφαιρέσουμε τον default admin τώρα
Αφού ο χρήστης που δημιουργήσαμε είναι πλέον admin

backup and restore traccar mysql

Ένα βασικό πλεονέκτημα του να έχουμε μια external database ειναι να μπορούμε να πάρουμε περιοδικα backup της και να επαναφέρουμε το traccar σε πρότερη κατάσταση

docker-compose -f  compose-file.yml exec dbname mysqldump -uroot -pYOUR_MARIADB_ROOT_PASSWORD --all-databases > dump-$(date +%F_%H-%M-%S).sql

restore

docker-compose -f compose-file.yml exec -T dbname mysql -uroot -pYOUR_MARIADB_ROOT_PASSWORD < mariadb-dump.sql

-f = αν δεν έχουμε κανει cd στο φάκελο τον οποίο βρίσκεται ή/και δεν έχουμε ονομάσει το compose αρχείο docker-compose.yml, με αυτή την παράμετρο ορίζουμε το filepath του αρχείου compose

dbname = το όνομα της database

mysqldump = υπάρχουν αρκετοί τρόποι να πάρεις backup των mariadb/mysql databases το mysqldump είναι ένα εργαλείο με το οποίο παράγει ένα set από SQL statements με το οποίο μπορούμε να αναδημιουργήσουμε τα database objects

Δε ξέρω αν είναι ο ιδανικός τρόπος πάντως τον έλγξα και όχι άπλα επαναφέρει μια διαγραμμένη corrupted db αλλά κάνει και πλήρη επαναφορά του traccar σε initial setup όταν είχα διαγράψει εντελώς τα αρχεία της db αλλά και τα volume του traccar και της db

-uroot =όπως είναι. Χρησιμοποιούμε τον root χρήστη της mariadb

-pYOUR_MARIADB_ROOT_PASSWORD = γράφουμε -p και κολλητά μια λέξη το root password όπως το έχουμε ορίσει στο compose file

–all-databases = self explained θα μπορούσαμε να μπλέξουμε με συγκεκριμένες db κτλ

-T = αυτό το flag μας εξασφαλίζει οτι δεν θα έχουμε interactive shell και tty error κατά την εκτέλεση της εντολής

dump-$(date +%F_%H-%M-%S).sql = δημιουργεί ενα .SQL αρχείο με την ήμερο.ηνία στο όνομα του αρχείου στο path που θέλουμε

mariadb-dump.sql = το filepath στο αρχείο sql που κάναμε backup

Το restore παίρνει αρκετό χρόνο, περιμένουμε να ολοκληρωθεί

περιοδικά backup

Δημιουργούμε ενα script

nano traccar-db.sh

docker  exec traccar-db mysqldump -uroot -proot_pass --all-databases > /run/media/ippo/TOSHIBA/traccar/db-backup/dump-$(date +%F_%H-%M-%S).sql

Το κάνουμε εκτελέσιμο

chmod +x traccar-db.sh

Τρχουμε το script απο το crontab

crontab -e

@daily bash /home/user/traccar-db.sh

Traccar notifications

Υπάρχουν αρκετοί τρόποι να ενεργοποιήσουμε τις ειδοποίησης

Εδώ θα δούμε το telegram ως μέσο.

Υπάρχουν πολλά είδη ειδοποιήσεων

enter / leave geofence
Device moving
Device stoped
Device online
Device offline

Όλα χρήσιμα αν κάνουμε monitor μια δεύτερη συσκευή πχ το τηλεφώνου του παιδιού
Η έχουμε ένα hardware traccar συμβατό

Θα πρεπει να δημιουργήσουμε ένα μποτ στο telegram και να εισάγουμε τα στοιχειά του στο config του traccar

Οποτε

nano /run/media/ippo/TOSHIBA/conf/traccar.xml

<entry key='notificator.types'>web,mail,telegram</entry>
<entry key='notificator.telegram.key'>BOT_KEY</entry>
<entry key='notificator.telegram.chatId'>CHAT_ID</entry>

Χρειαζόμαστε τα telegram.key και telegram.chatid

Επισκεπτόμαστε το @botfather

/newbot

enter

Name it

get the token

To Τόκεν είναι το telegram.key

Type @get_id_bot in the conversation chat with the bot

Επισκεπτόμαστε το μποτ που δημιουργήσαμε

Γράφουμε @get_id_bot

Αυτο είναι το telegram.chatid

Restart the container

Μπορούμε να τεσταρουμε την σύνδεση απο την καρτέλα ρυθμίσεις και απο το top left menu την επιλογή ειδοποιήσεις

Plus icon

Από την επιλογή κανάλι επιλέγουμε telegram

Και μπορούμε να ενεργοποιήσουμε το test channels button

Android client app
https://www.traccar.org/client/

Στη διεύθυνση διακομιστή επιλέγουμε τo ddns domain name μας ή τον public server αν απλά τεσταρουμε την υπηρεσία

Στη συχνότητα εγώ έχω βάλει 500sec

Απενεργοποιούμε το wakelock (κλείδωμα αφύπνισης)

η επιλογή είναι για καποιου OEM που περιοριζουν τα backround services στο android . στην πράξη δεν αφήνει τον κερνελ να “μπει” σε “deep sleep” state και η υπηρεσία λειτουργεί μια χαρά χωρίς αυτό

Αντιγράφουμε το αναγνωριστικό συσκευής

Android manager app
https://www.traccar.org/manager/

Απο το tab του χάρτη επιλέγουμε το plus icon στην πάνω δεξιά γωνία για να προσθέσουμε μια συσκευή

Εισάγουμε ένα όνομα και το αναγνωριστικό συσκευής από τον client

public demo servers

Αν απλά θες να δοκιμάσεις την υπηρεσία χωρίς να ξεκινήσεις να στήνεις, υπάρχουν public servers στους οποίους μπορείς να συνδεθείς

Public servers (demo)
https://www.traccar.org/demo-server/

Οπότε από το webui επιλέγεις έναν public server ή τον android manager στην login page στη δεξιά γωνία και κάνεις registerr και login

disadvantages:
Οι public servers είναι εφήμεροι και τα δεδομένα τους θα διαγράφονται περιοδικά

deep sleep state

Μπορείς περιοδικά ελεγξεις το κινητό αν ακολουθεί φυσολογικά τα deep sleep states

adb shell dumpsys batterystats |grep -E "Time on battery"\|"Time on battery screen off"\|"Device deep doze discharge"\|"Device light doze discharge"\|"Device light idling"\|"Device full idling"

μεταφορά του ιστορικου τοποθεσίας απο τη google στο traccar

κατεβάζουμε το google maps location history takeout

https://takeout.google.com/takeout/custom/local_actions,location_history,maps,mymaps?

επιλέγουμε location history only
και json as format

εξάγουμε το takeout

υπάρχει ενα αρχειο με όνομα Records.json το οποίο περιέχει το σύνολο του ιστορικού μας . Επίσης υπάρχουν μικρότερα αρχεία χωρισμένα σε χρόνια και μήνες .
θα χρειαστούμε το αρχείο με το πλήρες ιστορικό

οι πληροφορίες που περιέχει είναι μή διαχειρήσιμες
μέροι,δραστηριότητες,επιχειρήσεις,κτλ
επίσης οι συντεταγμένες ειναι multiplied by E7

θα χρεισιμοποιήσουμε ένα python script ωστε να περιορίσουμε τα δεδομένα μονο στην ημερομηνια και το γεωγραφικό μήκος και πλάτος σε συμβατη με το traccar μορφή

κάνουμε clone το project
git clone https://github.com/Scarygami/location-history-json-converter

και

cd location-history-json-converter

εγκαθιστούμε τα requirements

pip install -r requirements.txt

τρέχουμε το script με την επιλογή csv

python location_history_json_converter.py Records.json output.csv -f csv

θα δημιουργήσει ένα Comma-separated text file withμε ενα timestamp field και τα location fields

θα πρέπει να προσθέσουμε τα deviceid , protocol and valid fileds τα οποία τα απαιτεί το traccar ωστε να αναγνωρίσει και να μπορεί να χρησιμοποιήσει τις καταχωρήσεις

sed 's/^/osmand,1,/; s/$/,1/' output.csv > curated.csv

διαγράφουμε το"1" απο την πρωτη γραμμη και μετονομάζουμε το osmand σε protocol στην πρώτη γραμμηή

οπότε οι καταχωρήσεις στο αρχείο δείχνουν κάπως έτσι

protocol,Time,Latitude,Longitude
osmand,1,2012-08-25 21:26:20,37.95954620,23.72793730,1

6 columns
osmand = protocol
1 = deviceid
time = devicetime,servertime,fixtime
lat = lat
lon =lon
1 = valid

θα περάσουμε αυτές τις τιμές απο το csv ως sql LOAD DATA LOCAL INFILE statements στια κατάλληλα field του tc_position table της traccar-db βασης

αντιγραφουμε το csv στο container

docker cp curated.csv traccar-db:/

ανοίγουμε ένα root mysql shel container της βάσης

docker exec -it traccar-db mysql -uroot -pROOT_PASSWORD

επιλέγουμε τη database

use traccar-db

load the data

LOAD DATA LOCAL INFILE 'inn.csv' INTO TABLE tc_positions FIELDS TERMINATED BY ',' (@osmand,@deviceid,@Time,@Latitude,@Longitude,@valid) set protocol=@osmand,deviceid=@deviceid,devicetime=@Time,fixtime=@Time,servertime=@Time,latitude=@Latitude,longitude=@Longitude,valid=@valid;

2 «Μου αρέσει»

προστέθηκαν οδηγίες μεταφοράς του ιστορικού τοποθεσίας από τη google στη βάση δεδομένων του traccar

2 «Μου αρέσει»