Loxone Integration Energieoptimierung
Auch wenn die Intelligenz des beschriebenen Systems nicht über die Loxone Heimautomatisierung bereitgestellt wird, so stellen die Loxone Komponenten doch das zentrale Element in der Energieoptimierung. Folgende Aufgaben müssen durch unsere Loxone bewerkstelligt werden:
- Integration Awattar API
- Integration Wetterservice (bei Bedarf)
- Integration Optimization Web API
- Steuerung Vaillant Wärmepumpe
- Statiskikaufzeichnung
Wir wollen diese Komplexe nun der Reihe nach beschreiben und vor allem praktische Lösungen präsentieren, um die üblichen Probleme bei der Systemintegration zu lösen.
Integration Awattar API
Um in der Optimierung den Faktor Stromkosten bewerten zu können, habe ich mich entschieden die Ermittlung eben dieser über Loxone durchzuführen, und diese dann an den Optimierungs-Request zu übergeben.
Für die Ermittlung der Stromkosten stellt mein Stromanbieter glücklicherweise eine API zur Verfügung um über einen HTTP Request die Stromkosten für den folgenden Tag abgefragt werden können:
http://api.awattar.at/v1/marketdata/current.yaml?tomorrow=include
Um die Daten über Loxone abzufragen, verwenden wir einen Virtuellen HTTP Eingang und geben für die URL den obigen Link an.

Die Abfrage liefert folglich nachstehendes Ergebnis, bei dem uns die zukünftigen relativen Preise interessieren.
date_now: 2026-01-04 12:41:21
date_now_epoch: 1767526881860
date_now_day: 4
date_now_month: 1
date_now_year: 2026
date_start: 2026-01-04 00:00:00
date_end: 2026-01-04 23:59:59
price_low: 8.25600
price_high: 12.11800
price_median: 9.02100
price_average: 9.57608
price_current: 8.95400
price_unit: Cent/kWh
price_threshold_00: 8.25600
price_threshold_01: 8.34100
price_threshold_02: 8.38900
price_threshold_03: 8.39700
price_threshold_04: 8.50400
price_threshold_05: 8.53300
price_threshold_06: 8.67800
price_threshold_07: 8.68600
price_threshold_08: 8.84600
price_threshold_09: 8.88200
price_threshold_10: 8.92100
price_threshold_11: 8.95400
price_threshold_12: 9.08800
price_threshold_13: 9.31400
price_threshold_14: 9.43000
price_threshold_15: 9.47600
price_threshold_16: 9.55300
price_threshold_17: 10.04300
price_threshold_18: 10.56300
price_threshold_19: 11.24500
price_threshold_20: 11.79400
price_threshold_21: 11.84300
price_threshold_22: 11.97200
price_threshold_23: 12.11800
data_price_hour_rel_-12_amount: 8.88200
data_price_hour_abs_00_amount: 8.88200
data_price_hour_rel_-11_amount: 8.53300
data_price_hour_abs_01_amount: 8.53300
data_price_hour_rel_-10_amount: 8.50400
data_price_hour_abs_02_amount: 8.50400
data_price_hour_rel_-09_amount: 8.38900
data_price_hour_abs_03_amount: 8.38900
data_price_hour_rel_-08_amount: 8.25600
data_price_hour_abs_04_amount: 8.25600
data_price_hour_rel_-07_amount: 8.34100
data_price_hour_abs_05_amount: 8.34100
data_price_hour_rel_-06_amount: 8.39700
data_price_hour_abs_06_amount: 8.39700
data_price_hour_rel_-05_amount: 8.68600
data_price_hour_abs_07_amount: 8.68600
data_price_hour_rel_-04_amount: 8.84600
data_price_hour_abs_08_amount: 8.84600
data_price_hour_rel_-03_amount: 9.43000
data_price_hour_abs_09_amount: 9.43000
data_price_hour_rel_-02_amount: 9.47600
data_price_hour_abs_10_amount: 9.47600
data_price_hour_rel_-01_amount: 9.08800
data_price_hour_abs_11_amount: 9.08800
data_price_hour_rel_+00_amount: 8.95400
data_price_hour_abs_12_amount: 8.95400
data_price_hour_rel_+01_amount: 8.67800
data_price_hour_abs_13_amount: 8.67800
data_price_hour_rel_+02_amount: 9.31400
data_price_hour_abs_14_amount: 9.31400
data_price_hour_rel_+03_amount: 9.55300
data_price_hour_abs_15_amount: 9.55300
data_price_hour_rel_+04_amount: 11.79400
data_price_hour_abs_16_amount: 11.79400
data_price_hour_rel_+05_amount: 11.84300
data_price_hour_abs_17_amount: 11.84300
data_price_hour_rel_+06_amount: 12.11800
data_price_hour_abs_18_amount: 12.11800
data_price_hour_rel_+07_amount: 11.97200
data_price_hour_abs_19_amount: 11.97200
data_price_hour_rel_+08_amount: 11.24500
data_price_hour_abs_20_amount: 11.24500
data_price_hour_rel_+09_amount: 10.04300
data_price_hour_abs_21_amount: 10.04300
data_price_hour_rel_+10_amount: 10.56300
data_price_hour_abs_22_amount: 10.56300
data_price_hour_rel_+11_amount: 8.92100
data_price_hour_abs_23_amount: 8.92100
Zusätzlich bedarf es noch einer Anmerkung zur weiteren Aufbereitung der stündlichen Awattar Strompreise. Zuzüglich zu den von Awattar angegebenen Netto-Strompreisen werden noch weitere Gebühren und Kosten schlagend, womit sind nachstehende Stromkostenstruktur für Endbenutzer ergibt:
Stündliche Preise EPEX Spot ® AT
+ |Betrag Stündliche Preise EPEX Spot ® AT | * 0.03
+ 1,500 Cent/kWh
+ 20% MwSt.
Eine Besonderheit der Awattar API ist, dass die stündlichen Daten täglich jeweils um 14:00 Uhr aktualisiert werden und dann für den Folgetag von 00:00-24:00 zur Verfügung stehen, das bedeuted jedoch auch, dass bis 13:59:59 Uhr stündliche Strompreis Forecasts nur bis 24:00 Uhr des selben Tages verfügbar sind, also zumindest 10 Stunden im vorhinein, was den Optimierungshorizont temporär auf diesen Bereich einschränkt. Diese Einschränkung ist auch in den obigen Response Daten ersichtlich. Dieser Reduzierung wird aber im Optimierungsservice Rechnung getragen, in dem der Horizont mangels Input Daten angepasst wird. Durch stündlichen rollierenden Aufruf der Optimierung, entstehen in der Regel aber dadurch keine gravierenden Einschränkung bzw. Fehler im Ergebnis.
Für den Virtuellen HTTP Eingang müssen nun 24 Befehlskennungen (Virtueller HTTP Eingang Befehl) für die relativen Preise angelegt werden. Als Beispiel für den Strompreis in 4 Stunden verwenden wir den Befehl.
data_price_hour_rel_+04_amount: \v

Die verfügbaren Befehlskennungen sind sehr gut in der Loxone Dokumentation beschrieben:
https://www.loxone.com/dede/kb/befehlserkennung

Somit sind die entscheidenden Strompreisinformation nun in unserer Loxone verfügbar. Wie diese weiterverwendet werden, wird an späterer Stelle beschrieben. Um dem Loxone Benutzer auch noch etwas visuelles Feedback zum Strompreis zu geben wird nachstehender Link auf die Awattar Website genutzt:
https://www.awattar.at/services/charts/hourly
Diesen binden wir als Webpage Control in unsere Visualisierung ein.

Aus der Loxone Visualisierung springt man somit auf folgende Seite ab, welche eine recht ansprechende Darstellung der vergangenen und kommenden Tage bietet.

In der Loxone App sieht das nun folgendermaßen aus.

Integration Wetterservice
Da die selbst erstellte Optimization Web API die Möglichkeit bietet, eigenständig Wetterdaten und Vorhersagen abzufragen falls diese nicht über den Request bereitgestellt werden, wird diese Möglichkeit an der Stelle auch genutzt. Insofern besteht keine Notwendigkeit diese Daten über Loxone einzubinden.
Nichts desto trotz mag es für den ein oder anderen von Vorteil sein auch Wetterdaten in der Loxone Visualisierung darzustellen bzw. auch für Berechnungen in Loxone zu verwenden, bietet Loxone auch einen hervorragenden eigenen Wetterservice. Dieser kann natürlich ebenso eingebunden werden, um die entsprechenden Werte in der Folge an die Optimization Web API zu übergeben.
Zur Anzeige aktueller Wetterdaten wird in Loxone lediglich ein Webpage Baustein zum Absprung auf den Link
bereitgestellt.
Integration Optimization Web API
Loxone Script Programming PicoC
Für die Einbindung des Optimierungsservers wird ein Loxone Script Programm verwendet, welches unter „Baustein einfügen“ -> „Allgemein“ zu finden ist. Eine ausführliche Dokumentation der möglichen Befehle ist unter folgendem Link zu finden.
https://updatefiles.loxone.com/KnowledgeBase/Online/Common/Documents/CustomScriptProgramming.pdf
Alles in allem eine sehr mächtige Funktionalität, die viele zusätzliche Türen in der Loxone Config öffnet.

Letztendlich läuft das Programm in einer Endlosschleife, wobei alle 5s die erforderlichen Daten von Loxone Datenpunkten (virtuelle Eingänge, virtuelle HTTP Eingänge, …) gesammelt und in einen Request String zusammengebaut werden (siehe Request Dokumentation https://www.factorysensesoftware.at/energyoptimization/redoc-static.html) Durch einen Stundenimpuls wird ein Trigger Eingang I4 gesetzt, welcher im Programm den Request auf einen Programmausgang legt.

Der Stundenimpuls wird um 65s verzögert, um sicherzustellen, dass andere stündliche Updates von Datenpunkten (z.B. Awattar API Requests) abgeschlossen sind, und der Optimization Web API Request mit aktuellen Daten durchgeführt wird. Um sicherzugehen, dass der Impuls vom Programm aufgefangen wird, sollte die Länge ausreichend gewählt werden, in unserem Fall 10s. Wenn somit der Optimization Request übergeben wird, stellt eine weitere Wartezeit von 15s sicher, dass die Übergabe nur 1 mal durchgeführt wird.
Das vollständige Programm sieht folgendermaßen aus:
char req[2048];
char time[32];
char k[32];
char d[32];
char dt1[32];
char dt2[32];
char t1[32];
char t2[32];
char dem1[128];
char dem2[128];
char min1[128];
char min2[128];
char e[256];
float c[24];
while(true)
{
if(getinput(3)>0)
{
sprintf(time, "\"unixTimestamp\": %d,", getinput(0));
sprintf(k, "\"slopeHeatingCurve\": %f,", getio("VI36"));
sprintf(d, "\"offsetHeatingCurve\": %d,", getio("VI15"));
sprintf(dt1, "\"maxDeltaTemperature1\": %d,", getio("VI18"));
sprintf(dt2, "\"maxDeltaTemperature2\": %d,", getio("VI18"));
sprintf(t1, "\"currentTemperature1\": %f,", round(getinput(1)*10)/10);
sprintf(t2, "\"currentTemperature2\": %f,", round(getinput(2)*10)/10);
sprintf(dem1, "\"demandPowerProfile1\": [ %s ],", getinputtext(0));
sprintf(dem2, "\"demandPowerProfile2\": [ %s ],", getinputtext(1));
sprintf(min1, "\"minTemperatureSetPointsProfile1\": [ %s ],", "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0");
sprintf(min2, "\"minTemperatureSetPointsProfile2\": [ %s ],", getinputtext(2));
c[0]=getio("VCI124");
c[1]=getio("VCI125");
c[2]=getio("VCI126");
c[3]=getio("VCI127");
c[4]=getio("VCI128");
c[5]=getio("VCI129");
c[6]=getio("VCI130");
c[7]=getio("VCI131");
c[8]=getio("VCI132");
c[9]=getio("VCI133");
c[10]=getio("VCI134");
c[11]=getio("VCI135");
c[12]=getio("VCI136");
c[13]=getio("VCI137");
c[14]=getio("VCI138");
c[15]=getio("VCI139");
c[16]=getio("VCI140");
c[17]=getio("VCI141");
c[18]=getio("VCI142");
c[19]=getio("VCI143");
c[20]=getio("VCI144");
c[21]=getio("VCI145");
c[22]=getio("VCI146");
c[23]=getio("VCI147");
sprintf(e, "\"electricityCosts\": [%f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f],",
round((c[0]+fabs(c[0])*0.03+1.5+6.7)*1.2*100)/100,
round((c[1]+fabs(c[1])*0.03+1.5+6.7)*1.2*100)/100,
round((c[2]+fabs(c[2])*0.03+1.5+6.7)*1.2*100)/100,
round((c[3]+fabs(c[3])*0.03+1.5+6.7)*1.2*100)/100,
round((c[4]+fabs(c[4])*0.03+1.5+6.7)*1.2*100)/100,
round((c[5]+fabs(c[5])*0.03+1.5+6.7)*1.2*100)/100,
round((c[6]+fabs(c[6])*0.03+1.5+6.7)*1.2*100)/100,
round((c[7]+fabs(c[7])*0.03+1.5+6.7)*1.2*100)/100,
round((c[8]+fabs(c[8])*0.03+1.5+6.7)*1.2*100)/100,
round((c[9]+fabs(c[9])*0.03+1.5+6.7)*1.2*100)/100,
round((c[10]+fabs(c[10])*0.03+1.5+6.7)*1.2*100)/100,
round((c[11]+fabs(c[11])*0.03+1.5+6.7)*1.2*100)/100,
round((c[12]+fabs(c[12])*0.03+1.5+6.7)*1.2*100)/100,
round((c[13]+fabs(c[13])*0.03+1.5+6.7)*1.2*100)/100,
round((c[14]+fabs(c[14])*0.03+1.5+6.7)*1.2*100)/100,
round((c[15]+fabs(c[15])*0.03+1.5+6.7)*1.2*100)/100,
round((c[16]+fabs(c[16])*0.03+1.5+6.7)*1.2*100)/100,
round((c[17]+fabs(c[17])*0.03+1.5+6.7)*1.2*100)/100,
round((c[18]+fabs(c[18])*0.03+1.5+6.7)*1.2*100)/100,
round((c[19]+fabs(c[19])*0.03+1.5+6.7)*1.2*100)/100,
round((c[20]+fabs(c[20])*0.03+1.5+6.7)*1.2*100)/100,
round((c[21]+fabs(c[21])*0.03+1.5+6.7)*1.2*100)/100,
round((c[22]+fabs(c[22])*0.03+1.5+6.7)*1.2*100)/100,
round((c[23]+fabs(c[23])*0.03+1.5+6.7)*1.2*100)/100);
req = "";
strcat(req, "{");
strcat(req, "\"heatPumpEnvironment\":{");
strcat(req, time);
strcat(req, "\"timeZoneInfoId\": \"W. Europe Standard Time\",");
strcat(req, "\"latitude\": 43.59,");
strcat(req, "\"longitude\": 12.37,");
strcat(req, "\"heatPumpModel\": \"Vaillant_125_6_Linear\",");
strcat(req, "\"ratedPower\": 12,");
strcat(req, "\"minPower\": 2,");
strcat(req, "\"bufferSize1\": 500,");
strcat(req, "\"bufferSize2\": 500,");
strcat(req, "\"bufferHeatDissipation1\": 0.50,");
strcat(req, "\"bufferHeatDissipation2\": 0.25,");
strcat(req, t1);
strcat(req, t2);
strcat(req, dt1);
strcat(req, dt2);
strcat(req, k);
strcat(req, d);
strcat(req, e);
strcat(req, "\"spotPriceRenewalTime\": \"14:00:00\",");
strcat(req, dem1);
strcat(req, dem2);
strcat(req, min1);
strcat(req, min2);
strcat(req, "\"intakeAirTemperatures\": [ ]");
strcat(req, "}");
strcat(req, "}");
setoutputtext(0, req);
sleep(15000);
}
sleep(5000);
}
Wie im Programmlisting erkennbar, wird für die Datenermittlung großteils die getio(string) Funktion genutzt, wobei als Parameter der interne Name eines Virtuellen HTTP Eingangsbefehls gefordert wird. Dieser ist in der Loxone Config über das rechte Maus Kontextmenü des virtuellen Eingangs im Menüeintrag „Eigenschaften bearbeiten“ auffindbar. Dort findet sich die Spalte Anschluss, mit jener Bezeichnung, die als getio-Parameter gefordert wird.

Der Vollständigkeit halber noch eine Warnung: Der Programmbaustein erfordert ausreichend Kenntnisse, da durch fehlerhafte Programmierung der Miniserver crashen kann. Eine Möglichkeit der Wiederherstellung einer fehlerfreien Programmversion kann nicht garantiert werden. Insofern empfiehlt es sich auch ein Backup der SD Karte bereit zu halten, wenn man mit dem Programmbaustein experimentiert.
Loxone HTTP Request senden
Um nun den Request tatsächlich in den Ether zu senden, wird ein Virtueller Ausgang benötigt, dessen Adresse mit der IP-Adresse und Port des Host Rechners der Optimization Web API belegt wird. Das könnte beispielhaft folgendermaßen aussehen: http://64.203.158.23:39764 (IP Adressse und Port aus Sicherheitsgründen geändert).

Maßgeblicher Bedeutung ist dem Virtuellen Ausgangsbefehl zu schenken, welcher unter dem Virtuellen Ausgang angelegt wird. Die entsprechenden Request Parameter korrekt zu setzen, erforderte doch erhebliche Zeit und Dutzende Versuche. Letztendlich führte folgende Konfiguration zum gewünschten Ergebnis:
| Befehl bei ein: | /FactorysenseHeatPumpService/PostOptimization |
| HTTP Header bei ein: | Content-Type: application/json |
| HTTP Body bei ein: | <v> |
| HTTP Methode bei ein: | POST |
| HTTP Antwort speichern: | /user/common/FactorysenseHeatPumpServiceResponse.json |
An und für sich sieht das plausibel aus. Problematisch war vor allem die Erfordernis eines POST Requests anstatt eines GET Requests, um den Body korrekt übergeben zu können. Ein in C# erstellter Client verhält sich hier um einiges verzeihlicher. Letztendlich aber ist die Definition einer POST Methode, wie durch Loxone hier gefordert vollends gerechtfertigt und hier auch korrekt.
Unter Befehl wird der REST Endpoint definiert. Zusätzliche können Header Parameter angegeben werden. Body ist in diesem Fall der am Eingang anliegende Wert, welcher mit dem Ausgang unseres Programmbausteins (Txt1) verbunden wurde und den Request String enthält.

Wichtig an dieser Stelle auch das Verzeichnis am Miniserver, in dem der Response abgelegt wird. Zu Testzwecken kann das File mit Hilfe eines Filezilla FTP Clients downgeloadet werden um den Response zu inspizieren. In der weiteren Ergebnisverarbeitung wird dieses JSON File in der Folge durch Loxone Logik ausgelesen.

Loxone HTTP Response auslesen
Das Auslesen des JSON Responses erfolgt wiederum über einen Virtuellen HTTP Eingang und zugehörigen Virtuellen HTTP Eingang Befehlen (siehe Bild unten) unter Einstellung folgender Parameter:
| Virtueller HTTP Eingang (FactorysenseHeatPumpServiceResponse) | |
| URL: | http://UserName:Password@MiniserverIP:80/dev/fsget/user/ common/FactorysenseHeatPumpServiceResponse.json |
| Virtueller HTTP Eingang Befehlskennung (Einheit <v.1>, Werteinterpretation mit Vorzeichen) | ||
| p1_00 | WP Leistung HZ (Periode 0) | \i“power1″:\i\v |
| p2_00 | WP Leistung WW (Periode 0) | \i“power2″:\i\v |
| t1_01 | Temp. HZ Puffer (Periode 1 Start) | \i“temperature1″:\i\i“temperature1″:\i\v |
| t2_01 | Temp. WW Puffer (Periode 1 Start) | \i“temperature2″:\i\i“temperature1″:\i\v |
| cop1_00 | WP COP HZ (Periode 0) | \i“cop1″:\i\v |
| cop2_00 | WP COP WW (Periode 0) | \i“cop2″:\i\v |
| Status | Status | \i“Status \i\v |
Vor allem die obigen Parameter des Responses sind relevant für die weitere Verarbeitung. Über die Ausgangsleistungen und COP Werte können über einen Formel Baustein die Eingangsleistungen der Wärmepumpe errechnet werden.

Oben ist ersichtlich, dass neben den beschriebenen Befehlskennungen auch noch weitere Variablen zusätzlicher Perioden im Optimierungshorizont ausgelesen werden. Dies dient hauptsächlich der Visualisierung des Optimierungsergebnisses in der Loxonevisualisierung.
Für die Ermittlung der korrekten Befehlskennungen für einen vorgegeben Text ist vor allem der Editor hilfreich, der einerseits den gesamten Response Body im File anzeigt und der gleichzeitig on-the-fly den gefundenen Wert farblich laut Befehlskennung hinterlegt und damit den von Trial and Error geprägten Entwicklungsprozess für Befehlskennungen doch erheblich beschleunigt.

Zusammenfassend zur Integration der Request und Response Strukturen ist zu sagen, dass sich im Laufe des Projekts einige Best Practices etabliert haben:
- Unix Timestamps zur Zeitsynchronisierung (einfache Aufbereitung und Verarbeitung in Loxone)
- Werte Arrays anstatt Object Arrays (ansonsten teilweise kompliziert über Befehlskennungen zu lesen)
- Nutzung Miniserver Gen 2 wenn HTTPS Kommunikation erforderlich (zum Beispiel beim senden von sensiblen Anmelde Daten über den Request)
- Authorisierung bei HTTP Zugriff von Miniserver 1 empfangsseitig über Sender IP Adresse und Firewall möglich
Loxone HTTP Schnittstellen Überwachung mit Mailer
Eine Sache die während des ersten Jahres im Betrieb etwas störend auffiel, war, dass entweder das Programm zum Request-Aufbau oder aber der Virtuelle Ausgangsbefehl für PostOptimization nach einigen Monaten unter Umständen plötzlich den Dienst verweigern kann. Ein simpler Restart des Miniservers, manuell getriggert über die Loxone Mobile App löst das Problem und man kann sich wieder für einige Monate in Sicherheit wiegen. Um jedoch zu verhindern, dass das Heizsystem ohne neue Setpoints auskommen muss und im schlimmsten Fall sogar mit äußerst ungünstigen weil zur niedrigen oder überschießenden Temperaturen und Leistungen arbeitet, sollte derartiges Verhalten zumindest zeitnah identifiziert werden.
Hierfür bietet sich in Loxone der Status Baustein ein, der abhängig vom Status des letzten Optimization Responses, ausgelesen aus dem JSON File, und abhängig von den vergangenen Sekunden seit Erhalt des letzten Responses, den Status der Verbindung zur Optimization Web API ermittelt und visualisiert.
Wenn sich der Status ändert wird zusätzlich über den hinterlegten Mailer ein E-Mail an eine definierte Adresse gesendet. Somit wird unmittelbar ersichtlich wenn der Status von Feasible oder Optimal auf einen fehlerhaften Status wechselt, worauf der Miniserver kurz mal durchgestartet werden kann.

Die Definition des Mailers für meinen E-Mail Dienst GMX sieht dabei folgendermaßen aus.

Loxone HTTP Timeouts
Eine weitere Herausforderung ist die HTTP Timeout Zeit von 5s. Da mathematische Optimierungen durchaus einiges an Rechenzeit benötigen können (Industrieanwendungen laufen häufig nächtlich über mehrere Stunden), kommt einer effizienten Modellierung, wie im Beitrag https://www.factorysensesoftware.at/index.php/2026/01/01/optimierungsmodell/ beschrieben, umso größere Bedeutung zu. Durch die Performanceoptimierungen im Modell war es möglich innerhalb der gegebenen 5s sehr gute Lösungen für das mathematische Problem zu finden.
Eine Möglichkeit den Timeout Parameter anzupassen, konnte ich bislang in der Loxone Config leider nicht finden. Man muss allerdings auch einräumen, dass diese Einstellung für die meisten Anwendungsfälle ausreichend sein wird. Dennoch wäre es wünschenswert auch hier Anpassungsmöglichkeiten vorzufinden.
Integration Vaillant Wärmepumpe
Die Einbindung der Vaillant Wärmepumpe über das EEBUS Interface ein wesentlicher Bestandteil des Energieoptimierungssystem ist, wird diese Thematik in einem eigenen Beitrag behandelt, der unter nachstehenden Link verfügbar ist.
