]> www.average.org Git - loctrkd.git/blob - gps303/termconfig.py
Multiprotocol support in zmq messages and storage
[loctrkd.git] / gps303 / termconfig.py
1 """ For when responding to the terminal is not trivial """
2
3 from configparser import ConfigParser
4 from datetime import datetime, timezone
5 from logging import getLogger
6 from struct import pack
7 import zmq
8
9 from . import common
10 from .gps303proto import *
11 from .zmsg import Bcast, Resp, topic
12
13 log = getLogger("gps303/termconfig")
14
15
16 def runserver(conf: ConfigParser) -> None:
17     # Is this https://github.com/zeromq/pyzmq/issues/1627 still not fixed?!
18     zctx = zmq.Context()  # type: ignore
19     zsub = zctx.socket(zmq.SUB)  # type: ignore
20     zsub.connect(conf.get("collector", "publishurl"))
21     for proto in (
22         proto_name(STATUS),
23         proto_name(SETUP),
24         proto_name(POSITION_UPLOAD_INTERVAL),
25     ):
26         zsub.setsockopt(zmq.SUBSCRIBE, topic(proto))
27     zpush = zctx.socket(zmq.PUSH)  # type: ignore
28     zpush.connect(conf.get("collector", "listenurl"))
29
30     try:
31         while True:
32             zmsg = Bcast(zsub.recv())
33             msg = parse_message(zmsg.packet)
34             log.debug(
35                 "IMEI %s from %s at %s: %s",
36                 zmsg.imei,
37                 zmsg.peeraddr,
38                 datetime.fromtimestamp(zmsg.when).astimezone(tz=timezone.utc),
39                 msg,
40             )
41             if msg.RESPOND is not Respond.EXT:
42                 log.error(
43                     "%s does not expect externally provided response", msg
44                 )
45             if zmsg.imei is not None and conf.has_section(zmsg.imei):
46                 termconfig = common.normconf(conf[zmsg.imei])
47             elif conf.has_section("termconfig"):
48                 termconfig = common.normconf(conf["termconfig"])
49             else:
50                 termconfig = {}
51             kwargs = {}
52             if isinstance(msg, STATUS):
53                 kwargs = {
54                     "upload_interval": termconfig.get(
55                         "statusintervalminutes", 25
56                     )
57                 }
58             elif isinstance(msg, SETUP):
59                 for key in (
60                     "uploadintervalseconds",
61                     "binaryswitch",
62                     "alarms",
63                     "dndtimeswitch",
64                     "dndtimes",
65                     "gpstimeswitch",
66                     "gpstimestart",
67                     "gpstimestop",
68                     "phonenumbers",
69                 ):
70                     if key in termconfig:
71                         kwargs[key] = termconfig[key]
72             resp = Resp(
73                 imei=zmsg.imei, when=zmsg.when, packet=msg.Out(**kwargs).packed
74             )
75             log.debug("Response: %s", resp)
76             zpush.send(resp.packed)
77
78     except KeyboardInterrupt:
79         zsub.close()
80         zpush.close()
81         zctx.destroy()  # type: ignore
82
83
84 if __name__.endswith("__main__"):
85     runserver(common.init(log))