"Respond",
)
-MODNAME = __name__.split(".")[-1]
+PMODNAME = __name__.split(".")[-1]
PROTO_PREFIX = "BS:"
### Deframer ###
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,
longitude=self.longitude,
)
else:
- return MODNAME, HintReport(
+ return HintReport(
devtime=str(self.devtime),
battery_percentage=self.battery_percentage,
mcc=self.mcc,
zpub.send(
Bcast(
proto=proto,
+ pmod=pmod.PMODNAME,
imei=imei,
when=when,
peeraddr=peeraddr,
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
)
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
class ProtoModule:
- __name__: str
+ PMODNAME: str
class Stream:
def recv(self, segment: bytes) -> List[Union[bytes, str]]:
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(
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)
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"")
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":
KWARGS = (
("is_incoming", True),
("proto", "UNKNOWN"),
+ ("pmod", None),
("imei", None),
("when", None),
("peeraddr", None),
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):
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()
)
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()
"Respond",
)
-MODNAME = __name__.split(".")[-1]
+PMODNAME = __name__.split(".")[-1]
PROTO_PREFIX: str = "ZX:"
### Deframer ###
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,
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
]
)
- 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,