PID , WS300 ,Fussbodenheizung

Begonnen von My-FHEM, 11 Februar 2013, 17:44:24

Vorheriges Thema - Nächstes Thema

My-FHEM

Ich betreibe das PID Modul mit WS300 Temperatur Sensoren und lasse die PID Stellgröße
über ein shellscript an eine cron gesteuerte langsame PWM (Zykluszeit 15 min) auf die
thermischen Stellantriebe ausgeben.



define Badact dummy
define Bad_pid PID ws300.2:temperature:([\d\.]*) Badact:vBad:120:799.9 350 50 450
attr Bad_pid room BAD
set Bad_pid desired 22.1


define Bad_PID_info notify Badact {\
        my @@wtemp = split(" ", $value{"ws300.2"});; \
        my $soll =  ReadingsVal("Bad_pid","desired","0.0");;\
        my $StGr = ReadingsVal("Bad_pid","actuation","0");;\
        my $FL = "/var/log/fhem/HzBad-Stat-2011.log";;\
        system("/usr/local/bin/filelog.sh $FL 'Bad StGr '$StGr &") ;; \
        system("/usr/local/bin/filelog.sh $FL 'Bad soll '$soll &") ;; \
        system("/usr/local/bin/filelog.sh $FL 'Bad ist '$wtemp[1]&") ;;\
        }


define Bad_PID_PWD notify Badact "/usr/local/bin/setPID "%""

SetPID übergibt Hzkreiskennung und Stellgröße an Cronjob welcher Stellantrieb auf/zu fährt.




Dies funktioniert grundsätzlich soweit. das PID Modul variiert die Einstellzeit der Antriebe.
Die ws300 Werte werden alle 5 min aktualisiert. Dies bedeutet, das der D- Anteil des Reglers
nur zufällig Berücksichtigung findet. Da in der Zykluszeit 2 Wertupdates stattfinden und somit
nach 5 min. der D-Anteil wieder null ist.

Wie kann ich jetzt das PID Modul so abändern, das dTemp/dt nicht zum vorherigen sondern
gemittelt über 2..6 dt berechnet wird?

Mit anderen Worten wie kann ich auf die letzten 2 bis 6 Temp Werte in dem Modul zugreifen?



My-FHEM


Vorhand

Hallo,

ich bin auf der Suche nach einer kontinuierlichen Ansteuerung eines thermischen Stellantriebes. Offensichtlich hast du hierfür eine Lösung.
Hat sich deine Software bewährt? Ist das der komplette Code für fhem.cfg, oder muss noch was eingerichtet werden.
Kannst du bitte den kompletten Code aufzeigen?

Grüße
Vorhand
Viele Grüße
Raspi,Homatic,ESP,Fronius,KIA-PHEV,DHW300,Mi,Shelly

Joachim

Moin Vorhand,

Die Suchfunktion im Board funktioniert, und My-FHEM hat sogar einen Suchbegriff angeboten:

---------> PID Modul <----------

Gruß Joachim
FHEM aktuellste Version auf FB 7570 und 7390 mit Zebradem Toolbox Freetz
FHEM auf Raspberry
1-Wire mit LinkUSBi und Rs-Pi ds2482-800  1-Wire-9 Board; Max mit Cube, HMLAN
div. 1-Wire Sensoren; MAX-Thermostaten; Homematic-Komponenten, Zehnder KWL über RS-232

My-FHEM

#4
Ergänzend zu o.g. FHEM Code gibt es noch folgenden Eintrag in der crontab:


02-59/15 1-23 * * * /usr/local/bin/pwm.sh vBad >> /dev/null


und das Shell Script  pwm.sh


#!/bin/bash
ven=$1
current_time=$(date +%s)
# pwm 15 Min Zykluszeit = 900 sec
# Output fhem pid 130 <==> 799 --> Fhem PID Output = sleep seconds
# Stellantrieb immer aus bei kleiner 110 sec = 1 Min 50s
# Stellantrieb immer an bei groesser 900-110=790
# file .log/$ven enthaelt output Fhem PID Regler
# wird durch SetPID.sh geschrieben
fhem_path="/opt/fhem-cvs/"
case $ven in
     "vBad") reNr=0
            logtxt="Bad HzK"
            logfile=$fhem_path"log/HzBad-Stat-2011.log"
          ;;
     "vSz1") reNr=1
            logtxt="Sz1 HzK"
            logfile=$fhem_path"log/HzSz1-Stat.log"
          ;;
     "vSz2") reNr=2
            logtxt="Sz2 HzK"
            logfile=$fhem_path"log/HzSz2-Stat.log"
          ;;
     "vWz3") reNr=3
            logtxt="Wz3 HzK"
            logfile=$fhem_path"log/HzWz3-Stat.log"
          ;;
     "vKue") reNr=4
            logtxt="Kue HzK"
            logfile=$fhem_path"log/HzKue-Stat-2011.log"
          ;;
     "vWz5") reNr=5
            logtxt="Wz5 HzK"
            logfile=$fhem_path"log/HzWz5-Stat.log"
          ;;
     "vWz6") reNr=6
            logtxt="Wz6 HzK"
            logfile=$fhem_path"log/HzWz6-Stat.log"
          ;;
     "vKz") reNr=7
            logtxt="Kz HzK"
            logfile=$fhem_path"log/HzKz-Stat-2011.log"
          ;;

     *) echo "Use with Ventil Nummer"
     exit 1
esac
T_Vertstring=( $(/bin/cat $fhem_path/log/vT) )
T_vert=${T_Vertstring[0]}
PID=$(/bin/cat $fhem_path"log/$ven")
echo $T_vert
if [ "$PID" -le 130 ]; then
           echo $(date +"%Y-%m-%d_%T")" "$logtxt"  1"  >>$logfile
           /usr/local/bin/i2c-relay.sh $reNr 1
           if [ $(echo "$T_vert < 30.8"|bc) -ne 0 ];
             then sleep 120
#             else sleep 120
           else sleep 20
           fi
           echo $(date +"%Y-%m-%d_%T")" "$logtxt"  0"  >>$logfile
          /usr/local/bin/i2c-relay.sh $reNr 0
#   elif [  "$PID" -lt 150  ]; then
#           echo $(date +"%Y-%m-%d_%T")" "$logtxt"  1"  >>$logfile
#           /usr/local/bin/i2c-relay.sh $reNr 1
#           sleep 148
#           echo $(date +"%Y-%m-%d_%T")" "$logtxt"  0"  >>$logfile
#           /usr/local/bin/i2c-relay.sh $reNr 0
   elif [ "$PID" -ge 799 ]; then
            echo $(date +"%Y-%m-%d_%T")" "$logtxt"  1" >>$logfile
            /usr/local/bin/i2c-relay.sh $reNr 1
   else
          echo Go to sleep for $PID seconds
          echo $(date +"%Y-%m-%d_%T")" "$logtxt"  1" >>$logfile
          /usr/local/bin/i2c-relay.sh $reNr 1
          sleep $PID
#         PID_N=$(/bin/cat /var/log/fhem/$ven)
#         if [ "$PID" -lt "$PID_N" ]; then
#            PID_EXT=$(( PID_N-PID ))
#            echo sleep longer $PID_EXT
#            sleep $PID_EXT
#          fi
          echo $(date +"%Y-%m-%d_%T")" "$logtxt"  0" >>$logfile
          /usr/local/bin/i2c-relay.sh $reNr 0
    fi




Regelverhalten siehe Anhang.

fhainz

Schau dir mal das neue PID Modul an. Funktioniert prächtig und hat jede menge einstellungs möglichkeiten.
http://forum.fhem.de/index.php/topic,17067.0.html

Vorhand

#6
Hallo fhainz,

willst du damit sagen, dass das neue PID20 Modul von Haus aus in der Lage ist, einen thermischen Stellantrieb PWM (PulsWeiteModuliert) anzusteuern?
Das wäre natürlich super. Aus der Beschreibung konnte ich das nicht erkennen.
Das Programm von My-Fhem ist dafür schon eindeutig - sieht man an den Kurven.
Leider durchschaue ich den Perl-Code mit Cronjob noch nicht.

Ich dachte mir ein "at" Befehl würde genügen.
define a7 at +*00:10:00 set Stellantrieb on-for-timer (Stellwert-PID20 *6)
Wenn die Stellgröße 50% ist, würde on-for-time genau 300 s betragen (Hälfte der Zykluszeit).

Ich hab' leider noch nicht den richtigen Ausdruck hinter "on-for-timer" hingekriegt. Egal was ich das klammere - es geht nicht. Wenn mir dabei jemand helfen könnte?

Grüße
Vorhand
Viele Grüße
Raspi,Homatic,ESP,Fronius,KIA-PHEV,DHW300,Mi,Shelly

John

Hallo Vorhand

Zitatwillst du damit sagen, dass das neue PID20 Modul von Haus aus in der Lage ist, einen thermischen Stellantrieb PWM (PulsWeiteModuliert) anzusteuern?
Das wäre natürlich super. Aus der Beschreibung konnte ich das nicht erkennen.

PID20 liefert einen Wert zwischen 0 und 100 % als Stell-Sollwert an ein beliebiges Device.
Das kann auch ein Dummy-Device sein.

PWM unterstützt PID20 nicht direkt.

Du könntest natürlich auf das Dummy einen notify hängen und in einem Skript
PWM umsetzen.


John

CubieTruck Docker Node-Red Tasmota Shelly Homematic-IP

Vorhand

Hallo My-Fhem,

wo finde ich denn die Crontab um das einzutragen?

02-59/15 1-23 * * * /usr/local/bin/pwm.sh vBad >> /dev/null

Danke - Grüße
Viele Grüße
Raspi,Homatic,ESP,Fronius,KIA-PHEV,DHW300,Mi,Shelly

My-FHEM

#9
@john
Meine Umsetzung verfolgt genau dieses Prinzip. Ich habe PID anstatt PID20 benutzt, weil ich es vor ca. 3 Jahren
umgesetzt habe. Damals gab es PID 20 nicht. Könnte man heute sicher auch als Modul zur Regelung einsetzen.

Es bleibt die Ansteuerung der thermischen Stellantriebe. Hierzu ist der "Analoge" Output des Reglers in Pulsweiten
der Stellantriebe umzusetzen. dies machen meine cronjobs.

@Vorhand
Ich habe insgesamt 8 Heizkreise. welche ich 4 mal die Stunde also Periodendauer 15 min ansteuere.

daher PID max 900 => 900sec =15min, die thermischen stellantriebe haben eine Totzeit von ca. 2min. daher
unterer Stellgrösse 130 => 130sec =2min10sec. Durch diese Parameter erspare ich mir % in Zeitumrechnungen.
Dies erledigt das PID Modul implizit. Das cron script öffnet das Ventil wartet die  Zeit in sec des PID Outputs
und schaltet das Ventil dan aus.

Durch die Shell Ebene habe ich damit keine Blockierungen von FHEM. Wie gesagt das war vor ca. 3 Jahren alles etwas mühsamer.

Insgesamt ist diese Regelung in zwei Ebenen strukturiert:

FHEM sammelt IST-Werte der Räume und erzeugt Stellgröße über das PID MODUL (könnte sicher auch PID20 sein).

Die cronjobs sind Aktor Seite und dort wird das PWM Timing erzeugt.

Ich bin mit dieser Lösung ganz zufrieden. TH555 als Temp Sensoren, und einen Dockstar mit i2c Relaisanschluss
für Moehlenhoff Stellantriebe über FHEM und cron gesteuert.

Die Genauigkeit ist sehr gut für diese träge Fussbodenheizung. Wenn im Winter kein zu grosser Solareintrag
da ist, beträgt die Regelabweichung selten mehr als 0,2°C.

Gruß

Bei weiteren Fragen bitte Melden.

PS.

auf Shellebene Befehl crontab -e


Ach ja: Ich habe auch das Modul 98_PID.pm etwas verändert, Um den Integrator Teil zu stoppen,
wenn Ausgang in Begrenzung und mein Lösungsansatz zur Frage im ersten Beitrag (Mittelwertbildung des D-Anteils).

Anbei diff zum Original.


--- 98_PID.pm.1 2013-11-24 20:01:47.000000000 +0100
+++ 98_PID.pm   2014-01-09 12:53:12.000000000 +0100
@@ -94,6 +94,7 @@ PID_Define($$$)
   PID_sv($pid, 'delta',      0.0);
   PID_sv($pid, 'actuation',  0.0);
   PID_sv($pid, 'integrator', 0.0);
+  PID_sv($pid, 'davg',      0.0);
   $pid->{STATE} = 'initialized';

   return undef;
@@ -210,17 +211,31 @@ PID_setValue($)

   my $delta = $desired - $in;
   my $p = $delta * $pid->{pFactor};
+  my $y = PID_gv($pid, 'actuation');
+  my $i = PID_gv($pid, 'integrator');

-  my $i = PID_saturate($pid, PID_gv($pid,'integrator')+$delta*$pid->{iFactor});
-  PID_sv($pid, 'integrator', $i);
+  if (($y < $pid->{satMax}) && ($y > $pid->{satMin})) {
+     $i = PID_saturate($pid, PID_gv($pid, 'integrator')+$delta*$pid->{iFactor});
+     }
+  else {
+     $i = PID_saturate($pid, PID_gv($pid, 'integrator')+0.0 );
+  }
+
+#  my $i = PID_saturate($pid, PID_gv($pid,'integrator')+$delta*$pid->{iFactor});

+
+  PID_sv($pid, 'integrator', $i);
   my $d = ($delta - PID_gv($pid,'delta')) * $pid->{dFactor};
   PID_sv($pid, 'delta',  $delta);
+  my $davg = ($pid->{HELPER}{prevd}*3+$d)/4;
+  my $a =  PID_saturate($pid, $p + $i + $davg);
+  $pid->{HELPER}{prevd} = $davg;
+                Log 3, "P: $p I: $i d: $d davg: $davg ";

-  my $a =  PID_saturate($pid, $p + $i + $d);
+  PID_sv($pid, 'davg', $davg);
   PID_sv($pid, 'actuation', $a);

-  Log GetLogLevel($pn,4), sprintf("PID $pn: p:%.2f i:%.2f d:%.2f", $p, $i, $d);
+  Log GetLogLevel($pn,4), sprintf("PID $pn: p:%.2f i:%.2f d:%.2f davg:%2f", $p, $i, $d, $davg);

   # Hack to round.
   my ($satMin, $satMax) = ($pid->{satMin}, $pid->{satMax});



Vorhand

Hallo,

bin immer noch unterwegs, meine PID-Reglung mit einer 1wire Temperatur als Istwert ans laufen zu bekommen.
Kann jemand die genaue Syntax für die Definition aufschreiben?
Offensichtlich kennt PID und PID20 noch keine 1wire Sensoren - oder liege ich da falsch?
Folgendes hab ich getestet:
define BrVentil dummy
define BrFUBO PID20 Buero  BrVentil
oder
define BrFUBO PID20 Buero:temperature:([\d\.]*) BrVentil

Die Regelung läuft nicht los - was auf einen Syntaxfehler hinweist!

Grüße
Viele Grüße
Raspi,Homatic,ESP,Fronius,KIA-PHEV,DHW300,Mi,Shelly

John

Hallo Vorhand,

bitte folgendes einstellen
- Event-Log und das Reading markieren, das den Istwert liefert

- einen beispielhaften set-Befehl für den Aktor

Dann sehen wir weiter.

Es gibt keine Konditionierung von PID20 auf ein bestimmtes Geräte. Alles läuft über Readings und die sind in FHEM allgemeingültig.

John


CubieTruck Docker Node-Red Tasmota Shelly Homematic-IP

Vorhand

Hallo John,
hier der event-log

2014-02-17 16:11:39 OWTHERM Dach temperature: 19
2014-02-17 16:11:39 OWTHERM Dach T: 19.00 °C
2014-02-17 16:11:42 OWTHERM Wng temperature: 22.5625
2014-02-17 16:11:42 OWTHERM Wng T: 22.56 °C
2014-02-17 16:11:44 OWDevice S1 PIO: on
2014-02-17 16:11:44 Global global DEFINED PWMoff
2014-02-17 16:11:45 OWTHERM Buero temperature: 23.6875
2014-02-17 16:11:45 OWTHERM Buero T: 23.69 °C
2014-02-17 16:11:46 OWTHERM Blr7 temperature: 53.5625
2014-02-17 16:11:46 OWTHERM Blr7 T: 53.56 °C
Grüße
Viele Grüße
Raspi,Homatic,ESP,Fronius,KIA-PHEV,DHW300,Mi,Shelly

John

Hallo Vorhand

folgendes sollte zumindest bezüglich des Istwertes funktionieren:
define BrFUBO PID20 Buero:temperature BrVentil

abstrakt:
define <name> PID20 sensor[:reading[:regexp]] actor:cmd

sensor : Buero
reading : temperature
regexp:  leer, da Wert von Reading direkt als Zahl interpretierbar ist
actor : BrVentil
cmd : leer, da vermutlich ein Dummy und man den Stellwert via "set BrVentil 30" setzt

John
CubieTruck Docker Node-Red Tasmota Shelly Homematic-IP