diff --git a/fhem/CHANGED b/fhem/CHANGED index a4187de64..831a4ce04 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,6 @@ # Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # Do not insert empty lines here, update check depends on it. + - feature: 30_pilight_smoke: new module - represent a pilight smoke detector - bugfix: 73_GasCalculator: Bugfix for "Can't use an undefined value..." - bugfix: 10_pilight_ctrl: Experimental splice on scalar is now forbidden. - feature: 73_GasCalculator: "set" and "get" - command in GUI implemented. diff --git a/fhem/FHEM/10_pilight_ctrl.pm b/fhem/FHEM/10_pilight_ctrl.pm index 89d499434..9732f555e 100644 --- a/fhem/FHEM/10_pilight_ctrl.pm +++ b/fhem/FHEM/10_pilight_ctrl.pm @@ -42,6 +42,7 @@ # V 1.15 2016-03-28 - NEW: protocol daycom (switch) # V 1.16 2016-06-02 - NEW: protocol oregon_21 (temp) # V 1.17 2016-06-28 - FIX: Experimental splice on scalar is now forbidden - use explizit array notation +# V 1.18 2016-06-28 - NEW: support smoke sensors (protocol: secudo_smoke_sensor) ############################################## package main; @@ -64,7 +65,8 @@ my %sets = ( "reset:noArg" => "", "disconnect:noArg" => ""); my %matchList = ( "1:pilight_switch" => "^PISWITCH", "2:pilight_dimmer" => "^PISWITCH|^PIDIMMER|^PISCREEN", "3:pilight_temp" => "^PITEMP", - "4:pilight_raw" => "^PIRAW") ; + "4:pilight_raw" => "^PIRAW", + "5:pilight_smoke" => "^PISMOKE"); my @idList = ("id","systemcode","gpio"); my @unitList = ("unit","unitcode","programcode"); @@ -96,7 +98,7 @@ sub pilight_ctrl_Initialize($) $hash->{StateFn} = "pilight_ctrl_State"; $hash->{AttrList}= "ignoreProtocol brands ContactAsSwitch SendTimeout ".$readingFnAttributes; - $hash->{Clients} = ":pilight_switch:pilight_dimmer:pilight_temp:pilight_raw:"; + $hash->{Clients} = ":pilight_switch:pilight_dimmer:pilight_temp:pilight_raw::pilight_smoke:"; #$hash->{MatchList} = \%matchList; #only for autocreate } @@ -847,6 +849,10 @@ sub pilight_ctrl_Parse($$) case m/lm76/ {$protoID = 4;} case m/screen/ {$protoID = 5;} + + #smoke sensors + case m/secudo_smoke_sensor/ {$protoID = 6;} + case m/firmware/ {return;} else {Log3 $me, 3, "$me(Parse): unknown protocol -> $proto"; return;} } @@ -887,6 +893,7 @@ sub pilight_ctrl_Parse($$) return Dispatch($hash, $msg,undef); } case 5 { return Dispatch($hash, "PISCREEN,$proto,$id,$unit,$state",undef); } + case 6 { return Dispatch($hash, "PISMOKE,$proto,$id,$state",undef); } else {Log3 $me, 3, "$me(Parse): unknown protocol -> $proto"; return;} } return; diff --git a/fhem/FHEM/30_pilight_smoke.pm b/fhem/FHEM/30_pilight_smoke.pm new file mode 100644 index 000000000..c63fb31f6 --- /dev/null +++ b/fhem/FHEM/30_pilight_smoke.pm @@ -0,0 +1,168 @@ +############################################## +# $Id$ +# +# Usage +# +# define pilight_smoke +# +# Changelog +# +# V 0.10 2016-06-28 - initial alpha version +############################################## + +package main; + +use strict; +use warnings; +use Time::HiRes qw(gettimeofday); +use JSON; + +sub pilight_smoke_Parse($$); +sub pilight_smoke_Define($$); + +sub pilight_smoke_Initialize($) +{ + my ($hash) = @_; + + $hash->{DefFn} = "pilight_smoke_Define"; + $hash->{Match} = "^PISMOKE"; + $hash->{ParseFn} = "pilight_smoke_Parse"; + $hash->{StateFn} = "pilight_smoke_State"; + $hash->{AttrList} = "resetTime IODev ".$readingFnAttributes; +} + +##################################### +sub pilight_smoke_Define($$) +{ + my ($hash, $def) = @_; + my @a = split("[ \t][ \t]*", $def); + + if(@a < 4) { + my $msg = "wrong syntax: define pilight_smoke "; + Log3 undef, 2, $msg; + return $msg; + } + + my $me = $a[0]; + my $protocol = $a[2]; + my $id = $a[3]; + + $hash->{STATE} = "defined"; + $hash->{PROTOCOL} = lc($protocol); + $hash->{ID} = $id; + + #$attr{$me}{verbose} = 5; + + $modules{pilight_smoke}{defptr}{lc($protocol)}{$me} = $hash; + AssignIoPort($hash); + return undef; +} + +##################################### +sub pilight_smoke_State($$$$) +{ + my ($hash, $time, $name, $val) = @_; + my $me = $hash->{NAME}; + + #$hash->{STATE} wird nur ersetzt, wenn $hash->{STATE} == ??? fhem.pl Z: 2469 + #machen wir es also selbst + $hash->{STATE} = $val if ($name eq "state"); + return undef; +} + +########################################### +sub pilight_smoke_resetState($) +{ + my $hash = shift; + my $me = $hash->{NAME}; + + RemoveInternalTimer($hash); + + readingsBeginUpdate($hash); + readingsBulkUpdate($hash,"state","none"); + readingsEndUpdate($hash, 1); +} + +########################################### +sub pilight_smoke_Parse($$) +{ + my ($mhash, $rmsg, $rawdata) = @_; + my $backend = $mhash->{NAME}; + + Log3 $backend, 4, "pilight_smoke_Parse ($backend): RCV -> $rmsg"; + + my ($dev,$protocol,$id,$state,@args) = split(",",$rmsg); + return () if($dev ne "PISMOKE"); + + my $chash; + foreach my $n (keys %{ $modules{pilight_smoke}{defptr}{lc($protocol)} }) { + my $lh = $modules{pilight_smoke}{defptr}{$protocol}{$n}; + next if ( !defined($lh->{ID}) ); + if ($lh->{ID} eq $id) { + $chash = $lh; + last; + } + } + + return () if (!defined($chash->{NAME})); + + my $resetTime = AttrVal($chash->{NAME}, "resetTime",5); + + RemoveInternalTimer($chash); + + readingsBeginUpdate($chash); + readingsBulkUpdate($chash,"state",$state); + readingsEndUpdate($chash, 1); + + InternalTimer(gettimeofday()+$resetTime,"pilight_smoke_resetState", $chash, 0); + + return $chash->{NAME}; +} + + +1; + +=pod +=begin html + + +

pilight_smoke

+
    + + pilight_smoke represents a smoke sensor receiving data from pilight
    + You have to define the base device pilight_ctrl first.
    + Further information to pilight: http://www.pilight.org/
    +
    + + Define +
      + define <name> pilight_smoke protocol id +

      + + Example: +
        + define myctrl pilight_smoke secudo_smoke_sensor 0
        +
      +
    +
    + +

    Readings

    +
      +
    • + state
      + present the current state (alarm|none) +
    • +
    +
    + + Attributes +
      +
    • resetTime
      + Time [sec] to reset the state to none. +
    • +
    +
+ +=end html + +=cut