]> www.average.org Git - loctrkd.git/blob - gps303/lookaside.py
Broadcast location, gps and approximated
[loctrkd.git] / gps303 / lookaside.py
1 """ Estimate coordinates from WIFI_POSITIONING and send back """
2
3 from datetime import datetime, timezone
4 from logging import getLogger
5 from struct import pack
6 import zmq
7
8 from . import common
9 from .gps303proto import parse_message, proto_by_name, WIFI_POSITIONING
10 from .opencellid import qry_cell
11 from .zmsg import Bcast, LocEvt, Resp
12
13 log = getLogger("gps303/lookaside")
14
15
16 def runserver(conf):
17     zctx = zmq.Context()
18     zpub = zctx.socket(zmq.PUB)
19     zpub.bind(conf.get("lookaside", "publishurl"))
20     zsub = zctx.socket(zmq.SUB)
21     zsub.connect(conf.get("collector", "publishurl"))
22     for protoname in (
23         "GPS_POSITIONING",
24         "GPS_OFFLINE_POSITIONING",
25         "WIFI_POSITIONING",
26     ):
27         topic = pack("B", proto_by_name(protoname))
28         zsub.setsockopt(zmq.SUBSCRIBE, topic)
29     zpush = zctx.socket(zmq.PUSH)
30     zpush.connect(conf.get("collector", "listenurl"))
31
32     try:
33         while True:
34             zmsg = Bcast(zsub.recv())
35             msg = parse_message(zmsg.packet)
36             log.debug(
37                 "IMEI %s from %s at %s: %s",
38                 zmsg.imei,
39                 zmsg.peeraddr,
40                 datetime.fromtimestamp(zmsg.when).astimezone(tz=timezone.utc),
41                 msg,
42             )
43             if isinstance(msg, WIFI_POSITIONING):
44                 is_gps = False
45                 lat, lon = qry_cell(
46                     conf["opencellid"]["dbfn"], msg.mcc, msg.gsm_cells
47                 )
48                 resp = Resp(
49                     imei=zmsg.imei, packet=msg.Out(lat=lat, lon=lon).packed
50                 )
51                 log.debug("Response for lat=%s, lon=%s: %s", lat, lon, resp)
52                 zpush.send(resp.packed)
53             else:
54                 is_gps = True
55                 lat = msg.latitude
56                 lon = msg.longitude
57             zpub.send(
58                 LocEvt(
59                     imei=zmsg.imei,
60                     devtime=msg.devtime,
61                     is_gps=is_gps,
62                     lat=lat,
63                     lon=lon,
64                 ).packed
65             )
66
67     except KeyboardInterrupt:
68         pass
69
70
71 if __name__.endswith("__main__"):
72     runserver(common.init(log))