Röhren-Kollektor-Beschattungs-Projekt

  • Guten Tag

    Mein Name Udo , bin noch recht neu hier im Forum

    und möchte über mein neues Projekt schreiben.

    "Röhren-Kollektor-Beschattungs-Projekt"

    ? Wer braucht denn sowas und warum ?

    Vor 21 Jahren wurde ein Zweifamilienhaus für 6 Personen

    mit Fußbodenheizung und Solarer Thermieunterstützung geplant.

    Der Betrieb in den vergangen Jahren zeigte, daß sich der Mehraufwand

    bei der Installation bezahlt hat.

    Nur hat zu Beginn keiner mit unserem nun spührbaren Umweltveränderungen

    gerechnet .

    Es wurden 3 x Paradigma CPC20 Röhren Kolletoren verbaut,

    welche in meinem Fall, (PLZ88271) das gesamte Haus von April bis

    in den späten Oktober ausschließlich mit "Solarwärme" mit Warmwasser

    und zeitweise mit Heizung versorgt.

    Die 2 Enkel-Kinder ( ein maßgeblicher Warmwasser Verbraucher)

    sind flüge und ausgeflogen, das heißt weniger Warmwasserverbrauch

    plus seigende Sommertemperaturen treiben die Thermianlage in die Stagnation.

    Das ist absolut nicht gut und schädigt die Anlagenstruktur.

    Das ist also der Grund des Projekts das diesen Sommer bereits

    seine Funktion bewiesen hat.

    Das ganze aber mit manueller Bedienung.

    Die Hälfte der Röhren-Kollektoren werden mit einer quasi Markise beschattet

    und verhindern die Stagnation der "Thermie - Solar -Anlage".

    Stagnation ==> die gesammte Transportflüssigkeit ( Kühlmittel) wird in den

    Ausgleichsbehälter im Keller gedrückt und bei abkühlen entstehen Gasblasen

    im System . Passiert das öfter findet auf Grund der Gasblasen kein Umwälzung

    mehr statt und das Sytem ist ausgefallen.

    Soweit die Vorgeschichte; Hoffe ist nicht zu lang ausgefallen .

    Vor geraumer Zeit bin ich durch ein Youtube video

    "Wie geht die Scripting-Funktion der neuen Shelly PRO

    und Shelly PLUS und was kann man damit machen?";

    auf die Möglichkeit gestossen meine sehr geringen Erfahrungen

    mit Shelly-Produkten zu erweitern.

    So bin ich dann auch, auf dieses sehr interessante und gute

    Forum gestossen.

    Bisher habe ich den Shelly 2.5 als "switch ( Beleuchtung) & auch als cover"

    an einer Markise eingesetzt. Die Anlagen laufen problemlos seit ca 2 Jahren.

    Die Markisensteuerung unter Anwendung des Shelly 2PM brachten mich

    bei meinem " Röhren-Kollektor-Beschattungs-Projekt " auf die Idee,

    die deutlich anspruchsvollere Steuerung der Anlage damit duchzuführen.

    In der Zwischenzeit wurde das ADD-ON für den 2PM eingeführt und so

    erübrigte das den Einsatz eines Arduino für die Meßwerterfassung.

    Das Pflichtenheft:

    1. Keine Beschattung bei: T-Sensor Temp <= 25 Grad

    2. Volle Beschattung bei: T-Sensor Temp >= 75 Grad

    3. Entfernen der Beschattung : wenn Spannung >= 4 V = & > 4 Bf Wind

    am Schelly Add-On Spannungeingang anliegen

    ===> zu viel Wind ( Messung mit Flügelrad )

    4. Beschattung nicht notwendig wenn Uhrzeit >= 18:00

    ( Abends ist zu wenig Strahlung am Kollektor

    5. Anlage in den Winterschlaf legen (Okt. Bis Mai.) manuel per Netzschalter

    Meine Programmierkenntnisse sind sehr rudimentär in C , Basic & Arduino

    und so nahm ich mir Zeit die Grundlagen für Java Script zu studieren

    und die Zahlreichen Muster-Scripts in diesem Forum zu analysieren.

    Mit reinem copy & paste ist man in dieser Sache aber sehr schnell am

    Ende und die Reihe der Error's wird immer länger.

    In diesem Fall hilft nur Beharrlichkeit und so blieb ich meinem

    Wahlspruch treu !!! " Geht nicht gibts nicht "

    Die Hardware:

    1 Stck. Markise 3,5m x 1,6m Rohrmotor mit Endschaltern justierbar

    1 Stck Shelly ADD-ON

    1 Stck Shelly 2PM

    1 Stück Steckernetzteil 220AC/12v 1A DC Schaltnetzteil

    (Spannungsversorgung des Flügelrads)

    1 Stck Flügelrad (https://de.aliexpress.com/item/1005005500304078.html)

    hier die 0-10V Version verwenden

    1 Stck Temeratursensor DS18b20


    Herausgekommen ist dabei ein scetch der für meine Ansprüche funktioniert!

    Echte Programmierer werde sagen das geht besser ( ich kann es nicht )

    Für all diejenigen die etwas ähnliches brauchen können hier ohne Gewähr

    und nur für den eigenen Bedarf !!!

    der Code.

    Der Name: Rollo_Temp_Wind_Time

    /*

    Versuch die Beschattung der Roehren-Kollecktoren per Script zu steuern. Rev 3.0 UB

    Das läuft soweit seit 6.11.2023

    In der Config:

    temp_min = minimale Innentemperatur(z.B. meine 35°C)

    id_inside = Id des Innentemperaturfühlers (Solar_Kollektor_Ruecklauf_Temp)

    rollo == auf 100% (voll abgedeckt) ; auf 0% ( voll eingefahren)

    interval = Messen, Auswerten und Schalten alle z.B 10 Sekunden

    Für unteren code:

    1a. roller/0?go= 4% bei inside-Temp <= 25 Grad // das waren Werte zu testen

    2a. roller/0?go=90% bei outside-Temp >= 45 Grad

    3. roller/0?go= 4% wenn Spannung >= 4 V am Schelly Add-On Spannungeingang anliegen ===> zu viel Wind ( Messung mit Flügelrad )

    4. roller/0?go= 0% wenn Uhrzeit >= 18:00 ( Abends ist zu wenig Strahlung am Kollektor


    */

    function TsKonverter(ts, timeZone, yOff) {

    let a =[ts,timeZone,yOff],k =true,b =86400,d =0,e =0,f =0,g =0,h =0,j =[31,28,31,30,31,30,31,31,30,31,30,31];

    function fa(va,vb,vg,vd){return va +Math.floor((vb -vg) /vd);}

    function fb(ve,vf,vg){for (let y =ve; y <vf; y++){if ((y %4 === 0 && y %100 !== 0) || y %400 === 0)vg +=1;}return vg;}

    if (typeof(a[2]) === 'undefined')a[2] =1970;

    for (let i in a){let t =typeof(a[i]); if (t === 'undefined' || (t !== 'number' && t !== 'bigint')){print("Error_TsKonverter, Input",i, " wrong Datatype: ",t); a[i] =0; k =false;}}

    g =Math.floor(a[0] /b); f =fa(a[2],g,0,366); d =fb(a[2],f,0); f =fa(a[2],g,d,365); d =fb(a[2],f,0); f =fa(a[2],g,d,365);

    if ((f %4 === 0 && f %100 !== 0) || f %400 === 0)j[1] =29;

    h =(g -d) %365;

    for (let i =0; i <j.length; i++){if (h >j[i]){h -=j[i];}else {e =i +1; if (a[2] === 0) e -=1; break;}}

    if (a[2] >0)h +=1;

    let values ={aa:h,ab:e,ac:f,ad:Math.floor((a[0] %b) /3600) +a[1],ae:Math.floor((a[0] %3600) /60),af:Math.floor(a[0] %60)};

    if (values.ad === 24){values.aa +=1; values.ad =0;}

    let number ={Tag:values.aa,Monat:values.ab,Jahr:values.ac,Stunde:values.ad,Minute:values.ae,Sekunde:values.af};

    let string ={Tag:JSON.stringify(values.aa),Monat:JSON.stringify(values.ab),Jahr:JSON.stringify(values.ac),Stunde:JSON.stringify(values.ad),Minute:JSON.stringify(values.ae),Sekunde:JSON.stringify(values.af)};

    let sa ={Tag:JSON.stringify(values.aa),Monat:JSON.stringify(values.ab),Jahr:JSON.stringify(values.ac),Stunde:JSON.stringify(values.ad),Minute:JSON.stringify(values.ae),Sekunde:JSON.stringify(values.af)};

    string.Datum =(string.Tag +':' +string.Monat +':' +string.Jahr);

    string.Zeit =(string.Stunde +':' +string.Minute +':' +string.Sekunde);

    for (let v in sa){if (sa[v].length < 2){sa[v] ='0' +sa[v];}}

    let twoDigits ={Tag:sa.Tag,Monat:sa.Monat,Jahr:sa.Jahr,Stunde:sa.Stunde,Minute:sa.Minute,Sekunde:sa.Sekunde};

    twoDigits.Datum =(twoDigits.Tag +':' +twoDigits.Monat +':' +twoDigits.Jahr);

    twoDigits.Zeit =(twoDigits.Stunde +':' +twoDigits.Minute +':' +twoDigits.Sekunde);

    let ausgabe ={Valid:k,Number:number,String:string,TwoDigits:twoDigits};

    return ausgabe;

    }

    //############################## Config ############################

    let Config = {

    temp_min : 25, // Minimale Temperatur Testwerte

    temp_max : 45, // Maximale Kollektor Temperatur

    id_inside : 100, // Sensor Id (Solar_Kollektor_Ruecklauf_Temp)

    id_input : 100, // Wind Sensor 0 - 100%

    W_max : 40, // Zu viel Wind

    speed_real : 0, // Wahrer Wind

    w_speed : 0,

    w_temp : 0,

    roller : 0,

    Abend : 728, //18h==>1080 + 45 minuten == 1125

    interval : 10 // 2 seconds is the minimum interval

    }

    //############################## Config end ############################

    function watch()

    {

    try

    {

    let shellyTime = Shelly.getComponentStatus("sys").unixtime;

    let newDate = TsKonverter(shellyTime, +1);

    if(newDate.Valid)

    {

    print(newDate.TwoDigits.Zeit);

    // h:m in Minuten umrechnen

    let h =(newDate.Number.Stunde);

    let m = (newDate.Number.Minute);

    let minuten = (( h * 60 ) + m );

    print('Minuten = ',minuten);

    }

    //else {

    temp_inside = Shelly.getComponentStatus('Temperature', Config.id_inside).tC; //temperature:100":{"id": 100,"tC":20.9, "tF":69.6}

    print('Temp. Kollektor Ruecklauf =',temp_inside); // (Solar_Kollektor_Ruecklauf_Temp)

    let w_temp = Math.floor(temp_inside);

    print ('Kollektor Ruecklauf_integer =' ,w_temp);

    //----------------- das Läuft ------------------------------------------------

    speed_real = Shelly.getComponentStatus('input',Config.id_input).percent; //"input:100":{"id":100,"percent":0.0}

    print('Wind_real =', speed_real);

    let w_speed = Math.floor(speed_real);

    print ('Wind_integer =' ,w_speed);

    // --------------- Info wird ausgegeben ------------------------------------------------

    if (minuten >= Config. Abend) {

    Shelly.call("http.get",{url:'http://127.0.0.1/roller/' + JSON.stringify(Config.roller) + '?go=to_pos&roller_pos=4'});

    print('Rollo(',Config.roller, ') Rollo geschlossen Abend >= ', Config.minuten);

    }

    else {

    // tu nix

    if (w_speed >= Config. W_max) {

    Shelly.call("http.get",{url:'http://127.0.0.1/roller/' + JSON.stringify(Config.roller) + '?go=to_pos&roller_pos=4'});

    print('Rollo(',Config.roller, ') geschlossen. Wind_speed to high >= ', w_speed);

    } //

    else { //

    if (w_temp <= Config.temp_min) {

    Shelly.call("http.get",{url:'http://127.0.0.1/roller/' + JSON.stringify(Config.roller) + '?go=to_pos&roller_pos=4'});

    print('Rollo(',Config.roller, ') geschlossen. Inside temp <= ', Config.temp_min);

    }

    else {

    if (w_temp >= Config.temp_max) {

    Shelly.call("http.get",{url:'http://127.0.0.1/roller/' + JSON.stringify(Config.roller) + '?go=to_pos&roller_pos=90'});

    print('Rollo(',Config.roller, ') beschattet. Outside temp >= ', Config.temp_max);

    }

    else {

    }

    }

    }

    //}

    }

    }

    // print('\n')


    catch (err) {

    Shelly.call("http.get", {192.168.178.57 + JSON.stringify(Config.rollo) +'?go=to_pos&roller_pos=90'});

    print(err);

    }

    }

    function start() {

    // do a first shot

    watch();

    // set watch timer to configured value

    Timer.set(Config.interval * 1000,true,watch);

    }

    // schedule script start for 1 second

    Timer.set(1000,false,start); // alle 10 Secunden prüfen & reagieren

    Das war es dann , viel Spaß beim testen .

    Bin gespannt auf die Reaktionen

    Der Udo

  • UBrollo kannst du Deinen Beitrag nochmals Editieren und dein Script in den Code Tag einfügen? Dadurch wird er besser ersichtlich und lesbar.

    Der Inhalt kann nicht angezeigt werden, da Sie keine Berechtigung haben, diesen Inhalt zu sehen.
  • Moin Moin

    Entschuldigung , hab das ganz übersehen und den Code einfach angehängt.

    Mach ich gerne:

    Zur Ergänzung; Bin noch an einer Verbesserung dran.

    Zur Zeit fehlt da noch eine Hyserese für die Wind-Steuerung.

    Muß ich aber erst noch testen und zur Zeit ist da zu wenig Sonne !!!

    Wind währe ja genug .

    Hier nochmal und hoffe richtig.

  • Dieses Thema enthält einen weiteren Beitrag, der nur für registrierte Benutzer sichtbar ist.