diff --git a/fhem/FHEM/10_CUL_HM.pm b/fhem/FHEM/10_CUL_HM.pm
index b1454ab14..ac1d0937f 100755
--- a/fhem/FHEM/10_CUL_HM.pm
+++ b/fhem/FHEM/10_CUL_HM.pm
@@ -209,12 +209,16 @@ sub CUL_HM_Initialize($) {
$hash->{helper}{primary} = ""; # primary is one device in CUL_HM.It will be used for module notification.
# fhem does not provide module notifcation - so we streamline here.
$hash->{helper}{initDone} = 0;
+ $hash->{NotifyOrderPrefix} = "48-"; #Beta-User: make sure, CUL_HM is up and running prior to User code e.g. in notify, and also prior to HMinfo
+ InternalTimer(1,"CUL_HM_updateConfig","startUp",0);
+ #InternalTimer(1,"CUL_HM_setupHMLAN", "initHMLAN", 0);#start asap once FHEM is operational
+ return;
}
sub CUL_HM_updateConfig($){##########################
my $type = shift;
- # this routine is called 5 sec after the last define of a restart
- # this gives FHEM sufficient time to fill in attributes
+ # this routine is called immedately after INITALIZED or REREADCFG
+ # so all attributes and stateFile content has been read.
# it will also be called after each manual definition
# Purpose is to parse attributes and read config
RemoveInternalTimer("updateConfig");
@@ -227,6 +231,7 @@ sub CUL_HM_updateConfig($){##########################
Log 1,"CUL_HM start inital cleanup";
$mIdReverse = 1 if (scalar keys %{$culHmModel2Id});
my @hmdev = devspec2array("TYPE=CUL_HM:FILTER=DEF=......"); # devices only
+
foreach my $name (@hmdev){
if ($attr{$name}{subType} && $attr{$name}{subType} eq "virtual"){
$attr{$name}{model} = "VIRTUAL" if (!$attr{$name}{model} || $attr{$name}{model} =~ m/virtual_/);
@@ -241,7 +246,12 @@ sub CUL_HM_updateConfig($){##########################
}
CUL_HM_updtDeviceModel($name,AttrVal($name,"modelForce",AttrVal($name,"model","")),1) if($attr{$name}{".mId"});
# update IOdev
- CUL_HM_Attr("set",$name,"IOgrp",AttrVal($name,"IOgrp","")) if(AttrVal($name,"IOgrp","") ne "");# update helper by set attr again
+ my $IOgrp = AttrVal($name,"IOgrp","");
+ if($IOgrp ne ""){
+ delete $attr{$name}{IODev};
+ CUL_HM_Attr("set",$name,"IOgrp",$IOgrp);
+ CUL_HM_Attr('set',$name,'IOList',AttrVal($name,'IOList','')) if AttrVal($name,'IOList',undef); #Beta-User: Fix missing io->ioList in VCCU at startup, https://forum.fhem.de/index.php/topic,122848.msg1174047.html#msg1174047
+ }
my $h = $defs{$name};
delete $h->{helper}{io}{restoredIO} if ( defined($h->{helper}{io})
&& defined($h->{helper}{io}{restoredIO})
@@ -308,7 +318,7 @@ sub CUL_HM_updateConfig($){##########################
# move certain attributes to readings for future handling
my $aName = $rName;
$aName =~ s/D-//;
- my $aVal = AttrVal($name,$aName,undef);
+ my $aVal = AttrVal($name,$aName,undef);
CUL_HM_UpdtReadSingle($hash,$rName,$aVal,0)
if (!defined ReadingsVal($name,$rName,undef) && defined($aVal));
}
@@ -409,28 +419,21 @@ sub CUL_HM_updateConfig($){##########################
if ( $hash->{helper}{fkt}
&& $hash->{helper}{fkt} =~ m/^(vdCtrl|virtThSens)$/){
my $vId = substr($id."01",0,8);
- $hash->{helper}{vd}{msgRed}= 0 if(!defined $hash->{helper}{vd}{msgRed});
+ if (!defined $hash->{helper}{vd}{msgRed}) {
+ $hash->{helper}{vd}{msgRed}= 0;
+ my $attrVal = AttrVal($name,'param','');
+ if ($attrVal =~ m/msgReduce/) {
+ my (undef,$rCnt) = split(":",$attrVal,2);
+ $hash->{helper}{vd}{msgRed} = (defined $rCnt && $rCnt =~ m/^\d$/) ? $rCnt : 1;
+ }
+ }
if(!defined $hash->{helper}{vd}{next}){
($hash->{helper}{vd}{msgCnt},$hash->{helper}{vd}{next}) =
split(";",ReadingsVal($name,".next","0;".gettimeofday()));
$hash->{helper}{vd}{idl} = 0;
$hash->{helper}{vd}{idh} = 0;
}
- if ($hash->{helper}{fkt} eq "vdCtrl"){
- my $d = ReadingsVal($name,"valvePosTC","");
- $d =~ s/ %//;
- CUL_HM_Set($hash,$name,"valvePos",$d);
- CUL_HM_UpdtReadSingle($hash,"valveCtrl","restart",1) if ($d =~ m/^[-+]?[0-9]+\.?[0-9]*$/);
- RemoveInternalTimer("valvePos:$vId");
- RemoveInternalTimer("valveTmr:$vId");
- InternalTimer($hash->{helper}{vd}{next},"CUL_HM_valvePosUpdt","valvePos:$vId",0);
- }
- elsif($hash->{helper}{fkt} eq "virtThSens"){
- my $d = ReadingsVal($name,"temperature","");
- CUL_HM_Set($hash,$name,"virtTemp",$d) if($d =~ m/^[-+]?[0-9]+\.?[0-9]*$/);
- $d = ReadingsVal($name,"humidity","");
- CUL_HM_Set($hash,$name,"virtHum" ,$d) if($d =~ m/^[-+]?[0-9]+\.?[0-9]*$/);
- }
+ InternalTimer(time+10,'CUL_HM_initializeVirtuals', $hash,0); #Beta-User: make sure, CUL_HM is in toto up and running befor other devices want to use them,
# delete - virtuals dont have regs
delete $attr{$name}{$_} foreach ("autoReadReg","actCycle","actStatus","burstAccess","serialNr");
@@ -520,8 +523,8 @@ sub CUL_HM_updateConfig($){##########################
CUL_HM_SetList($name,"") if (!defined $defs{$name}{helper}{cmds}{cmdLst});
#remove invalid attributes. After set commands fot templist
CUL_HM_Attr("set",$name,"peerIDs",$attr{$name}{peerIDs}) if (defined $attr{$name}{peerIDs});# set attr again to update namings
- foreach(keys %{$attr{$name}}){
- delete $attr{$name}{$_} if (CUL_HM_AttrCheck('set',$name,$_,$attr{$name}{$_}));
+ foreach(sort keys %{$attr{$name}}){
+ delete $attr{$name}{$_} if (CUL_HM_AttrCheck($name,'set',$_,$attr{$name}{$_}));
}
CUL_HM_qStateUpdatIfEnab($name) if($hash->{helper}{role}{dev});
next if (0 == (0x07 & CUL_HM_getAttrInt($name,"autoReadReg")));
@@ -548,6 +551,29 @@ sub CUL_HM_updateConfig($){##########################
## configCheck will be issues by HMInfo once
}
+sub CUL_HM_initializeVirtuals {
+ my $hash = shift // return;
+ my $name = $hash->{NAME} // return;
+ my $vId = substr($hash->{DEF}."01",0,8);
+ if ($hash->{helper}{fkt} eq "vdCtrl"){
+ my $d = ReadingsNum($name,'valvePosTC','50');
+ #Log(1,"----- test2 ----- -> n:$name"); #Beta-User: For Debugging only
+ CUL_HM_Set($hash,$name,"valvePos",$d);
+ CUL_HM_UpdtReadSingle($hash,"valveCtrl","restart",1) if ($d =~ m/^[-+]?[0-9]+\.?[0-9]*$/);
+ RemoveInternalTimer("valvePos:$vId");
+ RemoveInternalTimer("valveTmr:$vId");
+ InternalTimer($hash->{helper}{vd}{next},"CUL_HM_valvePosUpdt","valvePos:$vId",0);
+ }
+ elsif($hash->{helper}{fkt} eq "virtThSens"){
+ #Log(1,"----- test2 ----- -> n:$name"); #Beta-User: For Debugging only
+ my $d = ReadingsNum($name,'temperature','');
+ CUL_HM_Set($hash,$name,"virtTemp",$d) if($d =~ m/^[-+]?[0-9]+\.?[0-9]*$/);
+ $d = ReadingsNum($name,"humidity","");
+ CUL_HM_Set($hash,$name,"virtHum" ,$d) if($d =~ m/^[-+]?[0-9]+\.?[0-9]*$/);
+ }
+ return;
+}
+
sub CUL_HM_primaryDev() {###########################
# one - and only one - CUL_HM entity will be primary device
# primary device is a) CUL_HM and b) not ignored
@@ -648,6 +674,7 @@ sub CUL_HM_Define($$) {##############################
$modules{CUL_HM}{defptr}{$HMid} = $hash;
notifyRegexpChanged($hash,"",1);# no notification required for this device
+ CUL_HM_primaryDev() if devspec2array('TYPE=CUL_HM') == 2; #Beta-User: we need at least one entity to initialize startup procedure
#- - - - create auto-update - - - - - -
CUL_HM_ActGetCreateHash() if($HMid eq '000000');#startTimer
@@ -905,6 +932,7 @@ sub CUL_HM_Attr(@) {#################################
$attr{$name}{subType} = "virtual";
$attr{$name}{".mId"} = CUL_HM_getmIdFromModel($attrVal);
$updtReq = 1;
+ CUL_HM_AttrAssign($name);
CUL_HM_UpdtCentral($name);
}
else{
@@ -977,7 +1005,7 @@ sub CUL_HM_Attr(@) {#################################
return 'CUL_HM '.$name.': IOgpr set => ccu to control the IO. Delete attr IOgrp if unwanted'
if (AttrVal($name,"IOgrp",undef));
if ($attrVal) {
- my @IOnames = devspec2array("Clients=:CUL_HM:");
+ my @IOnames = devspec2array('Clients=.*:CUL_HM:.*');
return 'CUL_HM '.$name.': Non suitable IODev '.$attrVal.' specified. Options are: ',join(",",@IOnames)
if (!grep /^$attrVal$/,@IOnames);
$attr{$name}{$attrName} = $attrVal;
@@ -1058,11 +1086,13 @@ sub CUL_HM_Attr(@) {#################################
return "vccu $ioCCU is no vccu with IOs assigned. It can't be used as IO" if (!$ioLst);# implicitely checks also for correct vccu
my @prefIOarr;
if ($prefIO){
- my @ioOpts = split(",",AttrVal($ioCCU,"IOList",""));
+ my @ioOpts = split(",",$ioLst);
return "$ioCCU not a valid CCU with IOs assigned" if (!scalar @ioOpts);
+ push @ioOpts, 'none';
@prefIOarr = split(",",$prefIO);
foreach my $pIO (@prefIOarr){
- return "$pIO is not part if VCCU IOs:$ioLst".join(",",@ioOpts) if(1 != grep/$pIO/,@ioOpts);
+ return "$pIO is not allowed in preferred IO list. Leave unassigned or choose one or more of ".join(",",@ioOpts) if(1 != grep m{\A$pIO\z},@ioOpts);
+ return "'none' may not be used without precedent other IO and has to be last!" if ($prefIO eq 'none' || $prefIO =~ m{\bnone[\b]*.+\z});
}
}
else{
@@ -1262,10 +1292,9 @@ sub CUL_HM_AttrCheck(@) {############################
$defs{$name}{'.AttrList'} =~ m/ ?($attrName)(:*)(.*?) /;
my ($attrFound,$attrOpt) = ($1,$3);
# return "$attrName not defined for $name" if (!defined $attrFound); # must not occure - already checked global
- return undef if (!$attrOpt || $attrOpt =~ m/^multiple/); # any value allowed
+ return undef if (!$attrOpt || $attrOpt =~ m/^(multiple|textField-)/); # any value allowed
return undef if(grep/^$attrVal$/,split(",",$attrOpt)); # attrval is valid option
-
- return "value $attrVal illegal. Choose one of:$attrOpt";
+ return "value $attrVal not allowed. Choose one of:$attrOpt";
}
sub CUL_HM_AttrInit($;$) {#############################
# define attributes and their options that are relevant/defined/controlled by CUL_HM
@@ -1328,7 +1357,7 @@ sub CUL_HM_AttrInit($;$) {#############################
};
$hash->{AttrX}{VIRTUAL} = { # model = virtual ###=> virtual {helper}{fkt} eq "vdCtrl" for VD
cyclicMsgOffset => ''
- ,param => ''
+ ,param => ''
};
$hash->{AttrX}{'blindActuator'} = { # subType
@@ -1382,12 +1411,12 @@ sub CUL_HM_AttrInit($;$) {#############################
}
}
$hash->{AttrList} = join(" ",sort
- map{my ($foo) = keys %{$hash->{ModulAttr}{$_}}; # use first option
+ map{my ($foo) = sort keys %{$hash->{ModulAttr}{$_}}; # use first option
my $val = $hash->{AttrX}{$foo}{$_};
$_.($val ? ':'.$val # add colon
: '')
}
- CUL_HM_noDup(keys %{$hash->{ModulAttr}}) # each attr just once
+ CUL_HM_noDup(sort keys %{$hash->{ModulAttr}}) # each attr just once
);
}
# update dependant
@@ -1529,7 +1558,8 @@ sub CUL_HM_Notify(@){###############################
);# no notification about myself
my $events = $dev->{CHANGED};
return undef if(!$events); # Some previous notify deleted the array.
- my $cws = join(";#",@{$dev->{CHANGED}});
+ #my $cws = join(";#",@{$dev->{CHANGED}});
+ my $count;
foreach my $evnt(@{$events}){
if($evnt =~ m/^(DELETEATTR)/){
}
@@ -1539,6 +1569,7 @@ sub CUL_HM_Notify(@){###############################
if ($ent eq $modules{CUL_HM}{helper}{primary}){
$modules{CUL_HM}{helper}{primary} = ""; # force rescan
CUL_HM_primaryDev();
+ $count++;
}
}
}
@@ -1550,6 +1581,7 @@ sub CUL_HM_Notify(@){###############################
||($evnt eq "RENAMED" && $defs{$new}{TYPE} eq "CUL_HM")){
CUL_HM_Rename($new,$ent) if($evnt eq "RENAMED");
CUL_HM_primaryDev() if ($ent eq $modules{CUL_HM}{helper}{primary});
+ $count++;
}
else{##------- update dependancies to IO devices used
my @culHmDevs = grep{$defs{$_}{DEF} =~ m/^......$/} grep{$defs{$_}{TYPE} eq "CUL_HM"} keys %defs;
@@ -1567,20 +1599,27 @@ sub CUL_HM_Notify(@){###############################
split(",",$ios)
);
$attr{$HMdef}{IOgrp} = "$vccu:$ios";
+ $count++;
}
else {# the vccu has no IO anymore - delete clients
CommandDeleteAttr (undef,"$HMdef IOgrp") ;
+ $count++;
}
}
- CommandAttr (undef,"$vccu IOList $ea")if ($ea ne $eaOld);
+ if ($ea ne $eaOld) {
+ CommandAttr (undef,"$vccu IOList $ea");
+ $count++;
+ }
}
foreach my $HMdef (grep{AttrVal($_,"IODev","") eq $ent} @culHmDevs){# for each IODev
CommandAttr (undef,"$HMdef IODev $new");
+ $count++;
}
}
- return "CUL_HM renamed a lot";
+ return ($count ? "CUL_HM: $count device(s) renamed or attributes changed due to DELETED or RENAMED event"
+ : undef);
}
- elsif (!$modules{CUL_HM}{helper}{initDone} && $evnt =~ m/INITIALIZED/){# grep the first initialize
+ elsif (!$modules{CUL_HM}{helper}{initDone} && $evnt =~ m/(INITIALIZED|REREADCFG)/){# grep the first initialize
CUL_HM_updateConfig("startUp");
InternalTimer(1,"CUL_HM_setupHMLAN", "initHMLAN", 0);#start asap once FHEM is operational
}
@@ -4383,7 +4422,7 @@ sub CUL_HM_parseSDteam_2(@){#handle SD team events
if ($sVal > 179 ||$sVal <51 ){# need to raise alarm
if ($sVal > 179){# need to raise alarm
#"SHORT_COND_VALUE_LO" value="50"/>
- #"SHORT_COND_VALUE_HI" value="180"/>
+ #"SHORT_COND_VALUE_HI" value="180"/>
$sProsa = "smoke-Alarm_".$No;
$smokeSrc = $dName;
push @evtEt,[$sHash,1,"recentAlarm:$smokeSrc"] if($sVal == 200);
@@ -4617,7 +4656,7 @@ sub CUL_HM_Get($@) {#+++++++++++++++++ get command+++++++++++++++++++++++++++++
}
else{
my $regVal = CUL_HM_getRegFromStore($name,$regReq,$list,$peerId);
- $regVal =~ s/ .*// if ($cmd eq "regVal");
+ $regVal =~ s/ .*// if ($cmd eq "regVal");
return ($regVal =~ m/^invalid/)? "Value not captured:$name - $regReq"
: $regVal;
}
@@ -4684,13 +4723,13 @@ sub CUL_HM_Get($@) {#+++++++++++++++++ get command+++++++++++++++++++++++++++++
}
elsif($cmd eq "tplInfo"){ ##################################################
my $info;
- my @tplCmd = split(" ",CUL_HMTmplSetCmd($name));
+ my @tplCmd = split(" ",CUL_HM_TmplSetCmd($name));
my %tplH;
my %tplTyp = (dev =>"device templates"
,ls =>"templates for peerings serving short OR long press"
,both =>"templates for peerings serving short AND long press"
);
- foreach my $tplSet (split(" ",CUL_HMTmplSetCmd($name))){
+ foreach my $tplSet (split(" ",CUL_HM_TmplSetCmd($name))){
my ($tplDst,$tplOpt) = split(":",$tplSet);
my @tplLst = sort split(",",$tplOpt);
if ($tplDst eq "tplSet_0"){#none peer template
@@ -4765,6 +4804,7 @@ sub CUL_HM_Get($@) {#+++++++++++++++++ get command+++++++++++++++++++++++++++++
keys %defs;
my @rl;
foreach (@dl){
+ next if IsIgnored($_) || IsDummy($_);
my(undef,$pref) = split":",$attr{$_}{IOgrp},2;
$pref = "---" if (!$pref);
my $IODev = $defs{$_}{IODev}->{NAME}?$defs{$_}{IODev}->{NAME}:"---";
@@ -4874,7 +4914,7 @@ sub CUL_HM_getTemplateModify(){
}
sub CUL_HM_SetList($$) {#+++++++++++++++++ get command basic list++++++++++++++
my($name,$cmdKey)=@_;
- my $hash = $defs{$name};
+ my $hash = $defs{$name} // return;
if(!$cmdKey){
my $devName = InternalVal($name,"device",$name);
@@ -4902,24 +4942,24 @@ sub CUL_HM_SetList($$) {#+++++++++++++++++ get command basic list++++++++++++++
}
}
- if( !$roleV &&($roleD || $roleC) ){push @arr1,map{"$_:".$culHmGlobalSets->{$_} }keys %{$culHmGlobalSets} };
- if(( $roleV||!$st||$st eq "no")&& $roleD){push @arr1,map{"$_:".$culHmGlobalSetsVrtDev->{$_} }keys %{$culHmGlobalSetsVrtDev} };
- if( !$roleV && $roleD){push @arr1,map{"$_:".${$culHmSubTypeDevSets->{$st}}{$_}}keys %{$culHmSubTypeDevSets->{$st}}};
- if( !$roleV && $roleC){push @arr1,map{"$_:".$culHmGlobalSetsChn->{$_} }keys %{$culHmGlobalSetsChn} };
- if( $culHmSubTypeSets->{$st} && $roleC){push @arr1,map{"$_:".${$culHmSubTypeSets->{$st}}{$_} }keys %{$culHmSubTypeSets->{$st}} };
- if( $culHmModelSets->{$md}) {push @arr1,map{"$_:".${$culHmModelSets->{$md}}{$_} }keys %{$culHmModelSets->{$md}} };
- if( $culHmChanSets->{$md."00"} && $roleD){push @arr1,map{"$_:".${$culHmChanSets->{$md."00"}}{$_} }keys %{$culHmChanSets->{$md."00"}} };
- if( $culHmChanSets->{$md."xx"} && $roleC){push @arr1,map{"$_:".${$culHmChanSets->{$md."xx"}}{$_} }keys %{$culHmChanSets->{$md."xx"}} };
- if( $culHmChanSets->{$md.$chn} && $roleC){push @arr1,map{"$_:".${$culHmChanSets->{$md.$chn}}{$_} }keys %{$culHmChanSets->{$md.$chn}} };
- if( $culHmFunctSets->{$fkt} && $roleC){push @arr1,map{"$_:".${$culHmFunctSets->{$fkt}}{$_} }keys %{$culHmFunctSets->{$fkt}} };
+ if( !$roleV &&($roleD || $roleC) ){push @arr1,map{"$_:".$culHmGlobalSets->{$_} } sort keys %{$culHmGlobalSets} };
+ if(( $roleV||!$st||$st eq "no")&& $roleD){push @arr1,map{"$_:".$culHmGlobalSetsVrtDev->{$_} } sort keys %{$culHmGlobalSetsVrtDev} };
+ if( !$roleV && $roleD){push @arr1,map{"$_:".${$culHmSubTypeDevSets->{$st}}{$_}} sort keys %{$culHmSubTypeDevSets->{$st}}};
+ if( !$roleV && $roleC){push @arr1,map{"$_:".$culHmGlobalSetsChn->{$_} } sort keys %{$culHmGlobalSetsChn} };
+ if( $culHmSubTypeSets->{$st} && $roleC){push @arr1,map{"$_:".${$culHmSubTypeSets->{$st}}{$_} } sort keys %{$culHmSubTypeSets->{$st}} };
+ if( $culHmModelSets->{$md}) {push @arr1,map{"$_:".${$culHmModelSets->{$md}}{$_} } sort keys %{$culHmModelSets->{$md}} };
+ if( $culHmChanSets->{$md."00"} && $roleD){push @arr1,map{"$_:".${$culHmChanSets->{$md."00"}}{$_} } sort keys %{$culHmChanSets->{$md."00"}} };
+ if( $culHmChanSets->{$md."xx"} && $roleC){push @arr1,map{"$_:".${$culHmChanSets->{$md."xx"}}{$_} } sort keys %{$culHmChanSets->{$md."xx"}} };
+ if( $culHmChanSets->{$md.$chn} && $roleC){push @arr1,map{"$_:".${$culHmChanSets->{$md.$chn}}{$_} } sort keys %{$culHmChanSets->{$md.$chn}} };
+ if( $culHmFunctSets->{$fkt} && $roleC){push @arr1,map{"$_:".${$culHmFunctSets->{$fkt}}{$_} } sort keys %{$culHmFunctSets->{$fkt}} };
$hash->{helper}{cmds}{lst}{peerOpt} = CUL_HM_getPeerOption($name);
push @arr1,"peerSmart:-peerOpt-" if ($hash->{helper}{cmds}{lst}{peerOpt});
my @cond = ();
- push @cond,map{$lvlStr{md}{$md}{$_}} keys%{$lvlStr{md}{$md}} if (defined $lvlStr{md}{$md});
- push @cond,map{$lvlStr{mdCh}{"$md$chn"}{$_}} keys%{$lvlStr{mdCh}{"$md$chn"}} if (defined $lvlStr{mdCh}{"$md$chn"});
- push @cond,map{$lvlStr{st}{$st}{$_}} keys%{$lvlStr{st}{$st}} if (defined $lvlStr{st}{$st});
+ push @cond,map{$lvlStr{md}{$md}{$_}} sort keys%{$lvlStr{md}{$md}} if (defined $lvlStr{md}{$md});
+ push @cond,map{$lvlStr{mdCh}{"$md$chn"}{$_}} sort keys%{$lvlStr{mdCh}{"$md$chn"}} if (defined $lvlStr{mdCh}{"$md$chn"});
+ push @cond,map{$lvlStr{st}{$st}{$_}} sort keys%{$lvlStr{st}{$st}} if (defined $lvlStr{st}{$st});
push @cond,"slider,0,1,255" if (!scalar @cond);
$hash->{helper}{cmds}{lst}{condition} = join(",",sort grep /./,@cond);
@@ -4964,10 +5004,10 @@ sub CUL_HM_SetList($$) {#+++++++++++++++++ get command basic list++++++++++++++
my $tmplAssTs = (defined $hash->{helper}{cmds}{TmplTs} ? $hash->{helper}{cmds}{TmplTs}:"noAssTs");# template assign timestamp
my $peerLst = InternalVal($name,"peerList","");
if($hash->{helper}{cmds}{TmplKey} ne $peerLst.":$tmplStamp:$tmplAssTs" ){
- my @arr1 = map{"$_:-value-"}split(" ",CUL_HMTmplSetParam($name));
+ my @arr1 = map{"$_:-value-"}split(" ",CUL_HM_TmplSetParam($name));
delete $hash->{helper}{cmds}{cmdLst}{$_} foreach(grep/^tpl(Set|Para)/,keys%{$hash->{helper}{cmds}{cmdLst}});
- CUL_HMTmplSetCmd($name);
+ CUL_HM_TmplSetCmd($name);
push @arr1, "tplSet_0:-tplChan-" if(defined $hash->{helper}{cmds}{lst}{tplChan});
if(defined $hash->{helper}{cmds}{lst}{tplPeer}){
push @arr1, "tplSet_$_:-tplPeer-" foreach(split(",",$peerLst));
@@ -5199,7 +5239,7 @@ sub CUL_HM_Set($@) {#+++++++++++++++++ set command+++++++++++++++++++++++++++++
foreach my $sect (@sectL){
if ($sect eq "readings"){
my @cH = ($hash);
- push @cH,$defs{$hash->{$_}} foreach(grep /^channel/,keys %{$hash});
+ push @cH,$defs{$hash->{$_}} foreach(grep /^channel/,sort keys %{$hash});
delete $_->{READINGS} foreach (@cH);
delete $modules{CUL_HM}{helper}{cfgCmpl}{$name};
CUL_HM_complConfig($_->{NAME}) foreach (@cH);
@@ -5214,7 +5254,7 @@ sub CUL_HM_Set($@) {#+++++++++++++++++ set command+++++++++++++++++++++++++++++
}
elsif($sect eq "register"){
my @cH = ($hash);
- push @cH,$defs{$hash->{$_}} foreach(grep /^channel/,keys %{$hash});
+ push @cH,$defs{$hash->{$_}} foreach(grep /^channel/,sort keys %{$hash});
foreach my $h(@cH){
delete $h->{READINGS}{$_}
@@ -5294,6 +5334,7 @@ sub CUL_HM_Set($@) {#+++++++++++++++++ set command+++++++++++++++++++++++++++++
if ($result){
return $result;
}
+ $hash->{device} = $newName;
if ($roleV){
foreach(1..50){
@@ -5315,12 +5356,18 @@ sub CUL_HM_Set($@) {#+++++++++++++++++ set command+++++++++++++++++++++++++++++
}
}
my @results;
- foreach my $cd (grep /^channel_/,keys %{$hash}){
+ my @renamed;
+ foreach my $cd (grep /^channel_/,sort keys %{$hash}){
my $cName = InternalVal($newName,$cd,"");
my $no = hex(substr($cd,8));
$result = CommandRename(undef,$cName.' '.$chLst[$no]);
+ $hash->{"channel_".sprintf "%02X",$no} = $chLst[$no]; #reference in device as well
+ $defs{$chLst[$no]}->{device} = $newName;
+ push @renamed, $chLst[$no];
push @results,"rename $cName failed: $result" if ($result);
}
+ CUL_HM_setAssotiat($newName);
+ for (@renamed) { CUL_HM_setAssotiat($_); }
return "channel rename failed:\n".join("\n",@results) if (scalar @results);
}
elsif($cmd eq "tempListTmpl") { #############################################
@@ -5337,7 +5384,7 @@ sub CUL_HM_Set($@) {#+++++++++++++++++ set command+++++++++++++++++++++++++++++
}
($fn,$template) = split(":",($template?$template
:AttrVal($name,"tempListTmpl",$name)));
- if ($modules{HMinfo}){
+ if (defined &HMinfo_tempListDefFn){
if (!$template){ $template = HMinfo_tempListDefFn() .":$fn" ;}
else{ $template = HMinfo_tempListDefFn($fn).":$template";}
}
@@ -5350,8 +5397,8 @@ sub CUL_HM_Set($@) {#+++++++++++++++++ set command+++++++++++++++++++++++++++++
return $ret;
}
elsif($cmd eq "tempTmplSet") { ##############################################
- return "template missing" if (!defined $a[2]);
- my $reply = CommandAttr(undef, "$name tempListTmpl $a[2]");
+ return "template missing" if (!defined $a[2]);
+ my $reply = CommandAttr(undef, "$name tempListTmpl $a[2]");
my ($fn,$template) = split(":",AttrVal($name,"tempListTmpl",$name));
if ($modules{HMinfo}){
@@ -5365,7 +5412,7 @@ sub CUL_HM_Set($@) {#+++++++++++++++++ set command+++++++++++++++++++++++++++++
CUL_HM_tempListTmpl($name,"restore",$template);
}
elsif($cmd eq "tplDel") { ###################################################
- return "template missing" if (!defined $a[2]);
+ return "template missing" if (!defined $a[2]);
my ($p,$t) = split(">",$a[2]);
HMinfo_templateDel($name,$t,$p) if (eval "defined(&HMinfo_templateDel)");
return;
@@ -5723,7 +5770,7 @@ sub CUL_HM_Set($@) {#+++++++++++++++++ set command+++++++++++++++++++++++++++++
$cName =~ s/_chn-\d\d$//;
my $curVal = CUL_HM_getRegFromStore($cName,$addr,$list,$peerId.$peerChn);
if ($curVal !~ m/^(set_|)(\d+)$/){
- return "peer required for $regName" if ($curVal =~ m/peer/);
+ return "peer required for $regName" if ($curVal =~ m/peer/);
return "cannot calculate value. Please issue set $name getConfig first - $curVal";
}
$curVal = $2; # we expect one byte in int, strap 'set_' possibly
@@ -7647,14 +7694,26 @@ sub CUL_HM_updtDeviceModel($$@) {#change the model for a device - obey overwrite
delete $hash->{helper}{rxType};
CUL_HM_getRxType($hash); #will update rxType
my $mId = CUL_HM_getMId($hash);# set helper valiable and use result
- return if(!defined $mId or $mId eq "");
+ return if(!defined $mId or $mId eq "" or $mId eq "none");
# autocreate undefined channels
my %chanExist;
%chanExist = map { $_ => 0 } CUL_HM_getAssChnIds($name);
if ($attr{$name}{subType} eq "virtual"){# do not apply all possible channels for virtual
- $attr{CUL_HM_id2Name($_)}{model} = $model foreach(keys %chanExist);
+ foreach my $chanid (keys %chanExist) {
+ my $chann = CUL_HM_id2Name($chanid);
+ next if (!defined $defs{$chann}); #special for ACTIONDETECTOR. Or use "next if ($chanExist{$_} == 1);"
+ $attr{$chann}{model} = $model;
+ if ( $fromUpdate && AttrVal($chann,'peerIDs',undef) && !keys %{$defs{$chann}{helper}{peerIDsH}} ) {
+ CUL_HM_ID2PeerList($chann,$_,1) for ('peerUnread',split q{,},AttrVal($chann,'peerIDs',''));
+ } #Beta-User: Might not have been called earlier. Then subtype is unknown yet, https://forum.fhem.de/index.php/topic,123136.msg1177303.html#msg1177303;
+ CUL_HM_SetList($chann,'') if ($fromUpdate || !defined $defs{$chann}{helper}{cmds}{cmdLst});
+ CUL_HM_AttrAssign($chann) if ($fromUpdate); #Beta-User: add .AttrList for virtual channels
+ $defs{$chann}->{'.AttrList'} =~ s{IOList |expert[\S]+ |levelRange }{}g if (defined $defs{$chann}->{'.AttrList'});
+ }
}
else{
+ CUL_HM_SetList($name,'') if ($fromUpdate || !defined $defs{$name}{helper}{cmds}{cmdLst});
+ CUL_HM_AttrAssign($name) if ($fromUpdate);
my @chanTypesList = split(',',$culHmModel->{$mId}{chn});
foreach my $chantype (@chanTypesList){# check all regulat channels
my ($chnTpName,$chnStart,$chnEnd) = split(':',$chantype);
@@ -7672,6 +7731,7 @@ sub CUL_HM_updtDeviceModel($$@) {#change the model for a device - obey overwrite
$attr{CUL_HM_id2Name($chnId)}{model} = $model ;
$chanExist{$chnId} = 1; # mark this channel as required
}
+ CUL_HM_SetList(CUL_HM_id2Name($chnId),"") if ($fromUpdate); #!defined $defs{CUL_HM_id2Name($chnId)}{helper}{cmds}{cmdLst};
CUL_HM_AttrAssign(CUL_HM_id2Name($chnId));
$chnNoTyp++;
}
@@ -8890,7 +8950,7 @@ sub CUL_HM_getAssChnNames($) { #in: name out:list of assotiated chan and device
if ($defs{$name}){
push @chnN,$name;
my $hash = $defs{$name};
- push @chnN,$hash->{$_} foreach (grep /^channel_/, keys %{$hash});
+ push @chnN,$hash->{$_} foreach (grep /^channel_/,sort keys %{$hash});
}
return sort(@chnN);
}
@@ -9251,7 +9311,7 @@ sub CUL_HM_getRegFromStore($$$$@) {#read a register from backup data
}
return $convFlg.$data.$unit;
}
-sub CUL_HMTmplSetCmd($){
+sub CUL_HM_TmplSetCmd($){
my $name = shift;
return "" if(not scalar devspec2array("TYPE=HMinfo"));
my $devId = substr($defs{$name}{DEF},0,6);
@@ -9267,7 +9327,7 @@ sub CUL_HMTmplSetCmd($){
$peer = "self".substr($peer,-2) if($peer =~ m/^${name}_chn-..$/);
my $ps = $peer eq "0" ? "R-" : "R-$peer-";
my %b = map { $_ => 1 }map {(my $foo = $_) =~ s/.?$ps//; $foo;} grep/.?$ps/,keys%{$defs{$name}{READINGS}};
- foreach my $t(keys %HMConfig::culHmTpl){
+ foreach my $t(reverse sort keys %HMConfig::culHmTpl){
next if (not scalar (keys %{$HMConfig::culHmTpl{$t}{reg}}));
my $f = 0;
my $typShLg=0;
@@ -9303,7 +9363,7 @@ sub CUL_HMTmplSetCmd($){
: "")#no template
;
}
-sub CUL_HMTmplSetParam($){
+sub CUL_HM_TmplSetParam($){
my $name = shift;
return "" if(not scalar devspec2array("TYPE=HMinfo"));
my @tCmd;
@@ -9428,6 +9488,13 @@ sub CUL_HM_updtRegDisp($$$) {
$chn = (length($chn) == 8)?substr($chn,6,2):"";
my @regArr = CUL_HM_getRegN($st,$md,$chn);
my @changedRead;
+
+
+ if( !CUL_HM_getPeers($name,"ID:$peerId")
+ && CUL_HM_getPeers($name,"ID:".substr($peerId,0,6))){
+ ($peerId) = CUL_HM_getPeers($name,"ID:".substr($peerId,0,6));
+ }
+
my $regLN = ($hash->{helper}{expert}{raw}?"":".")
.sprintf("RegL_%02X.",$listNo)
.($peerId ? CUL_HM_peerChName($peerId,$devId) : "");
@@ -9479,17 +9546,18 @@ sub CUL_HM_cfgStateUpdate($) {#update cfgState
my (undef,$name) = split(':',$tmrId,2);
return if (!defined $defs{$name} );
RemoveInternalTimer("cfgStateUpdate:$name") if($defs{$name}{helper}{cfgStateUpdt});#could be direct call or timeout
- if ( !$evtDly #noansi: first Readings must be set, helps also not to disturb others
+ if ( !$evtDly && $init_done && $fhem_started + 30 < time #noansi: first Readings must be set, helps also not to disturb others
&& !$defs{$name}{helper}{prt}{sProc} #not busy with commands?
){
$defs{$name}{helper}{cfgStateUpdt} = 0;
my ($hm) = devspec2array("TYPE=HMinfo");
HMinfo_GetFn($defs{$hm},$hm,"configCheck","-f","^(".join("|",(CUL_HM_getAssChnNames($name),$name)).")\$") if (defined $hm);
}
- else{
+ else {
$defs{$name}{helper}{cfgStateUpdt} = 1; # use to remove duplicate timer
- InternalTimer(gettimeofday() + 60, "CUL_HM_cfgStateUpdate","cfgStateUpdate:$name", 0); # try later
+ InternalTimer(gettimeofday() + 60, "CUL_HM_cfgStateUpdate","cfgStateUpdate:$name", 0) if ($init_done || length(CUL_HM_name2Id($name)) == 6); # try later
}
+ return;
}
sub CUL_HM_rmOldRegs($$){ # remove register i outdated
@@ -9627,7 +9695,7 @@ sub CUL_HM_initRegHash() { #duplicate short and long press register
}
else { # success - now update some datafiels
Log3 undef, 3, "additional HM config file loaded: $file";
- foreach (keys %{$culHmModel}){
+ foreach (sort keys %{$culHmModel}){
next if(!$_);
$culHmModel2Id->{$culHmModel->{$_}{name}} = $_ ;
$culHmModel->{$_}{alias} = $culHmModel->{$_}{name} if (!defined $culHmModel->{$_}{alias});
@@ -10595,7 +10663,7 @@ sub CUL_HM_setAttrIfCh($$$$) {
}
sub CUL_HM_noDup(@) {#return list with no duplicates
my %all;
- return "" if (scalar(@_) == 0);
+ return @_ if (!scalar(@_));
$all{$_}=0 foreach (grep {defined $_ && $_ !~ m/^$/} @_);
delete $all{""}; #remove empties if present
return (sort keys %all);
@@ -10691,7 +10759,11 @@ sub CUL_HM_UpdtCentral($){
,sort map{"IO:$_"} split(",",AttrVal($name,"IOList",""))
,sort devspec2array("TYPE=CUL_HM:FILTER=IOgrp=$name.*") # devices assigned to the vccu
)." ";
- $defs{$name}{'.AttrList'} =~ s/logIDs:.*? /$logOpt/;
+ if ( defined $defs{$name}{'.AttrList'} ) { #Beta-User: fixes "uninitialized ... in substitution" warning at startup
+ $defs{$name}{'.AttrList'} =~ s/logIDs:.*? /$logOpt/;
+ } else {
+ $defs{$name}{'.AttrList'} = $logOpt;
+ }
# --- search for peers to CCU and potentially device this channel
# create missing CCU channels
@@ -10817,16 +10889,17 @@ sub CUL_HM_assignIO($){ #check and assign IO, returns 1 if IO changed
$dIo = $oldIODevH->{NAME};
}
else {
- my @IOs = devspec2array("Clients=:CUL_HM:");
+ my @IOs = devspec2array('Clients=.*:CUL_HM:.*');
($dIo) = (grep{CUL_HM_operIObyIOName($_)} @IOs,@IOs);# tricky: use first active IO else use any IO for CUL_HM
}
$newIODevH = $defs{$dIo} if($dIo);
}
my $result = 0; # default: IO unchanged
- if( (defined $newIODevH && (!defined($oldIODevH) || $newIODevH != $oldIODevH))){
+ if( (defined $newIODevH && (!defined($oldIODevH) || $newIODevH ne $oldIODevH))){
my $ID = CUL_HM_hash2Id($hash);
- IOWrite($hash, "", "remove:".$ID) if(defined($oldIODevH) && defined $oldIODevH->{NAME}); #IODev still old
+ IOWrite($hash, "", "remove:".$ID) if( defined($oldIODevH) && defined $oldIODevH->{NAME}
+ && $oldIODevH->{TYPE} && $oldIODevH->{TYPE} =~ m/^(HMLAN|HMUARTLGW)$/); #IODev still old
AssignIoPort($hash,$newIODevH->{NAME}); # send preferred
$hash->{IODev} = $newIODevH;
if ( ($newIODevH->{TYPE} && $newIODevH->{TYPE} =~ m/^(HMLAN|HMUARTLGW)$/)
@@ -11551,6 +11624,8 @@ sub CUL_HM_getIcon($) { #######################################################
1;
+__END__
+
=pod
=encoding utf8
=item device
@@ -11562,7 +11637,7 @@ sub CUL_HM_getIcon($) { #######################################################
Support for eQ-3 HomeMatic devices via the CUL or the HMLAN.
- Define
+ Define
define <name> CUL_HM <6-digit-hex-code|8-digit-hex-code>
@@ -11669,7 +11744,7 @@ sub CUL_HM_getIcon($) { #######################################################
- Set
+ Set
Note: devices which are normally send-only (remote/sensor/etc) must be set
into pairing/learning mode in order to receive the following commands.
@@ -11677,12 +11752,12 @@ sub CUL_HM_getIcon($) { #######################################################
Universal commands (available to most hm devices):
- - assignHmKey
+ - assignHmKey
Initiates a key-exchange with the device, exchanging the old AES-key of the device with the key with the highest
index defined by the attribute hmKey* in the HMLAN or VCCU. The old key is determined by the reading aesKeyNbr,
which specifies the index of the old key when the reading is divided by 2.
- - clear <[rssi|readings|register|msgEvents|attack|all]>
+ - clear <[rssi|readings|register|msgEvents|attack|all]>
A set of variables can be removed.
readings: all readings will be deleted. Any new reading will be added usual. May be used to eliminate old data
@@ -11693,7 +11768,7 @@ sub CUL_HM_getIcon($) { #######################################################
all: all of the above.
- - getConfig
+ - getConfig
Will read major configuration items stored in the HM device. Executed
on a channel it will read pair Inforamtion, List0, List1 and List3 of
the 1st internal peer. Furthermore the peerlist will be retrieved for
@@ -11702,7 +11777,7 @@ sub CUL_HM_getIcon($) { #######################################################
configuration for additional peers.
The command is a shortcut
for a selection of other commands.
- - getRegRaw [List0|List1|List2|List3|List4|List5|List6|List7]<peerChannel>
+ - getRegRaw [List0|List1|List2|List3|List4|List5|List6|List7]<peerChannel>
Read registerset in raw format. Description of the registers is beyond
the scope of this documentation.
@@ -11757,7 +11832,7 @@ sub CUL_HM_getIcon($) { #######################################################
set mydimmer getRegRaw List3 all
- - getSerial
+ - getSerial
Read serial number from device and write it to attribute serialNr.
- inhibit [on|off]
@@ -11773,7 +11848,7 @@ sub CUL_HM_getIcon($) { #######################################################
- pair
+ pair
Pair the device with a known serialNumber (e.g. after a device reset)
to FHEM Central unit. FHEM Central is usualy represented by CUL/CUNO,
HMLAN,...
@@ -11786,7 +11861,7 @@ sub CUL_HM_getIcon($) { #######################################################
Don't confuse pair (to a central) with peer (channel to channel) with
peerChan.
- peerBulk <peerch1,peerch2,...> [set|unset]
+ peerBulk <peerch1,peerch2,...> [set|unset]
peerBulk will add peer channels to the channel. All peers in the list will be added.
with unset option the peers in the list will be subtracted from the device's peerList.
peering sets the configuration of this link to its defaults. As peers are not
@@ -11807,7 +11882,7 @@ sub CUL_HM_getIcon($) { #######################################################
set myChannel peerBulk 12345601 unset # remove peer 123456 channel 01
- regBulk <reg List>.<peer> <addr1:data1> <addr2:data2>...
+ regBulk <reg List>.<peer> <addr1:data1> <addr2:data2>...
This command will replace the former regRaw. It allows to set register
in raw format. Its main purpose is to restore a complete register list
to values secured before.
@@ -11830,7 +11905,7 @@ sub CUL_HM_getIcon($) { #######################################################
myblind will set the max drive time up for a blind actor to 25,6sec
- regSet [prep|exec] <regName> <value> <peerChannel>
+ regSet [prep|exec] <regName> <value> <peerChannel>
For some major register a readable version is implemented supporting
register names <regName> and value conversionsing. Only a subset
of register can be supproted.
@@ -11850,24 +11925,24 @@ sub CUL_HM_getIcon($) { #######################################################
using
- reset
+ reset
Factory reset the device. You need to pair it again to use it with
fhem.
- sign [on|off]
+ sign [on|off]
Activate or deactivate signing (also called AES encryption, see the note above). Warning: if the device is attached via
a CUL, you need to install the perl-module Crypt::Rijndael to be
able to switch it (or deactivate signing) from fhem.
- statusRequest
+ statusRequest
Update device status. For multichannel devices it should be issued on
an per channel base
- unpair
+ unpair
"Unpair" the device, i.e. make it available to pair with other master
devices. See pair for description.
- virtual <number of buttons>
+ virtual <number of buttons>
configures a defined curcuit as virtual remote controll. Then number
of button being added is 1 to 255. If the command is issued a second
time for the same entity additional buttons will be added.
@@ -11881,10 +11956,10 @@ sub CUL_HM_getIcon($) { #######################################################
see also press
- deviceRename <newName>
+ deviceRename <newName>
rename the device and all its channels.
- fwUpdate [onlyEnterBootLoader] <filename> [<waitTime>]
+ fwUpdate [onlyEnterBootLoader] <filename> [<waitTime>]
update Fw of the device. User must provide the appropriate file.
waitTime can be given optionally. In case the device needs to be set to
FW update mode manually this is the time the system will wait.
@@ -11900,17 +11975,17 @@ sub CUL_HM_getIcon($) { #######################################################
switch
- - on - set level to 100%
- - off - set level to 0%
- - on-for-timer <sec> -
+
- on - set level to 100%
+ - off - set level to 0%
+ - on-for-timer <sec> -
set the switch on for the given seconds [0-85825945].
Note:
off-for-timer like FS20 is not supported. It may to be programmed
thru channel register.
- - on-till <time> - set the switch on for the given end time.
+ - on-till <time> - set the switch on for the given end time.
set <name> on-till 20:32:10
Currently a max of 24h is supported with endtime.
- - pressL <peer> [<repCount>] [<repDelay>]
+ - pressL <peer> [<repCount>] [<repDelay>]
simulate a press of the local button or direct connected switch of the actor.
<peer> allows to stimulate button-press of any peer of the actor.
i.e. if the actor is peered to any remote, virtual or io (HMLAN/CUL)
@@ -11925,10 +12000,10 @@ sub CUL_HM_getIcon($) { #######################################################
set actor pressL fhem02 # trigger short of FHEM channel 2
- - pressS <peer>
+ - pressS <peer>
simulates a short press similar to long press
- - eventL <peer> <condition> [<repCount>] [<repDelay>]
+ - eventL <peer> <condition> [<repCount>] [<repDelay>]
simulate an event of an peer and stimulates the actor.
<peer> allows to stimulate button-press of any peer of the actor.
i.e. if the actor is peered to any remote, virtual or io (HMLAN/CUL)
@@ -11939,10 +12014,10 @@ sub CUL_HM_getIcon($) { #######################################################
set actor eventL md 30 # trigger from motion detector with level 30
- - eventS <peer> <condition>
+ - eventS <peer> <condition>
simulates a short event from a peer of the actor. Typically sensor do not send long events.
- - toggle - toggle the Actor. It will switch from any current
+
- toggle - toggle the Actor. It will switch from any current
level to off or from off to 100%
@@ -11966,7 +12041,7 @@ sub CUL_HM_getIcon($) { #######################################################
off
press <[short|long]><[on|off]>
toggle
- toggleDir - toggled drive direction between up/stop/down/stop
+ toggleDir - toggled drive direction between up/stop/down/stop
on-for-timer <sec> - Dimmer only!
on-till <time> - Dimmer only!
stop - stop motion (blind) or dim ramp
@@ -11984,7 +12059,7 @@ sub CUL_HM_getIcon($) { #######################################################
- remotes, pushButton
+ remotes, pushButton
This class of devices does not react on requests unless they are put
to learn mode. FHEM obeys this behavior by stacking all requests until
learn mode is detected. Manual interaction of the user is necessary to
@@ -11992,21 +12067,21 @@ sub CUL_HM_getIcon($) { #######################################################
device level with parameter 'protCmdPend'.
- - trgEventS [all|<peer>] <condition>
+ - trgEventS [all|<peer>] <condition>
Issue eventS on the peer entity. If all is selected each of the peers will be triggered. See also eventS
<condition>: is the condition being transmitted with the event. E.g. the brightness in case of a motion detector.
- - trgEventL [all|<peer>] <condition>
+ - trgEventL [all|<peer>] <condition>
Issue eventL on the peer entity. If all is selected each of the peers will be triggered. a normal device will not sent event long. See also eventL
<condition>: is the condition being transmitted with the event. E.g. the brightness in case of a motion detector.
- - trgPressS [all|<peer>]
+ - trgPressS [all|<peer>]
Issue pressS on the peer entity. If all is selected each of the peers will be triggered. See also pressS
- - trgPressL [all|<peer>]
+ - trgPressL [all|<peer>]
Issue pressL on the peer entity. If all is selected each of the peers will be triggered. See also pressL
- - peerIODev [IO] <btn_no> [set|unset]
+ - peerIODev [IO] <btn_no> [set|unset]
The command is similar to peerChan.
While peerChan
is executed on a remote and peers any remote to any actor channel peerIODev is
@@ -12015,7 +12090,7 @@ sub CUL_HM_getIcon($) { #######################################################
will be peered/unpeerd to the actor. press can be
used to stimulate the related actions as defined in the actor register.
- - peerSmart [<peer>]
+ - peerSmart [<peer>]
The command is similar to peerChan.
peerChan uses only one parameter, the peer which the channel shall be peered to.
Therefore peerSmart peers always in single mode (see peerChan). Funktionallity of the peered actor shall be applied
@@ -12023,8 +12098,7 @@ sub CUL_HM_getIcon($) { #######################################################
Smart register setting could be done using hmTemplate.
peerSmart is also available for actor-channel.
- - peerChan <btn_no> <actChan> [single|dual|reverse][set|unset] [both|actor|remote]
-
+ - peerChan <btn_no> <actChan> [single|dual|reverse][set|unset] [both|actor|remote]
peerChan will establish a connection between a sender- channel and
an actuator-channel called link in HM nomenclatur. Peering must not be
@@ -12100,10 +12174,10 @@ sub CUL_HM_getIcon($) { #######################################################
- virtual
+ virtual
- peerChan see remote
- - press [long|short] [<peer>] [<repCount>] [<repDelay>]
+
- press [long|short] [<peer>] [<repCount>] [<repDelay>]
simulates button press for an actor from a peered sensor.
will be sent of type "long".
@@ -12113,11 +12187,11 @@ sub CUL_HM_getIcon($) { #######################################################
- [<repDelay>] Valid for long press only. defines wait time between the single messages.
- - virtTemp <[off -10..50]>
+
- virtTemp <[off -10..50]>
simulates a thermostat. If peered to a device it periodically sends the
temperature until "off" is given. See also virtHum
- - virtHum <[off -10..50]>
+
- virtHum <[off -10..50]>
simulates the humidity part of a thermostat. If peered to a device it periodically sends
the temperature and humidity until both are "off". See also virtTemp
@@ -12298,7 +12372,7 @@ sub CUL_HM_getIcon($) { #######################################################
spaces must not be used in the list.
replay can be entered to repeat the last sound played once more.
repeat defines how often the sequence shall be played. Defaults to 1.
- volume is defined between 0 and 10. 0 stops any sound currently playing. Defaults to 10 (100%).
+ volume is defined between 0 and 10. 0 stops any sound currently playing. Defaults to 10 (100%).
Example:
# "hello" in display, symb bulb on, backlight, beep
@@ -12489,9 +12563,9 @@ sub CUL_HM_getIcon($) { #######################################################
- Get
+ Get
- - configSave <filename>
+ - configSave <filename>
Saves the configuration of an entity into a file. Data is stored in a
format to be executed from fhem command prompt.
The file is located in the fhem home directory aside of fhem.cfg. Data
@@ -12530,15 +12604,15 @@ sub CUL_HM_getIcon($) { #######################################################
Note: if this command is executed on a channel and 'model' is
requested the content hosting device's 'model' will be returned.
- - reg <addr> <list> <peerID>
+ - reg <addr> <list> <peerID>
returns the value of a register. The data is taken from the storage in FHEM and not
- read directly outof the device.
- If register content is not present please use getConfig, getReg in advance.
+ read directly outof the device.
+ If register content is not present please use getConfig, getReg in advance.
<addr> address in hex of the register. Registername can be used alternaly
- if decoded by FHEM. "all" will return all decoded register for this entity in one list.
+ if decoded by FHEM. "all" will return all decoded register for this entity in one list.
<list> list from which the register is taken. If rgistername is used list
- is ignored and can be set to 0.
+ is ignored and can be set to 0.
<peerID> identifies the registerbank in case of list3 and list4. It an be set to dummy if not used.
- regVal <addr> <list> <peerID>
@@ -12549,7 +12623,7 @@ sub CUL_HM_getIcon($) { #######################################################
Note that there could be more register implemented for a device.
- - saveConfig <file>
+ - saveConfig <file>
stores peers and register to the file.
Stored will be the data as available in fhem. It is necessary to read the information from the device prior to the save.
The command supports device-level action. I.e. if executed on a device also all related channel entities will be stored implicitely.
@@ -12562,7 +12636,7 @@ sub CUL_HM_getIcon($) { #######################################################
prior to rewrite data to an entity it is necessary to pair the device with FHEM.
restore will not delete any peered channels, it will just add peer channels.
- - list (normal|hidden);
+ - list (normal|hidden);
issue list command for the fiven entity normal or including the hidden parameter
- listDevice
@@ -12586,7 +12660,7 @@ sub CUL_HM_getIcon($) { #######################################################
- Attributes
+ Attributes
- eventMap
- do_not_notify
@@ -12594,12 +12668,12 @@ sub CUL_HM_getIcon($) { #######################################################
- dummy
- showtime
- readingFnAttributes
- - actAutoTry
+ - actAutoTry
actAutoTry 0_off,1_on
setting this option enables Action Detector to send a statusrequest in case of a device is going to be marked dead.
The attribut may be useful in case a device is being checked that does not send messages regularely - e.g. an ordinary switch.
- - actCycleactCycle <[hhh:mm]|off>
+ - actCycle <[hhh:mm]|off>
Supports 'alive' or better 'not alive' detection for devices. [hhh:mm] is the maximum silent time for the device.
Upon no message received in this period an event will be raised "<device> is dead".
If the device sends again another notification is posted "<device> is alive".
@@ -12615,18 +12689,18 @@ sub CUL_HM_getIcon($) { #######################################################
The overall function can be viewed checking out the "ActionDetector" entity. The status of all entities is present in the READING section.
Note: This function can be enabled for devices with non-cyclic messages as well. It is up to the user to enter a reasonable cycletime.
- - actStatus
+ - actStatus
readonly
This attribut is set by ActionDetector. It cannot be set manually
- - aesCommReq
+ - aesCommReq
if set IO is forced to request AES signature before sending ACK to the device.
Defautls to 0
- - aesKey
+ - aesKey
specifies which aes key is to be used if aesCommReq is active
- - autoReadReg
+ - autoReadReg
'0' autoReadReg will be ignored.
'1' will execute a getConfig for the device automatically after each reboot of FHEM.
'2' like '1' plus execute after power_on.
@@ -12645,14 +12719,14 @@ sub CUL_HM_getIcon($) { #######################################################
until the device "wakes up".
- burstAccess
+ burstAccess
can be set for the device entity if the model allowes conditionalBurst.
The attribut will switch off burst operations (0_off) which causes less message load
on HMLAN and therefore reduces the chance of HMLAN overload.
Setting it on (1_auto) allowes shorter reaction time of the device. User does not
need to wait for the device to wake up.
Note that also the register burstRx needs to be set in the device.
- expert <option1[[,option2],...]>
+ expert <option1[[,option2],...]>
This attribut controls the visibility of the register readings. This attibute controls
the presentation of device parameter in readings.
Options are:
@@ -12665,23 +12739,23 @@ sub CUL_HM_getIcon($) { #######################################################
If expert is applied to the device it is used for assotiated channels if not overwritten by it.
- communication status copied to channel reading
+ communication status copied to channel reading
on: device communication status not visible in channel entities
off: device communication status commState is visiblein channel entities
- firmware <FWversion>
+ firmware <FWversion>
Firmware version of the device. Should not be overwritten.
- hmKey <key>
+ hmKey <key>
AES key to be used
- hmKey2 <key>
+ hmKey2 <key>
AES key to be used
- hmKey3 <key>
+ hmKey3 <key>
AES key to be used
- hmProtocolEvents
+ hmProtocolEvents
parses and logs the device messages. This is performance consuming and may disturb the timing. Use with care.
Options:
@@ -12691,10 +12765,10 @@ sub CUL_HM_getIcon($) { #######################################################
3_dumpTrigger : log full and include trigger events
- readOnly
+ readOnly
1: restricts commands to read od observ only.
- readingOnDead
+ readingOnDead
defines how readings shall be treated upon device is marked 'dead'.
The attribute is applicable for devices only. It will modify the readings upon entering dead of the device.
Upon leaving state 'dead' the selected readings will be set to 'notDead'. It is expected that useful values will be filled by the normally operating device.
@@ -12716,12 +12790,12 @@ sub CUL_HM_getIcon($) { #######################################################
attr myDevice readingOnDead state,deviceMsg,CommandAccepted # upon entering dead state,deviceMsg and CommandAccepted of the device will be set to 'dead' if available.
-
+ rssiLog
can be given to devices, denied for channels. If switched '1' each RSSI entry will be
written to a reading. User may use this to log and generate a graph of RSSI level.
Due to amount of readings and events it is NOT RECOMMENDED to switch it on by default.
- IOgrp
+ IOgrp
can be given to devices and shall point to a virtual CCU.
Setting the attribut will remove attr IODev since it mutual exclusiv.
As a consequence the
@@ -12739,7 +12813,7 @@ sub CUL_HM_getIcon($) { #######################################################
attr myDevice2 IOgrp vccu:prefIO1,prefIO2,none
- levelRange <min,max>
+ levelRange <min,max>
It defines the usable dimm-range.
Can be used for e.g. LED light starting at 10% and reach maxbrightness at 40%.
levelRange will normalize the level to this range. I.e. set to 100% will physically set the
@@ -12752,32 +12826,32 @@ sub CUL_HM_getIcon($) { #######################################################
attr myChannel levelRange 10,80
- levelMap <=[:=[:...]]>
+ levelMap <=[:=[:...]]>
the level value valX will be replaced by keyX. Multiple values can be mapped.
- modelForce
+ modelForce
modelForce overwrites the model attribute. Doing that it converts the device and its channel to the new model.
Reason for this attribute is an eQ3 bug as some devices are delivered with wrong Module IDs.
ATTENTION: changing model id automatically starts reconfiguration of the device and its channels! channels may be deleted or incarnated
- model
+ model
showes model. This is read only.
- subType
+ subType
showes models subType. This is read only.
- serialNr
+ serialNr
device serial number. Should not be set manually
- msgRepeat
+ msgRepeat
defines number of repetitions if a device doesn't answer in time.
Devices which donly support config mode no repeat ist allowed.
For devices with wakeup mode the device will wait for next wakeup. Lonng delay might be
considered in this case.
Repeat for burst devices will impact HMLAN transmission capacity.
- param
+ param
param defines model specific behavior or functions. See available parameter for details
- peerIDs
+ peerIDs
will be filled automatically by getConfig and shows the direct peerings of the channel. Should not be changed by user.
- rawToReadable
+ rawToReadable
Used to convert raw KFM100 values to readable data, based on measured
values. E.g. fill slowly your container, while monitoring the
values reported with inform. You'll see:
@@ -12790,22 +12864,22 @@ sub CUL_HM_getIcon($) { #######################################################
Apply these values with: "attr KFM100 rawToReadable 10:0 50:20 79:40 270:100".
fhem will do a linear interpolation for values between the bounderies.
- tempListTmpl
+ tempListTmpl
Sets the default template for a heating controller. If not given the detault template is taken from
file tempList.cfg using the enitity name as template name (e.g. ./tempLict.cfg:RT1_Clima
- To avoid template usage set this attribut to '0'.
+ To avoid template usage set this attribut to 'none' or '0'.
Format is <file>:<templatename>. lt
- unit
+ unit
set the reported unit by the KFM100 if rawToReadable is active. E.g.
attr KFM100 unit Liter
- cyclicMsgOffset
+ cyclicMsgOffset
when calculating the timestamp for sending the next cyclic message (e.g. weather or valve data) then the value of this attribute
in milliseconds is added to the result. So adjusting this might fix problems for example when weather messages of virtual devices are not received reliably
- available parameter for attribut "param"
+ available parameter for attribut "param"
- HM-SEN-RD-O
offAtPon heat channel only: force heating off after powerOn
@@ -12814,7 +12888,7 @@ sub CUL_HM_getIcon($) { #######################################################
- virtuals
noOnOff virtual entity will not toggle state when trigger is received. If this parameter is
not given the entity will toggle its state between On and Off with each trigger
- msgReduce:<No> if channel is used for it skips every No message
+ msgReduce:<No> if channel is used for valvePos it skips every No message
in order to reduce transmit load. Numbers from 0 (no skip) up to 9 can be given.
VD will lose connection with more then 5 skips
@@ -12835,18 +12909,18 @@ sub CUL_HM_getIcon($) { #######################################################
This results eventually in state on-till which allowes better icon handling.
- Generated events:
+ Generated events:
- general
recentStateType:[ack|info] # cannot be used ti trigger notifies
- ack indicates that some statusinfo is derived from an acknowledge
- info indicates an autonomous message from the device
- - sabotageAttackId
+ - sabotageAttackId
Alarming configuration access to the device from a unknown source
- - sabotageAttack
+ - sabotageAttack
Alarming configuration access to the device that was not issued by our system
- - trigDst_<name>: noConfig
+ - trigDst_<name>: noConfig
A sensor triggered a Device which is not present in its peerList. Obviously the peerList is not up to date
@@ -13053,7 +13127,7 @@ sub CUL_HM_getIcon($) { #######################################################
[unlocked|locked|uncertain]
- Internals
+ Internals
- aesCommToDev
gives information about success or fail of AES communication between IO-device and HM-Device
@@ -13568,7 +13642,7 @@ sub CUL_HM_getIcon($) { #######################################################
- virtual
- peerChan siehe remote
- - press [long|short] [<peer>] [<repCount>] [<repDelay>]
+
- press [long|short] [<peer>] [<repCount>] [<repDelay>]
Simuliert den Tastendruck am Aktor eines gepeerted Sensors
- [long|short] soll ein langer oder kurzer Taastendrucl simuliert werden? Default ist kurz.
@@ -13577,11 +13651,11 @@ sub CUL_HM_getIcon($) { #######################################################
- [<repDelay>] nur gueltig fuer long. definiert die Zeit zwischen den einzelnen Messages.
- - virtTemp <[off -10..50]>
+
- virtTemp <[off -10..50]>
Simuliert ein Thermostat. Wenn mit einem Gerät gepeert wird periodisch eine Temperatur gesendet,
solange bis "off" gewählt wird. Siehe auch virtHum
- - virtHum <[off -10..50]>
+
- virtHum <[off -10..50]>
Simuliert den Feuchtigkeitswert eines Thermostats. Wenn mit einem Gerät verknüpft werden periodisch
Luftfeuchtigkeit undTemperatur gesendet, solange bis "off" gewählt wird. Siehe auch virtTemp
@@ -13760,12 +13834,12 @@ sub CUL_HM_getIcon($) { #######################################################
dürfen in der Liste nicht benutzt werden.
replay kann verwendet werden um den zuletzt gespielten Klang zu wiederholen.
repeat definiert wie oft die Sequenz ausgeführt werden soll. Standard ist 1.
- volume kann im Bereich 0..10 liegen. 0 stoppt jeden aktuell gespielten Sound. Standard ist 10 (100%.
+ volume kann im Bereich 0..10 liegen. 0 stoppt jeden aktuell gespielten Sound. Standard ist 10 (100%.
Beispiel:
set cfm_Mp3 playTone 3 # MP3 Titel 3 einmal
set cfm_Mp3 playTone 3 3 # MP3 Titel 3 dreimal
- set cfm_Mp3 playTone 3 1 5 # MP3 Titel 3 mit halber Lautstärke
+ set cfm_Mp3 playTone 3 1 5 # MP3 Titel 3 mit halber Lautstärke
set cfm_Mp3 playTone 3,6,8,3,4 # MP3 Titelfolge 3,6,8,3,4 einmal
set cfm_Mp3 playTone 3,6,8,3,4 255# MP3 Titelfolge 3,6,8,3,4 255 mal
set cfm_Mp3 playTone replay # Wiederhole letzte Sequenz
@@ -14031,7 +14105,8 @@ sub CUL_HM_getIcon($) { #######################################################
- Attribute
+
+ Attribute
- eventMap
- do_not_notify
@@ -14039,10 +14114,10 @@ sub CUL_HM_getIcon($) { #######################################################
- dummy
- showtime
- readingFnAttributes
- - readingOnDead
+ - readingOnDead
definiert wie readings behandelt werden sollten wenn das Device als 'dead' mariert wird.
Das Attribut ist nur auf Devices anwendbar. Es ändert die Readings wenn das Device nach dead geht.
- Beim Verlasen des Zustandes 'dead' werden die ausgewählten Readings nach 'notDead' geändert. Es kann erwartet werden, dass sinnvolle Werte vom Device eingetragen werden.
Upon leaving state 'dead' the selected readings will be set to 'notDead'. It is expected that useful values will be filled by the normally operating device.
+ Beim Verlasen des Zustandes 'dead' werden die ausgewählten Readings nach 'notDead' geändert. Es kann erwartet werden, dass sinnvolle Werte vom Device eingetragen werden.
Optionen sind:
noChange: keine Readings ausser Actvity werden geändert. Andere Einträge werden ignoriert.
state: das Reading 'state' wird auf 'dead' gesetzt.
@@ -14061,7 +14136,7 @@ sub CUL_HM_getIcon($) { #######################################################
attr myDevice readingOnDead state,deviceMsg,CommandAccepted # beim Eintreten in dead state,deviceMsg und CommandAccepted des Device werden, wenn verfuegbar, auf 'dead' gesetzt.
- aesCommReq
+ aesCommReq
wenn gesetzt wird IO AES signature anfordern bevor ACK zum Device gesendet wird.
actAutoTry
@@ -14069,7 +14144,7 @@ sub CUL_HM_getIcon($) { #######################################################
setzen erlaubt dem ActionDetector ein statusrequest zu senden falls das Device dead markiert werden soll.
Das Attribut kann für Devices nützlich sein, welche sich nicht von selbst zyklisch melden.
- actCycle
+ actCycle
actCycle <[hhh:mm]|off>
Bietet eine 'alive' oder besser 'not alive' Erkennung für Geräte. [hhh:mm] ist die maximale Zeit ohne Nachricht eines Geräts. Wenn innerhalb dieser Zeit keine Nachricht empfangen wird so wird das Event"<device> is dead" generiert.
Sendet das Gerät wieder so wird die Nachricht"<device> is alive" ausgegeben.
@@ -14084,7 +14159,10 @@ sub CUL_HM_getIcon($) { #######################################################
Die gesamte Funktion kann über den "ActionDetector"-Eintrag überprüft werden. Der Status aller Instanzen liegt im READING-Bereich.
Hinweis: Diese Funktion kann ebenfalls für Geräte ohne zyklische Übertragung aktiviert werden. Es obliegt dem Nutzer eine vernünftige Zeitspanne festzulegen.
- autoReadReg
+ aesKey
+ Spezifiziert, welcher aes key verwendet wird, falls aesCommReq aktiviert wird.
+
+ autoReadReg
'0' autoReadReg wird ignorert.
'1' wird automatisch in getConfig ausgeführt für das Device nach jedem reboot von FHEM.
'2' wie '1' plus nach Power on.
@@ -14100,7 +14178,7 @@ sub CUL_HM_getIcon($) { #######################################################
Das Setzen auf Level 5 wird für alle Devices und Typen empfohlen, auch wakeup Devices.
- burstAccess
+ burstAccess
kann für eine Geräteinstanz gesetzt werden falls das Model bedingte Bursts erlaubt.
Das Attribut deaktiviert den Burstbetrieb (0_off) was die Nachrichtenmenge des HMLAN reduziert
und damit die Wahrscheinlichkeit einer Überlast von HMLAN verringert.
@@ -14108,7 +14186,7 @@ sub CUL_HM_getIcon($) { #######################################################
bis das Gerät wach ist.
Zu beachten ist, dass das Register "burstRx" im Gerät ebenfalls gesetzt werden muss.
- expert
+ expert
Dieses Attribut steuert die Sichtbarkeit der Register Readngs. Damit wird die Darstellung der Geräteparameter kontrolliert.
Es handdelt sich um einen binaer kodierten Wert mit folgenden Empfehlungen:
@@ -14130,7 +14208,7 @@ sub CUL_HM_getIcon($) { #######################################################
- readOnly
beschränkt kommandos auf Lesen und Beobachten.
- - IOgrp
+ - IOgrp
kann an Devices vergeben werden und zeigt auf eine virtuelle VCCU.
Das Setzen des Attributs führt zum Löschen des Attributs IODev da sich diese ausschliessen.
Danach wird die VCCU
@@ -14147,7 +14225,7 @@ sub CUL_HM_getIcon($) { #######################################################
attr myDevice2 IOgrp vccu:prefIO1,prefIO2,none
- levelRange
+ levelRange
nur für Dimmer! Der Dimmbereich wird eingeschränkt.
Es ist gedacht um z.B. LED Lichter unterstützen welche mit 10% beginnen und bei 40% bereits das Maximum haben.
levelrange normalisiert den Bereich entsprechend. D.h. set 100 wird physikalisch den Dimmer auf 40%,
@@ -14165,31 +14243,31 @@ sub CUL_HM_getIcon($) { #######################################################
attr myChannel levelRange 10,80
- tempListTmpl
+ tempListTmpl
Setzt das Default für Heizungskontroller. Ist es nicht gesetzt wird der default filename genutzt und der name
der entity als templatename. Z.B. ./tempList.cfg:RT_Clima
- Um das template nicht zu nutzen kann man es auf '0'setzen.
+ Um das template nicht zu nutzen kann man es auf 'none' oder '0'setzen.
Format ist <file>:<templatename>.
- modelForce
+ modelForce
modelForce überschreibt das model attribut. Dabei wird das Device und seine Kanäle reconfguriert.
Grund für dieses Attribut ist ein eQ3 bug bei welchen Devices mit falscher ID ausgeliefert werden. Das Attribut
erlaubt dies zu ueberschreiben
ACHTUNG: Durch das Eintragen eines anderen model werden die Entites modifiziert, ggf. neu angelegt oder gelöscht.
- model
+ model
wird automatisch gesetzt.
- subType
+ subType
wird automatisch gesetzt.
- param
+ param
'param' definiert modelspezifische Verhalten oder Funktionen. Siehe "models" für Details.
- msgRepeat
+ msgRepeat
Definiert die Nummer an Wiederholungen falls ein Gerät nicht rechtzeitig antwortet.
Für Geräte die nur den "Config"-Modus unterstützen sind Wiederholungen nicht erlaubt.
Bei Geräte mit wakeup-Modus wartet das Gerät bis zum nächsten Aufwachen. Eine längere Verzögerung
sollte in diesem Fall angedacht werden.
Wiederholen von Bursts hat Auswirkungen auf die HMLAN Übertragungskapazität.
- rawToReadable
+ rawToReadable
Wird verwendet um Rohdaten von KFM100 in ein lesbares Fomrat zu bringen, basierend auf
den gemessenen Werten. Z.B. langsames Füllen eines Tanks, während die Werte mit inform
angezeigt werden. Man sieht:
@@ -14202,11 +14280,11 @@ sub CUL_HM_getIcon($) { #######################################################
Anwenden dieser Werte: "attr KFM100 rawToReadable 10:0 50:20 79:40 270:100".
FHEM für damit eine lineare Interpolation der Werte in den gegebenen Grenzen aus.
- unit
+ unit
setzt die gemeldete Einheit des KFM100 falls 'rawToReadable' aktiviert ist. Z.B.
attr KFM100 unit Liter
- autoReadReg
+ autoReadReg
'0' autoReadReg wird ignoriert.
'1' führt ein "getConfig" für ein Gerät automatisch nach jedem Neustart von FHEM aus.
'2' verhält sich wie '1',zusätzlich nach jedem power_on.
@@ -14228,7 +14306,7 @@ sub CUL_HM_getIcon($) { #######################################################
- verfügbare Parameter für "param"
+ verfügbare Parameter für "param"
- HM-SEN-RD-O
offAtPon: nur Heizkanäle: erzwingt Ausschalten der Heizung nach einem powerOn
@@ -14237,7 +14315,7 @@ sub CUL_HM_getIcon($) { #######################################################
- virtuals
noOnOff: eine virtuelle Instanz wird den Status nicht ändern wenn ein Trigger empfangen wird. Ist dieser Paramter
nicht gegeben so toggled die Instanz ihren Status mit jedem trigger zwischen An und Aus
- msgReduce: falls gesetzt und der Kanal wird für genutzt wird jede Nachricht
+ msgReduce: falls gesetzt und der Kanal wird für valvePos genutzt wird jede Nachricht
außer die der Ventilstellung verworfen um die Nachrichtenmenge zu reduzieren
- blind