2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-20 13:26:02 +00:00

autoReadReg, sort variables to groups, register modification marking set_

git-svn-id: https://svn.fhem.de/fhem/trunk@2316 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
martinp876 2012-12-11 22:13:42 +00:00
parent f2b7d76bf5
commit ac857e00c7
2 changed files with 160 additions and 100 deletions

View File

@ -15,7 +15,7 @@ sub HMLAN_secSince2000();
sub HMLAN_SimpleWrite(@); sub HMLAN_SimpleWrite(@);
my $debug = 1; # set 1 for better log readability my $debug = 0; # set 1 for better log readability
my %sets = ( my %sets = (
"hmPairForSec" => "HomeMatic", "hmPairForSec" => "HomeMatic",
"hmPairSerial" => "HomeMatic", "hmPairSerial" => "HomeMatic",
@ -220,7 +220,7 @@ HMLAN_Write($$$)
my $IDadd = '+'.$dst.',00,00,'; # guess: add ID? my $IDadd = '+'.$dst.',00,00,'; # guess: add ID?
my $IDsub = '-'.$dst; # guess: ID remove? my $IDsub = '-'.$dst; # guess: ID remove?
HMLAN_SimpleWrite($hash, $IDadd) if (!$lhash{$dst}); HMLAN_SimpleWrite($hash, $IDadd) if (!$lhash{$dst} && $dst ne "000000");
$lhash{$dst} = 1; $lhash{$dst} = 1;
my $tm = int(gettimeofday()*1000) % 0xffffffff; my $tm = int(gettimeofday()*1000) % 0xffffffff;

View File

@ -4,6 +4,8 @@
package main; package main;
# update actiondetector is supported with lines marked as "#todo Updt1 remove"
# the lines can be removed after some soak time - around version 2600
use strict; use strict;
use warnings; use warnings;
#use Time::HiRes qw(gettimeofday); #use Time::HiRes qw(gettimeofday);
@ -213,14 +215,10 @@ CUL_HM_Initialize($)
"showtime:1,0 loglevel:0,1,2,3,4,5,6 ". "showtime:1,0 loglevel:0,1,2,3,4,5,6 ".
"hmClass:receiver,sender serialNr firmware devInfo ". "hmClass:receiver,sender serialNr firmware devInfo ".
"rawToReadable unit ". "rawToReadable unit ".
"chanNo device peerList peerIDs ". "peerList ". #todo Updt1 remove
"actCycle actStatus ". "peerIDs ".
"protCmdPend protLastRcv protSndCnt protSndLast protCmdDel protNackCnt protNackLast protState ". "actCycle actStatus autoReadReg:1,0 ".
"protResndFailLast protResndLast protResndFailCnt protResndCnt protToutRespLast protToutRespCnt ". "";
"channel_01 channel_02 channel_03 channel_04 channel_05 channel_06 ".
"channel_07 channel_08 channel_09 channel_0A channel_0B channel_0C ".
"channel_0D channel_0E channel_0F channel_10 channel_11 channel_12 ".
"channel_13 channel_14 channel_15 channel_16 channel_17 channel_18";
my @modellist; my @modellist;
foreach my $model (keys %culHmModel){ foreach my $model (keys %culHmModel){
push @modellist,$culHmModel{$model}{name}; push @modellist,$culHmModel{$model}{name};
@ -229,6 +227,21 @@ CUL_HM_Initialize($)
$hash->{AttrList} .= " subType:".join(",", sort $hash->{AttrList} .= " subType:".join(",", sort
map { $culHmDevProps{$_}{st} } keys %culHmDevProps); map { $culHmDevProps{$_}{st} } keys %culHmDevProps);
CUL_HM_initRegHash(); CUL_HM_initRegHash();
}
sub
CUL_HM_updateConfig($){
foreach (@{$modules{CUL_HM}{helper}{updtCfgLst}}){
my $name = shift(@{$modules{CUL_HM}{helper}{updtCfgLst}});
if (1 == AttrVal($name,"autoReadReg","0")){
CUL_HM_Set(CUL_HM_name2Hash($name),$name,"getConfig");
CUL_HM_Set(CUL_HM_name2Hash($name),$name,"statusRequest");
InternalTimer(gettimeofday()+15,"CUL_HM_updateConfig", "updateConfig", 0);
last;
}
else{
}
}
} }
############################# #############################
sub sub
@ -252,10 +265,10 @@ CUL_HM_Define($$)
$modules{CUL_HM}{defptr}{$HMid} = $hash; $modules{CUL_HM}{defptr}{$HMid} = $hash;
AssignIoPort($hash); AssignIoPort($hash);
my $devName = $devHash->{NAME}; my $devName = $devHash->{NAME};
$attr{$name}{device} = $devName; $hash->{device} = $devName;
$attr{$name}{chanNo} = $chn; $hash->{chanNo} = $chn;
$attr{$name}{model} = $attr{$devName}{model} if ($attr{$devName}{model}); $attr{$name}{model} = $attr{$devName}{model} if ($attr{$devName}{model});
$attr{$devName}{"channel_$chn"} = $name; $devHash->{"channel_$chn"} = $name;
} }
else{# define a device else{# define a device
$modules{CUL_HM}{defptr}{$HMid} = $hash; $modules{CUL_HM}{defptr}{$HMid} = $hash;
@ -266,6 +279,15 @@ CUL_HM_Define($$)
$hash->{DEF} = $a[2]; $hash->{DEF} = $a[2];
CUL_HM_Parse($hash, $a[3]); CUL_HM_Parse($hash, $a[3]);
} }
RemoveInternalTimer("updateConfig");
InternalTimer(gettimeofday()+5,"CUL_HM_updateConfig", "updateConfig", 0);
my @arr;
if(!$modules{CUL_HM}{helper}{updtCfgLst}){
$modules{CUL_HM}{helper}{updtCfgLst} = \@arr;
}
push(@{$modules{CUL_HM}{helper}{updtCfgLst}}, $name);
return undef; return undef;
} }
############################# #############################
@ -273,15 +295,16 @@ sub
CUL_HM_Undef($$) CUL_HM_Undef($$)
{ {
my ($hash, $name) = @_; my ($hash, $name) = @_;
my $devName = $attr{$name}{device}; my $devName = $hash->{device};
my $HMid = $hash->{DEF}; my $HMid = $hash->{DEF};
my $chn = substr($HMid,6,2); my $chn = substr($HMid,6,2);
if ($chn){# delete a channel if ($chn){# delete a channel
delete $attr{$devName}{"channel_$chn"} if ($devName); my $devHash = CUL_HM_name2Hash($devName);
delete $devHash->{"channel_$chn"} if ($devName);
} }
else{# delete a device else{# delete a device
foreach my $channel (keys %{$attr{$name}}){ foreach my $channel (keys %{$hash}){
CommandDelete(undef,$attr{$name}{$channel}) CommandDelete(undef,$hash->{$channel})
if ($channel =~ m/^channel_/); if ($channel =~ m/^channel_/);
} }
} }
@ -295,15 +318,18 @@ CUL_HM_Rename($$$)
#my ($hash, $name,$newName) = @_; #my ($hash, $name,$newName) = @_;
my ($name, $oldName) = @_; my ($name, $oldName) = @_;
my $HMid = CUL_HM_name2Id($name); my $HMid = CUL_HM_name2Id($name);
my $hash = CUL_HM_name2Hash($name);
if (length($HMid) == 8){# we are channel, inform the device if (length($HMid) == 8){# we are channel, inform the device
$attr{$name}{chanNo} = substr($HMid,6,2); $hash->{chanNo} = substr($HMid,6,2);
my $device = AttrVal($name, "device", ""); my $device = $hash->{device}?$hash->{device}:"";
$attr{$device}{"channel_".$attr{$name}{chanNo}} = $name if ($device); my $devHash = CUL_HM_name2Hash($device);
$devHash->{"channel_".$hash->{chanNo}} = $name if ($device);
} }
else{# we are a device - inform channels if exist else{# we are a device - inform channels if exist
for (my$chn = 1; $chn <25;$chn++){ for (my$chn = 1; $chn <25;$chn++){
my $chnName = AttrVal($name, sprintf("channel_%02X",$chn), ""); my $chnName = $hash->{sprintf("channel_%02X",$chn)};
$attr{$chnName}{device} = $name if ($chnName); my $chnHash = CUL_HM_name2Hash($chnName);
$chnHash->{device} = $name if ($chnName);
} }
} }
return; return;
@ -1119,7 +1145,7 @@ my %culHmRegDefShLg = (# register that are available for short AND long button p
actionType =>{a=> 10.0,s=>0.2,l=>3,min=>0 ,max=>3 ,c=>'lit' ,f=>'' ,u=>'' ,d=>0,t=>"" ,lit=>{off=>0,jmpToTarget=>1,toggleToCnt=>2,toggleToCntInv=>3}}, actionType =>{a=> 10.0,s=>0.2,l=>3,min=>0 ,max=>3 ,c=>'lit' ,f=>'' ,u=>'' ,d=>0,t=>"" ,lit=>{off=>0,jmpToTarget=>1,toggleToCnt=>2,toggleToCntInv=>3}},
OnTimeMode =>{a=> 10.0,s=>0.1,l=>3,min=>0 ,max=>1 ,c=>'lit' ,f=>'' ,u=>'' ,d=>0,t=>"on time mode" ,lit=>{absolut=>0,minimal=>1}}, OnTimeMode =>{a=> 10.0,s=>0.1,l=>3,min=>0 ,max=>1 ,c=>'lit' ,f=>'' ,u=>'' ,d=>0,t=>"on time mode" ,lit=>{absolut=>0,minimal=>1}},
OffTimeMode =>{a=> 10.6,s=>0.1,l=>3,min=>0 ,max=>1 ,c=>'lit' ,f=>'' ,u=>'' ,d=>0,t=>"off time mode",lit=>{absolut=>0,minimal=>1}}, OffTimeMode =>{a=> 10.6,s=>0.1,l=>3,min=>0 ,max=>1 ,c=>'lit' ,f=>'' ,u=>'' ,d=>0,t=>"off time mode",lit=>{absolut=>0,minimal=>1}},
#dimmer mainly #dimmer mainly
OnDly =>{a=> 6.0,s=>1.0,l=>3,min=>0 ,max=>111600 ,c=>'fltCvT' ,f=>'' ,u=>'s' ,d=>0,t=>"on delay "}, OnDly =>{a=> 6.0,s=>1.0,l=>3,min=>0 ,max=>111600 ,c=>'fltCvT' ,f=>'' ,u=>'s' ,d=>0,t=>"on delay "},
OnTime =>{a=> 7.0,s=>1.0,l=>3,min=>0 ,max=>111600 ,c=>'fltCvT' ,f=>'' ,u=>'s' ,d=>0,t=>"on time"}, OnTime =>{a=> 7.0,s=>1.0,l=>3,min=>0 ,max=>111600 ,c=>'fltCvT' ,f=>'' ,u=>'s' ,d=>0,t=>"on time"},
OffDly =>{a=> 8.0,s=>1.0,l=>3,min=>0 ,max=>111600 ,c=>'fltCvT' ,f=>'' ,u=>'s' ,d=>0,t=>"off delay"}, OffDly =>{a=> 8.0,s=>1.0,l=>3,min=>0 ,max=>111600 ,c=>'fltCvT' ,f=>'' ,u=>'s' ,d=>0,t=>"off delay"},
@ -1182,7 +1208,7 @@ my %culHmRegDefine = (
#blindActuator mainly #blindActuator mainly
driveUp =>{a=> 13.0,s=>2.0,l=>1,min=>0 ,max=>6000.0 ,c=>'factor' ,f=>10 ,u=>'s' ,d=>1,t=>"drive time up"}, driveUp =>{a=> 13.0,s=>2.0,l=>1,min=>0 ,max=>6000.0 ,c=>'factor' ,f=>10 ,u=>'s' ,d=>1,t=>"drive time up"},
driveDown =>{a=> 11.0,s=>2.0,l=>1,min=>0 ,max=>6000.0 ,c=>'factor' ,f=>10 ,u=>'s' ,d=>1,t=>"drive time up"}, driveDown =>{a=> 11.0,s=>2.0,l=>1,min=>0 ,max=>6000.0 ,c=>'factor' ,f=>10 ,u=>'s' ,d=>1,t=>"drive time up"},
driveTurn =>{a=> 15.0,s=>1.0,l=>1,min=>0 ,max=>6000.0 ,c=>'factor' ,f=>10 ,u=>'s' ,d=>0,t=>"fliptime up <=>down"}, driveTurn =>{a=> 15.0,s=>1.0,l=>1,min=>0 ,max=>6000.0 ,c=>'factor' ,f=>10 ,u=>'s' ,d=>1,t=>"fliptime up <=>down"},
#remote mainly #remote mainly
language =>{a=> 7.0,s=>1.0,l=>0,min=>0 ,max=>1 ,c=>'' ,f=>'' ,u=>'' ,d=>1,t=>"Language 0:English, 1:German"}, language =>{a=> 7.0,s=>1.0,l=>0,min=>0 ,max=>1 ,c=>'' ,f=>'' ,u=>'' ,d=>1,t=>"Language 0:English, 1:German"},
stbyTime =>{a=> 14.0,s=>1.0,l=>0,min=>1 ,max=>99 ,c=>'' ,f=>'' ,u=>'s' ,d=>1,t=>"Standby Time"}, stbyTime =>{a=> 14.0,s=>1.0,l=>0,min=>1 ,max=>99 ,c=>'' ,f=>'' ,u=>'s' ,d=>1,t=>"Standby Time"},
@ -1191,8 +1217,8 @@ my %culHmRegDefine = (
backOnTime =>{a=> 14.0,s=>1.0,l=>0,min=>0 ,max=>255 ,c=>'' ,f=>'' ,u=>'s' ,d=>1,t=>"Backlight On Time"}, backOnTime =>{a=> 14.0,s=>1.0,l=>0,min=>0 ,max=>255 ,c=>'' ,f=>'' ,u=>'s' ,d=>1,t=>"Backlight On Time"},
longPress =>{a=> 4.4,s=>0.4,l=>1,min=>0.3,max=>1.8 ,c=>'m10s3' ,f=>'' ,u=>'s' ,d=>0,t=>"time to detect key long press"}, longPress =>{a=> 4.4,s=>0.4,l=>1,min=>0.3,max=>1.8 ,c=>'m10s3' ,f=>'' ,u=>'s' ,d=>0,t=>"time to detect key long press"},
dblPress =>{a=> 9.0,s=>0.4,l=>1,min=>0 ,max=>1.5 ,c=>'factor' ,f=>10 ,u=>'s' ,d=>0,t=>"time to detect double press"}, dblPress =>{a=> 9.0,s=>0.4,l=>1,min=>0 ,max=>1.5 ,c=>'factor' ,f=>10 ,u=>'s' ,d=>0,t=>"time to detect double press"},
peerNeedsBurst =>{a=> 1.0,s=>0.1,l=>4,min=>0 ,max=>1 ,c=>'lit' ,f=>'' ,u=>'' ,d=>0,t=>"peer expects burst",lit=>{off=>0,on=>1}}, peerNeedsBurst =>{a=> 1.0,s=>0.1,l=>4,min=>0 ,max=>1 ,c=>'lit' ,f=>'' ,u=>'' ,d=>1,t=>"peer expects burst",lit=>{off=>0,on=>1}},
expectAES =>{a=> 1.7,s=>0.1,l=>4,min=>0 ,max=>1 ,c=>'lit' ,f=>'' ,u=>'' ,d=>0,t=>"expect AES" ,lit=>{off=>0,on=>1}}, expectAES =>{a=> 1.7,s=>0.1,l=>4,min=>0 ,max=>1 ,c=>'lit' ,f=>'' ,u=>'' ,d=>1,t=>"expect AES" ,lit=>{off=>0,on=>1}},
lcdSymb =>{a=> 2.0,s=>0.1,l=>4,min=>0 ,max=>255 ,c=>'hex' ,f=>'' ,u=>'' ,d=>0,t=>"bitmask which symbol to display on message"}, lcdSymb =>{a=> 2.0,s=>0.1,l=>4,min=>0 ,max=>255 ,c=>'hex' ,f=>'' ,u=>'' ,d=>0,t=>"bitmask which symbol to display on message"},
lcdLvlInterp =>{a=> 3.0,s=>0.1,l=>4,min=>0 ,max=>255 ,c=>'hex' ,f=>'' ,u=>'' ,d=>0,t=>"bitmask fro symbols"}, lcdLvlInterp =>{a=> 3.0,s=>0.1,l=>4,min=>0 ,max=>255 ,c=>'hex' ,f=>'' ,u=>'' ,d=>0,t=>"bitmask fro symbols"},
msgShowTime =>{a=> 45.0,s=>1.0,l=>1,min=>0.0,max=>120 ,c=>'factor' ,f=>2 ,u=>'s' ,d=>1,t=>"Message show time(RC19). 0=always on"}, msgShowTime =>{a=> 45.0,s=>1.0,l=>1,min=>0.0,max=>120 ,c=>'factor' ,f=>2 ,u=>'s' ,d=>1,t=>"Message show time(RC19). 0=always on"},
@ -1227,8 +1253,8 @@ my %culHmRegDefine = (
DecalHr =>{a=>8.3 ,s=>0.5,l=>5,min=>0 ,max=>23 ,c=>'' ,f=>'' ,u=>'h' ,d=>1,t=>"Decalc hour"}, DecalHr =>{a=>8.3 ,s=>0.5,l=>5,min=>0 ,max=>23 ,c=>'' ,f=>'' ,u=>'h' ,d=>1,t=>"Decalc hour"},
DecalMin =>{a=>8 ,s=>0.3,l=>5,min=>0 ,max=>50 ,c=>'factor' ,f=>0.1 ,u=>'min' ,d=>1,t=>"Decalc min"}, DecalMin =>{a=>8 ,s=>0.3,l=>5,min=>0 ,max=>50 ,c=>'factor' ,f=>0.1 ,u=>'min' ,d=>1,t=>"Decalc min"},
#Thermal-cc-VD #Thermal-cc-VD
ValveOffset =>{a=>9 ,s=>0.5,l=>5,min=>0 ,max=>25 ,c=>'' ,f=>'' ,u=>'%' ,d=>0,t=>"Valve offset"}, # size actually 0.5 ValveOffset =>{a=>9 ,s=>0.5,l=>5,min=>0 ,max=>25 ,c=>'' ,f=>'' ,u=>'%' ,d=>1,t=>"Valve offset"}, # size actually 0.5
ValveError =>{a=>10 ,s=>1 ,l=>5,min=>0 ,max=>99 ,c=>'' ,f=>'' ,u=>'%' ,d=>0,t=>"Valve position when error"},# size actually 0.7 ValveError =>{a=>10 ,s=>1 ,l=>5,min=>0 ,max=>99 ,c=>'' ,f=>'' ,u=>'%' ,d=>1,t=>"Valve position when error"},# size actually 0.7
# keymatic secific register # keymatic secific register
signal =>{a=>3.4 ,s=>0.1,l=>0,min=>0 ,max=>1 ,c=>'lit' ,f=>'' ,u=>'' ,d=>0,t=>"Confirmation beep" ,lit=>{off=>0,on=>1}}, signal =>{a=>3.4 ,s=>0.1,l=>0,min=>0 ,max=>1 ,c=>'lit' ,f=>'' ,u=>'' ,d=>0,t=>"Confirmation beep" ,lit=>{off=>0,on=>1}},
signalTone =>{a=>3.6 ,s=>0.2,l=>0,min=>0 ,max=>3 ,c=>'lit' ,f=>'' ,u=>'' ,d=>0,t=>"" ,lit=>{low=>0,mid=>1,high=>2,veryHigh=>3}}, signalTone =>{a=>3.6 ,s=>0.2,l=>0,min=>0 ,max=>3 ,c=>'lit' ,f=>'' ,u=>'' ,d=>0,t=>"" ,lit=>{low=>0,mid=>1,high=>2,veryHigh=>3}},
@ -1249,8 +1275,8 @@ my %culHmRegDefine = (
brightFilter =>{a=>2.4 ,s=>0.4,l=>1,min=>0 ,max=>7 ,c=>'' ,f=>'' ,u=>'' ,d=>1,t=>"brightness filter"}, brightFilter =>{a=>2.4 ,s=>0.4,l=>1,min=>0 ,max=>7 ,c=>'' ,f=>'' ,u=>'' ,d=>1,t=>"brightness filter"},
ledOnTime =>{a=>34 ,s=>1 ,l=>1,min=>0 ,max=>1.275 ,c=>'factor' ,f=>200 ,u=>'s' ,d=>1,t=>"LED ontime"}, ledOnTime =>{a=>34 ,s=>1 ,l=>1,min=>0 ,max=>1.275 ,c=>'factor' ,f=>200 ,u=>'s' ,d=>1,t=>"LED ontime"},
# weather units # weather units
stormUpThresh =>{a=>6 ,s=>1 ,l=>1,min=>0 ,max=>255 ,c=>'' ,f=>'' ,u=>'' ,d=>0,t=>"Storm upper threshold"}, stormUpThresh =>{a=>6 ,s=>1 ,l=>1,min=>0 ,max=>255 ,c=>'' ,f=>'' ,u=>'' ,d=>1,t=>"Storm upper threshold"},
stormLowThresh =>{a=>7 ,s=>1 ,l=>1,min=>0 ,max=>255 ,c=>'' ,f=>'' ,u=>'' ,d=>0,t=>"Storm lower threshold"}, stormLowThresh =>{a=>7 ,s=>1 ,l=>1,min=>0 ,max=>255 ,c=>'' ,f=>'' ,u=>'' ,d=>1,t=>"Storm lower threshold"},
); );
my %culHmRegGeneral = ( my %culHmRegGeneral = (
@ -1417,11 +1443,9 @@ sub
CUL_HM_TCtempReadings($) CUL_HM_TCtempReadings($)
{ {
my ($hash)=@_; my ($hash)=@_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $reg5 = ReadingsVal($name,"RegL_05:",""); my $reg5 = ReadingsVal($name,"RegL_05:","");
my $reg6 = ReadingsVal($name,"RegL_06:",""); my $reg6 = ReadingsVal($name,"RegL_06:","");
my @days = ("Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri"); my @days = ("Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri");
$reg5 =~ s/.* 0B://; #remove register up to addr 11 from list 5 $reg5 =~ s/.* 0B://; #remove register up to addr 11 from list 5
my $tempRegs = $reg5.$reg6; #one row my $tempRegs = $reg5.$reg6; #one row
@ -1436,6 +1460,8 @@ CUL_HM_TCtempReadings($)
foreach (@temp){$_=hex($_)/2}; foreach (@temp){$_=hex($_)/2};
my $setting; my $setting;
my @changedRead; my @changedRead;
push (@changedRead,"tempList_State:".
($hash->{helper}{shadowReg}{"RegL_05:"}?"set":"verified"));
for (my $day = 0;$day<7;$day++){ for (my $day = 0;$day<7;$day++){
my $tSpan = 0; my $tSpan = 0;
my $dayRead = ""; my $dayRead = "";
@ -1462,14 +1488,14 @@ CUL_HM_Get($@)
return "no get value specified" if(@a < 2); return "no get value specified" if(@a < 2);
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $devName = $attr{$name}{device};# get devName as protocol entity my $devName = $hash->{device};# get devName as protocol entity
$devName = $name if (!$devName); # we control ourself if no chief available $devName = $name if (!$devName); # we control ourself if no device available
my $st = AttrVal($devName, "subType", ""); my $st = AttrVal($devName, "subType", "");
my $md = AttrVal($devName, "model", ""); my $md = AttrVal($devName, "model", "");
my $mId = CUL_HM_getMId($hash); my $mId = CUL_HM_getMId($hash);
my $rxType = CUL_HM_getRxType($hash); my $rxType = CUL_HM_getRxType($hash);
my $class = AttrVal($devName, "hmClass", "");#relevant is the chief my $class = AttrVal($devName, "hmClass", "");#relevant is the device
my $cmd = $a[1]; my $cmd = $a[1];
my $dst = $hash->{DEF}; my $dst = $hash->{DEF};
my $isChannel = (length($dst) == 8)?"true":""; my $isChannel = (length($dst) == 8)?"true":"";
@ -1582,13 +1608,13 @@ CUL_HM_Get($@)
my $reg = $culHmRegDefine{$regName}; my $reg = $culHmRegDefine{$regName};
my $help = $reg->{t}; my $help = $reg->{t};
$help .= " options:".join(",",keys%{$reg->{lit}})if (defined($reg->{lit})); $help .= " options:".join(",",keys%{$reg->{lit}})if (defined($reg->{lit}));
push @rI,sprintf("%4d: %13s | %3d to %-11s | %8s | %s\n", push @rI,sprintf("%4d: %16s | %3d to %-11s | %8s | %s\n",
$reg->{l},$regName,$reg->{min},$reg->{max}.$reg->{u}, $reg->{l},$regName,$reg->{min},$reg->{max}.$reg->{u},
((($reg->{l} == 3)||($reg->{l} == 4))?"required":""),$help) ((($reg->{l} == 3)||($reg->{l} == 4))?"required":""),$help)
if (!($isChannel && $reg->{l} == 0)); if (!($isChannel && $reg->{l} == 0));
} }
my $info = sprintf("list: %13s | %-18s | %-8s | %s\n", my $info = sprintf("list: %16s | %-18s | %-8s | %s\n",
"register","range","peer","description"); "register","range","peer","description");
foreach(sort(@rI)){$info .= $_;} foreach(sort(@rI)){$info .= $_;}
return $info; return $info;
@ -1790,7 +1816,6 @@ CUL_HM_Set($@)
my $isChannel = (length($dst) == 8)?"true":""; my $isChannel = (length($dst) == 8)?"true":"";
my $chn = ($isChannel)?substr($dst,6,2):"01"; my $chn = ($isChannel)?substr($dst,6,2):"01";
$dst = substr($dst,0,6); $dst = substr($dst,0,6);
my $devHash = CUL_HM_getDeviceHash($hash); my $devHash = CUL_HM_getDeviceHash($hash);
my $mdCh = $md.($isChannel?$chn:"00"); # chan specific commands? my $mdCh = $md.($isChannel?$chn:"00"); # chan specific commands?
@ -1854,10 +1879,13 @@ CUL_HM_Set($@)
CUL_HM_respPendRm($hash); CUL_HM_respPendRm($hash);
delete ($hash->{helper}{burstEvtCnt}); delete ($hash->{helper}{burstEvtCnt});
delete ($hash->{cmdStack}); delete ($hash->{cmdStack});
foreach my $var (keys %{$attr{$name}}){ foreach my $var (keys %{$attr{$name}}){ # can be removed versions later
delete ($attr{$name}{$var}) if ($var =~ m/^prot/); delete ($attr{$name}{$var}) if ($var =~ m/^prot/);
} }
$attr{$name}{protState} = "Info_Cleared" ; foreach my $var (keys %{$hash}){
delete ($hash->{$var}) if ($var =~ m/^prot/);
}
$hash->{protState} = "Info_Cleared" ;
} }
else{ else{
return "unknown section. User readings or msgEvents"; return "unknown section. User readings or msgEvents";
@ -1868,10 +1896,10 @@ CUL_HM_Set($@)
CUL_HM_PushCmdStack($hash,"++".$flag."11".$id.$dst."0400"); CUL_HM_PushCmdStack($hash,"++".$flag."11".$id.$dst."0400");
} }
elsif($cmd eq "pair") { ############################################# elsif($cmd eq "pair") { #############################################
$state = "";
return "pair is not enabled for this type of device, ". return "pair is not enabled for this type of device, ".
"use set <IODev> hmPairForSec" "use set <IODev> hmPairForSec"
if($class eq "sender"); if($class eq "sender");
$state = "";
my $serialNr = AttrVal($name, "serialNr", undef); my $serialNr = AttrVal($name, "serialNr", undef);
return "serialNr is not set" if(!$serialNr); return "serialNr is not set" if(!$serialNr);
CUL_HM_PushCmdStack($hash,"++A401".$id."000000010A".unpack("H*",$serialNr)); CUL_HM_PushCmdStack($hash,"++A401".$id."000000010A".unpack("H*",$serialNr));
@ -2361,9 +2389,9 @@ CUL_HM_Set($@)
DoTrigger("global", "UNDEFINED $chnName CUL_HM $chnId") DoTrigger("global", "UNDEFINED $chnName CUL_HM $chnId")
if (!$modules{CUL_HM}{defptr}{$chnId}); if (!$modules{CUL_HM}{defptr}{$chnId});
} }
foreach my $channel (keys %{$attr{$name}}){# remove higher numbers foreach my $channel (keys %{$hash}){# remove higher numbers
my $chNo = $1 if($channel =~ m/^channel_(.*)/); my $chNo = $1 if($channel =~ m/^channel_(.*)/);
CommandDelete(undef,$attr{$name}{$channel}) CommandDelete(undef,$hash->{$channel})
if (hex($chNo) > $maxBtnNo); if (hex($chNo) > $maxBtnNo);
} }
} }
@ -2608,9 +2636,7 @@ CUL_HM_getConfig($$$$$){
my $flag = CUL_HM_getFlag($hash); my $flag = CUL_HM_getFlag($hash);
foreach my $readEntry (keys %{$chnhash->{READINGS}}){ foreach my $readEntry (keys %{$chnhash->{READINGS}}){
if ($readEntry =~ m/^RegL_/){#remove old lists, no longer valid delete $chnhash->{READINGS}{$readEntry} if ($readEntry =~ m/^RegL_/);
delete $chnhash->{READINGS}{$readEntry};
}
} }
#get Peer-list in any case - it is part of config #get Peer-list in any case - it is part of config
CUL_HM_PushCmdStack($hash,sprintf("++%s01%s%s%s03",$flag,$id,$dst,$chn)); CUL_HM_PushCmdStack($hash,sprintf("++%s01%s%s%s03",$flag,$id,$dst,$chn));
@ -2633,7 +2659,6 @@ CUL_HM_getConfig($$$$$){
last if ($chnValid); last if ($chnValid);
} }
} }
#$listNo,$chnValid $peerReq
if ($chnValid){# yes, we will go for a list if ($chnValid){# yes, we will go for a list
if ($peerReq){# need to get the peers first if ($peerReq){# need to get the peers first
$chnhash->{helper}{getCfgList} = "all"; # peers first $chnhash->{helper}{getCfgList} = "all"; # peers first
@ -2695,7 +2720,6 @@ CUL_HM_responseSetup($$)
$chnhash = $hash if (!$chnhash); $chnhash = $hash if (!$chnhash);
$chnhash->{READINGS}{peerList}{VAL}="";#empty old list $chnhash->{READINGS}{peerList}{VAL}="";#empty old list
$attr{$chnhash->{NAME}}{peerIDs} = ''; $attr{$chnhash->{NAME}}{peerIDs} = '';
$attr{$chnhash->{NAME}}{peerList} = 'cleared';
return; return;
} }
elsif($subType eq "04"){ #RegisterRead------- elsif($subType eq "04"){ #RegisterRead-------
@ -2719,6 +2743,15 @@ CUL_HM_responseSetup($$)
delete ($chnhash->{READINGS}{"RegL_".$list.":".$peer}{TIME}); delete ($chnhash->{READINGS}{"RegL_".$list.":".$peer}{TIME});
return; return;
} }
# elsif($subType eq "0A"){ #Pair Serial----------
# #--- set messaging items
# $hash->{helper}{respWait}{Pending} = "PairSerial";
# $hash->{helper}{respWait}{forChn} = substr($p,4,20);
#
# # define timeout - holdup cmdStack until response complete or timeout
# InternalTimer(gettimeofday()+$rTo, "CUL_HM_respPendTout", "respPend:$dst", 0);
# return;
# }
elsif($subType eq "0E"){ #StatusReq---------- elsif($subType eq "0E"){ #StatusReq----------
#--- set messaging items #--- set messaging items
$hash->{helper}{respWait}{Pending} = "StatusReq"; $hash->{helper}{respWait}{Pending} = "StatusReq";
@ -2730,7 +2763,7 @@ CUL_HM_responseSetup($$)
} }
} }
if ($msgFlag & 0x20){ if (($msgFlag & 0x20) && ($dst ne '000000')){
my $iohash = $hash->{IODev}; my $iohash = $hash->{IODev};
$hash->{helper}{respWait}{cmd} = $cmd; $hash->{helper}{respWait}{cmd} = $cmd;
$hash->{helper}{respWait}{msgId} = $msgId; #msgId we wait to ack $hash->{helper}{respWait}{msgId} = $msgId; #msgId we wait to ack
@ -2747,17 +2780,18 @@ CUL_HM_eventP($$)
#todo: add severity, counter, history and acknowledge #todo: add severity, counter, history and acknowledge
my ($hash, $evntType) = @_; my ($hash, $evntType) = @_;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $nAttr = $attr{$name}; my $nAttr = $hash;
return if (!$name); return if (!$name);
if ($evntType eq "Rcv"){ if ($evntType eq "Rcv"){
$nAttr->{"protLastRcv"} = TimeNow(); $nAttr->{"protLastRcv"} = TimeNow();
return; return;
} }
$nAttr->{"prot".$evntType."Cnt"} = 0
if (!$nAttr->{"prot".$evntType."Cnt"}); my $evnt = $nAttr->{"prot".$evntType}?$nAttr->{"prot".$evntType}:"0 > x";
$nAttr->{"prot".$evntType."Cnt"}++; my ($evntCnt,undef) = split(' last_at:',$evnt);
$nAttr->{"prot".$evntType."Last"} = TimeNow(); $nAttr->{"prot".$evntType} = ++$evntCnt." last_at:".TimeNow();
if ($evntType ne "Rcv" && $evntType ne "Snd"){#count unusual events
if ($evntType ne "Snd"){#count unusual events
if ($hash->{helper}{burstEvtCnt}){ if ($hash->{helper}{burstEvtCnt}){
$hash->{helper}{burstEvtCnt}++; $hash->{helper}{burstEvtCnt}++;
}else {$hash->{helper}{burstEvtCnt}=1;}; }else {$hash->{helper}{burstEvtCnt}=1;};
@ -2783,7 +2817,7 @@ CUL_HM_respPendTout($)
my ($HMid) = @_; my ($HMid) = @_;
$HMid =~ s/.*://; #remove timer identifier $HMid =~ s/.*://; #remove timer identifier
my $hash = $modules{CUL_HM}{defptr}{$HMid}; my $hash = $modules{CUL_HM}{defptr}{$HMid};
if ($hash){ if ($hash && $hash->{DEF} ne '000000'){
CUL_HM_eventP($hash,"Tout") if ($hash->{helper}{respWait}{cmd}); CUL_HM_eventP($hash,"Tout") if ($hash->{helper}{respWait}{cmd});
CUL_HM_eventP($hash,"ToutResp") if ($hash->{helper}{respWait}{Pending}); CUL_HM_eventP($hash,"ToutResp") if ($hash->{helper}{respWait}{Pending});
CUL_HM_respPendRm($hash); CUL_HM_respPendRm($hash);
@ -2812,8 +2846,8 @@ CUL_HM_PushCmdStack($$)
} }
push(@{$hash->{cmdStack}}, $cmd); push(@{$hash->{cmdStack}}, $cmd);
my $entries = scalar @{$hash->{cmdStack}}; my $entries = scalar @{$hash->{cmdStack}};
$attr{$name}{protCmdPend} = $entries." CMDs_pending"; $hash->{protCmdPend} = $entries." CMDs_pending";
$attr{$name}{protState} = "CMDs_pending" $hash->{protState} = "CMDs_pending"
if (!$hash->{helper}{respWait}{cmd} && if (!$hash->{helper}{respWait}{cmd} &&
!$hash->{helper}{respWait}{Pending}); !$hash->{helper}{respWait}{Pending});
} }
@ -2829,17 +2863,17 @@ CUL_HM_ProcessCmdStack($)
if(@{$hash->{cmdStack}}) { if(@{$hash->{cmdStack}}) {
CUL_HM_SndCmd($hash, shift @{$hash->{cmdStack}}); CUL_HM_SndCmd($hash, shift @{$hash->{cmdStack}});
$sent = 1; $sent = 1;
$attr{$name}{protCmdPend} = scalar @{$hash->{cmdStack}}." CMDs pending"; $hash->{protCmdPend} = scalar @{$hash->{cmdStack}}." CMDs pending";
$attr{$name}{protState} = "CMDs_processing..."; $hash->{protState} = "CMDs_processing...";
CUL_HM_eventP($hash,"Snd"); CUL_HM_eventP($hash,"Snd");
} }
if(!@{$hash->{cmdStack}}) { if(!@{$hash->{cmdStack}}) {
delete($hash->{cmdStack}); delete($hash->{cmdStack});
delete($attr{$name}{protCmdPend}); delete($hash->{protCmdPend});
#-- update info --- #-- update info ---
my $burstEvt = ($hash->{helper}{burstEvtCnt})? my $burstEvt = ($hash->{helper}{burstEvtCnt})?
$hash->{helper}{burstEvtCnt}:0; $hash->{helper}{burstEvtCnt}:0;
$attr{$name}{protState} = "CMDs_done". $hash->{protState} = "CMDs_done".
(($burstEvt)?("_events:".$burstEvt):""); (($burstEvt)?("_events:".$burstEvt):"");
} }
} }
@ -2854,11 +2888,11 @@ CUL_HM_Resend($)
if($hash->{helper}{respWait}{reSent} >= 3) { if($hash->{helper}{respWait}{reSent} >= 3) {
CUL_HM_eventP($hash,"ResndFail"); CUL_HM_eventP($hash,"ResndFail");
delete($hash->{cmdStack}); delete($hash->{cmdStack});
delete($attr{$name}{protCmdPend}); delete($hash->{protCmdPend});
CUL_HM_respPendRm($hash); CUL_HM_respPendRm($hash);
my $burstEvt = ($hash->{helper}{burstEvtCnt})? my $burstEvt = ($hash->{helper}{burstEvtCnt})?
$hash->{helper}{burstEvtCnt}:0; $hash->{helper}{burstEvtCnt}:0;
$attr{$name}{protState} = "CMDs_done". $hash->{protState} = "CMDs_done".
(($burstEvt)?("_events:".$burstEvt):""); (($burstEvt)?("_events:".$burstEvt):"");
readingsSingleUpdate($hash,"state","MISSING ACK",1); readingsSingleUpdate($hash,"state","MISSING ACK",1);
} }
@ -2885,20 +2919,19 @@ CUL_HM_ID2PeerList ($$$)
} }
if (!$peerIDs){ #list now empty if (!$peerIDs){ #list now empty
delete $attr{$name}{peerIDs}; delete $attr{$name}{peerIDs};
delete $attr{$name}{peerList};
delete ($hash->{READINGS}{peerList}); delete ($hash->{READINGS}{peerList});
} }
else{# update the human readable list else{# update the human readable list
$attr{$name}{peerIDs} = $peerIDs; $attr{$name}{peerIDs} = $peerIDs;
$attr{$name}{peerList} = "";
my $dId = substr(CUL_HM_name2Id($name),0,6); my $dId = substr(CUL_HM_name2Id($name),0,6);
my $peerListTmp = "";
foreach my $pId (split(",",$peerIDs)){ foreach my $pId (split(",",$peerIDs)){
next if (!$pId); next if (!$pId);
$attr{$name}{peerList} .= (($dId eq substr($pId,0,6))? $peerListTmp .= (($dId eq substr($pId,0,6))?
("self".substr($pId,6,2).","): ("self".substr($pId,6,2).","):
(CUL_HM_id2Name($pId).",")); (CUL_HM_id2Name($pId).","));
} }
readingsSingleUpdate($hash,"peerList",$attr{$name}{peerList},0); readingsSingleUpdate($hash,"peerList",$peerListTmp,0);
} }
} }
################### Conversions ################ ################### Conversions ################
@ -2909,14 +2942,15 @@ CUL_HM_getAssChnIds($)
# if device and no channel # if device and no channel
my ($name) = @_; my ($name) = @_;
my @chnIdList; my @chnIdList;
foreach my $channel (keys %{$attr{$name}}){ my $hash = CUL_HM_name2Hash($name);
foreach my $channel (keys %{$hash}){
next if ($channel !~ m/^channel_/); next if ($channel !~ m/^channel_/);
my $chnHash = CUL_HM_name2Hash($attr{$name}{$channel}); my $chnHash = CUL_HM_name2Hash($hash->{$channel});
push @chnIdList,$chnHash->{DEF} if ($chnHash); push @chnIdList,$chnHash->{DEF} if ($chnHash);
} }
my $dId = CUL_HM_name2Id($name); my $dId = CUL_HM_name2Id($name);
push @chnIdList,$dId."01" if (length($dId) == 6 && !$attr{$name}{channel_01}); push @chnIdList,$dId."01" if (length($dId) == 6 && !$hash->{channel_01});
push @chnIdList,$dId if (length($dId) == 8); push @chnIdList,$dId if (length($dId) == 8);
return sort(@chnIdList); return sort(@chnIdList);
} }
@ -3229,7 +3263,7 @@ CUL_HM_parseCommon(@){
$success = "no"; $success = "no";
CUL_HM_eventP($shash,"Nack"); CUL_HM_eventP($shash,"Nack");
delete($shash->{cmdStack}); delete($shash->{cmdStack});
delete($attr{$shash->{NAME}}{protCmdPend}); delete($shash->{protCmdPend});
CUL_HM_respPendRm($shash); CUL_HM_respPendRm($shash);
$reply = "NACK"; $reply = "NACK";
} }
@ -3242,6 +3276,13 @@ CUL_HM_parseCommon(@){
if($dhash->{DEF} && (CUL_HM_Id($shash->{IODev}) eq $dhash->{DEF})); if($dhash->{DEF} && (CUL_HM_Id($shash->{IODev}) eq $dhash->{DEF}));
return $reply; return $reply;
} }
elsif($msgType eq "00"){
if ($pendType eq "PairSerial"){
if($shash->{helper}{respWait}{forChn} = substr($p,6,20)){
CUL_HM_respPendRm($shash);
}
}
}
elsif($msgType eq "10"){ elsif($msgType eq "10"){
my $subtype = substr($p,0,2); my $subtype = substr($p,0,2);
if($subtype eq "01"){ #storePeerList################# if($subtype eq "01"){ #storePeerList#################
@ -3257,9 +3298,6 @@ CUL_HM_parseCommon(@){
if ($p =~ m/000000..$/) {# last entry, peerList is complete if ($p =~ m/000000..$/) {# last entry, peerList is complete
CUL_HM_respPendRm($shash); CUL_HM_respPendRm($shash);
readingsSingleUpdate($chnhash,"peerList",
AttrVal($chnNname,"peerList",""),0);
# check for request to get List3 data # check for request to get List3 data
my $reqPeer = $chnhash->{helper}{getCfgList}; my $reqPeer = $chnhash->{helper}{getCfgList};
if ($reqPeer){ if ($reqPeer){
@ -3326,7 +3364,7 @@ CUL_HM_parseCommon(@){
# peer Channel name from/for user entry. <IDorName> <deviceID> <ioID> # peer Channel name from/for user entry. <IDorName> <deviceID> <ioID>
CUL_HM_updtRegDisp($chnHash,$list, CUL_HM_updtRegDisp($chnHash,$list,
CUL_HM_peerChId($peerName, CUL_HM_peerChId($peerName,
substr(CUL_HM_hash2Id($chnHash),0,6),"000000")); substr(CUL_HM_hash2Id($chnHash),0,6),"00000000"));
} }
else{ else{
CUL_HM_respPendToutProlong($shash);#wasn't last - reschedule timer CUL_HM_respPendToutProlong($shash);#wasn't last - reschedule timer
@ -3415,14 +3453,17 @@ CUL_HM_getRegFromStore($$$$)
my $convFlg = "";# confirmation flag - indicates data not confirmed by device my $convFlg = "";# confirmation flag - indicates data not confirmed by device
for (my $size2go = $size;$size2go>0;$size2go -=8){ for (my $size2go = $size;$size2go>0;$size2go -=8){
my $addrS = sprintf("%02X",$addr); my $addrS = sprintf("%02X",$addr);
my $dRead;
my $dReadS;
if ($hash->{helper}{shadowReg}&&$hash->{helper}{shadowReg}{$regLN}){ if ($hash->{helper}{shadowReg}&&$hash->{helper}{shadowReg}{$regLN}){
$convFlg = "set_"; $dReadS = $1 if($hash->{helper}{shadowReg}{$regLN} =~ m/$addrS:(..)/);
$dRead = $1 if($hash->{helper}{shadowReg}{$regLN} =~ m/$addrS:(..)/);
} }
if (!$dRead && $hash->{READINGS}{$regLN}) { my $dReadR;
$dRead = $1 if($hash->{READINGS}{$regLN}{VAL} =~ m/$addrS:(..)/); if ($hash->{READINGS}{$regLN}) {
$dReadR = $1 if($hash->{READINGS}{$regLN}{VAL} =~ m/$addrS:(..)/);
} }
$convFlg = "set_" if ($dReadS && $dReadR ne $dReadS);
my $dRead = $dReadS?$dReadS:$dReadR;
return "invalid" if (!defined($dRead)); return "invalid" if (!defined($dRead));
$data = ($data<< 8)+hex($dRead); $data = ($data<< 8)+hex($dRead);
@ -3452,7 +3493,8 @@ CUL_HM_updtRegDisp($$$)
my($hash,$list,$peerId)=@_; my($hash,$list,$peerId)=@_;
my $listNo = $list+0; my $listNo = $list+0;
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $peer = ($peerId)?CUL_HM_peerChName($peerId,substr($hash->{DEF},0,6),"")."-":""; my $peer = ($peerId && $peerId ne '00000000' )?
CUL_HM_peerChName($peerId,substr($hash->{DEF},0,6),"")."-":"";
$peer=~s/:/-/; $peer=~s/:/-/;
my $devName =CUL_HM_getDeviceHash($hash)->{NAME};# devName as protocol entity my $devName =CUL_HM_getDeviceHash($hash)->{NAME};# devName as protocol entity
my $st = AttrVal($devName, "subType", ""); my $st = AttrVal($devName, "subType", "");
@ -3476,9 +3518,9 @@ CUL_HM_updtRegDisp($$$)
# --- handle specifics - no general approach so far. # --- handle specifics - no general approach so far.
CUL_HM_TCtempReadings($hash) CUL_HM_TCtempReadings($hash)
if (($listNo == 5 ||$listNo == 6) && if (($list == 5 ||$list == 6) &&
substr($hash->{DEF},6,2) eq "02" && substr($hash->{DEF},6,2) eq "02" &&
CUL_HM_Get($hash,"param","model") eq "HM-CC-TC"); CUL_HM_Get($hash,$name,"param","model") eq "HM-CC-TC");
CUL_HM_UpdtReadBulk($hash,1,@changedRead) if (@changedRead); CUL_HM_UpdtReadBulk($hash,1,@changedRead) if (@changedRead);
} }
@ -3590,6 +3632,7 @@ CUL_HM_pushConfig($$$$$$$$)
} }
} }
$chnhash->{helper}{shadowReg}{$regLN} = $regs; $chnhash->{helper}{shadowReg}{$regLN} = $regs;
CUL_HM_updtRegDisp($hash,$list,$peerAddr.$peerChn);
CUL_HM_PushCmdStack($hash, "++".$flag.'01'.$src.$dst.$chn.'05'. CUL_HM_PushCmdStack($hash, "++".$flag.'01'.$src.$dst.$chn.'05'.
$peerAddr.$peerChn.$list); $peerAddr.$peerChn.$list);
@ -3625,21 +3668,24 @@ CUL_HM_ActGetCreateHash()
if (!$modules{CUL_HM}{defptr}{"000000"}){ if (!$modules{CUL_HM}{defptr}{"000000"}){
DoTrigger("global", "UNDEFINED ActionDetector CUL_HM 000000"); DoTrigger("global", "UNDEFINED ActionDetector CUL_HM 000000");
$attr{ActionDetector}{actCycle} = 600; $attr{ActionDetector}{actCycle} = 600;
} }
my $defPtr = $modules{CUL_HM}{defptr}; my $defPtr = $modules{CUL_HM}{defptr};
my $actName = $defPtr->{"000000"}{NAME} if($defPtr->{"000000"}); my $actName = $defPtr->{"000000"}{NAME} if($defPtr->{"000000"});
my $actHash = $modules{CUL_HM}{defptr}{"000000"}; my $actHash = $modules{CUL_HM}{defptr}{"000000"};
if (!$actHash->{helper}{first}){ # if called first time arrributes are no yet if ($attr{$actName}{peerList} && !$attr{$actName}{peerIDs}){#todo Updt1 remove
$attr{$actName}{peerIDs} = $attr{$actName}{peerList}; #todo Updt1 remove
delete ($attr{$actName}{peerList}); #todo Updt1 remove
} #todo Updt1 remove
if (!$actHash->{helper}{first}){ # if called first time attributes are no yet
#recovered #recovered
InternalTimer(gettimeofday()+3, "CUL_HM_ActGetCreateHash", "ActionDetector", 0); InternalTimer(gettimeofday()+3, "CUL_HM_ActGetCreateHash", "ActionDetector", 0);
$actHash->{helper}{first} = 1; $actHash->{helper}{first} = 1;
return; return;
} }
if (!$actHash->{helper}{actCycle} ){ #This is the first call if (!$actHash->{helper}{actCycle} ){ #This is the first call
my $peerList = AttrVal($actName,"peerList",""); my $peerIDs = AttrVal($actName,"peerIDs","");
my $tn = TimeNow(); my $tn = TimeNow();
foreach my $devId (split(",",$peerList)){ foreach my $devId (split(",",$peerIDs)){
$actHash->{helper}{$devId}{start} = $tn; $actHash->{helper}{$devId}{start} = $tn;
my $devName = CUL_HM_id2Name($devId); my $devName = CUL_HM_id2Name($devId);
readingsSingleUpdate($actHash,"status_".$devName,"unknown",1); readingsSingleUpdate($actHash,"status_".$devName,"unknown",1);
@ -3683,13 +3729,12 @@ CUL_HM_ActAdd($$)
$attr{$devName}{actCycle} = $cycleString; $attr{$devName}{actCycle} = $cycleString;
$attr{$devName}{actStatus}=""; # force trigger $attr{$devName}{actStatus}=""; # force trigger
CUL_HM_setAttrIfCh($devName,"actStatus","unknown","Activity"); CUL_HM_setAttrIfCh($devName,"actStatus","unknown","Activity");
my $actHash = CUL_HM_ActGetCreateHash(); my $actHash = CUL_HM_ActGetCreateHash();
my $actName = $actHash->{NAME}; # could have been renamed my $actName = $actHash->{NAME}; # could have been renamed
my $peerList = AttrVal($actName,"peerList",""); my $peerIDs = AttrVal($actName,"peerIDs","");
$peerList .= $devId."," if($peerList !~ m/$devId,/);#add if not in $peerIDs .= $devId."," if($peerIDs !~ m/$devId,/);#add if not in
$attr{$actName}{peerList} = $peerList; $attr{$actName}{peerIDs} = $peerIDs;
my $tn = TimeNow(); my $tn = TimeNow();
$actHash->{helper}{$devId}{start} = $tn; $actHash->{helper}{$devId}{start} = $tn;
readingsSingleUpdate($actHash,"status_".$devName,"unknown",1); readingsSingleUpdate($actHash,"status_".$devName,"unknown",1);
@ -3708,14 +3753,13 @@ CUL_HM_ActDel($)
delete ($attr{$devName}{actCycle}); delete ($attr{$devName}{actCycle});
CUL_HM_setAttrIfCh($devName,"actStatus","deleted","Activity");#post trigger CUL_HM_setAttrIfCh($devName,"actStatus","deleted","Activity");#post trigger
delete ($attr{$devName}{actStatus}); delete ($attr{$devName}{actStatus});
my $acthash = CUL_HM_ActGetCreateHash(); my $acthash = CUL_HM_ActGetCreateHash();
my $actName = $acthash->{NAME}; my $actName = $acthash->{NAME};
delete ($acthash->{helper}{$devId}); delete ($acthash->{helper}{$devId});
$attr{$actName}{peerList} = "" if (!defined($attr{$actName}{peerList})); $attr{$actName}{peerIDs} = "" if (!defined($attr{$actName}{peerIDs}));
$attr{$actName}{peerList} =~ s/$devId,//g; $attr{$actName}{peerIDs} =~ s/$devId,//g;
Log GetLogLevel($actName,3),"Device ".$devName." removed from ActionDetector"; Log GetLogLevel($actName,3),"Device ".$devName." removed from ActionDetector";
} }
sub sub
@ -3724,10 +3768,10 @@ CUL_HM_ActCheck()
my $actHash = CUL_HM_ActGetCreateHash(); my $actHash = CUL_HM_ActGetCreateHash();
my $tod = int(gettimeofday()); my $tod = int(gettimeofday());
my $actName = $actHash->{NAME}; my $actName = $actHash->{NAME};
my $peerList = AttrVal($actName,"peerList","none"); my $peerIDs = AttrVal($actName,"peerIDs","none");
delete ($actHash->{READINGS}); #cleansweep delete ($actHash->{READINGS}); #cleansweep
readingsSingleUpdate($actHash,"state","check_performed",0); readingsSingleUpdate($actHash,"state","check_performed",0);
foreach my $devId (split(",",$peerList)){ foreach my $devId (split(",",$peerIDs)){
my $devName = CUL_HM_id2Name($devId); my $devName = CUL_HM_id2Name($devId);
if(!$devName || !defined($attr{$devName}{actCycle})){ if(!$devName || !defined($attr{$devName}{actCycle})){
CUL_HM_ActDel($devId); CUL_HM_ActDel($devId);
@ -3740,7 +3784,8 @@ CUL_HM_ActCheck()
$state = "switchedOff"; $state = "switchedOff";
} }
else{ else{
my $tLast = $attr{$devName}{"protLastRcv"}; my $devHash = CUL_HM_name2Hash($devName);
my $tLast = $devHash->{"protLastRcv"};
my @t = localtime($tod - $tSec); #time since when a trigger is expected my @t = localtime($tod - $tSec); #time since when a trigger is expected
my $tSince = sprintf("%04d-%02d-%02d %02d:%02d:%02d", my $tSince = sprintf("%04d-%02d-%02d %02d:%02d:%02d",
$t[5]+1900, $t[4]+1, $t[3], $t[2], $t[1], $t[0]); $t[5]+1900, $t[4]+1, $t[3], $t[2], $t[1], $t[0]);
@ -4411,6 +4456,21 @@ CUL_HM_setAttrIfCh($$$$)
<li><a name="unit">unit</a><br> <li><a name="unit">unit</a><br>
set the reported unit by the KFM100 if rawToReadable is active. E.g.<br> set the reported unit by the KFM100 if rawToReadable is active. E.g.<br>
attr KFM100 unit Liter attr KFM100 unit Liter
</li>
<li><a name="autoReadReg">autoReadReg</a><br>
set to '1' will execute a getConfig for the device automatically after each reboot of FHEM.
Execution will be delayed in order to prevent congestion at startup. Therefore the update
of the readings and the display will be delayed depending on the sice of the database.<br>
Recommendations and constrains upon usage:<br>
<ul>
use this attribute on the device or channel 01. Do not use it separate on each channel
of a multi-channel device to avoid duplicate execution<br>
usage on devices which only react to 'config' mode is not recommended since executen will
not start until config is triggered by the user<br>
usage on devices which support wakeup-mode is usefull. But consider that execution is delayed
until the device "wakes up".<br>
</ul>
</li> </li>
</ul> </ul>
<br> <br>