]> www.average.org Git - loctrkd.git/commitdiff
add lookaside module and opencellid lookup
authorEugene Crosser <crosser@average.org>
Fri, 18 Mar 2022 23:31:17 +0000 (00:31 +0100)
committerEugene Crosser <crosser@average.org>
Fri, 18 Mar 2022 23:31:17 +0000 (00:31 +0100)
gps303.conf
gps303/GT06mod.py
gps303/__main__.py
gps303/lookaside.py [new file with mode: 0644]
gps303/opencellid.py

index 97c9959fa6c14e8bc90a52e91f711c1b670bc1b2..3a90e3bb5b0079ca854b1367779aaf9bd3dbac50 100644 (file)
@@ -2,6 +2,9 @@
 port = 4303
 dbfn = gps303.sqlite
 
+[opencellid]
+dbfn = opencellid.sqlite
+
 [device]
 uploadIntervalSeconds = 0x0300
 binarySwitch = 0b00110001
index 86cc8aacdc6542bab99a64a40b4befe90e42ddad..ded38f2eea34d51e56f3e14d9be589d4245bacf5 100755 (executable)
@@ -307,8 +307,13 @@ class RESTORE_PASSWORD(_GT06pkt):
 class WIFI_POSITIONING(_WIFI_POSITIONING):
     PROTO = 0x69
 
-    def response(self):
-        payload = b""  # TODO fill payload
+    def response(self, lat=None, lon=None):
+        if lat is None or lon is None:
+            payload = b""
+        else:
+            payload = "{:+#010.8g},{:+#010.8g}".format(lat, lon).encode(
+                "ascii"
+            )
         return super().response(payload)
 
 
@@ -397,8 +402,8 @@ def handle_packet(packet, addr, when):
             return make_object(length, proto, payload)
 
 
-def make_response(msg):
-    return msg.response()
+def make_response(msg, **kwargs):
+    return msg.response(**kwargs)
 
 
 def set_config(config):  # Note that we are setting _class_ attribute
index ddad2b780ea600df2b8da438d87d45d7e0fa39af..e3fd84a2460271a69fb65acfee1485e406e06a89 100755 (executable)
@@ -9,6 +9,7 @@ from time import time
 from .config import readconfig
 from .GT06mod import handle_packet, make_response, LOGIN, set_config
 from .evstore import initdb, stow
+from .lookaside import prepare_response
 
 CONF = "/etc/gps303.conf"
 
@@ -81,7 +82,8 @@ if __name__.endswith("__main__"):
                             msg.proto,
                             msg.payload,
                         )
-                        response = make_response(msg)
+                        kwargs = prepare_response(conf, msg)
+                        response = make_response(msg, **kwargs)
                         if response:
                             try:
                                 # Ignore possibility of blocking
diff --git a/gps303/lookaside.py b/gps303/lookaside.py
new file mode 100644 (file)
index 0000000..3c3ee32
--- /dev/null
@@ -0,0 +1,13 @@
+"""
+For when responding to the terminal is not trivial
+"""
+
+from .GT06mod import *
+from .opencellid import qry_cell
+
+def prepare_response(conf, msg):
+    if isinstance(msg, WIFI_POSITIONING):
+        lat, lon = qry_cell(conf["opencellid"]["dbfn"],
+                msg.mcc, msg.gsm_cells)
+        return {"lat": lat, "lon": lon}
+    return {}
index 5527a1912bf38f69013210b19d824e452ea72463..dc0daaee4bde2e201651dba2b3028484350208d0 100644 (file)
@@ -22,35 +22,54 @@ sqlite> .import <downloaded-file.csv> cells
 sqlite> create index if not exists cell_idx on cells (mcc, area, cell);
 """
 
-from datetime import datetime, timezone
-from pprint import pprint
 from sqlite3 import connect
-import sys
 
-from .GT06mod import *
 
-db = connect(sys.argv[1])
-ldb = connect(sys.argv[2])
-lc = ldb.cursor()
-c = db.cursor()
-c.execute(
-    """select timestamp, imei, clntaddr, length, proto, payload from events
-        where proto in (?, ?)""",
-    (WIFI_POSITIONING.PROTO, WIFI_OFFLINE_POSITIONING.PROTO),
-)
-for timestamp, imei, clntaddr, length, proto, payload in c:
-    obj = make_object(length, proto, payload)
-    qry = """select lat, lon from cells
-             where mcc = {} and (area, cell) in ({})""".format(
-        obj.mcc,
-        ", ".join(
-            [
-                "({}, {})".format(locac, cellid)
-                for locac, cellid, _ in obj.gsm_cells
-            ]
-        ),
+def qry_cell(dbname, mcc, gsm_cells):
+    with connect(dbname) as ldb:
+        lc = ldb.cursor()
+        lc.execute("""attach database ":memory:" as mem""")
+        lc.execute("create table mem.seen (locac int, cellid int, signal int)")
+        lc.executemany(
+            """insert into mem.seen (locac, cellid, signal)
+                            values (?, ?, ?)""",
+            gsm_cells,
+        )
+        lc.execute(
+            """select c.lat, c.lon, s.signal
+                      from main.cells c, mem.seen s
+                      where c.mcc = ?
+                      and c.area = s.locac
+                      and c.cell = s.cellid""",
+            (mcc,),
+        )
+        data = list(lc.fetchall())
+        sumsig = sum([sig for _, _, sig in data])
+        nsigs = [sig / sumsig for _, _, sig in data]
+        avlat = sum([lat * nsig for (lat, _, _), nsig in zip(data, nsigs)])
+        avlon = sum([lon * nsig for (_, lon, _), nsig in zip(data, nsigs)])
+        # lc.execute("drop table mem.seen")
+        lc.close()
+        return avlat, avlon
+
+
+if __name__.endswith("__main__"):
+    from datetime import datetime, timezone
+    import sys
+    from .GT06mod import *
+
+    db = connect(sys.argv[1])
+    c = db.cursor()
+    c.execute(
+        """select timestamp, imei, clntaddr, length, proto, payload from events
+            where proto in (?, ?)""",
+        (WIFI_POSITIONING.PROTO, WIFI_OFFLINE_POSITIONING.PROTO),
     )
-    print(qry)
-    lc.execute(qry)
-    for lat, lon in lc:
-        print(lat, lon)
+    for timestamp, imei, clntaddr, length, proto, payload in c:
+        obj = make_object(length, proto, payload)
+        avlat, avlon = qry_cell(sys.argv[2], obj.mcc, obj.gsm_cells)
+        print(
+            "{} {:+#010.8g},{:+#010.8g}".format(
+                datetime.fromtimestamp(timestamp), avlat, avlon
+            )
+        )