Grundlagen und Anwendungsbeispiel

TX-Fernsteuerung mittels Browser

Aktuell, Notizen

Freitag, 27. Februar 2015
CGI mit Windows

Wer glaubt, Windows sei die bessere Wahl fuer einen Server, der findet hier eine Installationsanleitung.

Freitag, 27. Februar 2015
Workshop 28.2.2015

Das CGI-Konzept verstehen

Admin

Python - Programmiersprache

Python ist eine universelle, höhere Programmiersprache. Merkmale sind (normalerweise) interpretierende Ausführung der Programme (kein Assembler), sehr kompakter Programm-Code (Uebersichtlichkeit) und eine Programmstruktur durch Einrückungen (keine Klammern und Sprungbefehle). Für Anwendungen wie etwa unsere TX- Steuerung ist die Geschwindigkeit der Programmausführung absolut genügend.

Realtime-Mechanismus (Option)

Die bisherigen Python-Programme wurden entweder im Interpreter oder als einzelnes Programm ausgeführt. Optionell können wir einen Realtime Mechanismus verwenden, der ähnlich wie ein Betriebssystem, eine Echtzeitverarbeitung ermöglicht.

CGI - Common Gateway Interface

Das Common Gateway Interface (CGI) ist ein Standard für den Datenaustausch zwischen einem Webserver und Dritt-Software (CGI Script oder auch CGI Programm genannt), die Anfragen bearbeitet und ev. eine HTML-Seite generiert.

Anwendungsbeispiel

Die Fernsteuerung eines Transceivers über das Internet soll die verschiedenen Techniken im Zusammenspiel veranschaulichen. In Schritt 1 wird die Gestaltung eines einfachen Benutzerinterfaces gezeigt. Schritt 2 veranschaulicht die Serverseite. Ein einfaches Pythonprogramm stellt den Link zwischen dem Apache-Server und dem Transceiver dar. Das CGI (Common Gateway Interface) verbindet die beiden Skripte HTML und Python innerhalb des Apache-Servers (Schritt 3) .


Inhalt

  • Python
  • Realtime Mechanismus (Option)
  • CGI Konzept
  • .
  • Anwendungsbeispiel TX-Fernsteuerung
  • Step 1 - Erstellung und Installation des HTML Script
  • Step 2 - Erstellung und Installation des CGI Script
  • Step 3 - Konfiguration des Apache-Servers (CGI)


Fernsteuerung mittels Smartphone

Eingabemaske (links)
Favoriten-Eingabe (Mitte)
Feedback vom Server/TX (rechts)


Python

Als Anfänger hat man schnell mal ein lauffähiges Programm in Python erstellt. Das sollte aber nicht darüber hinwegtäuschen, dass gute Python-Programmierung sehr anspruchsvoll ist. Das folgende Script (Frequenzausgabe zum TX) ist recht einfach.
Ein guter, erfahrener Programmierer schreibt diese Sequenz noch kompakter und übersichtlicher.

Ein Phyton-Kurs in deutscher Sprache kann helfen, aber nur viel Erfahrung macht den Meister.


Beispiel Python Subroutine

Aufruf mit Parameter Frequenz (string) und Delay


Realtime Mechanismus

Es werden 2 mögliche TX-Steuerungen vorgestellt. Die Varianten wurden soweit realisiert, dass die Machbarkeit bestätigt wurde.

a) Funktionsmuster einer TX-Steuerung mittels CGI-Schnittstelle:
Funktionen via Internet über beliebige Browser:
- Frequenz-/Mode-Uebermittlung an den FT-897
- Lesen und Darstellung von effektiver Frequenz/Mode am TX
- Senden (PTT)
- Uebermittlung weiterer Funktionen wie 'Lock'
- Absuchen des Frequenzbandes mittels eines Scanners.

Vorteil: relativ einfach zu realisieren und sehr leicht zu bedienen
Nachteil: Das 'Scannen' des Frequenzbandes ist nicht ganz einfach (Stop und Feintuning)

Fernsteuerung mittels Smartphone


b) Funktionsmuster einer TX-Steuerung mit grafischer Oberfläche:
Funktionen:
- Frequenz-/Mode-Uebermittlung an den FT-897
- Senden (PTT)
- Uebermittlung weiterer Funktionen wie etwa 'Lock'
- Absuchen des Frequenzbandes mittels eines 'Rulers' mit Feintuning (grün).

Vorteil: optisch attraktive Steuerung, eine Art 'HRD light'
Nachteil: Bedienung etwas umständlich, via 'TeamViewer' oder ähnlichem

Abb. Funktionsmuster mit Python /Tkinter


Beide Varianten müssen in der Lage sein, die Amateur-Frequenzbänder im Empfangsmodus sauber abzusuchen. Scanner und Ruler (Schieberegler) müssen also im Realtime arbeiten.

Dazu habe ich ein Basisgerüst für ein Realtime-Programm ausprobiert:
- Schneller Loop (1) für einen Bandscanner (z.B. 100 Hz in 10 Schritten)
- Schneller Loop (2), um die Frequenz in grösseren Schritten (z.B. 1 kHz) zu ändern
- Langsamer Loop (3), der den Status des Empfängers (Frequenz und Mode) ausliest

Alle 3 Loops laufen parallel (Multi-Thread)

Wer Lust und Zeit hat kann den Loop selbst ausprobieren:

File : Realtime_loop.py [1 KB]
..........


Hier noch ein Beispiel mit 5 Threads:
- 3 Loops wie oben
- 1 Status Loop zwecks kontinuierlichem Auslesen des TX-Status
-1 Command Loop

Parameter sind Text (name), Intervall in Sekunden und Anzahl Loops

Test-Tool: Spyder (für Linux, Windows, ..)
PC: Linux Mint (Rebecca)
Browser: Chrom, Firefox (PC, Tablett und Smartphone)


CGI Konzept

CGI Konzept

Steuerung FT-897

CGI Konzept


Das CGI Konzept

Was passiert, wenn wir einen HyperLink klicken,
um eine bestimmte Webseite oder URL aufzurufen ?

- Unser Browser (Chrom, Firefox, IE) contaktiert den HTTP Webserver und fragt nach der URL, z.Bsp. einen File-Namen

- Der Webserver (z.B. Apache) analysiert die die URL und sucht den Namen des Files und sendet dieses File zum Browser zurück. Andernfalls wird eine Fehlermeldung retourniert: 'Falsches File'

- Unser Browser empfängt das File vom Webserver und zeigt es an (oder die Fehlermeldung)

Nun ist es aber möglich, den Webserver so zu konfigurieren, dass wenn ein bestimmtes File in einer bestimmten Directory aufgerufen wird, dieses nicht retourniert wird. Das File wird als Programm im Webserver ausgeführt und die Ausgabe des Programms wird zum Browser gesendet. Diese Funktion nennt man Common Gateway Interface oder CGI und das Programm CGI Script. Diese Programme können Python Script, PERL Script, Shell Script, C or C++ Programm, etc. sein.


 


Hello PRIG - TX Control

Yaesu FT-897D


Frequenz VFO A:
Frequenz VFO B:
USB LSB CW FM AM Dig


Fernsteuerung eines Transceivers

Server - Hardware
Als Server verwende ich einen 6 Jahre alten Laptop. Er dient als Server, Client und Entwicklungssystem zugleich.

Server - Betriebssystem
Als Betriebssystem für das Funktionsmuster dient ein Linux Mint (Rebecca). Eine spätere Portierung auf den Rasperry Pi ist vorgesehen.
Linux hat gegenüber Windows folgende Vorteile:
- Zuverlässigkeit (bewährt, Updates nur auf Wunsch)
- Sicherheit
- Transparenz
- Geschwindigkeit (etwa 3 mal schneller als Windows)
- sehr ähnlich wie Windows XP/7
- Langzeit-Unterstützung
- kostenlos
Eingefleischte Windows Fans sollten sich gut überlegen, ob sie das Projekt wirklich auf dem geschlossenen Windows-Betriebssystem realisieren wollen. Möglich ist es. Es sprechen aber alle Argumente für das Win 7-ähnliche Linux Mint.

Webserver Apache
Der Apache bietet die Möglichkeit, mittels serverseitiger Skriptsprachen Webseiten dynamisch zu erstellen. Häufig verwendete Skriptsprachen sind PHP, Perl oder Ruby, Python, JavaScript, etc.. Diese sind kein Bestandteil des Webservers, sondern müssen entweder als Module eingebunden werden oder über das CGI angesprochen werden.
Der Apache HTTP Server ist, wie alle Programme der Apache Software Foundation, eine freie Software. Derzeit wird noch die stabile Version 2.2.x unterstützt.

Transceiver
Der zu steuernde Transceiver ist ein vorhandener Yaesu FT-897D
Das vorliegende Projekt kann leicht an andere Transceiver wie etwa den ICOM-7000 angepasst werden.

USB-Anschlusskabel Transceiver/Laptop CT-62 für Yaesu
Für Linux, Win 7/8 (32 oder 64 Bit)
Die CD-Rom mit Win-Driver wird für Linux Mint nicht benötigt.
Bezugsquelle: WiMo für rund 50 Euro.

Audio
mittels SignaLink USB von Tigertronics / Skype

Entwicklungsumgebung Spyder (Optional)
Spyder bietet etwas mehr Komfort als nur mit einem gewöhnlichen Editor. Die Aenderungen können zuerst auf mögliche Syntax-Fehler getestet werden und anschliessend direkt ins laufende System eingefügt werden. Die folgende Abbildung zeigt das Einfügen der zusätzlichen Bedingung 'nicht outband failure' zum Sende-Befehl (PTT)

Entwicklungsumgebung

Testen mit Spyder (Hintergrund) und Korrekturen am laufenden System (Vordergrund)


Netzwerkumgebung
- Netzwerkanschluss über WiFi (feste interne IP-Adresse).
- Verwendung eines DynDNS-Servers zwecks externem Zugang
- Konfiguration des Routers: DynDNS aktivieren und Portweiterleitung (für Port 80)

Ferneinschalten des Transceivers
Es gibt verschiedene Möglichkeiten, den Transceiver ein/auszuschalten. Da wir das Funkgerät über einen Browser steuern, liegt es nahe, auch die Ferneinschaltung über den Browser zu realisieren. Alternativ kann ein SMS Switch verwendet werden.

Fernsteuerbare Netzsteckdosen

Alternativ: SMS-Switch


Rechtlicher Hinweis
Es gibt länderspezifische Vorschriften bez. Betreibung einer fernbedienter Amateurfunkstation

Ausbau/Verbesserungen
Das System kann beliebig ausgebaut werden, beispielsweise mit einem Band-Scanner und Favoriten (Memory).
Eine Adaption für andere Transceiver-Typen ist leicht möglich.
Verbesserungen:
- Optimierung des Python-Skripts
- Zwangsläufige Steuerung des TX
- Komfortable Parameter-Eingabe
- Audio-Interface für den Raspy
- UHF/VHF (wird aufwändig)


Step 1

Der erste Schritt ist zugleich der einfachste. Das folgende File als Beispiel herunterladen:

Code für das Beispiel [1 KB]

In der default location: /var/www/html das vorhandene File index.html umbenennen in z.Bsp. default_index.html
Das heruntergeladene File muss nun in den Ordner html (Pfad /var/www/html) verschoben werden und in index.html umbenannt werden, da der Apache-Server zuerst nach diesem File sucht !
Gibt man in einem beliebigen Browser localhost in die Adresszeile ein, wird die Eingabemaske dargestellt

Webinterface im Browser

als eigenständige Webpage


Anmerkung:
Der HTML-Code für ein Webinterface kann an einer beliebigen Stelle einer normalen Webseite eingefügt werde. Alternativ kann eine einfache Website erzeugt werden (unser Beispiel).

Webinterface im Browser

Eingebunden in eine bestehende Website


Dieser Schritt war leicht. Wir können uns nun an den 2. Schritt wagen.


Step 2

Im zweiten Schritt bereiten wir das zum HTML-Skript (Step 1) passende CGI-Skript vor. Ein rudimentäres Beispiel-Programm wird im Ordner 'cgi-bin' bereitgestellt.

2.1 Directory 'cgi-bin' erstellen
Den Ordner mit dem Namen cgi-bin erstellen wir im Pfad /var/www/ ; gleich neben der Directory html. Dies vereinfacht eine parallele Weiterentwicklung in beiden Skripts.

Terminal-Kommando: mkdir /var/www/cgi-bin

Wer die grafischer Oberfläche bevorzugt, legt mittels rechter Maustaste den Ordner cgi-bin an, im Pfad: /var/www/cgi-bin
Darin wird das folgende CGI Script plaziert.

2.2 Diownload unseres Beispiels
Beispiel-Script, passend für den Yaesu FT-897D gemäss Schritt 1

Code für das Beispiel [7 KB]

Das heruntergeladene File muss unbedingt in prig.py umbenannt werden und
.



Das Python Script beginnt mit der Zeile: #!/usr/bin/python
Sie liefert den Link zum Starten des Python Interpreters .

Anschliessend werden diverse Module wie etwa 'serial' oder 'cgi' importiert.

Der folgende Python-Code liest und analysiert die vom Benutzer (Browser) gelieferten Eingabedaten (Frequenz, Mode, ...) und führt die serielle Kommunikation mit dem Transceiver FT-8x7 aus. Das Script ist geradlinig und modular aufgebaut, sodass Ergänzungen einfach hinzugefügt werden können.

Am Schluss werden zu Kontrollzwecken verschiedene Daten 'gedruckt' (Abbildung):

Fernsteuerung mittels Nexus 7 / Chrome Browser

im Heimnetzwerk 192.168.1.37 (Beispiel)


Die verzögerte Rückmeldung kann eingestellt werden zwischen rund einer Sekunde und vielen Stunden.

Programmablauf:

1. Frequenz
1.1 Einlesen der Frequenz und Abtesten, ob nur Ziffern eingegeben wurden.
>>> Resultat: Frequenz in Ziffern

1.2 Frequenzbandkontrolle, ob die Frequenz oberhalb 3'500 kHz und innerhalb der Amateur-Frequenzbänder ist.
>>> Resultat: failure = 0, falls dies der Fall ist

1.3 Der Frequenz-String musste für 1.1 und 1.2 in eine integere Zahl gewandelt werden. Nun muss der String wieder hergestellt werden, um ihn an den TX zu senden. Die Länge des Strings muss dabei exakt 6 Ziffern betragen. Allfällige Nullen werden vorne angefügt.
>>> Resultat: String mit exakt 6 Ziffern

1.4 Konvertierung des Strings in hex und Aussenden (ICOM: umgekehrt)
>>> Resultat: Der TX wird auf die eingegebene Frequenz eingestellt

2. Mode
Falls ein Mode gesetzt wurde, wird dieser Befehl an den TX gesendet.
Default Mode ist USB.

3. Spezielles
Die Spezalbefehle werden in einer 'Checkbox' gesetzt und können mehrfach gewählt werden.

3.1 Lock-Befehl
>>> Resultat: Der TX wird gesperrt

3.2 Status 5, benannt nach der Note im FT-897 Manual, bestehend aus 5 Bytes wird eingelesen und nach aktueller Frequenz und Modus analysiert. Status 3 und 4, bestehend aus je 1 Byte, werde vorläufig nicht eingelesen.
>>> Resultat: Aktuelle Frequenz und Modus des TX

4. PTT
Gesendet wird, sofern PTT in der Checkbox gesetzt ist, kein Fehler bei der Frequenzeingabe besteht (failure = 0) und eine der 'Submit'-Tasten links betätigt wird.
>>> Resultat: Der TX geht auf Senden

5. Loops
Das Python-Programm wird grundsätzlich durch Ereignisse gestartet, in unserem Fall durch Drücken einer der Tasten links. Sie lösen die 'Submit'-Funktion aus, welche das Script startet (event driven). Für den weiteren Ausbau (z.B. Scanning) benötigen wir weitere 'Realtime'-Loops, die unabhängig vom Haupt-Loop arbeiten (Multi Thread).

name: Loop in unserem Beispiel
delay: 0.3 Sekunden für Loop (1) und 0.6 Sekunden für Loop (2) in unserem Beispiel
repeat: 6 mal für beiden Loops in unserem Beispiel

Der Feedback (Ausdruck) zum Benutzer beträgt demnach ca. 4 sec.


Step 3


3.1 Das CGI-File
Das CGI Programm oder CGI Script (Schritt 2) muss den richtigen Filenamen aufweisen:
- filename.py (Dies muss dies im Apache Webserver definiert werden)
in unserem Beispiel ist dies: prig.py
oder: filename.cgi

Ausserdem muss das CGI-File als ausführbare Datei definiert werden....
... und die Berechtigungen müssen richtig gesetzt werden.
Terminal-Kommando: sudo chmod 755 /var/www/cgi-bin

3.2 Der Webserver (hier Apache) muss CGI erlauben.
Siehe auch http://httpd.apache.org/docs/2.2/howto/cgi.html
Der Ort des Servers befindet sich bei Linux Mint in /etc/apache2/apache2.conf

Terminal-Kommando: sudo a2enmod cgi

Danach restart von Apache: sudo service apache2 restart

Eigenschaften von cgi-bin Script

Ausschnitt aus dem apache2.config File.

auch je nach Distribution als httpd.conf bezeichnet

Kopiere die folgenden Zeilen ins apache2.config File.
Es befindet sich unter: /etc/apache2
Der Ordner apache2 muss als Systemverwalter geöffnet werden.

#Added by Werner, HB9CZV

ScriptAlias /cgi-bin/ /var/www/cgi-bin/
<Directory "/var/www/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
AddHandler cgi-script .py
AddHandler default-handler .html .htm
</Directory>

ServerName localhost

#Added by Werner, HB9CZV

Anmerkungen:
- Der ScriptAlias /cgi-bin/ /var/www/cgi-bin/ verweist auf den von uns speziell erzeugten Ordner cgi-bin gleich neben dem html-Ordner im Pfad /var/www/cgi-bin.
- Der AddHandler cgi-script .py kann bei Bedarf mit der Endung .cgi ergänzt werden

3.3 Berechtigung für Serial Out
Bei Linux wird das serielle Lesen/Schreiben sehr restriktiv erlaubt. Zusätzliche Berechtigungen sind notwendig:

sudo adduser nobody dialout
sudo adduser www-data dialout
sudo adduser werner dialout (mein Benutzername)

User running apache: ps aux | grep www-data

Terminal-Abfrage: sudo ls -la /dev/ttyUSB0

________________________________________________________________
* Ich kann gut verstehen, wenn jemand bei der Konfiguration entnervt aufgibt. Keine Distribution ist gleich, Bei Linux Mint z.B. heisst das Haupt-Konfigurationsfile nicht 'httpd.conf' sondern 'apache2.conf'. Vermutlich auch bei Ubuntu. Irgend ein Schlaumeier bei Debian hat das Haupt-Konfigurationsfile auf Dutzende Unterfiles aufgeteilt. Nun kannst Du alle Foren durchforsten, bist Du mal eine schlaue Antwort für Dein System bekommst. Manchmal hat man den Eindruck, dass die Linux-Leute bewusst Stolpersteine einfügen, um den Kreis ihrer 'Community' klein zu halten.

Falls es nicht funktioniert:
Wenn man versucht mit dem Browser das CGI Script zu starten, kann man folgendes sehen:

Das erstellte CGI Script wird dargestellt
Super !
Dies zeigt, dass alles soweit richtig läuft. Falls das Script korrekt ist, kontrolliere ob der richtige Content-Type im CGI Programm definiert ist.

Anzeige des Source Code vom erstellten CGI Programm oder eine "POST Method Not Allowed" Meldung
Dies bedeutet, dass Apache nicht richtig konfiguriert wurde um das CGI Script auszuführen. Kontrolliere nochmals genau jeden Schritt !

Eine Anzeige: "Forbidden"
Hier ist ein Berechtigungsproblem zu vermuten. Kontrolliere die Berechtigung gemäss der Fehlermeldung !
File Berechtigung
Wenn der Server aufstartet, läuft er wie ein unberechtigter Benutzer (User). Es braucht gemäss 3.3 eine extra Berechtigung um Deine (owner) Files auszuführen.


Quellen:

Einrichten eines Linux Apache-Webservers auf dem Raspy:
http://prig.ch/linux-applications/apache-webserver/index.php

Den Webserver für CGI-Skripte konfigurieren:
http://pronix.linuxdelta.de/Perl_cgi/cgi/cgi_kurs_kapitel3a.shtml

Command: /usr/sbin/apache2 -V


Zugriffe heute: 2 - gesamt: 2991.