################################################################# # $Id$ ################################################################# # The module was taken over by an unknown maintainer! # It is part of the SIGNALduinos project. # https://github.com/RFD-FHEM/RFFHEM # # 2018 - takeover from unknown maintainer # 2018-2020 - HomeAuto_User, elektron-bbs ################################################################# # FLAMINGO FA20RF # get sduino_dummy raw MU;;P0=-1384;;P1=815;;P2=-2725;;P3=-20001;;P4=8159;;P5=-891;;D=01010121212121010101210101345101210101210101212101010101012121212101010121010134510121010121010121210101010101212121210101012101013451012101012101012121010101010121212121010101210101345101210101210101212101010101012121212101010121010134510121010121010121;;CP=1;;O;; # FLAMINGO FA21RF # get sduino_dummy raw MS;;P0=-1413;;P1=757;;P2=-2779;;P3=-16079;;P4=8093;;P5=-954;;D=1345121210101212101210101012121012121210121210101010;;CP=1;;SP=3;;R=33;;O;; # FLAMINGO FA22RF # get sduino_dummy raw MU;;P0=-5684;;P1=8149;;P2=-887;;P3=798;;P4=-1393;;P5=-2746;;P6=-19956;;D=0123434353534353434343434343435343534343534353534353612343435353435343434343434343534353434353435353435361234343535343534343434343434353435343435343535343536123434353534353434343434343435343534343534353534353612343435353435343434343434343534353434353435;;CP=3;;R=0;; # LM-101LD # get sduino_dummy raw MS;;P1=-2708;;P2=796;;P3=-1387;;P4=-8477;;P5=8136;;P6=-904;;D=2456212321212323232321212121212121212123212321212121;;CP=2;;SP=4;; ################################################################# # note / ToDo´s / Bugs: # - ################################################################# package main; use strict; use warnings; our $VERSION = '200817'; my %sets = ( 'Testalarm:noArg', 'Counterreset:noArg', ); my %models = ( 'FA20RF', 'FA21RF', 'FA22RF', 'KD-101LA', 'LM-101LD', 'unknown', ); ##################################### sub FLAMINGO_Initialize { my ($hash) = @_; $hash->{Match} = '^P13\.?1?#[A-Fa-f0-9]+'; $hash->{SetFn} = 'FLAMINGO_Set'; $hash->{DefFn} = 'FLAMINGO_Define'; $hash->{UndefFn} = 'FLAMINGO_Undef'; $hash->{ParseFn} = 'FLAMINGO_Parse'; $hash->{AttrList} = 'IODev do_not_notify:0,1 showtime:0,1 ignore:0,1 '. 'model:'.join(q{,}, sort %models).q{ } . 'room:FLAMINGO '. $readingFnAttributes; $hash->{AutoCreate}= { 'FLAMINGO.*' => { ATTR => 'event-on-change-reading:.* event-min-interval:.*:300', FILTER => '%NAME', GPLOT => q{} }, }; return } ##################################### sub FLAMINGO_Define { my ($hash, $def) = @_; my @a = split("[ \t][ \t]*", $def); # Argument 0 1 2 3 4 return 'ERROR: wrong syntax, define FLAMINGO ' if(int(@a) < 3 || int(@a) > 5); ### check hex code ### return 'ERROR: wrong hex length ' . length($a[2]) . ', you need 6'if not length($a[2]) == 6; return 'ERROR: wrong hex value ' . $a[2] if not ($a[2] =~ /^[0-9a-fA-F]{6}$/xms); ### check model ### return 'ERROR: wrong model: '.$a[3] . "\n\n(allowed modelvalues: " . join(' | ', sort %models).')' if $a[3] && ( !grep { $_ eq $a[3] } %models ); $hash->{CODE} = $a[2]; $hash->{lastMSG} = 'no data'; $hash->{bitMSG} = 'no data'; $modules{FLAMINGO}{defptr}{$a[2]} = $hash; $hash->{STATE} = 'Defined'; my $name = $hash->{NAME}; my $iodev; if ($a[4]) { $iodev = $a[4]; }; if (exists $modules{FLAMINGO}{defptr}{ioname} && !$iodev) { $iodev = $modules{FLAMINGO}{defptr}{ioname}; }; ### Attributes ### if ( $init_done == 1 ) { if ($a[3]) { CommandAttr($hash,"$name model $a[3]") ;}; if (not $a[3]) { CommandAttr($hash,"$name model unknown") ;}; } AssignIoPort($hash,$iodev); ## sucht nach einem passenden IO-Gerät (physikalische Definition) return; } ##################################### sub FLAMINGO_Undef { my ($hash, $name) = @_; RemoveInternalTimer($hash, 'FLAMINGO_UpdateState'); if($hash && $hash->{CODE}) { delete($modules{FLAMINGO}{defptr}{$hash->{CODE}}); }; if ( exists $modules{FLAMINGO}{defptr}{testrunning} ) { delete($modules{FLAMINGO}{defptr}{testrunning}); } return; } ##################################### sub FLAMINGO_Set { my ( $hash, $name, @args ) = @_; my $ret = undef; my $message; my $list; my $model = AttrVal($name, 'model', 'unknown'); my $iodev = $hash->{IODev}{NAME}; $list = join (q{ }, %sets); return "ERROR: wrong command! (only $list)" if ($args[0] ne '?' && $args[0] ne 'Testalarm' && $args[0] ne 'Counterreset'); if ($args[0] eq '?') { if ($model eq 'unknown') { $ret = q{}; # no set if model unknown or no model attribut } else { $ret = $list; } } my $hlen = length($hash->{CODE}); my $blen = $hlen * 4; my $bitData= unpack("B$blen", pack("H$hlen", $hash->{CODE})); my $bitAdd = substr($bitData,23,1); # for last bit, is needed to send ## use the protocol ID how receive last message my $sendID = ReadingsVal($name, 'lastReceive_ID', q{}); # for send command, because ID´s can vary / MU / MS message $message = 'P'.$sendID.'#'.$bitData.$bitAdd.'P#R55'; ## Send Message to IODev and wait for correct answer if ($args[0] ne '?') { Log3 $hash, 3, "FLAMINGO set $name $args[0]"; } ## Counterreset ## if ($args[0] eq 'Counterreset') { readingsSingleUpdate($hash, 'alarmcounter', 0, 1); } ## Testarlarm ## if ($args[0] ne '?' and $args[0] ne 'Counterreset') { # remove InternalTimer RemoveInternalTimer($hash, 'FLAMINGO_UpdateState'); $modules{FLAMINGO}{defptr}{testrunning} = 'yes'; # marker, device send Testalarm to NOT register this alarm with other receivers in FHEM Log3 $hash, 4, 'FLAMINGO set marker TESTALARM is running'; readingsSingleUpdate($hash, 'state', 'Testalarm', 1); Log3 $hash, 4, "$iodev: FLAMINGO send raw Message: $message"; IOWrite($hash, 'sendMsg', $message); InternalTimer(gettimeofday()+15, 'FLAMINGO_UpdateState', $hash, 0); # set timer to Update status } return $ret; } ##################################### sub FLAMINGO_Parse { my ($iohash, $msg) = @_; #my $name = $iohash->{NAME}; my ($protocol,$rawData) = split('#',$msg); $protocol=~ s/^[P](\d+)/$1/xms; # extract protocol my $iodev = $iohash->{NAME}; $modules{FLAMINGO}{defptr}{ioname} = $iodev; my $hlen = length($rawData); my $blen = $hlen * 4; my $bitData= unpack("B$blen", pack("H$hlen", $rawData)); my $deviceCode = $rawData; # Message is in hex "4d4efd" my $def = $modules{FLAMINGO}{defptr}{$deviceCode}; if(!$def) { $def = $modules{FLAMINGO}{defptr}{$deviceCode}; } my $hash = $def; #my $model = AttrVal($name, 'model', 'unknown'); if(!$def) { Log3 $iohash, 1, "FLAMINGO UNDEFINED sensor detected, code $deviceCode, protocol $protocol"; return "UNDEFINED FLAMINGO_$deviceCode FLAMINGO $deviceCode"; } my $name = $hash->{NAME}; if(IsIgnored($name)) { return q{}; } $hash->{bitMSG} = $bitData; $hash->{lastMSG} = $rawData; $hash->{lastReceive} = time(); readingsSingleUpdate($hash, 'lastReceive_ID', $protocol, 0); # to save lastReceive_ID for send command ## check if Testalarm received from a other transmitter in FHEM ## my $testalarmcheck = q{}; if ( exists $modules{FLAMINGO}{defptr}{testrunning} ) { $testalarmcheck = $modules{FLAMINGO}{defptr}{testrunning}; } if ($testalarmcheck eq 'yes') { return q{}; } my $alarmcounter = ReadingsVal($name, 'alarmcounter', 0); if (ReadingsVal($name, 'state', q{}) ne 'Alarm') { $alarmcounter = $alarmcounter+1; } Log3 $name, 5, "$iodev: FLAMINGO actioncode: $deviceCode"; Log3 $name, 4, "$iodev: FLAMINGO $name: is receiving Alarm (Counter $alarmcounter)"; # remove InternalTimer RemoveInternalTimer($hash, 'FLAMINGO_UpdateState'); readingsBeginUpdate($hash); readingsBulkUpdate($hash, 'state', 'Alarm'); readingsBulkUpdate($hash, 'alarmcounter', $alarmcounter); # register non testalarms how user can set via FHEM readingsEndUpdate($hash, 1); # Notify is done by Dispatch InternalTimer(gettimeofday()+15, 'FLAMINGO_UpdateState', $hash, 0); # set timer to Update status return $name; } ##################################### sub FLAMINGO_UpdateState { my ($hash) = @_; my $name = $hash->{NAME}; readingsBeginUpdate($hash); readingsBulkUpdate($hash, 'state', 'no Alarm'); readingsEndUpdate($hash, 1); # Notify is done by Dispatch ## delete marker device Testalarm ## if ( exists $modules{FLAMINGO}{defptr}{testrunning} ) { Log3 $hash, 4, 'FLAMINGO delete marker TESTALARM was running'; delete($modules{FLAMINGO}{defptr}{testrunning}) }; Log3 $name, 4, "FLAMINGO: $name: Alarm stopped"; return; } 1; =pod =item summary Supports flamingo fa20rf/fa21 smoke detectors =item summary_DE Unterstützt Flamingo FA20RF/FA21/FA22RF/LM-101LD Rauchmelder =begin html

FLAMINGO

    The FLAMINGO module interprets FLAMINGO FA20RF/FA21/FA22RF type of messages received by the SIGNALduino.
    Of this smoke detector, there are identical types profitec KD101LA, POLLIN KD101LA or renkforce LM-101LD.

    Define
      define <name> FLAMINGO <code>

    • <code> is the unic code of the autogenerated address of the FLAMINGO device. This changes, after pairing to the master
    • <model> is the model name

    • - if autocreate, the defined model is unknown.
      - with manual define you can choose the model which is available as attribute.


    Set
    • Counterreset
      - set alarmcounter to 0
    • Testalarm
      - trigger a test alarm (The testalarm does not increase the alarm ounter!)

    Get
      N/A

    Attributes

    Generated readings
    - alarmcounter | counter started with 0
    - lastReceive_ID | the protocol ID from SIGNALduino
    - state | (no Alarm, Alarm, Testalaram)


    manual
    Pairing (Master-Slave)
    • Determine master
      LEARN button push until the green LED lights on
    • Determine slave
      LEARN button push until the red LED lights on
    • Master, hold down the TEST button until an alarm signal generated at all "Slaves"

    Standalone
    • LEARN button push until the green LED lights on
    • TEST button hold down until an alarm signal generated
=end html =begin html_DE

FLAMINGO

    Das FLAMINGO module dekodiert vom SIGNALduino empfangene Nachrichten des FLAMINGO FA20RF / FA21 / FA22RF Rauchmelders.
    Von diesem Rauchmelder gibt es baugleiche Typen wie profitec KD101LA, POLLIN KD101LA oder renkforce LM-101LD.

    Define
      define <name> FLAMINGO <code> <model>

    • <code> ist der automatisch angelegte eindeutige code des FLAMINGO Rauchmelders. Dieser ändern sich nach dem Pairing mit einem Master.
    • <model> ist die Modelbezeichnung

    • - Bei einem Autocreate wird als Model unknown definiert.
      - Bei einem manuellen define kann man das Model frei wählen welche als Attribut verfügbar sind .


    Set
    • Counterreset
      - Alarmzähler auf 0 setzen
    • Testalarm
      - auslösen eines Testalarmes. (Der Testalarm erhöht nicht den Alarmzähler!)

    Get
      N/A


    Attributes

    Generierte Readings
    - alarmcounter | Alarmzähler beginnend mit 0
    - lastReceive_ID | Protokoll ID vom SIGNALduino
    - state | (no Alarm, Alarm, Testalaram)


    Anleitung
    Melder paaren (Master-Slave Prinzip)
    • Master bestimmen
      LEARN-Taste bis grüne Anzeige LED leuchtet
    • Slave bestimmen
      LEARN-Taste bis rote Anzeige LED leuchtet
    • Master, TEST-Taste gedrückt halten, bevor LEDś abschalten und alles "Slaves" ein Alarmsignal erzeugen

    Paarung aufheben / Standalone Betrieb
    • LEARN-Taste bis grüne Anzeige LED leuchtet
    • TEST-Taste gedrückt halten bis ein Alarmsignal erzeugt wird
=end html_DE =cut