2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-01-31 18:59:33 +00:00

Switched to the readingsUpdate functions

git-svn-id: https://svn.fhem.de/fhem/trunk@2407 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
rudolfkoenig 2013-01-03 12:55:22 +00:00
parent b128ebbc5a
commit 0d91d55c6b
7 changed files with 390 additions and 297 deletions

View File

@ -12,9 +12,9 @@ sub EnOcean_Set($@);
sub EnOcean_MD15Cmd($$$);
my %EnO_rorgname = ("F6"=>"switch", # RPS
"D5"=>"contact", # 1BS
"A5"=>"sensor", # 4BS
);
"D5"=>"contact", # 1BS
"A5"=>"sensor", # 4BS
);
my @EnO_ptm200btn = ("AI", "A0", "BI", "B0", "CI", "C0", "DI", "D0");
my %EnO_ptm200btn;
@ -57,8 +57,8 @@ my %EnO_subType = (
2 => "contact",
3 => "sensor",
4 => "windowHandle",
5 => "dimmer",
6 => "dimmCtrl",
5 => "eltakoDimmer",
6 => "eltakoShutter",
7 => "FAH",
8 => "FBH",
9 => "FTF",
@ -90,7 +90,8 @@ EnOcean_Initialize($)
"showtime:1,0 loglevel:0,1,2,3,4,5,6 ".
"model:".join(",",@EnO_models)." ".
"subType:".join(",",values %EnO_subType)." ".
"actualTemp";
"subDef actualTemp dimTime shutTime ".
$readingFnAttributes;
for(my $i=0; $i<@EnO_ptm200btn;$i++) {
$EnO_ptm200btn{$EnO_ptm200btn[$i]} = "$i:30";
@ -107,7 +108,7 @@ EnOcean_Define($$)
my @a = split("[ \t][ \t]*", $def);
my $name = $hash->{NAME};
return "wrong syntax: define <name> EnOcean 8-digit-hex-code"
if(int(@a)!=3 || $a[2] !~ m/^[A-F0-9]{8}$/i);
if(int(@a)!=3 || $a[2] !~ m/^[A-F0-9]{8}$/i);
$modules{EnOcean}{defptr}{uc($a[2])} = $hash;
AssignIoPort($hash);
@ -124,6 +125,7 @@ EnOcean_Set($@)
my ($hash, @a) = @_;
return "no set value specified" if(@a < 2);
my $updateState = 1;
my $name = $hash->{NAME};
my $st = AttrVal($name, "subType", "");
my $ll2 = GetLogLevel($name, 2);
@ -163,37 +165,135 @@ EnOcean_Set($@)
$hash->{READINGS}{$cmd}{TIME} = $tn;
$hash->{READINGS}{$cmd}{VAL} = $arg;
} elsif($st eq "dimmCtrl") { # Tested for Eltako-Dimmer
###########################
} elsif($st eq "eltakoDimmer") {
my $sendDimCmd=0;
my $dimTime=AttrVal($name, "dimTime", 0);
my $onoff=1;
my $subDef = AttrVal($name, "subDef", "");
my $dimVal=$hash->{READINGS}{dimValue}{VAL};
if($cmd eq "teach") {
my $data=sprintf("A502000000%s00", $hash->{DEF});
Log $ll2, "dimmCtrl.Teach: " . $data;
IOWrite($hash, "000A0001", $data); # len:000a optlen:00 pakettype:1(radio)
} elsif($cmd eq "dimm") {
return "Usage: dimm percent [time 01-FF FF:slowest] [on/off]" if(@a<2);
my $time=0;
my $onoff=1;
# for eltako relative (0-100) (but not compliant to EEP because DB0.2 is 0)
my $dimVal=$a[1];
shift(@a);
if(defined($a[1])) { $time=$a[1]; shift(@a); }
if(defined($a[1])) { $onoff=($a[1] eq "off") ? 0 : 1; shift(@a); }
# EEP: A5/38/08 Central Command ->Typ 0x02: Dimming
my $data=sprintf("A502%02X%02X%02X%s00", $dimVal, $time, $onoff|0x08, $hash->{DEF});
my $data=sprintf("A502000000%s00", $subDef);
Log $ll2, $st . ".Teach: " . $data;
# len:000a optlen:00 pakettype:1(radio)
IOWrite($hash, "000A0001", $data);
Log $ll2, "dimmCtrl.dimm: " . $data;
} else {
return "Unknown argument $cmd, choose one of: teach, dimm:slider,0,1,100"
} elsif($cmd eq "dim") {
return "Usage: $cmd percent [dimspeed 1-100]" if(@a<2 or $a[1]>100);
# for eltako relative (0-100) (but not compliant to EEP because DB0.2
# is 0)
$dimVal=$a[1];
shift(@a);
if(defined($a[1])) {
$dimTime=sprintf("%x",(($a[1]*2.55)-255)*-1);
shift(@a);
}
$sendDimCmd=1;
} elsif($cmd eq "dimup") {
return "Usage: $cmd percent [dimspeed 1-100]" if(@a<2 or $a[1]>100);
$dimVal+=$a[1];
Log $ll2, "$st.$cmd val:" . $hash->{VALUE} .
" par:" . $a[1] . " val:" . $dimVal;
shift(@a);
if(defined($a[1])) {
$dimTime=$a[1];
shift(@a);
}
$sendDimCmd=1;
} elsif($cmd eq "dimdown") {
return "Usage: $cmd percent [dimspeed 1-100]" if(@a<2 or $a[1]>100);
$dimVal-=$a[1];
shift(@a);
if(defined($a[1])) { $dimTime=$a[1]; shift(@a); }
$sendDimCmd=1;
} elsif($cmd eq "on" || $cmd eq "B0") {
$dimTime=1;
$sendDimCmd=1;
$dimVal=100;
} elsif($cmd eq "off" || $cmd eq "BI") {
$dimTime=1;
$onoff=0;
$sendDimCmd=1;
} else {
return "Unknown argument $cmd, choose one of dim:slider,0,1,100 ".
"dimup:slider,0,1,100 dimdown:slider,0,1,100 on off teach"
}
if($sendDimCmd) {
$updateState = 0;
$a[0]="on";
if($dimVal > 100) { $dimVal=100; }
if($dimVal <= 0) { $dimVal=0; $onoff=0; $a[0]="off" }
ReadingsVal($name, "dimValue", $dimVal);
my $data=sprintf("A502%02X%02X%02X%s00",
$dimVal, $dimTime, $onoff|0x08, $subDef);
IOWrite($hash, "000A0001", $data);
Log $ll2, $st." ".$cmd.": ".$data.$subDef;
}
###########################
} elsif($st eq "eltakoShutter") {
my $shutTime=AttrVal($name, "shutTime", 0);
my $subDef = AttrVal($name, "subDef", "");
my $shutCmd = 0x00;
if($cmd eq "teach") {
my $data=sprintf("A5FFF80D80%s00", $subDef);
Log $ll2, $st . ".Teach: " . $data;
# len:000a optlen:00 pakettype:1(radio)
IOWrite($hash, "000A0001", $data);
} elsif($cmd eq "stop") {
$shutCmd = 0x00;
} elsif($cmd eq "up" || $cmd eq "B0") {
my $position = 100;
if($a[1]) {
$shutTime = $shutTime/100*$a[1];
$position = $hash->{READINGS}{position}{VAL}+$a[1];
if($position > 100) { $position = 100; };
}
$hash->{READINGS}{position}{TIME} = $tn;
$hash->{READINGS}{position}{VAL} = $position;
$shutCmd = 0x01;
} elsif($cmd eq "down" || $cmd eq "BI") {
my $position = 0;
if($a[1]) {
$shutTime = $shutTime/100*$a[1];
$position = $hash->{READINGS}{position}{VAL}-$a[1];
if($position <= 0) { $position = 0; };
}
$hash->{READINGS}{position}{TIME} = $tn;
$hash->{READINGS}{position}{VAL} = $position;
$shutCmd = 0x02;
} else {
return "Unknown argument " . $cmd . ", choose one of up down stop teach"
}
shift(@a);
if($shutCmd) {
$updateState = 0;
# EEP: A5/3F/7F Universal ???
my $data = sprintf("A5%02X%02X%02X%02X%s00",
0x00, $shutTime, $shutCmd, 0x08, $subDef);
IOWrite($hash, "000A0001", $data);
Log $ll2, $st . ".$cmd" . $data;
}
###########################
} else { # Simulate a PTM
my ($c1,$c2) = split(",", $cmd, 2);
return "Unknown argument $cmd, choose one of " .
join(" ", sort keys %EnO_ptm200btn)
if(!defined($EnO_ptm200btn{$c1}) || ($c2 && !defined($EnO_ptm200btn{$c2})));
join(" ", sort keys %EnO_ptm200btn)
if(!defined($EnO_ptm200btn{$c1}) ||
($c2 && !defined($EnO_ptm200btn{$c2})));
Log $ll2, "EnOcean: set $name $cmd";
my ($db_3, $status) = split(":", $EnO_ptm200btn{$c1}, 2);
@ -204,22 +304,21 @@ EnOcean_Set($@)
$db_3 |= ($d2<<1) | 0x01;
}
IOWrite($hash, "",
sprintf("6B05%02X000000%s%s", $db_3, $hash->{DEF}, $status));
sprintf("6B05%02X000000%s%s", $db_3, $hash->{DEF}, $status));
}
select(undef, undef, undef, 0.2); # Tested by joerg. He prefers 0.3 :)
}
my $cmd = join(" ", @a);
$hash->{CHANGED}[0] = $cmd;
$hash->{STATE} = $cmd;
$hash->{READINGS}{state}{TIME} = $tn;
$hash->{READINGS}{state}{VAL} = $cmd;
return undef;
if($updateState == 1) {
readingsSingleUpdate($hash, "state", join(" ", @a), 1);
return undef;
}
}
#############################
# "EnOcean:F6:50000000:0011C8D4:FF" -> EnO_switch on (BI)
sub
EnOcean_Parse($$)
{
@ -430,31 +529,18 @@ EnOcean_Parse($$)
# Eltako FTF55
# (EEP: 07-02-05)
####################################
# $db_1 is the temperature where 0x00 = 40°C and 0xFF 0°C
# $db_1 is the temperature where 0x00 = 40?C and 0xFF 0?C
my $temp = sprintf "%3d", $db_1;
$temp = sprintf "%0.1f", ( 40 - $temp * 40 / 255 ) ;
push @event, "3:temperature:$temp";
push @event, "3:state:$temp";
} elsif($st eq "dimmer") {
} elsif($st eq "eltakoDimmer") {
# todo: create a more general solution for the central-command responses
# response command from (Eltako-)Actor ( Central-Command:A5/38/08 )
if($db_3 eq 0x01) { # switch
push @event, "3:state:" . (($db_0 & 0x01) ? "on": "off");
push @event, "3:time:" . ($db_2<<8 + $db_1);
push @event, "3:timeType:" . (($db_0 & 0x02) ? "delay": "duration");
} elsif($db_3 eq 0x02) { # dimm
push @event, "3:state:" . (($db_0 & 0x01) ? "on": "off");
push @event, "3:dimmValue:$db_2";
} elsif($db_3 eq 0x03) { # setpoint-switch, todo
} elsif($db_3 eq 0x04) { # basic setpoint, todo
} elsif($db_3 eq 0x05) { # control-variable, todo
} elsif($db_3 eq 0x06) { # fan-stage, todo
if($db_3 eq 0x02) { # dimm
push @event, "3:state:" . ($db_0 & 0x01 ? "on" : "off");
push @event, "3:dimValue:" . $db_2;
}
} else {
push @event, "3:state:$db_3";
push @event, "3:sensor1:$db_3";
@ -469,31 +555,13 @@ EnOcean_Parse($$)
}
# Flag & 1: reading
# Flag & 2: changed
my $tn = TimeNow();
my @changed;
readingsBeginUpdate($hash);
for(my $i = 0; $i < int(@event); $i++) {
# Flag & 1: reading, Flag & 2: changed. Currently ignored.
my ($flag, $vn, $vv) = split(":", $event[$i], 3);
if($flag & 2) {
if($vn eq "state") {
$hash->{STATE} = $vv;
push @changed, $vv;
} else {
push @changed, "$vn: $vv";
}
}
if($flag & 1) {
$hash->{READINGS}{$vn}{TIME} = TimeNow();
$hash->{READINGS}{$vn}{VAL} = $vv;
}
readingsBulkUpdate($hash, $vn, $vv);
}
$hash->{CHANGED} = \@changed;
readingsEndUpdate($hash, 1);
return $name;
}
@ -583,12 +651,33 @@ EnOcean_A5Cmd($$$)
Do not regulate the MD15.</li>
</ul></li>
<li>subType dimmCtrl, tested with ElTako Dimmer only
<li>subType eltakoDimmer, tested with Eltako devices only
<ul>
<li>teach<br>
initiate teach-in mode
<li>dimm percent [time 01-FF FF:slowest] [on/off]<br>
issue dim command.
initiate teach-in mode</li>
<li>dimm percent [time 1-100]<br>
issue dim command.</li>
<li>dimmup percent [time 1-100]<br>
issue dim command.</li>
<li>dimmdown percent [time 1-100]<br>
issue dim command.</li>
<li>dimm on<br>
issue switch on command.</li>
<li>dimm off<br>
issue switch off command.</li>
</ul>
</li>
<li>subType eltakoShutter, tested with Eltako devices only
<ul>
<li>teach<br>
initiate teach-in mode</li>
<li>up [percent]<br>
issue roll up command.</li>
<li>down [percent]<br>
issue roll down command.</li>
<li>stop<br>
issue stop command.</li>
</ul>
</li>
@ -638,6 +727,7 @@ EnOcean_A5Cmd($$$)
<li><a href="#showtime">showtime</a></li>
<li><a href="#model">model</a></li>
<li><a href="#subType">subType</a></li>
<li><a href="#readingFnAttributes">readingFnAttributes</a></li>
<li><a name="actualTemp">actualTemp</a><br>
The value of the actual temperature, used when controlling MD15 devices.
Should by filled via a notify from a distinct temperature sensor. If
@ -652,103 +742,126 @@ EnOcean_A5Cmd($$$)
<li>switch. Switches (remotes) with more than one (pair) of buttons
are separate devices with separate address.
<ul>
<li>A0
<li>AI
<li>B0
<li>BI
<li>C0
<li>CI
<li>D0
<li>DI
<li>A0,BI
<li>A0</li>
<li>AI</li>
<li>B0</li>
<li>BI</li>
<li>C0</li>
<li>CI</li>
<li>D0</li>
<li>DI</li>
<li>A0,BI</li>
<li>&lt;BtnX,BtnY&gt; where BtnX and BtnY is one of the above, e.g.
A0,BI or D0,CI
<li>buttons:released
<li>buttons:<BtnX> released<br>
</ul>
A0,BI or D0,CI</li>
<li>buttons:released</li>
<li>buttons:<BtnX> released</li>
<br>
</ul></li>
<li>FSB61/FSM61 (set model to FSB61 or FSM61 manually)<br>
<ul>
<ul>di
<li>released<br>
The status of the device my become "released", this is not the case
for a normal switch.
</ul>
The status of the device may become "released", this is not the case
for a normal switch.</li>
</ul></li>
<li>windowHandle (HOPPE SecuSignal). Set the subType attr to windowHandle.
<ul>
<li>closed
<li>open
<li>tilted
<li>open from tilted
</ul>
<li>closed</li>
<li>open</li>
<li>tilted</li>
<li>open from tilted</li>
</ul></li>
<li>keycard. Set the subType attr to keycard. (untested)
<ul>
<li>keycard inserted
<li>keycard removed
</ul>
<li>keycard inserted</li>
<li>keycard removed</li>
</ul></li>
<li>STM-250 Door and window contact.
<ul>
<li>closed
<li>open
<li>learnBtn: on
</ul>
<li>closed</li>
<li>open</li>
<li>learnBtn: on</li>
</ul></li>
<li>SR04* (Temp sensor + Presence button and desired temp dial).<br>
Set the
model attribute to one of SR04 SR04P SR04PT SR04PST SR04PMS or the
subType attribute to SR04.
<ul>
<li>temperature: XY.Z
<li>set_point: [0..255]
<li>fan: [0|1|2|3|Auto]
<li>present: yes
<li>learnBtn: on
<li>T: XY.Z SP: [0..255] F: [0|1|2|3|Auto] P: [yes|no]
</ul>
<li>temperature: XY.Z</li>
<li>set_point: [0..255]</li>
<li>fan: [0|1|2|3|Auto]</li>
<li>present: yes</li>
<li>learnBtn: on</li>
<li>T: XY.Z SP: [0..255] F: [0|1|2|3|Auto] P: [yes|no]</li>
</ul></li>
<li>MD15-FtL-HE (Heating/Valve-regulator)<br>
The subType attibute must be MD15. This is done if the device was created by
autocreate.<br>
<ul>
<li>$actuator %
<li>currentValue: $actuator
<li>serviceOn: [yes|no]
<li>energyInput: [enabled|disabled]
<li>energyStorage: [charged|empty]
<li>battery: [ok|empty]
<li>cover: [open|closed]
<li>tempSensor: [failed|ok]
<li>window: [open|closed]
<li>actuator: [ok|obstructed]
<li>temperature: $tmp
</ul>
<li>$actuator %</li>
<li>currentValue: $actuator</li>
<li>serviceOn: [yes|no]</li>
<li>energyInput: [enabled|disabled]</li>
<li>energyStorage: [charged|empty]</li>
<li>battery: [ok|empty]</li>
<li>cover: [open|closed]</li>
<li>tempSensor: [failed|ok]</li>
<li>window: [open|closed]</li>
<li>actuator: [ok|obstructed]</li>
<li>temperature: $tmp</li>
</ul></li>
<li>Ratio Presence Sensor Eagle PM101.<br>
Set the model attribute to PM101<br>
<ul>
<li>brightness: $lux
<li>channel1: [on|off]
<li>channel2: [on|off]
</ul>
<li>brightness: $lux</li>
<li>channel1: [on|off]</li>
<li>channel2: [on|off]</li>
</ul></li>
<li>FAH60,FAH63,FIH63 brigthness senor.<br>
Set subType to FAH or model to FAH60/FAH63/FIH63 manually.<br>
<ul>
<li>brightness: $lux
<li>state: $lux
</ul>
<li>brightness: $lux</li>
<li>state: $lux</li>
</ul></li>
<li>FABH63,FBH55,FBH63,FIBH63 Motion/brightness sensor.<br>
Set subType to FBH or model to FABH63/FBH55/FBH63/FIBH63 manually.<br>
<ul>
<li>brightness: $lux
<li>motion:[yes|no]
<li>state: [motion: yes|no]
</ul>
<li>brightness: $lux</li>
<li>motion:[yes|no]</li>
<li>state: [motion: yes|no]</li>
</ul></li>
<li>FTF55 Temperature sensor.<br>
Set subType to FTF or model to FTF55 manually.<br>
<ul>
<li>temperature: $temp
<li>state: $temp
</ul>
<li>temperature: $temp</li>
<li>state: $temp</li>
</ul></li>
<li>eltakoDimmer<br>
<ul>
</ul></li>
<li>eltakoShutter<br>
<ul>
<li>B0<br>
The status of the device will become B0 after the TOP endpoint is
reached, or it has finished an "up %%" command.</li>
<li>BI<br>
The status of the device will become BI if the BOTTOM endpoint is
reached</li>
<li>released<br>
The status of the device may become "released", this is not the case
for a normal switch.</li>
</ul></li>
</ul>
</ul>

View File

@ -127,9 +127,8 @@ FS20_Initialize($)
$hash->{UndefFn} = "FS20_Undef";
$hash->{ParseFn} = "FS20_Parse";
$hash->{AttrList} = "IODev follow-on-for-timer:1,0 follow-on-timer ".
"do_not_notify:1,0 ".
"ignore:1,0 dummy:1,0 showtime:1,0 ".
"loglevel:0,1,2,3,4,5,6 " .
"do_not_notify:1,0 ignore:1,0 dummy:1,0 showtime:1,0 ".
"loglevel:0,1,2,3,4,5,6 $readingFnAttributes " .
"model:".join(",", sort keys %models);
}
@ -262,17 +261,9 @@ FS20_Set($@)
# Look for all devices with the same code, and set state, timestamp
my $code = "$hash->{XMIT} $hash->{BTN}";
my $tn = TimeNow();
my $defptr = $modules{FS20}{defptr};
foreach my $n (keys %{ $defptr->{$code} }) {
my $lh = $defptr->{$code}{$n};
$lh->{CHANGED}[0] = $v;
$lh->{STATE} = $v;
$lh->{READINGS}{state}{TIME} = $tn;
$lh->{READINGS}{state}{VAL} = $v;
my $lhname = $lh->{NAME};
if($name ne $lhname) {
DoTrigger($lhname, undef)
}
my $defptr = $modules{FS20}{defptr}{$code};
foreach my $n (keys %{ $defptr }) {
readingsSingleUpdate($defptr->{$n}, "state", $v, 1);
}
return $ret;
}
@ -397,10 +388,7 @@ FS20_Parse($$)
return "" if(IsIgnored($n)); # Little strange.
$lh->{CHANGED}[0] = $v;
$lh->{STATE} = $v;
$lh->{READINGS}{state}{TIME} = TimeNow();
$lh->{READINGS}{state}{VAL} = $v;
readingsSingleUpdate($lh, "state", $v, 1);
Log GetLogLevel($n,2), "FS20 $n $v";
if($modules{FS20}{ldata}{$n}) {
@ -570,13 +558,12 @@ four2hex($$)
<li>If the timer is set (i.e. it is not 0) then on, dim*,
and *-for-timer will take it into account (at least by the FS20ST).
</li>
<li>The <code>time</code> argument ranges from 0.25sec to 4 hours and
16 minutes.
As the time is encoded in one byte there are only 112 distinct
values, the resolution gets coarse with larger values. The program
will report the used timeout if the specified one cannot be set
exactly. The resolution is 0.25 sec from 0 to 4 sec, 0.5 sec from 4
to 8 sec, 1 sec from 8 to 16 sec and so on. If you need better
<li>The <code>time</code> argument ranges from 0.25sec to 4 hours and 16
minutes. As the time is encoded in one byte there are only 112
distinct values, the resolution gets coarse with larger values. The
program will report the used timeout if the specified one cannot be
set exactly. The resolution is 0.25 sec from 0 to 4 sec, 0.5 sec
from 4 to 8 sec, 1 sec from 8 to 16 sec and so on. If you need better
precision for large values, use <a href="#at">at</a> which has a 1
sec resolution.</li>
<li>on-till requires an absolute time in the "at" format (HH:MM:SS, HH:MM
@ -619,7 +606,6 @@ four2hex($$)
</code></ul>
</li><br>
<li><a href="#do_not_notify">do_not_notify</a></li><br>
<a name="attrdummy"></a>
<li>dummy<br>
Set the device attribute dummy to define devices which should not
@ -645,10 +631,6 @@ four2hex($$)
</li><br>
<li><a href="#loglevel">loglevel</a></li><br>
<li><a href="#showtime">showtime</a></li><br>
<a name="model"></a>
<li>model<br>
The model attribute denotes the model type of the device.
@ -687,6 +669,11 @@ four2hex($$)
"ignored=1" special devspec.
</li><br>
<li><a href="#do_not_notify">do_not_notify</a></li>
<li><a href="#loglevel">loglevel</a></li>
<li><a href="#showtime">showtime</a></li>
<li><a href="#readingFnAttributes">readingFnAttributes</a></li>
</ul>
<br>
@ -694,13 +681,13 @@ four2hex($$)
<b>Generated events:</b>
<ul>
From an FS20 device you can receive one of the following events.
<li>on
<li>off
<li>toggle
<li>dimdown
<li>dimup
<li>dimupdown
<li>on-for-timer
<li>on</li>
<li>off</li>
<li>toggle</li>
<li>dimdown</li>
<li>dimup</li>
<li>dimupdown</li>
<li>on-for-timer</li>
Which event is sent is device dependent and can sometimes configured on
the device.
</ul>

View File

@ -148,7 +148,7 @@ my %zwave_class = (
);
sub
sub
ZWave_Initialize($)
{
my ($hash) = @_;
@ -160,14 +160,14 @@ ZWave_Initialize($)
$hash->{ParseFn} = "ZWave_Parse";
$hash->{AttrList} = "IODev do_not_notify:1,0 ".
"ignore:1,0 dummy:1,0 showtime:1,0 classes ".
"loglevel:0,1,2,3,4,5,6 " .
"loglevel:0,1,2,3,4,5,6 $readingFnAttributes " .
"model:".join(",", sort @zwave_models);
map { $zwave_id2class{$zwave_class{$_}{id}} = $_ } keys %zwave_class;
}
#############################
sub
sub
ZWave_Define($$)
{
my ($hash, $def) = @_;
@ -292,16 +292,14 @@ ZWave_Cmd($$@)
my $tn = TimeNow();
if($type eq "set") {
$hash->{CHANGED}[0] = $cmd;
$hash->{STATE} = $cmd;
$hash->{READINGS}{state}{TIME} = $tn;
$hash->{READINGS}{state}{VAL} = $cmd;
readingsSingleUpdate($hash, "state", $cmd, 1);
} else {
my $mval = $val;
($cmd, $mval) = split(":", $val) if($val);
$hash->{READINGS}{$cmd}{TIME} = $tn;
$hash->{READINGS}{$cmd}{VAL} = $mval;
if($cmd && $mval) {
readingsSingleUpdate($hash, $cmd, $mval, 1);
}
}
return $val;
@ -353,6 +351,8 @@ ZWave_SetClasses($$$$)
return "";
}
###################################
# 0004000a03250300 (sensor binary off for id 11)
sub
ZWave_Parse($$@)
{
@ -440,26 +440,15 @@ ZWave_Parse($$@)
}
my @changed;
my $tn = TimeNow();
readingsBeginUpdate($hash);
for(my $i = 0; $i < int(@event); $i++) {
next if($event[$i] eq "");
my ($vn, $vv) = split(":", $event[$i], 2);
if($vn eq "state") {
if($hash->{STATE} ne $vv) {
$hash->{STATE} = $vv;
push @changed, $vv;
}
push @changed, "reportedState:$vv";
} else {
push @changed, "$vn: $vv";
}
$hash->{READINGS}{$vn}{TIME} = $tn;
$hash->{READINGS}{$vn}{VAL} = $vv;
readingsBulkUpdate($hash, $vn, $vv);
readingsBulkUpdate($hash, "reportedState", $vv)
if($vn eq "state"); # different from set
}
$hash->{CHANGED} = \@changed;
readingsEndUpdate($hash, 1);
return $hash->{NAME};
}
@ -523,40 +512,42 @@ ZWave_Undef($$)
<br><b>Class BASIC</b>
<li>basicValue value<br>
Send value (0-255) to this device. The interpretation is device dependent,
e.g. for a SWITCH_BINARY device 0 is off and anything else is on.
e.g. for a SWITCH_BINARY device 0 is off and anything else is on.</li>
<br><br><b>Class SWITCH_BINARY</b>
<li>on<br>
switch the device on
switch the device on</li>
<li>off<br>
switch the device off
switch the device off</li>
<li>reportOn,reportOff<br>
activate/deactivate the reporting of device state changes to the association group.
activate/deactivate the reporting of device state changes to the
association group.</li>
<br><br><b>Class CONFIGURATION</b>
<li>configByte cfgAddress 8bitValue<br>
configWord cfgAddress 16bitValue<br>
configLong cfgAddress 32bitValue<br>
Send a configuration value for the parameter cfgAddress. cfgAddress and
value is node specific.
value is node specific.</li>
<li>configDefault cfgAddress<br>
Reset the configuration parameter for the cfgAddress parameter to its default value.
See the device documentation to determine this value.
Reset the configuration parameter for the cfgAddress parameter to its
default value. See the device documentation to determine this value.</li>
<br><br><b>Class WAKE_UP</b>
<li>wakeupInterval value<br>
Set the wakeup interval of battery operated devices to the given value in
seconds. Upon wakeup the device sends a wakeup notification.
seconds. Upon wakeup the device sends a wakeup notification.</li>
<br><br><b>Class ASSOCIATION</b>
<li>associationAdd groupId nodeId ...<br>
Add the specified list of nodeIds to the assotion group groupId.<br>
Note: upon creating a fhem-device for the first time fhem will automatically
add the controller to the first association group of the node corresponding
to the fhem device, i.e it issues a "set name associationAdd 1 controllerNodeId"
Add the specified list of nodeIds to the assotion group groupId.<br> Note:
upon creating a fhem-device for the first time fhem will automatically add
the controller to the first association group of the node corresponding to
the fhem device, i.e it issues a "set name associationAdd 1
controllerNodeId"</li>
<li>associationDel groupId nodeId ...<br>
Remove the specified list of nodeIds from the assotion group groupId.
Remove the specified list of nodeIds from the assotion group groupId.</li>
</ul>
<br>
@ -569,42 +560,51 @@ ZWave_Undef($$)
<li>basicStatus<br>
return the status of the node as basicReport:XY. The value (XY) depends on
the node, e.g a SWITCH_BINARY device report 00 for off and FF (255) for on.
</li>
<br><br><b>Class SWITCH_BINARY</b>
<li>swbStatus<br>
return the status of the node, as state:on or state:off.
</li>
<br><br><b>Class SENSOR_BINARY</b>
<li>sbStatus<br>
return the status of the node, as state:open or state:closed.
</li>
<br><br><b>Class CONFIGURATION</b>
<li>config cfgAddress<br>
return the value of the configuration parameter cfgAddress. The value is
device specific.
</li>
<br><br><b>Class ALARM</b>
<li>alarm alarmId<br>
return the value for alarmId. The value is device specific.
</li>
<br><br><b>Class BATTERY</b>
<li>battery<br>
return the charge of the battery in %, as battery:value %
</li>
<br><br><b>Class WAKE_UP</b>
<li>wakeupInterval<br>
return the wakeup interval in seconds, in the form<br>
wakeupReport:interval:seconds target:id
</li>
<br><br><b>Class ASSOCIATION</b>
<li>association groupId<br>
return the list of nodeIds in the association group groupId in the form:<br>
assocGroup_X:Max:Y Nodes:id,id...
</li>
<br><br><b>Class VERSION</b>
<li>version<br>
return the version information of this node in the form:<br>
Lib:A Prot:x.y App:a.b
</li>
</ul>
<br>
@ -619,6 +619,7 @@ ZWave_Undef($$)
<li><a href="#showtime">showtime</a></li>
<li><a href="#loglevel">loglevel</a></li>
<li><a href="#model">model</a></li>
<li><a href="#readingFnAttributes">readingFnAttributes</a></li>
<li><a href="#classes">classes</a>
This attribute is needed by the ZWave module, as the list of the possible
set/get commands depends on it. It contains a space separated list of
@ -632,39 +633,39 @@ ZWave_Undef($$)
<ul>
<br><b>Class BASIC</b>
<li>basicReport:XY
<li>basicReport:XY</li>
<br><br><b>Class SWITCH_BINARY</b>
<li>state:on
<li>state:off
<li>state:on</li>
<li>state:off</li>
<br><br><b>Class SENSOR_BINARY</b>
<li>state:open
<li>state:closed
<li>state:open</li>
<li>state:closed</li>
<br><br><b>Class METER</b>
<li>power:val [kWh|kVAh|W|pulseCount]
<li>gas:val [m3|feet3|pulseCount]
<li>water:val [m3|feet3|USgallons|pulseCount]
<li>power:val [kWh|kVAh|W|pulseCount]</li>
<li>gas:val [m3|feet3|pulseCount]</li>
<li>water:val [m3|feet3|USgallons|pulseCount]</li>
<br><br><b>Class CONFIGURATION</b>
<li>config_X:Y
<li>config_X:Y</li>
<br><br><b>Class ALARM</b>
<li>alarm_type_X:level Y
<li>alarm_type_X:level Y</li>
<br><br><b>Class BATTERY</b>
<li>battery:chargelevel %
<li>battery:chargelevel %</li>
<br><br><b>Class WAKE_UP</b>
<li>wakeup:notification
<li>wakeupReport:interval:X target:Y
<li>wakeup:notification</li>
<li>wakeupReport:interval:X target:Y</li>
<br><br><b>Class ASSOCIATION</b>
<li>assocGroup_X:Max:Y Nodes:A,B,...
<li>assocGroup_X:Max:Y Nodes:A,B,...</li>
<br><br><b>Class VERSION</b>
<li>Lib:A Prot:x.y App:a.b
<li>Lib:A Prot:x.y App:a.b</li>
</ul>
</ul>

View File

@ -38,7 +38,7 @@ HMS_Initialize($)
$hash->{DefFn} = "HMS_Define";
$hash->{UndefFn} = "HMS_Undef";
$hash->{ParseFn} = "HMS_Parse";
$hash->{AttrList} = "IODev do_not_notify:0,1 showtime:0,1 model:hms100-t,hms100-tf,hms100-wd,hms100-mg,hms100-tfk,rm100-2,hms100-co,hms100-fit loglevel:0,1,2,3,4,5,6 ignore:0,1";
$hash->{AttrList} = "IODev do_not_notify:0,1 showtime:0,1 model:hms100-t,hms100-tf,hms100-wd,hms100-mg,hms100-tfk,rm100-2,hms100-co,hms100-fit loglevel:0,1,2,3,4,5,6 ignore:0,1 $readingFnAttributes";
}
#####################################
@ -215,21 +215,17 @@ HMS_Parse($$)
}
my $now = TimeNow();
Log GetLogLevel($name,4), "HMS Device $dev ($type: $val)";
readingsBeginUpdate($def);
my $max = int(@txt);
for( my $i = 0; $i < $max; $i++) {
$def->{READINGS}{$txt[$i]}{TIME} = $now;
$def->{READINGS}{$txt[$i]}{VAL} = $v[$i];
$def->{CHANGED}[$i] = "$txt[$i]: $v[$i]";
readingsBulkUpdate($def, $txt[$i], $v[$i]);
}
$def->{READINGS}{type}{TIME} = $now;
$def->{READINGS}{type}{VAL} = $type;
$def->{STATE} = $val;
$def->{CHANGED}[$max++] = $val;
$def->{CHANGED}[$max++] = "ExactId: $odev" if($odev ne $dev);
readingsBulkUpdate($def, "type", $type);
readingsBulkUpdate($def, "state", $val);
readingsBulkUpdate($def, "ExactId", $odev) if($odev ne $dev);
readingsEndUpdate($def, 1);
return $name;
}
@ -274,7 +270,7 @@ HMS_Parse($$)
<li>1001 for the HMS100-T</li>
<li>1002 for the HMS100-WD</li>
<li>1003 for the RM100-2</li>
<li>1004 for the HMS100-TFK/li>
<li>1004 for the HMS100-TFK</li>
<li>1006 for the HMS100-MG</li>
<li>1008 for the HMS100-CO</li>
<li>100e for the HMS100-FIT</li>
@ -300,14 +296,15 @@ HMS_Parse($$)
<a name="HMSattr"></a>
<b>Attributes</b>
<ul>
<li><a href="#ignore">ignore</a></li><br>
<li><a href="#do_not_notify">do_not_notify</a></li><br>
<li><a href="#loglevel">loglevel</a></li><br>
<li><a href="#showtime">showtime</a></li><br>
<li><a href="#IODev">IODev</a></li><br>
<li><a href="#eventMap">eventMap</a></li><br>
<li><a href="#ignore">ignore</a></li>
<li><a href="#do_not_notify">do_not_notify</a></li>
<li><a href="#loglevel">loglevel</a></li>
<li><a href="#showtime">showtime</a></li>
<li><a href="#IODev">IODev</a></li>
<li><a href="#eventMap">eventMap</a></li>
<li><a href="#model">model</a> (hms100-t hms100-tf hms100-wd hms100-mg
hms100-co hms100-tfk hms100-fit rm100-2)</li>
<li><a href="#readingFnAttributes">readingFnAttributes</a></li>
</ul>
<br>

View File

@ -18,7 +18,8 @@ CUL_TX_Initialize($)
$hash->{UndefFn} = "CUL_TX_Undef";
$hash->{ParseFn} = "CUL_TX_Parse";
$hash->{AttrList} = "IODev do_not_notify:1,0 ignore:0,1 " .
"showtime:1,0 loglevel:0,1,2,3,4,5,6";
"showtime:1,0 loglevel:0,1,2,3,4,5,6 " .
$readingFnAttributes;
}
#############################
@ -83,7 +84,7 @@ CUL_TX_Parse($$)
my $ll4 = GetLogLevel($name,4);
Log $ll4, "CUL_TX $name $id3 ($msg)";
my ($msgtype, $val, $changedTxt);
my ($msgtype, $val);
my $valraw = ($a[5].$a[6].".".$a[7]);
my $type = $a[2];
if($type eq "0") {
@ -94,7 +95,6 @@ CUL_TX_Parse($$)
$msgtype = "temperature";
$val = sprintf("%2.1f", ($valraw - 50 + $def->{corr}) );
Log $ll4, "CUL_TX $msgtype $name $id3 T: $val F: $id2";
$changedTxt = "temperature: $val";
} elsif ($type eq "E") {
if($now - $def->{lastH} < $def->{minsecs} ) {
@ -104,7 +104,6 @@ CUL_TX_Parse($$)
$msgtype = "humidity";
$val = $valraw;
Log $ll4, "CUL_TX $msgtype $name $id3 H: $val F: $id2";
$changedTxt = "humidity: $val";
} else {
my $ll2 = GetLogLevel($name,4);
@ -128,16 +127,11 @@ CUL_TX_Parse($$)
}
my $tn = TimeNow();
$def->{STATE} = $state;
$def->{READINGS}{state}{TIME} = $tn;
$def->{READINGS}{state}{VAL} = $state;
$def->{CHANGED}[0] = $changedTxt;
readingsBeginUpdate($def);
readingsBulkUpdate($def, "state", $state);
readingsBulkUpdate($def, $msgtype, $val);
readingsEndUpdate($def, 1);
$def->{READINGS}{$msgtype}{VAL} = $val;
$def->{READINGS}{$msgtype}{TIME} = $tn;
DoTrigger($name, undef) if($init_done);
return $name;
}
@ -187,14 +181,15 @@ CUL_TX_Parse($$)
<li><a href="#do_not_notify">do_not_notify</a></li><br>
<li><a href="#showtime">showtime</a></li><br>
<li><a href="#loglevel">loglevel</a></li><br>
<li><a href="#readingFnAttributes">readingFnAttributes</a></li>
</ul>
<br>
<a name="CUL_TXevents"></a>
<b>Generated events:</b>
<ul>
<li>temperature: $temp
<li>humidity: $hum
<li>temperature: $temp</li>
<li>humidity: $hum</li>
</ul>
<br>

View File

@ -25,7 +25,9 @@ CUL_WS_Initialize($)
$hash->{UndefFn} = "CUL_WS_Undef";
$hash->{AttrFn} = "CUL_WS_Attr";
$hash->{ParseFn} = "CUL_WS_Parse";
$hash->{AttrList} = "IODev do_not_notify:0,1 showtime:0,1 model:S300TH,KS300 loglevel ignore:0,1";
$hash->{AttrList} = "IODev do_not_notify:0,1 showtime:0,1 ".
"model:S300TH,KS300 loglevel ignore:0,1 ".
$readingFnAttributes;
}
@ -75,8 +77,8 @@ CUL_WS_Parse($$)
"6"=>"pyro",
"7"=>"temp/hum");
# -wusel, 2010-01-24: *sigh* No READINGS set, bad for other modules. Trying to add
# setting READINGS as well as STATE ...
# -wusel, 2010-01-24: *sigh* No READINGS set, bad for other modules. Trying
# to add setting READINGS as well as STATE ...
my $NotifyType;
my $NotifyHumidity;
my $NotifyTemperature;
@ -117,7 +119,6 @@ CUL_WS_Parse($$)
return "UNDEFINED CUL_WS_$cde CUL_WS $cde";
}
my $tm=TimeNow();
$hash = $def;
my $name = $hash->{NAME};
return "" if(IsIgnored($name));
@ -285,7 +286,9 @@ CUL_WS_Parse($$)
Log GetLogLevel($name,4), "CUL_WS $devtype $name: $val";
# Sanity checks
if($NotifyTemperature && $hash->{READINGS}{temperature}{VAL}) {
if($NotifyTemperature &&
$hash->{READINGS}{temperature} &&
$hash->{READINGS}{temperature}{VAL}) {
my $tval = $hash->{READINGS}{strangetemp} ?
$hash->{READINGS}{strangetemp}{VAL} :
$hash->{READINGS}{temperature}{VAL};
@ -293,7 +296,7 @@ CUL_WS_Parse($$)
if($diff < -15.0 || $diff > 15.0) {
Log 2, "$name: Temp difference ($diff) too large: $val, skipping it";
$hash->{READINGS}{strangetemp}{VAL} = $NotifyTemperature;
$hash->{READINGS}{strangetemp}{TIME} = $tm;
$hash->{READINGS}{strangetemp}{TIME} = TimeNow();
return "";
}
}
@ -304,11 +307,8 @@ CUL_WS_Parse($$)
return "";
}
$hash->{STATE} = $val; # List overview
$hash->{READINGS}{state}{TIME} = $tm; # For list
$hash->{READINGS}{state}{VAL} = $val;
$hash->{CHANGED}[0] = $val; # For notify
readingsBeginUpdate($hash);
readingsBulkUpdate($hash, "state", $val);
my $i=1;
my $j;
@ -327,15 +327,13 @@ CUL_WS_Parse($$)
} elsif($Notifies[$j] eq "P") { $val = $NotifyPressure;
}
my $nm = $NotifyMappings{$Notifies[$j]};
$hash->{READINGS}{$nm}{TIME} = $tm;
$hash->{READINGS}{$nm}{VAL} = $val;
$hash->{CHANGED}[$i++] = "$nm: $val";
readingsBulkUpdate($hash, $nm, $val);
}
$hash->{READINGS}{DEVTYPE}{VAL}=$devtype;
$hash->{READINGS}{DEVTYPE}{TIME}=$tm;
$hash->{READINGS}{DEVFAMILY}{VAL}=$family;
$hash->{READINGS}{DEVFAMILY}{TIME}=$tm;
readingsBulkUpdate($hash, "DEVTYPE", $devtype, 0);
readingsBulkUpdate($hash, "DEVFAMILY", $family, 0);
readingsEndUpdate($hash, 1); # Notify is done by Dispatch
return $name;
}
@ -390,13 +388,14 @@ CUL_WS_Attr(@)
<a name="CUL_WSattr"></a>
<b>Attributes</b>
<ul>
<li><a href="#ignore">ignore</a></li><br>
<li><a href="#do_not_notify">do_not_notify</a></li><br>
<li><a href="#showtime">showtime</a></li><br>
<li><a href="#loglevel">loglevel</a></li><br>
<li><a href="#model">model</a> (S300,KS300,WS7000)</li><br>
<li><a href="#IODev">IODev (!)</a></li><br>
<li><a href="#eventMap">eventMap</a></li><br>
<li><a href="#IODev">IODev (!)</a></li>
<li><a href="#do_not_notify">do_not_notify</a></li>
<li><a href="#eventMap">eventMap</a></li>
<li><a href="#ignore">ignore</a></li>
<li><a href="#loglevel">loglevel</a></li>
<li><a href="#model">model</a> (S300,KS300,WS7000)</li>
<li><a href="#showtime">showtime</a></li>
<li><a href="#readingFnAttributes">readingFnAttributes</a></li>
</ul>
<br>
</ul>

View File

@ -22,7 +22,8 @@ CUL_EM_Initialize($)
$hash->{UndefFn} = "CUL_EM_Undef";
$hash->{ParseFn} = "CUL_EM_Parse";
$hash->{AttrList} = "IODev do_not_notify:0,1 showtime:0,1 " .
"model:EMEM,EMWZ,EMGZ loglevel ignore:0,1";
"model:EMEM,EMWZ,EMGZ loglevel ignore:0,1".
$readingFnAttributes;
}
#####################################
@ -160,8 +161,8 @@ CUL_EM_Parse($$)
$val = sprintf("CNT: %d CUM: %0.3f 5MIN: %0.3f TOP: %0.3f",
$seqno, $total, $current, $peak);
$hash->{STATE} = $val;
$hash->{CHANGED}[$c++] = "$val";
readingsBeginUpdate($hash);
readingsBulkUpdate($hash, "state", $val);
$readings{total_cnt} = $total_cnt;
$readings{current_cnt} = $current_cnt;
@ -234,10 +235,9 @@ CUL_EM_Parse($$)
foreach my $k (keys %readings) {
$hash->{READINGS}{$k}{TIME}= $tn;
$hash->{READINGS}{$k}{VAL} = $readings{$k};
$hash->{CHANGED}[$c++] = "$k: $readings{$k}";
readingsBulkUpdate($hash, $k, $readings{$k});
}
readingsEndUpdate($hash, 1);
return $hash->{NAME};
} else {
@ -318,6 +318,7 @@ CUL_EM_Parse($$)
<li><a href="#model">model</a> (EMEM,EMWZ,EMGZ)</li><br>
<li><a href="#IODev">IODev</a></li><br>
<li><a href="#eventMap">eventMap</a></li><br>
<li><a href="#readingFnAttributes">readingFnAttributes</a></li>
</ul>
<br>
</ul>