mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-10 09:16:53 +00:00
10_ZWave.pm: Qubino fixes (Forum #103243)
git-svn-id: https://svn.fhem.de/fhem/trunk@20052 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
98b5ef3e48
commit
0bfcba3778
@ -364,7 +364,8 @@ my %zwave_class = (
|
||||
ZWAVEPLUS_INFO => { id => '5e',
|
||||
get => { zwavePlusInfo=>"01"},
|
||||
parse => { "095e02(..)(..)(..)(....)(....)"
|
||||
=> 'ZWave_plusInfoParse($1,$2,$3,$4,$5)'} },
|
||||
=> 'ZWave_plusInfoParse($1,$2,$3,$4,$5)'},
|
||||
init => { ORDER=>49, CMD => '"get $NAME zwavePlusInfo"' } },
|
||||
ZIP_GATEWAY => { id => '5f' },
|
||||
MULTI_CHANNEL => { id => '60', # Version 2, aka MULTI_INSTANCE
|
||||
set => { mcCreateAll => 'ZWave_mcCreateAll($hash,"")' },
|
||||
@ -445,7 +446,7 @@ my %zwave_class = (
|
||||
=> 'ZWave_mfsParse($hash,$1,$2,$3,1)',
|
||||
"0[8a]7205(....)(.{4})(.{4})(.*)"
|
||||
=> 'ZWave_mfsParse($hash,$1,$2,$3,2)' },
|
||||
init => { ORDER=>49, CMD => '"get $NAME model"' } },
|
||||
init => { ORDER=> 1, CMD => '"get $NAME model"' } },
|
||||
POWERLEVEL => { id => '73',
|
||||
set => { powerlevel => "01%02x%02x",
|
||||
powerlevelTest => "04%02x%02x%04x" },
|
||||
@ -542,7 +543,7 @@ my %zwave_class = (
|
||||
'%d.%02d App %d.%d HW %d FWCounter %d FW %d.%d",'.
|
||||
'unpack("C*",pack("H*","$1")))',
|
||||
"048614(..)(..)" => '"versionClass_".hex($1).":".hex($2)' },
|
||||
init => { ORDER=> 1, CMD => '"get $NAME versionClassAll"' } },
|
||||
init => { ORDER=> 2, CMD => '"get $NAME versionClassAll"' } },
|
||||
INDICATOR => { id => '87',
|
||||
set => { indicatorOff => "0100",
|
||||
indicatorOn => "01FF",
|
||||
@ -691,12 +692,11 @@ our %zwave_deviceSpecial;
|
||||
alarmAmbulanceOn=>"05000000000a030000",
|
||||
alarmPoliceOn =>"05000000000a010000",
|
||||
alarmDoorchimeOn=>"050000000006160000",
|
||||
alarmBeepOn =>"05000000000a050000" } } },
|
||||
|
||||
ZME_KFOB => {
|
||||
ZWAVEPLUS_INFO => {
|
||||
# Example only. ORDER must be >= 50
|
||||
init => { ORDER=>50, CMD => '"get $NAME zwavePlusInfo"' } } }
|
||||
alarmBeepOn =>"05000000000a050000" } } }
|
||||
# ZME_KFOB => {
|
||||
# ZWAVEPLUS_INFO => {
|
||||
# # Example only. ORDER must be >= 50
|
||||
# init => { ORDER=>50, CMD => '"get $NAME zwavePlusInfo"' } } }
|
||||
);
|
||||
|
||||
my $zwave_cryptRijndael = 0;
|
||||
@ -915,10 +915,33 @@ ZWave_execInits($$;$)
|
||||
my $homeReading = ReadingsVal($iodev->{NAME}, "homeId", "") if($iodev);
|
||||
my $CTRLID=hex($1) if($homeReading && $homeReading =~ m/CtrlNodeIdHex:(..)/);
|
||||
|
||||
# ZWavePlus devices with MCA need mcaAdd instead of associationAdd
|
||||
my $cls = AttrVal($NAME, "classes", "");
|
||||
my $isMc = ($cls =~ m/ZWAVEPLUS_INFO/ && $cls =~ m/MULTI_CHANNEL_ASSOCIATION/);
|
||||
|
||||
my @cmd;
|
||||
my $nih = $hash->{nodeIdHex};
|
||||
foreach my $i (sort { $a->{ORDER}<=>$b->{ORDER} } @initList) {
|
||||
my $version = $hash->{".vclasses"}{$i->{CC}};
|
||||
push @cmd, eval $i->{CMD} if(!defined($version) || $version > 0);
|
||||
if($isMc && $i->{CMD} =~ m/associationAdd 1/) {
|
||||
$hash->{p1} = eval $i->{CMD}; # cannot access local variables
|
||||
$hash->{p2} = eval '"set $NAME mcaAdd 1 0 $CTRLID 0"';
|
||||
next;
|
||||
}
|
||||
push @cmd, eval $i->{CMD}
|
||||
if(!defined($version) || $version > 0);
|
||||
}
|
||||
|
||||
if($isMc) {
|
||||
# Cannot access the stack here, only $hash (?)
|
||||
$zwave_parseHook{"$nih:versionClassAll"} = sub(){
|
||||
my $mcaVers = $hash->{".vclasses"}{MULTI_CHANNEL_ASSOCIATION};
|
||||
return if(!$mcaVers); # called too early
|
||||
AnalyzeCommand(undef, $hash->{$mcaVers < 3 ? "p1" : "p2"});
|
||||
delete($zwave_parseHook{"$hash->{nodeIdHex}:versionClassAll"});
|
||||
delete($hash->{p1});
|
||||
delete($hash->{p2});
|
||||
};
|
||||
}
|
||||
|
||||
push @cmd, ZWave_initFromModelfile($hash->{NAME}, $CTRLID, $cfg)
|
||||
@ -1729,9 +1752,12 @@ ZWave_assocGroupCmdList($$)
|
||||
}
|
||||
|
||||
my %zwm_unit = (
|
||||
energy=> ["kWh", "kVAh", "W", "pulseCount", "V", "A", "PowerFactor"],
|
||||
gas => ["m3", "feet3", "undef", "pulseCount"],
|
||||
water => ["m3", "feet3", "USgallons", "pulseCount"]
|
||||
energy => ["kWh", "kVAh", "W", "pulseCount", "V", "A", "PowerFactor", "undef",
|
||||
"kVar", "kVarh"],
|
||||
gas => ["m3", "feet3", "undef", "pulseCount"],
|
||||
water => ["m3", "feet3", "USgallons", "pulseCount"],
|
||||
heating => ["kWh" ],
|
||||
cooling => ["kWh" ]
|
||||
);
|
||||
|
||||
sub
|
||||
@ -1750,7 +1776,7 @@ ZWave_meterParse($$)
|
||||
"undef" : $rate_type_text[$rate_type]);
|
||||
|
||||
my $meter_type = ($v1 & 0x1f);
|
||||
my @meter_type_text =("undef", "energy", "gas", "water", "undef");
|
||||
my @meter_type_text =("undef", "energy", "gas", "water", "heating", "cooling");
|
||||
my $meter_type_text = ($meter_type > $#meter_type_text ?
|
||||
"undef" : $meter_type_text[$meter_type]);
|
||||
|
||||
@ -1759,6 +1785,7 @@ ZWave_meterParse($$)
|
||||
my $size = $v2 & 0x7; # 3 bits
|
||||
|
||||
$scale |= (($v1 & 0x80) >> 5);
|
||||
$scale = 8+hex(substr($v3, -2)) if($scale == 7); # V4
|
||||
|
||||
my $unit_text = ($meter_type_text eq "undef" ?
|
||||
"undef" : $zwm_unit{$meter_type_text}[$scale]);
|
||||
@ -1772,14 +1799,14 @@ ZWave_meterParse($$)
|
||||
$v3 = substr($v3, 2*$size, length($v3)-(2*$size));
|
||||
|
||||
if (length($v3) < 4) { # V1 report
|
||||
return "$meter_type_text: $mv $unit_text";
|
||||
return "$meter_type_text:$mv $unit_text";
|
||||
|
||||
} else { # V2 or greater report
|
||||
my $delta_time = hex(substr($v3, 0, 4));
|
||||
$v3 = substr($v3, 4, length($v3)-4);
|
||||
|
||||
if ($delta_time == 0) { # no previous meter value
|
||||
return "$meter_type_text: $mv $unit_text";
|
||||
return "$meter_type_text:$mv $unit_text";
|
||||
|
||||
} else { # previous meter value present
|
||||
my $pmv = hex(substr($v3, 0, 2*$size));
|
||||
@ -1791,7 +1818,7 @@ ZWave_meterParse($$)
|
||||
} else {
|
||||
$delta_time .= " s";
|
||||
};
|
||||
return "$meter_type_text: $mv $unit_text previous: $pmv delta_time: ".
|
||||
return "$meter_type_text:$mv $unit_text previous: $pmv delta_time: ".
|
||||
"$delta_time"; # V2 report
|
||||
}
|
||||
}
|
||||
@ -1806,19 +1833,18 @@ ZWave_meterGet($)
|
||||
return("", "01");
|
||||
};
|
||||
|
||||
if (($scale < 0) || ($scale > 6)) {
|
||||
return("argument must be one of: 0 to 6","");
|
||||
} else {
|
||||
$scale = $scale << 3;
|
||||
return("",sprintf('01%02x', $scale));
|
||||
};
|
||||
if($scale < 7) {
|
||||
return ("",sprintf('01%02x', $scale << 3));
|
||||
} else { # Version 4
|
||||
return ("",sprintf('01%02x%02x', 7<<3, $scale-8));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#V2: 1b7:reset 1b65:resrvd, 1b4-0:type, 2b7-4:resrvd, 2b3-0:scale
|
||||
#V3: 1b7:reset 1b65:resrvd, 1b4-0:type, 2b:scale
|
||||
#V4: 1b7:reset 1b65:rate, 1b4-0:type, 2b7:mst, 2b6-0:scale1, 3b:#scaleBytes,...
|
||||
# No V4 support...
|
||||
# some V4 support...
|
||||
sub
|
||||
ZWave_meterSupportedParse($$)
|
||||
{
|
||||
@ -1830,6 +1856,10 @@ ZWave_meterSupportedParse($$)
|
||||
|
||||
my $meter_reset = $v1 & 0x80;
|
||||
my $meter_reset_text = $meter_reset ? "yes" : "no";
|
||||
my $meter_rate_type = ($v1 & 0x60) >> 5;
|
||||
my @meter_rate_text = ("", ", import only (consumed)",
|
||||
", export only (produced)", ", both import and export");
|
||||
my $meter_rate_text = $meter_rate_text[$meter_rate_type];
|
||||
|
||||
my $meter_type = ($v1 & 0x1f);
|
||||
my @meter_type_text =("undef", "energy", "gas", "water", "undef");
|
||||
@ -1837,17 +1867,18 @@ ZWave_meterSupportedParse($$)
|
||||
"undef" : $meter_type_text[$meter_type]);
|
||||
|
||||
my $scale = $v2 & 0x7f;
|
||||
my $unit_text="";
|
||||
|
||||
for (my $i=0; $i <= 6; $i++) {
|
||||
if ($scale & 2**$i) {
|
||||
$unit_text .= ", " if (length($unit_text)>0);
|
||||
$unit_text .= $i.":".$zwm_unit{$meter_type_text}[$i];
|
||||
};
|
||||
};
|
||||
|
||||
return "meterSupported: type: $meter_type_text scales: $unit_text resetable:".
|
||||
" $meter_reset_text";
|
||||
my $l = 6;
|
||||
if($v2 & 0x80 && $val =~ m/^....(..)(..)/) {
|
||||
$l += 8;
|
||||
$scale = hex($2)*256+$scale;
|
||||
}
|
||||
my @unit_text;
|
||||
for (my $i=0; $i <= $l; $i++) {
|
||||
last if(@{$zwm_unit{$meter_type_text}} <= $i);
|
||||
push (@unit_text, "$i:".$zwm_unit{$meter_type_text}[$i]) if($scale & 2**$i);
|
||||
}
|
||||
return "meterSupported:type:$meter_type_text$meter_rate_text,".
|
||||
" resetable:$meter_reset_text, scales: ".join(" ", @unit_text);
|
||||
}
|
||||
|
||||
|
||||
@ -1890,6 +1921,11 @@ ZWave_versionClassAllGet($@)
|
||||
$hash->{".vclasses"}{$zwave_id2class{lc($1)}} = hex($2);
|
||||
$attr{$name}{vclasses} = join(" ", sort keys %h);
|
||||
}
|
||||
|
||||
if($zwave_parseHook{"$hash->{nodeIdHex}:versionClassAll"}) { # Used by init
|
||||
$zwave_parseHook{"$hash->{nodeIdHex}:versionClassAll"}->();
|
||||
}
|
||||
|
||||
return !$hash->{asyncGet}; # "veto" for parseHook/getAll
|
||||
}
|
||||
|
||||
@ -5409,11 +5445,12 @@ sub
|
||||
ZWave_firmware($$)
|
||||
{
|
||||
my ($hash, $args) = @_;
|
||||
if($args)
|
||||
{
|
||||
return("Firmware update in progress. Please try update again later", "EMPTY") if(defined $hash->{FW_UPDATE_DATA});
|
||||
if($args) {
|
||||
return("Firmware update in progress. Please try update again later", "EMPTY")
|
||||
if(defined $hash->{FW_UPDATE_DATA});
|
||||
my $classVersion = $hash->{".vclasses"}{FIRMWARE_UPDATE_MD};
|
||||
return("Firmware update with FIRMWARE_UPDATE_MD classversion > 4 not supported", "EMPTY") if($classVersion > 4);
|
||||
return("Firmware update with FIRMWARE_UPDATE_MD classversion > 4 ".
|
||||
"not supported", "EMPTY") if($classVersion > 4);
|
||||
my ($target, $fwFile) = split / /, $args;
|
||||
my $usage = "wrong argumets, need: <FwTarget> <FwFileName>";
|
||||
return ($usage, "EMPTY") if (!$target || !$fwFile);
|
||||
@ -5424,15 +5461,13 @@ ZWave_firmware($$)
|
||||
open(IN, $fName) || return "Cant open $fName: $!";
|
||||
binmode(IN);
|
||||
my $buf;
|
||||
while (1)
|
||||
{
|
||||
my $part = $l - length($buf);
|
||||
my $success = read(IN, $buf, 100, length($buf));
|
||||
if( not defined $success)
|
||||
{
|
||||
return "Cant read $l bytes from $fName";
|
||||
}
|
||||
last if not $success;
|
||||
while (1) {
|
||||
my $part = $l - length($buf);
|
||||
my $success = read(IN, $buf, 100, length($buf));
|
||||
if( not defined $success) {
|
||||
return "Cant read $l bytes from $fName";
|
||||
}
|
||||
last if not $success;
|
||||
}
|
||||
close(IN);
|
||||
my $strbuff = unpack('H*',$buf);
|
||||
@ -5444,19 +5479,18 @@ ZWave_firmware($$)
|
||||
$hash->{FW_UPDATE_DATA}->{CL} = $hash->{CL};
|
||||
$hash->{FW_UPDATE_DATA}->{STAGE} = "INTERVIEW";
|
||||
|
||||
Log3 $hash, 3, "ZWave_firmware: Target: $target FILE: $fName LENGTH: $l CRC $FwNewChkSum Version $classVersion";
|
||||
return("Firmware Update Version $classVersion does not support targets != 0", "EMPTY") if (int($target) != 0 && $classVersion < 3);
|
||||
Log3 $hash, 3, "ZWave_firmware: Target: $target FILE: $fName ".
|
||||
"LENGTH: $l CRC $FwNewChkSum Version $classVersion";
|
||||
return("Firmware Update Version $classVersion does not support targets != 0",
|
||||
"EMPTY") if (int($target) != 0 && $classVersion < 3);
|
||||
}
|
||||
|
||||
|
||||
ZWave_firmwareSendCmd($hash, "01"); #send FIRMWARE_MD_GET
|
||||
if(defined $hash->{FW_UPDATE_DATA})
|
||||
{
|
||||
if(defined $hash->{FW_UPDATE_DATA}) {
|
||||
$zwave_parseHook{"$hash->{nodeIdHex}:..7a.*"} = \&ZWave_firmwareUpdateParse;
|
||||
return(ZWave_WibMsg($hash).", performing firmware update", "EMPTY");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return(ZWave_WibMsg($hash).", fetching firmware meta data", "EMPTY");
|
||||
}
|
||||
}
|
||||
@ -7088,7 +7122,7 @@ ZWave_firmwareUpdateParse($$$)
|
||||
<li>modelConfig:configLocation</li>
|
||||
|
||||
<br><br><b>Class METER</b>
|
||||
<li>energy:val [kWh|kVAh|pulseCount|powerFactor]</li>
|
||||
<li>energy:val [kWh|kVAh|pulseCount|powerFactor|kVar|kVarh]</li>
|
||||
<li>gas:val [m3|feet3|pulseCount]</li>
|
||||
<li>water:val [m3|feet3|USgallons|pulseCount]</li>
|
||||
<li>power:val W</li>
|
||||
|
Loading…
x
Reference in New Issue
Block a user