Is2axudp.py: Unterschied zwischen den Versionen

Aus DXL-Wiki
Zur Navigation springen Zur Suche springen
 
(24 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
== Beschreibung ==
== Beschreibung ==


is2axudp.py ist ein Python3 Skript, um Pakete im APRS-IS Protokoll per TCP anzunehmen und in AXUDP Pakete zu wandeln. Dies ermöglicht es beispielsweise Daten einer Wetterstation mit CWOP Report (z.B. WeeWX) direkt per HF über APRS abzustrahlen, anstatt die Daten nur über das Internet an einen APRS-Server zu übermitteln. Selbstverständlich lassen sich so auch andere Daten das im APRS-IS Protokoll
is2axudp.py ist ein Python3 Skript, um Pakete im APRS-IS Protokoll entgegenzunehmen und in das AXUDP Format zu wandeln. Dies ermöglicht es beispielsweise Daten einer Wetterstation mit CWOP Report (z.B. [https://www.weewx.org WeeWX]) direkt per HF über APRS abzustrahlen, anstatt die Daten nur über das Internet an einen APRS-Server zu übermitteln. Selbstverständlich lassen sich so auch andere Daten aus dem APRS-IS Protokoll in AXUDP wandeln.


Anwendungszwecke:
Anwendungszwecke:
* Abstrahlung der Daten direkt lokal über HF
* Abstrahlung der Daten direkt lokal über HF (z.B. mit [[udpflex]] und einem TNC).
* Abstrahlung der Daten über einen entfernten APRS-Digipeater mit dxlAPRS Software
* Abstrahlung der Daten über einen entfernten APRS-Digipeater mit dxlAPRS Software.
 
== Technisches zu is2axudp.py ==
 
* Das Skript besteht aus zwei Teilen. Zum einen das Skript wx.py von Chris OE5DXL und zum anderen das Skript is2axudp.py von Matze DM4TZE.
* Beide Dateien müssen im gleichen Ordner liegen.
* Zum Ausführen wird python3 benötigt. Falls es noch nicht installiert ist, kann es auf Debian und kompatiblen Systemen (RaspberryPi, Ubuntu, Mint etc.) mit >> sudo apt-get install python3 << nachinstalliert werden.
* Das Skript kann gestartet werden mit dem Befehl >> python3 is2axudp.py <<. Alternativ kann man die python Datei auch mit >> chmod 755 << ausführbar gemacht und anschließend direkt mit ./is2axudp.py gestartet werden.
 
== Installation ==
is2axudp.py liegt in einem Github Repository und kann wie folgt geladen werden:
 
<nowiki>git clone https://github.com/dl1nux/is2axudp.git</nowiki>


== Funktionsweise ==
== Funktionsweise ==
Zeile 32: Zeile 44:
Das somit erzeugte AXUDP Paket kann an alle kompatiblen Tools der dxlAPRS Toolchain ([[udpflex]], [[afskmodem]], [[udpbox]] usw.) zur Weiterverarbeitung übergeben werden.
Das somit erzeugte AXUDP Paket kann an alle kompatiblen Tools der dxlAPRS Toolchain ([[udpflex]], [[afskmodem]], [[udpbox]] usw.) zur Weiterverarbeitung übergeben werden.


=== Lokale Aussendung am gleichen Standort ===
== Wie WeeWX eingestellt werden muss ==
 
In der WeeWX Konfiguration muss der sogenannte "CWOP" Report aktiviert werden. "CWOP" steht dabei nicht für den "Telegrafie-Operator", sondern für "[https://de.wikipedia.org/wiki/Citizen_Weather_Observer_Program Citizen Weather Observer Program]".
 
Die WeeWX Konfigurationsdatei liegt gewöhnlicherweise hier /etc/weewx/weewx.conf. Der Ort kann aber auch abweichen bei manueller Installation. Siehe auch [http://weewx.com/docs/usersguide.htm#Where_to_find_things WeeWX Doku].
<nowiki>
[StdRESTful]


Wenn die Wetterdaten vom gleichen Standort wie die Wetterstaton abgestrahlt wird, kann das Skript ohne Änderung verwendet werden. Es sind lediglich der gewünschte TCP Port einzutragen (Standard = 1234) sowie das AXUDP-Ziel (IP-Adresse und Port). Das Paket wird dann 1:1 ausgesendet.
    [[CWOP]]
        # This section is for configuring posts to CWOP.
 
        # If you wish to do this, set the option 'enable' to true,
        # and specify the station ID (e.g., CW1234).
        enable = true
        station = MYCALL-15
 
        # If this is an APRS (radio amateur) station, uncomment
        # the following and replace with a passcode (e.g., 12345).
        #passcode = 12345
        server_list = 127.0.0.1:1234, rotate.aprs2.net:14580
        log_success = true
        log_failure = true
</nowiki>
* "enable" muss auf "true" geändert werden.
* Unter "station" gibt man das eigene Rufzeichen mit SSID an, unter dem die Wetterstation die Daten veröffentlichen soll.
* Einen Passcode muss man für is2axudp.py nicht zwingend eintragen (von is2axudp.py wird es ignoriert). Es wird aber empfohlen falls es einen Fallback auf einen anderen APRS-Server gibt (z.B. is2axudp.py beendet sich), dann verbindet sich WeeWX wie in diesem Beispiel mit dem nächsten gelisteten Server "rotate.aprs2.net".
* Unter server_list gibt man IP-Adresse:Port des TCP Servers an, wo is2axudp.py läuft. Es ist empfehlenswert is2axudp direkt auf dem selben Rechner (127.0.0.1) wie WeeWX laufen zu lassen. Es kann aber auch wo anders laufen. Es können mit Kommas getrennt mehrere Server eingetragen werden. Sobald einer nicht erreichbar ist, wird der nächste angewählt.
* log_success und log_failure sind nicht zwingend notwendig, hinterlassen aber einen Eintrag in /var/log/syslog ob erfolgreich oder nicht übermittelt wurde.
 
== Direkte lokale Aussendung am gleichen Standort ==
 
Wenn die Wetterdaten vom gleichen Standort wie die Wetterstaton abgestrahlt wird, kann das Skript mit nur kleinen Anpassungen verwendet werden. Es sind lediglich bei Bedarf ein abweichender TCP Port einzutragen (Standard = 1234) sowie das AXUDP-Ziel (IP-Adresse und Port). Das Paket wird dann 1:1 ausgesendet.


Änderungen am Skript:
Änderungen am Skript:


TCP Port Eingang (Standard 1234):
TCP Port Eingang falls anders gewünscht (Standard = 1234):
  <nowiki>serversocket.bind(("0.0.0.0", 1234))</nowiki>
  <nowiki>serversocket.bind(("0.0.0.0", 1234))</nowiki>


AXDUP Ausgang (Standard = IP 127.0.0.1 und Port 9032):
AXUDP Ausgang (Standard = IP 127.0.0.1 und Port 9032):
  <nowiki>sendax(data,("127.0.0.1",9032),{})</nowiki>
  <nowiki>sendax(data,("127.0.0.1",9032),{})</nowiki>
Auf Port 9032 muss dann der Sender "hören", z.B. [[udpflex]] mit einem angeschlossenen TNC. Beispielkonfiguration von [[udpflex]]:
<nowiki>udpflex -t /dev/ttyUSB0:38400 -k -d 5000 -p 1:15 -p 2:255 -p 3:10 -p 128:0 -U 127.0.0.1:0:9032 -u -V</nowiki>


Aussendung nach dem Durchlaufen des Skripts:
Aussendung nach dem Durchlaufen des Skripts:
Zeile 48: Zeile 93:


Das Paket kann von allen Stationen in HF-Reichweite gelesen werden. Wenn ein iGate unter den Empfängern ist, erscheint die Aussendung auch auf aprs.fi & Co.
Das Paket kann von allen Stationen in HF-Reichweite gelesen werden. Wenn ein iGate unter den Empfängern ist, erscheint die Aussendung auch auf aprs.fi & Co.
Möchte man, dass das Paket ggf. noch digipeatet wird, muss man noch den APRS-Pfad durch ein z.B. WIDE1-1 erweitern. Dies geschieht recht einfach im "replace" Abschnitt der is2axudp.py. Anstatt dass ",TCPIP*" durch "nichts" ersetzt wird (quasi entfernt), kann man auch einen anderen String einfügen. Es muss aber immer ein "," (Komma - ohne Anführungszeichen) dem Pfad vorangestellt werden.
Möchte man, dass das Paket ggf. noch digipeatet wird, muss man noch den APRS-Pfad durch einen WIDE-Pfad erweitern, z.B. WIDE1-1. Dies geschieht recht einfach im "replace" Abschnitt der is2axudp.py. Anstatt dass ",TCPIP*" durch "nichts" ersetzt wird (quasi entfernt), kann man auch einen anderen Wert einfügen. Es muss aber immer ein "," (Komma - ohne Anführungszeichen) dem Pfad vorangestellt werden.


Original:
Original:
Zeile 59: Zeile 104:
  <nowiki>DL1NUX-14>APRS,WIDE1-1:@182025z5013.81N/01059.43E_000/002g004t035r001p009P009b10250h81.weewx-4.2.0-FineOffsetUSB</nowiki>
  <nowiki>DL1NUX-14>APRS,WIDE1-1:@182025z5013.81N/01059.43E_000/002g004t035r001p009P009b10250h81.weewx-4.2.0-FineOffsetUSB</nowiki>


=== Aussendung an einem entfernten Standort ===
== Aussendung an einem entfernten Standort ==


Wenn man die Daten der Wetterstation nicht am gleichen Standort sondern entfernt abstrahlen möchte, z.B. beim nächsten Digipeater, muss ein wenig mehr beachtet werden.
Wenn man die Daten der Wetterstation nicht am gleichen Standort sondern entfernt abstrahlen möchte, z.B. beim nächsten Digipeater, muss ein wenig mehr beachtet werden.


* Die Pakete der Wetterstation sollten nicht "direkt" eins-zu-eins ausgesendet werden. Heißt die Wetterstation z.B. DL1NUX-14 und der Digi DB0NU-10, würde eine eins-zu-eins Abstrahlung allen Empfänger der Aussendung vortäuschen, dass DL1NUX-14 direkt empfangen wurde. Das stimmt aber nicht, da sich DL1NUX-14 gar nicht am Standort von DB0NU befindet. Das "Relais" würde quasi mit dem "falschen Rufzeichen" seine Aussendung machen. Korrekter wäre, wenn der APRS-Digipeater die Aussendung auch als gedigipeatertes paket abstrahlen würde. Also so, als wenn es DL1NUX-14 über HF empfangen hätte und nun digipeaten würde.
* Die Pakete der Wetterstation sollten nicht "direkt" eins-zu-eins ausgesendet werden.
* Heißt die Wetterstation z.B. DL1NUX-14 und der Digi DB0NU-10, würde eine eins-zu-eins Abstrahlung allen Empfänger der Aussendung vortäuschen, dass DL1NUX-14 direkt empfangen wurde. Das stimmt aber nicht, da sich DL1NUX-14 gar nicht am Standort von DB0NU befindet. Das "Relais" würde quasi mit dem "falschen Rufzeichen" seine Aussendung machen.  
* Korrekter wäre es, wenn der APRS-Digipeater die Aussendung auch als gedigipeatertes Paket abstrahlen würde. Also so, als wenn DB0NU-10 DL1NUX-14 über HF empfangen hätte und nun digipeaten würde.


Paket wird durch is2axudp.py empfangen:
Beispiel:
 
Folgendes Paket wird durch is2axudp.py empfangen:
  <nowiki>DL1NUX-14>APRS,TCPIP*:@182205z5013.81N/01059.43E_341/002g006t035r001p011P011b10242h81.weewx-4.2.0-FineOffsetUSB</nowiki>
  <nowiki>DL1NUX-14>APRS,TCPIP*:@182205z5013.81N/01059.43E_341/002g006t035r001p011P011b10242h81.weewx-4.2.0-FineOffsetUSB</nowiki>


Paket wird von is2axudp.py umgewandelt und ein WIDE1-1 Pfad angehängt:
Das Paket wird von is2axudp.py in AXUDP umgewandelt und es wird ein WIDE1-1 Pfad angehängt:
  <nowiki>DL1NUX-14>APRS,WIDE1-1:@182205z5013.81N/01059.43E_341/002g006t035r001p011P011b10242h81.weewx-4.2.0-FineOffsetUSB</nowiki>
  <nowiki>DL1NUX-14>APRS,WIDE1-1:@182205z5013.81N/01059.43E_341/002g006t035r001p011P011b10242h81.weewx-4.2.0-FineOffsetUSB</nowiki>


Paket wird von DB0NU-10 korrekt auf HF abgestrahlt:
Paket wird wie folgt von DB0NU-10 auf HF abgestrahlt:
  <nowiki>DL1NUX-14>APRS,DB0NU-10*:@182205z5013.81N/01059.43E_341/002g006t035r001p011P011b10242h81.weewx-4.2.0-FineOffsetUSB</nowiki>
  <nowiki>DL1NUX-14>APRS,DB0NU-10*:@182205z5013.81N/01059.43E_341/002g006t035r001p011P011b10242h81.weewx-4.2.0-FineOffsetUSB</nowiki>


Zeile 79: Zeile 128:
# Als Pfad wird WIDE1-1 angehängt (String = ",WIDE1-1"), damit der Digipeater ([[udpbox]]) weiß, dass er es digipeaten soll.
# Als Pfad wird WIDE1-1 angehängt (String = ",WIDE1-1"), damit der Digipeater ([[udpbox]]) weiß, dass er es digipeaten soll.
# Anschließend wird das Paket im AXUDP Format an den Digipeater gesandt.
# Anschließend wird das Paket im AXUDP Format an den Digipeater gesandt.
# Der Digipeater "empfängt" das Paket über AXUDP, erkennt anhand des "WIDE1-1" dass es das Paket digipeaten soll.
# Der Digipeater [[udpbox]] "empfängt" das Paket über AXUDP, erkennt anhand des "WIDE1-1" dass es das Paket digipeaten soll.
# Das Paket wird von DB0NU-10 abgestrahlt und korrekterweise das H-Bit "*" an das eigene Call angehängt. Dadurch weiß jede Station, die das Paket empfängt, dass die Aussendung indirekt von DB0NU-10 stammt, und nicht direkt von Dl1NUX-14.
# Das Paket wird von DB0NU-10 abgestrahlt und korrekterweise das H-Bit "*" an das eigene Call angehängt. Dadurch weiß jede Station, die das Paket empfängt, dass die Aussendung indirekt von DB0NU-10 stammt, und nicht direkt von DL1NUX-14. Das WIDE1-1 wird in diesem Fall entfernt, da der Hop aus WIDE1-1 "verbraucht" ist.
# Würde man wollen, dass noch weitere Digis das Paket digipeaten sollen, kann man auch das WIDE erweitern auf WIDE2-2, oder WIDE1-1,WIDE2-1 usw. Es ist jede Kombination denkbar. Hierbei sollte man aber sparsam sein. Es sollte maximal bis zum nächsten iGate "getragen" werden. Um es weiter digipeaten zu können, muss der Digipeater bei der [[udpbox]] mindestens die Digipeater-Parameter -p4,6 haben, sonst wird der Pfad ggf. abgeschnitten und/oder gänzlich ignoriert.


Das Digipeating übernimmt die [[udpbox]]. Dazu gibt es mehrere technische Lösungen:
Das eigentliche Digipeating übernimmt die [[udpbox]]. Dazu gibt es mehrere technische Lösungen:
* Senden des AXUDP Paketes an den Listenport des vorhandenen Digipeaters
 
** Dieser muss aber auf die entfernte IP-Adresse hören. Meist hört die [[udpbox]] nur auf "127.0.0.1", damit werden Paket von entfernten Stationen nicht angenommen.
=== Senden des AXUDP Paketes an den Listen-Port des vorhandenen Digipeaters ===
** Die quick-and-dirty Lösung wäre die [[udpbox]] auf der Ip 0.0.0.0 hören zu lassen. Dadurch werden jedoch alle Pakete von allen IPs entgegen genommen. Es könnte also der Digi von Fremden "mißbraucht" werden, sollte die udpbox frei zugänglich sein (z.B. im Hamnet)
* Der [[udpbox]] Digipeater kann entweder nur auf einer Quell-IP hören (z.B. 127.0.0.1) oder auf alle (0.0.0.0).
* Senden des AXUDP Paketes an eine eigene Chain im vorhandenen udpbox
* Auf alle IPs zu hören ist unsicher, das könnte missbraucht werden.
** Man ergänzt die vorhandene [[udpbox]] um eine weitere chain für für die Übermittlung der Daten von der einen Wetterstation und setzt alle Digipeating-Optionen nach Wunsch erneut.  
* Auch wenn man is2axudp.py, [[udpflex]] und [[udpbox] auf dem selben Rechner laufen lässt, ist es gefährlich. Der TCP Server könnte ebenfalls mit fremden Daten gespeist werden, die dann zur Aussendung kommen.
** Der Vorteil daran ist, dass Daten nur von dieser einen Gegenstelle angenommen werden. Ein Mißbrauch ist unwahrscheinlich.
* Aber Achtung: Wer weiß dass dort ein TCP-Server läuft, könnte auch auch diesem Weg Daten direkt an is2axudp.py zuführen.
** Außerdem kann man bei Bedarf mit zusätzlichen Filtereinstellungen am Digi in der [[udpbox]] weitereren möglichen Mißbrauch einschränken.
* Diese Variante ist also eher nicht zu empfehlen, egal wie, da zu Risikoreich.
* Senden des AXUDP Paketes an eine zusätzliche Instanz von [[udpbox]]
 
** Die [[udpbox]] kann auch als zusätzlicher Prozess gestartet werden, auch mit dem selben Call wie im anderen Prozess.
Beispiel am Digi mit allen drei Programmen auf dem selben Rechner:
 
<nowiki>
is2axudp:
AXUDP Ziel = IP 127.0.0.1 Port 9001
 
TNC KISS Verbindung: 
udpflex -t /dev/ttyUSB0:38400 -k -d 5000 -p 1:15 -p 2:255 -p 3:10 -p 128:0 -U 127.0.0.1:9001:9032 -u -V
 
Digipeater:
udpbox -R 127.0.0.1:9001 -l 127.0.0.1:9101 -d DB0XYZ-10 -p 0,1,2,4,5,6,7,8,9 -t 1740,28 -f p28,29,33,35-39,41-43,46,47,58,59,61,64,91,95,96,123 -k 0/0/20000 -b 600:/home/pi/dxlAPRS/aprs/digibeacon.txt -x APLWS*,NOCALL -l 127.0.0.1:9032 -v
</nowiki>
 
Erklärung:
* Das TNC empfängt auf UDP 9032 alle Daten (listen port) die es Aussenden soll und sendet seine empfangenen Daten an UDP 9001 (destination port) am gleichen Rechner.
* Die RX Chain UDP 9001 wird in der [[udpbox]] nach UDP 9101 kopiert zum iGate [[udpgate4]] ...
* ... dann wird der Digipeater DB0XYZ-10 akiviert mit diversen Filteroptionen und einer HF-Bake ...
* ... und anschließend wird das, was durch den Digipeater gelaufen ist und "hinten raus" kommt an UDP 9032 gesendet - das ist der Port wo der TNC seine auszusendenden Daten erhält.
* Die Daten von WeeWX werden über TCP in is2axudp.py eingespielt, in AXUDP umgewandelt und das WIDEx-y eingefügt, und anschließend an den lokalen Port 9001 gesendet, wo sie von der [[udpbox]] gehört, weiterverarbeitet und digipeatet werden. Das Paket landet dann wie alle anderen zu digipeatenden Pakete auf Port 9032, also beim TNC.
 
=== Senden des AXUDP Paketes an eine eigene Chain im vorhandenen udpbox ===
 
* Man fügt in die vorhandene [[udpbox]] eine weitere chain ein und macht einen zweiten Digipeater, welcher nur die Daten von WeeWX digipeatet.
* is2axudp.py befindet sich in diesem Fall direkt auf dem WeeWX Rechner am entfernten Standort.
* WeeWX sendet lokal seine Daten per TCP an is2axudp.py.
* is2axudp.py wandelt diese Daten um (TCPIP* entfernen, WIDEx-y anhängen, in AXUDP umwandeln) und sendet diese an die entfernte [[udpbox]] am entfernten Rechner am Digistandort.
* Die zusätzliche [[udpbox]]-chain hört nur auf die IP-Adresse des WeeWX Rechners. Hier muss evtl. das Maskieren der IP-Adresse beachtet werden, wenn der WeeWX Rechner aus einem internen "LAN"-Netzwerk kommt.  
* Vorteil: in dieser [[udpbox]]-chain können weitere Filter definiert werden, um ggf. andere Paketarten etc. nicht zuzulassen.
 
Beispielkonfiguration am Digipeater
* IP Adresse des Digipeaters ist 44.149.25.4
* IP-Adresse des WeeWX Rechners ist 44.149.25.66
* Beide Rechner sind im Hamnet und können direkt miteinander ohne NAT/Masquerading miteinander kommunizieren.
 
<nowiki>
is2axudp:
AXUDP Ziel = IP 44.149.25.4 Port 9999
 
TNC KISS Verbindung: 
udpflex -t /dev/ttyUSB0:38400 -k -d 5000 -p 1:15 -p 2:255 -p 3:10 -p 128:0 -U 127.0.0.1:9001:9032 -u -V
 
Digipeater:
udpbox -R 127.0.0.1:9001 -l 127.0.0.1:9101 -d DB0XYZ-10 -p 0,1,2,4,5,6,7,8,9 -t 1740,28 -f p28,29,33,35-39,41-43,46,47,58,59,61,64,91,95,96,123 -k 0/0/20000 -b 600:/home/pi/dxlAPRS/aprs/digibeacon.txt -x APLWS*,NOCALL -l 127.0.0.1:9032 -R 44.149.25.66:9999 -d DB0XYZ-10 -p 4,6 -l 127.0.0.1:9032 -v
</nowiki>
Erklärung:
 
* Das TNC empfängt auf UDP 9032 alle Daten (listen port) die es Aussenden soll und sendet seine empfangenen Daten an UDP 9001 (destination port) am gleichen Rechner.
* Die RX Chain UDP 9001 wird in der udpbox nach UDP 9101 kopiert zum iGate udpgate4 ...
* ... dann wird der Digipeater DB0XYZ-10 akiviert mit diversen Filteroptionen und einer HF-Bake ...
* ... und anschließend wird das, was durch den Digipeater gelaufen ist und "hinten raus" kommt an UDP 9032 gesendet - das ist der Port wo der TNC seine auszusendenden Daten erhält.
* Die Daten von WeeWX werden über TCP in is2axudp.py eingespielt, in AXUDP umgewandelt und das WIDEx-y eingefügt, und anschließend an den lokalen Port 9999 zum Digipeater (IP 44.149.25.4) gesendet, wo sie von der zweiten chain [[udpbox] gehört, weiterverarbeitet und digipeatet werden. Das Paket landet dann wie alle anderen zu digipeatenden Pakete auf Port 9032, also beim TNC.  
* Wichtig ist hier, das passende Digipeating-Optionen in dieser chain gesetzt werden, wenn das Paket nach dem Aussenden über den Digipeater nochmals über andere Digipeater weiterverbreitet werden soll. Parameter -p 4,6 sollte dafür reichen.
 
=== Senden des AXUDP Paketes an eine zusätzliche Instanz von [[udpbox]] ===
* Man kann natürlich auch die [[udpbox]] in einem zusätzlichen Prozess starten anstatt alles in einen Prozess zu packen. Das macht es etwas übersichtlicher.
* Das Vorgehen ist dann identisch wie im Abschnitt vorher, nur dass man [[udpbox]] aufteilt.
 
<nowiki>
is2axudp:
AXUDP Ziel = IP 44.149.25.4 Port 9999
 
TNC KISS Verbindung: 
udpflex -t /dev/ttyUSB0:38400 -k -d 5000 -p 1:15 -p 2:255 -p 3:10 -p 128:0 -U 127.0.0.1:9001:9032 -u -V
 
Digipeater:
udpbox -R 127.0.0.1:9001 -l 127.0.0.1:9101 -d DB0XYZ-10 -p 0,1,2,4,5,6,7,8,9 -t 1740,28 -f p28,29,33,35-39,41-43,46,47,58,59,61,64,91,95,96,123 -k 0/0/20000 -b 600:/home/pi/dxlAPRS/aprs/digibeacon.txt -x APLWS*,NOCALL -l 127.0.0.1:9032 -v
udpbox -R 44.149.25.66:9999 -d DB0XYZ-10 -p 4,6 -l 127.0.0.1:9032 -v
</nowiki>

Aktuelle Version vom 17. Februar 2022, 15:13 Uhr

Beschreibung

is2axudp.py ist ein Python3 Skript, um Pakete im APRS-IS Protokoll entgegenzunehmen und in das AXUDP Format zu wandeln. Dies ermöglicht es beispielsweise Daten einer Wetterstation mit CWOP Report (z.B. WeeWX) direkt per HF über APRS abzustrahlen, anstatt die Daten nur über das Internet an einen APRS-Server zu übermitteln. Selbstverständlich lassen sich so auch andere Daten aus dem APRS-IS Protokoll in AXUDP wandeln.

Anwendungszwecke:

  • Abstrahlung der Daten direkt lokal über HF (z.B. mit udpflex und einem TNC).
  • Abstrahlung der Daten über einen entfernten APRS-Digipeater mit dxlAPRS Software.

Technisches zu is2axudp.py

  • Das Skript besteht aus zwei Teilen. Zum einen das Skript wx.py von Chris OE5DXL und zum anderen das Skript is2axudp.py von Matze DM4TZE.
  • Beide Dateien müssen im gleichen Ordner liegen.
  • Zum Ausführen wird python3 benötigt. Falls es noch nicht installiert ist, kann es auf Debian und kompatiblen Systemen (RaspberryPi, Ubuntu, Mint etc.) mit >> sudo apt-get install python3 << nachinstalliert werden.
  • Das Skript kann gestartet werden mit dem Befehl >> python3 is2axudp.py <<. Alternativ kann man die python Datei auch mit >> chmod 755 << ausführbar gemacht und anschließend direkt mit ./is2axudp.py gestartet werden.

Installation

is2axudp.py liegt in einem Github Repository und kann wie folgt geladen werden:

git clone https://github.com/dl1nux/is2axudp.git

Funktionsweise

Im Beispiel die Anbindung einer Wetterstation mit WeeWX und konfiguriertem CWOP Report.

python3 is2axudp.py 

connection
<-# is2axudp 0.1
->user DL1NUX-14 pass 21432 vers weewx 4.2.0
<-# logresp #
->DL1NUX-14>APRS,TCPIP*:@182025z5013.81N/01059.43E_000/002g004t035r001p009P009b10250h81.weewx-4.2.0-FineOffsetUSB
<~DL1NUX-14>APRS:@182025z5013.81N/01059.43E_000/002g004t035r001p009P009b10250h81.weewx-4.2.0-FineOffsetUSB

  1. Das Skript erzeugt einen TCP Server auf einem im Skript vorgegebenen und auch änderbaren Port.
  2. Die Wetterstation connected den TCP Server.
  3. is2axudp.py antwortet protokollgemäß mit der Softwareversion
  4. WeeWX sendet das APRS Loginskript mit Rufzeichen, Passcode und Softwareversion
  5. is2axudp.py antwortet mit einem # logresp #. Damit weiß WeeWX dass die Verbindung erfolgreich ist.
  6. WeeWX sendet das APRS Paket mit enthaltener TCPIP* Syntax. Das ist so definiert für Übergaben in das APRS-IS Netzwerk.
  7. Für die Aussendung als APRS-Paket wird durch is2axudp.py die Syntax ",TCPIP*" wieder entfernt. Es bleibt das eigentliche Rohpaket übrig.
  8. is2axudp.py wandelt mithilfe der wx.py von Chris OE5DXL das Paket in das AXUDP Format um.

Das somit erzeugte AXUDP Paket kann an alle kompatiblen Tools der dxlAPRS Toolchain (udpflex, afskmodem, udpbox usw.) zur Weiterverarbeitung übergeben werden.

Wie WeeWX eingestellt werden muss

In der WeeWX Konfiguration muss der sogenannte "CWOP" Report aktiviert werden. "CWOP" steht dabei nicht für den "Telegrafie-Operator", sondern für "Citizen Weather Observer Program".

Die WeeWX Konfigurationsdatei liegt gewöhnlicherweise hier /etc/weewx/weewx.conf. Der Ort kann aber auch abweichen bei manueller Installation. Siehe auch WeeWX Doku.

[StdRESTful]

    [[CWOP]]
        # This section is for configuring posts to CWOP.

        # If you wish to do this, set the option 'enable' to true,
        # and specify the station ID (e.g., CW1234).
        enable = true
        station = MYCALL-15

        # If this is an APRS (radio amateur) station, uncomment
        # the following and replace with a passcode (e.g., 12345).
        #passcode = 12345
        server_list = 127.0.0.1:1234, rotate.aprs2.net:14580
        log_success = true
        log_failure = true


  • "enable" muss auf "true" geändert werden.
  • Unter "station" gibt man das eigene Rufzeichen mit SSID an, unter dem die Wetterstation die Daten veröffentlichen soll.
  • Einen Passcode muss man für is2axudp.py nicht zwingend eintragen (von is2axudp.py wird es ignoriert). Es wird aber empfohlen falls es einen Fallback auf einen anderen APRS-Server gibt (z.B. is2axudp.py beendet sich), dann verbindet sich WeeWX wie in diesem Beispiel mit dem nächsten gelisteten Server "rotate.aprs2.net".
  • Unter server_list gibt man IP-Adresse:Port des TCP Servers an, wo is2axudp.py läuft. Es ist empfehlenswert is2axudp direkt auf dem selben Rechner (127.0.0.1) wie WeeWX laufen zu lassen. Es kann aber auch wo anders laufen. Es können mit Kommas getrennt mehrere Server eingetragen werden. Sobald einer nicht erreichbar ist, wird der nächste angewählt.
  • log_success und log_failure sind nicht zwingend notwendig, hinterlassen aber einen Eintrag in /var/log/syslog ob erfolgreich oder nicht übermittelt wurde.

Direkte lokale Aussendung am gleichen Standort

Wenn die Wetterdaten vom gleichen Standort wie die Wetterstaton abgestrahlt wird, kann das Skript mit nur kleinen Anpassungen verwendet werden. Es sind lediglich bei Bedarf ein abweichender TCP Port einzutragen (Standard = 1234) sowie das AXUDP-Ziel (IP-Adresse und Port). Das Paket wird dann 1:1 ausgesendet.

Änderungen am Skript:

TCP Port Eingang falls anders gewünscht (Standard = 1234):

serversocket.bind(("0.0.0.0", 1234))

AXUDP Ausgang (Standard = IP 127.0.0.1 und Port 9032):

sendax(data,("127.0.0.1",9032),{})

Auf Port 9032 muss dann der Sender "hören", z.B. udpflex mit einem angeschlossenen TNC. Beispielkonfiguration von udpflex:

udpflex -t /dev/ttyUSB0:38400 -k -d 5000 -p 1:15 -p 2:255 -p 3:10 -p 128:0 -U 127.0.0.1:0:9032 -u -V

Aussendung nach dem Durchlaufen des Skripts:

DL1NUX-14>APRS:@182025z5013.81N/01059.43E_000/002g004t035r001p009P009b10250h81.weewx-4.2.0-FineOffsetUSB

Das Paket kann von allen Stationen in HF-Reichweite gelesen werden. Wenn ein iGate unter den Empfängern ist, erscheint die Aussendung auch auf aprs.fi & Co. Möchte man, dass das Paket ggf. noch digipeatet wird, muss man noch den APRS-Pfad durch einen WIDE-Pfad erweitern, z.B. WIDE1-1. Dies geschieht recht einfach im "replace" Abschnitt der is2axudp.py. Anstatt dass ",TCPIP*" durch "nichts" ersetzt wird (quasi entfernt), kann man auch einen anderen Wert einfügen. Es muss aber immer ein "," (Komma - ohne Anführungszeichen) dem Pfad vorangestellt werden.

Original:

data = data.replace(b',TCPIP*',b'')

Änderung mit WIDE1-1 Pfad:

data = data.replace(b',TCPIP*',b',WIDE1-1')

Aussendung mit WIDE1-1:

DL1NUX-14>APRS,WIDE1-1:@182025z5013.81N/01059.43E_000/002g004t035r001p009P009b10250h81.weewx-4.2.0-FineOffsetUSB

Aussendung an einem entfernten Standort

Wenn man die Daten der Wetterstation nicht am gleichen Standort sondern entfernt abstrahlen möchte, z.B. beim nächsten Digipeater, muss ein wenig mehr beachtet werden.

  • Die Pakete der Wetterstation sollten nicht "direkt" eins-zu-eins ausgesendet werden.
  • Heißt die Wetterstation z.B. DL1NUX-14 und der Digi DB0NU-10, würde eine eins-zu-eins Abstrahlung allen Empfänger der Aussendung vortäuschen, dass DL1NUX-14 direkt empfangen wurde. Das stimmt aber nicht, da sich DL1NUX-14 gar nicht am Standort von DB0NU befindet. Das "Relais" würde quasi mit dem "falschen Rufzeichen" seine Aussendung machen.
  • Korrekter wäre es, wenn der APRS-Digipeater die Aussendung auch als gedigipeatertes Paket abstrahlen würde. Also so, als wenn DB0NU-10 DL1NUX-14 über HF empfangen hätte und nun digipeaten würde.

Beispiel:

Folgendes Paket wird durch is2axudp.py empfangen:

DL1NUX-14>APRS,TCPIP*:@182205z5013.81N/01059.43E_341/002g006t035r001p011P011b10242h81.weewx-4.2.0-FineOffsetUSB

Das Paket wird von is2axudp.py in AXUDP umgewandelt und es wird ein WIDE1-1 Pfad angehängt:

DL1NUX-14>APRS,WIDE1-1:@182205z5013.81N/01059.43E_341/002g006t035r001p011P011b10242h81.weewx-4.2.0-FineOffsetUSB

Paket wird wie folgt von DB0NU-10 auf HF abgestrahlt:

DL1NUX-14>APRS,DB0NU-10*:@182205z5013.81N/01059.43E_341/002g006t035r001p011P011b10242h81.weewx-4.2.0-FineOffsetUSB

Was passiert in diesem Beispiel und welche Bedeutung hat es?

  1. Wie oben beschrieben wird das von WeeWX empfangene Paket empfangen und der String ",TCPIP*" wird entfernt.
  2. Als Pfad wird WIDE1-1 angehängt (String = ",WIDE1-1"), damit der Digipeater (udpbox) weiß, dass er es digipeaten soll.
  3. Anschließend wird das Paket im AXUDP Format an den Digipeater gesandt.
  4. Der Digipeater udpbox "empfängt" das Paket über AXUDP, erkennt anhand des "WIDE1-1" dass es das Paket digipeaten soll.
  5. Das Paket wird von DB0NU-10 abgestrahlt und korrekterweise das H-Bit "*" an das eigene Call angehängt. Dadurch weiß jede Station, die das Paket empfängt, dass die Aussendung indirekt von DB0NU-10 stammt, und nicht direkt von DL1NUX-14. Das WIDE1-1 wird in diesem Fall entfernt, da der Hop aus WIDE1-1 "verbraucht" ist.
  6. Würde man wollen, dass noch weitere Digis das Paket digipeaten sollen, kann man auch das WIDE erweitern auf WIDE2-2, oder WIDE1-1,WIDE2-1 usw. Es ist jede Kombination denkbar. Hierbei sollte man aber sparsam sein. Es sollte maximal bis zum nächsten iGate "getragen" werden. Um es weiter digipeaten zu können, muss der Digipeater bei der udpbox mindestens die Digipeater-Parameter -p4,6 haben, sonst wird der Pfad ggf. abgeschnitten und/oder gänzlich ignoriert.

Das eigentliche Digipeating übernimmt die udpbox. Dazu gibt es mehrere technische Lösungen:

Senden des AXUDP Paketes an den Listen-Port des vorhandenen Digipeaters

  • Der udpbox Digipeater kann entweder nur auf einer Quell-IP hören (z.B. 127.0.0.1) oder auf alle (0.0.0.0).
  • Auf alle IPs zu hören ist unsicher, das könnte missbraucht werden.
  • Auch wenn man is2axudp.py, udpflex und [[udpbox] auf dem selben Rechner laufen lässt, ist es gefährlich. Der TCP Server könnte ebenfalls mit fremden Daten gespeist werden, die dann zur Aussendung kommen.
  • Aber Achtung: Wer weiß dass dort ein TCP-Server läuft, könnte auch auch diesem Weg Daten direkt an is2axudp.py zuführen.
  • Diese Variante ist also eher nicht zu empfehlen, egal wie, da zu Risikoreich.

Beispiel am Digi mit allen drei Programmen auf dem selben Rechner:

is2axudp:
AXUDP Ziel = IP 127.0.0.1 Port 9001

TNC KISS Verbindung:  
udpflex -t /dev/ttyUSB0:38400 -k -d 5000 -p 1:15 -p 2:255 -p 3:10 -p 128:0 -U 127.0.0.1:9001:9032 -u -V

Digipeater:
udpbox -R 127.0.0.1:9001 -l 127.0.0.1:9101 -d DB0XYZ-10 -p 0,1,2,4,5,6,7,8,9 -t 1740,28 -f p28,29,33,35-39,41-43,46,47,58,59,61,64,91,95,96,123 -k 0/0/20000 -b 600:/home/pi/dxlAPRS/aprs/digibeacon.txt -x APLWS*,NOCALL -l 127.0.0.1:9032 -v

Erklärung:

  • Das TNC empfängt auf UDP 9032 alle Daten (listen port) die es Aussenden soll und sendet seine empfangenen Daten an UDP 9001 (destination port) am gleichen Rechner.
  • Die RX Chain UDP 9001 wird in der udpbox nach UDP 9101 kopiert zum iGate udpgate4 ...
  • ... dann wird der Digipeater DB0XYZ-10 akiviert mit diversen Filteroptionen und einer HF-Bake ...
  • ... und anschließend wird das, was durch den Digipeater gelaufen ist und "hinten raus" kommt an UDP 9032 gesendet - das ist der Port wo der TNC seine auszusendenden Daten erhält.
  • Die Daten von WeeWX werden über TCP in is2axudp.py eingespielt, in AXUDP umgewandelt und das WIDEx-y eingefügt, und anschließend an den lokalen Port 9001 gesendet, wo sie von der udpbox gehört, weiterverarbeitet und digipeatet werden. Das Paket landet dann wie alle anderen zu digipeatenden Pakete auf Port 9032, also beim TNC.

Senden des AXUDP Paketes an eine eigene Chain im vorhandenen udpbox

  • Man fügt in die vorhandene udpbox eine weitere chain ein und macht einen zweiten Digipeater, welcher nur die Daten von WeeWX digipeatet.
  • is2axudp.py befindet sich in diesem Fall direkt auf dem WeeWX Rechner am entfernten Standort.
  • WeeWX sendet lokal seine Daten per TCP an is2axudp.py.
  • is2axudp.py wandelt diese Daten um (TCPIP* entfernen, WIDEx-y anhängen, in AXUDP umwandeln) und sendet diese an die entfernte udpbox am entfernten Rechner am Digistandort.
  • Die zusätzliche udpbox-chain hört nur auf die IP-Adresse des WeeWX Rechners. Hier muss evtl. das Maskieren der IP-Adresse beachtet werden, wenn der WeeWX Rechner aus einem internen "LAN"-Netzwerk kommt.
  • Vorteil: in dieser udpbox-chain können weitere Filter definiert werden, um ggf. andere Paketarten etc. nicht zuzulassen.

Beispielkonfiguration am Digipeater

  • IP Adresse des Digipeaters ist 44.149.25.4
  • IP-Adresse des WeeWX Rechners ist 44.149.25.66
  • Beide Rechner sind im Hamnet und können direkt miteinander ohne NAT/Masquerading miteinander kommunizieren.
is2axudp:
AXUDP Ziel = IP 44.149.25.4 Port 9999

TNC KISS Verbindung:  
udpflex -t /dev/ttyUSB0:38400 -k -d 5000 -p 1:15 -p 2:255 -p 3:10 -p 128:0 -U 127.0.0.1:9001:9032 -u -V

Digipeater:
udpbox -R 127.0.0.1:9001 -l 127.0.0.1:9101 -d DB0XYZ-10 -p 0,1,2,4,5,6,7,8,9 -t 1740,28 -f p28,29,33,35-39,41-43,46,47,58,59,61,64,91,95,96,123 -k 0/0/20000 -b 600:/home/pi/dxlAPRS/aprs/digibeacon.txt -x APLWS*,NOCALL -l 127.0.0.1:9032 -R 44.149.25.66:9999 -d DB0XYZ-10 -p 4,6 -l 127.0.0.1:9032 -v

Erklärung:

  • Das TNC empfängt auf UDP 9032 alle Daten (listen port) die es Aussenden soll und sendet seine empfangenen Daten an UDP 9001 (destination port) am gleichen Rechner.
  • Die RX Chain UDP 9001 wird in der udpbox nach UDP 9101 kopiert zum iGate udpgate4 ...
  • ... dann wird der Digipeater DB0XYZ-10 akiviert mit diversen Filteroptionen und einer HF-Bake ...
  • ... und anschließend wird das, was durch den Digipeater gelaufen ist und "hinten raus" kommt an UDP 9032 gesendet - das ist der Port wo der TNC seine auszusendenden Daten erhält.
  • Die Daten von WeeWX werden über TCP in is2axudp.py eingespielt, in AXUDP umgewandelt und das WIDEx-y eingefügt, und anschließend an den lokalen Port 9999 zum Digipeater (IP 44.149.25.4) gesendet, wo sie von der zweiten chain [[udpbox] gehört, weiterverarbeitet und digipeatet werden. Das Paket landet dann wie alle anderen zu digipeatenden Pakete auf Port 9032, also beim TNC.
  • Wichtig ist hier, das passende Digipeating-Optionen in dieser chain gesetzt werden, wenn das Paket nach dem Aussenden über den Digipeater nochmals über andere Digipeater weiterverbreitet werden soll. Parameter -p 4,6 sollte dafür reichen.

Senden des AXUDP Paketes an eine zusätzliche Instanz von udpbox

  • Man kann natürlich auch die udpbox in einem zusätzlichen Prozess starten anstatt alles in einen Prozess zu packen. Das macht es etwas übersichtlicher.
  • Das Vorgehen ist dann identisch wie im Abschnitt vorher, nur dass man udpbox aufteilt.
is2axudp:
AXUDP Ziel = IP 44.149.25.4 Port 9999

TNC KISS Verbindung:  
udpflex -t /dev/ttyUSB0:38400 -k -d 5000 -p 1:15 -p 2:255 -p 3:10 -p 128:0 -U 127.0.0.1:9001:9032 -u -V

Digipeater:
udpbox -R 127.0.0.1:9001 -l 127.0.0.1:9101 -d DB0XYZ-10 -p 0,1,2,4,5,6,7,8,9 -t 1740,28 -f p28,29,33,35-39,41-43,46,47,58,59,61,64,91,95,96,123 -k 0/0/20000 -b 600:/home/pi/dxlAPRS/aprs/digibeacon.txt -x APLWS*,NOCALL -l 127.0.0.1:9032 -v
udpbox -R 44.149.25.66:9999 -d DB0XYZ-10 -p 4,6 -l 127.0.0.1:9032 -v