diff --git a/fhem/FHEM/10_CUL_HM.pm b/fhem/FHEM/10_CUL_HM.pm index 7f209a162..4b9a697c4 100755 --- a/fhem/FHEM/10_CUL_HM.pm +++ b/fhem/FHEM/10_CUL_HM.pm @@ -299,7 +299,7 @@ sub CUL_HM_updateConfig($){ if ($attr{$name}{expert});#need update after readings are available if ($chn eq "03" && - $md =~ /(HM-CC-TC|ROTO_ZEL-STG-RM-FWT|HM-CC-RT-DN)/){ + $md =~ /(-TC|ROTO_ZEL-STG-RM-FWT|HM-CC-RT-DN)/){ $attr{$name}{stateFormat} = "last:trigLast"; } @@ -724,7 +724,7 @@ sub CUL_HM_Parse($$) {############################## my $i=0; $devH->{helper}{rpt}{ts} = gettimeofday(); CUL_HM_SndCmd(${$ack}[$i++],${$ack}[$i++]) while ($i<@{$ack}); - Log3 $name,4,"CUL_HM $name dupe: repeat ack, dont process"; + Log3 $name,4,"CUL_HM $name dupe: repeat ".scalar(@{$ack})." ack, dont process"; } else{ Log3 $name,4,"CUL_HM $name dupe: dont process"; diff --git a/fhem/FHEM/98_HMinfo.pm b/fhem/FHEM/98_HMinfo.pm index 74e65595a..c36645ee3 100644 --- a/fhem/FHEM/98_HMinfo.pm +++ b/fhem/FHEM/98_HMinfo.pm @@ -406,6 +406,60 @@ sub HMinfo_tempList(@) { ###################################################### } return $ret; } +sub HMinfo_tempListTmpl(@) { ################################################## + my ($filter,$tmpl,$fName)=@_; + $filter = "." if (!$filter); + return "no template name given" if (!$tmpl); + my $ret; + my @el ; + foreach my $eN(HMinfo_getEntities("d")){#search for devices and select correct channel + my $md = AttrVal($eN,"model",""); + my $chN; #tempList channel name + if ($md =~ m/(HM-CC-RT-DN-BoM|HM-CC-RT-DN)/) {$chN = $defs{$eN}{channel_04};} + elsif ($md =~ m/(ROTO_ZEL-STG-RM-FWT|HM-CC-TC)/){$chN = $defs{$eN}{channel_02};} + next if (!$chN || !$defs{$chN} || $chN !~ m/$filter/); + push @el; + } + return "no entities selected" if (!scalar @el); + + open(aSave, "$fName") || return("Can't open $fName: $!"); + my $found = 0; + my @entryFail = (); + my @exec = (); + while(){ + chomp; + if($_ =~ m/^entities:/){ + last if ($found != 0); + my $line = $_; + $line =~s/.*://; + foreach (split(",",$line)){ + $found = 1 if ($defs{$_} && $_ eq $tmpl); + } + } + elsif($found != 1 && $_ =~ m/tempList[SMFWT].*\>/){ + my ($tln,$val) = ($1,$2)if($_ =~ m/(.*)>(.*)/); + $tln =~ s/ //g; + $val =~ tr/ +/ /; + $val =~ s/^ //; + $val =~ s/ $//; + @exec = (); + foreach my $eN(@el){ + my $x = CUL_HM_Set($defs{$eN},$eN,$tln,"prep",split(" ",$val)); + push @entryFail,$eN." :".$tln." respose:$x" if ($x != 1); + push @exec,$eN." ".$tln." exec ".$val; + } + } + + foreach (@exec){ + my @param = split(" ",$_); + CUL_HM_Set($defs{$param[0]},@param); + } + + $ret = "failed Entries:\n " .join("\n ",@entryFail) if (scalar@entryFail); + } + close(aSave); + return $ret; +} sub HMinfo_getEntities(@) { ################################################### my ($filter,$re) = @_; @@ -812,10 +866,44 @@ sub HMinfo_SetFn($@) {######################################################### $ret = HMinfo_status($hash); } elsif($cmd eq "tempList") {##handle thermostat templist from file --------- - my $fn = $a[0]?$a[0]:"tempList.cfg"; + my $fn = $a[1]?$a[1]:"tempList.cfg"; $fn = AttrVal($name,"configDir",".")."\/".$fn if ($fn !~ m/\//); $ret = HMinfo_tempList($filter,$a[0],$fn); } + elsif($cmd eq "tempListTmpl"){##handle thermostat templist from file --------- + my $fn = $a[1]?$a[1]:"tempList.cfg"; + $fn = AttrVal($name,"configDir",".")."\/".$fn if ($fn !~ m/\//); + $ret = HMinfo_tempListTmpl($filter,$a[0],$fn); + } + elsif($cmd eq "loadConfig") {##action: saveConfig---------------------------- + my $fn = $a[0]?$a[0]:AttrVal($name,"configFilename","regSave.cfg"); + $fn = AttrVal($name,"configDir",".")."\/".$fn if ($fn !~ m/\//); + $ret = HMinfo_loadConfig($filter,$fn); + } + elsif($cmd eq "purgeConfig"){##action: saveConfig---------------------------- + my $id = ++$hash->{nb}{cnt}; + my $fn = $a[0]?$a[0]:AttrVal($name,"configFilename","regSave.cfg"); + $fn = AttrVal($name,"configDir",".")."\/".$fn if ($fn !~ m/\//); + my $bl = BlockingCall("HMinfo_purgeConfig", join(",",("$name:$id",$fn)), + "HMinfo_bpPost", 30, + "HMinfo_bpAbort", "$name:$id"); + $hash->{nb}{$id}{$_} = $bl->{$_} foreach (keys %{$bl}); + $ret = ""; + } + elsif($cmd eq "saveConfig") {##action: saveConfig---------------------------- + my $id = ++$hash->{nb}{cnt}; + my $fn = $a[0]?$a[0]:AttrVal($name,"configFilename","regSave.cfg"); + $fn = AttrVal($name,"configDir",".")."\/".$fn if ($fn !~ m/\//); + my $bl = BlockingCall("HMinfo_saveConfig", join(",",("$name:$id",$fn,$opt,$filter)), + "HMinfo_bpPost", 30, + "HMinfo_bpAbort", "$name:$id"); + $hash->{nb}{$id}{$_} = $bl->{$_} foreach (keys %{$bl}); + $ret = $cmd." done:" ."\n saved"; + } + elsif($cmd eq "archConfig") {##action: archiveConfig------------------------- + # save config only if register are complete + $ret = HMinfo_archConfig($hash,$name,$opt,($a[0]?$a[0]:"")); + } elsif($cmd eq "help") { $ret = " Unknown argument $cmd, choose one of " ."\n ---checks---" @@ -829,6 +917,7 @@ sub HMinfo_SetFn($@) {######################################################### ."\n loadConfig [] # restores register and peer readings if missing" ."\n autoReadReg [] # trigger update readings if attr autoReadReg is set" ."\n tempList [][save|restore|verify][]# handle tempList of thermostat devices" + ."\n tempListTmpl[][templateName][]# program a templist from a template in the file to one or multiple devices" ."\n ---infos---" ."\n update # update HMindfo counts" ."\n register [] # devicefilter parse devicename. Partial strings supported" @@ -881,35 +970,6 @@ sub HMinfo_SetFn($@) {######################################################### ."\n " ; } - elsif($cmd eq "loadConfig") {##action: saveConfig---------------------------- - my $fn = $a[0]?$a[0]:AttrVal($name,"configFilename","regSave.cfg"); - $fn = AttrVal($name,"configDir",".")."\/".$fn if ($fn !~ m/\//); - $ret = HMinfo_loadConfig($filter,$fn); - } - elsif($cmd eq "purgeConfig"){##action: saveConfig---------------------------- - my $id = ++$hash->{nb}{cnt}; - my $fn = $a[0]?$a[0]:AttrVal($name,"configFilename","regSave.cfg"); - $fn = AttrVal($name,"configDir",".")."\/".$fn if ($fn !~ m/\//); - my $bl = BlockingCall("HMinfo_purgeConfig", join(",",("$name:$id",$fn)), - "HMinfo_bpPost", 30, - "HMinfo_bpAbort", "$name:$id"); - $hash->{nb}{$id}{$_} = $bl->{$_} foreach (keys %{$bl}); - $ret = ""; - } - elsif($cmd eq "saveConfig") {##action: saveConfig---------------------------- - my $id = ++$hash->{nb}{cnt}; - my $fn = $a[0]?$a[0]:AttrVal($name,"configFilename","regSave.cfg"); - $fn = AttrVal($name,"configDir",".")."\/".$fn if ($fn !~ m/\//); - my $bl = BlockingCall("HMinfo_saveConfig", join(",",("$name:$id",$fn,$opt,$filter)), - "HMinfo_bpPost", 30, - "HMinfo_bpAbort", "$name:$id"); - $hash->{nb}{$id}{$_} = $bl->{$_} foreach (keys %{$bl}); - $ret = $cmd." done:" ."\n saved"; - } - elsif($cmd eq "archConfig") {##action: archiveConfig------------------------- - # save config only if register are complete - $ret = HMinfo_archConfig($hash,$name,$opt,($a[0]?$a[0]:"")); - } else{ my @cmdLst = ( "autoReadReg","clear" #"clear:msgStat,Protocol,readings,register,rssi" @@ -918,7 +978,7 @@ sub HMinfo_SetFn($@) {######################################################### ,"models" ,"regCheck","register","archConfig:-0,-a","saveConfig","loadConfig","purgeConfig","update" ,"cpRegs" - ,"tempList" + ,"tempList tempListTmpl" ,"templateChk","templateDef","templateList","templateSet"); $ret = join (" ",sort @cmdLst); } @@ -1781,8 +1841,14 @@ sub HMinfo_noDup(@) {#return list with no duplicates The actual entity holding the templist must be given - which is channel 04 for RTs or channel 02 for TCs
  • tempList... time and temp couples as used in the set tempList commands

  • - +
  • tempListTmpl [filter][templateName] [<file>]
    + program one or more thermostat lists. The list of thermostats is selected by filter.
    +
  • templateName is the name of the template as being named in the file. The file format ist + identical to tempList. If the entity in the file matches templateName the subsequent + temp-settings from the file are bing programmed to all Thermostats that match the filter
  • +
  • filename is the name of the file to be used. Default ist tempList.cfg
  • +
  • cpRegs <src:peer> <dst:peer>
    allows to copy register, setting and behavior of a channel to diff --git a/fhem/FHEM/HMConfig.pm b/fhem/FHEM/HMConfig.pm index f1b453b68..807c532b9 100644 --- a/fhem/FHEM/HMConfig.pm +++ b/fhem/FHEM/HMConfig.pm @@ -663,8 +663,8 @@ my $K_actDetID = '000000'; # id of actionDetector heatCool =>{a=> 15.7,s=>0.1,l=>7,min=>0 ,max=>1 ,c=>'lit' ,f=>'' ,u=>'' ,d=>1,t=>"select heating or cooling" ,lit=>{heating=>0,cooling=>1}}, weekPrgSel =>{a=> 16.0,s=>1.0,l=>7,min=>0 ,max=>2 ,c=>'lit' ,f=>'' ,u=>'' ,d=>1,t=>"select week program" ,lit=>{prog1=>0,prog2=>1,prog1=>2}}, - modePrioParty =>{a=> 18.0,s=>0.3,l=>7,min=>0 ,max=>5 ,c=>'lit' ,f=>'' ,u=>'' ,d=>1,t=>"allow tempChange for party only by..." ,lit=>{RT_TC_SC_SELF=>0,all=>1,RT_TC_CCU_SELF=>2,CCU=>3,self=>4}}, - modePrioManu =>{a=> 18.3,s=>0.3,l=>7,min=>0 ,max=>5 ,c=>'lit' ,f=>'' ,u=>'' ,d=>1,t=>"allow tempChange for manual only by..." ,lit=>{RT_TC_SC_SELF=>0,all=>1,RT_TC_CCU_SELF=>2,CCU=>3,self=>4}}, + modePrioParty =>{a=> 18.0,s=>0.3,l=>7,min=>0 ,max=>5 ,c=>'lit' ,f=>'' ,u=>'' ,d=>1,t=>"allow tempChange for party only by..." ,lit=>{RT_TC_SC_SELF=>0,all=>1,RT_TC_CCU_SELF=>2,CCU=>3,self=>4}}, + modePrioManu =>{a=> 18.3,s=>0.3,l=>7,min=>0 ,max=>5 ,c=>'lit' ,f=>'' ,u=>'' ,d=>1,t=>"allow tempChange for manual only by..." ,lit=>{RT_TC_SC_SELF=>0,all=>1,RT_TC_CCU_SELF=>2,CCU=>3,self=>4}}, winOpnMode =>{a=> 19.5,s=>0.3,l=>7,min=>0 ,max=>4 ,c=>'lit' ,f=>'' ,u=>'' ,d=>1,t=>"enable internal Windoe open in modes: " ,lit=>{off=>0,auto=>1,auto_manu=>2,auto_party=>3,on=>4}}, winOpnDetFall =>{a=> 19.0,s=>0.5,l=>7,min=>0.5,max=>2.5 ,c=>'' ,f=>'10' ,u=>'K' ,d=>1,t=>"detect Window Open if temp falls more then..."},