WeMos D1 mini als WLAN-Sensor/-Aktor

Problemlösungen und Hinweise von allgemeinem Interesse zur Haussteuerung mit HomeMatic

Moderator: Co-Administratoren

klassisch
Beiträge: 3974
Registriert: 24.03.2011, 04:32
System: Alternative CCU (auf Basis OCCU)
Hat sich bedankt: 110 Mal
Danksagung erhalten: 71 Mal

Emails vom WeMos über die CCU versenden

Beitrag von klassisch » 08.10.2016, 22:21

Für den ESP8266 scheint es keinen email clienten zu geben.
Aber emails Versenden vom WeMos aus ist oft hilfreich.
Für die CCU gibt es das email-Addon und das kann man als eine Art Relaisstation für den WeMos nutzen. Eine Einführung in das Addon findet sich im Forum http://homematic-forum.de/forum/viewtop ... 41&t=18610 . Aktuell scheint Version 1.6.6 zu sein. Meine CCU hat noch 1.6.0 drauf.
alchy hat dort http://homematic-forum.de/forum/viewtop ... 87#p256887 auch beschrieben, wie man damit emails von Skripten aus versendet. Etliche von uns betreiben das schon so und das ist auch die Basis für den WeMos. Wer das schon so eingerichtet hat, kann gleich mit dem Andocken des WeMos beginnen. Den anderen empfehle ich, sich erst mal mit dem email-Addon vertraut zu machen. Wer mit einem Skript emails verschicken kann, wird es auch mit dem WeMos können.

alchys Anleitung kurz zusammengefaßt:
3 Variablen in der CCU mit Namen EmailEmpfaenger, EmailBetreff, EmailText jeweils als Zeichenkette anlegen.
Im TCL Reiter steht dann irgendetwas so ähnlich:

Code: Alles auswählen

    load tclrega.so
    array set values [rega_script {
    var v1 = dom.GetObject("EmailEmpfaenger").Value();
    var v2 = dom.GetObject("EmailBetreff").Value();
    var v3 = dom.GetObject("EmailText").Value();
    } ]

    set v1 $values(v1)
    set v2 $values(v2)
    set v3 $values(v3)
Bei alchy sieht die emailvorlage 10 dann so aus
email_dynamisch-alchy.jpg
email_dynamisch-alchy.jpg (12.1 KiB) 2223 mal betrachtet
Bei mir ist das historisch gewachsen und deutlich komplizierter als hier bei alchy. ich brauche zusätzlich noch Zeilen wie

Code: Alles auswählen

set theText1 $values(v1)
set theText2 $values(v2)
set theText3 $values(v3)
Entsprechend steht bei mir in den Feldern An, Betreff und Text statt $v1, $v2, $v3 die Textvariablen $theText1, $theText2 und $theText3.
Dazu ist vielleicht noch der Post http://homematic-forum.de/forum/viewtop ... 33#p258533 hilfreich. Der macht es im Prinzip ähnlich aber im Detail deutlich besser. Dort wird noch die Zeichenkodierung auf der CCU umgesetzt.

Code: Alles auswählen

    load tclrega.so
    array set values [rega_script {
    var v1 = dom.GetObject("Betreff").Value(); }]
    set v1 [encoding convertfrom utf-8 $values(v1)]
Ich habe das jetzt nicht getestet, aber vielleicht wäre damit das whitespace-Problem (%20), welches ich auf dem WeMos löse, gar nicht erst entstanden (siehe http://homematic-forum.de/forum/viewtop ... 14#p309414). Dann könnte man den replace() Befehl auf dem WeMos entfallen lassen. Vielleicht mag das jemand testen. Ich tendiere derzeit noch zur replace() -Lösung, weil ich die CCU sowei als möglich entlasten möchte.

Jetzt wird noch ein WebUI-Programm benötigt, welches ein TCL-Skript aufnimmt und so die email losschickt. Das Programm nenne ich "EmailForward".
emailForwarder-1-screenshot.PNG
Triggerbedingung ist ein einmaliger Zeitpunkt in der Vergangenheit. Es soll ja nur direkt durch den WeMos aktiviert werden.
Das Skript sieht bei mir mittlerweile so einfach wie bei alchy aus:

Code: Alles auswählen

dom.GetObject("CUxD.CUX2801001:1.CMD_EXEC").State ("/etc/config/addons/email/email 10");
Das Ganze sollte man zuerst einmal auf der CCU testen. Wenn alles läuft gehts an den WeMos.
Dort werden die Variablen angelegt:

Code: Alles auswählen

/* ********* variables for emailing via CCU ************/
String emailTo = "eine.email@mail.de"; // addressee's email address. Multiple addresses can be used separated by semikolon (;)
String const emailToCcuVarName = "EmailEmpfaenger"; // Same name and same spelling as the CCU variable used in the mail program; may be case senssitive
String emailSubject = "WeMos Message"; // the email subject
String const emailSubjectCcuVarName = "EmailBetreff"; // Same name and same spelling as the CCU variable used in the mail program; may be case senssitive
String emailText = "keep it short and simple"; // the text of the email. 
String const emailTextCcuVarName = "EmailText"; // Same name and same spelling as the CCU variable used in the mail program; may be case senssitive
String const ccuEmailForwarder = "EmailForward";// Same name and same spelling as the CCU mail forward program; may be case senssitive
/* ********* end variables for emailing via CCU ************/
Wer das EEPROM und WPS nutzt, kann die email-Adresse konfigurierbar gestalten. Dadurch bleiben die Sketche frei von persönlichen Daten.
Zur Übermittlung an die CCU wird m.yodas melde_ccu modifiziert:

Code: Alles auswählen

void mailViaCCU() { // Werte an die CCU melden here: transfer email parameters and start email program
  WiFiClient client; // Webclient initialisieren
  String tempstring = ""; // temporaerer string
  if (!client.connect(cfg.hostCCU, cfg.hostportCCU))
  { // mit dem CCU-Port 8181 verbinden
#ifdef FSDEBUG
    DBG_OUTPUT_PORT.println(zeitstempel() + "  Fehler: Verbindung zur CCU konnte nicht aufgebaut werden");
#endif
    delay(100);
  }

  meldung = "";
  meldung = meldung +  ""; // without this an error message occured (types incompatible)
  meldung = "/eriwan.exe?antwort1=dom.GetObject('" + emailToCcuVarName + "').State('" + emailTo + "')";
  meldung = meldung + "&antwort2=dom.GetObject('" + emailSubjectCcuVarName + "').State('" + emailSubject + "')";
  meldung = meldung + "&antwort3=dom.GetObject('" + emailTextCcuVarName + "').State('" + emailText + "')";
  meldung = meldung + "&antwort4=dom.GetObject('"+ ccuEmailForwarder +"').ProgramExecute()";
  meldung = meldung + "    "; //to avoid to be shorter than %20
  meldung.replace(" ", F("%20")); // replaces whitespaces by %20. necessary otherwise CCU drops string. CCU cannot handle whitesspaces
  meldung = "GET " + meldung;

	
  client.println(meldung); // Daten an CCU melden
#ifdef FSDEBUG
  DBG_OUTPUT_PORT.println("command -String to CCU:");
  DBG_OUTPUT_PORT.println(meldung);
#endif
  delay(100);
  int i = 0;
  String zeile = "";
  while (client.available()) { // Antwort der CCU zeilenweise auslesen
    i ++;
    zeile = client.readStringUntil('\n'); // Zeitstempel der CCU ausfiltern und merken
    if (i == 7) {
      letzteMeldungCCUzeit = zeile;
    }
  }
#ifdef FSDEBUG
  DBG_OUTPUT_PORT.println("Werte an CCU gemeldet, " + letzteMeldungCCUzeit);
#endif
  letzteMeldungMillis = jetztMillis; // gemeldete Daten merken

} // end mail via CCU

Als einfache Anwendung sei das Verschicken einer Mail beim Start des WeMos demonstriert. In void setup() wird dazu folgendes eingebaut:

Code: Alles auswählen

/************ startup email **************/
emailSubject = F("WeMos - up and running");
emailText="";
emailText = emailText + cfg.sensorName + "\n" +  localip + "\nStarted: " + localUhrzeitstempel(); 
mailViaCCU();
/***********  end startup email **********/
In cfg.sensorName hier ist der Name des Sensors enthalten und in localUhrzeitstempel Datum und Zeit. Die email-Adresse ist meist konstant, also unanbhängig vom Anlass, und wird entweder bei der Variablen Definition oder über den Konfigurationsmechanismus vergeben.
Die email trägt dann den Betreff
WeMos - up and running
und den Text
Test-T-H-P-WeMos
192.178.1.70
Started: 2016-10-08 21:51:34
Als etwas komplexeres Anwendungsbeispiel habe ich das in einen BME280 Sketch eingebaut und maile neben dem Startup auch noch bei Über- und Untertemperatur (z.B. Frostgefahr), s. http://homematic-forum.de/forum/viewtop ... 49#p308449.

Edit / Nachträge:
- seit CCU2 FW 2.27.8 führen z.B. im emailText Zeilenumbrüche als "\n" kodiert zum Nichtversenden der email. Workaround: Zeilenumbruch als "%0D%0A% kodieren
- Mittlerweile gibt es auch eine Lösung emails über CUxD und email-Addon zu versenden. Dadurch spart man sich die Systemvariablen für Adresse, Subject und Text und man braucht kein Skript auf der CCU. Wie es geht habe ich dort beschrieben viewtopic.php?p=348490#p348490 und viewtopic.php?p=348484#p348484.
Zuletzt geändert von klassisch am 31.03.2017, 16:19, insgesamt 3-mal geändert.

Desti
Beiträge: 76
Registriert: 29.09.2014, 00:21

Re: RGB-5050-Strip-Controller

Beitrag von Desti » 10.10.2016, 15:10

m.yoda hat geschrieben:Dann mal zur Abwechslung was zum Löten: Das WeMos D1 mini RGB-5050-Strip-Controller Selbstbau-Shield :lol:
rgb2.jpg
Bauteile:
D.h. für ca. 6 Euronen bekommen wir einen schicken Controller. RGB-LED's und ein 12V-Netzteil kommen noch dazu, habe ich jetzt nicht kalkuliert, halt je nach Lust und Laune bzw. Länge der RGB-Strips. (Bsp. Netzteil: 12V mit 5A ca. 5 €)
WeMos_RGB.jpg
Verlötet auf einem WeMos D1 mini ProtoBoard:
rgb1.jpg
Nicht vergessen: Bevor wir unser Eigenbau-Shield auf den WeMos draufklemmen, unbedingt den Buck-Konverter auf 5V Ausgangsspannung einregeln!

Wenn ich am Wochenende dazu komme, reich ich vielleicht auch noch einen passenden Demo-Sketch nach - gute Nacht erstmal und ansonsten frohes Basteln und gutes Gelingen!
Ich hab nun einige Seiten durchsucht. Ist da schon nen Beispiel Skript gepostet worden ? Bin anscheinend zu Blind etwas zu finden. Habe meinen Wemos nun bereits soweit, dass ich ihn über nen websocket steuern kann. Aber leider habe ich noch keinen Weg gefunden die LED s automatisch achalten zu lassen.
Würde gern nen PIR mit dranklemmen und die Küchenbeleuchtung schalten, wenn man Abends mal in die Küche huscht um den Kühlschrank nach leckerreien zu durchsuchen ;)
Vielleicht hat da ja jemand noch ein paar Infos rumliegen. Würde mich freuen, wenn es irgendwie machbar wäre :)
YAHM,MediolaV4+,div. Homematic Sensoren, CCU.io(Dashui) auf Pi,

dondaik
Beiträge: 12935
Registriert: 16.01.2009, 18:48
Wohnort: Steingaden
Hat sich bedankt: 1614 Mal
Danksagung erhalten: 222 Mal

Re: WeMos D1 mini als WLAN-Sensor/-Aktor

Beitrag von dondaik » 10.10.2016, 17:23

zum dem thema gab es glaube ich kein demo-sketsch ... der piri ist aber besprochen, mit dem sketsch sollte es kein thema sein den port für die LEDs zu schalten. ( anfang des themas weoms d1 ist ein link aufs wiki....da ist auch vieles zu finden )
-------
!!! der download der handbüchern auf den seiten von eq3 und das lesen der tips und tricks kann das hm-leben sehr erleichtern - das nutzen der suche nach schlagworten ebenso :mrgreen: !!!
wer schreibfehler findet darf sie behalten.

mike9677
Beiträge: 422
Registriert: 17.04.2011, 11:08

Re: WeMos D1 mini als WLAN-Sensor/-Aktor

Beitrag von mike9677 » 10.10.2016, 17:40

mike9677 hat geschrieben:Ich seh' schon... der Sketch von klassisch hat es in sich. Das übersteigt meine Fähigkeiten total!

GIbt es evtl. einen fähigen und willigen "Könner", der den CuxD-Sketch aus dem Wiki http://www.renmet.com/wiki/index.php?ti ... be_an_CUxD so umbauen kann, dass er mit dem BME280 funktioniert ?

Es ist ja wahrscheinlich nicht damit getan, einfach die library auszutauschen, oder ?

Ich kann nur auf Hilfe hoffen... besten Dank!

Edit: Könnte es evtl. so funktionieren ?

Code: Alles auswählen

//based on:
// Adafruit Adafruit_BME280_Library
// https://github.com/adafruit/Adafruit_BME280_Library
//and
// Astuder BMP085-template-library-Energia
// https://github.com/astuder/BMP085-template-library-Energia
//plus code for altitude and relative pressure
//by r7
//
//PINS:
//      5V
//      GND
//      D4 - SCL
//      D3 - SDA

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <Wire.h>                                                       // required by BME280 library
#include <BME280_t.h>                                                   // import BME280 template library

float korrTemp = -2; // Korrekturwert fuer die Temperaturmessung
float korrFeucht = 0; // Korrekturwert fuer die Feuchtigkeitsmessung
float temp = 0, feucht = 0, pressure1 = 0, relpressure1 = 0, altitude1 = 0;

// ******* CUxD Variablen, bitte anpassen! *******

String tempstring = "";
String cuxdId = "CUX9002001";

// ******* Netzwerkeinstellungen, bitte anpassen! *******
const char* ssid = "SSID"; // SSID des vorhandenen WLANs
const char* password = "PWD"; // Passwort für das vorhandene WLAN
IPAddress gateway(xxx,xxx,xxx,xxx); // IP-Adresse des WLAN-Gateways
IPAddress subnet(255,255,255,0); // Subnetzmaske
IPAddress ip(xxx,xxx,xxx,xxx); // feste IP-Adresse für den WeMos
const char* host = "xxx.xxx.xxx.xxx"; // IP-Adresse der CCU

// ******* Einstellungen fuer Meldungen an die CCU, bitte anpassen! *******
String tempCCUname = "Lukas_Temperatur"; // Bezeichnung der CCU-Systemvariable für die gemessene Temperatur
String feuchtCCUname = "Lukas_Luftfeuchtigkeit"; // Bezeichnung der CCU-Systemvariable für die gemessene Luftfeuchtigkeit
String pressureCCUname = "Lukas_Luftdruck"; // Bezeichnung der CCU-Systemvariable für den gemessenen Luftdruck
String relpressureCCUname = "Lukas_rel_Luftdruck"; // Bezeichnung der CCU-Systemvariable für den gemessenen relativen Luftdruck
String altitudeCCUname = "Lukas_Hoehenmeter"; // Bezeichnung der CCU-Systemvariable für die gemessenen Höhenmeter
String meldung = "";

// ******** Zeit in Millisekunden für den Refresh, bitte anpassen! ********
int renew = 120000; // Aktualisierungsintervall in Millisekunden (2 Minuten)

#define ASCII_ESC 27


// ********* Angabe der Höhenmeter zu eurem Ort, bitte anpassen! *********
#define MYALTITUDE  112.00

char bufout[10];

BME280<> BMESensor;                                                     // instantiate sensor

void setup()
{
  Serial.begin(115200);                                                 // initialize serial
  Wire.begin(0,2);                                                      // initialize I2C that connects to sensor
  BMESensor.begin();                                                    // initalize bme280 sensor

  // WLAN-Verbindung herstellen
  WiFi.config(ip, gateway, subnet); // auskommentieren, falls eine dynamische IP bezogen werden soll
  WiFi.begin(ssid, password);

  // Verbindungsaufbau abwarten
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" erfolgreich!");
  Serial.println("");
  Serial.print("Verbunden mit: ");
  Serial.println(ssid);
  Serial.print("Signalstaerke: ");
  int rssi = WiFi.RSSI();
  Serial.print(rssi);
  Serial.println(" dBm");
  Serial.print("IP-Adresse: ");
  Serial.println(WiFi.localIP());
  Serial.println("");
  
}

void loop() {
  BMESensor.refresh();                                                  // read current sensor data
  //sprintf(bufout,"%c[1;0H",ASCII_ESC);
  //Serial.print(bufout);
  Serial.println(" ");

  temp = BMESensor.temperature + korrTemp;
  feucht = BMESensor.humidity + korrFeucht;
  pressure1 = BMESensor.pressure  / 100.0F;
  float relativepressure = BMESensor.seaLevelForAltitude(MYALTITUDE);
  relpressure1 = relativepressure  / 100.0F;
  altitude1 = BMESensor.pressureToAltitude(relativepressure);
  
  Serial.print("Temperature: ");
  Serial.print(temp);                                  // display temperature in Celsius
  Serial.println(" °C");

  Serial.print("Humidity:    ");
  Serial.print(feucht);                                     // display humidity in %   
  Serial.println(" %");

  Serial.print("Pressure:    ");
  Serial.print(pressure1);                           // display pressure in hPa
  Serial.println(" hPa");

  Serial.print("RelPress:    ");
  Serial.print(relpressure1);                             // display relative pressure in hPa for given altitude
  Serial.println(" hPa");   

  Serial.print("Altitude:    ");
  Serial.print(altitude1);         // display altitude in m for given pressure
  Serial.println(" m");

  WiFiClient client; // Webclient initialisieren
  if (!client.connect(host, 8181)) { // mit dem CCU-Port 8181 verbinden
    Serial.println("Fehler: Verbindung zur CCU konnte nicht aufgebaut werden");
     delay(100);
    return;
  }
  tempstring = "";
  tempstring = tempstring + cuxdId; 
  meldung = "GET /eriwan.exe?antwort1=dom.GetObject('CUxD." + tempstring + ":1.SET_TEMPERATURE').State('" + temp + "')";
  meldung = meldung + "&antwort2=dom.GetObject('CUxD." + tempstring + ":1.SET_HUMIDITY').State('" + feucht + "')";
  
  client.println(meldung); // Daten an CCU melden

  delay(100);   
  int i = 0;
  String zeile = "";
  while(client.available()){ // Antwort der CCU zeilenweise auslesen
    i ++;
    zeile = client.readStringUntil('\n'); // Zeitstempel der CCU ausfiltern und merken
    if (i == 7) {
      letzteMeldungCCUzeit = zeile;
    }
  }
  Serial.println("Werte an CCU gemeldet, " + letzteMeldungCCUzeit);
  letzteMeldungMillis = jetztMillis; // gemeldete Daten merken
  feuchtCCU = feucht;
  tempCCU = temp;
}                                                         
  
}
Braucht man dann eigentlich noch die Systemavariabeln in der CCU ?

Und noch ne kleine Frage: macht es einen Unterschied, ob ich im Sketch stehen habe

Code: Alles auswählen

#include "DHT.h"
oder

Code: Alles auswählen

#include <DHT.h>
Konnte den Sketch schon mal jemand testen ?

Desti
Beiträge: 76
Registriert: 29.09.2014, 00:21

Re: WeMos D1 mini als WLAN-Sensor/-Aktor

Beitrag von Desti » 10.10.2016, 17:43

okay, dann bin ich doch nicht so blind:)
Piri ist klar. Wiki ist längst in den Favoriten gespeichert;)
dann muss ich mal irgendwie rausbekommen wie ich die mofset ansteuern muss [SMILING FACE WITH OPEN MOUTH AND TIGHTLY-CLOSED EYES]

gesendet von unterwegs...
YAHM,MediolaV4+,div. Homematic Sensoren, CCU.io(Dashui) auf Pi,

dondaik
Beiträge: 12935
Registriert: 16.01.2009, 18:48
Wohnort: Steingaden
Hat sich bedankt: 1614 Mal
Danksagung erhalten: 222 Mal

Re: WeMos D1 mini als WLAN-Sensor/-Aktor

Beitrag von dondaik » 10.10.2016, 18:14

sonst sage ich dir beim ali ein treiber-board...... AVR STM32 :-)
Zuletzt geändert von dondaik am 10.10.2016, 18:58, insgesamt 1-mal geändert.
-------
!!! der download der handbüchern auf den seiten von eq3 und das lesen der tips und tricks kann das hm-leben sehr erleichtern - das nutzen der suche nach schlagworten ebenso :mrgreen: !!!
wer schreibfehler findet darf sie behalten.

dondaik
Beiträge: 12935
Registriert: 16.01.2009, 18:48
Wohnort: Steingaden
Hat sich bedankt: 1614 Mal
Danksagung erhalten: 222 Mal

Re: WeMos D1 mini als WLAN-Sensor/-Aktor

Beitrag von dondaik » 10.10.2016, 18:20

@mike9677
was soll man den testen?
D3 / D4 zu nutzen ist unglücklich besser D1 / D2 ... sowohl BME280 / als auch drt DHTxx haben hier 1-2 test-sketsch bitte die testen und schauen das daten auf den monitor kommen dann kann man das gesamtwerk teste. ( auf die klammern habe ich noch nie geachtet :- ) habe die beispiele portiert :-) )
die daten können an eine SV in der CCU gesendet werden oder an ein cuxd 90er device ( transformer )..
die beschreibung ist im wemos sketsch oder in einem eigen thema von klassisch dazu ansonsten:
http://homematic-forum.de/forum/viewtop ... 5&p=300460

der code sollte deine sensoren BME280 / DHT22 eigentlich zum sprechen bringen.. ggf ist der druck auf NN gerechnet falsch, da habe ich die lib geändert... es geht ja erst einmal nur um die funktion

Code: Alles auswählen

//based on:
// Adafruit Adafruit_BME280_Library
// https://github.com/adafruit/Adafruit_BME280_Library
//and
// Astuder BMP085-template-library-Energia
// https://github.com/astuder/BMP085-template-library-Energia
//plus code for altitude and relative pressure
//by r7
#include <credentials.h>
#include <Wire.h>                       //  required by BME280 library
#include <BME280_t.h>                //  BME280 template library

#include <OneWire.h>                      //  für Ds18x20 
#include <DallasTemperature.h>       //  DS18x20
#include "Adafruit_VEML6070.h"       //  IR-Sensor
#include "DHT.h"                               //   DHT xx  
#define DHTPIN D3                           // what pin we're connected to D5
// Uncomment whatever type you're using!
// #define DHTTYPE DHT11   // DHT 11 
#define DHTTYPE DHT22      // DHT 22  (AM2302) - DHT 21 (AM2301) -
#define DHTMHZ 20         // abhängig von der CCU 20


#define MYALTITUDE  755
#define ONE_WIRE_BUS 2  // D4 beim wemos D1 mini !!!
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);
BME280<> BMESensor;                                            // instantiate sensor

DHT dht(DHTPIN, DHTTYPE, DHTMHZ);                   // ini DHT-Sensor
float  dstemp = 0;


void setup()
{
  Serial.begin(115200);                 // initialize serial
// pinMode(BUILTIN_LED, OUTPUT);         // zum schalten der internen led
  Wire.begin(D2, D1);                   // initialize I2C that connects to sensor
  BMESensor.begin();                    // initalize bme280 sensor
  dht.begin();                         // DHT22 - AM 2302 spielt mit                                      
}

void loop() {
   //

  BMESensor.refresh();                                                  // read current sensor data
  delay(10);
  Serial.println("...");
  Serial.print("Temp BME280 : ");
  Serial.print(BMESensor.temperature - 1.6);                                  // display temperature in Celsius
  Serial.println("C");

  Serial.print("Temp DHT22  : ");
  Serial.print(dht.readTemperature() - 0.85);                                  // display temperature in Celsius
  Serial.println("C");
 
Serial.println("----");

  Serial.print("HumiBM2E80:    ");
  Serial.print(BMESensor.humidity);                                     // display humidity in %   
  Serial.println("%");

  Serial.print("HumiDHT22 :    ");
  Serial.print(dht.readHumidity());                                     // display humidity in %   
  Serial.println("%");
  
Serial.println("----");

  Serial.print("Pressure:    ");
  Serial.print(BMESensor.pressure  / 100.0F);                           // display pressure in hPa
  Serial.println("hPa");

  float relativepressure = BMESensor.seaLevelForAltitude(MYALTITUDE);
  Serial.print("RelPress:    ");
  Serial.print(relativepressure  / 100.0F);                             // display relative pressure in hPa for given altitude
  Serial.println("hPa");   

  Serial.print("Altitude:    ");
  Serial.print(BMESensor.pressureToAltitude(relativepressure));         // display altitude in m for given pressure
  Serial.println("m");

  //  digitalWrite(BUILTIN_LED, !digitalRead(BUILTIN_LED));   // turn the LED on (HIGH is the voltage level)

  delay(10000);                                                          // wait a while before next loop
}

-------
!!! der download der handbüchern auf den seiten von eq3 und das lesen der tips und tricks kann das hm-leben sehr erleichtern - das nutzen der suche nach schlagworten ebenso :mrgreen: !!!
wer schreibfehler findet darf sie behalten.

Benutzeravatar
m.yoda
Beiträge: 74
Registriert: 26.01.2016, 15:42
Danksagung erhalten: 1 Mal

Re: WeMos D1 mini als WLAN-Sensor/-Aktor

Beitrag von m.yoda » 10.10.2016, 22:44

@Desti

O-ha, das ist mir durchgerutscht. :roll:
Ich hab einen simplen Beispiel-Sketch zur Ansteuerung aber im WeMos-Forum gepostet. Die Farbe kannst du dann einfach über die RGB-Werte mischen, dabei ist der maximale Wert allerdings nicht wie meist üblich 255, sondern 1023. Beispiele zur Anbindung an PIR und Homematic gibt es ja schon.

Viel Erfolg und frohes Basteln!
—m.yoda

mike9677
Beiträge: 422
Registriert: 17.04.2011, 11:08

Re: WeMos D1 mini als WLAN-Sensor/-Aktor

Beitrag von mike9677 » 12.10.2016, 13:50

Nächster Versuch, einen BME280 mit CuxD in Verbindung zu bringen:

Code: Alles auswählen

/*
 *  WeMos Temperatur-/Luftfeuchtesensor (Prototyp)
 *  
 *  verbindet sich mit dem vorhandenen WLAN als Server
 *  und bei Bedarf mit der CCU als Client
 *  
 *  Steuerung über HTTP-Befehle:
 *     "<IP-Adresse>" gibt eine Status- und Befehlsübersicht aus
 *     "<IP-Adresse>/temp" gibt die zuletzt gemessene Temperatur aus (Grad Celsius)
 *     "<IP-Adresse>/feucht" gibt die zuletzt gemessene Luftfeuchtigkeit aus (in Prozent)
 *     "<IP-Adresse>/zeit" gibt den CCU-Zeitstempel aus, an dem die letzte Meldung an die CCU erfolgte
 *     "<IP-Adresse>/temp?delta=<wert>" setzt den Temperatur-Differenzwert, der eine CCU-Meldung ausloest
 *     "<IP-Adresse>/temp?korr=<wert>" setzt den Korrekturwert fuer die Temperaturmessung
 *     "<IP-Adresse>/feucht?delta=<wert>" setzt den Feuchtigkeits-Differenzwert, der eine CCU-Meldung ausloest
 *     "<IP-Adresse>/feucht?korr=<wert>" setzt den Korrekturwert fuer die Feuchtigkeitsmessung
 *     "<IP-Adresse>/zeit?delta=<wert>" setzt die Zeitspanne (in Sekunden), nach der spaetestens eine CCU-Meldung erfolgt
 *     "<IP-Adresse>/zeit?mess=<wert>" definiert das Messintervall (in Sekunden)
 *    
  */

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <Wire.h>
#include <BME280_t.h>
//#include "DHT.h"

// ******* CUxD Variablen, bitte anpassen! *******

String tempstring = "";
String cuxdId = "CUX9002001";

// ******* Netzwerkeinstellungen, bitte anpassen! *******
const char* ssid = xxxxxxx"; // SSID des vorhandenen WLANs
const char* password = "xxxxxx"; // Passwort für das vorhandene WLAN
IPAddress gateway(xxxxxxxxx); // IP-Adresse des WLAN-Gateways
IPAddress subnet(255,255,255,0); // Subnetzmaske
IPAddress ip(xxxxxxxx); // feste IP-Adresse für den WeMos
const char* host = "xxxxxxxxx"; // IP-Adresse der CCU
ESP8266WebServer server(80); // Webserver initialisieren auf Port 80

// ******* Sensoreinstellungen, bitte anpassen! *******
//DHT dht(D4, DHT11); // verwendeter Datenpin des Sensors, bei WeMos mini Shields = D4
                    // verwendeter Sensortyp, unterstützt werden DHT11 DHT21 DHT22
                    // WeMos mini DHT Shield = DHT11
                    // WeMos mini DHT Pro Shield = DHT22
unsigned long deltaMessungSekunden = 10; //Zeitintervall (Sekunden) nach dem eine Messung erfolgt
float korrTemp = 0; // Korrekturwert fuer die Temperaturmessung
float korrFeucht = 0; // Korrekturwert fuer die Feuchtigkeitsmessung
float temp = 0, feucht = 0, pressure1 = 0, relpressure1 = 0, altitude1 = 0;

// ******* Einstellungen fuer Meldungen an die CCU, bitte anpassen! *******
String tempCCUname = "Vorhaus_Temperatur"; // Bezeichnung der CCU-Systemvariable für die gemessene Temperatur
String feuchtCCUname = "Vorhaus_Luftfeuchtigkeit"; // Bezeichnung der CCU-Systemvariable für die gemessene Luftfeuchtigkeit
String pressureCCUname = "Vorhaus_Luftdruck"; // Bezeichnung der CCU-Systemvariable für den gemessenen Luftdruck
String relpressureCCUname = "Vorhaus_rel_Luftdruck"; // Bezeichnung der CCU-Systemvariable für den gemessenen relativen Luftdruck
String altitudeCCUname = "Vorhaus_Hoehenmeter"; // Bezeichnung der CCU-Systemvariable für die gemessenen Höhenmeter
unsigned long deltaMeldungSekunden = 80; // Zeitintervall (Sekunden) nach dem eine CCU-Meldung erfolgt (0 bedeutet nie)
float deltaTemp = 1; // Temperaturaenderung (*C) bei der eine CCU-Meldung erfolgt (0 bedeutet nie)
float deltaFeucht = 1; // Luftfeuchteaenderung (%) bei der eine CCU-Meldung erfolgt (0 bedeutet nie)

// ******** Zeit in Millisekunden für den Refresh, bitte anpassen! ********
int renew = 120000; // Aktualisierungsintervall in Millisekunden (2 Minuten)

#define ASCII_ESC 27


// ********* Angabe der Höhenmeter zu eurem Ort, bitte anpassen! *********
#define MYALTITUDE  480.00

char bufout[10];

BME280<> BMESensor;                                                     // instantiate sensor

float  feuchtCCU = 0, tempCCU = 0;
unsigned long jetztMillis = 0;
unsigned long deltaMessungMillis = deltaMessungSekunden * 1000, letzteMessungMillis = 0;
unsigned long deltaMeldungMillis = deltaMeldungSekunden * 1000, letzteMeldungMillis = 0;
String antwort = "", meldung = "",letzteMeldungCCUzeit = "";

String zeitstempel() { // Betriebszeit als Stunde:Minute:Sekunde
  char stempel[10];
  int lfdStunden = millis()/3600000;
  int lfdMinuten = millis()/60000-lfdStunden*60;
  int lfdSekunden = millis()/1000-lfdStunden*3600-lfdMinuten*60;
  sprintf (stempel,"%03d:%02d:%02d", lfdStunden, lfdMinuten, lfdSekunden);
  return stempel;
}

void messung() { // Sensor abfragen
  feucht = BMESensor.humidity + korrFeucht;
    temp = BMESensor.temperature + korrTemp;
    pressure1 = BMESensor.pressure  / 100.0F;
  float relativepressure = BMESensor.seaLevelForAltitude(MYALTITUDE);
  relpressure1 = relativepressure  / 100.0F;
  altitude1 = BMESensor.pressureToAltitude(relativepressure);
    if (isnan(feucht) || isnan(temp)) {
     Serial.println(zeitstempel() + "  Fehler: Sensor konnte nicht abgefragt werden");
     delay(100);
     return;
    }
  letzteMessungMillis = jetztMillis;
  Serial.println(zeitstempel() + "  Messung Luftfeuchtigkeit: " + feucht + " %  Temperatur: " + temp + " * C");
}

void melde_CCU() { // Werte an die CCU melden
  WiFiClient client; // Webclient initialisieren
  if (!client.connect(host, 8181)) { // mit dem CCU-Port 8181 verbinden
    Serial.println(zeitstempel() + "  Fehler: Verbindung zur CCU konnte nicht aufgebaut werden");
     delay(100);
    return;
  }
  tempstring = "";
  tempstring = tempstring + cuxdId; 
  meldung = "GET /eriwan.exe?antwort1=dom.GetObject('CUxD." + tempstring + ":1.SET_TEMPERATURE').State('" + temp + "')";
  meldung = meldung + "&antwort2=dom.GetObject('CUxD." + tempstring + ":1.SET_HUMIDITY').State('" + feucht + "')";
  
  client.println(meldung); // Daten an CCU melden
  delay(100);
  int i = 0;
  String zeile = "";
  while(client.available()){ // Antwort der CCU zeilenweise auslesen
    i ++;
    zeile = client.readStringUntil('\n'); // Zeitstempel der CCU ausfiltern und merken
    if (i == 7) {
      letzteMeldungCCUzeit = zeile;
    }
  }
  Serial.println("Werte an CCU gemeldet, " + letzteMeldungCCUzeit);
  letzteMeldungMillis = jetztMillis; // gemeldete Daten merken
  feuchtCCU = feucht;
  tempCCU = temp;
}   

void wurzel_behandlung() { // bei Aufruf des Root-Verzeichnisses
  String betriebszeit = zeitstempel();
  antwort = "WeMos Temperatur-/Luftfeuchtesensor\n";
  antwort = antwort + "\tBetriebszeit: " + betriebszeit + " (Std:Min:Sek)\n";
  antwort = antwort + "\tVerbunden mit: " + ssid + "\n";
  int rssi = WiFi.RSSI();
  antwort = antwort + "\tSignalstaerke: " + String(rssi) + " dBm\n\n";
  antwort = antwort + "Letzte Messwerte\n\tTemperatur: " + String(temp) + " * C\n";
  antwort = antwort + "\tLuftfeuchtigkeit: " + String(feucht) + " %\n\n";
  antwort = antwort + "Korrekturwerte\n\tTemperatur: " + String(korrTemp) + " * C\n";
  antwort = antwort + "\tLuftfeuchtigkeit: " + String(korrFeucht) + " %\n\n";
  antwort = antwort + "Letzte Datenuebertragung CCU\n\t" + letzteMeldungCCUzeit;
  antwort = antwort + "\tGemeldete Temperatur: " + String(tempCCU) + " * C\n";
  antwort = antwort + "\tGemeldete Luftfeuchtigkeit: " + String(feuchtCCU) + " %\n\n";
  antwort = antwort + "Ausloeser fuer Datenuebertragung CCU\n";
  antwort = antwort + "\tZeitintervall: " + String(deltaMeldungSekunden) + " Sekunden\n";
  antwort = antwort + "\tTemperaturdifferenzwert: " + String(deltaTemp) + " * C\n";
  antwort = antwort + "\tFeuchtigkeitsdifferenzwert: " + String(deltaFeucht) + " %\n\n";
  antwort = antwort + "HTTP-Befehlsuebersicht:\n";
  antwort = antwort + "\"<IP-Adresse>/temp\"\n\tgibt die zuletzt gemessene Temperatur aus (Grad Celsius)\n";
  antwort = antwort + "\"<IP-Adresse>/feucht\"\n\tgibt die zuletzt gemessene Luftfeuchtigkeit aus (in Prozent)\n";
  antwort = antwort + "\"<IP-Adresse>/zeit\"\n\tgibt den CCU-Zeitstempel aus, an dem die letzte Meldung an die CCU erfolgte\n";
  antwort = antwort + "\"<IP-Adresse>/temp?delta=<wert>\"\n\tsetzt den Temperatur-Differenzwert, der eine CCU-Meldung ausloest\n";
  antwort = antwort + "\"<IP-Adresse>/temp?korr=<wert>\"\n\tsetzt den Korrekturwert fuer die Temperaturmessung\n";
  antwort = antwort + "\"<IP-Adresse>/feucht?delta=<wert>\"\n\tsetzt den Feuchtigkeits-Differenzwert, der eine CCU-Meldung ausloest\n";
  antwort = antwort + "\"<IP-Adresse>/feucht?korr=<wert>\"\n\tsetzt den Korrekturwert fuer die Feuchtigkeitsmessung\n";
  antwort = antwort + "\"<IP-Adresse>/zeit?delta=<wert \"\n\tsetzt die Zeitspanne (in Sekunden), nach der spaetestens eine CCU-Meldung erfolgt\n";
  antwort = antwort + "\"<IP-Adresse>/zeit?mess=<wert>\"\n\tdefiniert das Messintervall (in Sekunden)\n";
  server.send(300, "text/plain", antwort);
  delay(150);
  Serial.println(zeitstempel() + "  unspezifische HTTP-Anfrage");
}

void melde_feucht() { // bei Aufruf von ".../feucht"
  String delta = server.arg("delta");
  String korr = server.arg("korr");
  if (delta != "") {
    deltaFeucht = delta.toFloat();
    server.send(200, "text/plain", "Feuchtigkeitsdifferenzwert fuer CCU-Meldungen auf " + delta + " % gesetzt.");
    delay(100);
    Serial.println(zeitstempel() + "  Feuchtigkeitsdifferenzwert ueber HTTP geaendert: " + delta + " %");
  }
  else if (korr != "") {
    korrFeucht = korr.toFloat() * 1000;
    server.send(200, "text/plain", "Korrekturwert fuer Feuchtigkeitsmessung auf " + korr + " % gesetzt.");
    delay(100);
    Serial.println(zeitstempel() + "  Feuchtigkeitskorrekturwert ueber HTTP geaendert: " + korr + " %");
  }
  else {
    server.send(200, "text/plain", String(feucht));
    delay(100);
    Serial.println(zeitstempel() + "  Luftfeuchtigkeit ueber HTTP gemeldet");
  } 
}

void melde_temp() { // bei Aufruf von ".../temp"
  String delta = server.arg("delta");
  String korr = server.arg("korr");
  if (delta != "") {
    deltaTemp = delta.toFloat();
    server.send(200, "text/plain", "Temperaturdifferenzwert fuer CCU-Meldungen auf " + delta + " * C gesetzt.");
    delay(100);
    Serial.println(zeitstempel() + "  Temperaturdifferenzwert ueber HTTP geaendert: " + delta + " * C");
  }
  else if (korr != "") {
    korrTemp = korr.toFloat() * 1000;
    server.send(200, "text/plain", "Korrekturwert fuer Temperaturmessung auf " + korr + " * C gesetzt.");
    delay(100);
    Serial.println(zeitstempel() + "  Temperaturkorrekturwert ueber HTTP geaendert: " + korr + " Sekunden");
  }
  else {
    server.send(200, "text/plain", String(temp));
    delay(100);
    Serial.println(zeitstempel() + "  Temperatur ueber HTTP gemeldet");
  }
}

void melde_zeit() { // bei Aufruf von ".../zeit"
  String delta = server.arg("delta");
  String mess = server.arg("mess");
  if (delta != "") {
    deltaMeldungSekunden = delta.toInt();
    deltaMeldungMillis = deltaMeldungSekunden * 1000;
    server.send(200, "text/plain", "Zeitintervall fuer CCU-Meldungen auf " + delta + " Sekunden gesetzt.");
    delay(100);
    Serial.println(zeitstempel() + "  Zeitintervall fuer CCU-Meldungen ueber HTTP geaendert: " + delta + " Sekunden");
  }
  else if (mess != "") {
    deltaMessungMillis = mess.toInt() * 1000;
    server.send(200, "text/plain", "Zeitintervall fuer Sensorabfrage auf " + mess + " Sekunden gesetzt.");
    delay(100);
    Serial.println(zeitstempel() + "  Zeitintervall fuer Sensorabfrage ueber HTTP geaendert: " + mess + " Sekunden");
  }
  else {
    server.send(200, "text/plain", "Letzte Aktualisierung der CCU\n" + letzteMeldungCCUzeit);
    delay(100);
    Serial.println(zeitstempel() + "  Letzte Aktualisierung der CCU ueber HTTP Status gemeldet");
  }
}

void setup() 
{
  Serial.begin(115200);
  Wire.begin(0,2);
  BMESensor.begin(); // Sensor initialisieren
  
  // Seriellen Monitor für Kontrollausgaben öffnen
  
  Serial.println("");
  Serial.println("WeMos Temperatur-/Luftfeuchtesensor");
  
  // WLAN-Verbindung herstellen
  WiFi.config(ip, gateway, subnet); // auskommentieren, falls eine dynamische IP bezogen werden soll
  WiFi.begin(ssid, password);
  Serial.print("Verbindungsaufbau");

  // Verbindungsaufbau abwarten
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" erfolgreich!");
  Serial.println("");
  Serial.print("Verbunden mit: ");
  Serial.println(ssid);
  Serial.print("Signalstaerke: ");
  int rssi = WiFi.RSSI();
  Serial.print(rssi);
  Serial.println(" dBm");
  Serial.print("IP-Adresse: ");
  Serial.println(WiFi.localIP());
  Serial.println("");

  // HTTP-Anfragen bearbeiten
  server.on("/", wurzel_behandlung);
  server.on("/temp", melde_temp);
  server.on("/feucht", melde_feucht);
  server.on("/zeit", melde_zeit);
  
  // HTTP-Server starten
  server.begin();
  Serial.println(zeitstempel() + "  HTTP-Server gestartet");

  // Startwerte fuer Zeittrigger
  letzteMessungMillis = millis();
  letzteMeldungMillis = millis();
}

void loop() {

  BMESensor.refresh();                                                  // read current sensor data
  //sprintf(bufout,"%c[1;0H",ASCII_ESC);
  //Serial.print(bufout);
  Serial.println(" ");
 
  // auf HTTP-Anfragen warten
  server.handleClient();

  jetztMillis = millis();

  // neue Messung falls Zeitintervall erreicht
  if(jetztMillis - letzteMessungMillis > deltaMessungMillis) {
    messung();
  }

  // neue Meldung an die CCU falls Zeitintervall erreicht
  if(!deltaMeldungMillis == 0 && jetztMillis - letzteMeldungMillis > deltaMeldungMillis) {
    Serial.print(zeitstempel() + "  Zeitintervall erreicht: "); 
    melde_CCU();
  }
   
  // neue Meldung an die CCU falls Luftfeuchtigkeitsaenderung den Schwellwert erreicht
   if(!deltaFeucht == 0 && abs(feucht - feuchtCCU) >= deltaFeucht) {
    Serial.print(zeitstempel() + "  Luftfeuchtigkeitsaenderung: "); 
   melde_CCU();
 }

  // neue Meldung an die CCU falls Temperaturaenderung den Schwellwert erreicht
  if(!deltaTemp == 0 && abs(temp - tempCCU) >= deltaTemp) { // Neue Meldung wg. Temperaturaenderung?
    Serial.print(zeitstempel() + "  Temperatursaenderung: "); 
    melde_CCU();
  }
}
Leider bringt mir der Wemos am Monitor dann nur schnell durchlaufende Symbole, keine Werte, nichts. Er ist auch nicht per IP ansprechbar. Könnte aber auch sein, dass der Wemos einen Schuss hat oder eben im Sketch was nicht stimmt.
Was durchaus sein könnte, da dieser einfach eine Mixtur aus den beiden Sktechen im Wiki ( BME280 und Sys-Variable sowie DHT und CuxD) ist.

Könnte evtl. jemand testen ?

DANKE

klassisch
Beiträge: 3974
Registriert: 24.03.2011, 04:32
System: Alternative CCU (auf Basis OCCU)
Hat sich bedankt: 110 Mal
Danksagung erhalten: 71 Mal

Re: WeMos D1 mini als WLAN-Sensor/-Aktor

Beitrag von klassisch » 12.10.2016, 18:05

mike9677 hat geschrieben: Leider bringt mir der Wemos am Monitor dann nur schnell durchlaufende Symbole, keine Werte, nichts.
Die baudraute ist aber richtig eingestellt?
mike9677 hat geschrieben: Könnte aber auch sein, dass der Wemos einen Schuss hat
Das kannst Du mit einem einfachen Beispielsketch z.B. Blink austesten.

Antworten

Zurück zu „HomeMatic Tipps & Tricks - keine Fragen!“