Forum: Mikrocontroller und Digitale Elektronik Universalfernbedienung mit Raspberry Pi


von Samuel J. (capstrovor)


Lesenswert?

Hey Leute!

Folgendes Problem: Ich möchte eine Universalfernbedienung mit dem 
Raspberry bauen. Die Steuerung erfolgt über eine Website. Ich kann den 
Raspberry jetzt mit Putty steuern, da ich ihn über TCP/IP anspreche 
(also ich schicke einfach den befehl SEND_ONCE [name_der_fernbedienung] 
[name_der_taste]). Jetzt möchte ich, dass ich auf meine Website gehe 
(sie liegt auf dem Rpi) und einen Button drücke (z.b fernseher lauter). 
Nun soll mit PHP über TCP der Befehl SEND_ONCE fernseher volume_up 
gesendet werden. Wie sieht der PHP-TCP Teil aus? Ich habe bereits 
gegooglet und Antworten gefunden, die ich aber nicht so richtig 
verstehe.

von dev (Gast)


Lesenswert?

Geht relativ einfach. Gehört hier aber eigl. nicht hin, sondern in ein 
PHP-Forum. Da ich aber jahrelang PHP entwickelt habe, kann ich hier 
wenigstens nen Bischen was zurück geben :-)

Als erstes musst Du eine Socket-Verbindung zum Rasberry öffnen (PHP-Code 
wird ausgeführt, wenn Du auf den Button klickst. Der Webserver muss sich 
im gleichen Netzwerk befinden, wie der Raspberry damit beide sich über 
ihre IP erreichen können(!). Der Webserver muss also lokal laufen - z.B. 
auf Deinem Notebook):

// IP des Raspberry
$raspberryIp = "192.168.1.133";
$raspberryPort = 31337;

$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_nonblock($sock);
socket_connect($sock, $raspberryIp, $raspberryPort);
socket_set_block($sock);
switch(socket_select($r = array($sock), $w = array($sock), $f = 
array($sock), 5))
{
        case 2:
                echo "[-] Connection Refused\n";
                break;
        case 1:
                echo "[+] Connected\n";
                break;
        case 0:
                echo "[-] Timeout\n";
                break;
}
?>


In Case 1 sendest Du dann Deine Datenpakete. z.B. so:

$st = "TV VOLUME +1";
$length = strlen($st);

    while (true) {

        $sent = socket_write($sock, $st, $length);

        if ($sent === false) {

            break;
        }

        // Check if the entire message has been sented
        if ($sent < $length) {

            // If not sent the entire message.
            // Get the part of the message that has not yet been sented 
as message
            $st = substr($st, $sent);

            // Get the length of the not sented part
            $length -= $sent;

        } else {

            break;
        }

    }

----

Natürlich brauchst Du auf dem Raspberry dann auch noch ein PHP-Skript, 
dass als TCP-Socket-Server läuft und auf dem Port, z.B. 31337 den Befehl 
"TV VOLUME +1" entgegen nimmt, parsed (z.B. mit explode(' ')) und dann 
z.B. per Kommandozeile (system('das auszuführende Kommando')) 
tatsächlich diese Operation ausführt - also den Fernseher lauter stellt.

Wie das geht, steht hier:

http://www.phpgangsta.de/wie-erstelle-ich-einen-socket-server-in-php

Stell den Port auf 31337 ein. Das Skript muss auf dem Raspberry 
DURCHGEHEND (also als Daemon) laufen, damit es zu jeder Zeit Anfragen 
vom Webserver annehmen kann. Schau Dir die $data-Variable an. Da kommt 
Dein Kommando dann an. Also "TV VOLUME +1". Anstatt dem switch-case 
implementierst Du den explode(' '), wertest der Reihenfolge nach die 
auszuführenden Aufgaben aus und baust Dir dann dynamisch das 
Shell-Kommando zusammen, mit dem Du Deine eigl. Hardware am Raspberry 
ansteuerst, den Fernseher tatsächlich lauter zu regeln.

Viel Erfolg,

dev (Der mal in der Ausbildung einen volständigen HTTP-Webserver mittels 
TCP-Socket API in PHP entwickelt hat - wer braucht schon Apache ;)

von c-hater (Gast)


Lesenswert?

Samuel J. schrieb:

> Wie sieht der PHP-TCP Teil aus? Ich habe bereits
> gegooglet und Antworten gefunden, die ich aber nicht so richtig
> verstehe.

Tja, dann wirst du halt noch ein wenig lernen müssen, bis du sie 
verstehst. Das kann dir niemand abnehmen.


Und ich persönlich würde es ganz sicher auch dann nicht wollen, wenn es 
möglich wäre.

von Samuel J. (capstrovor)


Lesenswert?

@dev

Ok vielen Dank für deine Antwort!

Also auf dem Arduino läuft ein Programm, dass auf den Port 8765 hört und 
eben Befehle wie SEND_ONCE [Name der Fernbedienung] [Name des Knopfes] 
entgegen nimmt. Jetzt könnte ich doch eigentlich den Port von 31337 auf 
8765 umstellen und den PHP Socket Server weglassen, oder?

lg

PS: Die Website ist auf dem Apache, welcher auf dem Raspberry Pi läuft.

@c-hater

Ja deswegen frag ich ja hier damit ich es lernen kann.

von dev (Gast)


Lesenswert?

@Samuel

danke nochmal für Deine Hilfe in meinem Thread.

Samuel J. schrieb:
> Also auf dem Arduino läuft ein Programm, dass auf den Port 8765 hört und
> eben Befehle wie SEND_ONCE [Name der Fernbedienung] [Name des Knopfes]
> entgegen nimmt. Jetzt könnte ich doch eigentlich den Port von 31337 auf
> 8765 umstellen und den PHP Socket Server weglassen, oder?

Ja genau, das kannst Du dann weg lassen. Den Port stellst Du einfach auf 
8765.

Samuel J. schrieb:
> PS: Die Website ist auf dem Apache, welcher auf dem Raspberry Pi läuft.

Wunderbar. Dann stellst Du den Port noch auf 127.0.0.1 ein, weil die 
beiden dann auch problemlos über das loopback-Interface miteinander 
reden können. Du brauchst Dir dann auch keine Sorgen machen, dass wenn 
Du dem Ding mal ne andere IP zuweist (z.B. wegen DHCP-Geschichten) dass 
Du das dynamsich auslesen oder den Programmcode ändern müsstest.

LG

von dev (Gast)


Lesenswert?

korrektur: Du stellst natürlich den Host, also $raspberryIp auf 
127.0.0.1 - nicht den Port! :-)

von Samuel J. (capstrovor)


Lesenswert?

Kein Problem :)

Ok vielen Dank!!
Das klingt schon mal gut.

lg

von Marcus W (Gast)


Lesenswert?

Diese ganze Socket-geschichte kannst du dir sparen, wenn der rPi eh 
einen Webserver hat - du führst schlicht mit z.B. exec() ein 
Konsolenkommando aus, das den Fernbedienungsteil ausführt...

von A. H. (dev)


Lesenswert?

Stimmt, der Wald... die Bäume.... - peinlich ;-)

Wie Marcus schon sagte.., pack in Dein PHP-Skript einfach nen system() 
bzw. exec()-Aufruf rein.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.