diff --git a/fhem/FHEM/10_EnOcean.pm b/fhem/FHEM/10_EnOcean.pm index fce96a452..87a5af8ac 100755 --- a/fhem/FHEM/10_EnOcean.pm +++ b/fhem/FHEM/10_EnOcean.pm @@ -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 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. -
  • subType dimmCtrl, tested with ElTako Dimmer only +
  • subType eltakoDimmer, tested with Eltako devices only +
  • + +
  • subType eltakoShutter, tested with Eltako devices only +
  • @@ -638,6 +727,7 @@ EnOcean_A5Cmd($$$)
  • showtime
  • model
  • subType
  • +
  • readingFnAttributes
  • actualTemp
    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($$$)
  • switch. Switches (remotes) with more than one (pair) of buttons are separate devices with separate address. + A0,BI or D0,CI
  • +
  • buttons:released
  • +
  • buttons: released
  • +
    +
  • FSB61/FSM61 (set model to FSB61 or FSM61 manually)
    -
  • windowHandle (HOPPE SecuSignal). Set the subType attr to windowHandle. +
  • closed
  • +
  • open
  • +
  • tilted
  • +
  • open from tilted
  • + +
  • keycard. Set the subType attr to keycard. (untested) +
  • keycard inserted
  • +
  • keycard removed
  • + +
  • STM-250 Door and window contact. +
  • closed
  • +
  • open
  • +
  • learnBtn: on
  • + +
  • SR04* (Temp sensor + Presence button and desired temp dial).
    Set the model attribute to one of SR04 SR04P SR04PT SR04PST SR04PMS or the subType attribute to SR04. +
  • temperature: XY.Z
  • +
  • set_point: [0..255]
  • +
  • fan: [0|1|2|3|Auto]
  • +
  • present: yes
  • +
  • learnBtn: on
  • +
  • T: XY.Z SP: [0..255] F: [0|1|2|3|Auto] P: [yes|no]
  • + +
  • MD15-FtL-HE (Heating/Valve-regulator)
    The subType attibute must be MD15. This is done if the device was created by autocreate.
    +
  • $actuator %
  • +
  • currentValue: $actuator
  • +
  • serviceOn: [yes|no]
  • +
  • energyInput: [enabled|disabled]
  • +
  • energyStorage: [charged|empty]
  • +
  • battery: [ok|empty]
  • +
  • cover: [open|closed]
  • +
  • tempSensor: [failed|ok]
  • +
  • window: [open|closed]
  • +
  • actuator: [ok|obstructed]
  • +
  • temperature: $tmp
  • +
  • Ratio Presence Sensor Eagle PM101.
    Set the model attribute to PM101
    +
  • brightness: $lux
  • +
  • channel1: [on|off]
  • +
  • channel2: [on|off]
  • +
  • FAH60,FAH63,FIH63 brigthness senor.
    Set subType to FAH or model to FAH60/FAH63/FIH63 manually.
    +
  • brightness: $lux
  • +
  • state: $lux
  • +
  • FABH63,FBH55,FBH63,FIBH63 Motion/brightness sensor.
    Set subType to FBH or model to FABH63/FBH55/FBH63/FIBH63 manually.
    +
  • brightness: $lux
  • +
  • motion:[yes|no]
  • +
  • state: [motion: yes|no]
  • + +
  • FTF55 Temperature sensor.
    Set subType to FTF or model to FTF55 manually.
    +
  • temperature: $temp
  • +
  • state: $temp
  • + + +
  • eltakoDimmer
    +
  • + +
  • eltakoShutter
    +
  • diff --git a/fhem/FHEM/10_FS20.pm b/fhem/FHEM/10_FS20.pm index 0e6d7fd4a..76ada4b38 100755 --- a/fhem/FHEM/10_FS20.pm +++ b/fhem/FHEM/10_FS20.pm @@ -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($$)
  • 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).
  • -
  • The time 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 +
  • The time 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 at which has a 1 sec resolution.
  • on-till requires an absolute time in the "at" format (HH:MM:SS, HH:MM @@ -619,7 +606,6 @@ four2hex($$)

  • -
  • do_not_notify

  • dummy
    Set the device attribute dummy to define devices which should not @@ -645,10 +631,6 @@ four2hex($$)

  • -
  • loglevel

  • - -
  • showtime

  • -
  • model
    The model attribute denotes the model type of the device. @@ -687,6 +669,11 @@ four2hex($$) "ignored=1" special devspec.

  • +
  • do_not_notify
  • +
  • loglevel
  • +
  • showtime
  • +
  • readingFnAttributes
  • +
    @@ -694,13 +681,13 @@ four2hex($$) Generated events: diff --git a/fhem/FHEM/10_ZWave.pm b/fhem/FHEM/10_ZWave.pm index 19f977d35..1f0fd1661 100755 --- a/fhem/FHEM/10_ZWave.pm +++ b/fhem/FHEM/10_ZWave.pm @@ -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($$)
    Class BASIC
  • basicValue value
    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.


  • Class SWITCH_BINARY
  • on
    - switch the device on + switch the device on
  • off
    - switch the device off + switch the device off
  • reportOn,reportOff
    - activate/deactivate the reporting of device state changes to the association group. + activate/deactivate the reporting of device state changes to the + association group.


  • Class CONFIGURATION
  • configByte cfgAddress 8bitValue
    configWord cfgAddress 16bitValue
    configLong cfgAddress 32bitValue
    Send a configuration value for the parameter cfgAddress. cfgAddress and - value is node specific. + value is node specific.
  • configDefault cfgAddress
    - 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.


  • Class WAKE_UP
  • wakeupInterval value
    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.


  • Class ASSOCIATION
  • associationAdd groupId nodeId ...
    - Add the specified list of nodeIds to the assotion group groupId.
    - 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.
    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"
  • associationDel groupId nodeId ...
    - Remove the specified list of nodeIds from the assotion group groupId. + Remove the specified list of nodeIds from the assotion group groupId.

  • @@ -569,42 +560,51 @@ ZWave_Undef($$)
  • basicStatus
    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. +


  • Class SWITCH_BINARY
  • swbStatus
    return the status of the node, as state:on or state:off. +


  • Class SENSOR_BINARY
  • sbStatus
    return the status of the node, as state:open or state:closed. +


  • Class CONFIGURATION
  • config cfgAddress
    return the value of the configuration parameter cfgAddress. The value is device specific. +


  • Class ALARM
  • alarm alarmId
    return the value for alarmId. The value is device specific. +


  • Class BATTERY
  • battery
    return the charge of the battery in %, as battery:value % +


  • Class WAKE_UP
  • wakeupInterval
    return the wakeup interval in seconds, in the form
    wakeupReport:interval:seconds target:id +


  • Class ASSOCIATION
  • association groupId
    return the list of nodeIds in the association group groupId in the form:
    assocGroup_X:Max:Y Nodes:id,id... +


  • Class VERSION
  • version
    return the version information of this node in the form:
    Lib:A Prot:x.y App:a.b +

  • @@ -619,6 +619,7 @@ ZWave_Undef($$)
  • showtime
  • loglevel
  • model
  • +
  • readingFnAttributes
  • classes 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($$) diff --git a/fhem/FHEM/12_HMS.pm b/fhem/FHEM/12_HMS.pm index 60210a6c8..e67b7b3a5 100755 --- a/fhem/FHEM/12_HMS.pm +++ b/fhem/FHEM/12_HMS.pm @@ -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($$)
  • 1001 for the HMS100-T
  • 1002 for the HMS100-WD
  • 1003 for the RM100-2
  • -
  • 1004 for the HMS100-TFK/li> +
  • 1004 for the HMS100-TFK
  • 1006 for the HMS100-MG
  • 1008 for the HMS100-CO
  • 100e for the HMS100-FIT
  • @@ -300,14 +296,15 @@ HMS_Parse($$) Attributes
    diff --git a/fhem/FHEM/14_CUL_TX.pm b/fhem/FHEM/14_CUL_TX.pm index 5d8b8af48..a8e3539c8 100644 --- a/fhem/FHEM/14_CUL_TX.pm +++ b/fhem/FHEM/14_CUL_TX.pm @@ -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($$)
  • do_not_notify

  • showtime

  • loglevel

  • +
  • readingFnAttributes

  • Generated events:
    diff --git a/fhem/FHEM/14_CUL_WS.pm b/fhem/FHEM/14_CUL_WS.pm index 7a0819046..1787f1deb 100755 --- a/fhem/FHEM/14_CUL_WS.pm +++ b/fhem/FHEM/14_CUL_WS.pm @@ -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(@) Attributes
    diff --git a/fhem/FHEM/15_CUL_EM.pm b/fhem/FHEM/15_CUL_EM.pm index d793f33cc..38f6b00a4 100755 --- a/fhem/FHEM/15_CUL_EM.pm +++ b/fhem/FHEM/15_CUL_EM.pm @@ -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($$)
  • model (EMEM,EMWZ,EMGZ)

  • IODev

  • eventMap

  • +
  • readingFnAttributes