Der eigene Pool – Neue Version des PoolAutomatation Skripts

Poolmon Code

… und dem was dazu gehört. Nicht nur am Pool, also der Hardware selber, hat sich was getan; auch an der Softwarefront gibt es Neuerungen. Noch letztes Jahr habe ich das Skript erweitert. Ich hatte bislang die Temperatur immer nur am Solarschlauch auf dem Dach gemessen (an einer Stelle). Was ist aber, wenn Schlaufen, die nicht gemessen werden, im Schatten sind. Was wenn die Temperatur vom Dach nicht im Pool ankommt. Das wäre blöd. Also gibt es jetzt einen zusätzlichen Temperatursensor am Poolschlauch direkt am Einlauf.

Ausserdem fand ich die Konfiguration in verschiedenen Dateien eher ungünstig. Die Übersichtswebseite füllt die Parameter und ist somit mehr als nur Übersicht, sondern auch die Einstellung der Automation. Außerdem habe ich die Sensoren jetzt nicht mehr in der PoolAutomation, in der Übersichtswebseite und den Checks hart gepflegt, sondern auch dafür eine Konfig-Datei gemacht. Die Übersichtswebseite hat zudem ein Icon bekommen. Das Bild dafür muss in zig Formate umgewandelt und hinterlegt werden. Im Code habe ich es stehen gelassen. Das Konvertieren muss aber jeder selber machen. Es funktioniert aber auch ohne Logo. 😉

Als ich im Frühjahr das Poolwasser eingelassen habe war es zwar tagsüber schon so warm, dass man in Wasser gehen konnte. Nachts ändert sich das aber. Vor allen Dingen die ungeschützt auf dem Dach liegenden Solarschlaufen sind gänzlich der Witterung und somit der Kälte in der Nacht ausgesetzt. Dabei ist mir ein Worst-Case-Szenario aufgefallen, das ich bislang nicht auf dem Radar hatte. Was ist, wenn es friert? Im schlimmsten Fall platzt ein Schlauch und dann pumpt die Pumpe sich irgendwann selber das Wasser weg und läuft trocken.

Wie die Dateien editiert werden hatte ich ja schon zuvor beschrieben, daher setze ich das Wissen jetzt einfach voraus und kopiere hier nur den Inhalt der Dateien rein.

/etc/PoolAutomatation/PoolAutomatation.py

#!/usr/bin/python3
# -*- coding: utf-8 -*-
import time
import datetime
import RPi.GPIO as GPIO

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(22, GPIO.OUT)

file = open('/etc/PoolAutomatation/Sensor.txt', 'r')
fileLines = file.readlines()
file.close()
for line in fileLines:
    if "TempAmbientFile=" in line:
        TempAmbientFile = line.replace("TempAmbientFile=","").replace("\n","").replace("\r","")
    if "TempPumproomFile=" in line:
        TempPumproomFile = line.replace("TempPumproomFile=","").replace("\n","").replace("\r","")
    if "TempSolarFile=" in line:
        TempSolarFile = line.replace("TempSolarFile=","").replace("\n","").replace("\r","")
    if "TempSolarBackFile=" in line:
        TempSolarBackFile = line.replace("TempSolarBackFile=","").replace("\n","").replace("\r","")
    if "TempWaterFile=" in line:
        TempWaterFile = line.replace("TempWaterFile=","").replace("\n","").replace("\r","")

while True:
    now = datetime.datetime.now()
    file = open('/etc/PoolAutomatation/PoolAutomatation.txt', 'r')
    fileLines = file.readlines()
    file.close()
    for line in fileLines:
        if "TargetTemp=" in line:
            TargetTemp = float(line.replace("TargetTemp=",""))
        if "SwitchOffDiff=" in line:
            SwitchOffDiff = float(line.replace("SwitchOffDiff=",""))
        if "SwitchOffReturnDiff=" in line:
            SwitchOffReturnDiff = float(line.replace("SwitchOffReturnDiff=",""))
        if "SwitchOnDiff=" in line:
            SwitchOnDiff = float(line.replace("SwitchOnDiff=",""))
        if "TargetTempDivergence=" in line:
            TargetTempDivergence = float(line.replace("TargetTempDivergence=",""))
        if "Starttime=" in line:
            line = line.replace("Starttime=","")
            pos = line.strip().find(':')
            StartHour = int(line.strip()[:pos])
            StartMin = int(line.strip()[pos+1:])
            Starttime = now.replace(hour=StartHour, minute=StartMin, second=0, microsecond=0)
        if "Endtime=" in line:
            line = line.replace("Endtime=","")
            pos = line.strip().find(':')
            EndHour = int(line.strip()[:pos])
            EndMin = int(line.strip()[pos+1:])
            Endtime = now.replace(hour=EndHour, minute=EndMin, second=0, microsecond=0)
        if "AutomatationEnabled=" in line:
            AutomatationEnabled = int(line.replace("AutomatationEnabled=",""))
        if "ForcePowerOn=" in line:
            ForcePowerOn = int(line.replace("ForcePowerOn=",""))
        if "ForcePowerOnPermanently=" in line:
            ForcePowerOnPermanently = int(line.replace("ForcePowerOnPermanently=",""))
        if "AntiFreezeTemp=" in line:
            AntiFreezeTemp = float(line.replace("AntiFreezeTemp=",""))

    #print("TargetTemp {} SwitchOffDiff {} SwitchOffReturnDiff {} SwitchOnDiff {} TargetTempDivergence {} Starttime {} Endtime {} Now {} AutomatationEnabled {} ForcePowerOn {} ForcePowerOnPermanently {} AntiFreezeTemp {}".format(TargetTemp, SwitchOffDiff, SwitchOffReturnDiff, SwitchOnDiff, TargetTempDivergence, Starttime, Endtime, now, AutomatationEnabled, ForcePowerOn, ForcePowerOnPermanently, AntiFreezeTemp))
    pinstate = GPIO.input(22)
    if AutomatationEnabled == 1:
        file = open(TempWaterFile, 'r')
        fileLines = file.readlines()
        file.close()
        count = 0
        crcPoolWater = 0
        for line in fileLines:
            count += 1
            if count == 1:
                if line.strip().endswith("YES"):
                    crcPoolWater = 1
            if count == 2:
                if crcPoolWater == 1:
                    pos = line.strip().find('t=')
                    temp1 = line.strip()[pos+2:]
                    templen = 5 - len(temp1)
                    TempPool = float(temp1[:2-templen] + "." + temp1[2-templen:])

        file = open(TempSolarFile, 'r')
        fileLines = file.readlines()
        file.close()
        count = 0
        crcSolar = 0
        for line in fileLines:
            count += 1
            if count == 1:
                if line.strip().endswith("YES"):
                    crcSolar = 1
            if count == 2:
                if crcSolar == 1:
                    pos = line.strip().find('t=')
                    temp1 = line.strip()[pos+2:]
                    templen = 5 - len(temp1)
                    TempSolar = float(temp1[:2-templen] + "." + temp1[2-templen:])
        
        file = open(TempSolarBackFile, 'r')
        fileLines = file.readlines()
        file.close()
        count = 0
        crcSolarReturn = 0
        for line in fileLines:
            count += 1
            if count == 1:
                if line.strip().endswith("YES"):
                    crcSolarReturn = 1
            if count == 2:
                if crcSolarReturn == 1:
                    pos = line.strip().find('t=')
                    temp1 = line.strip()[pos+2:]
                    templen = 5 - len(temp1)
                    TempSolarReturn = float(temp1[:2-templen] + "." + temp1[2-templen:])

        #print("TempPool {} TempSolar {} TempSolarReturn {} Starttime {} Endtime {} Now {}".format(TempPool, TempSolar, TempSolarReturn, Starttime, Endtime, now))
        if pinstate == 1:
            if ForcePowerOnPermanently == 0:
                if TempPool > TargetTemp:
                    GPIO.output(22, False) 
                if (TempSolar - TempPool) < SwitchOffDiff:
                    GPIO.output(22, False)
                if (TempSolarReturn - TempPool) < SwitchOffReturnDiff:
                    GPIO.output(22, False)
                if now > Endtime:
                    GPIO.output(22, False)
        if pinstate == 0:
            if (((TempSolar - TempPool) >= SwitchOnDiff) and (TempPool < TargetTemp) and (now > Starttime) and (now < Endtime) and (TempPool < (TargetTemp - TargetTempDivergence)) or (TempSolar < AntiFreezeTemp) or (TempSolarReturn < AntiFreezeTemp)):
                GPIO.output(22, True)
            if ForcePowerOnPermanently == 1:
                GPIO.output(22, True)
            if ForcePowerOn == 1:
                GPIO.output(22, True)
                #read input file
                file = open("/etc/PoolAutomatation/PoolAutomatation.txt", "rt")
                #read file contents to string
                data = file.read()
                #replace all occurrences of the required string
                data = data.replace('ForcePowerOn=1', 'ForcePowerOn=0')
                #close the input file
                file.close()
                #open the input file in write mode
                file = open("/etc/PoolAutomatation/PoolAutomatation.txt", "wt")
                #overrite the input file with the resulting data
                file.write(data)
                #close the file
                file.close()
    else:
        if pinstate == 1:
            GPIO.output(22, False)
    time.sleep(60)

/etc/PoolAutomatation/PoolAutomatation.txt

TargetTemp=32
SwitchOffDiff=1
SwitchOffReturnDiff=0.5
SwitchOnDiff=1.5
TargetTempDivergence=0.2
AntiFreezeTemp=3
Starttime=08:00
Endtime=20:00
AutomatationEnabled=1
ForcePowerOn=0
ForcePowerOnPermanently=0

/etc/PoolAutomatation/Sensor.txt

TempAmbientFile=/sys/bus/w1/devices/28-3c01e07621a0/w1_slave
TempPumproomFile=/sys/bus/w1/devices/28-000000044223/w1_slave
TempSolarFile=/sys/bus/w1/devices/28-3c01e07643eb/w1_slave
TempSolarBackFile=/sys/bus/w1/devices/28-062017ae61c3/w1_slave
TempWaterFile=/sys/bus/w1/devices/28-3cffe076da73/w1_slave

/var/www/html/index.php

<?php
$page = $_SERVER['PHP_SELF'];
$refreshinsec = "60";
?>
<HTML>
<head>
<meta http-equiv="refresh" content="<?php echo $refreshinsec?>;URL='<?php echo $page?>'">
</head>
<body>

<link rel="apple-touch-icon" sizes="57x57" href="/apple-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/apple-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="/apple-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png">
<link rel="icon" type="image/png" sizes="192x192"  href="/android-icon-192x192.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/manifest.json">
<meta name="msapplication-TileColor" content="#ffffff">
<meta name="msapplication-TileImage" content="/ms-icon-144x144.png">
<meta name="theme-color" content="#ffffff">

<?php

$File = '/etc/PoolAutomatation/PoolAutomatation.txt';
$lines = file($File);//file in to an array
foreach ($lines as &$value) {
    if (strpos($value, "TargetTemp=") !== false) {
        $pos = strpos( $value, "=" ) + 1;
        $TargetTemp = (float) substr($value,$pos);
    }
    if (strpos($value, "SwitchOffDiff=") !== false) {
        $pos = strpos( $value, "=" ) + 1;
        $SwitchOffDiff = (float) substr($value,$pos);
    }
    if (strpos($value, "SwitchOffReturnDiff=") !== false) {
        $pos = strpos( $value, "=" ) + 1;
        $SwitchOffReturnDiff = (float) substr($value,$pos);
    }
    if (strpos($value, "SwitchOnDiff=") !== false) {
        $pos = strpos( $value, "=" ) + 1;
        $SwitchOnDiff = (float) substr($value,$pos);
    }
    if (strpos($value, "TargetTempDivergence=") !== false) {
        $pos = strpos( $value, "=" ) + 1;
        $TargetTempDivergence = (float) substr($value,$pos);
    }
    if (strpos($value, "AntiFreezeTemp=") !== false) {
        $pos = strpos( $value, "=" ) + 1;
        $AntiFreezeTemp = (float) substr($value,$pos);
    }
    if (strpos($value, "Starttime=") !== false) {
        $pos = strpos( $value, "=" ) + 1;
        $Starttime = substr($value,$pos);
    }
    if (strpos($value, "Endtime=") !== false) {
        $pos = strpos( $value, "=" ) + 1;
        $Endtime = substr($value,$pos);
    }
    if (strpos($value, "AutomatationEnabled=") !== false) {
        $pos = strpos( $value, "=" ) + 1;
        $AutomatationEnabled = substr($value,$pos);
        if($AutomatationEnabled == 1) {
            $AutomatationEnabledChecked = " checked";
        } else {
            $AutomatationEnabledChecked = "";
        }
    }
    if (strpos($value, "ForcePowerOn=") !== false) {
        $pos = strpos( $value, "=" ) + 1;
        $ForcePowerOn = substr($value,$pos);
        if($ForcePowerOn == 1) {
            $ForcePowerOnChecked = " checked";
        } else {
            $ForcePowerOnChecked = "";
        }
    }
    if (strpos($value, "ForcePowerOnPermanently=") !== false) {
        $pos = strpos( $value, "=" ) + 1;
        $ForcePowerOnPermanently = substr($value,$pos);
        if($ForcePowerOnPermanently == 1) {
            $ForcePowerOnPermanentlyChecked = " checked";
        } else {
            $ForcePowerOnPermanentlyChecked = "";
        }
    }
}

$Sensorfile = '/etc/PoolAutomatation/Sensor.txt';
$lines = file($Sensorfile);//file in to an array
foreach ($lines as &$value) {
    if (strpos($value, "TempAmbientFile=") !== false) {
        $pos = strpos( $value, "=" ) + 1;
        $value = substr($value,$pos);
        $TempAmbientFile = substr($value,0,strlen($value)-1);
    }
    if (strpos($value, "TempPumproomFile=") !== false) {
        $pos = strpos( $value, "=" ) + 1;
        $value = substr($value,$pos);
        $TempPumproomFile = substr($value,0,strlen($value)-1);
    }
    if (strpos($value, "TempSolarFile=") !== false) {
        $pos = strpos( $value, "=" ) + 1;
        $value = substr($value,$pos);
        $TempSolarFile = substr($value,0,strlen($value)-1); 
    }
    if (strpos($value, "TempSolarBackFile=") !== false) {
        $pos = strpos( $value, "=" ) + 1;
        $value = substr($value,$pos);
        $TempSolarBackFile = substr($value,0,strlen($value)-1);
    }
    if (strpos($value, "TempWaterFile=") !== false) {
        $pos = strpos( $value, "=" ) + 1;
        $value = substr($value,$pos);
        $TempWaterFile = substr($value,0,strlen($value)-1);
    }

}

echo '<p>Temp Au&szlig;en: ';

$lines = file($TempAmbientFile);//file in to an array
if ((substr($lines[0], (strlen($lines[0]) -4),3)) == "YES") {
        #$TempAmbient = round((float)(substr($lines[1], (strlen($lines[1]) - 6), 2).'.'.substr($lines[1], (strlen($lines[1]) - 4), 3)),2);
        $TempAmbient = round((float)substr($lines[1],strpos($lines[1],"t=")+2)/1000,2); 
        echo $TempAmbient.'° C';
} else {
        echo 'Sensor not okay';
}
echo '</p>';

echo '<p>Temp Pumpenraum: ';

$lines = file($TempPumproomFile);//file in to an array
if ((substr($lines[0], (strlen($lines[0]) -4),3)) == "YES") {
        #$TempPumproom = round((float)(substr($lines[1], (strlen($lines[1]) - 6), 2).','.substr($lines[1], (strlen($lines[1]) - 4), 3)),2);
        $TempPumproom = round((float)substr($lines[1],strpos($lines[1],"t=")+2)/1000,2);
        echo $TempPumproom.'° C';
} else {
        echo 'Sensor not okay';
}
echo '</p>';

echo '<p>Temp Solar: ';
$lines = file($TempSolarFile);//file in to an array
if ((substr($lines[0], (strlen($lines[0]) -4),3)) == "YES") {
        #$TempSolar = round((float)(substr($lines[1], (strlen($lines[1]) - 6), 2).'.'.substr($lines[1], (strlen($lines[1]) - 4), 3)),2);
        $TempSolar = round((float)substr($lines[1],strpos($lines[1],"t=")+2)/1000,2);
        echo $TempSolar.'° C';
} else {
        echo 'Sensor not okay';
}

echo '</p>';

echo '<p>Temp SolarR&uuml;cklauf: ';

$lines = file($TempSolarBackFile);//file in to an array
if ((substr($lines[0], (strlen($lines[0]) -4),3)) == "YES") {
        #$TempSolarBack = round((float)(substr($lines[1], (strlen($lines[1]) - 6), 2).','.substr($lines[1], (strlen($lines[1]) - 4), 3)),2);
        $TempSolarBack = round((float)substr($lines[1],strpos($lines[1],"t=")+2)/1000,2);
        echo $TempSolarBack.'° C';
} else {
        echo 'Sensor not okay';
}
echo '</p>';



echo '<p>Temp Poolwasser: ';
$lines = file($TempWaterFile);//file in to an array
if ((substr($lines[0], (strlen($lines[0]) -4),3)) == "YES") {
        #$TempPoolwater = round((float)(substr($lines[1], (strlen($lines[1]) - 6), 2).'.'.substr($lines[1], (strlen($lines[1]) - 4), 3)),2);
        $TempPoolwater = round((float)substr($lines[1],strpos($lines[1],"t=")+2)/1000,2);
        echo $TempPoolwater.'° C';
} else {
        echo 'Sensor not okay';
}
echo '</p>';

echo '<p>Temp Solar/Wasser-Differenz: ';
$TempDiff = round($TempSolar - $TempPoolwater,2);

echo $TempDiff.'° C';
echo '</p>';

echo '</p>';

echo '<p>Temp SolarR&uuml;cklauf/Wasser-Differenz: ';
$TempDiff2 = round($TempSolarBack - $TempPoolwater,2);

echo $TempDiff2.'° C';
echo '</p>';

$command = escapeshellcmd('/etc/CQRobot/ReadPH.py');
$phresult = shell_exec($command);
echo '<p>'.$phresult.'</p>';

exec ('/etc/CQRobot/ReadPH.py',$ph);
echo '<p>'.$ph[0].'</p>';
exec ('/etc/CQRobot/ReadTDS.py',$tds);
echo '<p>'.$tds[0].'</p>';


exec ('gpio -g read 22', $gpiostat);
if ($gpiostat[0] == "1") {
	echo '<p style="color:green;">Die Pumpe ist derzeit eingeschaltet.</p>';
} else {
	echo '<p style="color:red;">Die Pumpe ist derzeit ausgeschaltet.</p>';
}


    #$output .= "\n" . 'AutomatationEnabled=' . $AutomatationEnabled
    #$output .= "\n" . 'ForcePowerOn=' . $ForcePowerOn
    #$output .= "\n" . 'ForcePowerOnPermanently=' . $ForcePowerOnPermanently

echo '<p>';
echo '<form method="put" action="setvalues.php">';
echo 'Ziel-Wassertemperatur: <input type="number" step="0.1" name="TargetTemp" value="'.(float) $TargetTemp.'">';
echo '<br>Ausschalt-Temperaturdifferenz: <input type="number" step="0.1" name="SwitchOffDiffTemp" value="'.$SwitchOffDiff.'">';
echo '<br>Ausschalt-Temperaturdifferenz R&uumlcklauf: <input type="number" step="0.1" name="SwitchOffReturnDiffTemp" value="'.$SwitchOffReturnDiff.'">';
echo '<br>Einschalt-Temperaturdifferenz: <input type="number" step="0.1" name="SwitchOnDiffTemp" value="'.$SwitchOnDiff.'">';
echo '<br>Erlaubte Ziel-Temperaturabweichung: <input type="number" step="0.1" name="TargetTempDivergence" value="'.$TargetTempDivergence.'">';
echo '<br>Frostschutztemperatur: <input type="number" step="0.1" name="AntiFreezeTemp" value="'.$AntiFreezeTemp.'">';
echo '<br>Startzeit: <input type="time" name="StartTime" value="'.substr($Starttime,0,5).'">';
echo '<br>Endzeit: <input type="time" name="EndTime" value="'.substr($Endtime,0,5).'">';
echo '<br>Automatation Aktiviert: <input type="checkbox" id="AutomatationEnabled" name="AutomatationEnabled" value="1"'. $AutomatationEnabledChecked  .'>';
echo '<br>Einschalten: <input type="checkbox" id="ForcePowerOn" name="ForcePowerOn" value="1"'. $ForcePowerOnChecked  .'>';
echo '<br>Einschalten erzwingen: <input type="checkbox" id="ForcePowerOnPermanently" name="ForcePowerOnPermanently" value="1"'. $ForcePowerOnPermanentlyChecked  .'>';

echo '<br><input type="submit" name="OK" value="OK">' ;
echo '</form>';
echo '<form method="put" action="index.php"><input type="submit" name="Action" value="Reload"></form>';

echo '</p>';
echo '<p>';
echo 'Zeitpunkt: ';
echo date("d.m.Y H:i:s");
echo '</p>';

echo '<p>';
echo 'Diese Seite aktualisiert sich alle '.$refreshinsec.' Sekunden.';
echo '</p>';
?>

</body>
</HTML>

/var/www/html/setvalues.php

<HTML>
<body>
<p>
<?php

	$TargetTemp = $_GET['TargetTemp'];
	$SwitchOffDiffTemp = $_GET['SwitchOffDiffTemp'];
	$SwitchOnDiffTemp = $_GET['SwitchOnDiffTemp'];
	$SwitchOffReturnDiffTemp = $_GET['SwitchOffReturnDiffTemp'];
	$StartTime = $_GET['StartTime'];
	$EndTime = $_GET['EndTime'];
	$TargetTempDivergence = $_GET['TargetTempDivergence'];
	$AntiFreezeTemp = $_GET['AntiFreezeTemp'];
    $AutomatationEnabled = "0";
    $AutomatationEnabled = $_GET['AutomatationEnabled'];
    if ($AutomatationEnabled == "") {
        $AutomatationEnabled = "0";
    }
    $ForcePowerOn = $_GET['ForcePowerOn'];
    if ($ForcePowerOn == "") {
        $ForcePowerOn = "0";
    }
    $ForcePowerOnPermanently = $_GET['ForcePowerOnPermanently'];
    if ($ForcePowerOnPermanently == "") {
        $ForcePowerOnPermanently = "0";
    }
    
    $output = 'TargetTemp=' . $TargetTemp;
    $output .= "\n" . 'SwitchOffDiff=' . $SwitchOffDiffTemp;
    $output .= "\n" . 'SwitchOffReturnDiff=' . $SwitchOffReturnDiffTemp;
    $output .= "\n" . 'SwitchOnDiff=' . $SwitchOnDiffTemp;
    $output .= "\n" . 'TargetTempDivergence=' . $TargetTempDivergence;
    $output .= "\n" . 'AntiFreezeTemp=' . $AntiFreezeTemp;
    $output .= "\n" . 'Starttime=' . $StartTime;
    $output .= "\n" . 'Endtime=' . $EndTime;
    $output .= "\n" . 'AutomatationEnabled=' . $AutomatationEnabled;
    $output .= "\n" . 'ForcePowerOn=' . $ForcePowerOn;
    $output .= "\n" . 'ForcePowerOnPermanently=' . $ForcePowerOnPermanently;
    
    echo '<p>' . $output . '</p>';
	
	$fileHandle = fopen('/etc/PoolAutomatation/PoolAutomatation.txt','w');
	fwrite($fileHandle, $output);
	fclose($fileHandle);
	header("location:index.php");

?>

</p>
</body>
</HTML>

Ich versuche meine Erfahrungen und Fehler so gut es geht hier niederzuschreiben und die verwendeten Artikel mit Links zu versehen, wenn es denn welche gibt. Wenn über die Produktlinks eingekauft wird erhalte ich einen kleinen Teil davon. Für den Käufer ändert sich am Endpreis nichts. Wenn euch der Blog gefällt, würde ich mich freuen, wenn ihr mich auf diese Weise beteiligen würdet.

Verschlagwortet

Schreibe einen Kommentar