]> www.average.org Git - loctrkd.git/commitdiff
A script to parse data from the database
authorEugene Crosser <crosser@average.org>
Wed, 16 Mar 2022 16:30:30 +0000 (17:30 +0100)
committerEugene Crosser <crosser@average.org>
Wed, 16 Mar 2022 16:30:30 +0000 (17:30 +0100)
gps303/GT06mod.py
gps303/qry.py [new file with mode: 0644]

index 3256d6ca5ae4f9e61fde001c3b3e8891b1e8fc74..aa8246facd3823946cb6aaef89df746ab8d345d4 100755 (executable)
@@ -8,7 +8,36 @@ from inspect import isclass
 from logging import getLogger
 from struct import pack, unpack
 
-__all__ = ("handle_packet", "make_response")
+__all__ = (
+    "handle_packet",
+    "make_object",
+    "make_response",
+    "set_config",
+    "UNKNOWN",
+    "LOGIN",
+    "SUPERVISION",
+    "HEARTBEAT",
+    "GPS_POSITIONING",
+    "GPS_OFFLINE_POSITIONING",
+    "STATUS",
+    "HIBERNATION",
+    "RESET",
+    "WHITELIST_TOTAL",
+    "WIFI_OFFLINE_POSITIONING",
+    "TIME",
+    "MOM_PHONE",
+    "STOP_ALARM",
+    "SETUP",
+    "SYNCHRONOUS_WHITELIST",
+    "RESTORE_PASSWORD",
+    "WIFI_POSITIONING",
+    "MANUAL_POSITIONING",
+    "BATTERY_CHARGE",
+    "CHARGER_CONNECTED",
+    "CHARGER_DISCONNECTED",
+    "VIBRATION_RECEIVED",
+    "POSITION_UPLOAD_INTERVAL",
+)
 
 log = getLogger("gps303")
 
@@ -38,13 +67,8 @@ class _GT06pkt:
         )
 
     @classmethod
-    def from_packet(cls, length, proto, payload):
-        adjust = 2 if proto == STATUS.PROTO else 4  # Weird special case
-        if length > 1 and len(payload) + adjust != length:
-            log.warning(
-                "length is %d but payload length is %d", length, len(payload)
-            )
-        return cls(length=length, proto=proto, payload=payload)
+    def from_packet(cls, proto, payload):
+        return cls(proto=proto, payload=payload)
 
     def response(self, *args):
         if len(args) == 0:
@@ -65,8 +89,8 @@ class LOGIN(_GT06pkt):
     PROTO = 0x01
 
     @classmethod
-    def from_packet(cls, length, proto, payload):
-        self = super().from_packet(length, proto, payload)
+    def from_packet(cls, proto, payload):
+        self = super().from_packet(proto, payload)
         self.imei = payload[:-1].hex()
         self.ver = unpack("B", payload[-1:])[0]
         return self
@@ -84,10 +108,9 @@ class HEARTBEAT(_GT06pkt):
 
 
 class _GPS_POSITIONING(_GT06pkt):
-
     @classmethod
-    def from_packet(cls, length, proto, payload):
-        self = super().from_packet(length, proto, payload)
+    def from_packet(cls, proto, payload):
+        self = super().from_packet(proto, payload)
         self.dtime = payload[:6]
         # TODO parse the rest
         return self
@@ -108,8 +131,8 @@ class STATUS(_GT06pkt):
     PROTO = 0x13
 
     @classmethod
-    def from_packet(cls, length, proto, payload):
-        self = super().from_packet(length, proto, payload)
+    def from_packet(cls, proto, payload):
+        self = super().from_packet(proto, payload)
         if len(payload) == 5:
             self.batt, self.ver, self.intvl, self.signal, _ = unpack(
                 "BBBBB", payload
@@ -226,8 +249,8 @@ class POSITION_UPLOAD_INTERVAL(_GT06pkt):
     PROTO = 0x98
 
     @classmethod
-    def from_packet(cls, length, proto, payload):
-        self = super().from_packet(length, proto, payload)
+    def from_packet(cls, proto, payload):
+        self = super().from_packet(proto, payload)
         self.interval = unpack("!H", payload[:2])
         return self
 
@@ -248,22 +271,33 @@ if True:  # just to indent the code, sorry!
         if hasattr(cls, "PROTO"):
             CLASSES[cls.PROTO] = cls
 
+def make_object(proto, payload):
+    if proto in CLASSES:
+        return CLASSES[proto].from_packet(proto, payload)
+    else:
+        return UNKNOWN.from_packet(proto, payload)
 
 def handle_packet(packet, addr, when):
     if len(packet) < 6:
-        msg = UNKNOWN.from_packet(0, 0, packet)
+        return UNKNOWN.from_packet(0, packet)
     else:
         xx, length, proto = unpack("!2sBB", packet[:4])
         crlf = packet[-2:]
         payload = packet[4:-2]
-        if xx != b"xx" or crlf != b"\r\n" or proto not in CLASSES:
-            msg = UNKNOWN.from_packet(length, proto, packet)
+        adjust = 2 if proto == STATUS.PROTO else 4  # Weird special case
+        if length > 1 and len(payload) + adjust != length:
+            log.warning(
+                "length is %d but payload length is %d", length, len(payload)
+            )
+        if xx != b"xx" or crlf != b"\r\n":
+            return UNKNOWN.from_packet(proto, packet)  # full packet as payload
         else:
-            msg = CLASSES[proto].from_packet(length, proto, payload)
-    return msg
+            return make_object(proto, payload)
+
 
 def make_response(msg):
     return msg.response()
 
+
 def set_config(config):  # Note that we are setting _class_ attribute
     _GT06pkt.CONFIG = config
diff --git a/gps303/qry.py b/gps303/qry.py
new file mode 100644 (file)
index 0000000..2d48899
--- /dev/null
@@ -0,0 +1,12 @@
+from datetime import datetime
+from sqlite3 import connect
+import sys
+
+from .GT06mod import *
+
+db = connect(sys.argv[1])
+c = db.cursor()
+c.execute("select timestamp, imei, clntaddr, proto, payload from events")
+for timestamp, imei, clntaddr, proto, payload in c:
+    print(datetime.fromtimestamp(timestamp).isoformat(),
+            make_object(proto, payload))