2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-16 10:46:03 +00:00

HMLAN improvement for TC, someregister for CFM

git-svn-id: https://svn.fhem.de/fhem/trunk@3063 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
martinp876 2013-04-11 19:02:49 +00:00
parent 5b6e38d217
commit a35aacff94
3 changed files with 70 additions and 46 deletions

View File

@ -256,7 +256,7 @@ sub HMLAN_Parse($$) {##########################################################
my $p = substr($mFld[5],18); # additional content
my $rssi = hex($mFld[4])-65536;
Log $ll5, 'HMLAN_Parse: '.$name.' R:'.$mFld[0]
Log $ll5, "HMLAN_Parse: $name R:".$mFld[0]
.(($mFld[0] =~ m/^E/)?' ':'')
.' stat:' .$mFld[1]
.' t:' .$mFld[2]
@ -289,20 +289,23 @@ sub HMLAN_Parse($$) {##########################################################
# HMLAN_SimpleWrite($hash, '+'.$src);
# }
if($stat & 0x040A){ # do not parse this message, no valid content
Log $ll5, 'HMLAN_Parse: problems detected - please restart HMLAN'if($stat & 0x0400);
Log $ll5, 'HMLAN_Parse: discard' if($stat & 0x000A);
Log $ll5, "HMLAN_Parse: $name problems detected - please restart HMLAN"if($stat & 0x0400);
Log $ll5, "HMLAN_Parse: $name discard" if($stat & 0x000A);
return ;# message with no ack is send - do not dispatch
}
if ($mFld[1] !~ m/00(01|02|21|41)/ && $letter eq 'R'){
Log $ll5, 'HMLAN_Parse: discard, NACK';
Log $ll5, "HMLAN_Parse: $name discard, NACK state:".$mFld[1];
return;
}
Log $ll5, 'HMLAN_Parse: special reply '.$mFld[1] if($stat & 0x0200);
Log $ll5, "HMLAN_Parse: $name special reply ".$mFld[1] if($stat & 0x0200);
# HMLAN sends ACK for flag 'A0' but not for 'A4'(config mode)-
# we ack ourself an long as logic is uncertain
if (hex($flg) == 0xA4 && $hash->{owner} eq $dst){
Log $ll5, "HMLAN: ACK config";
# we ack ourself an long as logic is uncertain - also possible is 'A6' for RHS
if (hex($flg)&0x2){
$hash->{helper}{$src}{nextSend} = gettimeofday() + 0.130;
}
if (hex($flg)&0xA4 == 0xA4 && $hash->{owner} eq $dst){
Log $ll5, "HMLAN_Parse: $name ACK config";
HMLAN_Write($hash,undef, "As15".$mNo."8002".$dst.$src."00");
}
#update some User information ------
@ -312,7 +315,6 @@ sub HMLAN_Parse($$) {##########################################################
$hash->{"${name}_MSGCNT"}++;
$hash->{"${name}_TIME"} = TimeNow();
if (($hash->{helper}{$src}{flg}) && ($letter eq 'R')){ #HMLAN is done?
$hash->{helper}{$src}{flg} = 0; #release send-holdoff
HMLAN_SimpleWrite($hash, $hash->{helper}{$src}{msg}) #send delayed msg if any
@ -334,6 +336,7 @@ sub HMLAN_Parse($$) {##########################################################
$hash->{uptime} = HMLAN_uptime($mFld[5]);
$hash->{assignIDsReport}=$mFld[6];
$hash->{helper}{keepAliveRec} = 1;
$hash->{helper}{keepAliveRpt} = 0;
Log $ll5, 'HMLAN_Parse: '.$name. ' V:'.$mFld[1]
.' sNo:'.$mFld[2].' d:'.$mFld[3]
.' O:' .$mFld[4].' m:'.$mFld[5].' IDcnt:'.$mFld[6];
@ -361,8 +364,18 @@ sub HMLAN_SimpleWrite(@) {#####################################################
my $name = $hash->{NAME};
my $ll5 = GetLogLevel($name,5);
my $len = length($msg);
# It is not possible to answer befor 100ms
if ($len>51){
my $dst = substr($msg,46,6);
if ($dst && $hash->{helper}{$dst}{nextSend}){
my $DevDelay=0;
$DevDelay = $hash->{helper}{$dst}{nextSend} - gettimeofday();
$DevDelay = ($DevDelay > 0.01)?( $DevDelay -= int($DevDelay)):0;
delete $hash->{helper}{$dst}{nextSend};
select(undef, undef, undef, $DevDelay)if ($DevDelay>0.01);
}
$msg =~ m/(.{9}).(..).(.{8}).(..).(.{8}).(..)(....)(.{6})(.{6})(.*)/;
Log $ll5, 'HMLAN_Send: '.$name.' S:'.$1
.' stat: ' .$2
@ -375,7 +388,7 @@ sub HMLAN_SimpleWrite(@) {#####################################################
.' ' .$9
.' ' .$10;
if ($len > 52){#channel informatiion included
my ($flg,$dst,$chn) = (substr($msg,36,2),substr($msg,46,6),substr($msg,52,2));
my ($flg,$chn) = (substr($msg,36,2),substr($msg,52,2));
if ( $hash->{helper}{$dst}{flg}){ #send not ack by HMLAN
if($hash->{helper}{$dst}{to} > gettimeofday()){#will not wait forever!
$hash->{helper}{$dst}{msg} = $msg; #postpone message
@ -423,6 +436,8 @@ sub HMLAN_DoInit($) {##########################################################
foreach (keys %lhash){delete ($lhash{$_})};# clear IDs - HMLAN might have a reset
$hash->{helper}{keepAliveRec} = 1; # ok for first time
$hash->{helper}{keepAliveRpt} = 0; # ok for first time
RemoveInternalTimer( "keepAliveCk:".$name);# avoid duplicate timer
RemoveInternalTimer( "keepAlive:".$name);# avoid duplicate timer
InternalTimer(gettimeofday()+25, "HMLAN_KeepAlive", "keepAlive:".$name, 0);
return undef;
@ -437,16 +452,26 @@ sub HMLAN_KeepAlive($) {#######################################################
HMLAN_SimpleWrite($hash, "K");
RemoveInternalTimer( "keepAlive:".$name);# avoid duplicate timer
my $rt = AttrVal($name,"respTime",1);
InternalTimer(gettimeofday()+$rt, "HMLAN_KeepAliveCheck", "keepAliveCk:".$name, 1);
InternalTimer(gettimeofday()+$rt,"HMLAN_KeepAliveCheck","keepAliveCk:".$name,1);
InternalTimer(gettimeofday()+25, "HMLAN_KeepAlive", "keepAlive:".$name, 1);
}
sub HMLAN_KeepAliveCheck($) {##################################################
my($in ) = shift;
my(undef,$name) = split(':',$in);
my $hash = $defs{$name};
if ($hash->{helper}{keepAliveRec} != 1){
DevIo_Disconnected($hash);
if ($hash->{helper}{keepAliveRec} != 1){# no answer
if ($hash->{helper}{keepAliveRpt} >2){# give up here
DevIo_Disconnected($hash);
}
else{
$hash->{helper}{keepAliveRpt}++;
HMLAN_KeepAlive("keepAlive:".$name);#repeat
}
}
else{
$hash->{helper}{keepAliveRpt}=0;
}
}
sub HMLAN_secSince2000() {#####################################################
# Calculate the local time in seconds from 2000.

View File

@ -2497,6 +2497,7 @@ sub CUL_HM_Set($@) {
readingsSingleUpdate($hash,"state",$state,1) if($state);
$rxType = CUL_HM_getRxType($devHash);
Log GetLogLevel($name,2), "CUL_HM set $name " .
join(" ", @a[1..$#a])." rxt:".$rxType;
@ -2617,7 +2618,6 @@ sub CUL_HM_Pair(@) {
sub CUL_HM_getConfig($$$$$){
my ($hash,$chnhash,$id,$dst,$chn) = @_;
my $flag = CUL_HM_getFlag($hash);
foreach my $readEntry (keys %{$chnhash->{READINGS}}){
delete $chnhash->{READINGS}{$readEntry} if ($readEntry =~ m/^[\.]?RegL_/);
}
@ -3394,7 +3394,7 @@ sub CUL_HM_fltCvT($) { # float -> config time
last if ($inValue < $fltCvT{$div});
$exp++;
}
return ($exp << 5)+int($inValue/$div2);
return ($exp << 5)+int($inValue/$div2+.1);
}
sub CUL_HM_CvTflt($) { # config time -> float
my ($inValue) = @_;

View File

@ -187,6 +187,7 @@ my %culHmModel=(
);
##----------definitions for register settings-----------------
# definition of Register for all devices
# a: address, incl bits 13.4 4th bit in reg 13
@ -211,7 +212,7 @@ my %culHmRegDefShLg = (# register that are available for short AND long button p
MaxTimeF =>{a=> 29.0,s=>1.0,l=>3,min=>0 ,max=>25.4 ,c=>'factor' ,f=>10 ,u=>'s' ,d=>0,t=>"max time first direction"},
DriveMode =>{a=> 31.0,s=>1.0,l=>3,min=>0 ,max=>3 ,c=>'lit' ,f=>'' ,u=>'' ,d=>0,t=>"" ,lit=>{direct=>0,viaUpperEnd=>1,viaLowerEnd=>2,viaNextEnd=>3}},
#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, 111600 = infinite"},
OffDly =>{a=> 8.0,s=>1.0,l=>3,min=>0 ,max=>111600 ,c=>'fltCvT' ,f=>'' ,u=>'s' ,d=>0,t=>"off delay"},
OffTime =>{a=> 9.0,s=>1.0,l=>3,min=>0 ,max=>111600 ,c=>'fltCvT' ,f=>'' ,u=>'s' ,d=>0,t=>"off time, 111600 = infinite"},
@ -242,6 +243,8 @@ my %culHmRegDefShLg = (# register that are available for short AND long button p
DimElsOnTimeMd =>{a=> 38.7,s=>0.1,l=>3,min=>0 ,max=>1 ,c=>'lit' ,f=>'' ,u=>'' ,d=>0,t=>"" ,lit=>{absolut=>0,minimal=>1}},
DimElsActionType=>{a=> 38.0,s=>0.4,l=>3,min=>0 ,max=>8 ,c=>'lit' ,f=>'' ,u=>'' ,d=>0,t=>"" ,lit=>{off=>0,jmpToTarget=>1,toggleToCnt=>2,toggleToCntInv=>3,upDim=>4,downDim=>5,toggelDim=>6,toggelDimToCnt=>7,toggelDimToCntInv=>8}},
#output Unit
ActTypeMp3 =>{a=> 36 ,s=>1 ,l=>3,min=>0 ,max=>255 ,c=>'' ,f=>'' ,u=>'' ,d=>0,t=>"Tone or MP3 to be palyed"},
ActTypeLed =>{a=> 36 ,s=>1 ,l=>3,min=>0 ,max=>255 ,c=>'lit' ,f=>'' ,u=>'' ,d=>0,t=>"LED color" ,lit=>{no=>0x00,red_short=>0x11,red_long=>0x12,green_short=>0x21,green_long=>0x22,orange_short=>0x31,orange_long=>0x32}},
ActType =>{a=> 36 ,s=>1 ,l=>3,min=>0 ,max=>255 ,c=>'' ,f=>'' ,u=>'' ,d=>0,t=>"Action type(LED or Tone)"},
ActNum =>{a=> 37 ,s=>1 ,l=>3,min=>1 ,max=>255 ,c=>'' ,f=>'' ,u=>'' ,d=>0,t=>"Action Number"},
Intense =>{a=> 43 ,s=>1 ,l=>3,min=>10 ,max=>255 ,c=>'lit' ,f=>'' ,u=>'' ,d=>0,t=>"Volume",lit=>{vol_0=>255,vol_1=>250,vol_2=>246,vol_3=>240,vol_4=>234,vol_5=>227,vol_6=>218,vol_7=>207,vol_8=>190,vol_9=>162,vol_00=>10}},
@ -667,21 +670,20 @@ $culHmRegModel{"HM-WDS40-TH-I"} = $culHmRegModel{"HM-WDS10-TH-O"};
$culHmRegModel{"Schueco_263-157"} = $culHmRegModel{"HM-WDS10-TH-O"};
$culHmRegModel{"IS-WDS-TH-OD-S-R3"} = $culHmRegModel{"HM-WDS10-TH-O"};
my %culHmRegChan = (# if channelspecific then enter them here
"HM-CC-TC02" =>{displayMode =>1,displayTemp =>1,displayTempUnit=>1,
controlMode =>1,decalcDay =>1,
"day-temp" =>1,"night-temp" =>1,"party-temp" =>1,
mdTempValve =>1,partyEndDay =>1,
partyEndMin =>1,partyEndHr =>1,
decalHr =>1,decalMin =>1,
"HM-CC-TC02" =>{displayMode =>1,displayTemp =>1,displayTempUnit =>1,
controlMode =>1,decalcDay =>1,
"day-temp" =>1,"night-temp" =>1,"party-temp" =>1,
mdTempValve =>1,partyEndDay =>1,
partyEndMin =>1,partyEndHr =>1,
decalHr =>1,decalMin =>1,
},
"HM-CC-TC03" =>{tempWinOpen =>1, }, #window channel
"HM-RC-1912" =>{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-CC-TC03" =>{tempWinOpen =>1, }, #window channel
"HM-RC-1912" =>{msgShowTime =>1, beepAtAlarm =>1, beepAtService =>1,beepAtInfo =>1,
backlAtAlarm =>1, backlAtService =>1, backlAtInfo =>1,
lcdSymb =>1, lcdLvlInterp =>1},
"HM-OU-CFM-PL01" =>{ActTypeLed =>1},
"HM-OU-CFM-PL02" =>{ActTypeMp3 =>1,Intense =>1},
"HM-SEC-WIN01" =>{setupDir =>1,pullForce =>1,pushForce =>1,tiltMax =>1,
CtValLo =>1,CtValHi =>1,
CtOn =>1,CtOff =>1,CtRampOn =>1,CtRampOff =>1,
@ -694,21 +696,6 @@ my %culHmRegChan = (# if channelspecific then enter them here
$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?
my @culHmCmdFlags = ("WAKEUP", "WAKEMEUP", "CFG", "Bit3",
"BURST", "BIDI", "RPTED", "RPTEN");
#RPTEN 0x80: set in every message. Meaning?
#RPTED 0x40: repeated (repeater operation)
#BIDI 0x20: response is expected
#Burst 0x10: set if burst is required by device
#Bit3 0x08:
#CFG 0x04: Device in Config mode
#WAKEMEUP 0x02: awake - hurry up to send messages
#WAKEUP 0x01: send initially to keep the device awake
##--------------- Conversion routines for register settings
##############################---get---########################################
@ -730,9 +717,9 @@ my %culHmModelGets = (
my %culHmGlobalSets = (# all but virtuals
regBulk => "<list>:<peer> <addr1:data1> <addr2:data2> ...",
statusRequest => "",
getRegRaw =>"[List0|List1|List2|List3|List4|List5|List6] ... <PeerChannel>",
getRegRaw =>"[List0|List1|List2|List3|List4|List5|List6] ... [<PeerChannel>]",
getConfig => "",
regSet =>"<regName> <value> ... <peerChannel>",
regSet =>"<regName> <value> ... [<peerChannel>]",
clear =>"[readings|msgEvents]",
);
my %culHmGlobalSetsVrtDev = (# virtuals and devices without subtype
@ -833,6 +820,18 @@ my %culHmChanSets = (
# clones- - - - - - - - - - - - - - - - -
$culHmChanSets{"HM-CC-TC00"} = $culHmChanSets{"HM-CC-TC02"};
# RC send BCAST to specific address. Is the meaning understood?
my @culHmCmdFlags = ("WAKEUP", "WAKEMEUP", "CFG", "Bit3",
"BURST", "BIDI", "RPTED", "RPTEN");
#RPTEN 0x80: set in every message. Meaning?
#RPTED 0x40: repeated (repeater operation)
#BIDI 0x20: response is expected
#Burst 0x10: set if burst is required by device
#Bit3 0x08:
#CFG 0x04: Device in Config mode
#WAKEMEUP 0x02: awake - hurry up to send messages
#WAKEUP 0x01: send initially to keep the device awake
##############################---messages---###################################
my %culHmBits = (
"00" => { txt => "DEVICE_INFO", params => {