yes!
...# Plugin zur Ansteuerung einer Zender ComfoAir
# Version 0.3 04.06.2012 ALPHA
# Copyright: swiss (https://knx-user-forum.de/members/swiss.html)
# Die Vorlage für die Datenübertragung via socat stammt von makki (https://knx-user-forum.de/members/makki.html)
# Aufbau möglichst so, dass man unterhalb der Einstellungen nichts verändern muss!
#
#
use Device::SerialPort;
####################
###Einstellungen:###
####################
my $ga_stufeabwesend = '14/7/0'; #1bit Trigger für Stufe "Abwesend". 1=Aktivieren
my $ga_stufe1 = '14/7/1'; #1bit Trigger für Stufe1. 1=Aktivieren
my $ga_stufe2 = '14/7/2'; #1bit Trigger für Stufe2. 1=Aktivieren
my $ga_stufe3 = '14/7/3'; #1bit Trigger für Stufe3. 1=Aktivieren
my $usb = '/dev/usbserial-2-3';
######################
##ENDE Einstellungen##
######################
my $return_value2;
my $daten;
my $reciv;
my $ack = pack("H*","07F3");
$plugin_info{$plugname.'_cycle'} = 30;
# Zyklischer Aufruf nach restart und alle 300 sek.
my $seriel = Device::SerialPort->new($usb) || die "Kann $usb nicht öffnen! ($!)\n";
$seriel->baudrate(9600);
$seriel->parity("none");
$seriel->databits(8);
$seriel->stopbits(1);
if ($msg{'apci'} eq "A_GroupValue_Write"){
if ($msg{'dst'} eq $ga_stufeabwesend && knx_read($msg{'dst'},0,1) == 1) {
$daten = "00990101";
plugin_log($plugname,'Stufe abwesend');
$return_value2 = command_senden($daten);
}elsif ($msg{'dst'} eq $ga_stufe1 && knx_read($msg{'dst'},0,1) == 1) {
$daten = "00990102";
plugin_log($plugname,'Stufe 1');
$return_value2 = command_senden($daten);
}elsif ($msg{'dst'} eq $ga_stufe2 && knx_read($msg{'dst'},0,1) == 1) {
$daten = "00990103";
plugin_log($plugname,'Stufe 2');
$return_value2 = command_senden($daten);
}elsif ($msg{'dst'} eq $ga_stufe3 && knx_read($msg{'dst'},0,1) == 1) {
$daten = "00990104";
plugin_log($plugname,'Stufe 3');
$return_value2 = command_senden($daten);
}
return $return_value2;
} else { # zyklischer Aufruf
# Plugin an Gruppenadresse "anmelden", hierdurch wird das Plugin im folgenden bei jedem eintreffen eines Telegramms auf die GA aufgerufen und der obere Teil dieser if-Schleife durchlaufen
$plugin_subscribe{$ga_stufeabwesend}{$plugname} = 1;
$plugin_subscribe{$ga_stufe1}{$plugname} = 1;
$plugin_subscribe{$ga_stufe2}{$plugname} = 1;
$plugin_subscribe{$ga_stufe3}{$plugname} = 1;
$daten = "000F00";
plugin_log($plugname,'Temperatur abrufen');
$return_value2 = command_senden($daten);
}
# Ab hier wird das Datenpaket inklusive Checksumme zusammengestellt und an die ComfoAir übertragen
sub command_senden{
my $checksum = 0;
my $data = $_[0];
my $datasum = $data . "AD"; #+173 für die Checksummenberechnung
my @hex = map { hex($_) } ($datasum =~ /(..)/g);
my $x07warschon = 0;
foreach (@hex) {
$checksum += ($_) unless $x07warschon; # unless ist dasselbe wie if not/!
if ($_ == 0x07) { $x07warschon = 1; }
}
$checksum = sprintf "%x\n" , $checksum; #Mache aus Integer wieder HEX
$checksum = substr($checksum,length($checksum)-3,2); #Verwede nur die letzten beiden stellen
my $command = pack("H*","07F0" . $data . $checksum . "070F");
my $commandhex = $command;
$commandhex =~ s/(.)/sprintf("0x%x ",ord($1))/eg;
$plugin_info{$plugname.'_debug_transmit'} = $commandhex;
plugin_log($plugname,'transmit:' . $commandhex);
$seriel->write($command);
$|=1;
my $exit=0;
while($exit < 30000)
{
my ($cin, $sin) = $seriel->read(25);
if($cin > 0){
$sin = unpack "H*", $sin;
$reciv .= $sin;
$exit=0;
}else{
$exit++
}
if($reciv =~ /07f3/i){
plugin_log($plugname,'reciv: ACK');
$reciv = '';
}
if($reciv =~ /070f/i){
plugin_log($plugname,'reciv: ' . $reciv);
if($reciv =~ /07f0001004/i){ #Wenn die Temperaturen empfangen wurden
my $t1 = substr($reciv,10,2);
my $t2 = substr($reciv,12,2);
my $t3 = substr($reciv,14,2);
my $t4 = substr($reciv,16,2);
plugin_log($plugname,'reciv: T1: ' . $t1 . ' T2:' . $t2 . ' T3: ' . $t3 . ' T4: ' . $t4);
$t1 = (hex($t1)/2)-20;
$t2 = (hex($t2)/2)-20;
$t3 = (hex($t3)/2)-20;
$t4 = (hex($t4)/2)-20;
plugin_log($plugname,'reciv: T1: ' . $t1 . '°C, T2:' . $t2 . '°C, T3: ' . $t3 . '°C, T4: ' . $t4 . '°C');
}
$seriel->write($ack);
last;
}
}
#$reciv = pack("H*",$reciv);
#$reciv =~ s/(.)/sprintf("0x%x ",ord($1))/eg;
plugin_log($plugname,'reciv: ' . $reciv);
$plugin_info{$plugname.'_debug_reciv'} = $reciv;
}
Ich werde es, wenn es dann mal funktioniert um die ganzen Debugausgaben kürzen und noch etwas besser kommentieren 


# Plugin zur Ansteuerung einer Zender ComfoAir
# Version 0.4 04.06.2012 ALPHA
# Copyright: swiss (https://knx-user-forum.de/members/swiss.html)
# Die Vorlage für die Datenübertragung via socat stammt von makki (https://knx-user-forum.de/members/makki.html)
# Aufbau möglichst so, dass man unterhalb der Einstellungen nichts verändern muss!
#
#
use Device::SerialPort;
####################
###Einstellungen:###
####################
#Zuordnung Steuerfunktionen zu den Gruppenadressen:
my $ga_stufeabwesend = '14/7/0'; #1bit Trigger für Stufe "Abwesend". 1=Aktivieren
my $ga_stufe1 = '14/7/1'; #1bit Trigger für Stufe1. 1=Aktivieren
my $ga_stufe2 = '14/7/2'; #1bit Trigger für Stufe2. 1=Aktivieren
my $ga_stufe3 = '14/7/3'; #1bit Trigger für Stufe3. 1=Aktivieren
#Zuordnung der Namen für die RRD's:
my $Name_rrd_AUL = 'KWL_Aussenluft'; #Name RRD Aussenluft
my $Name_rrd_ZUL = 'KWL_Zuluft'; #Name RRD Zuluft
my $Name_rrd_ABL = 'KWL_Abluft'; #Name RRD Abluft
my $Name_rrd_FOL = 'KWL_Fortluft'; #Name RRD Fortluft
#Pfand zur seriellen Schnittstelle oder dem USB-Seriell-Wandler:
my $schnittstelle = '/dev/usbserial-2-3';
######################
##ENDE Einstellungen##
######################
#Ab hier nichts mehr ändern.
#Hauptverarbeitung
my $return_value2;
my $daten;
my $reciv;
my $ack = pack("H*","07F3");
# Zyklischer Aufruf nach restart, empfang GA oder nach einstellung rrd (typisch 300sek).
$plugin_info{$plugname.'_cycle'} = $wg_config{''}{'rrd_interval'};
#Einrichten der Seriellen Schnittstelle für die Kommunikation mit dem ComfoAir
my $seriel = Device::SerialPort->new($schnittstelle) || die "Kann $schnittstelle nicht öffnen! ($!)\n";
$seriel->baudrate(9600);
$seriel->parity("none");
$seriel->databits(8);
$seriel->stopbits(1);
if ($msg{'apci'} eq "A_GroupValue_Write"){ #Wenn ein Telegramm vom KNX empfangenwird, ab hier auswerten
if ($msg{'dst'} eq $ga_stufeabwesend && knx_read($msg{'dst'},0,1) == 1) {
$daten = "00990101";
plugin_log($plugname,'Stufe abwesend');
$return_value2 = command_senden($daten);
}elsif ($msg{'dst'} eq $ga_stufe1 && knx_read($msg{'dst'},0,1) == 1) {
$daten = "00990102";
plugin_log($plugname,'Stufe 1');
$return_value2 = command_senden($daten);
}elsif ($msg{'dst'} eq $ga_stufe2 && knx_read($msg{'dst'},0,1) == 1) {
$daten = "00990103";
plugin_log($plugname,'Stufe 2');
$return_value2 = command_senden($daten);
}elsif ($msg{'dst'} eq $ga_stufe3 && knx_read($msg{'dst'},0,1) == 1) {
$daten = "00990104";
plugin_log($plugname,'Stufe 3');
$return_value2 = command_senden($daten);
}
return;
} else { # zyklischer Aufruf
# Plugin an Gruppenadresse "anmelden", hierdurch wird das Plugin im folgenden bei jedem eintreffen eines Telegramms auf die GA aufgerufen und der obere Teil dieser if-Schleife durchlaufen
$plugin_subscribe{$ga_stufeabwesend}{$plugname} = 1;
$plugin_subscribe{$ga_stufe1}{$plugname} = 1;
$plugin_subscribe{$ga_stufe2}{$plugname} = 1;
$plugin_subscribe{$ga_stufe3}{$plugname} = 1;
$daten = "000F00";
# plugin_log($plugname,'Temperatur abrufen');
return $return_value2 = command_senden($daten);
}
# Ab hier wird das Datenpaket inklusive Checksumme zusammengestellt und an die ComfoAir übertragen
sub command_senden{
my $checksum = 0;
my $data = $_[0];
my $datasum = $data . "AD"; #+173 für die Checksummenberechnung
my @hex = map { hex($_) } ($datasum =~ /(..)/g);
my $x07warschon = 0;
foreach (@hex) {
$checksum += ($_) unless $x07warschon; # unless ist dasselbe wie if not/!
if ($_ == 0x07) { $x07warschon = 1; }
}
$checksum = sprintf "%x\n" , $checksum; #Mache aus Integer wieder HEX
$checksum = substr($checksum,length($checksum)-3,2); #Verwede nur die letzten beiden stellen
my $command = pack("H*","07F0" . $data . $checksum . "070F");
$seriel->write($command); #Befehl an den ComfoAir senden
$|=1;
my $exit=0;
while($exit < 30000)
{
my ($cin, $sin) = $seriel->read(25);
if($cin > 0){
$sin = unpack "H*", $sin;
$reciv .= $sin;
$exit=0;
}else{
$exit++
}
if($reciv =~ /07f3/i){
# plugin_log($plugname,'reciv: ACK');
$reciv = '';
}
if($reciv =~ /070f/i){
# plugin_log($plugname,'reciv: ' . $reciv);
if($reciv =~ /07f0001004/i){ #Wenn die Temperaturen empfangen wurden
my $t1 = substr($reciv,10,2);
my $t2 = substr($reciv,12,2);
my $t3 = substr($reciv,14,2);
my $t4 = substr($reciv,16,2);
# plugin_log($plugname,'reciv: T1: ' . $t1 . ' T2:' . $t2 . ' T3: ' . $t3 . ' T4: ' . $t4);
$t1 = (hex($t1)/2)-20;
$t2 = (hex($t2)/2)-20;
$t3 = (hex($t3)/2)-20;
$t4 = (hex($t4)/2)-20;
update_rrd($Name_rrd_AUL,"",$t1);
update_rrd($Name_rrd_ZUL,"",$t2);
update_rrd($Name_rrd_ABL,"",$t3);
update_rrd($Name_rrd_FOL,"",$t4);
# plugin_log($plugname,'reciv: T1: ' . $t1 . '°C, T2:' . $t2 . '°C, T3: ' . $t3 . '°C, T4: ' . $t4 . '°C');
}
$seriel->write($ack); #ACK senden
last;
}
}
}



Klar könnte man Optionsschalter einführen, wo jeder sich seine Funktionen die er braucht aktivieren kann aber auch da treten wieder gewisse Probleme auf... Der Code wird noch mal eine ganze scheibe komplexer, länger und unübersichtilicher.
Es ist also im aktuellen Zustand eine Gratwanderung zwischen Performanc und Funktionsumfang.
Wir verarbeiten personenbezogene Daten über die Nutzer unserer Website mithilfe von Cookies und anderen Technologien, um unsere Dienste bereitzustellen. Weitere Informationen findest Du in unserer Datenschutzerklärung.
Indem Du unten auf "ICH stimme zu" klickst, stimmst Du unserer Datenschutzerklärung und unseren persönlichen Datenverarbeitungs- und Cookie-Praktiken zu, wie darin beschrieben. Du erkennst außerdem an, dass dieses Forum möglicherweise außerhalb Deines Landes gehostet wird und bist damit einverstanden, dass Deine Daten in dem Land, in dem dieses Forum gehostet wird, gesammelt, gespeichert und verarbeitet werden.


Kommentar