da der eigentliche Wemos D1 thread etwas voll geworden ist stell ich hier mal ein kleines separates Projekt vor um 10x 1-wire Sensoren an die Homematic anzubinden.
Das ganze läuft über einen Wemos D1 mini. Kaufen kann man den am günstigsten über einen der üblichen China Händler (Aliexpress etc)
Das Printnetzteil sowie die verwendeten Sicherungen bekommt man bei Reichelt relativ günstig. Zum betreiben der 1-Wire Sensoren benötigt man nur noch einen 4,7kOhm großen Widerstand. In der Homematic selber müssen nur die entsprechenden Systemvariablen vom Typ Zahl angelegt werden.
Der Arduino Sketch ist von mir schon mal vor ausgefüllt. Einfach die entsprechenden Daten für seine Zwecke anpassen.
Da man am Anfang noch nicht die genauen Adressen der 1-Wire Fühler hat, muss man einfach die Fühler anschließen und den Sketch starten. Über den Seriellen Monitor oder über die IP Adresse (Webbrowser) kann man dann die verwendeten 1-Wire Adressen sich anzeigen lassen und anschließend im Sketch eintragen.
Die Bibliothek "Umlaute" habe ich als zip angehängt.
Code: Alles auswählen
#include <OneWire.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <Umlaute.h>
// DS18S20 Temperaturchip i/o
OneWire ds(D1); // an pin D1
//Hier die Adressen von den Sensoren eingeben
#define Warmwasser_unten "28 F4 93 87 4 0 0 88" //Dies sind nur Beispiele, Wichtig hier keine Umlaute verwenden
#define Warmwasser_oben "28 FA B2 88 4 0 0 34"
#define Vorlauf_Heizung ""
#define Ruecklauf_Heizung ""
#define Vorlauf_Werkstatt ""
#define Ruecklauf_Heizung ""
#define Reserve1 ""
#define Reserve2 ""
#define Reserve3 ""
#define Reserve4 ""
#define SENSOR1 Warmwasser_unten //Dies sind nur Beispiele, Wichtig hier keine Umlaute verwenden
#define SENSOR2 Warmwasser_oben
#define SENSOR3 Vorlauf_Heizung
#define SENSOR4 Ruecklauf_Heizung
#define SENSOR5 Vorlauf_Werkstatt
#define SENSOR6 Ruecklauf_Heizung
#define SENSOR7 Reserve1
#define SENSOR8 Reserve2
#define SENSOR9 Reserve3
#define SENSOR10 Reserve4
// Einstellungen für Messungen und Meldungen
#define ZEITINTERVALL_MESSUNGEN 10 //Abfragezyklus der Sensoren in Sekunden
#define ZEITINTERVALL_MELDUNGEN 60 //Sendeintervall an die Homematic in Sekunden
#define DELTA_TEMPERATURSCHWELLWERT 1 //Temperaturdifferenz zum senden an die Homematic in °C
// ******* Netzwerkeinstellungen, bitte anpassen! *******
const char* ssid = "linksys"; // SSID des vorhandenen WLANs
const char* password = "Neindasverrateichnicht"; // Passwort für das vorhandene WLAN
IPAddress gateway(192,168,1,1); // IP-Adresse des WLAN-Gateways
IPAddress subnet(255,255,255,0); // Subnetzmaske
IPAddress ip(192,168,1,156); // feste IP-Adresse für den WeMos
const char* host = "192.168.1.13"; // IP-Adresse der CCU
ESP8266WebServer server(80); // Webserver initialisieren auf Port 80
// convert String object from UTF8 String to Extended ASCII
void MeldeWert(char* Sensor, float Temp)
{
String strSensor;
if(Contains(Sensor,"Sensor1")) strSensor = "Warmwasser_unten"; //hier dürfen auch Umlaute (ä,ü,ö) verwendet werden, das sind die Systemvariablen für die Homematic
if(Contains(Sensor,"Sensor2")) strSensor = "Warmwasser_oben"; //hier dürfen auch Umlaute (ä,ü,ö) verwendet werden, das sind die Systemvariablen für die Homematic
if(Contains(Sensor,"Sensor3")) strSensor = "Vorlauf_Heizung"; //hier dürfen auch Umlaute (ä,ü,ö) verwendet werden, das sind die Systemvariablen für die Homematic
if(Contains(Sensor,"Sensor4")) strSensor = "Rücklauf_Heizung"; //hier dürfen auch Umlaute (ä,ü,ö) verwendet werden, das sind die Systemvariablen für die Homematic
if(Contains(Sensor,"Sensor5")) strSensor = "Vorlauf_Werkstatt"; //hier dürfen auch Umlaute (ä,ü,ö) verwendet werden, das sind die Systemvariablen für die Homematic
if(Contains(Sensor,"Sensor6")) strSensor = "Rücklauf_Werkstatt"; //hier dürfen auch Umlaute (ä,ü,ö) verwendet werden, das sind die Systemvariablen für die Homematic
if(Contains(Sensor,"Sensor7")) strSensor = "Reserve1"; //hier dürfen auch Umlaute (ä,ü,ö) verwendet werden, das sind die Systemvariablen für die Homematic
if(Contains(Sensor,"Sensor8")) strSensor = "Reserve2"; //hier dürfen auch Umlaute (ä,ü,ö) verwendet werden, das sind die Systemvariablen für die Homematic
if(Contains(Sensor,"Sensor9")) strSensor = "Reserve3"; //hier dürfen auch Umlaute (ä,ü,ö) verwendet werden, das sind die Systemvariablen für die Homematic
if(Contains(Sensor,"Sensor10")) strSensor = "Reserve4"; //hier dürfen auch Umlaute (ä,ü,ö) verwendet werden, das sind die Systemvariablen für die Homematic
strSensor = utf8ascii(strSensor);
Serial.println("StrSensor: " + strSensor + " und " + "Sensor: " + Sensor);
String meldung = "";
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(50);
return;
}
meldung =meldung +"GET /eriwan.exe?befehl=dom.GetObject('" + strSensor +"').State('" + Temp + "')";
meldung = meldung + " HTTP/1.1\r\n" + "Host: " + host + ":8181" + "\r\n" + "Connection: close\r\n\r\n";
client.print(meldung); // Daten an CCU melden
}
char ConnectString[255] = "";
String Antwort = "";
unsigned long deltaMessungSekunden = ZEITINTERVALL_MESSUNGEN; //Zeitintervall (Sekunden) nach dem eine Messung erfolgt
unsigned long deltaMeldungSekunden = ZEITINTERVALL_MELDUNGEN; // Zeitintervall (Sekunden) nach dem eine CCU-Meldung erfolgt (0 bedeutet nie)
unsigned long jetztMillis = 0;
unsigned long deltaMessungMillis = deltaMessungSekunden * 1000, letzteMessungMillis = 0;
unsigned long deltaMeldungMillis = deltaMeldungSekunden * 1000, letzteMeldungMillis = 0;
String antwort = "", meldung = "";
float deltaTemp = DELTA_TEMPERATURSCHWELLWERT; // Temperaturaenderung (*C) bei der eine CCU-Meldung erfolgt (0 bedeutet nie)
float temp = 0, tempCCU = 0;
float NewTemp[10] = {-255,-255,-255,-255,-255,-255,-255,-255,-255,-255};
float OldTemp[10] = {-255,-255,-255,-255,-255,-255,-255,-255,-255,-255};
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 WLANVerbindung()
{
// WLAN-Verbindung herstellen
WiFi.config(ip, gateway, subnet); // auskommentieren, falls eine dynamische IP bezogen werden soll
WiFi.begin(ssid, password);
Serial.print("Verbindungsaufbau");
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("");
sprintf(ConnectString, "</br></br>Verbunden mit: %s </br>Signalstaerke: %d dBm </br></br>", ssid, rssi);
server.on("/", Hauptseite);
// HTTP-Server starten
server.begin();
}
void setup(void)
{
// inputs/outputs initialisieren
// seriellen port starten
Serial.begin(9600);
//ListSensors();
WLANVerbindung();
}
bool Contains(String s, String search)
{
int max = s.length() - search.length();
for (int i = 0; i <= max; i++) {
if (s.substring(i) == search) return true; // or i
}
return false; //or -1
}
void ListSensors(void)
{
int count=0,i=0;
byte addr[8];
float Temp = 0.0;
char Adress[10][255] = {"","","","","","","","","",""};
while(ds.search(addr))
{
sprintf(Adress[count], "");
for( i = 0; i < 8; i++)
{
sprintf(Adress[count], "%s %X", Adress[count],addr[i]);
}
count++;
}
Antwort += "Gefundene Sensoren \n</br>";
Serial.print("\nGefundene Sensoren\n");
for(count = 0; count<10;count++)
{
if(strcmp(Adress[count], ""))
{
Antwort += Adress[count];
Serial.print(Adress[count]);
Antwort += " Wert: ";
Serial.print(" Wert: ");
Temp = GetRoomTemperature(Adress[count], true);
Antwort += Temp;
Serial.print(Temp);
Antwort += "\n</br>";
Serial.print("\n");
}
}
Antwort += "</br>";
Serial.print("\n");
Antwort += "Definierte Sensoren:\n</br>";
Serial.print("Definierte Sensoren:\n");
for(count = 0; count<10;count++)
{
if(Contains(Adress[count], SENSOR1) && strcmp(Adress[count], "") && strcmp(SENSOR1, ""))
{
Antwort += "SENSOR1: ";
Serial.print("SENSOR1: ");
Antwort += Adress[count];
Serial.print(Adress[count]);
Antwort += " Wert: ";
Serial.print(" Wert: ");
Temp = GetRoomTemperature(Adress[count], true);
Antwort += Temp;
Serial.print(Temp);
Antwort += "\n</br>";
Serial.print("\n");
//MeldeWert("Sensor1", Temp);
OldTemp[0] = NewTemp[0];
NewTemp[0] = Temp;
if(OldTemp[0] == -255) OldTemp[0] = Temp;
}
else if(Contains(Adress[count], SENSOR2) && strcmp(Adress[count], "") && strcmp(SENSOR2, ""))
{
Antwort += "SENSOR2: ";
Serial.print("SENSOR2: ");
Antwort += Adress[count];
Serial.print(Adress[count]);
Antwort += " Wert: ";
Serial.print(" Wert: ");
Temp = GetRoomTemperature(Adress[count], true);
Antwort += Temp;
Serial.print(Temp);
Antwort += "\n</br>";
Serial.print("\n");
//MeldeWert("Sensor2", Temp);
OldTemp[1] = NewTemp[1];
NewTemp[1] = Temp;
if(OldTemp[1] == -255) OldTemp[1] = Temp;
}
else if(Contains(Adress[count], SENSOR3) && strcmp(Adress[count], "") && strcmp(SENSOR3, ""))
{
Antwort += "SENSOR3: ";
Serial.print("SENSOR3: ");
Antwort += Adress[count];
Serial.print(Adress[count]);
Antwort += " Wert: ";
Serial.print(" Wert: ");
Temp = GetRoomTemperature(Adress[count], true);
Antwort += Temp;
Serial.print(Temp);
Antwort += "\n</br>";
Serial.print("\n");
//MeldeWert("Sensor3", Temp);
OldTemp[2] = NewTemp[2];
NewTemp[2] = Temp;
if(OldTemp[2] == -255) OldTemp[2] = Temp;
}
else if(Contains(Adress[count], SENSOR4) && strcmp(Adress[count], "") && strcmp(SENSOR4, ""))
{
Antwort += "SENSOR4: ";
Serial.print("SENSOR4: ");
Antwort += Adress[count];
Serial.print(Adress[count]);
Antwort += " Wert: ";
Serial.print(" Wert: ");
Temp = GetRoomTemperature(Adress[count], true);
Antwort += Temp;
Serial.print(Temp);
Antwort += "\n</br>";
Serial.print("\n");
//MeldeWert("Sensor4", Temp);
OldTemp[3] = NewTemp[3];
NewTemp[3] = Temp;
if(OldTemp[3] == -255) OldTemp[3] = Temp;
}
else if(Contains(Adress[count], SENSOR5) && strcmp(Adress[count], "") && strcmp(SENSOR5, ""))
{
Antwort += "SENSOR5: ";
Serial.print("SENSOR5: ");
Antwort += Adress[count];
Serial.print(Adress[count]);
Antwort += " Wert: ";
Serial.print(" Wert: ");
Temp = GetRoomTemperature(Adress[count], true);
Antwort += Temp;
Serial.print(Temp);
Antwort += "\n</br>";
Serial.print("\n");
//MeldeWert("Sensor5", Temp);
OldTemp[4] = NewTemp[4];
NewTemp[4] = Temp;
if(OldTemp[4] == -255) OldTemp[4] = Temp;
}
else if(Contains(Adress[count], SENSOR6) && strcmp(Adress[count], "") && strcmp(SENSOR6, ""))
{
Antwort += "SENSOR6: ";
Serial.print("SENSOR6: ");
Antwort += Adress[count];
Serial.print(Adress[count]);
Antwort += " Wert: ";
Serial.print(" Wert: ");
Temp = GetRoomTemperature(Adress[count], true);
Antwort += Temp;
Serial.print(Temp);
Antwort += "\n</br>";
Serial.print("\n");
//MeldeWert("Sensor6", Temp);
OldTemp[5] = NewTemp[5];
NewTemp[5] = Temp;
if(OldTemp[5] == -255) OldTemp[5] = Temp;
}
else if(Contains(Adress[count], SENSOR7) && strcmp(Adress[count], "") && strcmp(SENSOR7, ""))
{
Antwort += "SENSOR7: ";
Serial.print("SENSOR7: ");
Antwort += Adress[count];
Serial.print(Adress[count]);
Antwort += " Wert: ";
Serial.print(" Wert: ");
Temp = GetRoomTemperature(Adress[count], true);
Antwort += Temp;
Serial.print(Temp);
Antwort += "\n</br>";
Serial.print("\n");
//MeldeWert("Sensor7", Temp);
OldTemp[6] = NewTemp[6];
NewTemp[6] = Temp;
if(OldTemp[6] == -255) OldTemp[6] = Temp;
}
else if(Contains(Adress[count], SENSOR8) && strcmp(Adress[count], "") && strcmp(SENSOR8, ""))
{
Antwort += "SENSOR8: ";
Serial.print("SENSOR8: ");
Antwort += Adress[count];
Serial.print(Adress[count]);
Antwort += " Wert: ";
Serial.print(" Wert: ");
Temp = GetRoomTemperature(Adress[count], true);
Antwort += Temp;
Serial.print(Temp);
Antwort += "\n</br>";
Serial.print("\n");
//MeldeWert("Sensor8", Temp);
OldTemp[7] = NewTemp[7];
NewTemp[7] = Temp;
if(OldTemp[7] == -255) OldTemp[7] = Temp;
}
else if(Contains(Adress[count], SENSOR9) && strcmp(Adress[count], "") && strcmp(SENSOR9, ""))
{
Antwort += "SENSOR9: ";
Serial.print("SENSOR9: ");
Antwort += Adress[count];
Serial.print(Adress[count]);
Antwort += " Wert: ";
Serial.print(" Wert: ");
Temp = GetRoomTemperature(Adress[count], true);
Antwort += Temp;
Serial.print(Temp);
Antwort += "\n</br>";
Serial.print("\n");
//MeldeWert("Sensor9", Temp);
OldTemp[8] = NewTemp[8];
NewTemp[8] = Temp;
if(OldTemp[8] == -255) OldTemp[8] = Temp;
}
else if(Contains(Adress[count], SENSOR10) && strcmp(Adress[count], "") && strcmp(SENSOR10, ""))
{
Antwort += "SENSOR10: ";
Serial.print("SENSOR10: ");
Antwort += Adress[count];
Serial.print(Adress[count]);
Antwort += " Wert: ";
Serial.print(" Wert: ");
Temp = GetRoomTemperature(Adress[count], true);
Antwort += Temp;
Serial.print(Temp);
Antwort += "\n</br>";
Serial.print("\n");
//MeldeWert("Sensor10", Temp);
OldTemp[9] = NewTemp[9];
NewTemp[9] = Temp;
if(OldTemp[9] == -255) OldTemp[9] = Temp;
}
}
Antwort += "</br>";
Serial.print("\n");
Antwort += "Nicht definierte Sensoren:\n</br>";
Serial.print("Nicht definierte Sensoren:\n");
for(count = 0; count<10;count++)
{
//Serial.print(Adress[count]);
if(!(Contains(Adress[count], SENSOR1) && strcmp(SENSOR1, "")) &&
!(Contains(Adress[count], SENSOR2) && strcmp(SENSOR2, "")) &&
!(Contains(Adress[count], SENSOR3) && strcmp(SENSOR3, "")) &&
!(Contains(Adress[count], SENSOR4) && strcmp(SENSOR4, "")) &&
!(Contains(Adress[count], SENSOR5) && strcmp(SENSOR5, "")) &&
!(Contains(Adress[count], SENSOR6) && strcmp(SENSOR6, "")) &&
!(Contains(Adress[count], SENSOR7) && strcmp(SENSOR7, "")) &&
!(Contains(Adress[count], SENSOR8) && strcmp(SENSOR8, "")) &&
!(Contains(Adress[count], SENSOR9) && strcmp(SENSOR9, "")) &&
!(Contains(Adress[count], SENSOR10) && strcmp(SENSOR10, "")))
{
if(strcmp(Adress[count], ""))
{
Antwort += Adress[count];
Serial.print(Adress[count]);
Antwort += " Wert: ";
Serial.print(" Wert: ");
Temp = GetRoomTemperature(Adress[count], true);
Antwort += Temp;
Serial.print(Temp);
Antwort += "\n</br>";
Serial.print("\n");
}
}
}
letzteMessungMillis = jetztMillis;
ds.reset_search();
}
void Hauptseite()
{
Antwort = "";
Antwort += "<meta http-equiv='refresh' content='60'/>";
ListSensors();
Antwort += ConnectString;
//Antwort += "</body></html>";
server.send ( 300, "text/html", Antwort );
delay(100);
//server.send(300, "text/plain", Antwort);
//delay(150);
}
float GetRoomTemperature(char adress[255], bool doreset)
{
int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract;
byte i,present = 0, data[12], addr[8];
char stradd[255];
while(ds.search(addr))
{
sprintf(stradd, "");
//Serial.print("\nR=");
for( i = 0; i < 8; i++)
{
sprintf(stradd, "%s %X", stradd,addr[i]);
}
ds.reset();
ds.select(addr);
ds.write(0x44,1); // start Konvertierung, mit power-on am Ende
delay(50); // 750ms sollten ausreichen
// man sollte ein ds.depower() hier machen, aber ein reset tut das auch
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Wert lesen
for ( i = 0; i < 9; i++)
{
// 9 bytes
data[i] = ds.read();
}
if(Contains(stradd, adress))
{
LowByte = data[0];
HighByte = data[1];
TReading = (HighByte << 8) + LowByte;
SignBit = TReading & 0x8000; // test most sig bit
if (SignBit) // negative
{
TReading = (TReading ^ 0xffff) + 1; // 2's comp
}
Tc_100 = (6 * TReading) + TReading / 4; // mal (100 * 0.0625) oder 6.25
/* Für DS18S20 folgendes verwenden Tc_100 = (TReading*100/2); */
Whole = Tc_100 / 100; // Ganzzahlen und Brüche trennen
Fract = Tc_100 % 100;
if (SignBit) // negative Werte ermitteln
{
//Serial.print("-");
}
if(doreset)ds.reset_search();
return (float)Whole+((float)Fract/100);
}
}
}
char Sensor[16];
void loop(void)
{
server.handleClient(); // auf HTTP-Anfragen warten
jetztMillis = millis();
// neue Messung falls Zeitintervall erreicht
if(jetztMillis - letzteMessungMillis > deltaMessungMillis)
{
ListSensors();
}
for(int c = 0; c <10;c++)
{
if(deltaTemp != 0 && abs(OldTemp[c]- NewTemp[c]) > deltaTemp)
{
Serial.print("Temperatur änderung bei Sensor: ");
Serial.print(c+1);
Serial.print(" erreicht.");
OldTemp[c] = NewTemp[c];
sprintf(Sensor, "Sensor%d", c+1);
MeldeWert(Sensor, NewTemp[c]);
}
}
// neue Meldung an die CCU falls Zeitintervall erreicht
if(!deltaMeldungMillis == 0 && jetztMillis - letzteMeldungMillis > deltaMeldungMillis)
{
Serial.print(zeitstempel() + " Zeitintervall erreicht: \n");
letzteMeldungMillis = jetztMillis;
//melde_CCU();
for(int c = 0; c <10;c++)
{
sprintf(Sensor, "Sensor%d", c+1);
MeldeWert(Sensor, NewTemp[c]);
}
}
}