LAN-Anbindung für BSB-Bus (Brötje, Elco Thision etc.)

Begonnen von justme1968, 29 November 2014, 19:50:40

Vorheriges Thema - Nächstes Thema

Bratmaxe

Ich habe ein Homematic-Skript erstellt, welches den gewünschten Parameter ausliest. Zudem erstellt das Skript automatisch eine Systemvariable (Name kann im Skript vorher festgelegt werden).
Ich muss das aber noch erst ausgiebig testen. Ist das hier auch von Interesse, z.B: für's Handbuch?

Gruß Carsten

Schotty

Hi Carsten,
danke fürs Angebot - prinzipiell immer gerne, allerdings habe ich schon ein Beispiel für die HomeMatic-Einbindung (eQ3) drin. Inwiefern weicht deines davon ab oder ergänzt es?
Gruß
Handbuch zur BSB-LAN Hard- & Software (Anbindung v. Heizungsreglern, u.a. von Brötje & Elco):
https://1coderookie.github.io/BSB-LPB-LAN/

Schotty

Nachtrag: Können wir aber dann auch lieber via PN oder (noch besser) email besprechen und klären - das wird hier sonst zu sehr OT.. ;)
Handbuch zur BSB-LAN Hard- & Software (Anbindung v. Heizungsreglern, u.a. von Brötje & Elco):
https://1coderookie.github.io/BSB-LPB-LAN/

freetz

Also wenn es fertig ist, dann gerne hier (mit etwas Erläuterung dazu) einstellen!
Alle Infos zur Anbindung von Heizungssystemen mit PPS-, LPB- bzw. BSB-Bus ans LAN gibt es hier:
https://github.com/fredlcore/bsb_lan

Alle Infos zum WLAN-Interface "Robotan" für Ambrogio/Stiga/Wolf und baugleiche Rasenmähroboter:
https://github.com/fredlcore/robotan

Bratmaxe

Alles klar, ich werde das erstmal ausgiebig testen, wenn es dann funktioniert, werde ich es euch einfach zur Verfügung stellen, was ihr dann damit macht überlasse ich dann euch  ;)

Gruß Carsten

Andreas29

#2450
Hallo Freunde und Nutzer des BSB_LAN-Adapters,

ich habe nun eine An- und Einbindung von MAX!-Thermostaten an BSB_LAN ohne FHEM am laufen.
Das bedeutet:

Es werden die Soll/Isttemperaturen von (sinnvollerweise, weil diese alle ca. 30 Sekunden edit: 3 Minuten (nachgemessen  :) ) zyklisch ohne weiteres Dazutun die Soll/Istwertinfos senden) Wandthermostaten ausgewertet. Daraus erfolgt eine Soll- und Istwertberechnung und die entsprechenden Temperaturen werden an die Therme gesendet.
Als Sollwert wird der Parameter 710 Komfortsollwert HK1 vorgegeben und als Raumistwert der Parameter 10000-Raumtemperatur HK1 an die Therme gesendet.
Werden aufgrund von Ausfall etc. unplausible Werte ermittelt oder werden Werte ausserhalb festlegbarer Grenzen ermittelt erfolgt keine Weiterleitung an die Therme.
Stattdessen wird ein festlegbarer Soll"not"wert an die Therme gesendet. Gleichzeitig wird als Fehlermerker der Parameter 1010 (Sollwert Heizkreis 2) auf 23 Grad gesetzt (ich habe keinen Heizkreis 2 und diese Änderung bewirkt nix an der Therme) und die Power-LED am Cube wird auf blinken geschaltet (Normalbetrieb dauernd ein).
Diesen Fehlermerker werte ich mit meinem Arduino Raumgerät "light" aus.
Ist der gesetzt erscheint im Display die Fehlermeldung "MAX!-Fehler" und der Raumistwert wird vom Sensor des Arduino-Raumgerätes an die Therme gesendet.
Das Arduino-Raumgerät ist dann die Fallback-Lösung falls die MAX!-Komponenten nicht mehr wollen oder können.

Wie man MAX!-Komponenten an BSB_LAN bekommt ist im Handbuch gut dokumentiert. Man braucht halt einen umgeflashten Cube (Parallelbetrieb mit original Cube ist möglich).

Die eigentliche Auswertelogik zur Ermittlung der Soll/Ist-Temperatur aus den Temperaturinfos der Thermostate ist von freetz hier https://forum.fhem.de/index.php/topic,60900.0.html beschrieben. Genauso erfolgt im beigefügten Code die Auswertung und Ermittlung Soll/Ist-Temperatur auch.

Ich habe es mir bei der Erstellung des ArduinoCodes ein bisschen leichter gemacht und eine zusätzliche Library "Array.h" eingebunden, damit wird die Array-Auswertung in C++ (Arduinosprache) ein bisschen einfacher.
Die Einbindung und Quelle Ist in der Kommentierung (in der Kommentierung in der custom.h) erläutert.
Ebenfalls ist am Anfang des Codes in der custom.h die Anzahl der in der config.h definierten (und mit BSB_LAN verbundenen) MAX!-Komponenten einzutragen.
Die Arraydefinition in BSB_LAN lässt derzeit maximal 20 MAX!-Komponenten zu. 
Im Bereich der Variablendefinition werden nach persönlichem Gusto ggf. die Grenzwerte angepasst.

Beim Programm für das Raumgerät sind die IP-Adressen im sketch anzupassen.

Die Zeiten und Temperaturen sind nun in den Programmen der Thermostate vorgegeben.

Das ist ok, nur morgens etwas unkomfortabel, weil diese Zeiten halt Schaltzeiten und keine Zielzeiten (dann soll es xx-Grad warm sein) sind.
Meine Therme könnte automatisch unter Berücksichtigung eines Aufheizgradienten die Schaltzeit vorverlegen um dann zielgenau die Räume warm zu haben.
Das können die Thermostate so nicht.
Aber wenn man nun folgendes macht:
Die Therme z.B. von 0:00Uhr bis 05:30 in Absenkbetrieb, gleichzeitig kann man unter Parameter 790 die maximale Vorverlegungszeit auf z.B. 1 Stunde stellen.
Die Thermostaten werden dann so gestellt, dass sie ab 04:30 an sein sollten.
So wird dann an die Therme bereits ein entsprechender KomfortSollwert gesendet (aber da sie noch im Absenkmodus ist, wird dieser nicht sofort umgesetzt) aufgrund dem die Therme dann passend rechnet und zu passendem Zeitpunkt anfängt zu heizen, so dass die Räume morgens zur Zielzeit warm sind. 
Das klappt ganz gut bisher.

Anbei der Code für die custom.h BSB_LAN sowie für ein Arduino-Raumgerät"light" in der oben beschriebenen Variante.

Wie gehabt ist der Adapter über das heimische Netzwerk oder von ausserhalb über z.B VPN zu erreichen.
Benutzt man zusätzlich noch einen originalen Cube kann man über den zusammen mit der entsprechenden Software ebenfalls im Heimnetzwerk zugreifen.
Mit MAX!-Remote als APP braucht man auch keinen Zugang über ein Portal, es bleibt komplett ohne Portallösung wenn man Portallösungen nicht mag  :D

Also, der Adapter kann eine ganze Menge. Traut Euch! ;) :D

Viele Grüße

Andreas

Schotty

Handbuch zur BSB-LAN Hard- & Software (Anbindung v. Heizungsreglern, u.a. von Brötje & Elco):
https://1coderookie.github.io/BSB-LPB-LAN/

Bratmaxe

Ich hätte da nochmal eine Frage..

Ich habe nun ein paar Parameter versucht zu beschreiben, erhalte aber immer die Rückmeldung
Fehlermeldung: FEHLER: Setzen fehlgeschlagen! - Parameter ist nur lesbar

getestet habe ich
Parameter 700 - Betriebsart und
Parameter 1610 - Trinkwasser Nennsollwert

Muss ich noch irgendwo was umstellen/aktivieren, das das klappt? Habe ich irgendwas wichtiges vergessen/überlesen?
Oder hat es evtl doch etwas mit den vorderen Serviceanschlüssen an der ISR-Plus Panel zu tun?? (Stecker ist bestellt, werden also bald an den "richtigen" Port gehen..)

Ob das umschalten über die WEB Oberfläche geht kann ich gerade nicht testen, bin nicht zuhause. Der Parameter 700 ist aber definitiv grau hinterlegt und ich kann hier zwischen den Modi 0-3 wählen... (ob es umgeschaltet wird müsste ich aber noch verifizieren)

Gruß Carsten

Schotty

#2453
Moin Carsten,
also an dem Anschluss an der Vorderseite liegt es nicht, das hat damit nichts zu tun. Busanschluß ist Busanschluß. Anschluß ohne den richtigen Stecker geht übrigens auch - mit Kabelschuhen, s. Handbuch. ;)

Vermutlich hast du die Parameter (einzeln oder generell alle) noch nicht schreibbar gemacht? Siehe Handbuch - insb. Kap. 5, vorletzter Punkt auf S.26.
Gruß
Handbuch zur BSB-LAN Hard- & Software (Anbindung v. Heizungsreglern, u.a. von Brötje & Elco):
https://1coderookie.github.io/BSB-LPB-LAN/

Schotty

Deine Frage findet sich im Prinzip übrigens auch hier im Handbuch (Kap. 14: Etwaige Probleme und deren mögliche Ursachen):
Zitat
14.10 Einstellungen des Reglers können nicht via Adapter verändert werden
- Zugriff des Adapters ist auf Lesen beschränkt (,, FL_RONLY ")
;)
Handbuch zur BSB-LAN Hard- & Software (Anbindung v. Heizungsreglern, u.a. von Brötje & Elco):
https://1coderookie.github.io/BSB-LPB-LAN/

Bratmaxe

Schande über mein Haupt.. Sorry ja ich habe es mir sogar in meinem Ausdruck "angemarkert" und habe es dennoch übersehen beim Konfigurieren..

Werde ich heute Abend nachholen, danke für Tritt in den Hintern! ::)

Schotty

Kein Problem, kann ja mal passieren. Wenn du es in der config.h entspr. änderst, dann das erneute Flashen des Arduino nicht vergessen.. ;)
Handbuch zur BSB-LAN Hard- & Software (Anbindung v. Heizungsreglern, u.a. von Brötje & Elco):
https://1coderookie.github.io/BSB-LPB-LAN/

Scherheinz

ZitatEs werden die Soll/Isttemperaturen von (sinnvollerweise, weil diese alle ca. 30 Sekunden die Soll/Istwertinfos senden)

Alle 30 Sekunden? Bei mir sendet das Wandthermostat alle 3min, was meiner Ansicht auch völlig reicht und auch den Funkverkehr deutlich kleiner ausfallen lässt. Kann man das Einstellen an den Thermostaten?

Gruß

Bratmaxe

#2458
So hier könnt ihr euch das Skript ja mal ansehen. Ich habe jetzt viele Parameter damit ausgelesen und keinen Fehler mehr gefunden.
Dennoch geschieht die Benutzung auf eigene Gefahr, ich kann nicht ausschließen, das irgendwo noch der Fehlerteufel zuschlägt.

Ich übernehme keinerlei Haftung für die Verwendung des Skriptes!

Kurze Beschreibung:
Es müssen lediglich 6 Parameter eingegeben werden.
CuxGeraetAbfrage = GeräteAdresse des CuxD Execute Gerätes, welches die Abfragen ausführt
CuxGeraetLogging = GeräteAdresse des CuxD Execute Gerätes, welches das Logging ausführt (leer==deaktiviert)
IPAdresseBSB = IP-Adresse des BSB-Adapters
Wort = Parameternummer: Beispiel Außentemperatur = 8700 oder Betriebsmodus = 700
Variablename = Name der Systemvariable in der CCU
Durchschnitt24h = true == Durchschnittswert 24h holen, false == aktuellen Wert holen

Es muss keine Variable vorher angelegt werden, das erledigt das Skript.
Der Variabeltyp (Zahl, Bool, Werteliste) wird automatisch an den abgefragten Parameter angepasst.

! BSB-Adapter Wert abfragen by Bratmaxe
! 29.10.2018 - V0.1 - Erste Version
! 11.11.2019 - V0.2 - Auslesen von Temperatursensoren hinzugefügt
! 15.11.2019 - V0.3 - Änderung der Ausleseart der Temperatursensoren mithilfe der ID

string CuxGeraetAbfrage = "CUX2801001:11"; ! GeräteAdresse des CuxD Execute Gerätes, welches die Abfragen ausführt
string CuxGeraetLogging = "CUX2801001:10"; ! GeräteAdresse des CuxD Execute Gerätes, welches das Logging ausführt, Leer ("") lassen, wenn kein Cuxd-Highcharts Logging gewünscht
string IPAdresseBSB = "192.168.178.88"; !IP_Adresse des BSB-Adapters
string Wort = "T"; !Parameternummer: Beispiel Außentemperatur = 8700, Betriebsmodus = 700, eigene Temperatursensoren = T
string TemperatursensorID = "28aa44085414010b"; !Wenn Wort = "T", dann hier die ID des auszulesenden Temperatursensors eingeben, wird sonst ignoriert!
string Variablename = "Wetter_Temperatur"; ! Name der Systemvariable
boolean Durchschnitt24h = false; ! true = Durchschnittswert holen, false = aktuellen Wert holen - diese muss vorher in der BSB_lan_config.h konfiguriert wurden sein!!! (Bei Wort = T wird dieser Parameter ignoriert)

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!Ab hier keine Anpassungen mehr notwendig!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

! URL Zusammenführen
string url="";
if (Durchschnitt24h && Wort != "T")
{
url="http://" # IPAdresseBSB # "/A" # Wort;
}
else
{
url="http://" # IPAdresseBSB # "/" # Wort;
}

! Variable anlegen, wenn nicht vorhanden:
object svObject = dom.GetObject(Variablename);
object svObjectlist = dom.GetObject(ID_SYSTEM_VARIABLES);
if (!svObject)
{
    svObject = dom.CreateObject(OT_VARDP);
    svObjectlist.Add(svObject.ID());
svObjectlist = dom.GetObject(ID_SYSTEM_VARIABLES);
    svObject.Name(Variablename);   
    svObject.Internal(false);
    svObject.Visible(true);
}

! Werte holen
dom.GetObject("CUxD." # CuxGeraetAbfrage # ".CMD_SETS").State("wget --tries=5 --timeout=20 --quiet --output-document=- '"# url #"'"); 
dom.GetObject("CUxD." # CuxGeraetAbfrage # ".CMD_QUERY_RET").State(1);
var stdout = dom.GetObject("CUxD." # CuxGeraetAbfrage # ".CMD_RETS").State();

! Prüfe, ob eine Ausgabe vorhanden ist, sonst z.B. IP-Adresse falsch, oder Netzwerkfehler
if (stdout != null && stdout != "")
{
integer pos = (stdout.Find(Wort# " "));

! Ausgabe filtern
if (Wort == "T")
{
pos = (stdout.Find(TemperatursensorID # ": "));
}

if (pos == -1)
{
WriteLine("Position vom Wort '" # Wort # "' konnte nicht ermittelt werden");
}

stdout = stdout.Substr(pos, stdout.Length());
pos = stdout.Find("/td");
stdout = stdout.Substr(0, pos);

! Sonderzeichen ersetzen
if (stdout.Contains("°")){ stdout = stdout.Replace("°","°"); } !& d e g ; ohne Leerzeichen
if (stdout.Contains("%")){ stdout = stdout.Replace("%","%"); } !& # 0 3 7 ; ohne Leerzeichen
!WriteLine("Nach Sonderzeichenumwandlung: " # stdout); !Debug: Welchen Wert hat stdout aktuell

! Systemvariabel Info ermitteln
string Info = "";
if (Wort == "T")
{
Info = "SensorID: " + TemperatursensorID;
}
else
{
Info = stdout.Substr(0,stdout.Find(":"));
}
!Info = Info.Substr(Wort.Length(), stdout.Length());
!WriteLine("DPInfo = " # Info); !Debug: Welcher DPInfo-Wert wurde gefunden

! Systemvariabel Wert ermitteln
string Wert = stdout.Substr(stdout.Find(": ") + 2,stdout.Length());
Wert = Wert.Substr(0,Wert.Find(" "));
!WriteLine("Wert = " # Wert); !Debug: Welcher Wert wurde gefunden

! Systemvariabel Einheit ermitteln
string Einheit = stdout.Substr(stdout.Find(Info) + Info.Length() + 1, stdout.Length());
Einheit = Einheit.Substr(Einheit.Find(Wert) + Wert.Length() + 1,Einheit.Length());
Einheit = Einheit.RTrim();
if (Einheit.Contains("- ")) { Einheit = ""; }
!WriteLine("Einheit = " # Einheit); !Debug: Welche Einheit wurde gefunden

! Systemvariable Typ und Werte setzen
svObject.DPInfo(Info);
svObject.ValueUnit(Einheit);

! Enums des Parameters ermitteln, wenn vorhanden
url="http://" # IPAdresseBSB # "/E" # Wort;

dom.GetObject("CUxD." # CuxGeraetAbfrage # ".CMD_SETS").State("wget --tries=5 --timeout=20 --quiet --output-document=- '"# url #"'"); 
dom.GetObject("CUxD." # CuxGeraetAbfrage # ".CMD_QUERY_RET").State(1);
stdout = dom.GetObject("CUxD." # CuxGeraetAbfrage # ".CMD_RETS").State();
! Prüfe, ob es sich um einen Parameter mit Enum-Werten handelt.
if (!stdout.Contains("FEHLER: Falscher Typ!"))
{
! Setzen des Systemvariabel Wertetyp und Ermitteln der Enum-Werte des Parameters
stdout = (stdout.Substr(stdout.Find("0 - "), stdout.Length())).ToLatin();
string value = "";
string newvalues = "";
integer inewvalues=0;
foreach (value, stdout.Split("\r"))
{
if (value.Contains(" - "))
{
if (newvalues == "") { newvalues = newvalues # value.Substr(value.Find(" - ") + 3,value.Length()); }
else { newvalues = newvalues # ";" # value.Substr(value.Find(" - ") + 3,value.Length()); }
inewvalues = inewvalues + 1;
}
}

svObject.ValueType(ivtInteger);
svObject.ValueSubType(istEnum);
svObject.ValueList(newvalues);
!prüft, ob der ermittelte Wert innerhalbe der möglichen Werte liegt
if (Wert < inewvalues) { if (Wert != svObject.Value()) { if (Wert != "") { svObject.State(Wert); }} }
else { WriteLine("Der ermittelte Wert entspricht keinem gültigen Enum-Wert. Bitte Ausgabe prüfen!") }
}
elseif (Einheit.Contains("- Aus") || Einheit.Contains("- Ein"))
{
! Setzen des Systemvariabel Wertetyp
svObject.ValueType(ivtBinary);
svObject.ValueSubType(istBool);
svObject.ValueName0("Aus");
svObject.ValueName1("Ein");
if (Wert != svObject.Value()) { if (Wert != "") { svObject.State(Wert); } }
}
elseif (Einheit.Contains("°"))
{
! Setzen des Systemvariabel Wertetyp
svObject.ValueType(ivtFloat);
svObject.ValueSubType(istGeneric);
svObject.ValueMin(-50);
svObject.ValueMax(100);
if (Wert != svObject.Value()) { if (Wert != "") { svObject.State(Wert); } }
}
elseif (Einheit.Contains("%"))
{
! Setzen des Systemvariabel Wertetyp
svObject.ValueType(ivtFloat);
svObject.ValueSubType(istGeneric);
svObject.ValueMin(0);
svObject.ValueMax(100);
if (Wert != svObject.Value()) { if (Wert != "") { svObject.State(Wert); } }
}
else
{
! Setzen des Systemvariabel Wertetyp
svObject.ValueType(ivtFloat);
svObject.ValueSubType(istGeneric);
if (Wert != svObject.Value()) { if (Wert != "") { svObject.State(Wert); } }
}
dom.RTUpdate(0); ! Interne Aktualisierung der Systemvariabelen

! Logging
if (CuxGeraetLogging != "") { dom.GetObject("CUxD."#CuxGeraetLogging#".LOGIT").State(dom.GetObject(ID_SYSTEM_VARIABLES).Get(Variablename).Name()#";"#dom.GetObject(ID_SYSTEM_VARIABLES).Get(Variablename).Value()); }
}



Die Parameterzahl in der Beschreibung der Systemvariable kann man entfernen, wenn man Zeile 59
!Info = Info.Substr(Wort.Length(), stdout.Length());
einkommentiert, ich habe mich aber absichtlich für den Wert mit Parameternummer entschieden, da ich dann mit einem weiteren Skript den Parameter automatisch aus der Info auslesen und über BSB-Adapter setzen kann. (Skript muss ich aber noch erstellen)

Edit 31.10.2018: Skript zum Setzen der Parameter hinzugefügt:
Kurzbeschreibung:
Ein Programm, wo alle Systemvariabeln die überwacht werden sollen mit ODER Verknüpft und größer oder gleich 0 und  "bei Aktualisierung auslösen" , anlegen.
Beispiel:
WENN Variablename größer oder gleich 0 "bei Aktualisierung auslösen"
DANN Dieses SKRIPT sofort ausführen

die Variable muss in der Info zuerst den ParameterWert enthalten (wird von meinem Auslese Skript automatisch so benannt. Beispiel: 700 Heizkreis 1 - Betriebsart
Die Parameternummer wird dann automatisch aus der Systemvariable Info ermittelt.
Wird die Variable geändert, so wird der geänderte Wert automatisch an den BSB-Adapter übermittelt und aktualisiert!

! BSB-Adapter Wert setzen by Bratmaxe
! 29.10.2018 - V0.1 - Erste Version

! Funktionsbeschreibung:
! Ein Programm, wo alle Systemvariabeln die Überwacht werden sollen mit ODER Verknüpft und größer oder gleich 0 und  "bei Aktualisierung auslösen" , anlegen.
! Beispiel:
! WENN Variablename größer oder gleich 0 "bei Aktualisierung auslösen"
! DANN Dieses SKRIPT sofort ausführen
! die Variable muss in der Info zuerst den Parameter-Wert enthalten (wird von meinem Auslese Skript automatisch so benannt. Beispiel: 700 Heizkreis 1 - Betriebsart
! Die Parameternummer wird dann automatisch aus der Systemvariable Info ermittelt.
! Wird die Variable geändert, so wird der geänderte Wert automatisch an den BSB-Adapter übermittelt und aktualisiert!

string CuxGeraetSetzen = "CUX2801001:12"; ! GeräteAdresse des CuxD Execute Gerätes
string IPAdresseBSB = "192.168.2.200"; !IP_Adresse des BSB-Adapters

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!Ab hier keine Anpassungen mehr notwendig!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

! Hole Auslösende Variabel
var source = dom.GetObject("$src$"); !Funktioniert nur beim automatischen Aufruf
! Zum manuellen Aufruf/testen nächste Zeile einkommentieren
!source = dom.GetObject(ID_SYSTEM_VARIABLES).Get("VARIABLENAMEN");

if (source)
{
! Wort ermitteln
string Wort = source.DPInfo().ToString().Substr(0,source.DPInfo().Find(" "));
!WriteLine("Wort: "#Wort);
if (Wort != null && Wort != "")
{
string Wert = source.Value().ToString();
!WriteLine("Wert: "#Wert);
if (Wert != null && Wert != "")
{
! Anweisung senden
string urlset="http://" # IPAdresseBSB # "/S" # Wort # "=" # Wert;
dom.GetObject("CUxD." # CuxGeraetSetzen # ".CMD_SETS").State("wget -t 5 -T 20 -q -O - '"# urlset #"'");
dom.GetObject("CUxD." # CuxGeraetSetzen # ".CMD_QUERY_RET").State(1);
var stdout = dom.GetObject("CUxD." # CuxGeraetSetzen # ".CMD_RETS").State();
if (stdout != null && stdout != "")
{
if (stdout.Contains("FEHLER: "))
{
stdout = stdout.Substr(stdout.Find("FEHLER: "), stdout.Length());
stdout = stdout.Substr(0, stdout.Find("/td"));
WriteLine("Fehlermeldung: "# stdout);
WriteLine("Wurde der BSB-Adapter zum Schreiben berechtigt? Handbuch Seite 26 beachten...");
}
else
{
! Kontrollabfrage
string url="http://" # IPAdresseBSB # "/" # Wort;
dom.GetObject("CUxD." # CuxGeraetSetzen # ".CMD_SETS").State("wget -t 5 -T 20 -q -O - '"# url #"'");
dom.GetObject("CUxD." # CuxGeraetSetzen # ".CMD_QUERY_RET").State(1);
stdout = dom.GetObject("CUxD." # CuxGeraetSetzen # ".CMD_RETS").State();

! Ausgabe filtern
integer pos = (stdout.Find("tr  td \r\n" # Wort # " ") + 9);
stdout = stdout.Substr(pos, stdout.Length());
pos = stdout.Find("/td");
stdout = stdout.Substr(0, pos);

! Sonderzeichen ersetzen
if (stdout.Contains("&deg;")){ stdout = stdout.Replace("&deg;","°"); }
if (stdout.Contains("%")){ stdout = stdout.Replace("%","%"); }
!WriteLine("Nach Sonderzeichenumwandlung: " # stdout); !Debug: Welchen Wert hat stdout aktuell

! Systemvariabel oldWert ermitteln
string oldWert = stdout.Substr(stdout.Find(": ") + 2,stdout.Length());
oldWert = oldWert.Substr(0,oldWert.Find(" "));
!WriteLine("oldWert = " # oldWert.ToFloat()); !Debug: Welcher oldWert wurde gefunden
!WriteLine("newWert = " # Wert.ToFloat()); !Debug: Welcher oldWert wurde gefunden

if (Wert.ToFloat() != oldWert.ToFloat()) { WriteLine("Fehler: Werte stimmen nach setzen nicht überein!"); }
else { WriteLine("Wert wurde erfolgreich gesetzt"); }
}
}
else { WriteLine("Keine Ausgabe gefunden. IP-Adresse und Verkabelung prüfen."); }
}
else { WriteLine("Der neue Wert konnte nicht ermittelt werden."); }
}
else { WriteLine("Wort konnte nicht ermittelt werden, Steht der Wert in der SystemvariableInfo am Anfang gefolgt von einem Leerzeichen?"); }
}
else { WriteLine("Auslösende Variable nicht erkannt! - Skript wird nicht ausgeführt."); }



Edit: 05.11.2018:
Für die Abfrage der Fehlercodes habe ich noch ein weiteres Skript verfasst, da hier mehrere Wörter abgefragt werden müssen, damit der Fehler eindeutig mit Datum abgefragt wird.
mit "AnzahlFehler" kann man einstellen, wie viele Fehler abgefragt werden sollen Meine Heizung mit ISR-Plus speichert bis zu 20 Fehler ab.
Ich lasse das Skript alle paar Stunden laufen und lasse mich dann benachrichtigen, wenn die Variable sich ändert, somit erhalte ich innerhalb kurzer Zeit die Info, wenn an der Heizung was nicht stimmt!

! BSB-Adapter Wert abfragen Fehlercodes by Bratmaxe
! 05.11.2018 - V0.1 - Erste Version

string CuxGeraetAbfrage = "CUX2801001:1"; ! GeräteAdresse des CuxD Execute Gerätes, welches die Abfragen ausführt
string IPAdresseBSB = "192.168.178.100"; !IP_Adresse des BSB-Adapters
string Variablename = "Heizung_Fehlercodes"; ! Name der Systemvariable
integer AnzahlFehler = 10;

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!Ab hier keine Anpassungen mehr notwendig!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

! Parameter Zusammenbauen
integer i =0;
string Woerter ="";
while (i < AnzahlFehler)
{
if (Woerter != "")
{
Woerter = Woerter + "," + ((6801) + (10 * i)).ToString();
}
else { Woerter = Woerter + ((6801) + (10 * i)).ToString(); }
i = i + 1;
}

! URL Zusammenführen
string Ergebnis = "";
string Wort = "";

foreach(Wort, Woerter.Split(","))
{
string url="http://" # IPAdresseBSB # "/" # ((Wort.ToInteger() - 1).ToString());

! Werte holen
dom.GetObject("CUxD." # CuxGeraetAbfrage # ".CMD_SETS").State("wget --tries=5 --timeout=20 --quiet --output-document=- '"# url #"'"); 
dom.GetObject("CUxD." # CuxGeraetAbfrage # ".CMD_QUERY_RET").State(1);
var stdout = dom.GetObject("CUxD." # CuxGeraetAbfrage # ".CMD_RETS").State();

! Prüfe, ob eine Ausgabe vorhanden ist, sonst z.B. IP-Adresse falsch, oder Netzwerkfehler
if (stdout != null && stdout != "")
{
! Ausgabe filtern
integer pos = (stdout.Find((Wort.ToInteger() - 1).ToString() #  " "));
stdout = stdout.Substr(pos, stdout.Length());
pos = stdout.Find("/td");
stdout = stdout.Substr(0, pos);

! Sonderzeichen ersetzen
if (stdout.Contains("°")){ stdout = stdout.Replace("°","°"); }
if (stdout.Contains("%")){ stdout = stdout.Replace("%","%"); }
stdout = stdout.ToLatin();
Ergebnis = Ergebnis # stdout.RTrim() # "\n\r";
}

url="http://" # IPAdresseBSB # "/" # Wort;
dom.GetObject("CUxD." # CuxGeraetAbfrage # ".CMD_SETS").State("wget --tries=5 --timeout=20 --quiet --output-document=- '"# url #"'"); 
dom.GetObject("CUxD." # CuxGeraetAbfrage # ".CMD_QUERY_RET").State(1);
stdout = dom.GetObject("CUxD." # CuxGeraetAbfrage # ".CMD_RETS").State();

! Prüfe, ob eine Ausgabe vorhanden ist, sonst z.B. IP-Adresse falsch, oder Netzwerkfehler
if (stdout != null && stdout != "")
{
! Ausgabe filtern
integer pos = (stdout.Find(Wort# " "));
stdout = stdout.Substr(pos, stdout.Length());
pos = stdout.Find("/td");
stdout = stdout.Substr(0, pos);

! Sonderzeichen ersetzen
if (stdout.Contains("°")){ stdout = stdout.Replace("°","°"); }
if (stdout.Contains("%")){ stdout = stdout.Replace("%","%"); }
stdout = stdout.ToLatin();
Ergebnis = Ergebnis # stdout.RTrim() # "\n\r\n\r";
}
}

!Wenn noch keine Systemvarible vorhanden, diese anlegen
object svObject = dom.GetObject(Variablename);
object svObjectlist = dom.GetObject(ID_SYSTEM_VARIABLES);
if (!svObject)
{   
    svObjectlist = dom.GetObject(ID_SYSTEM_VARIABLES);
    svObject = dom.CreateObject(OT_VARDP);
    svObjectlist.Add(svObject.ID());
    svObject.Name(Variablename);   
    svObject.ValueType(ivtString);
    svObject.ValueSubType(istChar8859);
    svObject.DPInfo("Die letzen 20 Fehlercodes der Heizung");
    svObject.Internal(false);
    svObject.Visible(true);
    dom.RTUpdate(0);
}

if (Ergebnis.ToLatin() != svObject.Value().ToLatin()) { svObject.State(Ergebnis); }



Ansonsten wünsche ich viel Spaß beim Ausprobieren. Sollten ihr Fehler finden, gerne direkt per PN an mich!

Edit - 15.11.2019 - Skript aktualisiert

Gruß Carsten

Schotty

Danke, habe den Link zum Beitrag gerade im entsprechenden (Unter-)Kapitel im Handbuch hinzugefügt und hochgeladen.

@Andreas29: Deinen Beiotrag von vorhin bzgl MAX!-Anbindung ohne FHEM ebenfalls.
Handbuch zur BSB-LAN Hard- & Software (Anbindung v. Heizungsreglern, u.a. von Brötje & Elco):
https://1coderookie.github.io/BSB-LPB-LAN/