Neueste Beiträge

#91
Homematic / Aw: Ersatz für defekten HM-LGW...
Letzter Beitrag von bommel-bs - 13 Mai 2026, 18:36:34
Hallo tndx,
nach dem ich im Wiki gelesen habe, werde ich mir wohl ein HM-MOD-RPI-PCB auf einem zweiten Raspi zulegen. Den kann ich dann unabhängig vom FHEM Raspi plazieren.

Danke
Stefan
#92
Solaranlagen / Aw: 76_SolarForecast - Informa...
Letzter Beitrag von 300P - 13 Mai 2026, 18:30:10
Zitat von: lorisurfen am 13 Mai 2026, 16:43:30In dem Bsp. sollen bei 7kw Gesamtüberschuss alle consumer ein sein.

Meine Auslegung der bestehenden Regelung bei Nutzung Prioritätszahlen:

Bei mehr als 7 kW Gesamtüberschuß (+ alle anderen Rahmenbedingungen die dabei gelten) wird sich auch der große (3.000 W Leistung) am Ende einschalten "müssen".



Aber die Logik mit den Prioritäten sieht halt zuerst mehr als 1.000 W PV-Überschuss
Ab jetzt würde Consumer02 mit Prio 50 und seinen 1.000 W eingeschaltet am frühen Morgen

Etwas später sind wieder mehr als 1.000 W PV-Überschuß "frei" (insgesamt jetzt mehr als 2.000 W)
Ab jetzt würde Consumer03 mit Prio 50 und seinen 1.000 W eingeschaltet (Consumer02 bleibt ja an)

Wieder etwas später sind wieder mehr als 1.000 W PV-Überschuß "frei" (insgesamt mehr als 3.000 W)
Nun würde Consumer04 mit Prio 50 und seinen 1.000 W eingeschaltet (Consumer02 und Consumer03 bleiben weiter an)

Zu guter letzt - wieder etwas später - sind wieder mehr als 1.000 W PV-Überschuß "frei" (insgesamt mehr als 4.000 W)
Nun würde Consumer05 mit Prio 50 und seinen 1.000 W eingeschaltet (Consumer02,Consumer03 und Consumer04 bleiben auch weiter an)


Jetzt muss Consumer01 (trotz Prio 100) leider weiterhin weiter warten bis das wieder mehr als weitere 3.000 W an PV-Überschuss anfallen, denn vorher kommt er nicht infrage auf ON geschaltet zu werden.

Grund:
Es gibt keinen Parameter der die anderen 4 ConsumerXX ausschalten würde, damit der eine andere Consumer01 angeht !! ;)
Wenn überhaupt, dann müsste das evtl. durch ein geschickte Logik per Code in "ctrlUserExitFn {<Code>}" deinerseits geregelt werden.
Ansonsten sehe ich m.W.n. im Augenblick keine Standartlösung dafür in SF.
#93
Multimedia / Aw: Bose und soundcork und FHE...
Letzter Beitrag von MIla1969 - 13 Mai 2026, 18:29:57
Zitat von: betateilchen am 12 Mai 2026, 22:08:59Die DeviceInfo.xml gibt es nicht als Datei auf dem Gerät.



War ein etwas längerer Kampf. Hab ja zwei von den ST10sm2.
Beide spielen nun auch Web-Radio, obwohl eine zickiger war. Hatte bei dieser zuvor ein Werksreset gemacht gemacht.

Abe rläuft nun mit soundcork, es werden beide gesehen, Preset direk tüber FB gehen auch.....
#94
Homematic / Aw: Ersatz für defekten HM-LGW...
Letzter Beitrag von tndx - 13 Mai 2026, 18:05:24
Du kannst halt das klassische HM-MOD-RPI-PCB auf GPIO-Leiste nutzen, oder per Adapter über WLAN/LAN/USB, s. auch Wiki. Außerdem lässt sich auch eine CCU2 zu HM-Funk-LAN-Gateway umflashen, und die gibt es genug gebraucht zu kaufen, z.T. schon fertig umgeflasht.
#95
Automatisierung / Aw: Frage zum überarbeiteten M...
Letzter Beitrag von rabehd - 13 Mai 2026, 17:17:51
Mein Verständnis und meine Erfahrung:
Was bisher ging, geht immer noch.
Es gibt eine erweiterte Funktionalität, die Du zukünftig nutzen kannst.
Schau Dir das mal an und überlege wo Du es bei bestehenden Device nutzen kannst.
#96
Automatisierung / Frage zum überarbeiteten Modul...
Letzter Beitrag von piet_pit - 13 Mai 2026, 17:09:48
Hallo Zusammen,
ich nutze ja "readingsproxy" für meinen Shelly ProDualCover PM, damit ich die beiden virtuellen Kanäle ansteuern und auch das Modul "AutoShuttersControl" nutzen kann und habe jetzt erst gelesen (wegen Urlaub), dass das Modul überarbeitet wurde.

Muss ich etwas tun, um das neue Modul zu testen oder wird das automatisch für meine bestehende Konfiguration eingesetzt?

Viele Grüße
Pit
#97
Solaranlagen / Aw: 76_SolarForecast - Informa...
Letzter Beitrag von Gisbert - 13 Mai 2026, 17:00:38
Hallo Heiko,

bei Sonne/Wolken-Wechsel und den damit sich stark ändernden Einspeisungen kommt es immer zu scheinbar hohen Haus-Verbäuchen im Flussdiagramm, die aber i.d.R. nur einige 100 W betragen.
Was kann man dagegen tun? Vom meinem Deye-Wechselrichter bekomme ich sowohl den Gesamt- als auch den Tagesverbrauch sowie die Leistung zur Verfügung gestellt. Gibt es dafür Eingabemöglichkeiten bei deinem Modul?

Viele Grüße Gisbert
#98
Homematic / Aw: Erweiterung einer HMConfig...
Letzter Beitrag von ritchie - 13 Mai 2026, 16:53:28
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.
#99
Solaranlagen / Aw: 76_SolarForecast - Informa...
Letzter Beitrag von lorisurfen - 13 Mai 2026, 16:43:30
Zitat von: 300P am 13 Mai 2026, 15:36:38Läuft das ganze in einer Consumer-,,exclgroup" oder einfach nur als einzelne ConsumerXX ?
Einfach nur einzelne consumerXX, hat nichts mit "exclgroup" zu tun.
In dem Bsp. sollen bei 7kw Gesamtüberschuss alle consumer ein sein.
#100
Solaranlagen / Aw: 76_SolarForecast - Informa...
Letzter Beitrag von 300P - 13 Mai 2026, 15:36:38
Läuft das ganze in einer Consumer-,,exclgroup" oder einfach nur als einzelne ConsumerXX ?