Erweiterung einer HMConfig_AskSinPPCustom.pm Datei für einen SDS011

Begonnen von ritchie, 02 Mai 2026, 20:07:57

Vorheriges Thema - Nächstes Thema

ritchie

Hallo Zusammen,

ich habe ein Board mit der Software "HB-UNI-Sen-DUST.ino" erstellt und im Debug Mode erscheinen auch die korrekten Werte:

ZitatPM25: 34
PM10: 113

Ich habe für die Einbindung die Datei "HMConfig_AskSinPPCustom.pm" und "HMMsg.pm" in FHEM eingebunden.

Ich habe in der Datei ""HMConfig_AskSinPPCustom.pm" folgende Definition eingefügt:

$HMConfig::culHmModel{"F314"} = {name  => "HB-UNI-Sen-DUST",st => "custom", cyc   => '',rxt   => '', lst   => '', chn   => "01" };
$customMsg{"HB-UNI-Sen-DUST"} = sub {
  my ($msg, $hash) = @_;

  main::Log 1,"HB-UNI-Sen-DUST Executed";

  my $pm25_avg = $msg->payloadWord(0) / 10;
  my $pm10_avg = $msg->payloadWord(2) / 10;
  my $pm25_max = $msg->payloadWord(4) / 10;
  my $pm10_max = $msg->payloadWord(6) / 10;
  my $pm25_min = $msg->payloadWord(8) / 10;
  my $pm10_min = $msg->payloadWord(10) / 10;

  my @evtEt=();
  my $device = main::CUL_HM_id2Hash($msg->from);

  push @evtEt,[$device,1,"pm10_min:".$pm10_min];
  push @evtEt,[$device,1,"pm10_avg:".$pm10_avg];
  push @evtEt,[$device,1,"pm10_max:".$pm10_max];
  push @evtEt,[$device,1,"pm25_min:".$pm25_min];
  push @evtEt,[$device,1,"pm25_avg:".$pm25_avg];
  push @evtEt,[$device,1,"pm25_max:".$pm25_max];

  return @evtEt;
};

Wenn die das Teil mit Pairing in FHEM einbinde, bekomme ich das Teil auch in FHEM zu sehen.
Wenn ich dann aber getConfig() mache, bekomme ich nicht die entsprechen Register für die Messwerte zu sehen.

Du darfst diesen Dateianhang nicht ansehen.

Ebenso sehe ich im Logfile keinen Eintrag "HB-UNI-Sen-DUST Executed" der mir sagen würde, das meine Erweiterung überhaupt
durchlaufen wird.

Kennt sich jemand mit der Erweiterung der "HMConfig_AskSinPPCustom.pm" aus und kann mir sagen, wo mein Fehler ist.

Viele Grüße
R.
IPU662  IPFIRE & FHEM (Homematic + MAX) - Produktiv
Intel iCore 3 / 16GBRAM / 500GB SSD / Ubuntu  (1Wire - USB) - Produktiv

ritchie

Hi,

erste Fehler behoben. Ich bekomme jetzt auch die korrekten Eigenschaften. Muss das aber noch genau prüfen.
Zugriffsberechtigung waren unter anderem falsch.

Viele Grüße
R.
IPU662  IPFIRE & FHEM (Homematic + MAX) - Produktiv
Intel iCore 3 / 16GBRAM / 500GB SSD / Ubuntu  (1Wire - USB) - Produktiv

papa

Hi.

Gut das Du Dir erst mal selber helfen konntest. Das ist aber alles schon ganz schön lange her. Aber wenn es noch probleme gibt, werde ich versuchen zu helfen.
BananaPi + CUL868 + CUL433 + HM-UART + 1Wire

ritchie

Hi,

habe dann in der Nacht so viel geändert, das es morgens plötzlich nicht mehr lief.
So muss ich das ganze jetzt nochmals von vorne machen.
Kein Problem. Das Problem liegt wohl zwischen meinen Ohren ;-)

Viele Grüße
R.
IPU662  IPFIRE & FHEM (Homematic + MAX) - Produktiv
Intel iCore 3 / 16GBRAM / 500GB SSD / Ubuntu  (1Wire - USB) - Produktiv

ritchie

Hallo papa,

ich muss nochmals auf hoffentlich Dein gutes Gedächnis zurückgreifen. Ich versuche nochmals einen Anlauf.
Ich habe jetzt auch Chat GPT dazu einiges gefragt, bin mir aber nicht sicher, ob das alles stimmt, was von da kommt.
Hier mein Code:

$HMConfig::culHmModel{"F314"} = {name  => "HB-UNI-Sen-DUST",st => "custom", cyc  => '',rxt  => '', lst  => '', chn  => "01" };
# Nicht "$customMsg{"HB-UNI-Sen-DUST"}
$customMsg{"F314"} = sub {
  my ($msg, $hash) = @_;

  main::Log 1,"HB-UNI-Sen-DUST Executed";

  return () unless $msg->isValues;    # Remark from chatgpt

  my $pm25_avg = $msg->payloadWord(0) / 10;
  my $pm10_avg = $msg->payloadWord(2) / 10;
  my $pm25_max = $msg->payloadWord(4) / 10;
  my $pm10_max = $msg->payloadWord(6) / 10;
  my $pm25_min = $msg->payloadWord(8) / 10;
  my $pm10_min = $msg->payloadWord(10) / 10;

  my @evtEt=();
  my $device = main::CUL_HM_id2Hash($msg->from); 
  push @evtEt,[$device,1,"pm10_min:".$pm10_min];
  push @evtEt,[$device,1,"pm10_avg:".$pm10_avg];
  push @evtEt,[$device,1,"pm10_max:".$pm10_max];
  push @evtEt,[$device,1,"pm25_min:".$pm25_min];
  push @evtEt,[$device,1,"pm25_avg:".$pm25_avg];
  push @evtEt,[$device,1,"pm25_max:".$pm25_max];
 
  return @evtEt;
};

Hierzu hätte ich folgende Fragen.

- Muss in $CustomMsg die DeviceID also "F314" stehen oder der der Devicename "HB-UNI-Sen-DUST".
  Chatgpt meint, das der Aufruf über die ID erfolgt. Wenn ich mir jedoch andere Definitionen
  in der Datei ansehen, scheint das nicht zu stimmen, da hier der Devicename steht.

- Die Zeile "return () unless $msg->isValues;" hat mir Chatgpt empfohlen. Wäre die O.k.

- Muss ich die Datei "10_CUL_HM.pm" entsprechend erweitern ?
  Das Modul wird geladen, aber ich erhalte nie die Meldung ""HB-UNI-Sen-DUST Executed".

- Gibt es eine Erklärung, was genau in der Definition von
  $HMConfig::culHmModel{"F314"} = {name  => "HB-UNI-Sen-DUST",st => "custom", cyc  => '',rxt  => '', lst  => '', chn  => "01" }; 
Stehen muss, damit ich prüfen kann, ob meine Definition stimmt.

In meinem Device steht derzeit
// define all device properties
const struct DeviceInfo PROGMEM devinfo = {
  {0xF3, 0x14, 0x01},          // Device ID
  "JPDUST0001",                // Device Serial
  {0xF3, 0x14},                // Device Model
  0x10,                        // Firmware Version
  0x53,    // Device Type 0x53 oder as::DeviceType::THSensor
  {0x01, 0x01}                // Info Bytes
};

Viele Grüße
R.
IPU662  IPFIRE & FHEM (Homematic + MAX) - Produktiv
Intel iCore 3 / 16GBRAM / 500GB SSD / Ubuntu  (1Wire - USB) - Produktiv

ritchie

Hallo Zusammen,

nach einigen Tests und Änderungen der Datei "HMConfig_AskSinPPCustom.pm" habe ich jetzt zumindestens einen stabile Anzeige der Eigenschaften in FHEM. Leider immer noch nicht die gewünschten Eigenschaften von PM25 und PM10.

Hier wird als Model jetzt korrekt der "HB-UNI-Sen-DUST" auch nach dem getConfig angezeigt.
Du darfst diesen Dateianhang nicht ansehen.
Hier jetzt der aktuelle Ausschnitt der "HMConfig_AskSinPPCustom.pm" für mein Device:

$HMConfig::culHmModel{"F314"} = {name  => "HB-UNI-Sen-DUST",st => "custom", cyc=>'00:10',rxt   => '', lst   => '', chn=>"value:1:1" };
$HMConfig::culHmRegChan{"F31401"} = $HMConfig::culHmRegType{custom_dimmer};
$HMConfig::culHmChanSets{"F31401"} = "";
$HMConfig::culHmRegDefine{"F31401"} = {};

# Nicht "$customMsg{"HB-UNI-Sen-DUST"}

$customMsg{"F314"} = sub {
  my ($msg, $hash) = @_;

main::Log 1,"HB-UNI-Sen-DUST Executed";   

  my $pm25_avg = $msg->payloadWord(0) / 10;
  my $pm10_avg = $msg->payloadWord(1) / 10;
  my $pm25_max = $msg->payloadWord(2) / 10;
  my $pm10_max = $msg->payloadWord(3) / 10;
  my $pm25_min = $msg->payloadWord(4) / 10;
  my $pm10_min = $msg->payloadWord(5) / 10;

  my @evtEt=();
  my $device = main::CUL_HM_id2Hash($msg->from); 
  push @evtEt,[$device,1,"pm10_min:".$pm10_min];
  push @evtEt,[$device,1,"pm10_avg:".$pm10_avg];
  push @evtEt,[$device,1,"pm10_max:".$pm10_max];
  push @evtEt,[$device,1,"pm25_min:".$pm25_min];
  push @evtEt,[$device,1,"pm25_avg:".$pm25_avg];
  push @evtEt,[$device,1,"pm25_max:".$pm25_max];
 
  return @evtEt;
};

# -------

sub HMConfig_AskSinPPCustom_Initialize ($) {
  main::Log 1,"Rerun Literal reverse mapping";
  foreach my $rN  (keys %HMConfig::culHmRegDefine){ #create literal inverse for fast search
    if ($HMConfig::culHmRegDefine{$rN}{lit}){# literal assigned => create inverse
      foreach my $lit (keys %{$HMConfig::culHmRegDefine{$rN}{lit}}){
        $HMConfig::culHmRegDefine{$rN}{litInv}{$HMConfig::culHmRegDefine{$rN}{lit}{$lit}}=$lit;
      }
    }
  }
};

$main::modules{HMConfig_AskSinPPCustom}{Initialize} = \&HMConfig_AskSinPPCustom_Initialize;

Einige Codeänderungen habe ich mit Hilfe von Chatgpt vorgenommen, damit die perl-Fehler des
Moduls im Logfile nicht mehr auftauchen.

Generell wird jedoch die Init-Routine des perl-Moduls und die CustomMsg nicht durchlaufen.
Chatgpt ist der festen Auffassung das hier der Eintrag "$customMsg{"F314"}" zu verwenden ist,
jedoch verwenden alle anderen Homebrew Einträge den jeweiligen Modulname "$customMsg{"HB-UNI-Sen-DUST"}"

Das muss ich noch weiter austesten.

Seltsam ist auch, das laut Aussage von Chatgpt das Pairing nicht korrekt abgeschlossen sein soll,
da in der Eigenschaft "cfgState" noch "Updating" steht. Ich habe noch Fensterkontakte, welche ich mit SinAsk
umgebaut habe, welche korrekt laufen und auch im "cfgState" noch "Updating" stehen haben.

Hier chn=>"value:1:1"  muss wohl Anfangs und EndChannel stehen, Wobei ich den "Channelname" hier mal mit Value belegt habe, wie ich Ihn bei anderen Einträgen auch gesehen habe.

Ich bekomme aber im FHEM nach dem Pairing immer noch diese Fehlermeldungen

2026.05.10 09:44:20 1: PERL WARNING: Use of uninitialized value in string comparison (cmp) at /opt/fhem/FHEM/10_CUL_HM.pm line 4596.
2026.05.10 09:44:20 1: PERL WARNING: Use of uninitialized value in string ne at /opt/fhem/FHEM/10_CUL_HM.pm line 4604.
2026.05.10 09:44:20 1: PERL WARNING: Use of uninitialized value $h in string ne at /opt/fhem/FHEM/10_CUL_HM.pm line 4604.

Viele Grüße
R.



IPU662  IPFIRE & FHEM (Homematic + MAX) - Produktiv
Intel iCore 3 / 16GBRAM / 500GB SSD / Ubuntu  (1Wire - USB) - Produktiv

papa

Ich nehme mal an, dass deine Eigenentwicklung im wesentlichen auf dem HB-GEN-SENS basiert - also nur einen Channel hat und dort die Werte entsprechend sendet. Somit muss auch das Device für FHEM auf den HB-GEN-SENS aufsetzen. Probiere mal folgendes:

$HMConfig::culHmModel{"F314"} = {name  => "HB-UNI-Sen-DUST",st=>'custom',cyc=>'',rxt=>'c',lst=>'1',chn=>"Values:1:1"};
$HMConfig::culHmChanSets{"HB-UNI-Sen-DUST00"}{fwUpdate} = "<filename>";
$HMConfig::culHmChanSets{"HB-UNI-Sen-DUST01"} = $HMConfig::culHmSubTypeSets{"Values"};
$HMConfig::culHmRegChan {"HB-UNI-Sen-DUST01"} = $HMConfig::culHmRegType{values};
$customMsg{"HB-UNI-Sen-DUST"} = sub {
  my ($msg, $hash) = @_;
  my @evtEt=();

  main::Log 1,"HB-UNI-Sen-DUST Executed";

  if( $msg->isValues ) {
    my $pm25_avg = $msg->payloadWord(0) / 10;
    my $pm10_avg = $msg->payloadWord(2) / 10;
    my $pm25_max = $msg->payloadWord(4) / 10;
    my $pm10_max = $msg->payloadWord(6) / 10;
    my $pm25_min = $msg->payloadWord(8) / 10;
    my $pm10_min = $msg->payloadWord(10) / 10;

    my $device = main::CUL_HM_id2Hash($msg->from);
    push @evtEt,[$device,1,"pm10_min:".$pm10_min];
    push @evtEt,[$device,1,"pm10_avg:".$pm10_avg];
    push @evtEt,[$device,1,"pm10_max:".$pm10_max];
    push @evtEt,[$device,1,"pm25_min:".$pm25_min];
    push @evtEt,[$device,1,"pm25_avg:".$pm25_avg];
    push @evtEt,[$device,1,"pm25_max:".$pm25_max];
  }
  return @evtEt;
};

Du könntest aber auch gleich den HB-GEN-SENS nutzen und nur das "valuesformat" entsprechend setzen:
2:pm25_avg:10 2:pm10_avg:10 2:pm25_max:10 2:pm10_max:10 2:pm25_min:10 2:pm10_min:10
https://github.com/pa-pa/AskSinPP/blob/master/examples/custom/HB-GEN-SENS/HB-GEN-SENS.ino

Details gibt es hier: https://forum.fhem.de/index.php?topic=57486.825
BananaPi + CUL868 + CUL433 + HM-UART + 1Wire

ritchie

Hi,

da ich keinen Eintrag im FHEM log habe, welcher ""HB-UNI-Sen-DUST Executed" heisst,
vermute ich, das etwas anderes nicht arbeitet.

Ich habe den Code von hier übernommen: https://github.com/jp112sdl/HB-UNI-Sen-DUST
Ebenso den Aufbau. Daher weiss ich nicht, ob der HB-GEN-SENS als Basis verwendet wurde.

Ich schaue mir jetzt mal den Code an und lade Ihn testweise (ohne Sensoren), da sollte dann doch wenigstens
FHEM den Typ richtig einbindet.

Viele Grüße
R.
IPU662  IPFIRE & FHEM (Homematic + MAX) - Produktiv
Intel iCore 3 / 16GBRAM / 500GB SSD / Ubuntu  (1Wire - USB) - Produktiv

papa

Bist Du Dir denn sicher, dass auch was gesendet wird ? Du müsstest laut dem Sketch folgende Ausgaben in der seriellen Konsole haben:

pm25avg: XXX, pm10avg: YYY
pm25max: ZZZ, pm10max: AAAA
pm25min: BBB, pm10min: CCC

Er sendet auch nicht gleich - sondern macht erst ein paar Messungen.
BananaPi + CUL868 + CUL433 + HM-UART + 1Wire

ritchie

Hi,

gerade nochmals ausprobiert.

Hier der Log aus dem Device:
16:33:28.140 -> PM25: 23
16:33:28.140 -> PM10: 61
16:33:38.176 -> MEASURE... #17
16:33:38.176 -> PM25: 23
16:33:38.209 -> PM10: 61
16:33:48.240 -> MEASURE... #18
16:33:48.240 -> PM25: 23
16:33:48.240 -> PM10: 62
16:33:48.240 -> pm25avg: 25, pm10avg: 25
16:33:48.240 -> pm25max: 28, pm10max: 28
16:33:48.273 -> pm25min: 23, pm10min: 23
16:33:48.273 -> <- 17 02 86 53 F31401 000000 01 00 00 19 00 36 00 1C 00 41 00 17 00 2A  - 183891
16:33:58.337 -> MEASURE... #1
16:33:58.337 -> FAIL - retry #1
16:33:59.430 -> FAIL - retry #2
16:34:00.655 -> FAIL - retry #3
16:34:01.913 -> FAIL - giving up
16:34:11.946 -> MEASURE... #2
Dieser Eintrag ist in der Zeit, wo ich diesen Text geschrieben habe, noch mehrfach aufgetreten. Ohne Eintrag im Log und Eigenschaften.

Hier der FHEM Log:

2026.05.13 16:32:36 1: RMDIR: /opt/fhem/restoreDir/save/2026-05-09
2026.05.13 16:33:20 1: PERL WARNING: Use of uninitialized value in string comparison (cmp) at /opt/fhem/FHEM/10_CUL_HM.pm line 4596.
2026.05.13 16:33:20 1: PERL WARNING: Use of uninitialized value in string ne at /opt/fhem/FHEM/10_CUL_HM.pm line 4604.
2026.05.13 16:33:20 1: PERL WARNING: Use of uninitialized value $h in string ne at /opt/fhem/FHEM/10_CUL_HM.pm line 4604.
Danach leider kein weiterer Eintrag.

Und hier die aktuellen Eigenschaften in FHEM für das Device:
Du darfst diesen Dateianhang nicht ansehen.

Leider weder ein Eintrag aus dem Log der msgCustom Routine, noch die erwarteten Eigenschaften.

Ich vermute das es an der Einbindung der Datei liegt. Diese wird aber korrekt geladen, was ich durch einen Diagnose-
eintrag geprüft habe. Nur wird irgendwie diese Routine einfach nicht durchlaufen:

Diese Routine sollte einen Logeintrag erzeugen:
$customMsg{"HB-UNI-Sen-DUST"} = sub {
  my ($msg, $hash) = @_;
 
 my @evtEt=();
 
main::Log 1,"HB-UNI-Sen-DUST Executed";   

if( $msg->isValues ) {
    my $pm25_avg = $msg->payloadWord(0) / 10;
    my $pm10_avg = $msg->payloadWord(2) / 10;
    my $pm25_max = $msg->payloadWord(4) / 10;
    my $pm10_max = $msg->payloadWord(6) / 10;
    my $pm25_min = $msg->payloadWord(8) / 10;
    my $pm10_min = $msg->payloadWord(10) / 10;

    my $device = main::CUL_HM_id2Hash($msg->from); 
    push @evtEt,[$device,1,"pm10_min:".$pm10_min];
    push @evtEt,[$device,1,"pm10_avg:".$pm10_avg];
    push @evtEt,[$device,1,"pm10_max:".$pm10_max];
    push @evtEt,[$device,1,"pm25_min:".$pm25_min];
    push @evtEt,[$device,1,"pm25_avg:".$pm25_avg];
    push @evtEt,[$device,1,"pm25_max:".$pm25_max];
  }
  return @evtEt;
};

Auch wird diese Routine nicht durchlaufen, da sie auch einen Log erzeugen würde:
sub HMConfig_AskSinPPCustom_Initialize ($) {
  main::Log 1,"Rerun Literal reverse mapping";
  foreach my $rN  (keys %HMConfig::culHmRegDefine){ #create literal inverse for fast search
    if ($HMConfig::culHmRegDefine{$rN}{lit}){# literal assigned => create inverse
      foreach my $lit (keys %{$HMConfig::culHmRegDefine{$rN}{lit}}){
        $HMConfig::culHmRegDefine{$rN}{litInv}{$HMConfig::culHmRegDefine{$rN}{lit}{$lit}}=$lit;
      }
    }
  }
};

Ich habe auf anraten von Google, diesen Eintrag eingefügt in die Datei:
$main::modules{HMConfig_AskSinPPCustom}{Initialize} = \&HMConfig_AskSinPPCustom_Initialize;

Hat aber auch nicht geholfen.

Alle Beschreibungen sagen, das ich diese Datei und die HMMSgs.pm in das FHEM Verzeichnis einfügen soll.
package HMMsg;

use strict;
use warnings;

#main::Log 1, "HMMSG: ICH WERDE GELADEN";

sub new {
  my $class = shift;
  my $self = { _type => hex(shift),
               _flags => hex(shift),
               _from => shift,
               _to => shift,
               _payload => shift  };
  bless $self, $class;
  return $self;
}

# print the message
sub print {
  my ($self) = @_;
  print $self->{_type}." ".$self->{_flags}." ".$self->{_from}." ".$self->{_to}." ".$self->{_payload}."\n";
}
# payload
# payload OFFSET
# payload OFFSET,LENGTH
sub payload {
  my ($self,$offset,$length) = @_;
  return substr($self->{_payload},$offset,$length) if defined($length);
  return substr($self->{_payload},$offset) if defined($offset);
  return $self->{_payload};
}
# payloadByte OFFSET
sub payloadByte {
  my ($self,$offset) = @_;
  return hex($self->payload($offset*2,2));
}
# payloadWord OFFSET
sub payloadWord {
  my ($self,$offset) = @_;
  return hex($self->payload($offset*2,4));
}
# payload3Byte OFFSET
sub payload3Byte {
  my ($self,$offset) = @_;
  return hex($self->payload($offset*2,6));
}
# payloadLong OFFSET
sub payloadLong {
  my ($self,$offset) = @_;
  return hex($self->payload($offset*2,8));
}
sub from {
  my ($self) = @_;
  return $self->{_from};
}
sub to {
  my ($self) = @_;
  return $self->{_to};
}
sub flags {
  my ($self) = @_;
  return $self->{_flags};
}
sub type {
  my ($self) = @_;
  return $self->{_type};
}

sub isStatus {
  my ($self) = @_;
  my $byte0 = $self->payloadByte(0);
  return ($self->type == 0x2 && $byte0 == 0x1) || ($self->type == 0x10 && $byte0 == 0x6);
}
sub isSensor {
  my ($self) = @_;
  return $self->type == 0x41; 
}
sub isRemote {
  my ($self) = @_;
  return $self->type == 0x40; 
}
sub isValues {
  my ($self) = @_;
  return $self->type == 0x53;
}
sub isWeather {
  my ($self) = @_;
  return $self->type == 0x70;
}

sub isRemoteLong {
  my ($self) = @_;
  return $self->payloadByte(0) & 0x40;
}
sub isRemoteLowBat {
  my ($self) = @_;
  return $self->payloadByte(0) & 0x80;
}

sub channel {
  my ($self) = @_;
  my $chn;
  if( $self->isStatus ) {
    $chn = $self->payloadByte(1)
  }
  else {
    $chn = $self->payloadByte(0);
  }
  return ($chn & 0x3f);
}

sub channelId {
  my ($self,$cnum) = @_;
  if( ! defined($cnum) ) {
    $cnum = $self->channel;
  }
  return $self->from . sprintf("%02X",$cnum);
}
 
sub processSwitchStatus {
  my ($self,$target) = @_;
  my @evtEt=();
  my $channel = $main::modules{CUL_HM}{defptr}{$self->channelId};
  if( defined($channel) ) {
    my $value = $self->payloadByte(2)/2;
    my $flags = $self->payloadByte(3);
    my $valuestr = "$value %";
    $valuestr = "on"  if $value==100;
    $valuestr = "off" if $value==0;

    push @evtEt,[$channel,1,"level:$value %"];
    push @evtEt,[$channel,1,"pct:$value"];     # duplicate to level - necessary for "slider"
    push @evtEt,[$channel,1,"deviceMsg:$valuestr$target"];
    push @evtEt,[$channel,1,"state:".$valuestr];
    push @evtEt,[$channel,1,"timedOn:".(($flags & 0x40)?"running":"off")];
  }
#  else {
#    main::Log 1,"No object for ".$self->channelId;
#  }
  return @evtEt;
}

sub processBlindStatus {
  my ($self,$target,$channel) = @_;
  my @evtEt=();
  # no channel given - calc channel
  if( ! defined($channel) ) {
    $channel = $main::modules{CUL_HM}{defptr}{$self->channelId};
  }
  if( defined($channel) ) {
    my $value = $self->payloadByte(2)/2;
    # invert value if requested
    if (main::AttrVal($channel->{NAME},"param","") =~ m/levelInverse/) {
        $value = 100-$value;
    }
    my $flags = $self->payloadByte(3);
    my $valuestr = "$value %";
    $valuestr = "on"  if $value==100;
    $valuestr = "off" if $value==0;
    my $dir = ($flags >> 4) & 3;
    my %dirName = ( 0=>"stop" ,1=>"up" ,2=>"down" ,3=>"err" );
    push @evtEt,[$channel,1,"level:$value"];
    push @evtEt,[$channel,1,"motor:$dirName{$dir}:$valuestr"];
    push @evtEt,[$channel,1,"pct:$value"];     # duplicate to level - necessary for "slider"
    push @evtEt,[$channel,1,"deviceMsg:$valuestr$target"];
    push @evtEt,[$channel,1,"state:".$valuestr];
    push @evtEt,[$channel,1,"timedOn:".(($flags & 0x40)?"running":"off")];
  }
#  else {
#    main::Log 1,"No object for ".$self->channelId;
#  }
  return @evtEt;
}

sub processMotion {
  my ($self,$target) = @_;
  my @evtEt=();
  my $channel = $main::modules{CUL_HM}{defptr}{$self->channelId};
  if( defined($channel) ) {
  if( $self->isStatus ) {
      my $bright = $self->payloadByte(2);
      push @evtEt,[$channel,1,"brightness:$bright"];
  }
  if( $self->isSensor ) {
      my $cnt = $self->payloadByte(1);
      my $bright = $self->payloadByte(2);
      my $next = $self->payloadByte(3);
      if( $next ) {
        my $stamp =  ::gettimeofday(); # take reception time;
        $next = (15 << ($next >> 4) - 4); # strange mapping of literals
        main::RemoveInternalTimer($channel->{NAME}.":motionCheck");
        main::InternalTimer($stamp+$next+2,"CUL_HM_motionCheck", $channel->{NAME}.":motionCheck", 0);
        $channel->{helper}{moStart} = $stamp if (!defined $channel->{helper}{moStart});
      }
      else {
        $next = "none";
      }
      push @evtEt,[$channel,1,"state:motion"];
      push @evtEt,[$channel,1,"motion:on$target"];
      push @evtEt,[$channel,1,"motionCount:$cnt"."_next:$next"."s"];
      push @evtEt,[$channel,1,"brightness:$bright"];
  }
  }
#  else {
#    main::Log 1,"No object for ".$self->channelId;
#  }
  return @evtEt;
}

sub processRemote {
  my ($self,$target) = @_;
  my @evtEt=();
  my $device = main::CUL_HM_id2Hash($self->from);
  my $channel = $main::modules{CUL_HM}{defptr}{$self->channelId};
  my $bno = $self->payloadByte(1);
  if( defined($channel) ) {
    my $state = "Short";
    my $trigType = "Short";
    my $btnName = $channel->{NAME};
    if( $self->isRemoteLong ) {
      if(!$device->{BNO} || $device->{BNO} ne $bno) { #bno = event counter
        $device->{BNO} = $bno;
        $device->{BNOCNT} = 0; # message counter reest
      }
      $device->{BNOCNT} += 1;
      $state = "Long" .(($self->flags & 0x24)==0x20 ? "Release" : "")." ".$device->{BNOCNT};
      $trigType = "Long";
    }
    $device->{helper}{addVal} = $self->payloadByte(0);   #store to handle changesFread
    push @evtEt,[$channel,1,"state:".$state.$target];
    push @evtEt,[$channel,1,"trigger:".$trigType."_".$bno];
    push @evtEt,[$device,1,"state:$btnName $state$target"];
  }
#  else {
#    main::Log 1,"No object for ".$self->channelId;
#  }
  return @evtEt;
}

sub processThreeState {
  my ($self,$target,%mapping) = @_;
  my @evtEt=();
  my $channel = $main::modules{CUL_HM}{defptr}{$self->channelId};
  if( ! defined($channel) ) {
  # fallback to device
  $channel = main::CUL_HM_id2Hash($self->from);
  }
  if( ! %mapping ) {
    %mapping = (0=>'closed',100=>'tilted',200=>'open');
  }
  my $val = $self->payloadByte(2);
  if( defined($channel) ) {
    my $vs = $val/2;
    $vs = $mapping{$val} if defined $mapping{$val};
    push @evtEt,[$channel,1,"state:".$vs];
    push @evtEt,[$channel,1,"contact:$vs$target"];
  }
#  else {
#    main::Log 1,"No object for ".$self->channelId;
#  }
  return @evtEt;
}

sub parseValueFormat {
  my @v;
  foreach my $value ( split / /,$_[0] ) {
    #print $value."\n";
    my @parts = split /:/,$value;
    my $valuedata = {};
    my $numb = $parts[0];
    $numb =~ s/([1,2,4,8])s?/$1/g;
    $valuedata->{'numbytes'} = $numb;
    $valuedata->{'signed'} = $parts[0] =~ m/([1,2,4,8])s/;
    $valuedata->{'reading'} = "value".scalar @v + 1;
    $valuedata->{'factor'} = 1;
    if( defined $parts[1] ) { $valuedata->{'reading'} = $parts[1]; }
    if( defined $parts[2] ) { $valuedata->{'factor'} = $parts[2]; }
    push @v, $valuedata;
  }
  return @v;
}

sub processValues {
  my ($self,$target) = @_;
  my @evtEt=();
  my $channel = $main::modules{CUL_HM}{defptr}{$self->channelId};
  my $numval = $self->payloadByte(1); # get number of values from message
  my $values = $self->payload(4);     # values starting at byte 4

  my $vfmt = main::AttrVal($channel->{NAME},"valuesformat","");
  # Log 1,$vfmt;
  if( $vfmt eq "" ) {
    main::Log3 $channel->{NAME}, 1, "Missing attribute valuesformat at $channel->{NAME}";
    for( my $i=0; $i<$numval; ++$i ) {
      $vfmt = $vfmt."1 ";
    }
  }
  my @valuesfmt = parseValueFormat($vfmt);
  my $fmtnumval = scalar(@valuesfmt);
  if( $numval != $fmtnumval ) {
    main::Log3 $channel->{NAME}, 1, "Attribute valuesformat mismatch at $channel->{NAME} - expected $numval items but got $fmtnumval items";
  }
  my $packstr = "";
  my $state = "";
  foreach my $data (@valuesfmt) {
    #Log 1, $data->{'numbytes'}."  ".$data->{'signed'}."  ".$data->{'reading'}."  ".$data->{'factor'}."\n";
    $packstr = $packstr."A".($data->{'numbytes'}*2);
  }
  #print $packstr."\n";
  my @unpacked = map{hex($_)} unpack($packstr,$values);
  #print "$unpacked[0] $unpacked[1] $unpacked[2] $unpacked[3]\n";
  my $num = 0;
  foreach my $data (@valuesfmt) {
    my $val = $unpacked[$num++];
    if( $data->{'signed'} ) {
      my $max =  0x01 << (8*$data->{'numbytes'});
      my $mask = $max >> 1;
      $val = ($val & $mask) ? ($val - $max) : $val;
    }
    $val /= $data->{'factor'};
    # print $data->{'reading'}." : ".$val."\n";
    push @evtEt,[$channel,1,$data->{'reading'}.":".$val];
    $state = $state.$val." ";
  }
  push @evtEt,[$channel,1,"state:".$state];
  return @evtEt;
}

sub ::HMMsg_Initialize {}
 
1;

Im Header von der Datei "HMConfig_AskSinPPCustom" habe ich folgende Änderungen gemacht, damit diese Datei fehlerfrei geladen wird.

package main;

use lib '/opt/fhem/FHEM';
package HMConfig_AskSinPPCustom;

use strict;
use warnings;
use HMMsg;

Viele Grüße
R.
IPU662  IPFIRE & FHEM (Homematic + MAX) - Produktiv
Intel iCore 3 / 16GBRAM / 500GB SSD / Ubuntu  (1Wire - USB) - Produktiv