コード例 #1
0
def packet_track():
    return APRSTrack(
        packets=[
            APRSPacket.from_frame(
                "W3EAX-8>APRS,WIDE1-1,WIDE2-1,qAR,K3DO-11:!/:Gh=:j)#O   /A=026909|!Q|  /W3EAX,262,0,18'C,http://www.umd.edu",
                packet_time=pytz.timezone("America/New_York").localize(
                    datetime(2018, 11, 11, 10, 20, 13)
                ),
            ),
            APRSPacket.from_frame(
                "W3EAX-8>APRS,N3TJJ-12,WIDE1*,WIDE2-1,qAR,N3FYI-2:!/:GiD:jcwO   /A=028365|!R|  /W3EAX,267,0,18'C,"
                "http://www.umd.edu",
                packet_time=pytz.timezone("America/New_York").localize(
                    datetime(2018, 11, 11, 10, 21, 24)
                ),
            ),
            APRSPacket.from_frame(
                "W3EAX-8>APRS,KC3FIT-1,WIDE1*,WIDE2-1,qAR,KC3AWP-10:!/:JL2:u4wO   /A=043080|!j|  /W3EAX,326,0,20'C,"
                "nearspace.umd.edu",
                packet_time=pytz.timezone("America/New_York").localize(
                    datetime(2019, 2, 3, 14, 39, 28)
                ),
            ),
        ],
        callsign="W3EAX-8",
    )
コード例 #2
0
ファイル: test_packets.py プロジェクト: UMDBPP/PacketRaven
def test_index():
    packet_1 = APRSPacket.from_frame(
        "W3EAX-13>APRS,N3KTX-10*,WIDE1,WIDE2-1,qAR,N3TJJ-11:!/:J..:sh'O   /A=053614|!g|  /W3EAX,313,0,21'C,"
        "nearspace.umd.edu",
        packet_time=datetime(2019, 2, 3, 14, 36, 16),
    )
    packet_2 = APRSPacket.from_frame(
        "W3EAX-13>APRS,WIDE1-1,WIDE2-1,qAR,W4TTU:!/:JAe:tn8O   /A=046255|!i|  /W3EAX,322,0,20'C,nearspace.umd.edu",
        packet_time=datetime(2019, 2, 3, 14, 38, 23),
    )
    packet_3 = APRSPacket.from_frame(
        "W3EAX-13>APRS,KC3FIT-1,WIDE1*,WIDE2-1,qAR,KC3AWP-10:!/:JL2:u4wO   /A=043080|!j|  /W3EAX,326,0,20'C,"
        "nearspace.umd.edu",
        packet_time=datetime(2019, 2, 3, 14, 39, 28),
    )

    track = APRSTrack(packets=[packet_1, packet_2, packet_3],
                      callsign="W3EAX-13")

    assert track[0] == packet_1
    assert track[0] is packet_1
    assert track[datetime(2019, 2, 3, 14, 36, 16)] == packet_1
    assert track["2019-02-03 14:36:16"] == packet_1

    assert track["2019-02-03 14:38:00"] == packet_2

    with pytest.raises(IndexError):
        track["2019-02-03 14:30:00"]
コード例 #3
0
ファイル: test_packets.py プロジェクト: UMDBPP/PacketRaven
def test_append():
    packet_1 = APRSPacket.from_frame(
        "W3EAX-13>APRS,N3KTX-10*,WIDE1,WIDE2-1,qAR,N3TJJ-11:!/:J..:sh'O   /A=053614|!g|  /W3EAX,313,0,21'C,"
        "nearspace.umd.edu",
        packet_time=datetime(2019, 2, 3, 14, 36, 16),
    )
    packet_2 = APRSPacket.from_frame(
        "W3EAX-13>APRS,WIDE1-1,WIDE2-1,qAR,W4TTU:!/:JAe:tn8O   /A=046255|!i|  /W3EAX,322,0,20'C,nearspace.umd.edu",
        packet_time=datetime(2019, 2, 3, 14, 38, 23),
    )
    packet_3 = APRSPacket.from_frame(
        "W3EAX-8>APRS,WIDE1-1,WIDE2-1,qAR,K3DO-11:!/:Gh=:j)#O   /A=026909|!Q|  /W3EAX,262,0,18'C,http://www.umd.edu"
    )

    track = APRSTrack(callsign="W3EAX-13")

    track.append(packet_1)
    track.append(packet_2)
    with pytest.raises(ValueError):
        track.append(packet_3)

    assert track[0] is packet_1
    assert track[1] is packet_2
    assert track[-1] is packet_2
    assert track[:] == track
    assert track[1:] == APRSTrack(packets=track.packets[1:],
                                  callsign=track.callsign,
                                  crs=track.crs)
コード例 #4
0
def test_packet_database(connection, credentials):
    table_name = "test_table"

    packet_1 = APRSPacket.from_frame(
        "W3EAX-13>APRS,N3KTX-10*,WIDE1,WIDE2-1,qAR,N3TJJ-11:!/:J..:sh'O   "
        "/A=053614|!g|  /W3EAX,313,0,21'C,nearspace.umd.edu",
        packet_time=datetime(2019, 2, 3, 14, 36, 16),
    )
    packet_2 = APRSPacket.from_frame(
        "W3EAX-13>APRS,WIDE1-1,WIDE2-1,qAR,W4TTU:!/:JAe:tn8O   "
        "/A=046255|!i|  /W3EAX,322,0,20'C,nearspace.umd.edu",
        packet_time=datetime(2019, 2, 3, 14, 38, 23),
    )
    packet_3 = APRSPacket.from_frame(
        "W3EAX-13>APRS,KC3FIT-1,WIDE1*,WIDE2-1,qAR,KC3AWP-10:!/:JL2:u4wO   "
        "/A=043080|!j|  /W3EAX,326,0,20'C,nearspace.umd.edu",
        packet_time=datetime(2019, 2, 3, 14, 39, 28),
    )

    input_packets = [packet_1, packet_2, packet_3]

    with connection:
        with connection.cursor() as cursor:
            if database_has_table(cursor, table_name):
                cursor.execute(f"DROP TABLE {table_name};")

    ssh_kwargs = {}
    if credentials["tunnel"] is not None:
        ssh_kwargs["hostname"] = (credentials["tunnel"]["hostname"],)
        ssh_kwargs["username"] = (credentials["tunnel"]["username"],)
        ssh_kwargs["password"] = (credentials["tunnel"]["password"],)

    packet_table = APRSDatabaseTable(
        hostname=credentials["hostname"],
        database=credentials["database"],
        table=table_name,
        username=credentials["username"],
        password=credentials["password"],
        **ssh_kwargs,
    )
    packet_table.insert(input_packets)

    assert packet_1 == packet_table[packet_1.time, packet_1.from_callsign]

    packets = packet_table.packets

    with connection:
        with connection.cursor() as cursor:
            assert database_has_table(cursor, table_name)
            cursor.execute(f"DROP TABLE {table_name};")

    assert len(packets) > 0 and all(
        packets[packet_index] == input_packets[packet_index]
        for packet_index in range(len(packets))
    )
コード例 #5
0
ファイル: test_packets.py プロジェクト: UMDBPP/PacketRaven
def test_time_to_ground():
    packet_1 = APRSPacket.from_frame(
        "W3EAX-13>APRS,N3KTX-10*,WIDE1,WIDE2-1,qAR,N3TJJ-11:!/:J..:sh'O   /A=053614|!g|  /W3EAX,313,0,21'C,"
        "nearspace.umd.edu",
        packet_time=datetime(2019, 2, 3, 14, 36, 16),
    )
    packet_2 = APRSPacket.from_frame(
        "W3EAX-13>APRS,WIDE1-1,WIDE2-1,qAR,W4TTU:!/:JAe:tn8O   /A=046255|!i|  /W3EAX,322,0,20'C,nearspace.umd.edu",
        packet_time=datetime(2019, 2, 3, 14, 38, 23),
    )
    packet_3 = APRSPacket.from_frame(
        "W3EAX-13>APRS,N3KTX-10*,WIDE1,WIDE2-1,qAR,N3TJJ-11:!/:J..:sh'O   /A=063614|!g|  /W3EAX,313,0,21'C,"
        "nearspace.umd.edu",
        packet_time=datetime(2019, 2, 3, 14, 39, 28),
    )
    packet_4 = APRSPacket.from_frame(
        "W3EAX-13>APRS,KC3FIT-1,WIDE1*,WIDE2-1,qAR,KC3AWP-10:!/:JL2:u4wO   /A=043080|!j|  /W3EAX,326,0,20'C,"
        "nearspace.umd.edu",
        packet_time=datetime(2019, 2, 3, 14, 41, 50),
    )
    packet_5 = APRSPacket.from_frame(
        "W3EAX-13>APRS,N3KTX-10*,WIDE1,WIDE2-1,qAR,N3TJJ-11:!/:J..:sh'O   /A=063614|!g|  /W3EAX,313,0,21'C,"
        "nearspace.umd.edu",
        packet_time=datetime(2019, 2, 3, 14, 42, 34),
    )

    track = APRSTrack(callsign="W3EAX-13")

    track.append(packet_1)

    assert not track.falling
    assert track.time_to_ground == timedelta(seconds=-1)

    track.append(packet_2)

    assert track.falling
    assert track.time_to_ground == timedelta(seconds=1603.148748)

    track.append(packet_3)

    assert not track.falling
    assert track.time_to_ground == timedelta(seconds=-1)

    track.append(packet_4)
    track.append(packet_5)

    assert not track.falling
    assert track.time_to_ground == timedelta(seconds=297.913704)
コード例 #6
0
ファイル: test_packets.py プロジェクト: UMDBPP/PacketRaven
def test_subtraction():
    packet_1 = APRSPacket.from_frame(
        "W3EAX-13>APRS,N3KTX-10*,WIDE1,WIDE2-1,qAR,N3TJJ-11:!/:J..:sh'O   /A=053614|!g|  /W3EAX,313,0,21'C,"
        "nearspace.umd.edu",
        packet_time=datetime(2019, 2, 3, 14, 36, 16),
    )
    packet_2 = APRSPacket.from_frame(
        "W3EAX-13>APRS,WIDE1-1,WIDE2-1,qAR,W4TTU:!/:JAe:tn8O   /A=046255|!i|  /W3EAX,322,0,20'C,nearspace.umd.edu",
        packet_time=datetime(2019, 2, 3, 14, 38, 23),
    )

    packet_delta = packet_2 - packet_1

    assert packet_delta.seconds == 127
    assert numpy.allclose(packet_delta.ascent, -2243.0231999999996)
    assert numpy.allclose(packet_delta.overground, 4019.3334763155167)
コード例 #7
0
 def add_frames(frame: str):
     try:
         packet = APRSPacket.from_frame(frame)
         if packet.from_callsign in self.callsigns and packet not in packets:
             packets.append(packet)
     except InvalidPacketError:
         pass
コード例 #8
0
    def packets(self) -> List[APRSPacket]:
        if self.__last_access_time is not None and self.interval is not None:
            interval = datetime.now() - self.__last_access_time
            if interval < self.interval:
                raise TimeIntervalError(
                    f"interval {interval} less than minimum interval {self.interval}"
                )

        packets = []
        for record in self.records:
            record = {
                field if field in ["time", "x", "y", "z"] else field.replace(
                    "packet_", ""): value
                for field, value in record.items() if field not in ["point"]
            }
            record["from_callsign"] = record["from"]
            del record["from"]
            if "to" in record:
                record["to_callsign"] = record["to"]
                del record["to"]
            else:
                record["to"] = None
            if record["source"] is None:
                record["source"] = self.location
            packets.append(APRSPacket(**record))

        self.__last_access_time = datetime.now()
        return packets
コード例 #9
0
    def from_file(cls, filename: PathLike) -> List["APRSTrack"]:
        tracks = LocationPacketTrack.from_file(filename)

        for index in range(len(tracks)):
            track = tracks[index]
            packets = []
            for packet in track.packets:
                packets.append(
                    APRSPacket(
                        from_callsign=packet.attributes["from"],
                        to_callsign=packet.attributes["to"],
                        time=packet.time,
                        x=packet.coordinates[0],
                        y=packet.coordinates[1],
                        z=packet.coordinates[2],
                        **{
                            key: value
                            for key, value in packet.attributes.items()
                            if key not in ["from", "to"]
                        },
                    ))
            tracks[index] = APRSTrack(packets=packets,
                                      crs=track.crs,
                                      **track.attributes)

        return tracks
コード例 #10
0
ファイル: test_packets.py プロジェクト: UMDBPP/PacketRaven
def test_values():
    packet_1 = APRSPacket.from_frame(
        "W3EAX-13>APRS,N3KTX-10*,WIDE1,WIDE2-1,qAR,N3TJJ-11:!/:J..:sh'O   /A=053614|!g|  /W3EAX,313,0,21'C,"
        "nearspace.umd.edu",
        packet_time=datetime(2019, 2, 3, 14, 36, 16),
    )

    track = APRSTrack(packets=[packet_1], callsign="W3EAX-13")

    assert numpy.all(track.coordinates[-1] == packet_1.coordinates)
コード例 #11
0
ファイル: test_packets.py プロジェクト: UMDBPP/PacketRaven
def test_sorting():
    packet_1 = APRSPacket.from_frame(
        "W3EAX-13>APRS,N3KTX-10*,WIDE1,WIDE2-1,qAR,N3TJJ-11:!/:J..:sh'O   /A=053614|!g|  /W3EAX,313,0,21'C,"
        "nearspace.umd.edu",
        packet_time=datetime(2019, 2, 3, 14, 36, 16),
    )
    packet_2 = APRSPacket.from_frame(
        "W3EAX-13>APRS,WIDE1-1,WIDE2-1,qAR,W4TTU:!/:JAe:tn8O   /A=046255|!i|  /W3EAX,322,0,20'C,nearspace.umd.edu",
        packet_time=datetime(2019, 2, 3, 14, 38, 23),
    )
    packet_3 = APRSPacket.from_frame(
        "W3EAX-13>APRS,KC3FIT-1,WIDE1*,WIDE2-1,qAR,KC3AWP-10:!/:JL2:u4wO   /A=043080|!j|  /W3EAX,326,0,20'C,"
        "nearspace.umd.edu",
        packet_time=datetime(2019, 2, 3, 14, 39, 28),
    )

    track = APRSTrack(packets=[packet_2, packet_1, packet_3],
                      callsign="W3EAX-13")

    assert sorted(track) == [packet_1, packet_2, packet_3]
コード例 #12
0
ファイル: test_packets.py プロジェクト: UMDBPP/PacketRaven
def test_from_frame():
    packet_1 = APRSPacket.from_frame(
        "W3EAX-13>APRS,N3KTX-10*,WIDE1,WIDE2-1,qAR,N3TJJ-11:!/:J..:sh'O   /A=053614|!g|  /W3EAX,313,0,21'C,"
        "nearspace.umd.edu",
        packet_time=datetime(2019, 2, 3, 14, 36, 16),
    )

    assert numpy.allclose(packet_1.coordinates,
                          (-77.48778502911327, 39.64903419561805, 16341.5472))
    assert packet_1["callsign"] == packet_1["from"]
    assert packet_1["callsign"] == "W3EAX-13"
    assert packet_1["comment"] == "|!g|  /W3EAX,313,0,21'C,nearspace.umd.edu"
コード例 #13
0
ファイル: test_packets.py プロジェクト: UMDBPP/PacketRaven
def test_equality():
    packet_1 = APRSPacket.from_frame(
        "W3EAX-13>APRS,N3KTX-10*,WIDE1,WIDE2-1,qAR,N3TJJ-11:!/:J..:sh'O   /A=053614|!g|  /W3EAX,313,0,21'C,"
        "nearspace.umd.edu",
        packet_time=datetime(2019, 2, 3, 14, 36, 16),
    )
    packet_2 = APRSPacket.from_frame(
        "W3EAX-13>APRS,WIDE1-1,WIDE2-1,qAR,W4TTU:!/:JAe:tn8O   /A=046255|!i|  /W3EAX,322,0,20'C,nearspace.umd.edu",
        packet_time=datetime(2019, 2, 3, 14, 38, 23),
    )
    packet_3 = APRSPacket.from_frame(
        "W3EAX-13>APRS,N3KTX-10*,WIDE1,WIDE2-1,qAR,N3TJJ-11:!/:J..:sh'O   /A=053614|!g|  /W3EAX,313,0,21'C,"
        "nearspace.umd.edu",
        packet_time=datetime(2019, 2, 3, 14, 38, 23),
    )
    packet_4 = APRSPacket.from_frame(
        "W3EAX-13>APRS,WIDE1-1,WIDE2-1,qAR,W4TTU:!/:JAe:tn8O   /A=046255|!i|  /W3EAX,322,0,20'C,nearspace.umd.edu",
        packet_time=datetime(2019, 2, 3, 14, 36, 16),
    )

    assert packet_2 != packet_1
    assert packet_3 == packet_1
    assert packet_4 != packet_1
コード例 #14
0
    def packets(self) -> List[LocationPacket]:
        if self.__last_access_time is not None and self.interval is not None:
            interval = datetime.now() - self.__last_access_time
            if interval < self.interval:
                raise TimeIntervalError(
                    f"interval {interval} less than minimum interval {self.interval}"
                )

        if Path(self.location).exists():
            with open(Path(
                    self.location).expanduser().resolve()) as file_connection:
                features = geojson.load(file_connection)
        else:
            response = requests.get(self.location, stream=True)
            features = geojson.loads(response.text)

        packets = []
        for feature in features["features"]:
            if feature["geometry"]["type"] == "Point":
                properties = feature["properties"]
                time = typepigeon.convert_value(properties["time"], datetime)
                del properties["time"]

                if "from" in properties:
                    from_callsign = properties["from"]
                    to_callsign = properties["to"]
                    del properties["from"], properties["to"]

                    packet = APRSPacket(
                        from_callsign,
                        to_callsign,
                        time,
                        *feature["geometry"]["coordinates"],
                        source=self.location,
                        **properties,
                    )
                else:
                    packet = LocationPacket(
                        time,
                        *feature["geometry"]["coordinates"],
                        source=self.location,
                        **properties,
                    )

                packets.append(packet)

        self.__last_access_time = datetime.now()

        return packets
コード例 #15
0
    def packets(self) -> List[APRSPacket]:
        if self.__last_access_time is not None and self.interval is not None:
            interval = datetime.now() - self.__last_access_time
            if interval < self.interval:
                raise TimeIntervalError(
                    f"interval {interval} less than minimum interval {self.interval}"
                )

        if Path(self.location).exists():
            file_connection = open(Path(self.location).expanduser().resolve())
            lines = file_connection.readlines()
        else:
            file_connection = requests.get(self.location, stream=True)
            lines = file_connection.iter_lines()

        packets = []
        for line in lines:
            if len(line) > 0:
                if isinstance(line, bytes):
                    line = line.decode()
                if line not in self.__parsed_lines:
                    self.__parsed_lines.append(line)
                    try:
                        packet_time, raw_aprs = line.split(": ", 1)
                        packet_time = typepigeon.convert_value(
                            packet_time, datetime)
                    except:
                        raw_aprs = line
                        packet_time = datetime.now()
                    raw_aprs = raw_aprs.strip()
                    try:
                        packets.append(
                            APRSPacket.from_frame(raw_aprs,
                                                  packet_time,
                                                  source=self.location))
                    except Exception as error:
                        logging.debug(f"{error.__class__.__name__} - {error}")

        file_connection.close()

        if self.callsigns is not None:
            packets = [
                packet for packet in packets
                if packet.from_callsign in self.callsigns
            ]
        self.__last_access_time = datetime.now()

        return packets
コード例 #16
0
 def __getitem__(self, key: (datetime, str)) -> APRSPacket:
     packet = PacketDatabaseTable.__getitem__(self, key)
     attributes = packet.attributes
     from_callsign = attributes["from"]
     del attributes["from"]
     if "to" in attributes:
         to_callsign = attributes["to"]
         del attributes["to"]
     else:
         to_callsign = None
     return APRSPacket(
         from_callsign,
         to_callsign,
         packet.time,
         *packet.coordinates,
         packet.crs,
         **attributes,
     )
コード例 #17
0
ファイル: serial.py プロジェクト: UMDBPP/PacketRaven
 def packets(self) -> List[APRSPacket]:
     if self.__last_access_time is not None and self.interval is not None:
         interval = datetime.now() - self.__last_access_time
         if interval < self.interval:
             raise TimeIntervalError(
                 f"interval {interval} less than minimum interval {self.interval}"
             )
     packets = []
     for line in self.serial_connection.readlines():
         try:
             packet = APRSPacket.from_frame(line, source=self.location)
             packets.append(packet)
         except Exception as error:
             logging.error(f"{error.__class__.__name__} - {error}")
     if self.callsigns is not None:
         packets = [
             packet for packet in packets if packet.from_callsign in self.callsigns
         ]
     self.__last_access_time = datetime.now()
     return packets
コード例 #18
0
    def send(self, packets: List[APRSPacket]):
        if not isinstance(packets, Sequence) or isinstance(packets, str):
            packets = [packets]
        packets = [
            packet
            if not isinstance(packet, str) else APRSPacket.from_frame(packet)
            for packet in packets
        ]

        if len(self.__send_buffer) > 0:
            packets.extend(self.__send_buffer)
            self.__send_buffer.clear()

        callsigns = {packet.from_callsign for packet in packets}
        packets = {
            callsign:
            [packet for packet in packets if packet.from_callsign == callsign]
            for callsign in callsigns
        }

        if len(packets) > 0:
            logging.info(
                f"sending {len(packets)} packet(s) to {self.location}: {packets}"
            )
            for callsign, callsign_packets in packets.items():
                try:
                    frames = [packet.frame for packet in callsign_packets]
                    aprs_is = aprslib.IS(callsign, aprslib.passcode(callsign),
                                         self.hostname, self.port)
                    aprs_is.connect()
                    if len(frames) > 0:
                        aprs_is.sendall(r"\rn".join(frames))
                    aprs_is.close()
                except ConnectionError as error:
                    logging.info(
                        f"could not send packet(s) ({error}); reattempting on next iteration",
                    )
                    self.__send_buffer.extend(packets)
コード例 #19
0
    def packets(self) -> List[APRSPacket]:
        if self.__last_access_time is not None and self.interval is not None:
            interval = datetime.now() - self.__last_access_time
            if interval < self.interval:
                raise TimeIntervalError(
                    f"interval {interval} less than minimum interval {self.interval}"
                )

        query = {
            "name": ",".join(self.callsigns),
            "what": "loc",
            "apikey": self.api_key,
            "format": "json",
            "timerange": int(timedelta(days=1) / timedelta(seconds=1)),
            "tail": int(timedelta(days=1) / timedelta(seconds=1)),
        }

        query = "&".join(f"{key}={value}" for key, value in query.items())
        response = self.request_with_backoff(f"{self.location}?{query}")

        packets = []
        if response["result"] == "ok":
            for packet_candidate in response["entries"]:
                try:
                    packet = APRSPacket.from_frame(packet_candidate,
                                                   source=self.location)
                    packets.append(packet)
                except Exception as error:
                    logging.error(f"{error.__class__.__name__} - {error}")
        else:
            logging.warning(
                f'query failure "{response["code"]}: {response["description"]}"'
            )

        self.__last_access_time = datetime.now()
        return packets