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

10_ZWave.pm: flexible initialization after inclusion (Forum #37121)

git-svn-id: https://svn.fhem.de/fhem/trunk@8580 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rudolfkoenig 2015-05-14 19:09:57 +00:00
parent 8897bfe7fd
commit c3bf9f2da2
2 changed files with 92 additions and 45 deletions

View File

@ -85,8 +85,10 @@ use vars qw(%zw_type6);
'34' => 'RTC_TIMER_READ',
'35' => 'RTC_TIMER_DELETE',
'36' => 'RTC_TIMER_CALL',
'40' => 'ZW_SET_LEARN_NODE_STATE',
'41' => 'ZW_GET_NODE_PROTOCOL_INFO',
'42' => 'ZW_SET_DEFAULT',
'43' => 'ZW_NEW_CONTROLLER',
'44' => 'ZW_REPLICATION_COMMAND_COMPLETE',
'45' => 'ZW_REPLICATION_SEND_DATA',
'46' => 'ZW_ASSIGN_RETURN_ROUTE',
@ -772,7 +774,8 @@ ZWDongle_Ready($)
<ul>
<li>ZW_ADD_NODE_TO_NETWORK [learnReady|nodeFound|controller|done|failed]
</li>
<li>ZW_REMOVE_NODE_TO_NETWORK [learnReady|nodeFound|slave|controller|done|failed]
<li>ZW_REMOVE_NODE_FROM_NETWORK
[learnReady|nodeFound|slave|controller|done|failed]
</li>
<li>UNDEFINED ZWave_${type6}_$id ZWave $homeId $id $classes"
</li>

View File

@ -220,15 +220,15 @@ my %zwave_class = (
configLong => "04%02x04%08x" },
get => { config => "05%02x" },
parse => { "^..70..(..)(..)(.*)" => 'ZWave_configParse($hash,$1,$2,$3)'} },
ALARM => { id => '71',
get => { alarm => "04%02x" },
parse => { "..7105(..)(..)(.*)" => 'ZWave_alarmParse($1,$2,$3)'} },
MANUFACTURER_SPECIFIC => { id => '72',
get => { model => "04" },
parse => { "087205(....)(....)(....)" => 'ZWave_mfsParse($1,$2,$3,0)',
"087205(....)(....)(.{4})" => 'ZWave_mfsParse($1,$2,$3,1)',
"087205(....)(.{4})(.{4})" => '"modelId:$1-$2-$3"'} },
parse => { "087205(....)(....)(....)" =>'ZWave_mfsParse($hash,$1,$2,$3,0)',
"087205(....)(....)(.{4})" =>'ZWave_mfsParse($hash,$1,$2,$3,1)',
"087205(....)(.{4})(.{4})" =>'ZWave_mfsParse($hash,$1,$2,$3,2)'},
init => { ORDER=>49, CMD => '"get $NAME model"' } },
POWERLEVEL => { id => '73' },
PROTECTION => { id => '75',
set => { protectionOff => "0100",
@ -272,7 +272,8 @@ my %zwave_class = (
set => { associationAdd => "01%02x%02x*",
associationDel => "04%02x%02x*" },
get => { association => "02%02x", },
parse => { "..8503(..)(..)..(.*)" => '"assocGroup_$1:Max $2 Nodes $3"'} },
parse => { "..8503(..)(..)..(.*)" => '"assocGroup_$1:Max $2 Nodes $3"'},
init => { ORDER=> 1, CMD=> '"set $NAME associationAdd 1 $CTRLID"' } },
VERSION => { id => '86',
get => { version => "11",
versionClass => "13%02x" },
@ -341,10 +342,12 @@ my %zwave_cmdArgs = (
my %zwave_modelConfig;
my %zwave_modelIdAlias = ( "010f-0301-1001" => "Fibaro_FGRM222",
"013c-0001-0003" => "Philio_PAN04" );
"013c-0001-0003" => "Philio_PAN04",
"0115-0100-0102" => "ZME_KFOB" );
# Patching certain devices.
my %zwave_deviceSpecial = (
use vars qw(%zwave_deviceSpecial);
%zwave_deviceSpecial = (
Fibaro_FGRM222 => {
MANUFACTURER_PROPRIETARY => {
set => { positionSlat=>"010f26010100%02x",
@ -354,10 +357,13 @@ my %zwave_deviceSpecial = (
'sprintf("position:Blinds %d Slat %d",hex($1),hex($2))' } } },
Philio_PAN04 => {
METER => {
get => { meter => "01",
meterWatt => "0110", #Watt
meterVoltage=> "0120", #Voltage
meterAmpere => "0128" } } } #Ampere
get_ADD => { meterWatt => "0110", #Watt
meterVoltage=> "0120", #Voltage
meterAmpere => "0128" } } },#Ampere
ZME_KFOB => {
ZWAVEPLUS_INFO => {
# Example only. ORDER must be >= 50
init => { ORDER=>50, CMD => '"get $NAME zwavePlusInfo"' } } }
);
sub
@ -405,26 +411,53 @@ ZWave_Define($$)
$modules{ZWave}{defptr}{"$homeId $id"} = $hash;
AssignIoPort($hash); # FIXME: should take homeId into account
if(@a) {
if(@a) { # Autocreate: set the classes, execute the init calls
$hash->{lastMsgTimestamp} = time(); # device is awake.
ZWave_SetClasses($homeId, $id, undef, $a[0]);
if($attr{$name}{classes} =~ m/ASSOCIATION/) {
my $iodev = $hash->{IODev};
my $homeReading = ReadingsVal($iodev->{NAME}, "homeId", "") if($iodev);
my $ctrlId = $1 if($homeReading && $homeReading =~ m/CtrlNodeId:(..)/);
if($ctrlId) {
Log3 $name, 1, "Adding the controller $ctrlId to association group 1";
IOWrite($hash, "00", "130a04850101${ctrlId}05");
} else {
Log3 $name, 1, "Cannot associate $name, missing controller id";
}
}
ZWave_execInits($hash, 0);
}
return undef;
}
sub
ZWave_doExecInits($)
{
my ($cmdArr) = @_;
my $cmd = shift @{$cmdArr};
my $ret = AnalyzeCommand(undef, $cmd);
Log 1, "ZWAVE INIT: $cmd: $ret" if ($ret);
InternalTimer(gettimeofday()+0.5, "ZWave_doExecInits", $cmdArr, 0)
if(@{$cmdArr});
}
sub
ZWave_execInits($$)
{
my ($hash, $min) = @_; # min = 50 for model-specific stuff
my @clList = split(" ", $attr{$hash->{NAME}}{classes});
my (@initList, %seen);
foreach my $cl (@clList) {
next if($seen{$cl});
$seen{$cl} = 1;
my $ptr = ZWave_getHash($hash, $cl, "init");
push @initList, $ptr if($ptr && $ptr->{ORDER} >= $min);
}
my $NAME = $hash->{NAME};
my $iodev = $hash->{IODev};
my $homeReading = ReadingsVal($iodev->{NAME}, "homeId", "") if($iodev);
my $CTRLID = $1 if($homeReading && $homeReading =~ m/CtrlNodeId:(..)/);
my @cmd;
foreach my $i (sort { $a->{ORDER}<=>$b->{ORDER} } @initList) {
push @cmd, eval $i->{CMD};
}
InternalTimer(gettimeofday()+0.5, "ZWave_doExecInits", \@cmd, 0)
if(@cmd);
}
###################################
sub
ZWave_Cmd($$@)
@ -434,7 +467,6 @@ ZWave_Cmd($$@)
my $name = shift(@a);
my $cmd = shift(@a);
# Collect the commands from the distinct classes
my %cmdList;
my $classes = AttrVal($name, "classes", "");
@ -549,12 +581,9 @@ ZWave_Cmd($$@)
my $awake = ($baseHash->{lastMsgTimestamp} &&
time() - $baseHash->{lastMsgTimestamp} < 2);
if($awake && @{$baseHash->{WakeUp}} == 0) {
push @{$baseHash->{WakeUp}}, ""; # Block the next
} else {
if(!$awake) {
push @{$baseHash->{WakeUp}}, $data.$id;
return (AttrVal($name,"verbose",3) > 2 ?
return (AttrVal($name,"verbose",3) > 2 ?
"Scheduled for sending after WAKEUP" : undef);
}
@ -741,9 +770,16 @@ ZWave_mcCapability($$)
}
sub
ZWave_mfsParse($$$$)
ZWave_mfsParse($$$$$)
{
my ($mf, $prod, $id, $config) = @_;
my ($hash, $mf, $prod, $id, $config) = @_;
if($config == 2) {
setReadingsVal($hash, "modelId", "$mf-$prod-$id", TimeNow());
ZWave_execInits($hash, 50);
return "modelId:$mf-$prod-$id";
}
my $xml = $attr{global}{modpath}.
"/FHEM/lib/openzwave_manufacturer_specific.xml";
($mf, $prod, $id) = (lc($mf), lc($prod), lc($id)); # Just to make it sure
@ -759,7 +795,7 @@ ZWave_mfsParse($$$$)
if($l =~ m/<Product type="([^"]*)".*id="([^"]*)".*name="([^"]*)"/) {
if($mf eq $lastMf && $prod eq lc($1) && $id eq lc($2)) {
if($config) {
$ret = "modelConfig:$1" if($l =~ m/config="([^"]*)"/);
$ret = "modelConfig:".(($l =~ m/config="([^"]*)"/) ? $1:"unknown");
return $ret;
} else {
$ret = "model:$mName $3";
@ -1275,25 +1311,33 @@ sub
ZWave_getHash($$$)
{
my ($hash, $cl, $type) = @_;
my $ptr = $zwave_class{$cl}{$type}
my $ptr; # must be standalone, as there is a $ptr in the calling fn.
$ptr = $zwave_class{$cl}{$type}
if($zwave_class{$cl} && $zwave_class{$cl}{$type});
if($cl eq "CONFIGURATION" && $type ne "parse") {
my $mc = ZWave_configGetHash($hash);
if($mc) {
my $mcp = $mc->{$type};
my %nptr = ();
map({$nptr{$_} = $ptr->{$_}} keys %{$ptr});
map({$nptr{$_} = $mcp->{$_}} keys %{$mcp});
$ptr = \%nptr;
if($mcp) {
my %nptr = ();
map({$nptr{$_} = $ptr->{$_}} keys %{$ptr});
map({$nptr{$_} = $mcp->{$_}} keys %{$mcp});
$ptr = \%nptr;
}
}
}
my $modelId = ReadingsVal($hash->{NAME}, "modelId", "");
$modelId = $zwave_modelIdAlias{$modelId} if($zwave_modelIdAlias{$modelId});
my $p = $zwave_deviceSpecial{$modelId};
$ptr = $p->{$cl}{$type} if($p && $p->{$cl} && $p->{$cl}{$type});
if($p && $p->{$cl}) {
$ptr = $p->{$cl}{$type} if($p->{$cl}{$type});
my $add = $p->{$cl}{$type."_ADD"};
$ptr = {} if($add && !$ptr);
map { $ptr->{$_} = $add->{$_} } keys %{$add} if($add);
}
return $ptr;
}
@ -1320,7 +1364,7 @@ ZWave_Parse($$@)
Log3 $ioName, 2, "ERROR: cannot SEND_DATA: $arg" if($arg != 1);
return "";
}
Log3 $ioName, 4, "$ioName: unhandled ANSWER: $cmd $arg";
Log3 $ioName, 4, "$ioName unhandled ANSWER: $cmd $arg";
return "";
}
@ -1483,7 +1527,7 @@ ZWave_Parse($$@)
if($arg =~ m/^$k/) {
my $val = $ptr->{$k};
$val = eval $val if(index($val, '$') >= 0);
push @event, $val;
push @event, $val if(defined($val));
}
}
push @event, "UNPARSED:$className $arg" if(!@event);