Eine Wetterstation mit dem NodeMCU

Themabewertung:
  • 0 Bewertung(en) - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
tesacrep
Administrator
*******

Beiträge: 500
Registriert seit: Dec 2013
Bewertung: 2
#11
26.08.2017, 00:25

Hey,


Zitat:Welche Schnittstelle meinst Du jetzt? Doch hoffentlich nicht die zu den Sensoren. Das wird dann nämlich reichlich komplex.
Eigentlich genau diese. Ich hatte mir die Schnittstelle in etwa so vorgestellt:

Der Controller ruft eine URL auf und gibt folgende Parameter mit: Key, Passwort, Sensorwert, Sensor.
Ich will das jeder Konfigurieren kann welche Sensoren er einsetzt. Folglich muss der Controller für acht Sensoren nachehr acht aufrufe machen.
Im "Backend" oder besser gesagt der Weboberfläche soll man dann festlegen können welcher Name welcher Sensor ist. Hier kann man sich dann auch Grafiken usw. Exportieren.

Das Problem mit der Zeit würde ich auch über das Internet lösen. Immer wenn Daten gesendet werden soll hier einfach der Zeitstempel gespeichert werden. Beim speichern auf der SD Karte bringt das natürlich nix. Eventuell kann man ja die Zeit auch aus dem Internet holen.

Wind und Regen finde ich auch interessant - aber die Sensoren sind einfach die teuersten. Deswegen würde ich die gerne am Anfang weglassen und dann ergänzen.

Das Problem mit den 3.3v habe ich bisher gar nicht bedacht. Es gibt da ja aber relativ gute Konverter.

Naja da sieht man wie gut das ganze durchdacht werden muss.


Grüße

tesacrep
Zitieren
Unilein
Fachgebiet Rauchentwicklung
*******

Beiträge: 726
Registriert seit: Apr 2014
Bewertung: 5
#12
26.08.2017, 12:33

Zitat:Der Controller ruft eine URL auf und gibt folgende Parameter mit: Key, Passwort, Sensorwert, Sensor.
Ich will das jeder Konfigurieren kann welche Sensoren er einsetzt. Folglich muss der Controller für acht Sensoren nachehr acht aufrufe machen.
Im "Backend" oder besser gesagt der Weboberfläche soll man dann festlegen können welcher Name welcher Sensor ist. Hier kann man sich dann auch Grafiken usw. Exportieren.

Mal sehen, ob ich das richtig verstehe.

Du möchtest, dass der Benutzer bzw. Erbauer frei wählen kann, welche Sensoren er einsetzt. Dann aber hoffentlich aus einer festgelegten Auswahl an Sensoren. Und auch mit fest definierten Pins. Das wird sonst mega aufwändig. Und aus meiner Sicht auch nicht Sinnvoll.

Also zur Verdeutlichung:

DHT21 = GPIO4 = An
CO2 = GPIO5 = Aus
Staub = GPIO2 = An

Das Ganze dann in der Konfiguration entsprechend gespeichert.

Dementsprechend dann auch die Ausgabe der Wetterdaten nur für die Module, die aktiv sind (und ggf. die Übertragung auf einen Server)

Richtig verstanden?

Was die Weboberfläche angeht: Die sollten wir ganz zum Schluss machen. Erstmal die zentrale Funktionalität und den Aufbau definieren.

Gruß
Uni
-----

Klopapier beidseitig verwenden und der Erfolg liegt auf der Hand!
Zitieren
Unilein
Fachgebiet Rauchentwicklung
*******

Beiträge: 726
Registriert seit: Apr 2014
Bewertung: 5
#13
26.08.2017, 13:05

Hallo zusammen,

für unsere Wetterstation müssen wir nun die Hardware (nur die Komponenten) festlegen:

Folgendes habe ich überlegt:

* NodeMCU 0.9 (Der kostet inzwischen fast nix mehr, so ca 8,00€ in DE. Geht aber auch für 2,70€ aus China. Unser Admin tesacrep hat noch zwei zu verschenken)
* Micro-SD-Kartenadapter, wie sie für Arduino und andere üblich sind. Natürlich mit SPI-Schnittstelle!
* DHT11, DHT21, DHT22 (Temperatur und Luftfeuchte. Wobei DHT21 für den Außeneinsatz am besten geeignet ist, zwischen 7,50€ und 9,00€, in China 2,19€ Big Grin )
* BH1750 Lichtsensor (für die Helligkeitsmessung, kostet zwischen 3,10€ und 4,00€)
* BMP180/BMP280 Luftdruck (BMP280 scheint etwas genauer zu sein und kostet zwischen 3,00€ und 5,00€, BMP180 geht aber natürlich auch)
* WH1080 Anemometer (Das ist ein Ersatzteil für die Wetterstation WH1080. Kostet ca 20,00€)
* ML8511 UV Sensor (Zur Messung des UV-Index. Kostet zwischen 7,00€ und 8,00€.)
* MG811 CO2-Sensor (Zur Messung der CO2-Konzentration in der Luft. Verhältnismäßig teuer: Zwischen 43,00€ und 65,00€ aus China [Achtung Zoll und Einfuhrumsatzsteuer können hier nochmals zuschlagen] )
* Sharp GP2Y1010AU0F Feinstaubsensor für ca 14,00 € oder SDS018 für 28,00€. (Das Teil arbeitet übrigens seriell)
* Regenmesser (Bislang keine Idee für ein passendes Modul, aber wenn schon Regenmesser, dann bitte Niederschlagsmenge und nicht nur "es regnet")

Bitte schaut doch mal, ob das so passt. Wenn nicht, dann bitte alternative Vorschläge.

Gruß
Uni
-----

Klopapier beidseitig verwenden und der Erfolg liegt auf der Hand!
(Dieser Beitrag wurde zuletzt bearbeitet: 26.08.2017, 13:10 von Unilein.)
Zitieren
Unilein
Fachgebiet Rauchentwicklung
*******

Beiträge: 726
Registriert seit: Apr 2014
Bewertung: 5
#14
26.08.2017, 13:08

Was den Bau der Station angeht, würde ich vorschlagen, alle Entscheidungen und Fortschritte in einem eigenen Thread zu sammeln.
So wird es für Elektronikfreunde, die nachbauen wollen einfacher, dem Aufbau zu folgen. In dem eigenen Thread werden also nur Ergebnisse festgehalten und keine Diskussionen geführt.

Diskussionen, Vorschläge, Änderungen, Probleme usw... Alles hier in diesen Thread.

Einverstanden? Wenn ja, dann lege ich einen solchen Thread an und beschreibe unser Ziel.

Gruß
Uni
-----

Klopapier beidseitig verwenden und der Erfolg liegt auf der Hand!
Zitieren
tesacrep
Administrator
*******

Beiträge: 500
Registriert seit: Dec 2013
Bewertung: 2
#15
26.08.2017, 19:48

Hey,


klar - finde ich super. Dann bleibt das übersichtlich. Ich werde mal schauen das ich die Tage meinen NodeMCU zum laufen bringe.
Das kann ich ja dann da als erstes eintragen Smile


Grüße

tesacrep
Zitieren
Unilein
Fachgebiet Rauchentwicklung
*******

Beiträge: 726
Registriert seit: Apr 2014
Bewertung: 5
#16
29.08.2017, 20:32

Mal schnell ein paar Infos zu einigen der genannten Sensoren:

* DHT22 = AM2320B = AM2301 = DHT11 Und wird auch genauso angesprochen wie DHT11. Eine passende Lib gibt's auch für NodeMCU. Lib: https://github.com/chaeplin/PietteTech_DHT-8266

* BMP280 funktioniert wie BMP180 und hat ein I2C Schnittstelle. Lib: https://github.com/adafruit/Adafruit_BMP280_Library

* BH1750 hat ebenfalls eine I2C Schnittstelle. Lib: https://github.com/claws/BH1750

* ML8511 hat einen analogen Ausgang. Eine Lib benötigt man nicht. Aber hier ein Beispiel: http://www.esp8266learning.com/wemos-ml8511-example.php

Gruß
Uni
-----

Klopapier beidseitig verwenden und der Erfolg liegt auf der Hand!
(Dieser Beitrag wurde zuletzt bearbeitet: 02.09.2017, 18:22 von Unilein.)
Zitieren
Unilein
Fachgebiet Rauchentwicklung
*******

Beiträge: 726
Registriert seit: Apr 2014
Bewertung: 5
#17
31.08.2017, 16:02

Hallo zusammen,

wichtig für unser Projekt ist natürlich auch eine Beschreibung des NodeMCU. Dazu habe ich eine informative Seite gefunden (naja, das war jetzt auch keine Kunst...).
Die Seite lautet: https://nodemcu.readthedocs.io/en/master/en/
Gruß
Uni
-----

Klopapier beidseitig verwenden und der Erfolg liegt auf der Hand!
(Dieser Beitrag wurde zuletzt bearbeitet: 31.08.2017, 16:03 von Unilein.)
Zitieren
Unilein
Fachgebiet Rauchentwicklung
*******

Beiträge: 726
Registriert seit: Apr 2014
Bewertung: 5
#18
31.08.2017, 16:30

Hallo zusammen,

da ich heute ein wenig Zeit hatte, habe ich auch mal einen ersten "Anschlussplan" für die Sensoren am NodeMCU entworfen. Aktuell kommen wir mit den vorgeschlagenen Sensoren und den zur Verfügung stehenden Pin's zurecht. Ob mein Vorschlag so funktioniert, habe ich noch nicht getestet. Das werde ich aber in Kürze tun. Ich werde dann auch ein paar Code-Schnipsel zur Verfügung stellen, mit denen die Sensoren getestet werden können.

Über meine Vorschläge darf sehr gerne diskutiert werden. Momentan können wir noch alles ändern  Smile

Gruß
Uni

   
-----

Klopapier beidseitig verwenden und der Erfolg liegt auf der Hand!
Zitieren
Unilein
Fachgebiet Rauchentwicklung
*******

Beiträge: 726
Registriert seit: Apr 2014
Bewertung: 5
#19
03.09.2017, 14:53

Hallo zusammen,

arbeite ich eigentlich alleine an unserem Gemeinschaftsprojekt? Bin ich zu schnell? Seid Ihr zu langsam? Habt Ihr alle keine Lust, keine Zeit, keine Ahnung wie es weitergeht?  Big Grin  Tongue  Wink

Naja... Ich habe jedenfalls heute mal ein paar Dinge ausprobiert, über die ich Euch nicht im Unklaren lassen möchte. Zuvor hatte ich ja mal überlegt, welche Pins wie verwendet werden könnten. Dabei hatte ich auch D9 und D10 vorgeschlagen. Leider ist das keine gute Idee, da hierüber auch die serielle Kommunikation läuft. Solange man also, zum Beispiel für's Debugging, die serielle Schnittstelle (USB) nutzen will, sind die beiden Pins leider nicht verfügbar. Da kommt dann nur Müll rüber... Sowohl an der seriellen Schnittstelle, als auch die Messwerte, die darüber kommuniziert werden.

Vorübergehend habe ich deshalb einen der für die SD-Karte vorgesehenen Pin's für die Messwerte genutzt. Mir ging es momentan auch nur darum, das erforderliche Coding für die Messungen zu testen. Ich habe mal ein Bildchen beigefügt. Zu sehen sind die Messwerte des DHT22, des BMP280 und des BH1750. Der UV-Sensor befindet sich noch auf dem Weg nach Deutschland und kommt vermutlich erst gegen Ende des Monats.

Gruß
Uni

   
-----

Klopapier beidseitig verwenden und der Erfolg liegt auf der Hand!
(Dieser Beitrag wurde zuletzt bearbeitet: 03.09.2017, 17:54 von Unilein.)
Zitieren
Unilein
Fachgebiet Rauchentwicklung
*******

Beiträge: 726
Registriert seit: Apr 2014
Bewertung: 5
#20
05.09.2017, 20:45

So Leute,

hier mal ein erster, selbstverständlich unvollständiger, Codingvorschlag. Der Code initialisiert die Sensoren und ließt sie aus. die Ergebnisse werden auf die SD-Karte geschrieben. Ein Teil kann per Webseite abgerufen werden (wenn man die IP des NodeMCU kennt). Der Webserver ist noch rudimentär. Zugriffe auf einen NTP-Server habe ich noch nicht realisiert, ebenso das Schreiben der Daten auf eine entfernte Datenbank. Naja... schaut selbst...

Gruß
Uni

 
/*
 
ESP8266 Wetterstation
 
mit Webserver, diversen Sensoren und Multitasking-Abfrage der Sensoren
mit Speicherung der Daten auf SD-Karte und Übertragung der Daten an einen
externen Server
 
Version 0.1
 
- Vorbereitung Webserverfunktionalität
- Vorbereitung Konfigurationsdatei lesen
- Vorbereitung Messungen
 
 
Version 0.5 vom 03.09.2017
 
- Strukturierung Programmcode
- Codeoptimierung
- Vorbereitung Multitasking
- Vorbereitung Datenbanksystem
- Vorbereitung Webseitengenerierung
 
Version 0.6 vom 05.09.2017
 
- weitere Codeoptimierung
- Entfernunf Multitaskingbausteine (Abstürze)
- Datenbankaufzeichnung
 
*/

 
 
 
// Einbinden der Bibliotheken
#include <string.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <PietteTech_DHT.h>
#include <BMP280.h>
#include <BH1750.h>
#include <Wire.h>
#include <SD.h>
#include <EDB.h>
 
 
 
// Vorbelegte Direktiven
#define REPORT_INTERVALL 5000 // Reportingintervall muss > 2000 sein
#define DHT_TYPE DHT22  // DHT-Sensortyp
#define DRUCK_NORMAL 1013.25  // Luftdruck auf Meereshöhe
#define BMP_SDA D1  // SDA-Pin für BMP280
#define BMP_SCL D2  // SCL-Pin für BMP280
#define LH_SDA  D4  // SDA-Pin für LH1570
#define LH_SCL  D7  // SCL-Pin für LH1570
#define DHT_DATA D3  // Daten-Pin für DHT22
#define SELECT_SD D8  // Chipselect der SD-Karte
#define TABLE_SIZE 8192  // Datenbank Tabellengrösse
 
 
// Globale Variable
// Zugangsdaten zum WLAN Router (später über Config-Datei und verschlüsselt)
const char *ssid = "netzwerk ssid";
const char *password = "passwort#";
const char *mDNSName = "wetterstation";
 
// Ergebnisvariable vom DHT22
bool bDHTstarted;       // Flag zur Anzeige, dass DHT arbeitet
float temperatur;
float luftfeuchte;
float taupunkt;
int acquireresult;
int acquirestatus;
unsigned long startMills;
 
// Ergebnisvariable vom BMP280
double temperatur2;
double luftdruck;
double hoehe;
 
// Ergbenis vom BH1570
uint16_t lux;
 
 
// Datenbankstruktur
struct wetterDaten {
int id;
float temperatur;
float luftfeuchte;
float taupunkt;
double temperatur2;
double luftdruck;
double hoehe;
uint16_t lux;
int uvindex;
}
wetterDaten;
 
// Datendateien
File htmlStream;
File logStream;
File dbFile;
String htmlFile;
char* dbName = "wetter.db";
 
 
// Unterprogrammdeklaration
void dht_wrapper();  // Muss vor Benutzung der Bibliothek deklariert sein.
 
void writer (unsigned long address, byte data) {
dbFile.seek(address);
dbFile.write(data);
dbFile.flush();
}
 
byte reader (unsigned long address) {
dbFile.seek(address);
byte b = dbFile.read();
return b;
}
 
 
// Lib-Referenzen initialisieren
EDB db(&writer, &reader);  // Datenbank
ESP8266WebServer server ( 80 );  // Webserver
PietteTech_DHT DHT(DHT_DATA, DHT_TYPE, dht_wrapper);  // DHT22, Luftfeuchte und Temperatur
BMP280 bmp;  // BMP280, Luftdruck und Temperatur
BH1750 LS;  // LH1750, Lichtsensor
 
 
 
// Der Webserver startet mit der Datei "index.htm"
void handleRoot() {
String temp;
char buff[20];
 
temp += "<html>";
temp += "<head>";
temp += "<meta http-equiv='refresh' content='5'/>";
temp += "<title>Wetterstation</title>";
temp += "<style>";
temp += "body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }";
temp += "</style>";
temp += "</head>";
temp += "<body>";
temp += "<h1>Aktuelles Wetter:</h1>";
temp += "<p>Temperatur: ";
itoa(wetterDaten.temperatur,buff,10);
temp += buff;
temp += "</p><p>Luftfeuchtigkeit: ";
itoa(wetterDaten.luftfeuchte,buff,10);
temp += buff;
temp += "</p><p>Luftdruck: ";
itoa(wetterDaten.luftdruck,buff,10);
temp += buff;
temp += "</p><p>Lichtstaerke: ";
itoa(wetterDaten.lux,buff,10);
temp += buff;
temp += "</p><img src=\"/test.svg\" />";
temp += "</body>";
temp += "</html>";
 
server.send ( 200, "text/html", temp );
}
 
// Webdatei oder Verzeichnis nicht gefunden.
void handleNotFound() {
 
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethode: ";
message += ( server.method() == HTTP_GET ) ? "GET" : "POST";
message += "\nParameter: ";
message += server.args();
message += "\n";
 
for ( uint8_t i = 0; i < server.args(); i++ ) {
message += " " + server.argName ( i ) + ": " + server.arg ( i ) + "\n";
}
 
message += "\n";
message += "Ist die SD-Karte eingelegt?\n";
server.send ( 404, "text/plain", message );
 
}
 
 
 
 
// Dieser wrapper steht in direktem Zusammenhang mit dem Abruf der Daten von DHT22
// und muss so definiert sein, damit die Lib funktioniert
void dht_wrapper() {
DHT.isrCallback();
}
 
 
void dummy(void){}
 
// Zu Begin muss die Wetterstation eingerichtet werden
// Verschiedene Parameter sowie das Multitasking-System werden eingestellt.
void setup ( void ) {
if (SD.begin(SELECT_SD)){
// Logfile erstellen um die Initialisierung aufzuzeichnen
logStream=SD.open("logfile.txt",FILE_WRITE);
}
 
// WiFi initialisieren und auf Verbindung warten
WiFi.begin ( ssid, password );
while ( WiFi.status() != WL_CONNECTED ) {
delay ( 500 );
}
 
logStream.println ( "WLAN-Parameter:" );
logStream.print ( "SSID: "); logStream.println( ssid );
logStream.print ( "IP-Adresse: " ); logStream.println ( WiFi.localIP() );
logStream.println("");
 
logStream.println("mDNS:");
if ( MDNS.begin ( mDNSName ) ) {
logStream.print("mDNS-Name: "); logStream.println(mDNSName);
logStream.println ( "MDNS Responder gestartet. (Das Netzwerk muss BonJour unsterstützen!)" );
}
logStream.println("");
 
 
server.on ( "/", handleRoot );
server.on ( "/test.svg", drawGraph );
server.on ( "/hurz.htm", showTable );
 
server.onNotFound ( handleNotFound );
server.begin();
 
logStream.println ( "HTTP server gestartet." );
logStream.println("");
 
startMills = millis();
// 2 Sekündchen warten
while ( (millis() - startMills) < 2000 ) {
yield();
}
 
 
// Datenbank öffnen oder erstellen.
if (SD.exists(dbName)) {
logStream.println("Datenbank öffnen:");
 
dbFile = SD.open(dbName, FILE_WRITE);
if (!dbFile) {
dbFile = SD.open(dbName, FILE_WRITE);
}
 
if (dbFile) {
logStream.print("Aktuelle Datenbank öffnen...  ");
EDB_Status result = db.open(0);
 
if (result == EDB_OK) {
logStream.println("Erledigt");
 
} else {
logStream.println("Fehler");
logStream.print("Datenbank nicht gefunden. Neue Datenbank wird angelegt... ");
db.create(0, TABLE_SIZE, (unsigned int)sizeof(wetterDaten));
logStream.println("Erledigt");
return;
}
} else {
logStream.println("--> Datenbankdatei kann nicht geöffnet werden: "+String(dbName));
return;
}
} else {
logStream.print("..Datenbanktabelle wird erzeugt... ");
dbFile = SD.open(dbName, FILE_WRITE);
db.create(0, TABLE_SIZE, (unsigned int)sizeof(wetterDaten));
logStream.println("Erledigt");     }
 
logStream.close();
 
taskSetupDHT();
taskSetupBMP();
taskSetupBH();
 
}
 
 
// Setup DHT-Sensor
void taskSetupDHT(void){
// DHT22 initial einmal abfragen und Ergebnis löschen
acquirestatus = 0;
acquireresult = DHT.acquireAndWait(1000);
if ( acquireresult == 0 ) {
temperatur = DHT.getCelsius();
luftfeuchte = DHT.getHumidity();
taupunkt = DHT.getDewPoint();
} else {
temperatur = luftfeuchte = taupunkt = 0;
}
}
 
// Task: DHT-Sensor lesen
void taskReadDHT(void) {
bDHTstarted =true;
// Sensorwerte auslesen und der Datenstruktur zuweisen
if (bDHTstarted) {
acquirestatus = DHT.acquiring();
if (!acquirestatus) {
acquireresult = DHT.getStatus();
if ( acquireresult == 0 ) {
wetterDaten.temperatur = DHT.getCelsius();    // In Grad Celcius
wetterDaten.luftfeuchte = DHT.getHumidity();  // in Prozent
wetterDaten.taupunkt = DHT.getDewPoint();     // in Grad Celcius
}
bDHTstarted = false;
}
}
 
// Wenn DHT fest steckt, dann Reset
if (acquirestatus == 1) {
DHT.reset();
}
 
if (!bDHTstarted) {
// non blocking method
DHT.acquire();
bDHTstarted = true;
}
 
}
 
// Setup BMP-Sensor
void taskSetupBMP(void) {
bmp.begin(BMP_SDA,BMP_SCL);
}
 
// Task: BMP-Sensor lesen
void taskReadBMP(void) {
// Ab hier BMP280
 
bmp.setOversampling(4);
char result = bmp.startMeasurment();
if(result!=0){
delay(result);
result = bmp.getTemperatureAndPressure(temperatur2,luftdruck);
 
if(result!=0)
{
hoehe = bmp.altitude(luftdruck,DRUCK_NORMAL);
 
wetterDaten.temperatur2=temperatur2;  // In Grad Celcius
wetterDaten.luftdruck=luftdruck;  // Luftdruck in mBar
wetterDaten.hoehe=hoehe;  // Höhe in meter
}
}
 
}
 
// Setup LH-Sensor
void taskSetupBH(void) {
 
}
 
// Task: BH1570-Sensor lesen
void taskReadBH(void) {
Wire.begin(LH_SDA,LH_SCL);
LS.begin();
wetterDaten.lux = LS.readLightLevel();
 
}
 
 
// Hauptschleife (Webserver & Datenbankhandling)
void loop ( void ) {
 
server.handleClient(); // WebServer
 
// Daten der Sensoren gemäß definiertem Intervall wegschreiben
if ((millis() - startMills) > REPORT_INTERVALL) {
taskReadDHT();
taskReadBMP();
taskReadBH();
 
wetterDaten.id = db.count();
db.insertRec((wetterDaten.id+1), EDB_REC wetterDaten);
 
startMills = millis();
}
 
 
 
}
 
void drawGraph() {
String out = "";
char temp[100];
out += "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"400\" height=\"150\">\n";
out += "<rect width=\"400\" height=\"150\" fill=\"rgb(250, 230, 210)\" stroke-width=\"1\" stroke=\"rgb(0, 0, 0)\" />\n";
out += "<g stroke=\"black\">\n";
int y = 20;
for (int x = 10; x < 390; x+= 10) {
int y2 = 20*sin(y + x)+20;
sprintf(temp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" stroke-width=\"1\" />\n", x, 140 - y, x + 10, 140 - y2);
out += temp;
y = y2;
}
out += "</g>\n</svg>\n";
 
server.send ( 200, "image/svg+xml", out);
}
 
void showTable() {
String out ="";
out += "<table border=1>";
out += "<tr><td>Martin</td><td>Martin</td><td>Martin</td></tr>";
out += "<tr><td>Regina</td><td>Regina</td><td>Regina</td></tr>";
out += "</table>";
server.send(200, "text/html", out);
}
 
-----

Klopapier beidseitig verwenden und der Erfolg liegt auf der Hand!
(Dieser Beitrag wurde zuletzt bearbeitet: 05.09.2017, 20:49 von Unilein.)
Zitieren


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste