2019-02-19 21:02:24 +00:00
#################################################################
# $Id$
#################################################################
# The module was taken over by an unknown maintainer!
# It is part of the SIGNALduinos project.
2020-08-17 17:29:09 +00:00
# https://github.com/RFD-FHEM/RFFHEM
2019-02-19 21:02:24 +00:00
#
2020-08-17 17:29:09 +00:00
# 2018 - takeover from unknown maintainer
# 2018-2020 - HomeAuto_User, elektron-bbs
2019-02-19 21:02:24 +00:00
#################################################################
# 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 ;
2020-08-17 17:29:09 +00:00
our $ VERSION = '200817' ;
2019-02-19 21:02:24 +00:00
my % sets = (
2020-08-17 17:29:09 +00:00
'Testalarm:noArg' ,
'Counterreset:noArg' ,
2019-02-19 21:02:24 +00:00
) ;
my % models = (
2020-08-17 17:29:09 +00:00
'FA20RF' ,
'FA21RF' ,
'FA22RF' ,
'KD-101LA' ,
'LM-101LD' ,
'unknown' ,
2019-02-19 21:02:24 +00:00
) ;
#####################################
2020-08-17 17:29:09 +00:00
sub FLAMINGO_Initialize {
2019-02-19 21:02:24 +00:00
my ( $ hash ) = @ _ ;
2020-08-17 17:29:09 +00:00
$ 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
2019-02-19 21:02:24 +00:00
}
#####################################
2020-08-17 17:29:09 +00:00
sub FLAMINGO_Define {
my ( $ hash , $ def ) = @ _ ;
my @ a = split ( "[ \t][ \t]*" , $ def ) ;
# Argument 0 1 2 3 4
return 'ERROR: wrong syntax, define <name> FLAMINGO <code> <model> <optional IODev>' 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 ;
2019-02-19 21:02:24 +00:00
}
#####################################
2020-08-17 17:29:09 +00:00
sub FLAMINGO_Undef {
2019-02-19 21:02:24 +00:00
my ( $ hash , $ name ) = @ _ ;
2020-08-17 17:29:09 +00:00
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 ;
2019-02-19 21:02:24 +00:00
}
#####################################
2020-08-17 17:29:09 +00:00
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' ) ;
2019-02-19 21:02:24 +00:00
2020-08-17 17:29:09 +00:00
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 ;
2019-02-19 21:02:24 +00:00
}
#####################################
2020-08-17 17:29:09 +00:00
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 ;
2019-02-19 21:02:24 +00:00
}
#####################################
2020-08-17 17:29:09 +00:00
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 ;
2019-02-19 21:02:24 +00:00
}
1 ;
= pod
= item summary Supports flamingo fa20rf / fa21 smoke detectors
= item summary_DE Unterst & uumltzt Flamingo FA20RF /FA21/ FA22RF / LM - 101 LD Rauchmelder
= begin html
< a name = "FLAMINGO" > </a>
<h3> FLAMINGO </h3>
<ul>
The FLAMINGO module interprets FLAMINGO FA20RF /FA21/ FA22RF type of messages received by the SIGNALduino . <br>
Of this smoke detector , there are identical types profitec KD101LA , POLLIN KD101LA or renkforce LM - 101 LD .
<br> <br>
< a name = "FLAMINGOdefine" > </a>
<b> Define </b>
<ul>
<code> define & lt ; name & gt ; FLAMINGO & lt ; code & gt ; </code> <br>
<br>
<li> & lt ; code & gt ; is the unic code of the autogenerated address of the FLAMINGO device . This changes , after pairing to the master </li>
2020-08-17 17:29:09 +00:00
<li> & lt ; model & gt ; is the model name </li> <br>
- if autocreate , the defined model is <code> unknown </code> . <br>
- with manual <code> define </code> you can choose the model which is available as attribute .
2019-02-19 21:02:24 +00:00
</ul>
<br> <br>
< a name = "FLAMINGOset" > </a>
<b> Set </b>
<ul>
<li> Counterreset <br>
- set alarmcounter to 0 </li>
<li> Testalarm <br>
- trigger a test alarm ( The testalarm does not increase the alarm ounter ! ) </li>
</ul> <br>
< a name = "FLAMINGOget" > </a>
<b> Get </b> <ul> N /A</ ul > <br>
< a name = "FLAMINGOattr" > </a>
<b> Attributes </b>
<ul>
<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>
2020-08-17 17:29:09 +00:00
< a name = "model" > </a>
<li> model <br>
FA20RF , FA21RF , FA22RF , KD - 101 LA , LM - 101 LD , unknown </li>
2019-02-19 21:02:24 +00:00
< a name = "showtime" > </a>
2020-08-17 17:29:09 +00:00
<li> < a href = "#showtime" > showtime </a> </li>
2019-02-19 21:02:24 +00:00
<li> < a href = "#readingFnAttributes" > readingFnAttributes </a> </li>
</ul>
<br> <br>
<b> <u> Generated readings </u> </b> <br>
- alarmcounter | counter started with 0 <br>
- lastReceive_ID | the protocol ID from SIGNALduino <br>
- state | ( no Alarm , Alarm , Testalaram ) <br>
<br> <br>
<u> <b> manual <br> </b> </u>
<b> Pairing ( Master - Slave ) </b>
<ul>
<li> Determine master <br>
LEARN button push until the green LED lights on </li>
<li> Determine slave <br>
LEARN button push until the red LED lights on </li>
<li> Master , hold down the TEST button until an alarm signal generated at all "Slaves" </li>
</ul> <br>
<b> Standalone </b>
<ul>
<li> LEARN button push until the green LED lights on </li>
<li> TEST button hold down until an alarm signal generated </li>
</ul>
</ul>
= end html
= begin html_DE
< a name = "FLAMINGO" > </a>
<h3> FLAMINGO </h3>
<ul>
Das FLAMINGO module dekodiert vom SIGNALduino empfangene Nachrichten des FLAMINGO FA20RF / FA21 / FA22RF Rauchmelders . <br>
Von diesem Rauchmelder gibt es baugleiche Typen wie profitec KD101LA , POLLIN KD101LA oder renkforce LM - 101 LD .
<br> <br>
< a name = "FLAMINGOdefine" > </a>
<b> Define </b>
<ul>
<code> define & lt ; name & gt ; FLAMINGO & lt ; code & gt ; & lt ; model & gt ; </code> <br>
<br>
<li> & lt ; code & gt ; ist der automatisch angelegte eindeutige code des FLAMINGO Rauchmelders . Dieser & auml ; ndern sich nach
2020-08-17 17:29:09 +00:00
dem Pairing mit einem Master . </li>
<li> & lt ; model & gt ; ist die Modelbezeichnung </li> <br>
- Bei einem Autocreate wird als Model <code> unknown </code> definiert . <br>
- Bei einem manuellen <code> define </code> kann man das Model frei w & auml ; hlen welche als Attribut verf & uuml ; gbar sind .
2019-02-19 21:02:24 +00:00
</ul>
<br> <br>
< a name = "FLAMINGOset" > </a>
<b> Set </b>
<ul>
2020-08-17 17:29:09 +00:00
<li> Counterreset <br>
- Alarmz & auml ; hler auf 0 setzen </li>
<li> Testalarm <br>
- ausl & ouml ; sen eines Testalarmes . ( Der Testalarm erh & ouml ; ht nicht den Alarmz & auml ; hler ! ) </li>
2019-02-19 21:02:24 +00:00
</ul> <br>
< a name = "FLAMINGOget" > </a>
<b> Get </b> <ul> N /A</ ul > <br> <br>
< a name = "FLAMINGOattr" > </a>
<b> Attributes </b>
<ul>
<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>
2020-08-17 17:29:09 +00:00
< a name = "model" > </a>
<li> model <br>
FA20RF , FA21RF , FA22RF , KD - 101 LA , LM - 101 LD , unknown </li>
< a name = "showtime" > </a>
2019-02-19 21:02:24 +00:00
<li> < a href = "#showtime" > showtime </a> </li>
<li> < a href = "#readingFnAttributes" > readingFnAttributes </a> </li>
</ul>
<br> <br>
<b> <u> Generierte Readings </u> </b> <br>
- alarmcounter | Alarmz & auml ; hler beginnend mit 0 <br>
- lastReceive_ID | Protokoll ID vom SIGNALduino <br>
- state | ( no Alarm , Alarm , Testalaram ) <br>
<br> <br>
<u> <b> Anleitung <br> </b> </u>
<b> Melder paaren ( Master - Slave Prinzip ) </b>
<ul>
2020-08-17 17:29:09 +00:00
<li> Master bestimmen <br>
LEARN - Taste bis gr & uuml ; ne Anzeige LED leuchtet </li>
<li> Slave bestimmen <br>
LEARN - Taste bis rote Anzeige LED leuchtet </li>
<li> Master , TEST - Taste gedr & uuml ; ckt halten , bevor LEDś abschalten und alles "Slaves" ein Alarmsignal erzeugen </li>
2019-02-19 21:02:24 +00:00
</ul> <br>
<b> Paarung aufheben / Standalone Betrieb</ b >
<ul>
2020-08-17 17:29:09 +00:00
<li> LEARN - Taste bis gr & uuml ; ne Anzeige LED leuchtet </li>
<li> TEST - Taste gedr & uuml ; ckt halten bis ein Alarmsignal erzeugt wird </li>
2019-02-19 21:02:24 +00:00
</ul>
</ul>
= end html_DE
= cut