Mit diesem Plugin ist es möglich die Daten aus Heliotherm Wärmepumpen (verbunden über die Serielle-Schnittstelle des Wiregate) ans KNX zu schicken.
Code:
######################################### # HELIOTHERM # # Communication with WP # # V1.19 25.04.2014 # # Author: C.Prenner # ######################################### $plugin_info{$plugname.'_cycle'} = 120; # DeBug Level my $debug = 2; my %GA_; # GroupaddressSettings $GA_{WD} = '13/7/2'; # WatchDog $GA_{Temp_Aussen}='7/2/100'; $GA_{Temp_Vorlauf}='7/2/101'; $GA_{Temp_Ruecklauf}='7/2/102'; $GA_{Temp_Brauchwasser}='7/2/103'; $GA_{Temp_EQ_Eintritt}='7/2/105'; $GA_{Temp_Frischwasser}='7/2/104'; $GA_{Temp_Verdampfung}='7/2/106'; $GA_{Temp_Kondensation}='7/2/107'; $GA_{Stoerung}='7/5/1'; $GA_{Betriebsart}='7/5/2'; $GA_{Verdichteranforderung}='7/5/3'; $GA_{WW_Normaltemp}='7/5/4'; $GA_{WW_Minimaltemp}='7/5/5'; $GA_{HKR_Soll_Raum}='7/5/6'; $GA_{HKR_Aufheiztemp}='7/5/7'; $GA_{HKR_Absenktemp}='7/5/8'; $GA_{HKR_Heizgrenze}='7/5/9'; $GA_{Verdichter_Status}='7/5/10'; $GA_{Verdichter_Zeit}='7/5/11'; $GA_{Status_HKRPumpe}='7/5/12'; $GA_{Status_Frischwasserpumpe}='7/5/13'; $GA_{Status_EQPumpe}='7/5/14'; $GA_{Status_Verdichter}='7/5/15'; $GA_{Status_Warmwasser}='7/5/16'; $GA_{HKR_Soll}='7/5/17'; $GA_{Niederdruck}='7/5/18'; $GA_{Hochdruck}='7/5/19'; $GA_{Vierwegeventil_Luft}='7/5/20'; $GA_{Kurve_oHG}='7/5/21'; $GA_{Kurve_0}='7/5/22'; $GA_{Kurve_uHG}='7/5/23'; $GA_{Betriebsst_ges}='7/5/25'; $GA_{Betriebsst_HKR}='7/5/26'; $GA_{Betriebsst_WW}='7/5/27'; $GA_{Energiezaehler}='7/5/50'; $GA_{Entstoerung}='7/5/100'; my %Command; # Adding Commands for LogIN and LogOUT $Command{LIN}='LIN;'; $Command{LOUT}='LOUT;'; # Adding known MP Numbers $Command{Temp_Aussen}='MP,NR=0;'; $Command{Temp_Brauchwasser}='MP,NR=2;'; $Command{Temp_Vorlauf}='MP,NR=3;'; $Command{Temp_Ruecklauf}='MP,NR=4;'; $Command{Temp_EQ_Eintritt}='MP,NR=6;'; $Command{Temp_Frischwasser}='MP,NR=11;'; $Command{Temp_Verdampfung}='MP,NR=12;'; $Command{Temp_Kondensation}='MP,NR=13;'; $Command{Niederdruck}='MP,NR=20;'; $Command{Hochdruck}='MP,NR=21;'; $Command{Status_HKRPumpe}='MP,NR=22;'; $Command{Status_EQPumpe}='MP,NR=24;'; $Command{Status_Warmwasser}='MP,NR=25;'; $Command{Status_Verdichter}='MP,NR=30;'; $Command{Stoerung}='MP,NR=31;'; $Command{Vierwegeventil_Luft}='MP,NR=32;'; $Command{Status_Frischwasserpumpe}='MP,NR=50;'; $Command{Verdichteranforderung}='MP,NR=56;'; $Command{HKR_Soll}='MP,NR=57;'; # Adding known SP Numbers $Command{ID}='SP,NR=9;'; $Command{Verdichter_Status}='SP,NR=10;'; $Command{Verdichter_Zeit}='SP,NR=11;'; $Command{Betriebsart}='SP,Nr=13;'; $Command{Entstoerung}='SP,Nr=14;'; $Command{HKR_Soll_Raum}='SP,NR=69;'; $Command{HKR_Aufheiztemp}='SP,NR=71;'; $Command{HKR_Absenktemp}='SP,NR=72;'; $Command{HKR_Heizgrenze}='SP,NR=76;'; $Command{Kurve_oHG}='SP,Nr=80;'; $Command{Kurve_0}='SP,Nr=81;'; $Command{Kurve_uHG}='SP,Nr=82;'; $Command{WW_Normaltemp}='SP,NR=83;'; $Command{WW_Minimaltemp}='SP,NR=85;'; $Command{Betriebsst_WW}='SP,Nr=171;'; $Command{Betriebsst_HKR}='SP,Nr=172;'; $Command{Betriebsst_ges}='SP,Nr=173;'; $Command{MKR2_aktiviert}='SP,Nr=222;'; $Command{Energiezaehler}='SP,Nr=263;'; my $CtrlCom = "02FDD0E00000"; #Control Commando my $RplyCom = "02FDE0D00000"; # Reply Commando my $schnittstelle = '/dev/ttyS0'; # the device my $timeout = "2500"; use Device::SerialPort; my $serial; if($debug>=1){plugin_log($plugname,"Schnittstelle: " . $schnittstelle . " öffnen");} # init serial port $serial = Device::SerialPort->new($schnittstelle) || die "Kann $schnittstelle nicht öffnen! ($!)\n"; $serial->baudrate(19200); $serial->parity("none"); $serial->databits(8); $serial->stopbits(1); if($debug>=1){plugin_log($plugname,"Schnittstelle: " . $schnittstelle . " erfolgreich geöffnet");} if ( Query(MakeQuery($Command{LIN})) == 'OK;' ) { # try LogIN - if Reply=OK; -> if($debug>=1){plugin_log($plugname, " LogIn OK");} # Getting values and write them to knx knx_write($GA_{Stoerung},GetValue('Stoerung'),1.001); knx_write($GA_{Temp_Aussen},GetValue('Temp_Aussen'),9.001); knx_write($GA_{Temp_Vorlauf},GetValue('Temp_Vorlauf'),9.001); knx_write($GA_{Temp_Ruecklauf},GetValue('Temp_Ruecklauf'),9.001); knx_write($GA_{Temp_Brauchwasser},GetValue('Temp_Brauchwasser'),9.001); knx_write($GA_{Temp_Frischwasser},GetValue('Temp_Frischwasser'),9.001); knx_write($GA_{Temp_EQ_Eintritt},GetValue('Temp_EQ_Eintritt'),9.001); knx_write($GA_{WW_Normaltemp},GetValue('WW_Normaltemp'),9.001); knx_write($GA_{WW_Minimaltemp},GetValue('WW_Minimaltemp'),9.001); knx_write($GA_{HKR_Soll_Raum},GetValue('HKR_Soll_Raum'),9.001); knx_write($GA_{HKR_Aufheiztemp},GetValue('HKR_Aufheiztemp'),9.001); knx_write($GA_{HKR_Absenktemp},GetValue('HKR_Absenktemp'),10.001); knx_write($GA_{HKR_Heizgrenze},GetValue('HKR_Heizgrenze'),9.001); knx_write($GA_{Verdichter_Status},GetValue('Verdichter_Status'),9.001); knx_write($GA_{Verdichter_Zeit},GetValue('Verdichter_Zeit'),9.001); knx_write($GA_{Status_HKRPumpe},GetValue('Status_HKRPumpe'),1.001); knx_write($GA_{Status_Frischwasserpumpe},GetValue('Status_Frischwasserpumpe'),1.001); knx_write($GA_{Status_EQPumpe},GetValue('Status_EQPumpe'),1.001); knx_write($GA_{Status_Warmwasser},GetValue('Status_Warmwasser'),1.001); knx_write($GA_{Status_Verdichter},GetValue('Status_Verdichter'),1.001); knx_write($GA_{Betriebsart},GetValue('Betriebsart'),9.001); knx_write($GA_{Verdichteranforderung},GetValue('Verdichteranforderung'),9.001); knx_write($GA_{HKR_Soll},GetValue('HKR_Soll'),9.001); knx_write($GA_{Temp_Verdampfung},GetValue('Temp_Verdampfung'),9.001); knx_write($GA_{Temp_Kondensation},GetValue('Temp_Kondensation'),9.001); knx_write($GA_{Kurve_oHG},GetValue('Kurve_oHG'),9.001); knx_write($GA_{Kurve_0},GetValue('Kurve_0'),9.001); knx_write($GA_{Kurve_uHG},GetValue('Kurve_uHG'),9.001); knx_write($GA_{Betriebsst_WW},GetValue('Betriebsst_WW'),9.001); knx_write($GA_{Betriebsst_HKR},GetValue('Betriebsst_HKR'),9.001); knx_write($GA_{Betriebsst_ges},GetValue('Betriebsst_ges'),9.001); knx_write($GA_{Niederdruck},GetValue('Niederdruck'),9.001); knx_write($GA_{Hochdruck},GetValue('Hochdruck'),9.001); Query(MakeQuery($Command{LOUT})); knx_write($GA_{WD},1,1.001); # Heartbeat Heliotherm-Plugin return 'OK'; } else { return 'ERROR'; } sub GetValue { # get the Value within Data ..'VAL='.. ->returns Value my $Data = MakeQuery($Command{$_[0]}); # build query for command my $Reply = Query($Data); # send query - > $Reply =~ /^.+VAL=(-?\d+(\.[0-9]+)?)[^,]?/; # get the reply after VAL= my $Value = $1; return $Value; } sub MakeQuery { # build query-string my $QueryCommand = shift; my $Lenght = length($QueryCommand)+1; $QueryCommand =~ s/(.)/sprintf("%X",ord($1))/eg; my $SendCommand = $CtrlCom . sprintf("%02X", $Lenght) . "7E" . $QueryCommand; $SendCommand .= MakeCRC($SendCommand); # adding CRC return $SendCommand; } sub MakeCRC { # Calculate CRC-Code my $daten = shift; my @array = map{ hex }( $daten=~/(..)/g ); my $crc = '0x01'; my $DataByte; my $i; foreach $DataByte (@array) { $crc ^= $DataByte; if ($DataByte & '0x80'){ $DataByte = ($DataByte << 1) | 1; } else { $DataByte = $DataByte << 1;} $crc ^= $DataByte; } # $crc ^= 0x30; if ($crc > 256) {$crc -= 256;} return sprintf("%X", $crc); } sub Query{ # sends the command and receives reply -> returns DataString my $Data = pack("H*",$_[0]); # Translate to HEX values $serial->write($Data); # Send Data my $sin=''; #Serial Input my $count=''; #Counter Input my $reciv = ''; # received Data $|=1; #$OUTPUT_AUTOFLUSH my $exit=0; while($exit < $timeout) { # read ($count, $sin) = $serial->read(8); #read byte if($count > 0){ # data recived ? $sin = unpack "H*", $sin; $reciv .= $sin; # add that byte to received Data $exit=0; } else{ $exit++ } } return GetData($reciv); # return extracted Data } sub GetData { # check if Data(HEX) is consistent (CRC) -> returns DataString or CRC_ERROR my $RawData = $_[0]; my $Data = pack("H*",$RawData); # to String my $CheckCRC = MakeCRC(substr($RawData, 0, -1)); # get CRC if ( pack("H*",$CheckCRC) == chop($Data) ) { # CRC Valid $Data = substr($Data, 8); # chop first 8 Letters (.ýàÐ..x~) $Data =~ s/\r|\n//g; # remove CRLF } else { $Data = 'CRC_ERROR' } return $Data; }
Kommentar