From: Eugene Crosser Date: Fri, 29 Apr 2022 22:18:00 +0000 (+0200) Subject: Broadcast location, gps and approximated X-Git-Tag: 0.01~22 X-Git-Url: http://www.average.org/gitweb/?p=loctrkd.git;a=commitdiff_plain;h=80e795c08def3466884223357798cd1aff265212 Broadcast location, gps and approximated --- diff --git a/debian/gps303.conf b/debian/gps303.conf index 10889eb..2ee044b 100644 --- a/debian/gps303.conf +++ b/debian/gps303.conf @@ -6,6 +6,9 @@ listenurl = ipc:///var/lib/gps303/responses [storage] dbfn = /var/lib/gps303/gps303.sqlite +[lookaside] +publishurl = ipc:///var/lib/gps303/locevt + [opencellid] dbfn = /var/lib/opencellid/opencellid.sqlite diff --git a/gps303.conf b/gps303.conf index 7669381..59ab59b 100644 --- a/gps303.conf +++ b/gps303.conf @@ -6,6 +6,9 @@ listenurl = ipc:///tmp/responses [storage] dbfn = /home/crosser/src/gps303/gps303.sqlite +[lookaside] +publishurl = ipc:///tmp/locevt + [opencellid] dbfn = /home/crosser/src/gps303/opencellid.sqlite diff --git a/gps303/gps303proto.py b/gps303/gps303proto.py index c19c7c1..d07d4fa 100755 --- a/gps303/gps303proto.py +++ b/gps303/gps303proto.py @@ -245,8 +245,9 @@ class _GPS_POSITIONING(GPS303Pkt): if self.dtime == b"\0\0\0\0\0\0": self.devtime = None else: + yr, mo, da, hr, mi, se = unpack("BBBBBB", self.dtime) self.devtime = datetime( - *unpack("BBBBBB", self.dtime), tzinfo=timezone.utc + 2000 + yr, mo, da, hr, mi, se, tzinfo=timezone.utc ) self.gps_data_length = payload[6] >> 4 self.gps_nb_sat = payload[6] & 0x0F diff --git a/gps303/lookaside.py b/gps303/lookaside.py index 93103a6..085cbe9 100644 --- a/gps303/lookaside.py +++ b/gps303/lookaside.py @@ -8,17 +8,24 @@ import zmq from . import common from .gps303proto import parse_message, proto_by_name, WIFI_POSITIONING from .opencellid import qry_cell -from .zmsg import Bcast, Resp +from .zmsg import Bcast, LocEvt, Resp log = getLogger("gps303/lookaside") def runserver(conf): zctx = zmq.Context() + zpub = zctx.socket(zmq.PUB) + zpub.bind(conf.get("lookaside", "publishurl")) zsub = zctx.socket(zmq.SUB) zsub.connect(conf.get("collector", "publishurl")) - topic = pack("B", proto_by_name("WIFI_POSITIONING")) - zsub.setsockopt(zmq.SUBSCRIBE, topic) + for protoname in ( + "GPS_POSITIONING", + "GPS_OFFLINE_POSITIONING", + "WIFI_POSITIONING", + ): + topic = pack("B", proto_by_name(protoname)) + zsub.setsockopt(zmq.SUBSCRIBE, topic) zpush = zctx.socket(zmq.PUSH) zpush.connect(conf.get("collector", "listenurl")) @@ -33,23 +40,29 @@ def runserver(conf): datetime.fromtimestamp(zmsg.when).astimezone(tz=timezone.utc), msg, ) - if not isinstance(msg, WIFI_POSITIONING): - log.error( - "IMEI %s from %s at %s: %s", - zmsg.imei, - zmsg.peeraddr, - datetime.fromtimestamp(zmsg.when).astimezone( - tz=timezone.utc - ), - msg, + if isinstance(msg, WIFI_POSITIONING): + is_gps = False + lat, lon = qry_cell( + conf["opencellid"]["dbfn"], msg.mcc, msg.gsm_cells ) - continue - lat, lon = qry_cell( - conf["opencellid"]["dbfn"], msg.mcc, msg.gsm_cells + resp = Resp( + imei=zmsg.imei, packet=msg.Out(lat=lat, lon=lon).packed + ) + log.debug("Response for lat=%s, lon=%s: %s", lat, lon, resp) + zpush.send(resp.packed) + else: + is_gps = True + lat = msg.latitude + lon = msg.longitude + zpub.send( + LocEvt( + imei=zmsg.imei, + devtime=msg.devtime, + is_gps=is_gps, + lat=lat, + lon=lon, + ).packed ) - resp = Resp(imei=zmsg.imei, packet=msg.Out(lat=lat, lon=lon).packed) - log.debug("Response for lat=%s, lon=%s: %s", lat, lon, resp) - zpush.send(resp.packed) except KeyboardInterrupt: pass diff --git a/gps303/watch.py b/gps303/watch.py new file mode 100644 index 0000000..8ae9ab9 --- /dev/null +++ b/gps303/watch.py @@ -0,0 +1,28 @@ +""" Watch for locevt and print them """ + +from datetime import datetime, timezone +from logging import getLogger +import zmq + +from . import common +from .zmsg import LocEvt + +log = getLogger("gps303/watch") + + +def runserver(conf): + zctx = zmq.Context() + zsub = zctx.socket(zmq.SUB) + zsub.connect(conf.get("lookaside", "publishurl")) + zsub.setsockopt(zmq.SUBSCRIBE, b"") + + try: + while True: + zmsg = LocEvt(zsub.recv()) + print(zmsg) + except KeyboardInterrupt: + pass + + +if __name__.endswith("__main__"): + runserver(common.init(log)) diff --git a/gps303/zmsg.py b/gps303/zmsg.py index 5639200..80cf000 100644 --- a/gps303/zmsg.py +++ b/gps303/zmsg.py @@ -1,9 +1,10 @@ """ Zeromq messages """ +from datetime import datetime, timezone import ipaddress as ip from struct import pack, unpack -__all__ = "Bcast", "Resp" +__all__ = "Bcast", "LocEvt", "Resp" def pack_peer(peeraddr): @@ -119,3 +120,31 @@ class Resp(_Zmsg): def decode(self, buffer): self.imei = buffer[:16].decode() self.packet = buffer[16:] + + +class LocEvt(_Zmsg): + """Zmq message with original or approximated location from lookaside""" + + KWARGS = ( + ("imei", "0000000000000000"), + ("devtime", datetime(1970, 1, 1, tzinfo=timezone.utc)), + ("lat", 0.0), + ("lon", 0.0), + ("is_gps", True), + ) + + @property + def packed(self): + return self.imei.encode() + pack( + "!dddB", + self.devtime.replace(tzinfo=timezone.utc).timestamp(), + self.lat, + self.lon, + int(self.is_gps), + ) + + def decode(self, buffer): + self.imei = buffer[:16].decode() + when, self.lat, self.lon, is_gps = unpack("!dddB", buffer[16:]) + self.devtime = datetime.fromtimestamp(when).astimezone(tz=timezone.utc) + self.is_gps = bool(is_gps)