introduce Level and update dimmer's virtual channels

git-svn-id: https://svn.fhem.de/fhem/trunk@2997 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
martinp876 2013-03-29 19:05:07 +00:00
parent 62b9fa8e13
commit 7f0caa33fd
2 changed files with 256 additions and 234 deletions

View File

@ -23,7 +23,9 @@ my %culHmGlobalGets =HMConfig::HMConfig_getHash("culHmGlobalGets");
my %culHmSubTypeGets =HMConfig::HMConfig_getHash("culHmSubTypeGets"); my %culHmSubTypeGets =HMConfig::HMConfig_getHash("culHmSubTypeGets");
my %culHmModelGets =HMConfig::HMConfig_getHash("culHmModelGets"); my %culHmModelGets =HMConfig::HMConfig_getHash("culHmModelGets");
my %culHmGlobalSetsDevice =HMConfig::HMConfig_getHash("culHmGlobalSetsDevice"); my %culHmGlobalSetsDevice =HMConfig::HMConfig_getHash("culHmGlobalSetsDevice");
my %culHmGlobalSetsChn =HMConfig::HMConfig_getHash("culHmGlobalSetsChn");
my %culHmGlobalSets =HMConfig::HMConfig_getHash("culHmGlobalSets"); my %culHmGlobalSets =HMConfig::HMConfig_getHash("culHmGlobalSets");
my %culHmGlobalSetsVrtDev =HMConfig::HMConfig_getHash("culHmGlobalSetsVrtDev");
my %culHmSubTypeSets =HMConfig::HMConfig_getHash("culHmSubTypeSets"); my %culHmSubTypeSets =HMConfig::HMConfig_getHash("culHmSubTypeSets");
my %culHmModelSets =HMConfig::HMConfig_getHash("culHmModelSets"); my %culHmModelSets =HMConfig::HMConfig_getHash("culHmModelSets");
my %culHmChanSets =HMConfig::HMConfig_getHash("culHmChanSets"); my %culHmChanSets =HMConfig::HMConfig_getHash("culHmChanSets");
@ -31,6 +33,7 @@ my %culHmBits =HMConfig::HMConfig_getHash("culHmBits");
my @culHmCmdFlags =HMConfig::HMConfig_getHash("culHmCmdFlags"); my @culHmCmdFlags =HMConfig::HMConfig_getHash("culHmCmdFlags");
my $K_actDetID =HMConfig::HMConfig_getHash("K_actDetID"); my $K_actDetID =HMConfig::HMConfig_getHash("K_actDetID");
############################################################ ############################################################
sub CUL_HM_Initialize($); sub CUL_HM_Initialize($);
@ -132,13 +135,14 @@ sub CUL_HM_updateConfig($){
my $name = shift(@nameList); my $name = shift(@nameList);
my $hash = CUL_HM_name2Hash($name); my $hash = CUL_HM_name2Hash($name);
my $id = CUL_HM_hash2Id($hash); my $id = CUL_HM_hash2Id($hash);
my $isDevice = (length($id) == 6)?"true":"";
if ($id ne $K_actDetID){# if not action detector if ($id ne $K_actDetID){# if not action detector
CUL_HM_ID2PeerList($name,"",1); # update peerList out of peerIDs CUL_HM_ID2PeerList($name,"",1); # update peerList out of peerIDs
my $actCycle = AttrVal($name,"actCycle",undef); my $actCycle = AttrVal($name,"actCycle",undef);
CUL_HM_ActAdd($id,$actCycle) if ($actCycle);# add to ActionDetect? CUL_HM_ActAdd($id,$actCycle) if ($actCycle);# add to ActionDetect?
# --- set default attrubutes if missing --- # --- set default attrubutes if missing ---
$attr{$name}{expert}= AttrVal($name,"expert","2_full") if ($isDevice); $attr{$name}{expert}= AttrVal($name,"expert","2_full")
if ($hash->{helper}{role}{dev});
# convert variables, delete obsolete, move to hidden level # convert variables, delete obsolete, move to hidden level
$attr{$name}{".devInfo"} = $attr{$name}{devInfo} if($attr{$name}{devInfo});#todo Updt4 remove $attr{$name}{".devInfo"} = $attr{$name}{devInfo} if($attr{$name}{devInfo});#todo Updt4 remove
@ -147,17 +151,24 @@ sub CUL_HM_updateConfig($){
} }
else{ else{
$attr{$name}{"event-on-change-reading"} = AttrVal($name, "event-on-change-reading", ".*"); $attr{$name}{"event-on-change-reading"} = AttrVal($name, "event-on-change-reading", ".*");
;#delete $attr{$name}{peerIDs}; # remove historical data delete $hash->{helper}{role};
$hash->{helper}{role}{vrt} = 1;
next;
#delete $attr{$name}{peerIDs}; # remove historical data
} }
if ("dimmer" eq CUL_HM_Get($hash,$name,"param","subType")) {#setup virtuals my $st = CUL_HM_Get($hash,$name,"param","subType");
my $md = CUL_HM_Get($hash,$name,"param","model");
if ("HM-CC-TC" eq $md){
$hash->{helper}{role}{chn} = 1 if (length($id) == 6); #tc special
}
elsif ("dimmer" eq $st) {#setup virtual dimmer channels
my $mId = CUL_HM_getMId($hash);
#configure Dimmer virtual channel assotiation #configure Dimmer virtual channel assotiation
if (length($id) == 8 || !$hash->{"channel_01"}){ if ($hash->{helper}{role}{chn}){
my $chn = substr($id,6,2); my $chn = (length($id) == 8)?substr($id,6,2):"01";
$chn = "01" if (!$chn); # device acts as channel 01
my $devId = substr($id,0,6); my $devId = substr($id,0,6);
my $mId = CUL_HM_getMId($hash); if ($culHmModel{$mId}{chn} =~ m/Sw._V/){# there are virtual channels
if ($culHmModel{$mId}{chn} =~ m/Sw._V/){
my @chnPh = (grep{$_ =~ m/Sw:/ } split ',',$culHmModel{$mId}{chn}); my @chnPh = (grep{$_ =~ m/Sw:/ } split ',',$culHmModel{$mId}{chn});
@chnPh = split ':',$chnPh[0] if (@chnPh); @chnPh = split ':',$chnPh[0] if (@chnPh);
my $chnPhyMax = $chnPh[2]?$chnPh[2]:1; # max Phys channels my $chnPhyMax = $chnPh[2]?$chnPh[2]:1; # max Phys channels
@ -165,7 +176,6 @@ sub CUL_HM_updateConfig($){
my $idPhy = $devId.sprintf("%02X",$chnPhy);# ID assot phy chan my $idPhy = $devId.sprintf("%02X",$chnPhy);# ID assot phy chan
my $pHash = CUL_HM_id2Hash($idPhy); # hash assot phy chan my $pHash = CUL_HM_id2Hash($idPhy); # hash assot phy chan
$idPhy = CUL_HM_hash2Id($pHash); # could be device!!! $idPhy = CUL_HM_hash2Id($pHash); # could be device!!!
if ($pHash){ if ($pHash){
$pHash->{helper}{vDim}{idPhy} = $idPhy; $pHash->{helper}{vDim}{idPhy} = $idPhy;
my $vHash = CUL_HM_id2Hash($devId.sprintf("%02X",$chnPhyMax+2*$chnPhy-1)); my $vHash = CUL_HM_id2Hash($devId.sprintf("%02X",$chnPhyMax+2*$chnPhy-1));
@ -188,20 +198,21 @@ sub CUL_HM_updateConfig($){
} }
} }
} }
elsif ("virtual" eq $st) {#setup virtuals
$hash->{helper}{role}{vrt} = 1;
}
# add default web-commands # add default web-commands
my $webCmd; my $webCmd;
my $st = AttrVal(($hash->{device}?$hash->{device}:$name), "subType", "");
$webCmd = AttrVal($name,"webCmd",undef); $webCmd = AttrVal($name,"webCmd",undef);
if (!defined $webCmd){ if(!defined $webCmd){
if((length (CUL_HM_hash2Id($hash)) == 6)&& if ($st eq "virtual" ){$webCmd="press short:press long";
$hash->{channel_01} && }elsif($hash->{helper}{role}{dev} &&
$st ne "virtual" && !$hash->{helper}{role}{chn} &&
$st ne "thermostat" ){$webCmd="getConfig"; $st ne "thermostat" ){$webCmd="getConfig";
}elsif($st eq "blindActuator"){$webCmd="toggle:on:off:up:down:stop:statusRequest"; }elsif($st eq "blindActuator"){$webCmd="toggle:on:off:up:down:stop:statusRequest";
}elsif($st eq "dimmer" ){$webCmd="toggle:on:off:up:down:statusRequest"; }elsif($st eq "dimmer" ){$webCmd="toggle:on:off:up:down:statusRequest";
}elsif($st eq "switch" ){$webCmd="toggle:on:off:statusRequest"; }elsif($st eq "switch" ){$webCmd="toggle:on:off:statusRequest";
}elsif($st eq "virtual" ){$webCmd="press short:press long";
}elsif($st eq "smokeDetector"){$webCmd="test:alarmOn:alarmOff"; }elsif($st eq "smokeDetector"){$webCmd="test:alarmOn:alarmOff";
}elsif($st eq "keyMatic" ){$webCmd="lock:inhibit on:inhibit off"; }elsif($st eq "keyMatic" ){$webCmd="lock:inhibit on:inhibit off";
} }
@ -239,8 +250,12 @@ sub CUL_HM_Define($$) {##############################
$hash->{chanNo} = $chn; #readable ref to Channel $hash->{chanNo} = $chn; #readable ref to Channel
$devHash->{"channel_$chn"} = $name; #reference in device as well $devHash->{"channel_$chn"} = $name; #reference in device as well
$attr{$name}{model} = AttrVal($devName, "model", undef); $attr{$name}{model} = AttrVal($devName, "model", undef);
$hash->{helper}{role}{chn}=1;
delete $devHash->{helper}{role}{chn} if($chn eq "01");#device no longer
} }
else{# define a device else{# define a device
$hash->{helper}{role}{dev}=1;
$hash->{helper}{role}{chn}=1;# take role of chn 01 until it is defined
AssignIoPort($hash); AssignIoPort($hash);
} }
$modules{CUL_HM}{defptr}{$HMid} = $hash; $modules{CUL_HM}{defptr}{$HMid} = $hash;
@ -267,6 +282,7 @@ sub CUL_HM_Undef($$) {###############################
if ($chn){# delete a channel if ($chn){# delete a channel
my $devHash = CUL_HM_name2Hash($devName); my $devHash = CUL_HM_name2Hash($devName);
delete $devHash->{"channel_$chn"} if ($devName); delete $devHash->{"channel_$chn"} if ($devName);
$devHash->{helper}{role}{chn}=1 if($chn eq "01");# return chan 01 role
} }
else{# delete a device else{# delete a device
foreach my $channel (keys %{$hash}){ foreach my $channel (keys %{$hash}){
@ -298,7 +314,8 @@ sub CUL_HM_Rename($$$) {#############################
sub CUL_HM_Attr(@) {################################# sub CUL_HM_Attr(@) {#################################
my ($cmd,$name, $attrName,$attrVal) = @_; my ($cmd,$name, $attrName,$attrVal) = @_;
my @hashL; my @hashL;
if ($attrName eq "expert"){#[0,1,2] my $updtReq = 0;
if ($attrName eq "expert"){#[0,1,2]
$attr{$name}{expert} = $attrVal; $attr{$name}{expert} = $attrVal;
my $eHash = CUL_HM_name2Hash($name); my $eHash = CUL_HM_name2Hash($name);
foreach my $chId (CUL_HM_getAssChnIds($name)){ foreach my $chId (CUL_HM_getAssChnIds($name)){
@ -353,13 +370,16 @@ sub CUL_HM_Attr(@) {#################################
elsif($attrName eq "actCycle"){#"000:00" or 'off' elsif($attrName eq "actCycle"){#"000:00" or 'off'
return if (CUL_HM_name2Id($name) eq $K_actDetID); return if (CUL_HM_name2Id($name) eq $K_actDetID);
# Add to ActionDetector. Wait a little - config might not be finished # Add to ActionDetector. Wait a little - config might not be finished
$updtReq = 1;
}
if ($updtReq){
my @arr; my @arr;
if(!$modules{CUL_HM}{helper}{updtCfgLst}){ if(!$modules{CUL_HM}{helper}{updtCfgLst}){
$modules{CUL_HM}{helper}{updtCfgLst} = \@arr; $modules{CUL_HM}{helper}{updtCfgLst} = \@arr;
} }
push(@{$modules{CUL_HM}{helper}{updtCfgLst}}, $name); push(@{$modules{CUL_HM}{helper}{updtCfgLst}}, $name);
RemoveInternalTimer("updateConfig");
RemoveInternalTimer("updateConfig");
InternalTimer(gettimeofday()+5,"CUL_HM_updateConfig", "updateConfig", 0); InternalTimer(gettimeofday()+5,"CUL_HM_updateConfig", "updateConfig", 0);
} }
return; return;
@ -408,7 +428,7 @@ sub CUL_HM_Parse($$) {##############################
my $name = $shash->{NAME}; my $name = $shash->{NAME};
my @event; my @event;
my @entities; my @entities;
my $st = AttrVal($name, "subType", ""); my $st = AttrVal($name, "subType", "");# still on device level here
my $model = AttrVal($name, "model", ""); my $model = AttrVal($name, "model", "");
my $tn = TimeNow(); my $tn = TimeNow();
CUL_HM_storeRssi($name, CUL_HM_storeRssi($name,
@ -418,19 +438,25 @@ sub CUL_HM_Parse($$) {##############################
my $msgX = "No:$msgcnt - t:$msgType s:$src d:$dst ".($p?$p:""); my $msgX = "No:$msgcnt - t:$msgType s:$src d:$dst ".($p?$p:"");
if($shash->{lastMsg} && $shash->{lastMsg} eq $msgX) { if($shash->{lastMsg} && $shash->{lastMsg} eq $msgX) {
Log GetLogLevel($name,4), "CUL_HM $name dup mesg"; if($shash->{helper}{rpt} && #was responded
if(($id eq $dst)&& (hex($msgFlag)&0x20)){ $shash->{helper}{rpt}{IO} eq $ioName && #from same IO
# CUL_HM_SndCmd($shash, $msgcnt."8002".$id.$src."00"); # Send Ack $shash->{helper}{rpt}{msg} eq $msg && #not from repeater
Log GetLogLevel($name,4), "CUL_HM $name dup mesg - ack and ignore"; $shash->{helper}{rpt}{ts} < gettimeofday()-0.5){#todo: hack since HMLAN sends duplicate status messages
my $ack = $shash->{helper}{rpt}{ack};#shorthand
my $i=0;
CUL_HM_SndCmd(${$ack}[$i++],${$ack}[$i++]) while ($i<@{$ack});
$shash->{helper}{rpt}{ts} = gettimeofday();
Log GetLogLevel($name,4), "CUL_HM $name dup: repeat ack, dont process";
} }
else{ else{
Log GetLogLevel($name,4), "CUL_HM $name dup mesg - ignore"; Log GetLogLevel($name,4), "CUL_HM $name dup: dont process";
} }
return $name; #return something to please dispatcher return $name; #return something to please dispatcher
} }
$shash->{lastMsg} = $msgX; $shash->{lastMsg} = $msgX;
$iohash->{HM_CMDNR} = hex($msgcnt) if($dst eq $id);# updt message cnt to rec $iohash->{HM_CMDNR} = hex($msgcnt) if($dst eq $id);# updt message cnt to rec
delete $shash->{helper}{rpt};# new msg, rm recent ack
my @ack; # ack and responses, might be repeated
CUL_HM_DumpProtocol("RCV",$iohash,$len,$msgcnt,$msgFlag,$msgType,$src,$dst,$p); CUL_HM_DumpProtocol("RCV",$iohash,$len,$msgcnt,$msgFlag,$msgType,$src,$dst,$p);
@ -438,8 +464,6 @@ sub CUL_HM_Parse($$) {##############################
my $parse = CUL_HM_parseCommon($msgcnt,$msgFlag,$msgType,$src,$dst,$p); my $parse = CUL_HM_parseCommon($msgcnt,$msgFlag,$msgType,$src,$dst,$p);
push @event, "powerOn" if($parse eq "powerOn"); push @event, "powerOn" if($parse eq "powerOn");
my $sendAck = "yes";# if yes Ack will be determined automatically
if ($parse eq "ACK"){# remember - ACKinfo will be passed on if ($parse eq "ACK"){# remember - ACKinfo will be passed on
push @event, ""; push @event, "";
} }
@ -501,10 +525,9 @@ sub CUL_HM_Parse($$) {##############################
my ( $t, $h) = (hex($1), hex($2));# temp is 15 bit signed my ( $t, $h) = (hex($1), hex($2));# temp is 15 bit signed
$t = ($t & 0x3fff)/10*(($t & 0x4000)?-1:1); $t = ($t & 0x3fff)/10*(($t & 0x4000)?-1:1);
my $chnHash = $modules{CUL_HM}{defptr}{$src.$chn}; my $chnHash = $modules{CUL_HM}{defptr}{$src.$chn};
push @entities, push @entities,CUL_HM_UpdtReadBulk($chnHash,1,"state:T: $t H: $h",
CUL_HM_UpdtReadBulk($chnHash,1,"state:T: $t H: $h", # update weather channel "measured-temp:$t",
"measured-temp:$t", "humidity:$h")
"humidity:$h")
if ($chnHash); if ($chnHash);
push @event, "state:T: $t H: $h"; push @event, "state:T: $t H: $h";
push @event, "measured-temp:$t"; push @event, "measured-temp:$t";
@ -659,9 +682,8 @@ sub CUL_HM_Parse($$) {##############################
} }
elsif($cmd eq "A03F" && $id eq $dst) { # Timestamp request elsif($cmd eq "A03F" && $id eq $dst) { # Timestamp request
my $s2000 = sprintf("%02X", CUL_HM_secSince2000()); my $s2000 = sprintf("%02X", CUL_HM_secSince2000());
CUL_HM_SndCmd($shash, "++803F$id${src}0204$s2000"); push @ack,$shash,"++803F$id${src}0204$s2000";
push @event, "time-request"; push @event, "time-request";
$sendAck = "";
} }
} }
elsif($model eq "HM-CC-VD") { ############################################### elsif($model eq "HM-CC-VD") { ###############################################
@ -777,38 +799,43 @@ sub CUL_HM_Parse($$) {##############################
my ($subType,$chn,$val,$err) = ($1,hex($2),hex($3)/2,hex($4)) my ($subType,$chn,$val,$err) = ($1,hex($2),hex($3)/2,hex($4))
if($p =~ m/^(..)(..)(..)(..)/); if($p =~ m/^(..)(..)(..)(..)/);
$chn = sprintf("%02X",$chn&0x3f); $chn = sprintf("%02X",$chn&0x3f);
$shash = $modules{CUL_HM}{defptr}{"$src$chn"} my $chId = $src.$chn;
if($modules{CUL_HM}{defptr}{"$src$chn"}); $shash = $modules{CUL_HM}{defptr}{$chId}
my ($x,$pl) = ($1,hex($2)/2) if($p =~ m/^........(..)(..)$/); if($modules{CUL_HM}{defptr}{$chId});
my $stUpdt = 1;# shall state be updated? my $physLvl; #store phys level if available
if (defined $pl){# device with virtual channels... if($p =~ m/^........(..)(..)$/){ #message with physical level?
push @event,"virtLevel:".($val == 100?"on":($val == 0?"off":"$val %")); my $pl = hex($2)/2;
my $vDim = $shash->{helper}{vDim};#shortcut my $vDim = $shash->{helper}{vDim}; #shortcut
my $ph = CUL_HM_id2Hash($vDim->{idPhy}) if ($vDim->{idPhy}); if ($vDim->{idPhy} &&
if ($msgType eq "10"){ CUL_HM_id2Hash($vDim->{idPhy})){ #has virt chan
$val = $pl;# Physical level is pl - but only for InfoStatus RemoveInternalTimer("sUpdt:".$chId);
$pl = ($pl == 100 ? "on" : ($pl == 0 ? "off" : "$pl %")); if ($msgType eq "10"){ #valid PhysLevel
#set state for all virtual foreach my $tmpKey ("idPhy","idV2","idV3",){#update all virtuals
RemoveInternalTimer("sUpdt:".$ph->{NAME}); my $vh = CUL_HM_id2Hash($vDim->{$tmpKey}) if ($vDim->{$tmpKey});
if ($ph){ next if (!$vh || $vDim->{$tmpKey} eq $chId);
push @entities,CUL_HM_UpdtReadSingle($ph,"state",$pl,1); my $vl = ReadingsVal($vh->{NAME},"level","???");
my $vh; my $vs = ($vl eq "100 %"?"on":($vl eq "0 %"?"off":"$vl"));
$vh = CUL_HM_id2Hash($vDim->{idV2}) if ($vDim->{idV2}); $vs = (($pl." %") ne $vl)?"chn:$vs phys:$pl %":$vs;
push @entities,CUL_HM_UpdtReadSingle($vh,"state",$pl,1) if ($vh); push @entities,CUL_HM_UpdtReadBulk($vh ,1,"state:$vs",
$vh = CUL_HM_id2Hash($vDim->{idV3}) if ($vDim->{idV3}); "phyLevel:$pl %");
push @entities,CUL_HM_UpdtReadSingle($vh,"state",$pl,1) if ($vh); }
push @event,"phyLevel:$pl %"; #phys level
$physLvl = $pl." %";
}
else{ #invalid PhysLevel
InternalTimer(gettimeofday()+3,"CUL_HM_stateUpdat","sUpdt:".
$shash->{NAME},0);
} }
} }
else{
$stUpdt = 0;# no update
$val = ReadingsVal($name,"state",""); # keep value
InternalTimer(gettimeofday()+3,"CUL_HM_stateUpdat", "sUpdt:".$ph->{NAME}, 0);
}
} }
$physLvl = ReadingsVal($name,"phyLevel",$val." %")
if(!$physLvl); #not updated? use old or ignore
my $vs = ($val==100 ? "on":($val==0 ? "off":"$val %")); # user string...
$val = ($val == 100 ? "on" : ($val == 0 ? "off" : "$val %")) push @event,"level:$val %";
if ($stUpdt ); push @event,"deviceMsg:$vs$target" if($chn ne "00");
push @event, "deviceMsg:$val$target" if($chn ne "00"); push @event,"state:".(($physLvl ne $val." %")?"chn:$vs phys:$physLvl":
$vs);
my $eventName = "unknown"; # different names for events my $eventName = "unknown"; # different names for events
$eventName = "switch" if($st eq "switch"); $eventName = "switch" if($st eq "switch");
@ -816,9 +843,9 @@ sub CUL_HM_Parse($$) {##############################
$eventName = "dim" if($st eq "dimmer"); $eventName = "dim" if($st eq "dimmer");
my $action; #determine action my $action; #determine action
if ($st ne "switch"){ if ($st ne "switch"){
push @event, "$eventName:up:$val" if(($err&0x30) == 0x10); push @event, "$eventName:up:$vs" if(($err&0x30) == 0x10);
push @event, "$eventName:down:$val" if(($err&0x30) == 0x20); push @event, "$eventName:down:$vs" if(($err&0x30) == 0x20);
push @event, "$eventName:stop:$val" if(($err&0x30) == 0x00); push @event, "$eventName:stop:$vs" if(($err&0x30) == 0x00);
} }
if ($st eq "dimmer"){ if ($st eq "dimmer"){
push @event,"overload:".(($err&0x02)?"on":"off"); push @event,"overload:".(($err&0x02)?"on":"off");
@ -832,15 +859,14 @@ sub CUL_HM_Parse($$) {##############################
} }
elsif ($model eq "HM-SEC-SFA-SM"){ # && $chn eq "00") elsif ($model eq "HM-SEC-SFA-SM"){ # && $chn eq "00")
push @entities, push @entities,
CUL_HM_UpdtReadBulk(CUL_HM_getDeviceHash($shash),1, CUL_HM_UpdtReadBulk(CUL_HM_getDeviceHash($shash),1,
"powerError:" .(($err&0x02) ? "on":"off"), "powerError:" .(($err&0x02) ? "on":"off"),
"sabotageError:".(($err&0x04) ? "on":"off"), "sabotageError:".(($err&0x04) ? "on":"off"),
"battery:".(($err&0x08)?"critical":($err&0x80?"low":"ok"))); "battery:".(($err&0x08)?"critical":($err&0x80?"low":"ok")));
} }
elsif ($model eq "HM-LC-SW1-BA-PCB"){ elsif ($model eq "HM-LC-SW1-BA-PCB"){
push @event, "battery:" . (($err&0x80) ? "low" : "ok" ); push @event,"battery:" . (($err&0x80) ? "low" : "ok" );
} }
push @event, "state:$val";
} }
} }
elsif($st =~ m /^(remote|pushButton|swi)$/) { ############################### elsif($st =~ m /^(remote|pushButton|swi)$/) { ###############################
@ -985,8 +1011,7 @@ sub CUL_HM_Parse($$) {##############################
} }
if($id eq $dst && $cmd ne "8002" && $state){ if($id eq $dst && $cmd ne "8002" && $state){
CUL_HM_SndCmd($shash, $msgcnt."8002".$id.$src."0101${state}00"); push @ack,$shash,$msgcnt."8002".$id.$src."0101${state}00";
$sendAck = ""; #todo why is this special?
} }
} }
elsif($st eq "smokeDetector") { ############################################# elsif($st eq "smokeDetector") { #############################################
@ -1068,8 +1093,7 @@ sub CUL_HM_Parse($$) {##############################
} }
if($id eq $dst && (hex($msgFlag)&0x20)){ # Send Ack/Nack if($id eq $dst && (hex($msgFlag)&0x20)){ # Send Ack/Nack
CUL_HM_SndCmd($shash, $msgcnt."8002".$id.$src.($cmd eq "A001" ? "80":"00")); push @ack,$shash,$msgcnt."8002".$id.$src.($cmd eq "A001" ? "80":"00");
$sendAck = ""; #todo why is this special?
} }
} }
elsif($st eq "threeStateSensor") { ########################################## elsif($st eq "threeStateSensor") { ##########################################
@ -1125,9 +1149,6 @@ sub CUL_HM_Parse($$) {##############################
my %dir = (0=>"no",1=>"up",2=>"down",3=>"undefined"); my %dir = (0=>"no",1=>"up",2=>"down",3=>"undefined");
push @event, "motorError:".$err{(hex($stat)>>1)&0x02}; push @event, "motorError:".$err{(hex($stat)>>1)&0x02};
push @event, "direction:".$dir{(hex($stat)>>4)&0x02}; push @event, "direction:".$dir{(hex($stat)>>4)&0x02};
# CUL_HM_SndCmd($shash, $msgcnt."8002".$id.$src."0101".$lst."00")
# if($id eq $dst);# Send AckStatus
# $sendAck = "";
} }
else{ #should be akku else{ #should be akku
my %statF = (0=>"trickleCharge",1=>"charge",2=>"dischange",3=>"unknown"); my %statF = (0=>"trickleCharge",1=>"charge",2=>"dischange",3=>"unknown");
@ -1203,9 +1224,8 @@ sub CUL_HM_Parse($$) {##############################
if (hex($msgFlag)&0x20){ if (hex($msgFlag)&0x20){
$longPress .= "_Release"; $longPress .= "_Release";
$dChHash->{helper}{trgLgRpt}=0; $dChHash->{helper}{trgLgRpt}=0;
CUL_HM_SndCmd($dhash,$msgcnt."8002".$dst.$src.'01'.$dChNo. push @ack,$dhash,$msgcnt."8002".$dst.$src.'01'.$dChNo.
(($state eq "ON")?"C8":"00")."00"); (($state eq "ON")?"C8":"00")."00";
$sendAck = "";
} }
push @entities, push @entities,
CUL_HM_UpdtReadBulk($dChHash,1,"state:".$state, CUL_HM_UpdtReadBulk($dChHash,1,"state:".$state,
@ -1221,12 +1241,10 @@ sub CUL_HM_Parse($$) {##############################
my ($d1,$vp) =($1,hex($2)); # adjust_command[0..4] adj_data[0..250] my ($d1,$vp) =($1,hex($2)); # adjust_command[0..4] adj_data[0..250]
$vp = int($vp/2.56+0.5); # valve position in % $vp = int($vp/2.56+0.5); # valve position in %
my $chnHash = $modules{CUL_HM}{defptr}{$dst."01"}; my $chnHash = $modules{CUL_HM}{defptr}{$dst."01"};
push @entities, push @entities, CUL_HM_UpdtReadBulk($chnHash,1,"ValvePosition:$vp %",
CUL_HM_UpdtReadBulk($chnHash,1,"ValvePosition:$vp %", "ValveAdjCmd:".$d1);
"ValveAdjCmd:".$d1); push @ack,$chnHash,$msgcnt."8002".$dst.$src.'0101'.
CUL_HM_SndCmd($chnHash,$msgcnt."8002".$dst.$src.'0101'. sprintf("%02X",$vp*2)."0000";
sprintf("%02X",$vp*2)."0000");#$vp, $err,$??
$sendAck = "";
} }
elsif($msgType eq "02"){ elsif($msgType eq "02"){
if ($dhash->{helper}{respWait}{msgId} && if ($dhash->{helper}{respWait}{msgId} &&
@ -1235,31 +1253,36 @@ sub CUL_HM_Parse($$) {##############################
CUL_HM_respPendRm($dhash); CUL_HM_respPendRm($dhash);
} }
} }
if (hex($msgFlag)&0x20 && ($sendAck eq "yes")){ push @ack,$dhash,$msgcnt."8002".$dst.$src."00" if (hex($msgFlag)&0x20 && (!@ack));
CUL_HM_SndCmd($dhash, $msgcnt."8002".$dst.$src."00");#virtual must ack
}
} }
elsif($id eq $dst){# if fhem is destination check if we need to react elsif($id eq $dst){# if fhem is destination check if we need to react
if($msgType =~ m/^4./ && $p =~ m/^(..)/ && #Push Button event if($msgType =~ m/^4./ && $p =~ m/^(..)/ && #Push Button event
(hex($msgFlag)&0x20)){ #response required Flag (hex($msgFlag)&0x20)){ #response required Flag
my ($recChn) = ($1);# button number/event count my ($recChn) = (hex($1));# button number/event count
# fhem CUL shall ack a button press # fhem CUL shall ack a button press
CUL_HM_SndCmd($shash, $msgcnt."8002".$dst.$src."0101". push @ack,$shash,"($msgcnt)8002$dst($src)0101".(($recChn&1)?"C8":"00")."00";
((hex($recChn)&1)?"C8":"00")."00");#Actor simulation
$sendAck = "";
} }
} }
#------------ send default ACK if not applicable------------------ #------------ send default ACK if not applicable------------------
# ack if we are destination, anyone did accept the message (@event) # ack if we are destination, anyone did accept the message (@event)
# parser did not supress # parser did not supress
CUL_HM_SndCmd($shash, $msgcnt."8002".$id.$src."00") # Send Ack push @ack,$shash, $msgcnt."8002".$id.$src."00"
if( ($id eq $dst) #are we adressee if( ($id eq $dst) #are we adressee
&& (hex($msgFlag)&0x20) #response required Flag && (hex($msgFlag)&0x20) #response required Flag
&& @event #only ack of we identified it && @event #only ack of we identified it
&& ($sendAck eq "yes") #sender requested ACK && (!@ack) #sender requested ACK
); );
if (@ack) {# send acks and store for repeat
$modules{CUL_HM}{defptr}{$src}{helper}{rpt}{IO} = $ioName;
$modules{CUL_HM}{defptr}{$src}{helper}{rpt}{msg} = $msg;
$modules{CUL_HM}{defptr}{$src}{helper}{rpt}{ack} = \@ack;
$modules{CUL_HM}{defptr}{$src}{helper}{rpt}{ts} = gettimeofday();
my $i=0;
CUL_HM_SndCmd($ack[$i++],$ack[$i++]) while ($i<@ack);
}
CUL_HM_ProcessCmdStack($shash) if ($respRemoved); # cont stack if a response is complete CUL_HM_ProcessCmdStack($shash) if ($respRemoved); # cont stack if a response is complete
#------------ process events ------------------ #------------ process events ------------------
@ -1284,11 +1307,12 @@ sub CUL_HM_parseCommon(@){#####################################################
#------------ parse message flag for start processing command Stack #------------ parse message flag for start processing command Stack
# TC wakes up with 8270, not with A258 # TC wakes up with 8270, not with A258
# VD wakes up with 8202 # VD wakes up with 8202
# 9610
if( $shash->{cmdStack} && if( $shash->{cmdStack} &&
((hex($msgFlag) & 0xA2) == 0x82) && ((hex($msgFlag) & 0xA2) == 0x82) &&
(CUL_HM_getRxType($shash) & 0x08)){ #wakeup ##### (CUL_HM_getRxType($shash) & 0x08)){ #wakeup #####
#send wakeup and process command stack #send wakeup and process command stack
CUL_HM_SndCmd($shash, '++A112'.CUL_HM_IOid($shash).$src); #CUL_HM_SndCmd($shash, '++A112'.CUL_HM_IOid($shash).$src); #not necessary even for TC
CUL_HM_ProcessCmdStack($shash); CUL_HM_ProcessCmdStack($shash);
} }
@ -1297,7 +1321,7 @@ sub CUL_HM_parseCommon(@){#####################################################
#response we waited for - stop Waiting #response we waited for - stop Waiting
CUL_HM_respPendRm($shash); CUL_HM_respPendRm($shash);
} }
if ($msgType eq "02"){# Ack/Nack ############################# if ($msgType eq "02"){# Ack/Nack ###########################
#see if the channel is defined separate - otherwise go for chief #see if the channel is defined separate - otherwise go for chief
my $subType = substr($p,0,2); my $subType = substr($p,0,2);
@ -1694,17 +1718,23 @@ sub CUL_HM_Set($@) {
my $rxType = CUL_HM_getRxType($hash); my $rxType = CUL_HM_getRxType($hash);
my $flag = CUL_HM_getFlag($hash); #set burst flag my $flag = CUL_HM_getFlag($hash); #set burst flag
my $cmd = $a[1]; my $cmd = $a[1];
return "devicepair is outdated. Please use peerChan instead" if ($cmd eq "devicepair");#todo Updt4 remove at some point
my $dst = $hash->{DEF}; my $dst = $hash->{DEF};
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 $roleC = $hash->{helper}{role}{chn}?1:0; #entity may act in multiple roles
my $roleD = $hash->{helper}{role}{dev}?1:0;
my $roleV = $hash->{helper}{role}{vrt}?1:0;
my $mdCh = $md.($isChannel?$chn:"00"); # chan specific commands? my $mdCh = $md.($isChannel?$chn:"00"); # chan specific commands?
my $h = $culHmGlobalSets{$cmd} if($st ne "virtual"); my $h = $culHmGlobalSets{$cmd} if( $st ne "virtual");
$h = $culHmGlobalSetsDevice{$cmd} if(!defined($h) && $st ne "virtual" && !$isChannel); $h = $culHmGlobalSetsVrtDev{$cmd} if(!defined($h) &&($st eq "virtual"||!$st) && $roleD);
$h = $culHmSubTypeSets{$st}{$cmd} if(!defined($h) && $culHmSubTypeSets{$st}); $h = $culHmGlobalSetsDevice{$cmd} if(!defined($h) && $st ne "virtual" && $roleD);
$h = $culHmModelSets{$md}{$cmd} if(!defined($h) && $culHmModelSets{$md} ); $h = $culHmGlobalSetsChn{$cmd} if(!defined($h) && $st ne "virtual" && $roleC);
$h = $culHmChanSets{$mdCh}{$cmd} if(!defined($h) && $culHmChanSets{$mdCh} ); $h = $culHmSubTypeSets{$st}{$cmd} if(!defined($h) && $culHmSubTypeSets{$st} && $roleC);
$h = $culHmModelSets{$md}{$cmd} if(!defined($h) && $culHmModelSets{$md} );
$h = $culHmChanSets{$md."00"}{$cmd}if(!defined($h) && $culHmChanSets{$md."00"} && $roleD);
$h = $culHmChanSets{$md.$chn}{$cmd}if(!defined($h) && $culHmChanSets{$md.$chn} && $roleC);
my @h; my @h;
@h = split(" ", $h) if($h); @h = split(" ", $h) if($h);
@ -1714,11 +1744,14 @@ sub CUL_HM_Set($@) {
} }
elsif(!defined($h)) { elsif(!defined($h)) {
my @arr; my @arr;
@arr = keys %culHmGlobalSets if($st ne "virtual"); @arr = keys %culHmGlobalSets if( $st ne "virtual");
push @arr, keys %culHmGlobalSetsDevice if($st ne "virtual" && !$isChannel); push @arr, keys %culHmGlobalSetsVrtDev if(($st eq "virtual"||!$st) && $roleD);
push @arr, keys %{$culHmSubTypeSets{$st}} if($culHmSubTypeSets{$st}); push @arr, keys %culHmGlobalSetsDevice if( $st ne "virtual" && $roleD);
push @arr, keys %{$culHmModelSets{$md}} if($culHmModelSets{$md}); push @arr, keys %culHmGlobalSetsChn if( $st ne "virtual" && $roleC);
push @arr, keys %{$culHmChanSets{$mdCh}} if($culHmChanSets{$mdCh}); push @arr, keys %{$culHmSubTypeSets{$st}} if( $culHmSubTypeSets{$st} && $roleC);
push @arr, keys %{$culHmModelSets{$md}} if( $culHmModelSets{$md});
push @arr, keys %{$culHmChanSets{$md."00"}}if( $culHmChanSets{$md."00"} && $roleD);
push @arr, keys %{$culHmChanSets{$md.$chn}}if( $culHmChanSets{$md.$chn} && $roleC);
my $usg = "Unknown argument $cmd, choose one of ".join(" ",sort @arr); my $usg = "Unknown argument $cmd, choose one of ".join(" ",sort @arr);
$usg =~ s/ pct/ pct:slider,0,1,100/; $usg =~ s/ pct/ pct:slider,0,1,100/;
@ -1761,7 +1794,7 @@ sub CUL_HM_Set($@) {
my $id = CUL_HM_IOid($hash); my $id = CUL_HM_IOid($hash);
my $state = "set_".join(" ", @a[1..(int(@a)-1)]); my $state = "set_".join(" ", @a[1..(int(@a)-1)]);
if($cmd eq "raw") { ######################################################## if ($cmd eq "raw") { #####################################################
return "Usage: set $a[0] $cmd data [data ...]" if(@a < 3); return "Usage: set $a[0] $cmd data [data ...]" if(@a < 3);
$state = ""; $state = "";
for (my $i = 2; $i < @a; $i++) { for (my $i = 2; $i < @a; $i++) {
@ -1785,7 +1818,7 @@ sub CUL_HM_Set($@) {
delete ($hash->{EVENTS}); delete ($hash->{EVENTS});
delete ($hash->{helper}{rssi}); delete ($hash->{helper}{rssi});
} }
$hash->{protState} = "Info_Cleared" ; CUL_HM_protState($hash,"Info_Cleared");
} }
else{ else{
return "unknown section. User readings or msgEvents"; return "unknown section. User readings or msgEvents";
@ -1834,9 +1867,9 @@ sub CUL_HM_Set($@) {
return "unknown peer".$peer if (length($pID) != 8);# peer only to channel return "unknown peer".$peer if (length($pID) != 8);# peer only to channel
my $pCh1 = substr($pID,6,2); my $pCh1 = substr($pID,6,2);
my $pCh2 = $pCh1; my $pCh2 = $pCh1;
if($culHmSubTypeSets{$st}{peerChan}|| if(($culHmSubTypeSets{$st} &&$culHmSubTypeSets{$st}{peerChan} )||
$culHmModelSets{$md}{peerChan}|| ($culHmModelSets{$md} &&$culHmModelSets{$md}{peerChan} )||
$culHmChanSets{$mdCh}{peerChan}){ ($culHmChanSets{$md.$chn} &&$culHmChanSets{$md.$chn}{peerChan}) ){
$pCh2 = "00"; # button behavior $pCh2 = "00"; # button behavior
} }
CUL_HM_PushCmdStack($hash,'++'.$flag.'01'.$id.$dst.$chn.'01'. CUL_HM_PushCmdStack($hash,'++'.$flag.'01'.$id.$dst.$chn.'01'.
@ -2068,18 +2101,19 @@ sub CUL_HM_Set($@) {
} }
elsif($cmd eq "text") { ################################################# reg elsif($cmd eq "text") { ################################################# reg
$state = ""; $state = "";
return "$a[2] is not a button number" if($a[2] !~ m/^\d$/ || $a[2] < 1); my ($bn,$l1, $l2, $s) = ($chn,$a[2],$a[3],54); # Create CONFIG_WRITE_INDEX string
return "$a[3] is not on or off" if($a[3] !~ m/^(on|off)$/); if (!$roleC){# if used on device. Should be removed :todo
my $bn = $a[2]*2-($a[3] eq "on" ? 0 : 1); return "$a[2] is not a button number" if($a[2] !~ m/^\d$/ || $a[2] < 1);
return "$a[3] is not on or off" if($a[3] !~ m/^(on|off)$/);
$bn = $a[2]*2-($a[3] eq "on" ? 0 : 1);
($l1, $l2) = ($a[4],$a[5]);
}
my ($l1, $l2, $s); # Create CONFIG_WRITE_INDEX string $l1 = substr($l1."\x00", 0, 13);
$l1 = $a[4] . "\x00";
$l1 = substr($l1, 0, 13);
$s = 54; $s = 54;
$l1 =~ s/(.)/sprintf("%02X%02X",$s++,ord($1))/ge; $l1 =~ s/(.)/sprintf("%02X%02X",$s++,ord($1))/ge;
$l2 = $a[5] . "\x00"; $l2 = substr($l2."\x00", 0, 13);
$l2 = substr($l2, 0, 13);
$s = 70; $s = 70;
$l2 =~ s/(.)/sprintf("%02X%02X",$s++,ord($1))/ge; $l2 =~ s/(.)/sprintf("%02X%02X",$s++,ord($1))/ge;
$l1 .= $l2; $l1 .= $l2;
@ -2389,7 +2423,7 @@ sub CUL_HM_Set($@) {
$pressCnt)); $pressCnt));
} }
} }
elsif($cmd =~ m/^(devicepair|peerChan)$/) { ################################# elsif($cmd eq "peerChan") { #################################################
#peerChan <btnN> device ... [single|dual] [set|unset] [actor|remote|both] #peerChan <btnN> device ... [single|dual] [set|unset] [actor|remote|both]
my ($bNo,$peerN,$single,$set,$target) = ($a[2],$a[3],$a[4],$a[5],$a[6]); my ($bNo,$peerN,$single,$set,$target) = ($a[2],$a[3],$a[4],$a[5],$a[6]);
$state = ""; $state = "";
@ -2429,7 +2463,9 @@ sub CUL_HM_Set($@) {
my $cmdB = ($set)?"01":"02";# do we set or remove? my $cmdB = ($set)?"01":"02";# do we set or remove?
# First the remote (one loop for on, one for off) # First the remote (one loop for on, one for off)
my $pSt = AttrVal( CUL_HM_id2Name($peerDst), "subType", "");#peer SubType
if (!$target || $target =~ m/^(remote|both)$/){ if (!$target || $target =~ m/^(remote|both)$/){
my $burst = ($pSt eq "thermostat"?"0101":"0100");#set burst for target
for(my $i = 1; $i <= $nrCh2Pair; $i++) { for(my $i = 1; $i <= $nrCh2Pair; $i++) {
my $b = ($i==1 ? $b1 : $b2); my $b = ($i==1 ? $b1 : $b2);
if ($st eq "virtual"){ if ($st eq "virtual"){
@ -2442,13 +2478,13 @@ sub CUL_HM_Set($@) {
my $bStr = sprintf("%02X",$b); my $bStr = sprintf("%02X",$b);
CUL_HM_PushCmdStack($hash, CUL_HM_PushCmdStack($hash,
"++".$flag."01${id}${dst}${bStr}$cmdB${peerDst}${peerChn}00"); "++".$flag."01${id}${dst}${bStr}$cmdB${peerDst}${peerChn}00");
CUL_HM_pushConfig($hash,$id, $dst,$b,$peerDst,hex($peerChn),4,"0100") CUL_HM_pushConfig($hash,$id, $dst,$b,$peerDst,hex($peerChn),4,$burst)
if($md ne "HM-CC-TC"); if($md ne "HM-CC-TC");
} }
} }
} }
if (!$target || $target =~ m/^(actor|both)$/ ){ if (!$target || $target =~ m/^(actor|both)$/ ){
if (AttrVal( CUL_HM_id2Name($peerDst), "subType", "") eq "virtual"){ if ($pSt eq "virtual"){
CUL_HM_ID2PeerList ($peerN,$dst.sprintf("%02X",$b2),$set); #update peerlist CUL_HM_ID2PeerList ($peerN,$dst.sprintf("%02X",$b2),$set); #update peerlist
CUL_HM_ID2PeerList ($peerN,$dst.sprintf("%02X",$b1),$set) if ($b1 & !$single); #update peerlist CUL_HM_ID2PeerList ($peerN,$dst.sprintf("%02X",$b1),$set) if ($b1 & !$single); #update peerlist
} }
@ -2743,10 +2779,15 @@ sub CUL_HM_eventP($$) {#handle protocol events
my $delMsgSum; my $delMsgSum;
$nAttr->{protCmdDel} = 0 if(!$nAttr->{protCmdDel}); $nAttr->{protCmdDel} = 0 if(!$nAttr->{protCmdDel});
$nAttr->{protCmdDel} += scalar @{$hash->{cmdStack}} if ($hash->{cmdStack}); $nAttr->{protCmdDel} += scalar @{$hash->{cmdStack}} if ($hash->{cmdStack});
$hash->{protState} = "CMDs_done".($hash->{helper}{burstEvtCnt}? CUL_HM_protState($hash,"CMDs_done".($hash->{helper}{burstEvtCnt}?
("_events:".$hash->{helper}{burstEvtCnt}):""); ("_events:".$hash->{helper}{burstEvtCnt}):""));
} }
} }
sub CUL_HM_protState($$){
my ($hash,$state) = @_;
$hash->{protState} = $state;
readingsSingleUpdate($hash,"state",$state,1)if (!$hash->{helper}{role}{chn});
}
sub CUL_HM_respPendRm($) {#del response related entries in messageing entity sub CUL_HM_respPendRm($) {#del response related entries in messageing entity
my ($hash) = @_; my ($hash) = @_;
delete ($hash->{helper}{respWait}); delete ($hash->{helper}{respWait});
@ -2776,8 +2817,8 @@ sub CUL_HM_respPendTout($) {
if ((CUL_HM_getRxType($hash) & 0x03) == 0){#to slow for wakeup and config if ((CUL_HM_getRxType($hash) & 0x03) == 0){#to slow for wakeup and config
delete($hash->{cmdStack}); delete($hash->{cmdStack});
delete($hash->{protCmdPend}); delete($hash->{protCmdPend});
$hash->{protState} = "CMDs_done".($hash->{helper}{burstEvtCnt}? CUL_HM_protState($hash,"CMDs_done".($hash->{helper}{burstEvtCnt}?
("_events:".$hash->{helper}{burstEvtCnt}):""); ("_events:".$hash->{helper}{burstEvtCnt}):""));
} }
CUL_HM_respPendRm($hash); CUL_HM_respPendRm($hash);
CUL_HM_ProcessCmdStack($hash); # continue processing commands CUL_HM_ProcessCmdStack($hash); # continue processing commands
@ -2802,7 +2843,7 @@ sub CUL_HM_PushCmdStack($$) {
push(@{$hash->{cmdStack}}, $cmd); push(@{$hash->{cmdStack}}, $cmd);
my $entries = scalar @{$hash->{cmdStack}}; my $entries = scalar @{$hash->{cmdStack}};
$hash->{protCmdPend} = $entries." CMDs_pending"; $hash->{protCmdPend} = $entries." CMDs_pending";
$hash->{protState} = "CMDs_pending" CUL_HM_protState($hash,"CMDs_pending")
if (!$hash->{helper}{respWait}{cmd} && if (!$hash->{helper}{respWait}{cmd} &&
!$hash->{helper}{respWait}{Pending}); !$hash->{helper}{respWait}{Pending});
} }
@ -2817,15 +2858,15 @@ sub CUL_HM_ProcessCmdStack($) {
CUL_HM_SndCmd($hash, shift @{$hash->{cmdStack}}); CUL_HM_SndCmd($hash, shift @{$hash->{cmdStack}});
$sent = 1; $sent = 1;
$hash->{protCmdPend} = scalar @{$hash->{cmdStack}}." CMDs pending"; $hash->{protCmdPend} = scalar @{$hash->{cmdStack}}." CMDs pending";
$hash->{protState} = "CMDs_processing..."; CUL_HM_protState($hash,"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($hash->{protCmdPend}); delete($hash->{protCmdPend});
#-- update info --- #-- update info ---
$hash->{protState} = "CMDs_done".($hash->{helper}{burstEvtCnt}? CUL_HM_protState($hash,"CMDs_done".($hash->{helper}{burstEvtCnt}?
("_events:".$hash->{helper}{burstEvtCnt}):""); ("_events:".$hash->{helper}{burstEvtCnt}):""));
} }
} }
return $sent; return $sent;
@ -2872,8 +2913,8 @@ sub CUL_HM_pushConfig($$$$$$$$) {#generate messages to cnfig data to register
substr($content,$l,$ml)); substr($content,$l,$ml));
} }
CUL_HM_PushCmdStack($hash,"++A001".$src.$dst.$chn."06"); CUL_HM_PushCmdStack($hash,"++A001".$src.$dst.$chn."06");
CUL_HM_queueAutoRead(CUL_HM_hash2Name($hash)) my $rd = substr(CUL_HM_Get($hash,$hash->{NAME},"param","autoReadReg"),0,1);
if (2 < substr(CUL_HM_Get($hash,$hash->{NAME},"param","autoReadReg"),0,1)); CUL_HM_queueAutoRead(CUL_HM_hash2Name($hash)) if ($rd=~m/\d/ && 2 < $rd);
} }
sub CUL_HM_Resend($) {#resend a message if there is no answer sub CUL_HM_Resend($) {#resend a message if there is no answer
my $hash = shift; my $hash = shift;
@ -2884,8 +2925,8 @@ sub CUL_HM_Resend($) {#resend a message if there is no answer
delete($hash->{cmdStack}); delete($hash->{cmdStack});
delete($hash->{protCmdPend}); delete($hash->{protCmdPend});
CUL_HM_respPendRm($hash); CUL_HM_respPendRm($hash);
$hash->{protState} = "CMDs_done".($hash->{helper}{burstEvtCnt}? CUL_HM_protState($hash,"CMDs_done".($hash->{helper}{burstEvtCnt}?
("_events:".$hash->{helper}{burstEvtCnt}):""); ("_events:".$hash->{helper}{burstEvtCnt}):""));
readingsSingleUpdate($hash,"state","MISSING ACK",1); readingsSingleUpdate($hash,"state","MISSING ACK",1);
} }
else { else {
@ -4025,7 +4066,7 @@ sub CUL_HM_putHash($) {# provide data for HMinfo
</ul> </ul>
<br> <br>
subType (i.e family) dependent commands: <B>subType (i.e family) dependent commands:</B>
<ul> <ul>
<br> <br>
<li>switch <li>switch
@ -4050,7 +4091,7 @@ sub CUL_HM_putHash($) {# provide data for HMinfo
</ul> </ul>
<br> <br>
</li> </li>
<li>dimmer, blindActuator <li>dimmer, blindActuator<br>
Dimmer may support virtual channels. Those are autocrated if applicable. Usually there are 2 virtual channels Dimmer may support virtual channels. Those are autocrated if applicable. Usually there are 2 virtual channels
in addition to the primary channel. Virtual dimmer channels are inactive by default but can be used in in addition to the primary channel. Virtual dimmer channels are inactive by default but can be used in
in parallel to the primay channel to control light. <br> in parallel to the primay channel to control light. <br>
@ -4067,7 +4108,7 @@ sub CUL_HM_putHash($) {# provide data for HMinfo
</li> </li>
<li><B>on</B> set level to 100%<br></li> <li><B>on</B> set level to 100%<br></li>
<li><B>off</B> set level to 0%<br></li> <li><B>off</B> set level to 0%<br></li>
<li><B><a href="#CUL_HMpress">press &lt;[short|long]&gt;&lt;[on|off]&gt;</B></li> <li><B><a href="#CUL_HMpress">press &lt;[short|long]&gt;&lt;[on|off]&gt;</a></B></li>
<li><B>toggle</B> - toggle between off and the last on-value</li> <li><B>toggle</B> - toggle between off and the last on-value</li>
<li><B><a href="#CUL_HMonForTimer">on-for-timer &lt;sec&gt;</a></B> - Dimmer only! <br></li> <li><B><a href="#CUL_HMonForTimer">on-for-timer &lt;sec&gt;</a></B> - Dimmer only! <br></li>
<li><B><a href="#CUL_HMonForTimer">on-till &lt;time&gt;</a></B> - Dimmer only! <br></li> <li><B><a href="#CUL_HMonForTimer">on-till &lt;time&gt;</a></B> - Dimmer only! <br></li>
@ -4157,9 +4198,8 @@ sub CUL_HM_putHash($) {# provide data for HMinfo
</ul> </ul>
</li> </li>
</ul> </ul>
<br>
</li> </li>
<li>virtual<a name="CUL_HMvirtual"></a><br> <li><br>virtual<a name="CUL_HMvirtual"></a><br>
<ul> <ul>
<li><B><a href="#CUL_HMpeerChan">peerChan</a></B> see remote</li> <li><B><a href="#CUL_HMpeerChan">peerChan</a></B> see remote</li>
<li><B>press [long|short]<a name="CUL_HMpress"></a></B> <li><B>press [long|short]<a name="CUL_HMpress"></a></B>
@ -4169,7 +4209,7 @@ sub CUL_HM_putHash($) {# provide data for HMinfo
</li> </li>
</ul> </ul>
</li> </li>
<li>smokeDetector<br> <li><br>smokeDetector<br>
Note: All these commands work right now only if you have more then one Note: All these commands work right now only if you have more then one
smoekDetector, and you peered them to form a group. For issuing the smoekDetector, and you peered them to form a group. For issuing the
commands you have to use the master of this group, and currently you commands you have to use the master of this group, and currently you
@ -4185,17 +4225,20 @@ sub CUL_HM_putHash($) {# provide data for HMinfo
<li><B>alarmOff</B> - switch off the alarm</li> <li><B>alarmOff</B> - switch off the alarm</li>
</ul> </ul>
</li> </li>
<li>4Dis (HM-PB-4DIS-WM) <li><br>4Dis (HM-PB-4DIS-WM)
<ul> <ul>
<li><B>text &lt;btn_no&gt; [on|off] &lt;text1&gt; &lt;text2&gt;</B><br> <li><B>text &lt;btn_no&gt; [on|off] &lt;text1&gt; &lt;text2&gt;</B><br>
Set the text on the display of the device. To this purpose issue Set the text on the display of the device. To this purpose issue
this set command first (or a number of them), and then choose from this set command first (or a number of them), and then choose from
the teach-in menu of the 4Dis the "Central" to transmit the data. the teach-in menu of the 4Dis the "Central" to transmit the data.<br>
If used on a channel btn_no and on|off must not be given but only pure text.
Example: Example:
<ul> <ul>
<code> <code>
set 4Dis text 1 on On Lamp<br> set 4Dis text 1 on On Lamp<br>
set 4Dis text 1 off Kitchen Off<br> set 4Dis text 1 off Kitchen Off<br>
<br>
set 4Dis_chn4 text Kitchen Off<br>
</code> </code>
</ul> </ul>
</li> </li>

View File

@ -134,19 +134,19 @@ my %culHmModel=(
"0064" => {name=>"DORMA_atent" ,st=>'' ,cyc=>'' ,rxt=>'c' ,lst=>'1,3' ,chn=>"",}, # DORMA Remote 3 buttons "0064" => {name=>"DORMA_atent" ,st=>'' ,cyc=>'' ,rxt=>'c' ,lst=>'1,3' ,chn=>"",}, # DORMA Remote 3 buttons
"0065" => {name=>"DORMA_BRC-H" ,st=>'' ,cyc=>'' ,rxt=>'c' ,lst=>'1,3' ,chn=>"",}, # Dorma Remote 4 single buttons "0065" => {name=>"DORMA_BRC-H" ,st=>'' ,cyc=>'' ,rxt=>'c' ,lst=>'1,3' ,chn=>"",}, # Dorma Remote 4 single buttons
"0066" => {name=>"HM-LC-SW4-WM" ,st=>'switch' ,cyc=>'' ,rxt=>'b' ,lst=>'3' ,chn=>"Sw:1:4",}, "0066" => {name=>"HM-LC-SW4-WM" ,st=>'switch' ,cyc=>'' ,rxt=>'b' ,lst=>'3' ,chn=>"Sw:1:4",},
"0067" => {name=>"HM-LC-Dim1PWM-CV" ,st=>'dimmer' ,cyc=>'' ,rxt=>'' ,lst=>'1,3' ,chn=>"Sw1_V:2:3",},#Sw:1:1, "0067" => {name=>"HM-LC-Dim1PWM-CV" ,st=>'dimmer' ,cyc=>'' ,rxt=>'' ,lst=>'1,3' ,chn=>"Sw:1:1,Sw1_V:2:3",},
"0068" => {name=>"HM-LC-Dim1TPBU-FM" ,st=>'dimmer' ,cyc=>'' ,rxt=>'' ,lst=>'1,3' ,chn=>"Sw1_V:2:3",},#Sw:1:1, "0068" => {name=>"HM-LC-Dim1TPBU-FM" ,st=>'dimmer' ,cyc=>'' ,rxt=>'' ,lst=>'1,3' ,chn=>"Sw:1:1,Sw1_V:2:3",},
"0069" => {name=>"HM-LC-Sw1PBU-FM" ,st=>'switch' ,cyc=>'' ,rxt=>'' ,lst=>'1,3' ,chn=>"",}, "0069" => {name=>"HM-LC-Sw1PBU-FM" ,st=>'switch' ,cyc=>'' ,rxt=>'' ,lst=>'1,3' ,chn=>"",},
"006A" => {name=>"HM-LC-Bl1PBU-FM" ,st=>'blindActuator' ,cyc=>'' ,rxt=>'' ,lst=>'1,3' ,chn=>"",}, "006A" => {name=>"HM-LC-Bl1PBU-FM" ,st=>'blindActuator' ,cyc=>'' ,rxt=>'' ,lst=>'1,3' ,chn=>"",},
"006B" => {name=>"HM-PB-2-WM55" ,st=>'pushButton' ,cyc=>'' ,rxt=>'c:w' ,lst=>'1,4' ,chn=>"Btn:1:2",}, "006B" => {name=>"HM-PB-2-WM55" ,st=>'pushButton' ,cyc=>'' ,rxt=>'c:w' ,lst=>'1,4' ,chn=>"Btn:1:2",},
"006C" => {name=>"HM-LC-SW1-BA-PCB" ,st=>'switch' ,cyc=>'' ,rxt=>'b' ,lst=>'3' ,chn=>"",}, "006C" => {name=>"HM-LC-SW1-BA-PCB" ,st=>'switch' ,cyc=>'' ,rxt=>'b' ,lst=>'3' ,chn=>"",},
"006D" => {name=>"HM-OU-LED16" ,st=>'outputUnit' ,cyc=>'' ,rxt=>'' ,lst=>'' ,chn=>"Led:1:16",}, "006D" => {name=>"HM-OU-LED16" ,st=>'outputUnit' ,cyc=>'' ,rxt=>'' ,lst=>'' ,chn=>"Led:1:16",},
"006E" => {name=>"HM-LC-Dim1L-CV" ,st=>'dimmer' ,cyc=>'' ,rxt=>'' ,lst=>'1,3' ,chn=>"Sw1_V:2:3",},# Sw:1:1, "006E" => {name=>"HM-LC-Dim1L-CV" ,st=>'dimmer' ,cyc=>'' ,rxt=>'' ,lst=>'1,3' ,chn=>"Sw:1:1,Sw1_V:2:3",},
"006F" => {name=>"HM-LC-Dim1L-Pl" ,st=>'dimmer' ,cyc=>'' ,rxt=>'' ,lst=>'1,3' ,chn=>"Sw1_V:2:3",},# Sw:1:1, "006F" => {name=>"HM-LC-Dim1L-Pl" ,st=>'dimmer' ,cyc=>'' ,rxt=>'' ,lst=>'1,3' ,chn=>"Sw:1:1,Sw1_V:2:3",},
"0070" => {name=>"HM-LC-Dim2L-SM" ,st=>'dimmer' ,cyc=>'' ,rxt=>'' ,lst=>'1,3' ,chn=>"Sw:1:2,Sw1_V:3:4,Sw2_V:5:6",},# "0070" => {name=>"HM-LC-Dim2L-SM" ,st=>'dimmer' ,cyc=>'' ,rxt=>'' ,lst=>'1,3' ,chn=>"Sw:1:2,Sw1_V:3:4,Sw2_V:5:6",},#
"0071" => {name=>"HM-LC-Dim1T-Pl" ,st=>'dimmer' ,cyc=>'' ,rxt=>'' ,lst=>'1,3' ,chn=>"Sw1_V:2:3",},# Sw:1:1, "0071" => {name=>"HM-LC-Dim1T-Pl" ,st=>'dimmer' ,cyc=>'' ,rxt=>'' ,lst=>'1,3' ,chn=>"Sw:1:1,Sw1_V:2:3",},
"0072" => {name=>"HM-LC-Dim1T-CV" ,st=>'dimmer' ,cyc=>'' ,rxt=>'' ,lst=>'1,3' ,chn=>"Sw1_V:2:3",},# Sw:1:1, "0072" => {name=>"HM-LC-Dim1T-CV" ,st=>'dimmer' ,cyc=>'' ,rxt=>'' ,lst=>'1,3' ,chn=>"Sw:1:1,Sw1_V:2:3",},
"0073" => {name=>"HM-LC-Dim1T-FM" ,st=>'dimmer' ,cyc=>'' ,rxt=>'' ,lst=>'1,3' ,chn=>"Sw1_V:2:3",},# Sw:1:1, "0073" => {name=>"HM-LC-Dim1T-FM" ,st=>'dimmer' ,cyc=>'' ,rxt=>'' ,lst=>'1,3' ,chn=>"Sw:1:1,Sw1_V:2:3",},
"0074" => {name=>"HM-LC-Dim2T-SM" ,st=>'dimmer' ,cyc=>'' ,rxt=>'' ,lst=>'1,3' ,chn=>"Sw:1:2,Sw1_V:3:4,Sw2_V:5:6",},# "0074" => {name=>"HM-LC-Dim2T-SM" ,st=>'dimmer' ,cyc=>'' ,rxt=>'' ,lst=>'1,3' ,chn=>"Sw:1:2,Sw1_V:3:4,Sw2_V:5:6",},#
"0075" => {name=>"HM-OU-CFM-PL" ,st=>'outputUnit' ,cyc=>'' ,rxt=>'' ,lst=>'3' ,chn=>"Led:1:1,Mp3:2:2",}, "0075" => {name=>"HM-OU-CFM-PL" ,st=>'outputUnit' ,cyc=>'' ,rxt=>'' ,lst=>'3' ,chn=>"Led:1:1,Mp3:2:2",},
"0076" => {name=>"HM-Sys-sRP-Pl" ,st=>'repeater' ,cyc=>'' ,rxt=>'' ,lst=>'2' ,chn=>"",}, # repeater "0076" => {name=>"HM-Sys-sRP-Pl" ,st=>'repeater' ,cyc=>'' ,rxt=>'' ,lst=>'2' ,chn=>"",}, # repeater
@ -488,9 +488,6 @@ my %culHmRegType = (
remote =>{expectAES =>1,peerNeedsBurst =>1,dblPress =>1,longPress =>1, remote =>{expectAES =>1,peerNeedsBurst =>1,dblPress =>1,longPress =>1,
sign =>1, sign =>1,
}, },
pushButton =>{expectAES =>1,peerNeedsBurst =>1,dblPress =>1,longPress =>1,
sign =>1,
},
blindActuator =>{driveUp =>1,driveDown =>1,driveTurn =>1,refRunCounter =>1, blindActuator =>{driveUp =>1,driveDown =>1,driveTurn =>1,refRunCounter =>1,
sign =>1, sign =>1,
transmitTryMax =>1,statusInfoMinDly=>1,statusInfoRandom=>1, # nt present in all files transmitTryMax =>1,statusInfoMinDly=>1,statusInfoRandom=>1, # nt present in all files
@ -553,20 +550,14 @@ my %culHmRegType = (
peerNeedsBurst =>1,expectAES =>1, peerNeedsBurst =>1,expectAES =>1,
}, },
); );
#clones - - - - - - - - - - - - - - -
$culHmRegType{pushButton} = $culHmRegType{remote};
my %culHmRegModel = ( my %culHmRegModel = (
"HM-RC-12" =>{backAtKey =>1, backAtMotion =>1, backOnTime =>1}, "HM-RC-12" =>{backAtKey =>1, backAtMotion =>1, backOnTime =>1},
"HM-RC-12-B" =>{backAtKey =>1, backAtMotion =>1, backOnTime =>1},
"HM-RC-12-SW" =>{backAtKey =>1, backAtMotion =>1, backOnTime =>1},
"HM-RC-19" =>{backAtKey =>1, backAtMotion =>1, backOnTime =>1,backAtCharge =>1,language =>1,}, "HM-RC-19" =>{backAtKey =>1, backAtMotion =>1, backOnTime =>1,backAtCharge =>1,language =>1,},
"HM-RC-19-B" =>{backAtKey =>1, backAtMotion =>1, backOnTime =>1,backAtCharge =>1,language =>1,},
"HM-RC-19-SW" =>{backAtKey =>1, backAtMotion =>1, backOnTime =>1,backAtCharge =>1,language =>1,},
"HM-LC-Dim1PWM-CV"=>{characteristic =>1}, "HM-LC-Dim1PWM-CV"=>{characteristic =>1},
"HM-LC-Dim1L-P" =>{loadAppearBehav =>1,loadErrCalib =>1}, "HM-LC-Dim1L-P" =>{loadAppearBehav =>1,loadErrCalib =>1},
"HM-LC-Dim1L-CV" =>{loadAppearBehav =>1,loadErrCalib =>1},
"HM-LC-Dim2L-SM" =>{loadAppearBehav =>1,loadErrCalib =>1},
"HM-CC-VD" =>{valveOffset =>1,valveError =>1}, "HM-CC-VD" =>{valveOffset =>1,valveError =>1},
"HM-PB-4DIS-WM" =>{peerNeedsBurst =>1,expectAES =>1,language =>1,stbyTime =>1}, "HM-PB-4DIS-WM" =>{peerNeedsBurst =>1,expectAES =>1,language =>1,stbyTime =>1},
@ -617,6 +608,15 @@ my %culHmRegModel = (
fillLvlUpThr =>1,fillLvlLoThr =>1, fillLvlUpThr =>1,fillLvlLoThr =>1,
expectAES =>1,peerNeedsBurst =>1,}, expectAES =>1,peerNeedsBurst =>1,},
); );
#clones - - - - - - - - - - - - - - -
$culHmRegModel{"HM-RC-12-B"} = $culHmRegModel{"HM-RC-12"};
$culHmRegModel{"HM-RC-12-SW"} = $culHmRegModel{"HM-RC-12"};
$culHmRegModel{"HM-RC-19-B"} = $culHmRegModel{"HM-RC-19"};
$culHmRegModel{"HM-RC-19-SW"} = $culHmRegModel{"HM-RC-19"};
$culHmRegModel{"HM-LC-Dim1L-CV"} = $culHmRegModel{"HM-LC-Dim1L-P"};
$culHmRegModel{"HM-LC-Dim1L-SM"} = $culHmRegModel{"HM-LC-Dim1L-P"};
my %culHmRegChan = (# if channelspecific then enter them here my %culHmRegChan = (# if channelspecific then enter them here
"HM-CC-TC02" =>{displayMode =>1,displayTemp =>1,displayTempUnit=>1, "HM-CC-TC02" =>{displayMode =>1,displayTemp =>1,displayTempUnit=>1,
controlMode =>1,decalcDay =>1, controlMode =>1,decalcDay =>1,
@ -629,12 +629,6 @@ my %culHmRegChan = (# if channelspecific then enter them here
"HM-RC-1912" =>{msgShowTime =>1, beepAtAlarm =>1, beepAtService =>1,beepAtInfo =>1, "HM-RC-1912" =>{msgShowTime =>1, beepAtAlarm =>1, beepAtService =>1,beepAtInfo =>1,
backlAtAlarm =>1, backlAtService =>1, backlAtInfo =>1, backlAtAlarm =>1, backlAtService =>1, backlAtInfo =>1,
lcdSymb =>1, lcdLvlInterp =>1}, lcdSymb =>1, lcdLvlInterp =>1},
"HM-RC-19-B12" =>{msgShowTime =>1, beepAtAlarm =>1, beepAtService =>1,beepAtInfo =>1,
backlAtAlarm =>1, backlAtService =>1, backlAtInfo =>1,
lcdSymb =>1, lcdLvlInterp =>1},
"HM-RC-19-SW12" =>{msgShowTime =>1, beepAtAlarm =>1, beepAtService =>1,beepAtInfo =>1,
backlAtAlarm =>1, backlAtService =>1, backlAtInfo =>1,
lcdSymb =>1, lcdLvlInterp =>1},
"HM-OU-CFM-PL02" =>{Intense=>1}, "HM-OU-CFM-PL02" =>{Intense=>1},
"HM-SEC-WIN01" =>{setupDir =>1,pullForce =>1,pushForce =>1,tiltMax =>1, "HM-SEC-WIN01" =>{setupDir =>1,pullForce =>1,pushForce =>1,tiltMax =>1,
CtValLo =>1,CtValHi =>1, CtValLo =>1,CtValHi =>1,
@ -644,6 +638,12 @@ my %culHmRegChan = (# if channelspecific then enter them here
OnLevelKm =>1,OnRampOnSp =>1,OnRampOffSp =>1 OnLevelKm =>1,OnRampOnSp =>1,OnRampOffSp =>1
} }
); );
#clones - - - - - - - - - - - - - - -
$culHmRegChan{"HM-RC-19-B12"} = $culHmRegChan{"HM-RC-1912"};
$culHmRegChan{"HM-RC-19-SW12"} = $culHmRegChan{"HM-RC-1912"};
# RC send BCAST to specific address. Is the meaning understood? # RC send BCAST to specific address. Is the meaning understood?
my @culHmCmdFlags = ("WAKEUP", "WAKEMEUP", "CFG", "Bit3", my @culHmCmdFlags = ("WAKEUP", "WAKEMEUP", "CFG", "Bit3",
@ -675,25 +675,30 @@ my %culHmModelGets = (
); );
##############################---set---######################################## ##############################---set---########################################
my %culHmGlobalSetsDevice = ( my %culHmGlobalSets = (# all but virtuals
raw => "data ...",
reset => "",
pair => "",
unpair => "",
getSerial => "",
virtual =>"<noButtons>",
);
my %culHmGlobalSets = (
sign => "[on|off]",
regBulk => "<list>:<peer> <addr1:data1> <addr2:data2> ...", regBulk => "<list>:<peer> <addr1:data1> <addr2:data2> ...",
peerBulk => "<peer1,peer2,...>",
statusRequest => "", statusRequest => "",
getRegRaw =>"[List0|List1|List2|List3|List4|List5|List6] ... <PeerChannel>", getRegRaw =>"[List0|List1|List2|List3|List4|List5|List6] ... <PeerChannel>",
getConfig => "", getConfig => "",
regSet =>"<regName> <value> ... <peerChannel>", regSet =>"<regName> <value> ... <peerChannel>",
clear =>"[readings|msgEvents]", clear =>"[readings|msgEvents]",
); );
my %culHmSubTypeSets = ( my %culHmGlobalSetsVrtDev = (# virtuals and devices without subtype
raw => "data ...",
virtual =>"<noButtons>",
);
my %culHmGlobalSetsDevice = (# all devices but virtuals
raw => "data ...",
reset => "",
pair => "",
unpair => "",
getSerial => "",
);
my %culHmGlobalSetsChn = (# all channels but virtuals
sign => "[on|off]",
peerBulk => "<peer1,peer2,...>",
);
my %culHmSubTypeSets = (# channels of this subtype
switch =>{ "on-for-timer"=>"sec", "on-till"=>"time", switch =>{ "on-for-timer"=>"sec", "on-till"=>"time",
on=>"", off=>"", toggle=>"", on=>"", off=>"", toggle=>"",
press => "[long|short] [on|off] ..."}, press => "[long|short] [on|off] ..."},
@ -708,22 +713,12 @@ my %culHmSubTypeSets = (
up => "[<changeValue>] [ontime] [ramptime]...", up => "[<changeValue>] [ontime] [ramptime]...",
down => "[<changeValue>] [ontime] [ramptime]..." down => "[<changeValue>] [ontime] [ramptime]..."
}, },
remote =>{ devicepair => "... outdated, use peerChan", remote =>{ peerChan => "<btnNumber> device ... [single|dual] [set|unset] [actor|remote|both]",},
peerChan => "<btnNumber> device ... [single|dual] [set|unset] [actor|remote|both]",}, threeStateSensor =>{ peerChan => "<btnNumber> device ... single [set|unset] [actor|remote|both]",},
pushButton =>{ devicepair => "... outdated, use peerChan", virtual =>{ peerChan => "<btnNumber> device ... [single|dual] [set|unset] [actor|remote|both]",
peerChan => "<btnNumber> device ... [single|dual] [set|unset] [actor|remote|both]",},
threeStateSensor =>{ devicepair => "... outdated, use peerChan",
peerChan => "<btnNumber> device ... single [set|unset] [actor|remote|both]",},
motionDetector =>{ devicepair => "... outdated, use peerChan",
peerChan => "<btnNumber> device ... single [set|unset] [actor|remote|both]",},
virtual =>{ raw => "data ...",
devicepair => "... outdated, use peerChan",
peerChan => "<btnNumber> device ... [single|dual] [set|unset] [actor|remote|both]",
press => "[long|short]...", press => "[long|short]...",
valvePos => "position",#acting as TC valvePos => "position", },#acting as TC
virtual =>"<noButtons>",}, #redef necessary for virtual
smokeDetector =>{ test => "", alarmOn=>"", alarmOff=>"", smokeDetector =>{ test => "", alarmOn=>"", alarmOff=>"",
devicepair => "... outdated, use peerChan",
peerChan => "<btnNumber> device ... single [set|unset] actor",}, peerChan => "<btnNumber> device ... single [set|unset] actor",},
winMatic =>{ matic => "<btn>", winMatic =>{ matic => "<btn>",
keydef => "<btn> <txt1> <txt2>", keydef => "<btn> <txt1> <txt2>",
@ -733,55 +728,35 @@ my %culHmSubTypeSets = (
open =>"[sec] ...", open =>"[sec] ...",
inhibit =>"[on|off]"}, inhibit =>"[on|off]"},
); );
my %culHmModelSets = ( # clones- - - - - - - - - - - - - - - - -
"HM-CC-VD"=>{ $culHmSubTypeSets{pushButton} = $culHmSubTypeSets{remote};
valvePos => "position"}, $culHmSubTypeSets{motionDetector} = $culHmSubTypeSets{threeStateSensor};
"HM-RC-19"=> {
service => "<count>", my %culHmModelSets = (# channels of this subtype-------------
alarm => "<count>", "HM-CC-VD" =>{
display => "<text> [comma,no] [unit] [off|1|2|3] [off|on|slow|fast] <symbol>"}, valvePos => "position"},
"HM-RC-19-B"=> { "HM-RC-19" =>{
service => "<count>",
alarm => "<count>",
display => "<text> [comma,no] [unit] [off|1|2|3] [off|on|slow|fast] <symbol>"},
"HM-RC-19-SW"=> {
service => "<count>", service => "<count>",
alarm => "<count>", alarm => "<count>",
display => "<text> [comma,no] [unit] [off|1|2|3] [off|on|slow|fast] <symbol>"}, display => "<text> [comma,no] [unit] [off|1|2|3] [off|on|slow|fast] <symbol>"},
"HM-PB-4DIS-WM"=>{ "HM-PB-4DIS-WM"=>{
text => "<btn> [on|off] <txt1> <txt2>"}, text => "<btn> [on|off] <txt1> <txt2>"},
"HM-OU-LED16" =>{ "HM-OU-LED16" =>{
led =>"[off|red|green|orange]" , led =>"[off|red|green|orange]" ,
ilum =>"[0-15] [0-127]" }, ilum =>"[0-15] [0-127]" },
"HM-OU-CFM-PL"=>{ "HM-OU-CFM-PL" =>{
led => "<color>[,<color>..]", led => "<color>[,<color>..]",
playTone => "<MP3No>[,<MP3No>..]"}, playTone => "<MP3No>[,<MP3No>..]"},
"HM-Sys-sRP-Pl"=>{ "HM-Sys-sRP-Pl"=>{
setRepeat => "[no1..36] <sendName> <recName> [bdcast-yes|no]"}, setRepeat => "[no1..36] <sendName> <recName> [bdcast-yes|no]"},
); );
# clones- - - - - - - - - - - - - - - - -
$culHmModelSets{"HM-RC-19-B"} = $culHmModelSets{"HM-RC-19"};
$culHmModelSets{"HM-RC-19-SW"} = $culHmModelSets{"HM-RC-19"};
#%{$culHmModelSets{"HM-RC-19-SW"}} = %{$culHmModelSets{"HM-RC-19"}}; copy
my %culHmChanSets = ( my %culHmChanSets = (
"HM-CC-TC00"=>{ "HM-CC-TC02" =>{
devicepair => "... outdated, use peerChan",
peerChan => "<btnNumber> device ... single [set|unset] [actor|remote|both]",
"day-temp" => "[on,off,6.0..30.0]",
"night-temp" => "[on,off,6.0..30.0]",
"party-temp" => "[on,off,6.0..30.0]",
"desired-temp" => "[on,off,6.0..30.0]",
tempListSat => "HH:MM temp ...",
tempListSun => "HH:MM temp ...",
tempListMon => "HH:MM temp ...",
tempListTue => "HH:MM temp ...",
tempListThu => "HH:MM temp ...",
tempListWed => "HH:MM temp ...",
tempListFri => "HH:MM temp ...",
displayMode => "[temp-only|temp-hum]",
displayTemp => "[actual|setpoint]",
displayTempUnit => "[celsius|fahrenheit]",
controlMode => "[manual|auto|central|party]",
decalcDay => "day", },
"HM-CC-TC02"=>{
devicepair => "... outdated, use peerChan",
peerChan => "<btnNumber> device ... single [set|unset] [actor|remote|both]", peerChan => "<btnNumber> device ... single [set|unset] [actor|remote|both]",
"day-temp" => "[on,off,6.0..30.0]", "day-temp" => "[on,off,6.0..30.0]",
"night-temp" => "[on,off,6.0..30.0]", "night-temp" => "[on,off,6.0..30.0]",
@ -802,6 +777,8 @@ my %culHmChanSets = (
"HM-SEC-WIN01"=>{ stop =>"", "HM-SEC-WIN01"=>{ stop =>"",
level =>"<level> <relockDly> <speed>..."}, level =>"<level> <relockDly> <speed>..."},
); );
# clones- - - - - - - - - - - - - - - - -
$culHmChanSets{"HM-CC-TC00"} = $culHmChanSets{"HM-CC-TC02"};
##############################---messages---################################### ##############################---messages---###################################
my %culHmBits = ( my %culHmBits = (
@ -868,13 +845,13 @@ my %culHmBits = (
"02" => { txt => "Request AES", params => { #todo check data "02" => { txt => "Request AES", params => { #todo check data
DATA => "0," } }, DATA => "0," } },
"03" => { txt => "AES reply", params => { "03" => { txt => "AES reply", params => { # send 'old' AES key to actor
DATA => "0," } }, DATA => "0," } },
"04;p01=01" => { txt => "To-HMLan:send AES code", params => { # req HMLAN to send AES code "04;p01=01" => { txt => "To-HMLan:send AES code", params => { # FHEM req HMLAN to send AES key to aktor ??
CHANNEL => "00,2", CHANNEL => "00,2",
TYPE => "02,2" } }, TYPE => "02,2" } }, #00: old key? 01: new key?
"04" => { txt => "To-Actor:send AES code", params => { # HMLAN sends AES code "04" => { txt => "To-Actor:send AES key" , params => { # HMLAN sends AES key to actor ??
CODE => "00" } }, CODE => "00" } },
"10;p01=00" => { txt => "INFO_SERIAL", params => { "10;p01=00" => { txt => "INFO_SERIAL", params => {
@ -958,7 +935,9 @@ sub HMConfig_getHash($){
return %culHmSubTypeGets if($hn eq "culHmSubTypeGets" ); return %culHmSubTypeGets if($hn eq "culHmSubTypeGets" );
return %culHmModelGets if($hn eq "culHmModelGets" ); return %culHmModelGets if($hn eq "culHmModelGets" );
return %culHmGlobalSetsDevice if($hn eq "culHmGlobalSetsDevice"); return %culHmGlobalSetsDevice if($hn eq "culHmGlobalSetsDevice");
return %culHmGlobalSetsChn if($hn eq "culHmGlobalSetsChn" );
return %culHmGlobalSets if($hn eq "culHmGlobalSets" ); return %culHmGlobalSets if($hn eq "culHmGlobalSets" );
return %culHmGlobalSetsVrtDev if($hn eq "culHmGlobalSetsVrtDev");
return %culHmSubTypeSets if($hn eq "culHmSubTypeSets" ); return %culHmSubTypeSets if($hn eq "culHmSubTypeSets" );
return %culHmModelSets if($hn eq "culHmModelSets" ); return %culHmModelSets if($hn eq "culHmModelSets" );
return %culHmChanSets if($hn eq "culHmChanSets" ); return %culHmChanSets if($hn eq "culHmChanSets" );