Steuerung Pumpenvorlage mittels Füllstandskontrolle

Programmierung der HomeMatic CCU mittels contronics homeputer CL

Moderator: Co-Administratoren

AFi
Beiträge: 166
Registriert: 14.12.2016, 20:44

Re: Steuerung Pumpenvorlage mittels Füllstandskontrolle

Beitrag von AFi » 02.07.2017, 19:55

Hi,

Problem gelöst, jetzt kann die Programmierung kommen.

Ursache:
Com3 auf PC: 57600 Baudrate
IDE Upload: 57600

Einstellungen waren bei 9600.

Jetzt habe ich keine Fehlermeldungen mehr, verstehen muss ich dies jedoch nicht. (Info war in Forum)

Gruß Axel

AFi
Beiträge: 166
Registriert: 14.12.2016, 20:44

Re: Steuerung Pumpenvorlage mittels Füllstandskontrolle

Beitrag von AFi » 09.07.2017, 10:30

Hi,

steh gerade prinzipiell an.

Die Software auf dem Arduino ist programmiert (Änderung von Vorlage -m.yoda) und hochgeladen. Der Arduino ist ersichtlich
im Router und auf der Geräteanzeige in Windows, also eigentlich alles ok. Der Webserver auf der CCU2 ist schon lange installiert, da ich auf die EE via Webserver für die Haupteinstellungen auch zugreife.

Wie frage ich jetzt die gesendeten Werte in HC ab? Ist es der gleiche Webserver, lieg ich da richtig?

Gruß Axel

Familienvater
Beiträge: 7151
Registriert: 31.12.2006, 15:18
System: Alternative CCU (auf Basis OCCU)
Wohnort: Rhein-Main
Danksagung erhalten: 34 Mal

Re: Steuerung Pumpenvorlage mittels Füllstandskontrolle

Beitrag von Familienvater » 09.07.2017, 10:37

Hi,

ich kenne die Vorlage vom Yoga nicht, aber ich gehe davon aus, das dort in eine Systemvariable der WebUI geschrieben wird, Du willst aber ein Objekt in HPCL beschreiben, also musst Du Deine Daten auf das CLWebI.ccc-Interface "schreiben", das PDF hatte ich Dir ja mal verlinkt. Dann kannst Du nämlich einfach das Objekt in HPCL auf Änderung triggern, und wenn Daten vom wemos kommen, dann passiert irgendwas in HPCL, da wird nur gepusht und nicht sinnlos gepollt.

Der Familienvater

AFi
Beiträge: 166
Registriert: 14.12.2016, 20:44

Re: Steuerung Pumpenvorlage mittels Füllstandskontrolle

Beitrag von AFi » 09.07.2017, 10:58

Hi,

Besten Dank, anbei Code

Code: Alles auswählen

/*
 *  WeMos-Schaltaktor (Prototyp)
 *  
 *  verbindet sich mit dem vorhandenen WLAN als Server
 *  Steuerung über HTTP-Befehle:
 *     "<IP-Adresse>" gibt eine Status- und Befehlsübersicht aus
 *     "<IP-Adresse>/aus" schaltet das Relais aus
 *     "<IP-Adresse>/ein" schaltet das Relais ein
 *     "<IP-Adresse>/status" gibt den Schaltzustand des Relais als Logikwert ("ein" oder "aus") zurück
 *
 *  Getesteter Aufbau:
 *     WeMos D1 mini
 *     Relay Shield mini
 *     Pin-Belegung:
 *        D1: Steuerleitung Relais
 *
 *  31.Januar 2016 —m.yoda
 */

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>

// ******* Netzwerkeinstellungen, bitte anpassen! *******
const char* ssid     = "abc123"; // SSID des vorhandenen WLANs
const char* password = "geheim"; // 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

ESP8266WebServer server(80); // Webserver initialisieren auf Port 80
String antwort = "";

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 wurzel_behandlung() { // bei Aufruf des Root-Verzeichnisses
  String temp = zeitstempel();
  antwort = "WeMos Schaltaktor\n\n";
  if (digitalRead(D1) == HIGH)
    antwort = antwort + "Status: eingeschaltet\n";
  else
    antwort = antwort + "Status: ausgeschaltet\n";
  antwort = antwort + "Betriebszeit: " + temp + " (Std:Min:Sek)\n";
  antwort = antwort + "Verbunden mit: " + ssid + "\n";
  int rssi = WiFi.RSSI();
  antwort = antwort + "Signalstaerke: " + String(rssi) + " dBm\n\n";
  antwort = antwort + "HTTP-Befehlsuebersicht:\n";
  antwort = antwort + "\"<IP-Adresse>/aus\" schaltet das Relais aus\n";
  antwort = antwort + "\"<IP-Adresse>/ein\" schaltet das Relais ein\n";
  antwort = antwort + "\"<IP-Adresse>/status\" gibt den Schaltzustand des\n  Relais als Logikwert (\"ein\" oder \"aus\") zurueck\n";
  server.send(300, "text/plain", antwort);
  delay(150);
  Serial.println(temp + " unspezifische HTTP-Anfrage");
}

void mach_an() {
  pinMode(D1, OUTPUT);
  digitalWrite(D1, HIGH);
  server.send(200, "text/plain", "WeMos-Schaltaktor ist eingeschaltet");
  delay(100);
  Serial.println(zeitstempel() + " ueber HTTP eingeschaltet");
}

void mach_aus() {
  pinMode(D1, OUTPUT);
  digitalWrite(D1, LOW);
  server.send(200, "text/plain", "WeMos-Schaltaktor ist ausgeschaltet");
  delay(100);
  Serial.println(zeitstempel() + " ueber HTTP ausgeschaltet");
}

void melde_status() {
  String temp = zeitstempel();
  if (digitalRead(D1) == HIGH)
    antwort = "ein";
  else
    antwort = "aus";
  server.send(200, "text/plain", antwort);
  delay(100);
  Serial.println(zeitstempel() + " ueber HTTP Status gemeldet");
}

void setup() {
  pinMode(D1, OUTPUT); // Relais-Pin als Ausgang setzen
  
  // Seriellen Monitor für Kontrollausgaben öffnen
  Serial.begin(9600);
  Serial.println("");
  Serial.println("WeMos-Schaltaktor");
  
  // 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("/ein", mach_an);
  server.on("/aus", mach_aus);
  server.on("/status", melde_status);
  
  // HTTP-Server starten
  server.begin();
  Serial.println(zeitstempel() + " HTTP-Server gestartet");
}

void loop() {
  server.handleClient(); // auf HTTP-Anfragen warten
}
Die pdf habe ich gelesen, leider fehlt mir der Bezug zu HPCL oder CCU2, so dass ich den Wert in eine Variable einschreiben kann, sorry steh gerade noch bei Adam und Eva auf diesem Gebiet. Die Beschreibung den Wert in Explorer abzufragen hilft mir nicht.
Mit dem Webserver lieg ich da richtig?

Gruß Axel

Familienvater
Beiträge: 7151
Registriert: 31.12.2006, 15:18
System: Alternative CCU (auf Basis OCCU)
Wohnort: Rhein-Main
Danksagung erhalten: 34 Mal

Re: Steuerung Pumpenvorlage mittels Füllstandskontrolle

Beitrag von Familienvater » 09.07.2017, 17:17

Hi,

bei dem Sketch sehe ich nur einen Webserver auf dem Wemos, der müsste regelmäßigst von HPCL abgefragt werden, und bei Deiner Anwendung reicht es auch wieder nicht, alle 2 Minuten den Status abzufragen...

Dein Sketch muss "aktiv" einen WebRequest an den HPCL-Webserver schicken, damit dann eventgetriggert was in HPCL passieren kann.

Du musst nach Beispielen z.B. mit dieser Bibliothek schauen:

Code: Alles auswählen

#include <ESP8266HTTPClient.h>
und dann so etwas wie

Code: Alles auswählen

    String completeURI = "http://192.168.1.87/addons/contronics/CLWebI.ccc?GETVARBYNAME1&UHR"

    HTTPClient http;
    http.begin(completeURI);
    int httpCode = http.GET();
    // file found at server
    if(httpCode == HTTP_CODE_OK) {
      requestResult = http.getString();
      Serial.println(requestResult);
    }
    else
    {
      Serial.print("Result-Code");
      Serial.println(httpCode);
    }
    http.end();
Der Familienvater

AFi
Beiträge: 166
Registriert: 14.12.2016, 20:44

Re: Steuerung Pumpenvorlage mittels Füllstandskontrolle

Beitrag von AFi » 09.07.2017, 18:23

Hi,

besten Dank, aber ich verzweifle immer noch. Der untenstehende Sketch sollte sich doch mit der CCU2 verbinden, somit muss ich doch nur noch eine Systemvariable
in der CCU2 konfigurieren und ein Script dazu schreiben (da fängt das Unwissen an, da ich bisher nur HPCL programmiert habe). Diese Systemvariable müsste ich doch
dann in HPCL nur noch abfragen?

Code: Alles auswählen

/*
 *  WeMos LevelControl
 *  
 *  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>/level" gibt die zuletzt gemessene Temperatur aus (mWS)
 *     "<IP-Adresse>/zeit" gibt den CCU-Zeitstempel aus, an dem die letzte Meldung an die CCU erfolgte
 *    
 *  Getesteter Aufbau:
 *     AZDelivery D1 Mini NodeMcu Lua ESP8266 ESP-12E WLAN WIFI Internet Module Entwicklungsboard für Arduino, 100% kompatibel mit WeMos D1 Mini
 *     
 *     Pin-Belegung:
 *        A0 = analoger Eingang
 *  
 *     DHT sensor library by Adafruit v.1.2.3
 *
 *  9.Februar 2016 —m.yoda
 *  1. Juli 2017 -AFi
 */

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>

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

float sensorPin = A0;
unsigned long deltaMessungSekunden = 10; //Zeitintervall (Sekunden) nach dem eine Messung erfolgt
float korrLevel = 0; // Korrekturwert fuer die Level Messung


// ******* Einstellungen fuer Meldungen an die CCU, bitte anpassen! *******
String levelCCUname = "P_004LevelTonne"; // Bezeichnung der CCU-Systemvariable für die gemessene Temperatur
unsigned long deltaMeldungSekunden = 3600; // Zeitintervall (Sekunden) nach dem eine CCU-Meldung erfolgt (0 bedeutet nie)
float deltaLevel = 2; // Levelaenderung (*mWS) bei der eine CCU-Meldung erfolgt (0 bedeutet nie)


float level = 0, levelCCU = 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
    level = analogRead(sensorPin) + korrLevel;
    if (isnan(level)) {
     Serial.println(zeitstempel() + "  Fehler: Sensor konnte nicht abgefragt werden");
     delay(100);
     return;
    }
  letzteMessungMillis = jetztMillis;
  Serial.println(zeitstempel() + "  Messung LEVEL: " + level + " mWS ");
}

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;
  }
  meldung = "GET /eriwan.exe?antwort1=dom.GetObject('" + levelCCUname + "').State('" + level + "')";
  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
  levelCCU = level;
}   

void melde_level() { // bei Aufruf von ".../level"
    server.send(200, "text/plain", String(level));
    delay(100);
    Serial.println(zeitstempel() + "  Level 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() {
  // Seriellen Monitor für Kontrollausgaben öffnen
  Serial.begin(57600);
  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("/level", melde_level);
  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() {
  // 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(!deltaLevel == 0 && abs(level - levelCCU) >= deltaLevel) {
    Serial.print(zeitstempel() + "  Levelaenderung: "); 
    melde_CCU();
  }
}
Gruß Axel

AFi
Beiträge: 166
Registriert: 14.12.2016, 20:44

Re: Steuerung Pumpenvorlage mittels Füllstandskontrolle

Beitrag von AFi » 09.07.2017, 19:29

Hi,

habs!

Das Programm oben gepostet, baut den gesamten Funkverkehr bis zur CCU2 auf.
In der CCU2 muss eine Systemvariable erstellt werden, das Wichtige daran ist, den gleichen Variablennamen zu
verwenden "P_002LevelTonne" wie im Programm auf dem Arduino.
konfig.JPG
Anbei Konfiguration:
skript.JPG
Anbei Werteausgabe:
Anzeige.JPG
So hoffe ich habe jetzt alles richtig, dann geht es mit der Anbindung des Füllstandssensor und Elektronik weiter und zum Schluss die Technik der Einbindung des Sensors an die Tonne (ohne Wasserberührung).

Gruß Axel

Familienvater
Beiträge: 7151
Registriert: 31.12.2006, 15:18
System: Alternative CCU (auf Basis OCCU)
Wohnort: Rhein-Main
Danksagung erhalten: 34 Mal

Re: Steuerung Pumpenvorlage mittels Füllstandskontrolle

Beitrag von Familienvater » 09.07.2017, 19:58

Hi,

nein, DU hast es leider nicht ganz begriffen. Was nützt es Dir, wenn bei deinem "Nachbarn" (WebUI) die Events eintreffen?
Nichts! Entweder Du rennst dauernd zu Deinem Nachbarn, klingelst, und fragst ganz Freundlich: Ist meine Tonne voll? Machst Du das 1x im Jahr, denkt sich Dein Nachbar, wahrscheinlich hat er gerade Burn-Out... Machst Du das alle 10 Sekunden, öffnet der nach 1h nicht mehr, und zieht um.

Der Wemos muss die Meldung direkt in HPCL einliefern! Alles andere hat keinen Sinn! Anstatt also an eriwan.exe zu funken, einfach an das CLWebI.ccc funken!

Dein WebUI-Programm stellt nur die Systemvariable zurück, und sorgt im schlimmsten Fall für eine Endlos-Schleife in der WebUI, weil es auf jeden Wert zischen 0 und 1100 triggert, und stellst es auf 0 zurück, was ggf. das Programm neu triggert! (Wenn die WebUI logisch und einfach wäre, bräuchten wir kein HPCL!)

Der Familienvater

AFi
Beiträge: 166
Registriert: 14.12.2016, 20:44

Re: Steuerung Pumpenvorlage mittels Füllstandskontrolle

Beitrag von AFi » 09.07.2017, 21:12

Hi Familienvater,

habe nie behauptet, dass ich alles verstehe. Das Script in der WebUI habe ich um die Aktivität beraubt, bei näherem hinsehen wurde mir klar, dass es unnötig ist. Der Code für den Arduino stammt nicht von mir (ist eigentlich deutlich zu sehen), ich habe nur versucht in anzupassen (erste Berührung mit C), ich glaube m.yoda hat sich dabei etwas gedacht.

Es ist mir klar, der direkte Weg ist meistens der Beste, leider fehlt mir dazu die Erfahrung den Code von yoda umzuschreiben.
Sorry habe Deine letzten Ansätze nicht verstanden (liegt hoffentlich nur an meiner fehlenden Erfahrung in c)

Gruß Axel

Familienvater
Beiträge: 7151
Registriert: 31.12.2006, 15:18
System: Alternative CCU (auf Basis OCCU)
Wohnort: Rhein-Main
Danksagung erhalten: 34 Mal

Re: Steuerung Pumpenvorlage mittels Füllstandskontrolle

Beitrag von Familienvater » 09.07.2017, 23:17

Hi,

es hat mit C nichts zu tun, der grundlegende Gedankengang fehlt noch bei Dir... Der Code-Block mit der eriwan.exe setzt eine Systemvariable (das was durch den Code passiert ist nichts anderes, als wenn Du im Browser auf Deinem Computer genau diese URL mit den Parametern aufrufst, oder in HPCL ein SetCCUSysvar auf diese Systemvariable absetzt).
Das setzen der Systemvariable in der WebUI bringt Dir aber theortisch nichts für HPCL, weil HPCL bekommt das nicht mit, HPCL kann nur den Inhalt der Systemvariable per Abfrage (GetCCUSysvar) feststellen. Wenn HPCL aber alle 10 Sekunden den Wert der Sysvar abholt, geht HPCL in die Knie. Man könnte jetzt per virtueller Tasten-Kommunikation und WebUI-Programm (was auf Änderung der Systemvariable triggert), HPCL von der WebUI aus ein Event senden, und HPCL weiß, auf Tastendruck der virtuellen Taste soll es dann die Systemvariable abfragen, aber das ist alles "grütze", Du brauchst den Füllstand ja gar nicht in der WebUI, warum also dort verwalten?
Und Dein WebUI-Programm was Du zusammengeklickt hast, hat halt im Aktionsteil absolut keinen Sinn ergeben.

Man muss den WebRequest im Wemos so ändern, das er ein Objekt in HPCL ändert, direkt. Und das geht in dem man den Request an das CLWebI.ccc "Interface" schickt, das geht grundsätzlich genauso, wie das setzen der Systemvariable, nur die URL ist halt ein bisschen anders, und die Parameter auch.
So wie www.spiegel.de nicht www.focus.de ist, aber beides sind Nachrichtenseiten, und beides kannst Du im Browser eintippen.

Der Familienvater

Antworten

Zurück zu „homeputer CL“