From 808f12aac57321b2fb3b902833c1c5247cac8323 Mon Sep 17 00:00:00 2001 From: Eugene Crosser Date: Sun, 27 Nov 2022 22:46:01 +0100 Subject: [PATCH] Change reporting of pmod to events --- loctrkd/beesure.py | 8 ++++---- loctrkd/collector.py | 4 +++- loctrkd/common.py | 2 +- loctrkd/protomodule.py | 2 +- loctrkd/rectifier.py | 6 ++---- loctrkd/storage.py | 28 +++++++++++++++------------- loctrkd/zmsg.py | 30 ++++++++++++++++-------------- loctrkd/zx303proto.py | 14 +++++++------- 8 files changed, 49 insertions(+), 45 deletions(-) diff --git a/loctrkd/beesure.py b/loctrkd/beesure.py index e782c73..b3afae1 100755 --- a/loctrkd/beesure.py +++ b/loctrkd/beesure.py @@ -43,7 +43,7 @@ __all__ = ( "Respond", ) -MODNAME = __name__.split(".")[-1] +PMODNAME = __name__.split(".")[-1] PROTO_PREFIX = "BS:" ### Deframer ### @@ -381,12 +381,12 @@ class _LOC_DATA(BeeSurePkt): self.latitude = p.lat * p.nors self.longitude = p.lon * p.eorw - def rectified(self) -> Tuple[str, Report]: + def rectified(self) -> Report: # self.gps_valid is supposed to mean it, but it does not. Perfectly # good looking coordinates, with ten satellites, still get 'V'. # I suspect that in reality, 'A' means "hint data is absent". if self.gps_valid or self.num_of_sats > 3: - return MODNAME, CoordReport( + return CoordReport( devtime=str(self.devtime), battery_percentage=self.battery_percentage, accuracy=self.positioning_accuracy, @@ -397,7 +397,7 @@ class _LOC_DATA(BeeSurePkt): longitude=self.longitude, ) else: - return MODNAME, HintReport( + return HintReport( devtime=str(self.devtime), battery_percentage=self.battery_percentage, mcc=self.mcc, diff --git a/loctrkd/collector.py b/loctrkd/collector.py index 788cb11..5c1c34e 100644 --- a/loctrkd/collector.py +++ b/loctrkd/collector.py @@ -223,6 +223,7 @@ def runserver(conf: ConfigParser, handle_hibernate: bool = True) -> None: zpub.send( Bcast( proto=proto, + pmod=pmod.PMODNAME, imei=imei, when=when, peeraddr=peeraddr, @@ -255,8 +256,9 @@ def runserver(conf: ConfigParser, handle_hibernate: bool = True) -> None: Bcast( is_incoming=False, proto=rpmod.proto_of_message(zmsg.packet), - when=zmsg.when, + pmod=pmod.PMODNAME, imei=zmsg.imei, + when=zmsg.when, packet=zmsg.packet, ).packed ) diff --git a/loctrkd/common.py b/loctrkd/common.py index 162fe0d..026f5f3 100644 --- a/loctrkd/common.py +++ b/loctrkd/common.py @@ -73,7 +73,7 @@ def pmod_for_proto(proto: str) -> Optional[ProtoModule]: def pmod_by_name(pmodname: str) -> Optional[ProtoModule]: for pmod in pmods: - if pmod.__name__.split(".")[-1] == pmodname: + if pmod.PMODNAME == pmodname: return pmod return None diff --git a/loctrkd/protomodule.py b/loctrkd/protomodule.py index a1698f2..0ffff17 100644 --- a/loctrkd/protomodule.py +++ b/loctrkd/protomodule.py @@ -122,7 +122,7 @@ class ProtoClass(Protocol, metaclass=_MetaProto): class ProtoModule: - __name__: str + PMODNAME: str class Stream: def recv(self, segment: bytes) -> List[Union[bytes, str]]: diff --git a/loctrkd/rectifier.py b/loctrkd/rectifier.py index 5926377..161e2a9 100644 --- a/loctrkd/rectifier.py +++ b/loctrkd/rectifier.py @@ -68,12 +68,10 @@ def runserver(conf: ConfigParser) -> None: datetime.fromtimestamp(zmsg.when).astimezone(tz=timezone.utc), msg, ) - pmod, rect = msg.rectified() + rect = msg.rectified() log.debug("rectified: %s", rect) if isinstance(rect, (CoordReport, StatusReport)): - zpub.send( - Rept(imei=zmsg.imei, pmod=pmod, payload=rect.json).packed - ) + zpub.send(Rept(imei=zmsg.imei, payload=rect.json).packed) elif isinstance(rect, HintReport): try: lat, lon, acc = qry.lookup( diff --git a/loctrkd/storage.py b/loctrkd/storage.py index e1be227..8439915 100644 --- a/loctrkd/storage.py +++ b/loctrkd/storage.py @@ -14,6 +14,7 @@ log = getLogger("loctrkd/storage") def runserver(conf: ConfigParser) -> None: + stowevents = conf.getboolean("storage", "events", fallback=False) dbname = conf.get("storage", "dbfn") log.info('Using Sqlite3 database "%s"', dbname) initdb(dbname) @@ -21,8 +22,7 @@ def runserver(conf: ConfigParser) -> None: zctx = zmq.Context() # type: ignore zraw = zctx.socket(zmq.SUB) # type: ignore zraw.connect(conf.get("collector", "publishurl")) - if conf.getboolean("storage", "events", fallback=False): - zraw.setsockopt(zmq.SUBSCRIBE, b"") + zraw.setsockopt(zmq.SUBSCRIBE, b"") zrep = zctx.socket(zmq.SUB) # type: ignore zrep.connect(conf.get("rectifier", "publishurl")) zrep.setsockopt(zmq.SUBSCRIBE, b"") @@ -41,31 +41,33 @@ def runserver(conf: ConfigParser) -> None: except zmq.Again: break log.debug( - "%s IMEI %s from %s at %s: %s", + "%s IMEI %s from %s at %s %s: %s", "I" if zmsg.is_incoming else "O", zmsg.imei, zmsg.peeraddr, + zmsg.pmod, datetime.fromtimestamp(zmsg.when).astimezone( tz=timezone.utc ), zmsg.packet.hex(), ) - stow( - is_incoming=zmsg.is_incoming, - peeraddr=str(zmsg.peeraddr), - when=zmsg.when, - imei=zmsg.imei, - proto=zmsg.proto, - packet=zmsg.packet, - ) + if zmsg.imei is not None and zmsg.pmod is not None: + stowpmod(zmsg.imei, zmsg.pmod) + if stowevents: + stow( + is_incoming=zmsg.is_incoming, + peeraddr=str(zmsg.peeraddr), + when=zmsg.when, + imei=zmsg.imei, + proto=zmsg.proto, + packet=zmsg.packet, + ) elif sk is zrep: while True: try: rept = Rept(zrep.recv(zmq.NOBLOCK)) except zmq.Again: break - if rept.imei is not None and rept.pmod is not None: - stowpmod(rept.imei, rept.pmod) data = loads(rept.payload) log.debug("R IMEI %s %s", rept.imei, data) if data.pop("type") == "location": diff --git a/loctrkd/zmsg.py b/loctrkd/zmsg.py index 6539d5f..07798a6 100644 --- a/loctrkd/zmsg.py +++ b/loctrkd/zmsg.py @@ -110,6 +110,7 @@ class Bcast(_Zmsg): KWARGS = ( ("is_incoming", True), ("proto", "UNKNOWN"), + ("pmod", None), ("imei", None), ("when", None), ("peeraddr", None), @@ -120,28 +121,36 @@ class Bcast(_Zmsg): def packed(self) -> bytes: return ( pack( - "!B16s16sd", + "!B16s16sd16s", int(self.is_incoming), self.proto[:16].ljust(16, "\0").encode(), b"0000000000000000" if self.imei is None else self.imei.encode(), 0 if self.when is None else self.when, + b" " + if self.pmod is None + else self.pmod.encode(), ) + pack_peer(self.peeraddr) + self.packet ) def decode(self, buffer: bytes) -> None: - is_incoming, proto, imei, when = unpack("!B16s16sd", buffer[:41]) + is_incoming, proto, imei, when, pmod = unpack( + "!B16s16sd16s", buffer[:57] + ) self.is_incoming = bool(is_incoming) self.proto = proto.decode().rstrip("\0") self.imei = ( None if imei == b"0000000000000000" else imei.decode().strip("\0") ) self.when = when - self.peeraddr = unpack_peer(buffer[41:59]) - self.packet = buffer[59:] + self.pmod = ( + None if pmod == b" " else pmod.decode().strip("\0") + ) + self.peeraddr = unpack_peer(buffer[57:75]) + self.packet = buffer[75:] class Resp(_Zmsg): @@ -175,19 +184,16 @@ class Resp(_Zmsg): class Rept(_Zmsg): """Broadcast zmq message with "rectified" proto-agnostic json data""" - KWARGS = (("imei", None), ("payload", ""), ("pmod", None)) + KWARGS = (("imei", None), ("payload", "")) @property def packed(self) -> bytes: return ( pack( - "16s16s", + "16s", b"0000000000000000" if self.imei is None else self.imei.encode(), - b" " - if self.pmod is None - else self.pmod.encode(), ) + self.payload.encode() ) @@ -197,8 +203,4 @@ class Rept(_Zmsg): self.imei = ( None if imei == b"0000000000000000" else imei.decode().strip("\0") ) - pmod = buffer[16:32] - self.pmod = ( - None if pmod == b" " else pmod.decode().strip("\0") - ) - self.payload = buffer[32:].decode() + self.payload = buffer[16:].decode() diff --git a/loctrkd/zx303proto.py b/loctrkd/zx303proto.py index a7329c3..bc044dd 100755 --- a/loctrkd/zx303proto.py +++ b/loctrkd/zx303proto.py @@ -48,7 +48,7 @@ __all__ = ( "Respond", ) -MODNAME = __name__.split(".")[-1] +PMODNAME = __name__.split(".")[-1] PROTO_PREFIX: str = "ZX:" ### Deframer ### @@ -370,8 +370,8 @@ class _GPS_POSITIONING(GPS303Pkt): ttup = (tup[0] % 100,) + tup[1:6] return pack("BBBBBB", *ttup) - def rectified(self) -> Tuple[str, CoordReport]: # JSON-able dict - return MODNAME, CoordReport( + def rectified(self) -> CoordReport: # JSON-able dict + return CoordReport( devtime=str(self.devtime), battery_percentage=None, accuracy=None, @@ -420,8 +420,8 @@ class STATUS(GPS303Pkt): def out_encode(self) -> bytes: # Set interval in minutes return pack("B", self.upload_interval) - def rectified(self) -> Tuple[str, StatusReport]: - return MODNAME, StatusReport(battery_percentage=self.batt) + def rectified(self) -> StatusReport: + return StatusReport(battery_percentage=self.batt) class HIBERNATION(GPS303Pkt): # Server can send to send devicee to sleep @@ -501,8 +501,8 @@ class _WIFI_POSITIONING(GPS303Pkt): ] ) - def rectified(self) -> Tuple[str, HintReport]: - return MODNAME, HintReport( + def rectified(self) -> HintReport: + return HintReport( devtime=str(self.devtime), battery_percentage=None, mcc=self.mcc, -- 2.39.2