Forum: Mikrocontroller und Digitale Elektronik Werte verarbeiten und laufend aktualisieren (AJAX)


von Marcus W. (makkez)


Lesenswert?

Hallo zusammen,


ich lese mit dem Raspi über einen A/D-Wandler Werte von einem 
10Gang-Poti ein. Funktioniert problemlos.
Ich habe ein Webinterface aufgebaut, mit dem ich nun in Echtzeit die 
Werte dort anzeigen lassen möchte. Die Aktualisierung des Wertes sollte 
nach jeder Sekunde (oder weniger als 1s) erfolgen.
Nun ist die Frage wie man das am besten umsetzen kann.

Es scheidet aus, die Seite dauerhaft komplett zu aktualisieren.

Ich habe in einigen Threads was von AJAX gehört, womit das wohl möglich 
wäre. Da mein Wissen über HTML, PHP JAVA usw. nicht ganz ausreicht, um 
die AJAX Hilfestellungen aus dem Netz  komplett zu verstehen, hoffe ich 
hier vielleicht ein paar einfachere und/oder direktere Lösungsvorschläge 
zu bekommen bzw. vielleicht hat jemand schon mal so ein Projekt gehabt 
und könnte mir mit einer kleinen Anleitung (oder LINK) weiter helfen.

Vielen Dank, Makkez

von Peter II (Gast)


Lesenswert?

Man kann es z.b. mit jquery machen

http://api.jquery.com/jquery.ajax/

jquery biete auch Timer an, damit kannst du jedes sekunde so ein reqest 
erzeugen.

von Cube_S (Gast)


Lesenswert?

Mit jquery und PHP lösbar:

Die Hauptseite könnte so aussehen:
1
<!DOCTYPE html> 
2
<html>
3
  <body>
4
    <script src="jquery.js"></script>
5
    <script type="text/javascript">
6
      $( document ).ready(function(){
7
        setInterval(function(){
8
            $.ajax({
9
              type: "GET",
10
              url: "messwert.php",
11
              success: function(result) {
12
                $( "#messwert" ).text(result.wert);
13
                $( "#datum" ).text(result.datum);
14
              }
15
            });
16
        }, 1000);
17
      });
18
    </script>
19
    
20
    Mein Messwert: <span id="messwert" ></span><br/>
21
    Gemessen am: <span id="datum"></span>
22
    
23
  </body>
24
</html>

Hier wird jede Sekunde (die 1000) ein Datenobjekt aus "messwert.php" 
nachgeladen. Diese "Seite" könnte so aussehen:
1
<?php
2
  date_default_timezone_set('UTC');
3
  $wert = 33;
4
  $datum = date(DATE_RFC822);
5
  $result = array("wert" => $wert, "datum" => $datum);
6
  
7
  header('Content-Type: application/json'); 
8
  echo json_encode($result); 
9
?>

"json_encode" gibt quasi ein JavaScript-Kompatibles Objekt zurück, 
welches in der Interval-Funktion benutzt werden kann.

von Frank (Gast)


Lesenswert?

Ich hab vor kurzem mal was ähnliches gemacht.
War nach dem ähnlichem Schema wie von Cube_S.

Eine andere wäre über WebSockets.
Eine C Applikation liest die Poti Werte.
Wird die Page aufgerufen wird in einem JavaScript der Websocket zur C 
Applikation geöffnet und die Daten ausgetauscht.

von Mick (Gast)


Lesenswert?

Hallo Makkez

node.js und Socket.io ist für dein Vorhaben optimal geeignet. So, wie du 
schreibst, benötigst du aber in jedem Fall etwas Einarbeitungszeit.

Falls du das so umsetzen möchtest, kann ich dir ein paar Codebeispiele 
zur Verfügung stellen.

von Eisebär (Gast)


Lesenswert?

Hi,

Ich stehe seit Tagen vor dem gleichen Problem, weil ich über den 
Raspberry mit node.js (nur Websocket ist schnell genug) einen Slider auf 
einer Webseite realisieren will. Die Werte des sliders sollen dann über 
I2C auf einen Atmel geschickt werden, der mein Licht dimmt.

Mein Problem dabei: Es wird immer vorausgesetzt, daß man Linux-Fachmann 
ist. Bin ich aber nicht. Ich finde Schnipsel, die ich dann nicht 
zusammensetzen kann.

Geschafft habe ich, node zu installieren (und express).
Über beides kann ich ein "Hello, World!" auf den Browser bringen.
Dann habe ich etliche Seiten gefunden, auf denen ein Server- und ein 
Client-Teil stehen. Das beschreibt mein grundsätzliches Problem recht 
gut: Es steht nämlich nirgens dabei, wo der Client-Teil hinkommen soll. 
Ok, dann endlich gelöst, einen Public-Folder angelegt und in der app.js 
eingebunden.
Auch hier das "Hello World!"

Unabhängig davon kann ich meinen Atmel mit I2C beschicken.

So, und jetzt stehe ich an.

Ich bräuchte (und wäre unendlich dankbar):

eine index.html, die mir einen slider und zwei Textboxen anzeigt, in der 
einen den Slider-Wert.
Sobald der Slider bewegt wird, soll er die Daten per jQuery mit ajax an 
den Raspberry schicken und von ihm auch wieder zurückbekommen. Der 
Rückgabewert soll in die zweite Textbox geschrieben werden.
Also sollten dann in beiden Textboxen die gleichen Werte stehen.

Und eine Info: Wenn ich jQuery, jQuery mobile und die dazugehörigen 
css-Dateien auf den Raspberry lege, wie muß ich das in der app.js 
eintragen?

Ich weiß, es ist viel verlangt, aber nach den letzten Tagen zucke ich 
nur noch schwach, wenn ich das Google-Logo sehe.

Als Gegenleistung für die Community kann ich nur anbieten, eine Schritt 
für Schritt Anleitug (samt Installation der Komponenten an einem nackten 
Raspi) zu schreiben. Eine, die auch Linux-Dummies wie ich verstehen.

Damit wäre dann nicht nur mir, sondern auch Makkez geholfen.

hoffnungsvoll,
Stefan

von Mick (Gast)


Lesenswert?

Hallo Stefan

Hier findest du die Lösung für dein Problem: 
http://dev.toldotechnik.li/wp-content/uploads/2015/07/slidertest.zip
Es sind lediglich zwei Dateien (app.js und index.html).

Installation wie folgt:
- ZIP Datei entpacken und auf den Raspberry Pi kopieren.
- Auf dem Raspberry Pi im Ordner "slidertest" folgende Module 
installieren: npm install socket.io express
- node.js Applikation starten mit: node app.js
- Browser starten und folgende URL aufrufen: http://RPI_IP:8080

Optische Optimierungen (CSS) haben wir weggelassen. Du musst ja auch 
noch was zu tun haben :-)

LG

===== Quellcode app.js =====
1
var express = require('express');
2
var io = require('socket.io')();
3
4
//*** WEB SERVER ***//
5
var app = express();
6
app.use(express.static("./html"));                                  //statischer ordner "html" einbinden
7
server = require('http').createServer(app);                //web server erstellen
8
io.listen(server);                            //secket.io listener anhängen
9
server.listen(8080, function(){                               //web server auf port 8080 starten
10
  console.log("webserver: now running on port %d", 8080);
11
});
12
13
//*** SOCKET.IO ***//
14
io.sockets.on('connection', function(socket) {
15
    console.log("socket.io: new client connected:" + socket.handshake.address);
16
  //slider wert vom browser erhalten
17
    socket.on('sliderValueFromBrowser', function(value) {
18
        console.log("socket.io: got slider value: " + value);
19
        //wert zurücksenden an browser
20
        io.emit("sliderValueFromRPi", value);
21
  });
22
});

===== Quellcode html/index.html (h.r.e.f anpassen!) =====
1
<!doctype html>
2
<html>
3
4
<head>
5
    <meta charset="utf-8">
6
    <title>Slider Roundtrip Test</title>
7
    <link rel="stylesheet" h.r.e.f="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
8
    <script src="//code.jquery.com/jquery-1.10.2.js"></script>
9
    <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
10
    <script src="//cdn.socket.io/socket.io-1.3.5.js"></script>
11
    <script>
12
        $(function() {
13
            //socket.io objekt erstellen (auf port 8080)
14
            var socket = io.connect(':8080/');
15
16
            //slider
17
            $("#slider").slider({
18
                //change event des sliders
19
                change: function(event, ui) {
20
                    //aktueller slider wert in textbox schreiben (standard 0-100)
21
                    $("#valueLocal").val(ui.value);
22
                    //aktueller wert über socket.io senden
23
                    socket.emit("sliderValueFromBrowser", ui.value);
24
                }
25
            });
26
27
            //socket.io events
28
            socket.on("sliderValueFromRPi", function(value) {
29
                //rückgabewert vom raspberry in textbox schreiben
30
                $("#valueRemote").val(value);
31
            });
32
        });
33
34
    </script>
35
</head>
36
37
<body>
38
    <div id="slider"></div>
39
    <div>Lokaler Browser Wert:
40
        <input id="valueLocal" type="text" />
41
    </div>
42
    <div>Wert vom Raspberry Pi
43
        <input id="valueRemote" type="text" />
44
    </div>
45
</body>
46
47
</html>

: Bearbeitet durch User
von Eisebär (Gast)


Lesenswert?

Hi,

Begeistert, mehr kann ich einstweilen nicht sagen, als absolut 
begeistert...

Ich kann es jetzt nicht gleich ausprobieren, weil ich den Raspi in der 
Firma hab', aber offensichtlich macht das Ding genau, was ich gesucht 
habe.

Tausend Dank!

Mir sind noch Kleinigkeiten unklar, z.B. bezüglich der Ordnerstruktur, 
aber erst mal versuchen, es hinzukriegen, und bei Bedarf fragen.

Ich weiß zwar nicht, wer "Ihr" seid, aber ich danke Euch vielmals.

Rückmeldung kommt auf jeden Fall, eventuell mit Fragen.

Liebe Grüße,
Stefan

von Eisebär (Gast)


Lesenswert?

nochmal hi,

ich konnte natürlich nicht warten und habe dem Raspi, den ich hier 
zuhause habe, schnell das Raspian verpasst.

es funktioniert, ich bin ganz weg...

Also nochmal: Tausend Dank!

Was ich mir noch ansehen muß: Beim "Schieben" des Sliders werden die 
Werte nicht aktualisiert, erst beim Loslassen, obwohl Ihr es doch an 
"change" gebunden habt. Eigentlich soll ja schon während des Schiebens 
das Licht dimmen. Aber das ist eine js/jQuery-Sache, da komm' ich 
hoffentlich schon dahinter.

Ich hab' nur grad Gäste hier, die schon schimpfen, und sechs Bier 
getrunken.
Nicht die besten Voraussetzungen...

Ich melde mich dann wieder, einstweilen danke und liebe Grüße,
Stefan

von Frank (Gast)


Lesenswert?

Eisebär schrieb:
> Beim "Schieben" des Sliders werden die Werte nicht aktualisiert, erst
> beim Loslassen, obwohl Ihr es doch an "change" gebunden habt.

Ich meine das es da noch das Slide-Event gab.

Eisebär schrieb:
> Ich hab' nur grad Gäste hier, die schon schimpfen, und sechs Bier
> getrunken.

Na dann Prost.

von Daniel A. (daniel-a)


Lesenswert?

Eisebär schrieb:
> Was ich mir noch ansehen muß: Beim "Schieben" des Sliders werden die
> Werte nicht aktualisiert, erst beim Loslassen, obwohl Ihr es doch an
> "change" gebunden habt.

Ich weis nichts über jquery ui slider, aber falls daraus range inputs 
werden, dann ist dass das Korrekte verhalten eines Rangeinputs cange 
events. siehe:
https://bugzilla.mozilla.org/show_bug.cgi?id=853670

Ersetze mal das change: durch slide:
Siehe auch: 
http://stackoverflow.com/questions/9121160/jquery-ui-slider-value-returned-from-slide-event-on-release-is-different-fro

PS: Ich mag jquery nicht, es verkürtzt und verschleiert einiges, dadurch 
wird ein einfaches  <input type="range"  zum undurchsichtigen 
$("").slider  und ein simples input.addEventListener("input" zum 
obscuren slider({slide:

von Mick (Gast)


Lesenswert?

Eisebär schrieb:
> es funktioniert, ich bin ganz weg...
>
> Also nochmal: Tausend Dank!

Gerngeschehen :-)

Du kannst den "change"-Event auf "slide" ändern. Dann werden die Werte 
schon während des Ziehens übertragen.

Hier noch die Dokumentation des jQuery Sliders: 
http://api.jqueryui.com/slider/

von Eisebär (Gast)


Lesenswert?

hi,

Mick, ich kann wirklich nicht oft genug danken...

Durch slide ersetzt, das Ding läuft ja mit affenartiger Geschwindigkeit, 
Technik ganz groß.

Ich hab' beim Testen vorher den input type=range verwendet, und wußte 
nicht, daß jQueryUI einen eigenen slider anbietet. Der slider von jQuery 
ist ja etwas ganz anderes, das ist verwirrend, wenn man sucht.

@Daniel: Ich hab' früher viel mehr programmiert (bin, wie Ihr seht, 
schon lange nicht mehr uptodate), und hab' schon 2000 begeistert  mit 
XMLHttpRequest gearbeitet, lange bevor von AJAX oder Web2.0 die Rede 
war. Bibliotheken wie später jQuery mochte ich damals auch nicht, man 
verliert, wie Du sagst, die Kontrolle. Und nachdem in der Firma ohnehin 
alle den gleichen Browser (IE) verwenden, muß man sich auch darüber 
keine Sorgen machen.

In jQuery hab' ich erst reingerochen, als ich mein Licht schalten 
wollte, einfach weil jQuery mobile super dafür geeignet ist. Das läuft 
jetzt seit drei Jahren mit einem atMega328 als Webserver einwandfrei, 
aber nun wollte ich halt auch dimmen können.

Ich spiel das Image noch mal auf den Raspberry drauf, mach eine 
Schritt-für-Schritt-Anleitung für Dummies (obwohl das oben von Mick ja 
dem schon sehr nahekommt), und stell es ins Arduino.cc-Wiki. Kann 
natürlich gern von einem Mitglied hier auch ins hiesige Forum kopiert 
werden.

Ich meld' mich dann, nochmals tausend Dank an Mick und liebe Grüße aus 
Wien an alle,
Stefan

von Mick (Gast)


Lesenswert?

Freut mich, dass dir die Codeschnipsel aus unserem Firmenarchiv 
weitergeholfen haben.

Ein Video von deinem neuen Dimmer wäre noch ganz interessant :-)

LG

von Eisebär (Gast)


Lesenswert?

hi,

Sehr gern, ich hab' eine von den Platinen zum Lichtschalten mit 40 LEDs 
zum Testen umgebaut. Muß nur erst die Schaltung aufbauen. Es geht ja:

Raspberry > i2c > atMega1284 > MAX485 > CAT6 > MAX485 > atMega328

Und auch noch auf mobile umbauen. Hab' jetzt kurz probiert, dann war 
zwar der slider hübsch, aber hat nichts mehr gesendet War wirklich nur 
ein kurzer Versuch, morgen in der Firma kann ich das viel gemütlicher.

gruß Stefan

von Mick (Gast)


Lesenswert?

Hallo Stefan

Der Raspberry unterstützt kein I2C Clock Stretching. Das fürht zu 
Übertragungsfehlern zum ATmega. Einzig das Drosseln der I2C 
Übertragungsgeschwindigkeit führt zu einem aktzeptablen Ergebnis.

$nano /boot/config.txt
Zeile einfügen (baud 10k):
dtparam=i2c=on,i2c1_baudrate=10000

LG

von Eisebär (Gast)


Lesenswert?

Hi, Mick,

Deinen letzten Post verstehe ich jetzt nicht, ich hab' ja (bis jetzt) 
keine Probleme mit i2c.
mit "hat nichts mehr gesendet" hab' ich gemeint, "an den node-Server".

Ich wollte mir das in der Firma ansehen, hatte aber erst nicht soviel 
Zeit und dann kam es zu Phänomenen, die mir bisher unerklärlich sind.

ich erzähl' es Dir, aber nicht, weil ich Dich (zu diesem Zeitpunkt) um 
Hilfe bitte, es sollte eigentlich trotzdem machen, was ich will, Aber es 
ist, finde ich, sehr interessant.

Erstmal meine Konfiguration hier in der Firma:

Einen Raspi mit node und zwei Windows-Rechner an einem WLAN-Router, an 
dem noch ein LTE-Datenstick hängt, der alle drei Rechner ins Internet 
bringt.

Viele Rechner im Firmennetz, die über einen Proxy in Deutschland im 
Internet hängen.

Ich hab' mich gleich heute morgen über's Firmennetz mit dem Raspi 
zuhause verbunden, funktioniert sogar über Deutschland superschnell.

Dann hab' ich den Raspi hier in der Firma fertig gemacht, funktioniert.

Als nächstes hab' ich auf einem zweiten Rechner am Router die Seite 
aufgerufen, funktioniert natürlich auch.

In der Shell (heißt das so?), in der ich node app.js gestartet habe, 
zeigt er mir auch an, wenn sich ein Rechner verbindet, bzw. der Wert 
sich ändert.

Aber mir ist aufgefallen, wenn ich den slider auf einem Rechner schiebe, 
werden die Felder "Wert auf Raspberry Pi" auf beiden Rechnern 
aktualisiert. Der node-Server schickt das also an alle Rechner, die 
dranhängen. Ist ja Super, das kann man nützen.

Also übermütig in der index.html nach

$("#valueRemote").val(value);

ein

$("#slider").slider("value", value);

reingeschrieben, und wenn ich jetzt den slider auf einem Rechner 
verschiebe, bewegen sich beide slider praktisch synchron. Wird ja immer 
besser...

Ab jetzt wird's seltsam:

Ich verbinde mich dann mit einem der Rechner (egal ob an dem Router oder 
einem Firmenrechner) über die öffentliche IP des Routers zum Raspi und 
wenn ich der slider schiebe, wird der Rückgabewert brav angezeigt, ABER:

Auf dem Raspi wird nicht angezeigt, daß sich ein Rechner verbindet und 
die Werte werden auch nicht angezeigt. Auch auf den Rechnern im lokalen 
Netz ändert sich der Rückgabewert diesmal nicht und der slider bewegt 
sich nicht.

Umgekehrt: Wenn ich im lokalen Netz den slider bewege, zeigt er mir das 
auf dem Raspi an, aber auf dem Rechner über's Internet rührt sich 
nichts.

Meine erste Vermutung: Wenn ich's über's Internet mache, funtkioniert 
der node-Server garnicht, und in das Feld "Wert auf Raspberry Pi" wird 
der wert von "Lokaler Browser Wert" eingetragen, weil nichts 
zurückkommt.  Heißen ja beide value.

Aber nein! Ich habe mich dann mit zwei Rechnern über's Internet mit dem 
Raspi verbunden, keine Reaktion im schwarzen Fenster, keine Werte, aber 
ich sehe auf einmal, daß in diesem Fall das Feld "Wert auf Raspberry Pi" 
auf beiden Rechnern wieder synchronisiert wird.

Der slider auf dem zweiten Rechner bewegt sich allerdings nicht.

Ein langer Post, aber ich wollte es möglichst genau schildern. Das ist 
doch verrückt. Die drei Dinge:

Empfangenen Wert in der Shell anzeigen.
Empfangenen Wert zurückschicken.
Slider auf den empfangenen Wert setzen

macht er doch unmittelbar hintereinander.

Zusammenfassung:

Der Rückgabewert auf dem Rechner, auf dem ich den slider bediene, wird 
IMMER richtig angezeigt.

Rechner im lokalen Netzwerk:
Verbindung und Wertänderung wird in der Shell angezeigt.

Zwei Rechner im lokalen Netzwerk:
Rückgabewert UND slider auf beiden Rechnern werden aktualisiert.

Rechner im Internet:
Verbindung und Wertänderung wird NICHT in der Shell angezeigt.

Zwei Rechner im Internet:
Rückgabewert auf beiden Rechnern wird aktualisiert, der slider NICHT.

Ein Rechner im lokalen Netzwerk, ein Rechner im Internet:
Weder der Rückgabewert noch der slider auf dem jeweils anderen Rechner 
werden aktualisiert.

Wie gesagt, sollte meine Anwendung ja trotzdem funktionieren, aber es 
ist so verrückt...

Liebe Grüße, ein fassungsloser Stefan

von Eisebaer (Gast)


Lesenswert?

hi,

Nachtrag:

Ich hab' den Raspberry grade runtergefahren, während die Seite auf einem 
anderen Rechner noch geöffnet war.

Wenn ich den slider bewege, wird der Rückgabewert trotzdem aktualisiert, 
also da dürfte value wirklich "durchschlagen".

gruß stefan

von Frank (Gast)


Lesenswert?

Eisebär schrieb:
> Raspberry > i2c > atMega1284 > MAX485 > CAT6 > MAX485 > atMega328

Für was ist denn der Atmega1284?
Bzw. wieso der Umweg über I2C?

von Mick (Gast)


Lesenswert?

Keine Ahnung. Habe deine Problematik auch nicht ganz verstanden. Werde 
mir deine Schilderungen morgen nochmals genau durchlesen :-)

Kann es sein, dass du dich mit dem Raspberry zu hause verbunden hast, 
ohne es zu merken?

von Eisebaer (Gast)


Lesenswert?

hi,

den Gedanken hatte ich dann auch gestern beim Nachhausefahren. So muß es 
sein, das würde alle Seltsamkeiten erklären.

Die IP-Adresse hatte ich von einer Webseite, die die einem die eigene IP 
anzeigt. Man steigt aber mit seinem User ein, und offensichtlich zeigt 
die Seite nicht unbedingt die "aktuelle" Adresse.

Ich überprüf' das gleich, sobald ich bei meinem Aufbau bin, aber anders 
ist es ja garnicht möglich...

Gruß stefan

von Eisebär (Gast)


Lesenswert?

hi,

MeineGüte, ist das peeeeiiiinlich...

Die Webseite hat mir eine gespeicherte IP angezeigt und ich hab' mich 
dorthin verbunden.

Erklärt natürlich alles.

Ich setz mich jetzt mal in die Ecke und schäme mich.

von Eisebär (Gast)


Lesenswert?

hi,

Ich wollte mich mal wieder melden, schließlich hab' ich ja auch was 
versprochen (ein Tutorial für Dummies wie mich), ich hab' das nicht 
vergessen...

Aber erst war Urlaub, danach viel in der Firma zu tun nach dem Urlaub, 
und dann hat jQuery beschlossen, mich zu ärgern.

Aber: "Du musst ja auch noch was zu tun haben :-)" hat Mick gesagt, und 
das ist schon gut so.

Der slider von Mick ist ja der jQuery-ui-slider. ich brauch aber 
jQuery-mobile. es soll ja auf Tablets und dem Handy gut aussehen. also 
umgebaut. schöner Mist, mobile unterstützt keinen slide-event. den 
brauche ich aber, weil ich will, daß auf den beiden Tablets an der wand 
der Wohnung der slider "mitfährt", wenn man auf einem anderen Gerät 
etwas verstellt.

Nach einigem Suchen fand ich eine Möglichkeit, mobile nach ui 
einzubinden und trotzdem den slider von ui zu verwenden. Alles war da, 
Freude und Eierkuchen, aber dann hab' ich gemerkt (und mich erinnert, 
ich hatte es nur verdrängt), daß der ui-slider auf mobilen Geräten nicht 
funktioniert.  Man kann zwar "tippen", aber nicht "ziehen".

Depression.

Aber: Auch dafür gibt es eine Lösung! Noch eine kleine Bibliothek nach 
ui eingebunden, und es funzt.

So, das war's auch schon, sollte ja nur ein Zwischenbericht sein. Doku 
folgt, sobald es eine schöne Seite für Mobiles ist.

Noch ein Danke, ich such' ja wirklich gern selbst nach Lösungen, aber 
mir hat der Anfang des Fadens gefehlt.

Gruß Stefan

PS: Doch noch eine Frage: Kennt jemand hier freien Webspace. wo ich 
einen Node-Server betreiben könnte, um meine Doku auch interaktiv zu 
machen?

Ich hab' heute gesucht, das Vielversprechendste war OpenShift, aber da 
muß man dann plötzlich ein git haben, ein repository, ssh installieren 
und konfigurieren und pipapo. Ich will doch nur einen Ordner, in den ich 
meine app.js stelle und dazu einen Unterodner für die html- und 
js-Dateien. Ein Button, um den node-Server neu zu starten, nachdem man 
was verändert hat, und das war's.

noch ein Gruß, Stefan

von Mick (Gast)


Lesenswert?

Hallo Stefan

Probier's mal mit ngrok (https://ngrok.com/) Damit kannst du einen Port 
von deinem Raspberry über das Internet zugreifbar machen. Dann brauchst 
du nicht extra einen Webserver dazu.

Grüsse

von Eisebär (Gast)


Lesenswert?

hi, Mick,

Nett von Dir, aber das will ich eher nicht. Trotzdem danke...

Ich werde mir lieber einen externen node-server suchen und dazu meinen 
Neffen ausfragen, der arbeitet exzessiv mit gits und dem Zeuch.

Gruß Stefan

von Daniel A. (daniel-a)


Lesenswert?

Eisebär schrieb:
> PS: Doch noch eine Frage: Kennt jemand hier freien Webspace. wo ich
> einen Node-Server betreiben könnte, um meine Doku auch interaktiv zu
> machen?

Ich betreibe meinen Zuhause, mit einer Statischen IP und eigenem DNS 
Server und eigenem Domain Name (danielabrecht.ch und mvsync.ch). Die 
statische IP war nach dem zwangswechsel auf Quickline zwar nichtmehr 
gratis, aber mit einem Server Zuhause kann man auch Programme schreiben 
um Geräte im Heimnetzwerk von aussen zu bedienen, etc. Natürlich könnte 
ein der ISP und andere die Dazwischenhänngen immernoch Ports usw. 
sperren, aber das ist wesentlich unwarscheinlicher und man hat die volle 
kontrolle wer Zugriff zum PC und dessen Daten hat (mal abgesen von der 
NSA, die sich überall hintertüren einbauen lässt)

PS: Doku interaktiv zu machen heisst Dokumentation zu schreiben, die auf 
eingaben des Benutzers reagiert, was nicht immer sonderlich sinvoll ist.

von Eisebär (Gast)


Lesenswert?

hi,

Daniel, ich möchte nicht gerne, daß fremde Leute in meinem Netzwerk 
zuhause fuhrwerken. Ich mache das schon, der Raspberry und die Dreambox 
sowie ein Atmel mit W5100er, der mein Licht derzeit schaltet, sind von 
außen erreichbar.

Wenn ich aber die Demo mache, sollte das einfach irgendwo extern liegen. 
Zeigen möchte ich damit, wie schnell das funktioniert, indem ich z.B. 
eine Farbfläche dimme, und zwar mit den Werten, die vom Server 
zurückkommen. Außerdem, wie andere Geräte, die am Node-Server hängen, 
reagieren, wenn an einem Gerät etwas geschalten wird.

Gruß Stefan

von Felix P. (flexus)


Lesenswert?

Guten Tag.
Du sagtest du würdest eine Anleitung für Dummis verfassen.
Ich schaue hier gelegentlich mal rein,aber es tut sich nichts.
Könntest du eventuell mal bitte kurz umreißen welches Modul was macht,
wann, und wieso.
Wen ich das dann mal begriffen hätte wüsste ich, was ich sonst noch so 
zu lernen hätte,,,alleine.
Ich bin wirklich lernwillig, aber sehe den Wald gerade vor lauter Bäumen 
nicht.

von Eisebär (Gast)


Lesenswert?

hi,

so, jetzt hab' ich endlich eine kleine anleitung zur installation des 
node-servers geschrieben:

http://playground.arduino.cc/PmWiki/Haustechnik-Eisebaer

danke nochmal für die hilfe,

stefan

von Sheeva P. (sheevaplug)


Lesenswert?

Eisebär schrieb:
> Mein Problem dabei: Es wird immer vorausgesetzt, daß man Linux-Fachmann
> ist. Bin ich aber nicht.

Wenn man Linux benutzen möchte, ist es vielleicht nicht die schlechteste 
Idee, sich ein paar Kenntnisse darüber anzueignen. Erfreulicherweise 
gibt es wohl kaum eine Software, die so umfangreich und in jeder 
Detailtiefe dokumentiert ist wie Linux -- jedenfalls ist mir noch keine 
begegnet.

> Und eine Info: Wenn ich jQuery, jQuery mobile und die dazugehörigen
> css-Dateien auf den Raspberry lege, wie muß ich das in der app.js
> eintragen?

Zwar habe ich keine Ahnung von node.js, aber mit diesen beiden Seiten 
([1, 2]) sowie dem auf der ersten Seite verlinkten Framework 
"node-router" (da habe ich nur die Datei "node-router.js" [3] aus dem 
Ordner "lib/" gezogen) habe ich folgendes Beispiel geschrieben:
1
#!/usr/bin/nodejs
2
3
var server = require('./node-router').getServer();
4
var fs     = require('fs');
5
6
server.get('/', function(request, response) {
7
    response.simpleText(200, "Yo.");
8
});
9
10
server.get('/eins', function(request, response) {
11
    fs.readFile('eins.txt', 'utf8', function(error, data) {
12
  if(error) { console.log(error); }
13
  response.simpleText(200, data);
14
    });
15
});
16
17
server.listen(8000, 'localhost');

Darin wird jeweils eine Funktion an die URLs "/" und "/eins" gebunden; 
in der ersten Funktion ("/") wird einfach nur der Text "Yo." mit dem 
Code 200 (HTTP Ok) zurückgegeben, in der zweiten Funktion der Inhalt der 
Datei "eins.txt". Dank der Shebang-Zeile kann diese Beispieldatei 
entweder mit "chmod 755 <dateiname>" als ausführbar markiert und mit 
"./<dateiname>" , oder ohne Ausführrechte mit "nodejs <dateiname>" 
ausgeführt werden. Sie startet dann einen Webserver auf "localhost" Port 
8000 (127.0.0.1:8000).

[1] http://howtonode.org/hello-node
[2] 
https://docs.nodejitsu.com/articles/file-system/how-to-read-files-in-nodejs
[3] 
https://raw.githubusercontent.com/creationix/node-router/master/lib/node-router.js

von Mike (Gast)


Lesenswert?

Hallo
ich weiß der Beitrag ist schon älter, aber viellecht liest ihn ja noch 
jemand und kann mir bei meinem Problem helfen.

Ich habe obiges Beispiel von Mick versucht für meine Zwecke zu nutzen.
Dazu wollte ich von der Webseite ein paar Felddaten an den Server 
übertragen, damit auf dem Server arbeiten und dann die Ergebnisse wieder 
zurück an den Client an verschiedene Elemente senden.

Also die Daten aus den Feldern im Client an den Server senden 
funktioniert problemlos. Wobei ich hängen bleibe ist das Zurücksenden 
der Daten an den Client. Sobald der Server die Daten senden möchte läuft 
er in einen Fehler und beendet sich. Der Fehler lautet:

Error: Callbacks are not supported when broadcasting

Meine server.app ( socket Auszug ) sieht wie folgt aus:

io.sockets.on('connection', function(socket) {
    console.log("socket.io: new client connected:" + 
socket.handshake.address);

//wert zurücksenden an browser
        socket.broadcast.emit('test', function (data) {
    console.log("socket.io: send feld1 value: " + data.feld1);
    console.log("socket.io: send feld2 value: " + data.feld2);
    console.log("socket.io: send feld3 value: " + data.feld3);
    });

// wert vom browser erhalten
        socket.on('test', function (data) {
        // zur Überprüfung ob die Daten ankommen
        console.log("socket.io: Feld-1: " + data.feld1);
        console.log("socket.io: Feld-2: " + data.feld2);
        console.log("socket.io: Feld-3: " + data.feld3);

});


Der Client-Teil sieht wie folgt aus:

<script>
$(document).ready(function(){

// WebSocket
    var socket = io.connect();

    // neue Nachricht

// Nachricht senden
    function senden(){
        // Eingabefelder auslesen
        var feld1 = $('#feld1').val();
        var feld2 = $('#feld2').val();
  var feld3 = $('#feld3').val();
// Socket senden
        socket.emit('test', { feld1: feld1, feld2: feld2, feld3: feld3 
});
    }
// bei einem Klick
    $('#senden').click(senden);
});
</script>


Bis zu dem Teil dass die Client Daten angepasst werden bin ich noch gar 
nicht gekommen weil der Server ja beim Versuch zu senden schon stirbt.

Ich versuche seit geraumer Zeit eine Lösung zu finden, ohne fremde Hilfe 
in Anspruch zu nehmen. Aber langsam sehe ich vor lauter Bäume den Wald 
nicht mehr. Ich habe das Konstrukt schon mehrfach umgebaut, lande aber 
immer bei diesem Fehler.

Ich wäre dankbar wenn mir da jemand helfen könnte mein Problem zu lösen 
damit ich weiterbasteln kann :)

In diesem Sinne vielen Dank schon mal dafür.

Gruss
Mike

von Daniel A. (daniel-a)


Lesenswert?

Mike schrieb:
> Error: Callbacks are not supported when broadcasting

Eigentlich müsste ich mir die socketio api anschauen, um darüber etwas 
mit sicherheit sagen zu können, aber ich denke dei Fehlermeldung ist 
ziemlich klar.

> socket.broadcast.emit('test', function (data) {

Die Funktion, die du hier übergiebst, ist die im fehler erwähnte 
callback funktion. Vermutlich kann man, wenn man etwas an einen 
bestimmten client sendet, damit auf eine Antwort eines bestimmten client 
warten. Da du aber an alle also an broadcast, sendest, gibt es keinen 
bestimmten client.

Wenn du an alle daten senden willst, musst du sowas machen:
1
socket.broadcast.emit('test', {key:"value"});
Also irgendwelche werte übergeben. Beim client dann wieder die socket.on 
geschichte, die du schon beim Server hast. Falls du nur an den einen 
Client etwas senden willst, lasse das broadcast weg.

Wenn du dem Client auf die Anfrage antworten willst, musst du vermutlich 
beim Client beim Emmit noch einen callback mitgeben der beim empfangen 
der Antwort aufgerufen wird, und beim server in der Function die bei 
socket.on übergeben wird, etwas mit return zurück geben.

: Bearbeitet durch User
von Mike (Gast)


Lesenswert?

Hi,
Mit deinem Hinweis habe ich es jetzt endlich hinbekommen. Mir hat wohl 
noch der letzte Input gefehlt. Jetzt kann ich endlich den nächsten 
Schritt gehen.
Ich bin mir aber fast sicher dass im weiteren Verlauf noch Hilfe 
benötigen werde. Mal schauen.. :)
Danke bis dahin für deine Hilfe

LG

Mike

von Eisebär (Gast)


Lesenswert?

hi,

bevor jemand in die falle läuft:

mir ist vor die micro-sd-karte eingegangen und ich hab' versucht, 
einfach alles neu zu installieren. irgendwie beißt sich das mit den 
versionen.

node 0.12 passt mit socket.io und express anscheinend nicht mehr 
zusammen.
wenn ich aber node 8 verwende und das originale programm von hier nehme 
oder auch meines, das seit jahren läuft, dann kommt, sobald ich über 
einen browser verbinde, eine endlose anzeige in der raspberry-konsole, 
das sich der client mit ip xxx.xxx usw verbunden hat.

zeile für zeile für zeile

sonst funktioniert dann nichts mehr. muß nach dem feiertag mal suchen, 
woran das liegt.

gruß stefan

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.