Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Hardware
    4. IOBroker Anbindung an einen Kostal Plenticore

    NEWS

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    • Monatsrückblick - April 2025

    IOBroker Anbindung an einen Kostal Plenticore

    This topic has been deleted. Only users with topic management privileges can see it.
    • Marco Laser
      Marco Laser @StrathCole last edited by

      @StrathCole Klar
      Unbenannt.PNG

      StrathCole 1 Reply Last reply Reply Quote 0
      • StrathCole
        StrathCole @Marco Laser last edited by

        @Marco-Laser Ach so, du hast 3 Strings … Das ist interessant. Kannst du mir vielleicht auch einen Screenshot von den "Momentanwerten" schicken (gern auch per PN), mit ausgeklappten Details?
        Bei mir gibt es nur 2 Strings. Könnte also sein, dass ich da auch noch was machen muss.

        Marco Laser 1 Reply Last reply Reply Quote 0
        • Marco Laser
          Marco Laser @StrathCole last edited by

          @StrathCole Unbenannt.PNG
          Bittesehr

          StrathCole 1 Reply Last reply Reply Quote 0
          • StrathCole
            StrathCole @Marco Laser last edited by

            @Marco-Laser danke. Zeigt er im IOB als Wert zufällig 7 an, wenn du für alle drei das Schattenmanagement anschaltest?

            Marco Laser 1 Reply Last reply Reply Quote 0
            • Marco Laser
              Marco Laser @StrathCole last edited by

              @StrathCole Exakt das tut er 😄

              StrathCole 1 Reply Last reply Reply Quote 0
              • StrathCole
                StrathCole @Marco Laser last edited by StrathCole

                @Marco-Laser Könntest du bitte den Adapter noch einmal aktualisieren, aber:
                Erst Instanz deaktivieren, dann den Datenpunkt plenticore.0.devices.local.generator.ShadowMgmt einmal aus den Objekten löschen, dann vom GIT aktualisieren und erst dann die Instanz wieder einschalten.

                Ich habe auch die Batterieerkennung geändert, hoffe, dass es trotzdem noch genauso klappt.

                Er sollte jetzt auch neue Datenpunkte für dein pv3 anlegen, vorher hatte er nur 1 und 2 unter devices.local.

                Marco Laser 1 Reply Last reply Reply Quote 0
                • Marco Laser
                  Marco Laser @StrathCole last edited by

                  @StrathCole Jo stimmt so weit aber schalten tut er beim Schattenmanagement trotzdem nix wird wieder auf das vorherige gesetzt

                  StrathCole 1 Reply Last reply Reply Quote 0
                  • StrathCole
                    StrathCole @Marco Laser last edited by

                    @Marco-Laser kommt denn etwas im Log, dass es fehlschlägt?

                    Marco Laser 1 Reply Last reply Reply Quote 0
                    • Marco Laser
                      Marco Laser @StrathCole last edited by

                      @StrathCole Ne leider nicht. Kann es daran liegen dass ich polling mittlerweile auf 5000 gestellt hab? Dass das zu schnell geht?

                      StrathCole 1 Reply Last reply Reply Quote 0
                      • StrathCole
                        StrathCole @Marco Laser last edited by

                        @Marco-Laser Probier doch mal aus, ob es geht, wenn du Polling auf 20 stellst und direkt nach dem Update änderst. Vielleicht erwischst du manuell genau den Zeitpunkt, an dem er selbst den Status schreibt.

                        Marco Laser 1 Reply Last reply Reply Quote 0
                        • Marco Laser
                          Marco Laser @StrathCole last edited by

                          @StrathCole Tut sich leider auch nix, wird rot wenn ich es ändert und bleibt dann so bis es nach den 20 sekunden geändert wird

                          StrathCole 1 Reply Last reply Reply Quote 0
                          • StrathCole
                            StrathCole @Marco Laser last edited by

                            @Marco-Laser Problem gefunden und eliminiert. Denke, du hattest nur getestet, das Management zu deaktivieren 😉
                            Einen Wert auf 0 bzw. "false" zu setzen, hat allerdings grundsätzlich nicht funktioniert. Da hatte ich Mist gebaut.

                            Marco Laser 1 Reply Last reply Reply Quote 0
                            • Marco Laser
                              Marco Laser @StrathCole last edited by

                              @StrathCole Und das soll jetzt funktionieren ? Also auf was anderes als 0 setzten klappt, ohne Probleme aber 0 iwie nicht (V1.4)

                              StrathCole 1 Reply Last reply Reply Quote 0
                              • StrathCole
                                StrathCole @Marco Laser last edited by

                                @Marco-Laser Seltsam. Und es dauert auch nicht nur einen Moment, bis er es aktualisiert? Bei mir kann ich problemlos auf 0 setzen. 😕

                                Marco Laser 1 Reply Last reply Reply Quote 0
                                • Marco Laser
                                  Marco Laser @StrathCole last edited by

                                  @StrathCole Ui das ging schnell 😛 ne bei 0 wirds Rot und beim nächsten Poll zurück gesetzt alle anderen werden Grün und dann auch nicht zurück gesetzt. Gleiches gilt auch für ext. module control, kann ich auch nicht ändern wird auch zurück gesetzt

                                  1 Reply Last reply Reply Quote 0
                                  • StrathCole
                                    StrathCole last edited by

                                    Ext. Module Control habe ich deaktiviert. Das wird im UI immer automatisch auf 0 gesetzt, wenn man die Einstellungen für das Schattenmanagement ändert.
                                    Hast du den Datenpunkt denn gelöscht gehabt, sodass er nun eine Auswahlbox zeigt, wenn du etwas ändern willst (mit Text)?

                                    Marco Laser 1 Reply Last reply Reply Quote 0
                                    • Marco Laser
                                      Marco Laser @StrathCole last edited by

                                      @StrathCole Jap hab Auswahlboxen gehabt und auch jetzt nochmal gelöscht aber ändert nix 🤔

                                      StrathCole 1 Reply Last reply Reply Quote 0
                                      • StrathCole
                                        StrathCole @Marco Laser last edited by

                                        @Marco-Laser Gibt's doch nicht …
                                        Da bräuchte ich jetzt vermutlich Infos aus der Developer-Konsole von deinem Browser, während du in der UI den Wert auf "Disabled" stellst. Nutzt du dafür Chrome oder Firefox?

                                        1 Reply Last reply Reply Quote 0
                                        • Diginix
                                          Diginix last edited by Diginix

                                          @StrathCole Habe eben von 0.1.4 auf 2.0.0 aktualisiert (alle vorherigen Updates wurden mir nie angeboten).
                                          Soweit scheint alles zu funktionieren.

                                          Hab die Doku in Git nur kurz überflogen. Kannst du vllt hier noch bissel was zum neuen Bereich "Leistungsprognose" schreiben.

                                          StrathCole 1 Reply Last reply Reply Quote 0
                                          • StrathCole
                                            StrathCole @Diginix last edited by StrathCole

                                            @Diginix sagte in IOBroker Anbindung an einen Kostal Plenticore:

                                            @StrathCole Habe eben von 0.1.4 auf 2.0.0 aktualisiert (alle vorherigen Updates wurden mir nie angeboten).
                                            Soweit scheint alles zu funktionieren.

                                            Hab die Doku in Git nur kurz überflogen. Kannst du vllt hier noch bissel was zum neuen Bereich "Leistungsprognose" schreiben.

                                            Der Adapter ist gerade erst im latest Repository gelandet, daher gab es die vorherigen Updates immer nur via manuellem Git-Update.

                                            Zum Forecast:
                                            Ich habe für mich eine Funktion benötigt, anhand derer ich abschätzen kann, ob ich "stromfressende" Dinge starte, wie z. B. die Warmwasseraufheizung auf 60° statt 50° usw.
                                            Also habe ich die Basisberechnung zur PV-Leistung aus dem Forum genommen, die anhand der Eingabedaten zu Neigung und Ausrichtung sowie Effizienz und Gesamtfläche der Module eine mögliche Leistung über den Tag verteilt berechnet. Dabei wird dann die Geo-Position und somit der Sonnenstand einbezogen.

                                            Diese Werte kombiniere ich dann mit den Werten der Wettervorhersagen entweder aus dem DarkSky-Adapter oder Weatherunderground (muss jeder schauen, welcher Dienst die besseren Vorhersagen in der Region liefert).

                                            Daraus ergibt sich dann eine prognostizierte Leistung der PV-Anlage in den einzelnen Sonnenstunden des Tages.

                                            Weiterhin nimmt der Adapter die laufenden Verbrauchswerte des Hausverbrauchs (sofern im KOSTAL vorhanden) und bildet daraus einen Nacht- und eine Tagsdurchschnitt. So kann man sehen, wie viel Überschuss voraussichtlich am aktuellen Tag noch produziert wird.

                                            Bei aktiviertem MinSoC wird dann der minimale Entladestand der Batterie automatisch angepasst, je nachdem wie die Werte für den nächsten Tag erwartet werden (damit keine Energie verschwendet, aber die Batterie auch nicht zu sehr entladen wird, wenn am nächsten Tag nicht genug Leistung zum Wiederaufladen da wäre).

                                            Ich nutze das Ganze zum Beispiel für meine Viessmann Heizung mit dem Adapter viessmannapi wie folgt:

                                            
                                            if(existsState('javascript.0.heizung.dhw.lastrun') === false) {
                                                createState('heizung.dhw.lastrun', 0, {name: 'Letzter gestarteter Aufheizprozess', unit: '', type: 'number', role: 'value'});
                                            }
                                            if(existsState('javascript.0.heizung.dhw.pvsince') === false) {
                                                createState('heizung.dhw.pvsince', 0, {name: 'Beginn des Überschusszeitraums', unit: '', type: 'number', role: 'value'});
                                            }
                                            
                                            let low_power = 0;
                                            let battery_capacity = 8960;
                                            
                                            function calcHeatingPower() {
                                                let dc1 = getState('modbus.0.holdingRegisters.260_PV_Leistung 1').val;
                                                let dc2 = getState('modbus.0.holdingRegisters.270_PV_Leistung 2').val;
                                                
                                                //* calculate current overall PV power
                                                let pvpower = dc1 + dc2;
                                            
                                                //* get current battery power state of charging (+ for discharging, - for charging)
                                                let batt_charge = getState('modbus.0.holdingRegisters.582_Batterieladung').val;
                                                let batt_charge_signed = batt_charge;
                                                if(batt_charge > 0) {
                                                    batt_charge = 0;
                                                }
                                            
                                                //* current home power consumption
                                                let house_usage = getState('modbus.0.holdingRegisters.252_Hausverbrauch').val;
                                                //* thereof provided by PV
                                                let house_from_pv = getState('modbus.0.holdingRegisters.116_Verbrauch_aus PV').val;
                                                //* current battery state of charge in percent
                                                let batt_soc = getState('modbus.0.holdingRegisters.514_Battery_SOC').val;
                                            
                                                let inv_output = getState('modbus.0.holdingRegisters.575_Wechselrichteroutput').val;
                                            
                                                //* power adjusted by battery charge
                                                let pvpower_real = inv_output - batt_charge_signed;
                                                if(pvpower_real < 0) {
                                                    pvpower_real = 0;
                                                }
                                            
                                                //* remaining power that possibly would be sent to grid
                                                let rest = pvpower + batt_charge - house_from_pv;
                                                let rest_real = rest - 40;
                                                //* half of battery charging power is ignored for calculation
                                                rest_real = rest - (batt_charge / 2);
                                            
                                                let curTime = new Date();
                                            
                                                log('PV: ' + pvpower + " (" + pvpower_real + "), WR: " + inv_output + ", Charge: " + batt_charge + " (" + batt_charge_signed + ", " + batt_soc + "), House: " + house_from_pv + " (" + house_usage + "), Überschuss: " + rest + " (" + rest_real + ")", 'debug');
                                                
                                                let sunrise;
                                                let sunset = getAstroDate('sunset');
                                                if(sunset.getTime() < curTime.getTime()) {
                                                    let nextDay = new Date(curTime.getTime());
                                                    nextDay.setDate(nextDay.getDate() + 1);
                                                    sunset = getAstroDate('sunset', nextDay.getTime());
                                                    sunrise = getAstroDate('sunrise', nextDay.getTime());
                                                } else {
                                                    sunrise = getAstroDate('sunrise');
                                                }
                                                if(sunrise > sunset) {
                                                    let prevDay = new Date(sunrise.getTime());
                                                    prevDay.setDate(prevDay.getDate() - 1);
                                                    sunrise = getAstroDate('sunrise', prevDay.getTime());
                                                }
                                                
                                                //* calc hours of (possible) sunshine - daylight
                                                let sun_hours = (sunset - sunrise) / 1000 / 60 / 60;
                                                let highForecast = false;
                                            
                                                let powerUntilSunset = 0;
                                                let powerStartTime = new Date(curTime.getTime());
                                                if(powerStartTime.getTime() < sunrise.getTime()) {
                                                    powerStartTime.setTime(sunrise.getTime());
                                                }
                                                let powerTime = new Date(powerStartTime.getTime()).toGermanTime();
                                                let powerHours = (sunset.getTime() - powerStartTime.getTime()) / 1000 / 60 / 60;
                                                if(powerHours > 0) {
                                                    log('There are ' + powerHours + ' of ' + sun_hours + ' hours of sun time left to take into account.');
                                                    let fcH = 0;
                                                    for(let p = powerHours; p > 0; p--) {
                                                        fcH++;
                                                        let fcPower = (existsState('plenticore.0.forecast.power.' + Math.ceil(sun_hours + 1 - p) + 'h.power') ? getState('plenticore.0.forecast.power.' + Math.ceil(sun_hours + 1 - p) + 'h.power').val : 0);
                                                        //log('Power for fc hour ' + (powerTime.getHours() + fcH) + ' is ' + fcPower);
                                                        if(fcPower) {
                                                            if(p < 1) {
                                                                fcPower = fcPower * p;
                                                                //log('Power for fc hour ' + (powerTime.getHours() + fcH) + ' is ' + fcPower + ' because of factor ' + p);
                                                            }
                                                            powerUntilSunset += fcPower;
                                                        }
                                                    }
                                            
                                                    let powerUsageForecast = getState('plenticore.0.forecast.consumption.day').val * powerHours / sun_hours;
                                                    let neededBatteryCharge = 1.1 * battery_capacity * (100 - batt_soc) / 100;
                                                    log('FC: ' + powerUntilSunset + 'W. Usage forecast is ' + powerUsageForecast + ', needed battery power is about ' + neededBatteryCharge);
                                                    if(powerUntilSunset > (powerUsageForecast * 1.1) + neededBatteryCharge && powerUntilSunset - powerUsageForecast - neededBatteryCharge >= 3000) {
                                                        highForecast = true;
                                                        log('We are at a very high forecast currently.');
                                                    }
                                                }
                                            
                                                let curMinSoC = getState('plenticore.0.devices.local.battery.MinSoc').val;
                                            
                                                //* since when (timestamp) power is sent to grid
                                                let pv_plus_since = getState('javascript.0.heizung.dhw.pvsince').val
                                                let pv_plus_for = 0;
                                                if((highForecast || curMinSoC <= 30 || batt_soc >= 80) && rest_real > 200) {
                                                    low_power = 0;
                                                    if(!pv_plus_since) {
                                                        setState('javascript.0.heizung.dhw.pvsince', (new Date()).getTime());
                                                    } else {
                                                        //* how long (minutes) power is already sent to grid
                                                        let curtime = (new Date()).getTime();
                                                        pv_plus_for = Math.round((curtime - pv_plus_since) / 1000 / 60);
                                                    }
                                                } else if(low_power > 2) {
                                                    //* low power for more than 2 loops, so reset the "since" timestamp
                                                    setState('javascript.0.heizung.dhw.pvsince', 0);
                                                    low_power = 0;
                                                } else {
                                                    // no rest, so reset the timer if more than 2 times lower than needed
                                                    low_power++;
                                                }
                                            
                                                //* if we have enough power generated for a long enough period
                                                if((pv_plus_for >= 5 || (pv_plus_for >= 2 && batt_soc > 85) || (pv_plus_for >= 3 && highForecast === true)) && rest_real > 400 && batt_soc > 40 && (batt_charge < -1500 || batt_soc > 75 || highForecast === true)) {
                                                    //* check if warm water charging is currently active
                                                    let dhw_active = getState('viessmannapi.0.heating.dhw.charging.active').val;
                                                    if(!dhw_active) {
                                                        //* check current warm water temperature
                                                        let temp = getState('viessmannapi.0.heating.dhw.sensors.temperature.hotWaterStorage.top.value').val;
                                                        let targetTemperature = 60;
                                                        //* if we have enough power but not that much, we lower the warm water temp by 5°C
                                                        if(pvpower < 3000 || (rest_real < 1000 && batt_soc < 80)) {
                                                            targetTemperature = 55;
                                                        }
                                                        if(targetTemperature > temp + 7.5) {
                                                            targetTemperature = temp + 8;
                                                        }
                                                        if(targetTemperature < 55) {
                                                            targetTemperature = 55;
                                                        }
                                                        log('WW-Temperatur: ' + temp + '°C', 'info');
                                                        //* if current temperature is less than 6°C below the desired temperature
                                                        if(temp <= targetTemperature - 5) {
                                                            //* check if last charging was completed more than 10 minutes ago
                                                            let last = getState('javascript.0.heizung.dhw.lastrun').val;
                                                            let checkLast = new Date();
                                                            checkLast.setMinutes(checkLast.getMinutes() - 10);
                                                            if(last < checkLast.getTime())  {
                                                                //* if this is true the request for one time charging was not fulfilled by the heater
                                                                let started = getState('viessmannapi.0.heating.dhw.oneTimeCharge.active').val;
                                                                if(!started) {
                                                                    //* set new desired temperature and start charging now
                                                                    log('Starte Warmwassergenerierung.');
                                                                    setState('javascript.0.heizung.dhw.lastrun', (new Date()).getTime());
                                                                    let curTargetTemp = getState('viessmannapi.0.heating.dhw.temperature.temp2.value').val;
                                                                    if(curTargetTemp != targetTemperature) {
                                                                        sendTo('viessmannapi.0', 'action', {
                                                                            feature: 'heating.dhw.temperature.temp2',
                                                                            action: 'setTargetTemperature',
                                                                            payload: {temperature: targetTemperature}
                                                                        });                        
                                                                    }
                                                                    sendTo('viessmannapi.0', 'action', {
                                                                        feature: 'heating.dhw.oneTimeCharge',
                                                                        action: 'activate',
                                                                        payload: {}
                                                                    });
                                                                } else {
                                                                    log('WW-Generierung bereits angefordert, aber noch nicht gestartet.');
                                                                }
                                                            } else {
                                                                log('Warmwassergenerierung nicht lang genug her (' + Math.round(((new Date()).getTime() - last) / 1000 / 60) + ').', 'debug');
                                                            }
                                                        }
                                                    } else {
                                                        let temp = getState('viessmannapi.0.heating.dhw.sensors.temperature.hotWaterStorage.top.value').val;
                                                        log('Warmwassergenerierung läuft bereits.', 'debug');
                                                        log('WW-Temperatur: ' + temp + '°C', 'debug');
                                                    }
                                                } else if(rest_real > 100 && pv_plus_for > 0 && pv_plus_for < 5) {
                                                    log('PV Überschuss erst seit ' + pv_plus_for + ' Minute(n).', 'debug');
                                                }
                                            }
                                            
                                            //* subscribe to changes in modbus value of inverter output
                                            on({ id: 'modbus.0.holdingRegisters.575_Wechselrichteroutput', change: "ne" }, function (obj) {
                                                calcHeatingPower();
                                            });
                                            calcHeatingPower();
                                            
                                            //* subscribe on hot water charging state
                                            on({id: 'viessmannapi.0.heating.dhw.charging.active', change: 'ne'}, function(obj) {
                                                //* set last run marker (timestamp) on each state change
                                                if(obj.state.val == true) {
                                                    log('Warmwassergenerierung gestartet.');
                                                    setState('javascript.0.heizung.dhw.lastrun', (new Date()).getTime());
                                                } else {
                                                    log('Warmwassergenerierung beendet.');
                                                    setState('javascript.0.heizung.dhw.lastrun', (new Date()).getTime());
                                            
                                                    //* reset target hot water temperature for one-time-charging to 55°C
                                                    let targetTemp = getState('viessmannapi.0.heating.dhw.temperature.temp2.value').val;
                                                    if(targetTemp > 55) {
                                                        sendTo('viessmannapi.0', 'action', {
                                                            feature: 'heating.dhw.temperature.temp2',
                                                            action: 'setTargetTemperature',
                                                            payload: {temperature: 55}
                                                        });
                                                    }
                                                }
                                            });
                                            
                                            schedule('*/5 * * * *', function() {
                                                let last = getState('javascript.0.heizung.dhw.lastrun').val;
                                                let checkLast = new Date();
                                                checkLast.setMinutes(checkLast.getMinutes() - 10);
                                                if(last < checkLast.getTime())  {
                                                    //* if this is true the request for one time charging was not fulfilled by the heater
                                                    let started = getState('viessmannapi.0.heating.dhw.oneTimeCharge.active').val;
                                                    let dhw_active = getState('viessmannapi.0.heating.dhw.charging.active').val;
                                                    if(started && !dhw_active) {
                                                        log('Stoppe Warmwassergenerierung. Charge ist nicht "true".');
                                                        setState('javascript.0.heizung.dhw.lastrun', (new Date()).getTime());
                                                        sendTo('viessmannapi.0', 'action', {
                                                            feature: 'heating.dhw.oneTimeCharge',
                                                            action: 'deactivate',
                                                            payload: {}
                                                        });
                                                    }
                                                }
                                            });
                                            

                                            Es kann sein, dass da noch was optimiert werden müsste, da ich die Prognose vorher in Javascript gemacht hatte statt im Adapter und das im Skript noch nicht 100% angepasst wurde.

                                            Diginix 1 Reply Last reply Reply Quote 2
                                            • First post
                                              Last post

                                            Support us

                                            ioBroker
                                            Community Adapters
                                            Donate

                                            886
                                            Online

                                            31.7k
                                            Users

                                            79.8k
                                            Topics

                                            1.3m
                                            Posts

                                            83
                                            1302
                                            378654
                                            Loading More Posts
                                            • Oldest to Newest
                                            • Newest to Oldest
                                            • Most Votes
                                            Reply
                                            • Reply as topic
                                            Log in to reply
                                            Community
                                            Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                                            The ioBroker Community 2014-2023
                                            logo