@@ -0,0 +1,33 @@
|
||||
Traccar to DaWarIch Converter
|
||||
=============================
|
||||
|
||||
|
||||
Step 1
|
||||
------
|
||||
|
||||
Use e.g. [Adminer](https://www.adminer.org/en/) to export your [Traccar](https://www.traccar.org)'s `tc_points`
|
||||
table into a **CSV** file.
|
||||
|
||||
|
||||
|
||||
Step 2
|
||||
------
|
||||
|
||||
Change line #4 in `convert.py` to the filename of the CSV file you've just exported.
|
||||
And put both into the same directory.
|
||||
|
||||
|
||||
Step 3
|
||||
------
|
||||
|
||||
Run:
|
||||
|
||||
```
|
||||
./convert.py > dawarich.sql
|
||||
```
|
||||
|
||||
|
||||
Step 4
|
||||
------
|
||||
|
||||
Import the resulting `dawarich.sql` into your [DaWarIch](https://dawarich.app) database.
|
||||
Executable
+117
@@ -0,0 +1,117 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Export traccar tc_positions table as CSV (e.g. using Adminer)
|
||||
FILE="traccar-export-example.csv"
|
||||
|
||||
|
||||
import csv
|
||||
import json
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
# traccar_id --> topic
|
||||
tcid_map = {
|
||||
1: 'owntracks/mb/iPhone 13 Pro',
|
||||
2: 'owntracks/mb/iPhone XS',
|
||||
3: 'owntracks/mb/iPhone 6S',
|
||||
4: 'Google Latitude',
|
||||
5: 'owntracks/mb/iPhone 16 Pro'
|
||||
}
|
||||
|
||||
with open(FILE, "rt", encoding="utf-8-sig") as f:
|
||||
csvreader = csv.DictReader(f)
|
||||
i = 0
|
||||
for row in csvreader:
|
||||
attrs = json.loads(row["attributes"])
|
||||
|
||||
# OwnTracks format: https://owntracks.org/booklet/tech/json/#_typelocation
|
||||
owntr = {
|
||||
"_type": "location",
|
||||
"acc": int(row["accuracy"]),
|
||||
"alt": int(row["altitude"]),
|
||||
"bs": 1, # 0=unknown, 1=unplugged, 2=charging, 3=full
|
||||
"lat": float(row["latitude"]),
|
||||
"lon": float(row["longitude"]),
|
||||
"t": "p", # p=ping, u=manual, t=timer, etc.
|
||||
"tid": "MB",
|
||||
"tst": int(datetime.strptime(row["fixtime"], "%Y-%m-%d %H:%M:%S").timestamp()),
|
||||
"topic": tcid_map[int(row["deviceid"])],
|
||||
}
|
||||
if "batteryLevel" in attrs:
|
||||
owntr["batt"] = int(attrs["batteryLevel"])
|
||||
|
||||
if float(row["speed"]) > 0:
|
||||
owntr["vel"] = float(row["speed"])
|
||||
owntr["cog"] = int(row["course"])
|
||||
|
||||
#print("### Source data:")
|
||||
#print(repr(row))
|
||||
|
||||
#print("### Output:")
|
||||
#print(json.dumps(owntr))
|
||||
|
||||
dwirec = {
|
||||
"battery_status": 1,
|
||||
"ping": None,
|
||||
"battery": owntr["batt"] if "batt" in owntr else None,
|
||||
"tracker_id": owntr["tid"],
|
||||
"topic": owntr["topic"],
|
||||
"altitude": owntr["alt"],
|
||||
"longitude": owntr["lon"],
|
||||
"velocity": str(owntr["vel"]) if "vel" in owntr else None,
|
||||
"trigger": 0,
|
||||
"bssid": None,
|
||||
"ssid": None,
|
||||
"connection": 0,
|
||||
"vertical_accuracy": None,
|
||||
"accuracy": owntr["acc"],
|
||||
"timestamp": owntr["tst"],
|
||||
"latitude": owntr["lat"],
|
||||
"mode": None,
|
||||
"inrids": None,
|
||||
"in_regions": None,
|
||||
"raw_data": json.dumps(owntr),
|
||||
"import_id": None,
|
||||
"city": None,
|
||||
"country" :None,
|
||||
"created_at": row["fixtime"],
|
||||
"updated_at": row["fixtime"],
|
||||
"user_id": 1,
|
||||
"geodata": "{}",
|
||||
"visit_id": None,
|
||||
"reverse_geocoded_at": None,
|
||||
"course": owntr["cog"] if "cog" in owntr else None,
|
||||
"course_accuracy": None,
|
||||
"external_track_id": None,
|
||||
}
|
||||
|
||||
if i%10 == 0:
|
||||
if i>0:
|
||||
print(";")
|
||||
keys = dwirec.keys()
|
||||
keystring = '"' + '", "'.join(keys) + '"'
|
||||
print(f'INSERT INTO "points" ({keystring}) VALUES ')
|
||||
elif i>0:
|
||||
print(",")
|
||||
|
||||
values = []
|
||||
for k in keys:
|
||||
v = dwirec[k]
|
||||
if type(v) is str:
|
||||
if "'" in v:
|
||||
v = v.replace("'", "\\'")
|
||||
values.append("'" + v + "'")
|
||||
elif v is None:
|
||||
values.append("NULL")
|
||||
else:
|
||||
values.append(str(v))
|
||||
|
||||
valuestring = ", ".join(values)
|
||||
print(f"({valuestring})", end="")
|
||||
|
||||
i += 1
|
||||
#if i > 10:
|
||||
# break
|
||||
|
||||
print(";")
|
||||
print(f"{f} records converted.", file=sys.stderr)
|
||||
Executable
+11
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
DWI_HOST=dawarich.example.org
|
||||
DWI_APIKEY=0123456789abcdef
|
||||
cat converted.txt | while read line; do
|
||||
#echo $line
|
||||
curl "https://${DWI_HOST}/api/v1/owntracks/points?api_key=${DWI_APIKEY}" \
|
||||
--retry 99 \
|
||||
--retry-delay 5 \
|
||||
--retry-all-errors \
|
||||
--json "$line"
|
||||
done
|
||||
@@ -0,0 +1,20 @@
|
||||
id,protocol,deviceid,servertime,devicetime,fixtime,valid,latitude,longitude,altitude,speed,course,address,attributes,accuracy,network,geofenceids
|
||||
1,owntracks,1,2023-12-24 18:47:47,2023-12-24 18:47:26,2023-12-24 18:47:26,1,52.502427,13.251705,7,"0","0",,"{""tid"":""1"",""batteryLevel"":64,""distance"":0.0,""totalDistance"":0.0,""motion"":false}",5,null,null
|
||||
2,owntracks,1,2023-12-24 19:02:57,2023-12-24 19:02:48,2023-12-24 19:02:48,1,52.502427,13.251705,7,"0","0",,"{""tid"":""1"",""batteryLevel"":64,""distance"":0.0,""totalDistance"":0.0,""motion"":false}",5,null,null
|
||||
3,owntracks,1,2023-12-24 19:03:27,2023-12-24 19:03:26,2023-12-24 19:03:26,1,52.502427,13.251705,7,"0","0",,"{""tid"":""1"",""batteryLevel"":64,""distance"":0.0,""totalDistance"":0.0,""motion"":false}",5,null,null
|
||||
4,owntracks,1,2023-12-24 19:25:31,2023-12-24 19:25:24,2023-12-24 19:25:24,1,52.502427,13.251705,6,"0","0",,"{""tid"":""1"",""batteryLevel"":64,""distance"":0.0,""totalDistance"":0.0,""motion"":false}",5,null,null
|
||||
5,owntracks,1,2023-12-24 19:56:45,2023-12-24 19:56:44,2023-12-24 19:56:44,1,52.502448,13.251687,6,"0","0",,"{""tid"":""1"",""batteryLevel"":55,""distance"":2.6496482557134002,""totalDistance"":2.6496482557134002,""motion"":false}",35,null,null
|
||||
6,owntracks,1,2023-12-24 23:08:36,2023-12-24 23:08:36,2023-12-24 23:08:36,1,52.50243,13.25171,7,"0","0",,"{""tid"":""1"",""batteryLevel"":20,""distance"":2.5602962697448706,""totalDistance"":5.209944525458271,""motion"":false}",5,null,null
|
||||
7,owntracks,1,2023-12-25 11:38:54,2023-12-25 11:38:53,2023-12-25 11:38:53,1,52.501312,13.252581,6,2.69978,233,,"{""tid"":""1"",""t"":""v"",""batteryLevel"":85,""distance"":138.31830028323412,""totalDistance"":143.5282448086924,""motion"":true}",5,null,null
|
||||
8,owntracks,1,2023-12-25 11:46:30,2023-12-25 11:46:29,2023-12-25 11:46:29,1,52.498118,13.254032,-8,2.69978,159,,"{""tid"":""1"",""batteryLevel"":85,""distance"":369.49923295378073,""totalDistance"":513.0274777624732,""motion"":true}",10,null,null
|
||||
9,owntracks,1,2023-12-25 11:51:14,2023-12-25 11:51:13,2023-12-25 11:51:13,1,52.495697,13.254832,7,"0",74,,"{""tid"":""1"",""t"":""v"",""batteryLevel"":85,""distance"":275.14814739262914,""totalDistance"":788.1756251551024,""motion"":false}",5,null,null
|
||||
10,owntracks,1,2023-12-25 11:51:15,2023-12-25 11:46:29,2023-12-25 11:46:29,1,52.498118,13.254032,-8,2.69978,159,,"{""tid"":""1"",""batteryLevel"":85,""distance"":275.14814739262914,""totalDistance"":1063.3237725477316,""motion"":true}",10,null,null
|
||||
11,owntracks,1,2023-12-25 13:54:15,2023-12-25 13:54:14,2023-12-25 13:54:14,1,52.493614,13.255329,6,"0","0",,"{""tid"":""1"",""batteryLevel"":75,""distance"":234.42292307499253,""totalDistance"":1022.5985482300948,""motion"":false}",40,null,null
|
||||
12,owntracks,1,2023-12-25 13:58:56,2023-12-25 13:58:55,2023-12-25 13:58:55,1,52.493439,13.25523,7,"0","0",,"{""tid"":""1"",""t"":""v"",""batteryLevel"":75,""distance"":20.65395275868584,""totalDistance"":1043.2525009887806,""motion"":false}",35,null,null
|
||||
13,owntracks,1,2023-12-25 13:58:57,2023-12-25 13:54:14,2023-12-25 13:54:14,1,52.493614,13.255329,6,"0","0",,"{""tid"":""1"",""batteryLevel"":75,""distance"":20.65395275868584,""totalDistance"":1063.9064537474665,""motion"":false}",40,null,null
|
||||
14,owntracks,1,2023-12-25 14:00:01,2023-12-25 14:00:00,2023-12-25 14:00:00,1,52.493683,13.255418,2,2.69978,348,,"{""tid"":""1"",""t"":""v"",""batteryLevel"":69,""distance"":30.125558440026264,""totalDistance"":1073.3780594288069,""motion"":true}",4,null,null
|
||||
15,owntracks,1,2023-12-25 14:00:02,2023-12-25 13:54:14,2023-12-25 13:54:14,1,52.493614,13.255329,6,"0","0",,"{""tid"":""1"",""batteryLevel"":69,""distance"":9.851263572220656,""totalDistance"":1083.2293230010275,""motion"":false}",40,null,null
|
||||
16,owntracks,1,2023-12-25 14:13:26,2023-12-25 14:13:26,2023-12-25 14:13:26,1,52.497498,13.253328,5,"0","0",,"{""tid"":""1"",""t"":""v"",""batteryLevel"":69,""distance"":448.7059070673693,""totalDistance"":1522.0839664961761,""motion"":false}",40,null,null
|
||||
17,owntracks,1,2023-12-25 14:13:27,2023-12-25 13:54:14,2023-12-25 13:54:14,1,52.493614,13.255329,6,"0","0",,"{""tid"":""1"",""batteryLevel"":69,""distance"":454.06082222124735,""totalDistance"":1976.1447887174236,""motion"":false}",40,null,null
|
||||
18,owntracks,1,2023-12-25 14:13:54,2023-12-25 14:13:53,2023-12-25 14:13:53,1,52.497904,13.253075,-1,"0","0",,"{""tid"":""1"",""batteryLevel"":69,""distance"":48.47750466076835,""totalDistance"":1570.5614711569444,""motion"":false}",40,null,null
|
||||
19,owntracks,1,2023-12-25 14:20:18,2023-12-25 14:20:18,2023-12-25 14:20:18,1,52.500702,13.252914,7,1.61987,1,,"{""tid"":""1"",""t"":""v"",""batteryLevel"":69,""distance"":311.6716997925153,""totalDistance"":1882.2331709494597,""motion"":true}",5,null,null
|
||||
|
Reference in New Issue
Block a user