From c343e2398b42ebcb7286366622240686a349de55 Mon Sep 17 00:00:00 2001 From: sidey79 Date: Mon, 17 Jan 2022 20:23:26 +0000 Subject: [PATCH] 00_SIGNALduino.pm: - Version 3.5.2 commited - SD_ProtocolsData v1.42 - SD_Protocols.pm v2.05 git-svn-id: https://svn.fhem.de/fhem/trunk@25482 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 30 + fhem/FHEM/00_SIGNALduino.pm | 9303 +++++++++++++++--------------- fhem/FHEM/lib/SD_ProtocolData.pm | 5956 ++++++++++--------- fhem/FHEM/lib/SD_Protocols.pm | 2196 ++++++- 4 files changed, 9869 insertions(+), 7616 deletions(-) diff --git a/fhem/CHANGED b/fhem/CHANGED index fbca1293f..7c6e9fba1 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,35 @@ # 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: 00_SIGNALduino.pm version 3.5.2 + xFSK processing + Added support for directio and none. + Extension for "get sduino ccreg" (#918) + parse subs optimized (#926) + update reading config when change settings (#948) + Allow incremental addition of match list entries (#1026) + added commandref rfmode & cc1101_reg_user + added hardware ESP32cc1101, MAPLEMINI_F103CB on attribute + added new attrib rfmode to changed to xFSK & revised commandref + added separat sub SIGNALduino_Attr_rfmode + added set cmd LaCrossePairForSec (for LaCrosse + - change: 00_SIGNALduino.pm version 3.5.2 + added N to send SN xFSK sendCommand + added new sub SIGNALduino_calcRSSI to simplification code + revised Parse_MN and loglevel + revised logoutput text SIGNALduino_Get_Command + rename "get raw" to "get rawmsg" (#925) + - bugfix: 00_SIGNALduino.pm version 3.5.2 + SIGNALduino_CheckccConfResponse is more robust #1015 (#1031) + fix PERL WARNING (#895) (#972) + get ccreg command caused stacktrace #898 + Bugfix define with hostname 901 (#904) + Wrong version assignment fixed + module runs now without fhemweb instance + display protocol list (#947) + require 99_Utils only if really needed (#950) + corrected incorrect logoutput (#951) + Fix Multiple send delay (#941) + Fixes high CPU and MEM usage in patternExists (#988) - bugfix: 89_FULLY: Removed parseParam - bugfix: 73_AutoShuttersControl: fix setter Readings in ShuttersControl.pm - change: 73_AutoShuttersControl: change Attribut ASC_advDate diff --git a/fhem/FHEM/00_SIGNALduino.pm b/fhem/FHEM/00_SIGNALduino.pm index ea113eace..556ca508d 100644 --- a/fhem/FHEM/00_SIGNALduino.pm +++ b/fhem/FHEM/00_SIGNALduino.pm @@ -1,61 +1,63 @@ # $Id$ -# -# v3.4.4 - https://github.com/RFD-FHEM/RFFHEM/tree/master +# v3.5.2 - https://github.com/RFD-FHEM/RFFHEM/tree/master # The module is inspired by the FHEMduino project and modified in serval ways for processing the incoming messages # see http://www.fhemwiki.de/wiki/SIGNALDuino # It was modified also to provide support for raw message handling which can be send from the SIGNALduino # The purpos is to use it as addition to the SIGNALduino which runs on an arduno nano or arduino uno. # It routes Messages serval Modules which are already integrated in FHEM. But there are also modules which comes with it. # -# N. Butzek, S. Butzek, 2014-2015 -# S.Butzek,Ralf9 2016-2019 -# S.Butzek, HomeAutoUser, elektron-bbs 2019-2020 +# 2014-2015 S.Butzek, N.Butzek +# 2016-2019 S.Butzek, Ralf9 +# 2019-2022 S.Butzek, HomeAutoUser, elektron-bbs package main; use strict; use warnings; -#use version 0.77; our $VERSION = version->declare('v3.4.4'); +#use version 0.77; our $VERSION = version->declare('v3.5.2'); -my $missingModulSIGNALduino=""; +my $missingModulSIGNALduino = ''; use DevIo; +require "99_Utils.pm" if (!defined $modules{"Utils"} || !exists $modules{"Utils"}{"LOADED"} ); ## no critic +use Carp; no warnings 'portable'; eval {use Data::Dumper qw(Dumper);1}; +eval {use Digest::CRC;1 or $missingModulSIGNALduino .= 'Digest::CRC '}; eval {use JSON;1 or $missingModulSIGNALduino .= 'JSON '}; eval {use Scalar::Util qw(looks_like_number);1}; eval {use Time::HiRes qw(gettimeofday);1} ; use lib::SD_Protocols; +use List::Util qw(first); -#$| = 1; #Puffern abschalten, Hilfreich fuer PEARL WARNINGS Search +#$| = 1; #Puffern abschalten, Hilfreich fuer PEARL WARNINGS Search -#use POSIX qw( floor); # can be removed #use Math::Round qw(); use constant { - SDUINO_VERSION => "v3.4.4", - SDUINO_INIT_WAIT_XQ => 1.5, # wait disable device - SDUINO_INIT_WAIT => 2, - SDUINO_INIT_MAXRETRY => 3, - SDUINO_CMD_TIMEOUT => 10, - SDUINO_KEEPALIVE_TIMEOUT => 60, - SDUINO_KEEPALIVE_MAXRETRY => 3, - SDUINO_WRITEQUEUE_NEXT => 0.3, - SDUINO_WRITEQUEUE_TIMEOUT => 2, + SDUINO_VERSION => '3.5.2', # Datum wird automatisch bei jedem pull request aktualisiert + SDUINO_INIT_WAIT_XQ => 1.5, # wait disable device + SDUINO_INIT_WAIT => 2, + SDUINO_INIT_MAXRETRY => 3, + SDUINO_CMD_TIMEOUT => 10, + SDUINO_KEEPALIVE_TIMEOUT => 60, + SDUINO_KEEPALIVE_MAXRETRY => 3, + SDUINO_WRITEQUEUE_NEXT => 0.3, + SDUINO_WRITEQUEUE_TIMEOUT => 2, - SDUINO_DISPATCH_VERBOSE => 5, # default 5 - SDUINO_MC_DISPATCH_VERBOSE => 5, # wenn kleiner 5, z.B. 3 dann wird vor dem dispatch mit loglevel 3 die ID und rmsg ausgegeben - SDUINO_MC_DISPATCH_LOG_ID => '12.1', # die o.g. Ausgabe erfolgt nur wenn der Wert mit der ID uebereinstimmt - SDUINO_PARSE_DEFAULT_LENGHT_MIN => 8, - SDUINO_GET_CONFIGQUERY_DELAY => 0.75 # delay for cmd to no overwrite a working cmd + SDUINO_DISPATCH_VERBOSE => 5, # default 5 + SDUINO_MC_DISPATCH_VERBOSE => 5, # wenn kleiner 5, z.B. 3 dann wird vor dem dispatch mit loglevel 3 die ID und rmsg ausgegeben + SDUINO_MC_DISPATCH_LOG_ID => '12.1', # die o.g. Ausgabe erfolgt nur wenn der Wert mit der ID uebereinstimmt + SDUINO_PARSE_DEFAULT_LENGHT_MIN => 8, + SDUINO_GET_CONFIGQUERY_DELAY => 0.75 # delay for cmd to no overwrite a working cmd }; #sub SIGNALduino_Attr(@); -sub SIGNALduino_HandleWriteQueue($); +#sub SIGNALduino_HandleWriteQueue($); #sub SIGNALduino_Parse($$$$@); #sub SIGNALduino_Read($); #sub SIGNALduino_Ready($); @@ -63,209 +65,234 @@ sub SIGNALduino_HandleWriteQueue($); #sub SIGNALduino_SimpleWrite(@); #sub SIGNALduino_LoadProtocolHash($); #sub SIGNALduino_Log3($$$); + #my $debug=0; our %modules; our %defs; -my %gets = ( # NameOFCommand => StyleMod for Fhemweb, SubToCall if get is executed, String to send to uC, sub called with response, regex to verify response, - "?" => ['', \&SIGNALduino_Get_FhemWebList ], - "version" => ['noArg', \&SIGNALduino_Get_Command, "V", \&SIGNALduino_CheckVersionResp, 'V\s.*SIGNAL(?:duino|ESP).*(?:\s\d\d:\d\d:\d\d)' ], - "freeram" => ['noArg', \&SIGNALduino_Get_Command, "R", \&SIGNALduino_GetResponseUpdateReading, '^[0-9]+' ] , - "uptime" => ['noArg', \&SIGNALduino_Get_Command, "t", \&SIGNALduino_CheckUptimeResponse, '^[0-9]+' ], - "cmds" => ['noArg', \&SIGNALduino_Get_Command, "?", \&SIGNALduino_CheckCmdsResponse, '.*' ], - "ping" => ['noArg', \&SIGNALduino_Get_Command, "P", \&SIGNALduino_GetResponseUpdateReading, '^OK$' ], - "config" => ['noArg', \&SIGNALduino_Get_Command, "CG", \&SIGNALduino_GetResponseUpdateReading, '^MS.*MU.*MC.*' ], - "ccconf" => ['noArg', \&SIGNALduino_Get_Command, "C0DnF", \&SIGNALduino_CheckccConfResponse, 'C0Dn11=[A-F0-9a-f]+'], - "ccreg" => ['textFieldNL', \&SIGNALduino_Get_Command_CCReg,"C", \&SIGNALduino_CheckCcregResponse, '^(?:C[A-Fa-f0-9]{2}\s=\s[0-9A-Fa-f]+$|ccreg 00:)'], - "ccpatable" => ['noArg', \&SIGNALduino_Get_Command, "C3E", \&SIGNALduino_CheckccPatableResponse, '^C3E\s=\s.*'], - "raw" => ['textFieldNL', \&SIGNALduino_Get_Raw ], - "availableFirmware" => ['noArg', \&SIGNALduino_Get_availableFirmware ] +my %gets = ( # NameOFCommand => StyleMod for Fhemweb, SubToCall if get is executed, String to send to uC, sub called with response, regex to verify response, + '?' => ['', \&SIGNALduino_Get_FhemWebList ], + 'version' => ['noArg', \&SIGNALduino_Get_Command, "V", \&SIGNALduino_CheckVersionResp, 'V\s.*SIGNAL(?:duino|ESP|STM).*(?:\s\d\d:\d\d:\d\d)' ], + 'freeram' => ['noArg', \&SIGNALduino_Get_Command, "R", \&SIGNALduino_GetResponseUpdateReading, '^[0-9]+' ] , + 'uptime' => ['noArg', \&SIGNALduino_Get_Command, "t", \&SIGNALduino_CheckUptimeResponse, '^[0-9]+' ], + 'cmds' => ['noArg', \&SIGNALduino_Get_Command, "?", \&SIGNALduino_CheckCmdsResponse, '.*' ], + 'ping' => ['noArg', \&SIGNALduino_Get_Command, "P", \&SIGNALduino_GetResponseUpdateReading, '^OK$' ], + 'config' => ['noArg', \&SIGNALduino_Get_Command, "CG", \&SIGNALduino_GetResponseUpdateReading, '^MS.*MU.*MC.*' ], + 'ccconf' => ['noArg', \&SIGNALduino_Get_Command, "C0DnF", \&SIGNALduino_CheckccConfResponse, 'C0Dn11=[A-F0-9a-f]+'], + 'ccreg' => ['textFieldNL', \&SIGNALduino_Get_Command_CCReg,"C", \&SIGNALduino_CheckCcregResponse, '^(?:C[A-Fa-f0-9]{2}\s=\s[0-9A-Fa-f]+$|ccreg 00:)'], + 'ccpatable' => ['noArg', \&SIGNALduino_Get_Command, "C3E", \&SIGNALduino_CheckccPatableResponse, '^C3E\s=\s.*'], + 'rawmsg' => ['textFieldNL', \&SIGNALduino_Get_RawMsg ], + 'availableFirmware' => ['noArg', \&SIGNALduino_Get_availableFirmware ] ); -my %ProtocolListSIGNALduino; my %patable = ( - "433" => + '433' => { - "-30_dBm" => '12', - "-20_dBm" => '0E', - "-15_dBm" => '1D', - "-10_dBm" => '34', - "-5_dBm" => '68', - "0_dBm" => '60', - "5_dBm" => '84', - "7_dBm" => 'C8', - "10_dBm" => 'C0', + '-30_dBm' => '12', + '-20_dBm' => '0E', + '-15_dBm' => '1D', + '-10_dBm' => '34', + '-5_dBm' => '68', + '0_dBm' => '60', + '5_dBm' => '84', + '7_dBm' => 'C8', + '10_dBm' => 'C0', }, - "868" => + '868' => { - "-30_dBm" => '03', - "-20_dBm" => '0F', - "-15_dBm" => '1E', - "-10_dBm" => '27', - "-5_dBm" => '67', - "0_dBm" => '50', - "5_dBm" => '81', - "7_dBm" => 'CB', - "10_dBm" => 'C2', + '-30_dBm' => '03', + '-20_dBm' => '0F', + '-15_dBm' => '1E', + '-10_dBm' => '27', + '-5_dBm' => '67', + '0_dBm' => '50', + '5_dBm' => '81', + '7_dBm' => 'CB', + '10_dBm' => 'C2', }, ); -my @ampllist = (24, 27, 30, 33, 36, 38, 40, 42); # rAmpl(dB) +my @ampllist = (24, 27, 30, 33, 36, 38, 40, 42); # rAmpl(dB) my %sets = ( - #Command name [FhemWeb Argument type, code to run] - "?" => ['', \&SIGNALduino_Set_FhemWebList ], - "raw" => ['textFieldNL',\&SIGNALduino_Set_raw ], - "flash" => ['textFieldNL', \&SIGNALduino_Set_flash ], - "reset" => ['noArg', \&SIGNALduino_Set_reset ], - "close" => ['noArg', \&SIGNALduino_Set_close ], - "enableMessagetype" => ['syncedMS,unsyncedMU,manchesterMC', \&SIGNALduino_Set_MessageType ], - "disableMessagetype" => ['syncedMS,unsyncedMU,manchesterMC', \&SIGNALduino_Set_MessageType ], - "sendMsg" => ['textFieldNL',\&SIGNALduino_Set_sendMsg ], - "cc1101_freq" => ['textFieldNL', \&cc1101::SetFreq ], - "cc1101_bWidth" => ['58,68,81,102,116,135,162,203,232,270,325,406,464,541,650,812', \&SIGNALduino_Set_bWidth ], - "cc1101_rAmpl" => ['24,27,30,33,36,38,40,42', \&cc1101::setrAmpl ], - "cc1101_sens" => ['4,8,12,16', \&cc1101::SetSens ], - "cc1101_patable" => ['-30_dBm,-20_dBm,-15_dBm,-10_dBm,-5_dBm,0_dBm,5_dBm,7_dBm,10_dBm', \&cc1101::SetPatable ], - "cc1101_reg" => [ 'textFieldNL', \&cc1101::SetRegisters ], + #Command name [FhemWeb Argument type, code to run] + '?' => ['', \&SIGNALduino_Set_FhemWebList ], + 'raw' => ['textFieldNL',\&SIGNALduino_Set_raw ], + 'flash' => ['textFieldNL', \&SIGNALduino_Set_flash ], + 'reset' => ['noArg', \&SIGNALduino_Set_reset ], + 'close' => ['noArg', \&SIGNALduino_Set_close ], + 'enableMessagetype' => ['syncedMS,unsyncedMU,manchesterMC', \&SIGNALduino_Set_MessageType ], + 'disableMessagetype' => ['syncedMS,unsyncedMU,manchesterMC', \&SIGNALduino_Set_MessageType ], + 'sendMsg' => ['textFieldNL',\&SIGNALduino_Set_sendMsg ], + 'cc1101_bWidth' => ['58,68,81,102,116,135,162,203,232,270,325,406,464,541,650,812', \&SIGNALduino_Set_bWidth ], + 'cc1101_dataRate' => ['textFieldNL', \&cc1101::SetDataRate ], + 'cc1101_deviatn' => ['textFieldNL', \&cc1101::SetDeviatn ], + 'cc1101_freq' => ['textFieldNL', \&cc1101::SetFreq ], + 'cc1101_patable' => ['-30_dBm,-20_dBm,-15_dBm,-10_dBm,-5_dBm,0_dBm,5_dBm,7_dBm,10_dBm', \&cc1101::SetPatable ], + 'cc1101_rAmpl' => ['24,27,30,33,36,38,40,42', \&cc1101::setrAmpl ], + 'cc1101_reg' => ['textFieldNL', \&cc1101::SetRegisters ], + 'cc1101_reg_user' => ['noArg', \&cc1101::SetRegistersUser ], + 'cc1101_sens' => ['4,8,12,16', \&cc1101::SetSens ], + 'LaCrossePairForSec' => ['textFieldNL', \&SIGNALduino_Set_LaCrossePairForSec ], ); ## Supported config CC1101 ## -my @modformat = ("2-FSK","GFSK","-","ASK/OOK","4-FSK","-","-","MSK"); -my @syncmod = ("No preamble/sync","15/16 sync word bits detected","16/16 sync word bits detected","30/32 sync word bits detected", - "No preamble/sync, carrier-sense above threshold, carrier-sense above threshold", "15/16 + carrier-sense above threshold", "16/16 + carrier-sense above threshold", "30/32 + carrier-sense above threshold"); +my @modformat = ('2-FSK','GFSK','-','ASK/OOK','4-FSK','-','-','MSK'); +my @syncmod = ( 'No preamble/sync','15/16 sync word bits detected','16/16 sync word bits detected','30/32 sync word bits detected', + 'No preamble/sync, carrier-sense above threshold, carrier-sense above threshold', '15/16 + carrier-sense above threshold', + '16/16 + carrier-sense above threshold', '30/32 + carrier-sense above threshold' + ); -my %cc1101_register = ( # for get ccreg 99 and set cc1101_reg - "00" => 'IOCFG2 ', # ! the values with spaces for output get ccreg 99 ! - "01" => 'IOCFG1 ', - "02" => 'IOCFG0 ', - "03" => 'FIFOTHR ', - "04" => 'SYNC1 ', - "05" => 'SYNC0 ', - "06" => 'PKTLEN ', - "07" => 'PKTCTRL1', - "08" => 'PKTCTRL0', - "09" => 'ADDR ', - "0A" => 'CHANNR ', - "0B" => 'FSCTRL1 ', - "0C" => 'FSCTRL0 ', - "0D" => 'FREQ2 ', - "0E" => 'FREQ1 ', - "0F" => 'FREQ0 ', - "10" => 'MDMCFG4 ', - "11" => 'MDMCFG3 ', - "12" => 'MDMCFG2 ', - "13" => 'MDMCFG1 ', - "14" => 'MDMCFG0 ', - "15" => 'DEVIATN ', - "16" => 'MCSM2 ', - "17" => 'MCSM1 ', - "18" => 'MCSM0 ', - "19" => 'FOCCFG ', - "1A" => 'BSCFG ', - "1B" => 'AGCCTRL2', - "1C" => 'AGCCTRL1', - "1D" => 'AGCCTRL0', - "1E" => 'WOREVT1 ', - "1F" => 'WOREVT0 ', - "20" => 'WORCTRL ', - "21" => 'FREND1 ', - "22" => 'FREND0 ', - "23" => 'FSCAL3 ', - "24" => 'FSCAL2 ', - "25" => 'FSCAL1 ', - "26" => 'FSCAL0 ', - "27" => 'RCCTRL1 ', - "28" => 'RCCTRL0 ', - "29" => 'FSTEST ', - "2A" => 'PTEST ', - "2B" => 'AGCTEST ', - "2C" => 'TEST2 ', - "2D" => 'TEST1 ', - "2E" => 'TEST0 ', +my %cc1101_register = ( # for get ccreg 99 and set cc1101_reg + '00' => 'IOCFG2 - 0x0D', # ! the values with spaces for output get ccreg 99 ! + '01' => 'IOCFG1 - 0x2E', + '02' => 'IOCFG0 - 0x2D', + '03' => 'FIFOTHR - 0x47', + '04' => 'SYNC1 - 0xD3', + '05' => 'SYNC0 - 0x91', + '06' => 'PKTLEN - 0x3D', + '07' => 'PKTCTRL1 - 0x04', + '08' => 'PKTCTRL0 - 0x32', + '09' => 'ADDR - 0x00', + '0A' => 'CHANNR - 0x00', + '0B' => 'FSCTRL1 - 0x06', + '0C' => 'FSCTRL0 - 0x00', + '0D' => 'FREQ2 - 0x10', + '0E' => 'FREQ1 - 0xB0', + '0F' => 'FREQ0 - 0x71', + '10' => 'MDMCFG4 - 0x57', + '11' => 'MDMCFG3 - 0xC4', + '12' => 'MDMCFG2 - 0x30', + '13' => 'MDMCFG1 - 0x23', + '14' => 'MDMCFG0 - 0xB9', + '15' => 'DEVIATN - 0x00', + '16' => 'MCSM2 - 0x07', + '17' => 'MCSM1 - 0x00', + '18' => 'MCSM0 - 0x18', + '19' => 'FOCCFG - 0x14', + '1A' => 'BSCFG - 0x6C', + '1B' => 'AGCCTRL2 - 0x07', + '1C' => 'AGCCTRL1 - 0x00', + '1D' => 'AGCCTRL0 - 0x91', + '1E' => 'WOREVT1 - 0x87', + '1F' => 'WOREVT0 - 0x6B', + '20' => 'WORCTRL - 0xF8', + '21' => 'FREND1 - 0xB6', + '22' => 'FREND0 - 0x11', + '23' => 'FSCAL3 - 0xE9', + '24' => 'FSCAL2 - 0x2A', + '25' => 'FSCAL1 - 0x00', + '26' => 'FSCAL0 - 0x1F', + '27' => 'RCCTRL1 - 0x41', + '28' => 'RCCTRL0 - 0x00', + '29' => 'FSTEST - N/A ', + '2A' => 'PTEST - N/A ', + '2B' => 'AGCTEST - N/A ', + '2C' => 'TEST2 - N/A ', + '2D' => 'TEST1 - N/A ', + '2E' => 'TEST0 - N/A ', ); ## Supported Clients per default -my $clientsSIGNALduino = ":IT:" - ."CUL_TCM97001:" - ."SD_RSL:" - ."OREGON:" - ."CUL_TX:" - ."SD_AS:" - ."Hideki:" - ."SD_WS07:" - ."SD_WS09:" - ." :" # Zeilenumbruch - ."SD_WS:" - ."RFXX10REC:" - ."Dooya:" - ."SOMFY:" - ."SD_BELL:" ## bells - ."SD_UT:" ## universal - more devices with different protocols - ."SD_WS_Maverick:" - ."FLAMINGO:" - ."CUL_WS:" - ."Revolt:" - ." :" # Zeilenumbruch - ."FS10:" - ."CUL_FHTTK:" - ."Siro:" - ."FHT:" - ."FS20:" - ."CUL_EM:" - ."Fernotron:" - ."SD_Keeloq:" - ."SD_GT:" - ."SIGNALduino_un:" - ; +my $clientsSIGNALduino = ':CUL_EM:' + .'CUL_FHTTK:' + .'CUL_TCM97001:' + .'CUL_TX:' + .'CUL_WS:' + .'Dooya:' + .'FHT:' + .'FLAMINGO:' + .'FS10:' + .'FS20:' + .' :' # Zeilenumbruch + .'Fernotron:' + .'Hideki:' + .'IT:' + .'KOPP_FC:' + .'LaCrosse:' + .'OREGON:' + .'PCA301:' + .'RFXX10REC:' + .'Revolt:' + .'SD_AS:' + .'SD_Rojaflex:' + .' :' # Zeilenumbruch + .'SD_BELL:' + .'SD_GT:' + .'SD_Keeloq:' + .'SD_RSL:' + .'SD_UT:' + .'SD_WS07:' + .'SD_WS09:' + .'SD_WS:' + .'SD_WS_Maverick:' + .'SOMFY:' + .' :' # Zeilenumbruch + .'Siro:' + .'SIGNALduino_un:' + ; ## default regex match List for dispatching message to logical modules, can be updated during runtime because it is referenced my %matchListSIGNALduino = ( - "1:IT" => "^i......", # Intertechno Format - "2:CUL_TCM97001" => "^s[A-Fa-f0-9]+", # Any hex string beginning with s - "3:SD_RSL" => "^P1#[A-Fa-f0-9]{8}", - "5:CUL_TX" => "^TX..........", # Need TX to avoid FHTTK - "6:SD_AS" => "^P2#[A-Fa-f0-9]{7,8}", # Arduino based Sensors, should not be default - "4:OREGON" => "^(3[8-9A-F]|[4-6][0-9A-F]|7[0-8]).*", - "7:Hideki" => "^P12#75[A-F0-9]+", - "9:CUL_FHTTK" => "^T[A-F0-9]{8}", - "10:SD_WS07" => "^P7#[A-Fa-f0-9]{6}[AFaf][A-Fa-f0-9]{2,3}", - "11:SD_WS09" => "^P9#F[A-Fa-f0-9]+", - "12:SD_WS" => '^W\d+x{0,1}#.*', - "13:RFXX10REC" => '^(20|29)[A-Fa-f0-9]+', - "14:Dooya" => '^P16#[A-Fa-f0-9]+', - "15:SOMFY" => '^Ys[0-9A-F]+', - "16:SD_WS_Maverick" => '^P47#[A-Fa-f0-9]+', - "17:SD_UT" => '^P(?:14|20|26|29|30|34|46|68|69|76|81|83|86|90|91|91.1|92|93|95|97|99|104)#.*', # universal - more devices with different protocols - "18:FLAMINGO" => '^P13\.?1?#[A-Fa-f0-9]+', # Flamingo Smoke - "19:CUL_WS" => '^K[A-Fa-f0-9]{5,}', - "20:Revolt" => '^r[A-Fa-f0-9]{22}', - "21:FS10" => '^P61#[A-F0-9]+', - "22:Siro" => '^P72#[A-Fa-f0-9]+', - "23:FHT" => "^81..(04|09|0d)..(0909a001|83098301|c409c401)..", - "24:FS20" => "^81..(04|0c)..0101a001", - "25:CUL_EM" => "^E0.................", - "26:Fernotron" => '^P82#.*', - "27:SD_BELL" => '^P(?:15|32|41|42|57|79|96|98)#.*', - "28:SD_Keeloq" => '^P(?:87|88)#.*', - "29:SD_GT" => '^P49#[A-Fa-f0-9]+', - "X:SIGNALduino_un" => '^[u]\d+#.*', + '1:IT' => '^i......', + '2:CUL_TCM97001' => '^s[A-Fa-f0-9]+', + '3:SD_RSL' => '^P1#[A-Fa-f0-9]{8}', + '5:CUL_TX' => '^TX..........', # Need TX to avoid FHTTK + '6:SD_AS' => '^P2#[A-Fa-f0-9]{7,8}', # Arduino based Sensors, should not be default + '4:OREGON' => '^(3[8-9A-F]|[4-6][0-9A-F]|7[0-8]).*', + '7:Hideki' => '^P12#75[A-F0-9]+', + '9:CUL_FHTTK' => '^T[A-F0-9]{8}', + '10:SD_WS07' => '^P7#[A-Fa-f0-9]{6}[AFaf][A-Fa-f0-9]{2,3}', + '11:SD_WS09' => '^P9#F[A-Fa-f0-9]+', + '12:SD_WS' => '^W\d+x{0,1}#.*', + '13:RFXX10REC' => '^(20|29)[A-Fa-f0-9]+', + '14:Dooya' => '^P16#[A-Fa-f0-9]+', + '15:SOMFY' => '^Ys[0-9A-F]+', + '16:SD_WS_Maverick' => '^P47#[A-Fa-f0-9]+', + '17:SD_UT' => '^P(?:14|20|24|26|29|30|34|46|56|68|69|76|78|81|83|86|90|91|91.1|92|93|95|97|99|104|105|114)#.*', # universal - more devices with different protocols + '18:FLAMINGO' => '^P13\.?1?#[A-Fa-f0-9]+', # Flamingo Smoke + '19:CUL_WS' => '^K[A-Fa-f0-9]{5,}', + '20:Revolt' => '^r[A-Fa-f0-9]{22}', + '21:FS10' => '^P61#[A-F0-9]+', + '22:Siro' => '^P72#[A-Fa-f0-9]+', + '23:FHT' => '^81..(04|09|0d)..(0909a001|83098301|c409c401)..', + '24:FS20' => '^81..(04|0c)..0101a001', + '25:CUL_EM' => '^E0.................', + '26:Fernotron' => '^P82#.*', + '27:SD_BELL' => '^P(?:15|32|41|42|57|79|96|98|112)#.*', + '28:SD_Keeloq' => '^P(?:87|88)#.*', + '29:SD_GT' => '^P49#[A-Fa-f0-9]+', + '30:LaCrosse' => '^(\\S+\\s+9 |OK\\sWS\\s)', + '31:KOPP_FC' => '^kr\w{18,}', + '32:PCA301' => '^\\S+\\s+24', + '33:SD_Rojaflex' => '^P109#[A-Fa-f0-9]+', + 'X:SIGNALduino_un' => '^[u]\d+#.*', ); - - - my %symbol_map = (one => 1 , zero =>0 ,sync => '', float=> 'F', 'start' => ''); +## rfmode for attrib & supported rfmodes +my @rfmode; +my $Protocols = new lib::SD_Protocols(); + ############################# package main -sub SIGNALduino_Initialize($) { +sub SIGNALduino_Initialize { my ($hash) = @_; + my $dev = ''; + $dev = ',1' if (index(SDUINO_VERSION, 'dev') >= 0); - my $dev = ""; - if (index(SDUINO_VERSION, "dev") >= 0) { - $dev = ",1"; + $Protocols->registerLogCallback(SIGNALduino_createLogCallback($hash)); + my $error = $Protocols->LoadHash(qq[$attr{global}{modpath}/FHEM/lib/SD_ProtocolData.pm]); + if (defined($error)) { + Log3 'SIGNALduino', 1, qq[Error loading Protocol Hash. Module is in inoperable mode error message:($error)]; + } else { + $hash->{protocolObject} = $Protocols; + @rfmode = ('SlowRF'); + push @rfmode, map { $Protocols->checkProperty($_, 'rfmode') } $Protocols->getKeys('rfmode'); + @rfmode = sort @rfmode; + Log3 'SIGNALduino', 4, qq[SIGNALduino_Initialize: rfmode list: @rfmode]; } # Provider @@ -274,95 +301,83 @@ sub SIGNALduino_Initialize($) { $hash->{ReadyFn} = \&SIGNALduino_Ready; # Normal devices - $hash->{DefFn} = \&SIGNALduino_Define; - $hash->{FingerprintFn} = \&SIGNALduino_FingerprintFn; - $hash->{UndefFn} = \&SIGNALduino_Undef; - $hash->{GetFn} = \&SIGNALduino_Get; - $hash->{SetFn} = \&SIGNALduino_Set; - $hash->{AttrFn} = \&SIGNALduino_Attr; - $hash->{AttrList} = - "Clients MatchList do_not_notify:1,0 dummy:1,0" - ." hexFile" - ." initCommands" - ." flashCommand" - ." hardware:ESP8266,ESP8266cc1101,ESP32,nano328,nanoCC1101,miniculCC1101,promini,radinoCC1101" - ." updateChannelFW:stable,testing" - ." debug:0$dev" - ." longids" - ." minsecs" - ." whitelist_IDs" - ." blacklist_IDs" - ." WS09_CRCAUS:0,1,2" - ." addvaltrigger" - ." rawmsgEvent:1,0" - ." cc1101_frequency" - ." doubleMsgCheck_IDs" - ." suppressDeviceRawmsg:1,0" - ." development:0$dev" - ." noMsgVerbose:0,1,2,3,4,5" - ." eventlogging:0,1" - ." maxMuMsgRepeat" - ." $readingFnAttributes"; + $hash->{DefFn} = \&SIGNALduino_Define; + $hash->{FingerprintFn} = \&SIGNALduino_FingerprintFn; + $hash->{UndefFn} = \&SIGNALduino_Undef; + $hash->{GetFn} = \&SIGNALduino_Get; + $hash->{SetFn} = \&SIGNALduino_Set; + $hash->{AttrFn} = \&SIGNALduino_Attr; + $hash->{AttrList} = + 'Clients MatchList do_not_notify:1,0 dummy:1,0' + .' WS09_CRCAUS:0,1,2' + .' addvaltrigger' + .' blacklist_IDs' + .' cc1101_frequency' + .' cc1101_reg_user' + ." debug:0$dev" + ." development:0$dev" + .' doubleMsgCheck_IDs' + .' eventlogging:0,1' + .' flashCommand' + .' hardware:ESP32,ESP32cc1101,ESP8266,ESP8266cc1101,MAPLEMINI_F103CB,MAPLEMINI_F103CBcc1101,nano328,nanoCC1101,miniculCC1101,promini,radinoCC1101' + .' hexFile' + .' initCommands' + .' longids' + .' maxMuMsgRepeat' + .' minsecs' + .' noMsgVerbose:0,1,2,3,4,5' + .' rawmsgEvent:1,0' + .' rfmode:'.join(',', @rfmode) + .' suppressDeviceRawmsg:1,0' + .' updateChannelFW:stable,testing' + .' whitelist_IDs' + ." $readingFnAttributes"; - $hash->{ShutdownFn} = "SIGNALduino_Shutdown"; - $hash->{FW_detailFn} = "SIGNALduino_FW_Detail"; - $hash->{FW_deviceOverview} = 1; + $hash->{ShutdownFn} = 'SIGNALduino_Shutdown'; + $hash->{FW_detailFn} = 'SIGNALduino_FW_Detail'; + $hash->{FW_deviceOverview} = 1; $hash->{msIdList} = (); $hash->{muIdList} = (); $hash->{mcIdList} = (); + $hash->{mnIdList} = (); #our $attr; - - %ProtocolListSIGNALduino = SIGNALduino_LoadProtocolHash("$attr{global}{modpath}/FHEM/lib/SD_ProtocolData.pm"); - - if (exists($ProtocolListSIGNALduino{error}) ) { - Log3 "SIGNALduino", 1, "Error loading Protocol Hash. Module is in inoperable mode error message:($ProtocolListSIGNALduino{error})"; - delete($ProtocolListSIGNALduino{error}); - return ; - } } + # # Predeclare Variables from other modules may be loaded later from fhem # our $FW_wname; our $FW_ME; - -# -# Predeclare Variables from other modules may be loaded later from fhem -# our $FW_CSRF; our $FW_detail; -# Load Protocol hash from File into a hash. -# First Parameter is for filename (full or relativ path) to be loaded -# -# returns a hash with protocols if loaded without error. Returns a hash with {eror} => errormessage if there was an error -############################# package main -sub SIGNALduino_LoadProtocolHash($) { - my $ret= lib::SD_Protocols::LoadHash($_[0]); - return %$ret; -} -############################# package main -sub SIGNALduino_FingerprintFn($$) { +############################# package main, test exists +sub SIGNALduino_FingerprintFn { my ($name, $msg) = @_; + # Das FingerprintFn() darf nur im physikalischen oder logischem Modul aktiv sein. + # Wenn FingerprintFn in beiden aktiv ist, funktioniert der Dispatch nicht richtig. + # Da FingerprintFn bei den LaCrosse Modulen verwendet wird, darf es im 00_Signalduino Modul nicht aktiv sein. + return if (substr($msg,0,2) eq 'OK'); + # Store only the "relevant" part, as the Signalduino won't compute the checksum #$msg = substr($msg, 8) if($msg =~ m/^81/ && length($msg) > 8); - - return ("", $msg); + return ('', $msg); } + ############################# package main -sub SIGNALduino_Define($$) { +sub SIGNALduino_Define { my ($hash, $def) = @_; - my @a = split("[ \t][ \t]*", $def); + my @a =split m{\s+}xms, $def; if(@a != 3) { - my $msg = "Define, wrong syntax: define SIGNALduino {none | devicename[\@baudrate] | devicename\@directio | hostname:port}"; + my $msg = 'Define, wrong syntax: define SIGNALduino {none | devicename[\@baudrate] | devicename\@directio | hostname:port}'; Log3 undef, 2, $msg; return $msg; } @@ -370,74 +385,81 @@ sub SIGNALduino_Define($$) { DevIo_CloseDev($hash); my $name = $a[0]; - if (!exists &round) { - Log3 $name, 1, "$name: Define, Signalduino can't be activated (sub round not found). Please update Fhem via update command"; - return ; + Log3 $name, 1, "$name: Define, Signalduino can't be activated (sub round not found). Please update Fhem via update command"; + return ; } my $dev = $a[2]; #Debug "dev: $dev" if ($debug); - #my $hardware=AttrVal($name,"hardware","nano"); + #my $hardware=AttrVal($name,'hardware','nano'); #Debug "hardware: $hardware" if ($debug); - if($dev eq 'none') { Log3 $name, 1, "$name: Define, device is none, commands will be echoed only"; $attr{$name}{dummy} = 1; - #return ; + } elsif ($dev !~ m/\@/) { + if ( ($dev =~ m~^(?:/[^/ ]*)+?$~xms || $dev =~ m~^COM\d$~xms) ) # bei einer IP oder hostname wird kein \@57600 angehaengt + { + $dev .= '@57600' + } elsif ($dev !~ /@\d+$/ && ($dev !~ /^ + (?: (?:[a-z0-9-]+(?:\.[a-z]{2,6})?)*|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3} + (?:25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])) + : (?:6553[0-5]|655[0-2]\d|65[0-4]\d{2}|6[0-4]\d{3}|[1-5]\d{4}|[1-9]\d{0,3})$/xmsi) ) { + my $msg = 'Define, wrong hostname/port syntax: define SIGNALduino {none | devicename[\@baudrate] | devicename\@directio | hostname:port}'; + Log3 undef, 2, $msg; + return $msg; + } } - - - if ($dev ne 'none' && $dev =~ m/[a-zA-Z]/ && $dev !~ m/\@/) { # bei einer IP wird kein \@57600 angehaengt - $dev .= "\@57600"; - } - - #$hash->{CMDS} = ""; - $hash->{Clients} = $clientsSIGNALduino; - $hash->{MatchList} = \%matchListSIGNALduino; + + #$hash->{CMDS} = ''; + $hash->{Clients} = $clientsSIGNALduino; + $hash->{MatchList} = \%matchListSIGNALduino; $hash->{DeviceName} = $dev; - $hash->{logMethod} = \&main::Log3; + $hash->{logMethod} = \&main::Log3; my $ret=undef; + $Protocols->registerLogCallback(SIGNALduino_createLogCallback($hash)); + $hash->{protocolObject} = $Protocols; - InternalTimer(gettimeofday(), \&SIGNALduino_IdList,"sduino_IdList:$name",0); # verzoegern bis alle Attribute eingelesen sind + InternalTimer(gettimeofday(), \&SIGNALduino_IdList,"sduino_IdList:$name",0); # verzoegern bis alle Attribute eingelesen sind if($dev ne 'none') { $ret = DevIo_OpenDev($hash, 0, \&SIGNALduino_DoInit, \&SIGNALduino_Connect); } else { - $hash->{DevState} = 'initialized'; - readingsSingleUpdate($hash, 'state', 'opened', 1); + $hash->{DevState} = 'initialized'; + readingsSingleUpdate($hash, 'state', 'opened', 1); } - $hash->{DMSG}='nothing'; - $hash->{LASTDMSG} = 'nothing'; - $hash->{LASTDMSGID} = 'nothing'; - $hash->{TIME}=time(); - $hash->{versionmodul} = SDUINO_VERSION; - $hash->{versionProtocols} = lib::SD_Protocols::getProtocolVersion(); - #notifyRegexpChanged($hash,"^$name$:^opened\$"); # Auf das Event opened der eigenen Definition reagieren - #notifyRegexpChanged($hash,"sduino:opened"); # Auf das Event opened der eigenen Definition reagieren - #$hash->{NOTIFYDEV}="$name"; - #Log3 $name, 3, "$name: Define, Firmwareversion: ".$hash->{READINGS}{version}{VAL} if ($hash->{READINGS}{version}{VAL}); + $hash->{DMSG} = 'nothing'; + $hash->{LASTDMSG} = 'nothing'; + $hash->{LASTDMSGID} = 'nothing'; + $hash->{TIME} = time(); + $hash->{versionmodul} = SDUINO_VERSION; + $hash->{versionProtocols} = $hash->{protocolObject}->getProtocolVersion(); + + if (!defined($hash->{versionProtocols})) { + Log3 $name, 1, qq[$name: Error loading Protocol Hash! SIGNALduino is in inoperable mode!]; + return ; + } return $ret; } ############################# package main -sub SIGNALduino_Connect($$) { - my ($hash, $err) = @_; +sub SIGNALduino_Connect { + my ($hash, $err) = @_; - # damit wird die err-msg nur einmal ausgegeben - if (!defined($hash->{disConnFlag}) && $err) { - $hash->{logMethod}->($hash->{NAME}, 3, "$hash->{NAME}: Connect, ${err}"); - $hash->{disConnFlag} = 1; - } + # damit wird die err-msg nur einmal ausgegeben + if (!defined($hash->{disConnFlag}) && $err) { + $hash->{logMethod}->($hash->{NAME}, 3, "$hash->{NAME}: Connect, ${err}"); + $hash->{disConnFlag} = 1; + } } ############################# package main -sub SIGNALduino_Undef($$) { +sub SIGNALduino_Undef { my ($hash, $arg) = @_; my $name = $hash->{NAME}; @@ -460,953 +482,1077 @@ sub SIGNALduino_Undef($$) { } ############################# package main -sub SIGNALduino_Shutdown($) { +sub SIGNALduino_Shutdown { my ($hash) = @_; #DevIo_SimpleWrite($hash, "XQ\n",2); - SIGNALduino_SimpleWrite($hash, "XQ"); # Switch reception off, it may hang up the SIGNALduino + SIGNALduino_SimpleWrite($hash, 'XQ'); # Switch reception off, it may hang up the SIGNALduino return ; } ############################# package main -sub SIGNALduino_avrdude($) { - my $name = shift; - my $hash = $defs{$name}; +sub SIGNALduino_avrdude { + my $name = shift; + my $hash = $defs{$name}; - if (defined($hash->{helper}{stty_pid})) - { - waitpid( $hash->{helper}{stty_pid}, 0 ); - delete ( $hash->{helper}{stty_pid}); - } + if (defined($hash->{helper}{stty_pid})) + { + waitpid( $hash->{helper}{stty_pid}, 0 ); + delete ( $hash->{helper}{stty_pid}); + } - readingsSingleUpdate($hash,"state","FIRMWARE UPDATE running",1); - $hash->{helper}{avrdudelogs} .= "$name closed\n"; - my $logFile = AttrVal("global", "logdir", "./log/") . "$hash->{TYPE}-Flash.log"; + readingsSingleUpdate($hash,'state','FIRMWARE UPDATE running',1); + $hash->{helper}{avrdudelogs} .= "$name closed\n"; + my $logFile = AttrVal('global', 'logdir', './log/') . "$hash->{TYPE}-Flash.log"; - if (-e $logFile) { - unlink $logFile; + if (-e $logFile) { + unlink $logFile; + } + + $hash->{helper}{avrdudecmd} =~ s/\Q[LOGFILE]\E/$logFile/g; + local $SIG{CHLD} = 'DEFAULT'; + delete($hash->{FLASH_RESULT}) if (exists($hash->{FLASH_RESULT})); + + qx($hash->{helper}{avrdudecmd}); + + if ($? != 0 ) + { + readingsSingleUpdate($hash,'state','FIRMWARE UPDATE with error',1); # processed in tests + $hash->{logMethod}->($name ,3, "$name: avrdude, ERROR: avrdude exited with error $?"); + if (defined $FW_wname) + { + FW_directNotify("FILTER=$name", "FHEMWEB:$FW_wname", "FW_okDialog('ERROR: avrdude exited with error, for details see last flashlog.')", ''); } + $hash->{FLASH_RESULT}='ERROR: avrdude exited with error'; # processed in tests + } else { + $hash->{logMethod}->($name ,3, "$name: avrdude, Firmware update was successfull"); + readingsSingleUpdate($hash,'state','FIRMWARE UPDATE successfull',1); # processed in tests + } - $hash->{helper}{avrdudecmd} =~ s/\Q[LOGFILE]\E/$logFile/g; - local $SIG{CHLD} = 'DEFAULT'; - delete($hash->{FLASH_RESULT}) if (exists($hash->{FLASH_RESULT})); + local $/=undef; + if (-e $logFile) { + open FILE, $logFile; + $hash->{helper}{avrdudelogs} .= "--- AVRDUDE ---------------------------------------------------------------------------------\n"; + $hash->{helper}{avrdudelogs} .= ; + $hash->{helper}{avrdudelogs} .= "--- AVRDUDE ---------------------------------------------------------------------------------\n\n"; + close FILE; + } else { + $hash->{helper}{avrdudelogs} .= "WARNING: avrdude created no log file\n\n"; + readingsSingleUpdate($hash,'state','FIRMWARE UPDATE with error',1); + $hash->{FLASH_RESULT}= 'WARNING: avrdude created no log file'; # processed in tests + } - qx($hash->{helper}{avrdudecmd}); - - - if ($? != 0 ) - { - readingsSingleUpdate($hash,"state","FIRMWARE UPDATE with error",1); # processed in tests - $hash->{logMethod}->($name ,3, "$name: avrdude, ERROR: avrdude exited with error $?"); - FW_directNotify("FILTER=$name", "#FHEMWEB:WEB", "FW_okDialog('ERROR: avrdude exited with error, for details see last flashlog.')", ""); - $hash->{FLASH_RESULT}="ERROR: avrdude exited with error"; # processed in tests - } else { - $hash->{logMethod}->($name ,3, "$name: avrdude, Firmware update was successfull"); - readingsSingleUpdate($hash,"state","FIRMWARE UPDATE successfull",1); # processed in tests - } - - local $/=undef; - if (-e $logFile) { - open FILE, $logFile; - $hash->{helper}{avrdudelogs} .= "--- AVRDUDE ---------------------------------------------------------------------------------\n"; - $hash->{helper}{avrdudelogs} .= ; - $hash->{helper}{avrdudelogs} .= "--- AVRDUDE ---------------------------------------------------------------------------------\n\n"; - close FILE; - } else { - $hash->{helper}{avrdudelogs} .= "WARNING: avrdude created no log file\n\n"; - readingsSingleUpdate($hash,"state","FIRMWARE UPDATE with error",1); - $hash->{FLASH_RESULT}= "WARNING: avrdude created no log file"; # processed in tests - } - - DevIo_OpenDev($hash, 0, \&SIGNALduino_DoInit, \&SIGNALduino_Connect); - $hash->{helper}{avrdudelogs} .= "$name reopen started\n"; - return $hash->{FLASH_RESULT}; + DevIo_OpenDev($hash, 0, \&SIGNALduino_DoInit, \&SIGNALduino_Connect); + $hash->{helper}{avrdudelogs} .= "$name reopen started\n"; + return $hash->{FLASH_RESULT}; } ############################# package main sub SIGNALduino_PrepareFlash { - my ($hash,$hexFile) = @_; + my ($hash,$hexFile) = @_; - my $name=$hash->{NAME}; - my $hardware=AttrVal($name,"hardware",""); - my ($port,undef) = split('@', $hash->{DeviceName}); - my $baudrate= 57600; - my $log = ""; - my $avrdudefound=0; - my $tool_name = "avrdude"; - my $path_separator = ':'; - if ($^O eq 'MSWin32') { - $tool_name .= ".exe"; - $path_separator = ';'; - } - for my $path ( split /$path_separator/, $ENV{PATH} ) { - if ( -f "$path/$tool_name" && -x _ ) { - $avrdudefound=1; - last; - } - } - $hash->{logMethod}->($name, 5, "$name: PrepareFlash, avrdude found = $avrdudefound"); - return "avrdude is not installed. Please provide avrdude tool example: sudo apt-get install avrdude" if($avrdudefound == 0); + my $name=$hash->{NAME}; + my $hardware=AttrVal($name,'hardware',''); + my ($port,undef) = split('@', $hash->{DeviceName}); + my $baudrate= 57600; + my $log = ''; + my $avrdudefound=0; + my $tool_name = 'avrdude'; + my $path_separator = ':'; + if ($^O eq 'MSWin32') { + $tool_name .= '.exe'; + $path_separator = ';'; + } + for my $path ( split /$path_separator/, $ENV{PATH} ) { + if ( -f "$path/$tool_name" && -x _ ) { + $avrdudefound=1; + last; + } + } + $hash->{logMethod}->($name, 5, "$name: PrepareFlash, avrdude found = $avrdudefound"); + return 'avrdude is not installed. Please provide avrdude tool example: sudo apt-get install avrdude' if($avrdudefound == 0); - $log .= "flashing Arduino $name\n"; - $log .= "hex file: $hexFile\n"; - $log .= "port: $port\n"; + $log .= "flashing Arduino $name\n"; + $log .= "hex file: $hexFile\n"; + $log .= "port: $port\n"; - # prepare default Flashcommand - my $defaultflashCommand = ($hardware eq "radinoCC1101" ? "avrdude -c avr109 -b [BAUDRATE] -P [PORT] -p atmega32u4 -vv -D -U flash:w:[HEXFILE] 2>[LOGFILE]" : "avrdude -c arduino -b [BAUDRATE] -P [PORT] -p atmega328p -vv -U flash:w:[HEXFILE] 2>[LOGFILE]"); + # prepare default Flashcommand + my $defaultflashCommand = ($hardware eq 'radinoCC1101' + ? 'avrdude -c avr109 -b [BAUDRATE] -P [PORT] -p atmega32u4 -vv -D -U flash:w:[HEXFILE] 2>[LOGFILE]' + : 'avrdude -c arduino -b [BAUDRATE] -P [PORT] -p atmega328p -vv -U flash:w:[HEXFILE] 2>[LOGFILE]'); - # get User defined Flashcommand - my $flashCommand = AttrVal($name,"flashCommand",$defaultflashCommand); + # get User defined Flashcommand + my $flashCommand = AttrVal($name,'flashCommand',$defaultflashCommand); - if ($defaultflashCommand eq $flashCommand) { - $hash->{logMethod}->($name, 5, "$name: PrepareFlash, standard flashCommand is used to flash."); - } else { - $hash->{logMethod}->($name, 3, "$name: PrepareFlash, custom flashCommand is manual defined! $flashCommand"); - } + if ($defaultflashCommand eq $flashCommand) { + $hash->{logMethod}->($name, 5, "$name: PrepareFlash, standard flashCommand is used to flash."); + } else { + $hash->{logMethod}->($name, 3, "$name: PrepareFlash, custom flashCommand is manual defined! $flashCommand"); + } - DevIo_CloseDev($hash); - if ($hardware eq "radinoCC1101" && $^O eq 'linux') { - $hash->{logMethod}->($name, 3, "$name: PrepareFlash, forcing special reset for $hardware on $port"); - # Mit dem Linux-Kommando 'stty' die Port-Einstellungen setzen - use IPC::Open3; + DevIo_CloseDev($hash); + if ($hardware eq 'radinoCC1101' && $^O eq 'linux') { + $hash->{logMethod}->($name, 3, "$name: PrepareFlash, forcing special reset for $hardware on $port"); + # Mit dem Linux-Kommando 'stty' die Port-Einstellungen setzen + use IPC::Open3; - my($chld_out, $chld_in, $chld_err); - use Symbol 'gensym'; - $chld_err = gensym; - my $pid; - eval { - $pid = open3($chld_in,$chld_out, $chld_err, "stty -F $port ospeed 1200 ispeed 1200"); - close($chld_in); # give end of file to kid, or feed him - }; - if ($@) { - $hash->{helper}{stty_output}=$@; - } else { - my @outlines = <$chld_out>; # read till EOF - my @errlines = <$chld_err>; # XXX: block potential if massive - $hash->{helper}{stty_pid}=$pid; - $hash->{helper}{stty_output} = join(" ",@outlines).join(" ",@errlines); - } - $port =~ s/usb-Unknown_radino/usb-In-Circuit_radino/g; - $hash->{logMethod}->($name ,3, "$name: PrepareFlash, changed usb port to \"$port\" for avrdude flashcommand compatible with radino"); - } - $hash->{helper}{avrdudecmd} = $flashCommand; - $hash->{helper}{avrdudecmd}=~ s/\Q[PORT]\E/$port/g; - $hash->{helper}{avrdudecmd} =~ s/\Q[HEXFILE]\E/$hexFile/g; - if ($hardware =~ "^nano" && $^O eq 'linux') { - $hash->{logMethod}->($name ,5, "$name: PrepareFlash, try additional flash with baudrate 115200 for optiboot"); - $hash->{helper}{avrdudecmd} = $hash->{helper}{avrdudecmd}." || ". $hash->{helper}{avrdudecmd}; - $hash->{helper}{avrdudecmd} =~ s/\Q[BAUDRATE]\E/$baudrate/; - $baudrate=115200; - } - $hash->{helper}{avrdudecmd} =~ s/\Q[BAUDRATE]\E/$baudrate/; - $log .= "command: $hash->{helper}{avrdudecmd}\n\n"; - InternalTimer(gettimeofday() + 1,\&SIGNALduino_avrdude,$name); - $hash->{helper}{avrdudelogs} = $log; - return ; + my($chld_out, $chld_in, $chld_err); + use Symbol 'gensym'; + $chld_err = gensym; + my $pid; + eval { + $pid = open3($chld_in,$chld_out, $chld_err, "stty -F $port ospeed 1200 ispeed 1200"); + close($chld_in); # give end of file to kid, or feed him + }; + if ($@) { + $hash->{helper}{stty_output}=$@; + } else { + my @outlines = <$chld_out>; # read till EOF + my @errlines = <$chld_err>; # XXX: block potential if massive + $hash->{helper}{stty_pid}=$pid; + $hash->{helper}{stty_output} = join(' ',@outlines).join(' ',@errlines); + } + $port =~ s/usb-Unknown_radino/usb-In-Circuit_radino/g; + $hash->{logMethod}->($name ,3, "$name: PrepareFlash, changed usb port to \"$port\" for avrdude flashcommand compatible with radino"); + } + $hash->{helper}{avrdudecmd} = $flashCommand; + $hash->{helper}{avrdudecmd}=~ s/\Q[PORT]\E/$port/g; + $hash->{helper}{avrdudecmd} =~ s/\Q[HEXFILE]\E/$hexFile/g; + if ($hardware =~ '^nano' && $^O eq 'linux') { + $hash->{logMethod}->($name ,5, "$name: PrepareFlash, try additional flash with baudrate 115200 for optiboot"); + $hash->{helper}{avrdudecmd} = $hash->{helper}{avrdudecmd}." || ". $hash->{helper}{avrdudecmd}; + $hash->{helper}{avrdudecmd} =~ s/\Q[BAUDRATE]\E/$baudrate/; + $baudrate=115200; + } + $hash->{helper}{avrdudecmd} =~ s/\Q[BAUDRATE]\E/$baudrate/; + $log .= "command: $hash->{helper}{avrdudecmd}\n\n"; + InternalTimer(gettimeofday() + 1,\&SIGNALduino_avrdude,$name); + $hash->{helper}{avrdudelogs} = $log; + return ; } -#$hash,$name,"sendmsg","P17;R6#".substr($arg,2) -############################# package main +#$hash,$name,'sendmsg','P17;R6#'.substr($arg,2) +############################# package main, test exists +sub SIGNALduino_RemoveLaCrossePair { + my $hash = shift; + delete($hash->{LaCrossePair}); + $hash->{logMethod}->($hash->{NAME}, 4, "$hash->{NAME}: Set_LaCrossePairForSec, time expired, LaCrosse autocreate deactivate"); +} + +############################# package main, test exists sub SIGNALduino_Set($$@) { - my ($hash,$name, @a) = @_; + my ($hash,$name, @a) = @_; - return "\"set SIGNALduino\" needs at least one parameter" if(@a < 1); + return "\"set SIGNALduino\" needs at least one parameter" if(@a < 1); - if (!InternalVal($name,"cc1101_available",0) && $a[0] =~ /^cc1101/) { - return "This command is only available with a cc1101 receiver"; - } - if (!exists($sets{$a[0]})) { - return "Unknown argument $a[0], choose one of supported commands"; - } - my $rcode=undef; - if ( ( (exists($hash->{DevState}) && $hash->{DevState} eq "initialized") || $a[0] eq "?" || $a[0] eq 'reset'|| $a[0] eq 'flash') && ref @{$sets{$a[0]}}[1] eq "CODE") { #Todo uninitalized value - $rcode= @{$sets{$a[0]}}[1]->($hash,@a); - } elsif ($hash->{DevState} ne "initialized") { - $rcode= "$name is not active, may firmware is not supported, please flash or reset"; - } + if (!InternalVal($name,'cc1101_available',0) && $a[0] =~ /^cc1101/) { + return 'This command is only available with a cc1101 receiver'; + } + if (!exists($sets{$a[0]})) { + return "Unknown argument $a[0], choose one of supported commands"; + } + my $rcode=undef; + if ( ( (exists($hash->{DevState}) && $hash->{DevState} eq 'initialized') || $a[0] eq '?' || $a[0] eq 'reset'|| $a[0] eq 'flash') && ref @{$sets{$a[0]}}[1] eq 'CODE') { #Todo uninitalized value + $rcode= @{$sets{$a[0]}}[1]->($hash,@a); + } elsif ($hash->{DevState} ne 'initialized') { + $rcode= "$name is not active, may firmware is not supported, please flash or reset"; + } - return $rcode; # We will exit here, and give an output only, $rcode has some value + return $rcode; # We will exit here, and give an output only, $rcode has some value } ############################# package main sub SIGNALduino_Set_FhemWebList { - my ($hash, @a) = @_; - my @cList = sort map { "$_:@{$sets{$_}}[0]" } grep { - ($_ ne "?" && - ( - ( IsDummy($hash->{NAME}) && $_ =~ m/^(?:close|reset)/ ) || - ( InternalVal($hash->{NAME},"cc1101_available",0) || (!InternalVal($hash->{NAME},"cc1101_available",0) && $_ !~ /^cc/)) && - ( !IsDummy($hash->{NAME}) && (defined(DevIo_IsOpen($hash)) || $_ =~ m/^(?:flash|reset)/) ) - ) - ) - } keys %sets; - map { - my $set_key=$_; - my ($index) = grep { $cList[$_] =~ /^$set_key:/ } (0 .. $#cList-1); - $cList[$index] = "$set_key:".$hash->{additionalSets}{$set_key} if (defined($index)); - } keys %{$hash->{additionalSets}}; - return "Unknown argument $a[0], choose one of " . join(" ", @cList); + my ($hash, @a) = @_; + my @cList = sort map { "$_:@{$sets{$_}}[0]" } grep { + ($_ ne '?' && + ( + ( IsDummy($hash->{NAME}) && $_ =~ m/^(?:close|reset|LaCrossePairForSec)/ ) || + ($_ =~ m/^LaCrossePairForSec/ && ReadingsVal($hash->{NAME},'cc1101_config_ext','') =~ '2-FSK') || + ( (InternalVal($hash->{NAME},'cc1101_available',0 ) || (!InternalVal($hash->{NAME},'cc1101_available',0) && $_ !~ /^cc/ )) && $_ !~ m/^LaCrossePairForSec/) && + ( !IsDummy($hash->{NAME}) && (defined(DevIo_IsOpen($hash)) || $_ =~ m/^(?:flash|reset)/) ) + ) + ) + } keys %sets; + map { + my $set_key=$_; + my ($index) = grep { $cList[$_] =~ /^$set_key:/ } (0 .. $#cList-1); + $cList[$index] = "$set_key:".$hash->{additionalSets}{$set_key} if (defined($index)); + } keys %{$hash->{additionalSets}}; + return "Unknown argument $a[0], choose one of " . join(' ', @cList); } +############################# package main sub SIGNALduino_Set_raw { - my ($hash, @a) = @_; - $hash->{logMethod}->($hash->{NAME}, 4, "$hash->{NAME}: Set_raw, ".join(" ",@a)); - SIGNALduino_AddSendQueue($hash,$a[1]); - return ; + my ($hash, @a) = @_; + $hash->{logMethod}->($hash->{NAME}, 4, "$hash->{NAME}: Set_raw, ".join(' ',@a)); + SIGNALduino_AddSendQueue($hash,$a[1]); + if ($a[1] =~ m/^C[D|E]R/) { # enable/disable data reduction + SIGNALduino_Get_Command($hash,'config'); + } + return ; } ############################# package main sub SIGNALduino_Set_flash { - my ($hash, @a) = @_; - my $name = $hash->{NAME}; - return "Please define your hardware! (attr $name hardware ) " if (AttrVal($name,"hardware","") eq ""); + my ($hash, @a) = @_; + my $name = $hash->{NAME}; + return "Please define your hardware! (attr $name hardware ) " if (AttrVal($name,'hardware','') eq ''); - my @args = @a[1..$#a]; - return "ERROR: argument failed! flash [hexFile|url]" if (!$args[0]); + my @args = @a[1..$#a]; + return 'ERROR: argument failed! flash [hexFile|url]' if (!$args[0]); - my %http_param = ( - timeout => 5, - hash => $hash, # Muss gesetzt werden, damit die Callback funktion wieder $hash hat - method => "GET", # Lesen von Inhalten - header => "User-Agent: perl_fhem\r\nAccept: application/json", # Den Header gemaess abzufragender Daten aendern - ); + my %http_param = ( + timeout => 5, + hash => $hash, # Muss gesetzt werden, damit die Callback funktion wieder $hash hat + method => 'GET', # Lesen von Inhalten + header => "User-Agent: perl_fhem\r\nAccept: application/json", # Den Header gemaess abzufragender Daten aendern + ); - my $hexFile = ""; - if( grep $args[0] eq $_ , split(",",$hash->{additionalSets}{flash}) ) - { - $hash->{logMethod}->($hash, 3, "$name: Set_flash, $args[0] try to fetch github assets for tag $args[0]"); - my $ghurl = "https://api.github.com/repos/RFD-FHEM/SIGNALDuino/releases/tags/$args[0]"; - $hash->{logMethod}->($hash, 3, "$name: Set_flash, $args[0] try to fetch release $ghurl"); + my $hexFile = ''; + if( ( exists $hash->{additionalSets}{flash} ) && ( grep $args[0] eq $_ , split(',',$hash->{additionalSets}{flash}) ) ) + { + $hash->{logMethod}->($hash, 3, "$name: Set_flash, $args[0] try to fetch github assets for tag $args[0]"); + my $ghurl = "https://api.github.com/repos/RFD-FHEM/SIGNALDuino/releases/tags/$args[0]"; + $hash->{logMethod}->($hash, 3, "$name: Set_flash, $args[0] try to fetch release $ghurl"); - $http_param{url} = $ghurl; - $http_param{callback} = \&SIGNALduino_githubParseHttpResponse; # Diese Funktion soll das Ergebnis dieser HTTP Anfrage bearbeiten - $http_param{command} = "getReleaseByTag"; - HttpUtils_NonblockingGet(\%http_param); # Starten der HTTP Abfrage. Es gibt keinen Return-Code. - return; - } - elsif ($args[0] =~ m/^https?:\/\// ) { - $http_param{url} = $args[0]; - $http_param{callback} = \&SIGNALduino_ParseHttpResponse; # Diese Funktion soll das Ergebnis dieser HTTP Anfrage bearbeiten - $http_param{command} = "flash"; - HttpUtils_NonblockingGet(\%http_param); - return; - } else { - $hexFile = $args[0]; + $http_param{url} = $ghurl; + $http_param{callback} = \&SIGNALduino_githubParseHttpResponse; # Diese Funktion soll das Ergebnis dieser HTTP Anfrage bearbeiten + $http_param{command} = 'getReleaseByTag'; + HttpUtils_NonblockingGet(\%http_param); # Starten der HTTP Abfrage. Es gibt keinen Return-Code. + return; + } elsif ($args[0] =~ m/^https?:\/\// ) { + $http_param{url} = $args[0]; + $http_param{callback} = \&SIGNALduino_ParseHttpResponse; # Diese Funktion soll das Ergebnis dieser HTTP Anfrage bearbeiten + $http_param{command} = 'flash'; + HttpUtils_NonblockingGet(\%http_param); + return; + } else { + $hexFile = $args[0]; + } + $hash->{logMethod}->($name, 3, "$name: Set_flash, filename $hexFile provided, trying to flash"); + + # Only for Arduino , not for ESP + my $hardware = AttrVal($name,'hardware',''); + if ($hardware =~ m/(?:nano|mini|radino)/) + { + return SIGNALduino_PrepareFlash($hash,$hexFile); + } else { + if (defined $FW_wname) + { + FW_directNotify("FILTER=$name", "#FHEMWEB:$FW_wname", "FW_okDialog('ERROR:
Sorry, flashing your $hardware is currently not supported.
The file is only downloaded in /opt/fhem/FHEM/firmware.')", ''); } - $hash->{logMethod}->($name, 3, "$name: Set_flash, filename $hexFile provided, trying to flash"); - # Only for Arduino , not for ESP - if (AttrVal($name,"hardware","") =~ m/(?:nano|mini|radino)/) - { - SIGNALduino_PrepareFlash($hash,$hexFile); - } else { - FW_directNotify("FILTER=$name", "#FHEMWEB:WEB", "FW_okDialog('ERROR:
Sorry, flashing your ESP is currently not supported.
The file is only downloaded in /opt/fhem/FHEM/firmware.')", ""); - return "Sorry, Flashing your ESP via Module is currently not supported."; # processed in tests - } + return "Sorry, Flashing your $hardware via Module is currently not supported."; # processed in tests + } } ############################# package main sub SIGNALduino_Set_reset { - my $hash = shift; - delete($hash->{initResetFlag}) if defined($hash->{initResetFlag}); - return SIGNALduino_ResetDevice($hash); + my $hash = shift; + delete($hash->{initResetFlag}) if defined($hash->{initResetFlag}); + return SIGNALduino_ResetDevice($hash); +} + +############################# package main +sub SIGNALduino_Attr_rfmode { + my $hash = shift // carp 'must be called with hash of iodevice as first param'; + my $aVal = shift // return; + + if ( (InternalVal($hash->{NAME},"cc1101_available",0) == 0) && (!IsDummy($hash->{NAME})) ) { + return 'ERROR: This attribute is only available for a receiver with CC1101.'; + } + + ## DevState waitInit is on first start after FHEM restart | initialized is after cc1101 available + if ( ($hash->{DevState} eq 'initialized') && (InternalVal($hash->{NAME},"cc1101_available",0) == 1) ) { + $hash->{logMethod}->($hash->{NAME}, 3, "$hash->{NAME}: Set_rfmode, set to $aVal on DevState $hash->{DevState} (please check activated protocols via 'Display protocollist')"); + + my $rfmode; + if ($aVal ne 'SlowRF') { + if ( scalar( @{$hash->{mnIdList}} ) >= 1 ) { + MNIDLIST: + for my $id (@{$hash->{mnIdList}}) { + $rfmode=$hash->{protocolObject}->checkProperty($id,'rfmode',-1); + + if ($rfmode eq $aVal) { + $hash->{logMethod}->($hash->{NAME}, 4, qq[$hash->{NAME}: Set_rfmode, rfmode found on ID=$id]); + my $register=$hash->{protocolObject}->checkProperty($id,'register', -1); + + if ($register != -1) { + $hash->{logMethod}->($hash->{NAME}, 5, qq[$hash->{NAME}: Set_rfmode, register settings exist on ID=$id ]); + + for my $i (0...scalar(@{$register})-1) { + $hash->{logMethod}->($hash->{NAME}, 5, "$hash->{NAME}: Set_rfmode, write value " . @{$register}[$i]); + my $argcmd = sprintf("W%02X%s",hex(substr(@{$register}[$i],0,2)) + 2,substr(@{$register}[$i],2,2)); + main::SIGNALduino_AddSendQueue($hash,$argcmd); + } + main::SIGNALduino_WriteInit($hash); + last MNIDLIST; # found $rfmode, exit loop + } else { + $hash->{logMethod}->($hash->{NAME}, 1, "$hash->{NAME}: Set_rfmode, set to $aVal (ID $id, no register entry found in protocols)"); + } + } + }; + ## rfmode is always set if it is available / if the set supported is not available, it is always unequal + if ($rfmode ne $aVal) { + $hash->{logMethod}->($hash->{NAME}, 3, "$hash->{NAME}: Set_rfmode, set to $aVal rfmode value not found in protocols"); + return 'ERROR: protocol '.$aVal.' is not activated in \'Display protocollist\''; + }; + } else { + $hash->{logMethod}->($hash->{NAME}, 3, qq[$hash->{NAME}: Set_rfmode, no MN protocols in 'Display protocollist' activated]); + return 'ERROR: no MN protocols activated in \'Display protocollist\''; + } + } else { + SIGNALduino_AddSendQueue($hash,'e'); + $hash->{logMethod}->($hash->{NAME}, 1, "$hash->{NAME}: Set_rfmode, set to $aVal (ASK/OOK mode load default register settings from uC)"); + } + } + + return; } ############################# package main sub SIGNALduino_Set_sendMsg { - my ($hash, @a) = @_; - $hash->{logMethod}->($hash->{NAME}, 5, "$hash->{NAME}: Set_sendMsg, msg=$a[1]"); + my ($hash, @a) = @_; + $hash->{logMethod}->($hash->{NAME}, 5, "$hash->{NAME}: Set_sendMsg, msg=$a[1]"); + return "Error: $hash->{NAME} does not exists" if (!IsDevice($hash->{NAME})); + # Split args in serval variables + my ($protocol,$data,$repeats,$clock,$frequency,$datalength,$dataishex); + my $n=0; + for my $s (split '#', $a[1]) { + my $c = substr($s,0,1); + if ($n == 0 ) { # protocol + $protocol = substr($s,1); + } elsif ($n == 1) { # Data + $data = $s; + if ( substr($s,0,2) eq '0x' ) { $dataishex=1; $data=substr($data,2); } + else { $dataishex=0; } - # Split args in serval variables - my ($protocol,$data,$repeats,$clock,$frequency,$datalength,$dataishex); - my $n=0; - foreach my $s (split "#", $a[1]) { - my $c = substr($s,0,1); - if ($n == 0 ) { # protocol - $protocol = substr($s,1); - } elsif ($n == 1) { # Data - $data = $s; - if ( substr($s,0,2) eq "0x" ) { $dataishex=1; $data=substr($data,2); } - else { $dataishex=0; } + } else { + if ($c eq 'R') { $repeats = substr($s,1); } + elsif ($c eq 'C') { $clock = substr($s,1); } + elsif ($c eq 'F' && InternalVal($hash->{NAME},'cc1101_available',0)) { $frequency = substr($s,1); } + elsif ($c eq 'L') { $datalength = substr($s,1); } + } + $n++; + }; + return "$hash->{NAME}: sendmsg, unknown protocol: $protocol" if (!$hash->{protocolObject}->protocolExists($protocol)); - } else { - if ($c eq 'R') { $repeats = substr($s,1); } - elsif ($c eq 'C') { $clock = substr($s,1); } - elsif ($c eq 'F') { $frequency = substr($s,1); } - elsif ($c eq 'L') { $datalength = substr($s,1); } - } - $n++; - } - return "$hash->{NAME}: sendmsg, unknown protocol: $protocol" if (!exists($ProtocolListSIGNALduino{$protocol})); + $repeats //= 1 ; + if (InternalVal($hash->{NAME},'cc1101_available',0)) + { + my $f=$hash->{protocolObject}->getProperty($protocol,'frequency'); + if ( defined $f ) { + $frequency = q[F=].$hash->{protocolObject}->getProperty($protocol,'frequency'). q[;] + } + } + $frequency //= q{}; + my %signalHash; + my %patternHash; + my $pattern=''; + my $cnt=0; - $repeats=1 if (!defined($repeats)); + my $sendData; + ## modulation ASK/OOK - MC + if (defined($hash->{protocolObject}->getProperty($protocol,'format')) && $hash->{protocolObject}->getProperty($protocol,'format') eq 'manchester') + { + $clock += $_ for( @{$hash->{protocolObject}->getProperty($protocol,'clockrange')} ); + $clock = round($clock/2,0); - if (exists($ProtocolListSIGNALduino{$protocol}{frequency}) && InternalVal($hash->{NAME},"cc1101_available",0) && !defined($frequency)) { - $frequency = $ProtocolListSIGNALduino{$protocol}{frequency}; - } - if (defined($frequency) && InternalVal($hash->{NAME},"cc1101_available",0)) { - $frequency="F=$frequency;"; - } else { - $frequency=""; - } + my $intro; + my $outro; - my %signalHash; - my %patternHash; - my $pattern=""; - my $cnt=0; + $intro = $hash->{protocolObject}->checkProperty($protocol,'msgIntro',''); + $outro = sprintf('%s',$hash->{protocolObject}->checkProperty($protocol,'msgOutro','')); - my $sendData; - if (exists($ProtocolListSIGNALduino{$protocol}{format}) && $ProtocolListSIGNALduino{$protocol}{format} eq 'manchester') - { - $clock += $_ for(@{$ProtocolListSIGNALduino{$protocol}{clockrange}}); - $clock = round($clock/2,0); + if ($intro ne '' || $outro ne '') + { + $intro = qq[SC;R=$repeats;] . $intro; + $repeats = 0; + } - my $intro = ""; - my $outro = ""; + $sendData = $intro . 'SM;' . ($repeats > 0 ? "R=$repeats;" : '') . "C=$clock;D=$data;" . $outro . $frequency; # SM;R=2;C=400;D=AFAFAF; + $hash->{logMethod}->($hash->{NAME}, 5, "$hash->{NAME}: Set_sendMsg, Preparing manchester protocol=$protocol, repeats=$repeats, clock=$clock data=$data"); - $intro = $ProtocolListSIGNALduino{$protocol}{msgIntro} if ($ProtocolListSIGNALduino{$protocol}{msgIntro}); - $outro = $ProtocolListSIGNALduino{$protocol}{msgOutro}.";" if ($ProtocolListSIGNALduino{$protocol}{msgOutro}); + ## modulation xFSK + } elsif (defined($hash->{protocolObject}->getProperty($protocol,'register')) && defined($hash->{protocolObject}->getProperty($protocol,'rfmode'))) { + $hash->{logMethod}->($hash->{NAME}, 5, "$hash->{NAME}: Set_sendMsg, Preparing ".$hash->{protocolObject}->getProperty($protocol,'rfmode')." protocol=$protocol, repeats=$repeats,data=$data"); + $sendData = 'SN;' . ($repeats > 0 ? "R=$repeats;" : '') . "D=$data;" # SN;R=1;D=08C11484498ABCDE; + ## modulation ASK/OOK - MS MU + } else { + if ($protocol == 3 || substr($data,0,2) eq 'is') { + if (substr($data,0,2) eq 'is') { + $data = substr($data,2); # is am Anfang entfernen + } + $data = $hash->{protocolObject}->ConvITV1_tristateToBit($data); + $hash->{logMethod}->($hash->{NAME}, 5, "$hash->{NAME}: Set_sendMsg, IT V1 convertet tristate to bits=$data"); + } + if (!defined $clock ) { + $hash->{ITClock} = 250 if (!defined $hash->{ITClock} ); # Todo: Klaeren wo ITClock verwendet wird und ob wir diesen Teil nicht auf Protokoll 3,4 und 17 minimieren + $clock= $hash->{protocolObject}->checkProperty($protocol,'clockabs',0) > 1 + ? $hash->{protocolObject}->getProperty($protocol,'clockabs') + : $hash->{ITClock}; + } - if ($intro ne "" || $outro ne "") - { - $intro = "SC;R=$repeats;" . $intro; - $repeats = 0; - } + if ($dataishex == 1) + { + # convert hex to bits + my $hlen = length($data); + my $blen = $hlen * 4; + $data = unpack("B$blen", pack("H$hlen", $data)); + } + $hash->{logMethod}->($hash->{NAME}, 5, "$hash->{NAME}: Set_sendMsg, Preparing rawsend command for protocol=$protocol, repeats=$repeats, clock=$clock bits=$data"); - $sendData = $intro . "SM;" . ($repeats > 0 ? "R=$repeats;" : "") . "C=$clock;D=$data;" . $outro . $frequency; # SM;R=2;C=400;D=AFAFAF; - $hash->{logMethod}->($hash->{NAME}, 5, "$hash->{NAME}: Set_sendMsg, Preparing manchester protocol=$protocol, repeats=$repeats, clock=$clock data=$data"); + for my $item (qw(preSync sync start one zero float pause end universal)) + { + my $value = $hash->{protocolObject}->getProperty($protocol,$item); + next if (!defined $value ); - } else { - if ($protocol == 3 || substr($data,0,2) eq "is") { - if (substr($data,0,2) eq "is") { - $data = substr($data,2); # is am Anfang entfernen - } - $data = SIGNALduino_ITV1_tristateToBit($data); - $hash->{logMethod}->($hash->{NAME}, 5, "$hash->{NAME}: Set_sendMsg, IT V1 convertet tristate to bits=$data"); - } - if (!defined($clock)) { - $hash->{ITClock} = 250 if (!defined($hash->{ITClock})); # Todo: Klaeren wo ITClock verwendet wird und ob wir diesen Teil nicht auf Protokoll 3,4 und 17 minimieren - $clock=$ProtocolListSIGNALduino{$protocol}{clockabs} > 1 ?$ProtocolListSIGNALduino{$protocol}{clockabs}:$hash->{ITClock}; - } + for my $p ( @{$value} ) + { + if (!exists($patternHash{$p})) + { + $patternHash{$p}=$cnt; + $pattern.='P'.$patternHash{$p}.'='. int($p*$clock) .';'; + $cnt++; + } + $signalHash{$item}.=$patternHash{$p}; + } + } + my @bits = split('', $data); - if ($dataishex == 1) - { - # convert hex to bits - my $hlen = length($data); - my $blen = $hlen * 4; - $data = unpack("B$blen", pack("H$hlen", $data)); - } - $hash->{logMethod}->($hash->{NAME}, 5, "$hash->{NAME}: Set_sendMsg, Preparing rawsend command for protocol=$protocol, repeats=$repeats, clock=$clock bits=$data"); + my %bitconv = (1=>'one', 0=>'zero', 'D'=> 'float', 'F'=> 'float', 'P'=> 'pause', 'U'=> 'universal'); + my $SignalData='D='; - foreach my $item (qw(preSync sync start one zero float pause end universal)) - { - next if (!exists($ProtocolListSIGNALduino{$protocol}{$item})); - - foreach my $p (@{$ProtocolListSIGNALduino{$protocol}{$item}}) - { - if (!exists($patternHash{$p})) - { - $patternHash{$p}=$cnt; - $pattern.="P".$patternHash{$p}."=". int($p*$clock) .";"; - $cnt++; - } - $signalHash{$item}.=$patternHash{$p}; - } - } - my @bits = split("", $data); - - my %bitconv = (1=>"one", 0=>"zero", 'D'=> "float", 'F'=> "float", 'P'=> "pause", 'U'=> "universal"); - my $SignalData="D="; - - $SignalData.=$signalHash{preSync} if (exists($signalHash{preSync})); - $SignalData.=$signalHash{sync} if (exists($signalHash{sync})); - $SignalData.=$signalHash{start} if (exists($signalHash{start})); - foreach my $bit (@bits) - { - next if (!exists($bitconv{$bit})); - $SignalData.=$signalHash{$bitconv{$bit}}; ## Add the signal to our data string - } - $SignalData.=$signalHash{end} if (exists($signalHash{end})); - $sendData = "SR;R=$repeats;$pattern$SignalData;$frequency"; - } - SIGNALduino_AddSendQueue($hash,$sendData); - $hash->{logMethod}->($hash->{NAME}, 4, "$hash->{NAME}: Set_sendMsg, sending : $sendData"); + $SignalData.=$signalHash{preSync} if (exists($signalHash{preSync})); + $SignalData.=$signalHash{sync} if (exists($signalHash{sync})); + $SignalData.=$signalHash{start} if (exists($signalHash{start})); + foreach my $bit (@bits) + { + next if (!exists($bitconv{$bit})); + $SignalData.=$signalHash{$bitconv{$bit}}; ## Add the signal to our data string + } + $SignalData.=$signalHash{end} if (exists($signalHash{end})); + $sendData = "SR;R=$repeats;$pattern$SignalData;$frequency"; + } + SIGNALduino_AddSendQueue($hash,$sendData); + $hash->{logMethod}->($hash->{NAME}, 4, "$hash->{NAME}: Set_sendMsg, sending : $sendData"); } ############################# package main sub SIGNALduino_Set_close { - my $hash = shift; - $hash->{DevState} = 'closed'; - return SIGNALduino_CloseDevice($hash); + my $hash = shift; + $hash->{DevState} = 'closed'; + return SIGNALduino_CloseDevice($hash); } ############################# package main -sub SIGNALduino_Set_MessageType -{ - my ($hash, @a) = @_; - my $argm; - if ($a[0] =~ /^enable/) { - $argm = 'CE' . substr($a[1],-1,1); - } else { - $argm = 'CD' . substr($a[1],-1,1); - } - SIGNALduino_AddSendQueue($hash,$argm); - $hash->{logMethod}->($hash->{NAME}, 4, "$hash->{NAME}: Set_MessageType, $a[0] $a[1] $argm"); +sub SIGNALduino_Set_MessageType { + my ($hash, @a) = @_; + my $argm; + if ($a[0] =~ /^enable/) { + $argm = 'CE' . substr($a[1],-1,1); + } else { + $argm = 'CD' . substr($a[1],-1,1); + } + SIGNALduino_AddSendQueue($hash,$argm); + SIGNALduino_Get_Command($hash,'config'); + $hash->{logMethod}->($hash->{NAME}, 4, "$hash->{NAME}: Set_MessageType, $a[0] $a[1] $argm"); } ############################# package main -sub SIGNALduino_Set_bWidth -{ - my ($hash, @a) = @_; +sub SIGNALduino_Set_bWidth { + my ($hash, @a) = @_; - if (exists($hash->{ucCmd}->{cmd}) && $hash->{ucCmd}->{cmd} eq "set_bWidth" && $a[0] =~ /^C10\s=\s([A-Fa-f0-9]{2})$/ ) - { - my ($ob,$bw) = cc1101::CalcbWidthReg($hash,$1,$hash->{ucCmd}->{arg}); - $hash->{logMethod}->($hash->{NAME}, 3, "$hash->{NAME}: Set_bWidth, bWidth: Setting MDMCFG4 (10) to $ob = $bw KHz"); - # Toddo setRegisters verwenden - main::SIGNALduino_AddSendQueue($hash,"W12$ob"); - main::SIGNALduino_WriteInit($hash); - return ("Setting MDMCFG4 (10) to $ob = $bw KHz" ,undef); - } else { - $hash->{logMethod}->($hash->{NAME}, 3, "$hash->{NAME}: Set_bWidth, Request register 10"); - # Get Register 10 - cc1101::GetRegister($hash,10); + if (exists($hash->{ucCmd}->{cmd}) && $hash->{ucCmd}->{cmd} eq 'set_bWidth' && $a[0] =~ /^C10\s=\s([A-Fa-f0-9]{2})$/ ) + { + my ($ob,$bw) = cc1101::CalcbWidthReg($hash,$1,$hash->{ucCmd}->{arg}); + $hash->{logMethod}->($hash->{NAME}, 3, "$hash->{NAME}: Set_bWidth, bWidth: Setting MDMCFG4 (10) to $ob = $bw KHz"); + # Toddo setRegisters verwenden + main::SIGNALduino_AddSendQueue($hash,"W12$ob"); + main::SIGNALduino_WriteInit($hash); + return ("Setting MDMCFG4 (10) to $ob = $bw KHz" ,undef); + } else { + $hash->{logMethod}->($hash->{NAME}, 3, "$hash->{NAME}: Set_bWidth, Request register 10"); + # Get Register 10 + cc1101::GetRegister($hash,10); - $hash->{ucCmd}->{cmd} = "set_bWidth"; - $hash->{ucCmd}->{arg} = $a[1]; # Zielbandbreite - $hash->{ucCmd}->{responseSub} = \&SIGNALduino_Set_bWidth; # Callback auf sich selbst setzen - $hash->{ucCmd}->{asyncOut} = $hash->{CL} if (defined($hash->{CL})); - $hash->{ucCmd}->{timenow}=time(); - #return "Register 10 requested"; - return ; - } + $hash->{ucCmd}->{cmd} = 'set_bWidth'; + $hash->{ucCmd}->{arg} = $a[1]; # Zielbandbreite + $hash->{ucCmd}->{responseSub} = \&SIGNALduino_Set_bWidth; # Callback auf sich selbst setzen + $hash->{ucCmd}->{asyncOut} = $hash->{CL} if (defined($hash->{CL})); + $hash->{ucCmd}->{timenow} = time(); + #return 'Register 10 requested'; + return ; + } } ############################# package main +# LaCrosse sensor is comfortable to put on (own way from 36_LaCrosse.pm) +sub SIGNALduino_Set_LaCrossePairForSec { + my ($hash, @a) = @_; + + # set NAME a[0] a[1] a[2] + return "Usage: set $hash->{NAME} $a[0] [ignore_battery]" if(!$a[0] || $a[1] !~ m/^\d+$/xms || (defined $a[2] && $a[2] ne 'ignore_battery') ); + $hash->{LaCrossePair} = 2; # LaCrosse autoCreateState: 0 = autoreate not defined | 1 = autocreate defined | 2 = autocreate active + $hash->{logMethod}->($hash->{NAME}, 4, "$hash->{NAME}: Set_LaCrossePairForSec, LaCrosse autocreate active for $a[1] seconds"); + InternalTimer(gettimeofday()+$a[1], 'SIGNALduino_RemoveLaCrossePair', $hash, 0); + + return ; +} + +############################# package main, test exists sub SIGNALduino_Get($@) { - my ($hash,$name, @a) = @_; - #my $type = $hash->{TYPE}; + my ($hash,$name, @a) = @_; + #my $type = $hash->{TYPE}; - return "\"get SIGNALduino\" needs at least one parameter" if(@a < 1); + return "\"get SIGNALduino\" needs at least one parameter" if(@a < 1); - if (!InternalVal($name,"cc1101_available",0) && $a[0] =~ /^cc/) { - return "This command is only available with a cc1101 receiver"; - } - if (!exists($gets{$a[0]})) { - return "Unknown argument $a[0], choose one of supported commands"; - } - my $rcode=undef; - if (exists($hash->{ucCmd}) && $a[0] ne "?" ) { - SIGNALduino_Get_delayed("SIGNALduino_Get_delayed:$name:".join(":",@a)); - } - elsif ( ($hash->{DevState} eq "initialized" || $a[0] eq "?" || $a[0] eq 'availableFirmware') && ref @{$gets{$a[0]}}[1] eq "CODE") { # - $rcode= @{$gets{$a[0]}}[1]->($hash,@a); - } elsif ($hash->{DevState} ne "initialized") { - $rcode= "$name is not active, may firmware is not supported, please flash or reset"; - } + if (!InternalVal($name,'cc1101_available',0) && $a[0] =~ /^cc/) { + return 'This command is only available with a cc1101 receiver'; + } + if (!exists($gets{$a[0]})) { + return "Unknown argument $a[0], choose one of supported commands"; + } + my $rcode=undef; + if (exists($hash->{ucCmd}) && $a[0] ne '?' ) { + SIGNALduino_Get_delayed("SIGNALduino_Get_delayed:$name:".join(':',@a)); + } elsif ( ($hash->{DevState} eq 'initialized' || $a[0] eq '?' || $a[0] eq 'availableFirmware') && ref @{$gets{$a[0]}}[1] eq 'CODE') { # + $rcode= @{$gets{$a[0]}}[1]->($hash,@a); + } elsif ($hash->{DevState} ne 'initialized') { + $rcode= "$name is not active, may firmware is not supported, please flash or reset"; + } - return $rcode; # We will exit here, and give an output only, $rcode has some value + return $rcode; # We will exit here, and give an output only, $rcode has some value } - -############################# package main +############################# package main, test exists #SIGNALduino_Get_Callback($name, $callbackFn, @args); -sub SIGNALduino_Get_Callback($$$) { - my ($name, $callbackFn, $arg) = @_; +sub SIGNALduino_Get_Callback { + my ($name, $callbackFn, $arg) = @_; - my @a = split (" ",$arg); - return "\"get _Get_Callback\" needs at least two parameters" if(@a < 2); - return "\"$name\" is not a definition of type SIGNALduino" if (!IsDevice($name, "SIGNALduino")); + my @a = split (' ',$arg); + return "\"get _Get_Callback\" needs at least two parameters" if(@a < 2); + return "\"$name\" is not a definition of type SIGNALduino" if (!IsDevice($name, 'SIGNALduino')); - my $hash = $defs{$name}; - my $rcode = SIGNALduino_Get($hash,$name,@a); + my $hash = $defs{$name}; + my $rcode = SIGNALduino_Get($hash,$name,@a); - if (!defined($rcode)) - { - $hash->{ucCmd}->{responseSub}=$callbackFn; - delete($hash->{ucCmd}->{asyncOut}); - } + if (!defined($rcode)) + { + $hash->{ucCmd}->{responseSub}=$callbackFn; + delete($hash->{ucCmd}->{asyncOut}); + } - return $rcode; # We will exit here, and give an output only, $rcode has some value + return $rcode; # We will exit here, and give an output only, $rcode has some value } ############################# package main sub SIGNALduino_Get_FhemWebList { - my ($hash, @a) = @_; - my @cList = sort map { "$_:@{$gets{$_}}[0]" } grep { - ($_ ne "?" && - ( - (IsDummy($hash->{NAME}) && $_ =~ m/^(?:availableFirmware|raw)/) || - ( InternalVal($hash->{NAME},"cc1101_available",0) || (!InternalVal($hash->{NAME},"cc1101_available",0) && $_ !~ /^cc/)) && - ( !IsDummy($hash->{NAME}) && (defined(DevIo_IsOpen($hash)) || $_ =~ m/^(?:availableFirmware|raw)/ )) ) - ) - } keys %gets; - return "Unknown argument $a[0], choose one of " . join(" ", @cList); + my ($hash, @a) = @_; + my @cList = sort map { "$_:@{$gets{$_}}[0]" } grep { + ($_ ne '?' && + ( + (IsDummy($hash->{NAME}) && $_ =~ m/^(?:availableFirmware|raw)/) || + ( InternalVal($hash->{NAME},'cc1101_available',0) || (!InternalVal($hash->{NAME},'cc1101_available',0) && $_ !~ /^cc/)) && + ( !IsDummy($hash->{NAME}) && (defined(DevIo_IsOpen($hash)) || $_ =~ m/^(?:availableFirmware|raw)/ )) + ) + ) + } keys %gets; + return "Unknown argument $a[0], choose one of " . join(' ', @cList); } ############################# package main sub SIGNALduino_Get_availableFirmware { - my ($hash, @a) = @_; + my ($hash, @a) = @_; - if ($missingModulSIGNALduino =~ m/JSON/ ) - { - $hash->{logMethod}->($hash->{NAME}, 1, "$hash->{NAME}: get $a[0] failed. Pleas install Perl module JSON. Example: sudo apt-get install libjson-perl"); - return "$a[0]: \n\nFetching from github is not possible. Please install JSON. Example:
sudo apt-get install libjson-perl"; - } + if ($missingModulSIGNALduino =~ m/JSON/ ) + { + $hash->{logMethod}->($hash->{NAME}, 1, "$hash->{NAME}: get $a[0] failed. Please install Perl module JSON. Example: sudo apt-get install libjson-perl"); + return "$a[0]: \n\nFetching from github is not possible. Please install JSON. Example:
sudo apt-get install libjson-perl"; + } - my $channel=AttrVal($hash->{NAME},"updateChannelFW","stable"); - my $hardware=AttrVal($hash->{NAME},"hardware",undef); + my $channel=AttrVal($hash->{NAME},'updateChannelFW','stable'); + my $hardware=AttrVal($hash->{NAME},'hardware',undef); - my ($validHw) = $modules{$hash->{TYPE}}{AttrList} =~ /.*hardware:(.*?)\s/; - $hash->{logMethod}->($hash->{NAME}, 1, "$hash->{NAME}: found availableFirmware for $validHw"); + my ($validHw) = $modules{$hash->{TYPE}}{AttrList} =~ /.*hardware:(.*?)\s/; + $hash->{logMethod}->($hash->{NAME}, 1, "$hash->{NAME}: found availableFirmware for $validHw"); - if (!defined($hardware) || $validHw !~ /$hardware(?:,|$)/ ) - { - $hash->{logMethod}->($hash->{NAME}, 1, "$hash->{NAME}: get $a[0] failed. Please set attribute hardware first"); - return "$a[0]: \n\n$hash->{NAME}: get $a[0] failed. Please choose one of $validHw attribute hardware"; - } - SIGNALduino_querygithubreleases($hash); - return "$a[0]: \n\nFetching $channel firmware versions for $hardware from github\n"; + if (!defined($hardware) || $validHw !~ /$hardware(?:,|$)/ ) + { + $hash->{logMethod}->($hash->{NAME}, 1, "$hash->{NAME}: get $a[0] failed. Please set attribute hardware first"); + return "$a[0]: \n\n$hash->{NAME}: get $a[0] failed. Please choose one of $validHw attribute hardware"; + } + SIGNALduino_querygithubreleases($hash); + return "$a[0]: \n\nFetching $channel firmware versions for $hardware from github\n"; } ############################# package main -sub SIGNALduino_Get_Command -{ - my ($hash, @a) = @_; - my $name=$hash->{NAME}; - return "Unsupported command for the microcontroller" if (!exists(${$gets{$a[0]}}[2])); - $hash->{logMethod}->($name, 5, "$name: Get $a[0] executed"); - SIGNALduino_AddSendQueue($hash, @{$gets{$a[0]}}[2] . (exists($a[1]) ? "$a[1]" : "")); - $hash->{ucCmd}->{cmd}=$a[0]; - $hash->{ucCmd}->{responseSub}=$gets{$a[0]}[3]; - $hash->{ucCmd}->{asyncOut}=$hash->{CL} if (defined($hash->{CL})); - $hash->{ucCmd}->{timenow}=time(); - return ; +sub SIGNALduino_Get_Command { + my ($hash, @a) = @_; + my $name=$hash->{NAME}; + return 'Unsupported command for the microcontroller' if (!exists(${$gets{$a[0]}}[2])); + $hash->{logMethod}->($name, 5, "$name: Get_Command $a[0] executed"); + SIGNALduino_AddSendQueue($hash, @{$gets{$a[0]}}[2] . (exists($a[1]) ? "$a[1]" : '')); + $hash->{ucCmd}->{cmd}=$a[0]; + $hash->{ucCmd}->{responseSub}=$gets{$a[0]}[3]; + $hash->{ucCmd}->{asyncOut}=$hash->{CL} if (defined($hash->{CL})); + $hash->{ucCmd}->{timenow}=time(); + return ; } ############################# package main -sub SIGNALduino_Get_Command_CCReg -{ - my ($hash, @a) = @_; - my $name=$hash->{NAME}; - if (exists($cc1101_register{uc($_[2])}) || $_[2] =~ /^99$/ ) { - return SIGNALduino_Get_Command(@_); - } else { - return "unknown Register $_[2], please choose a valid cc1101 register"; - } +sub SIGNALduino_Get_Command_CCReg { + my ($hash, @a) = @_; + return 'not enough number of arguments' if $#a < 1; + return 'Wrong command provided' if $a[0] ne 'ccreg'; + my $name=$hash->{NAME}; + if (exists($cc1101_register{uc($a[1])}) || $a[1] eq '99' || $a[1] =~ /^3[0-9a-dA-D]$/ ) { + return SIGNALduino_Get_Command(@_); + } else { + return "unknown Register $a[1], please choose a valid cc1101 register"; + } } ############################# package main -sub SIGNALduino_Get_Raw { - my ($hash, @a) = @_; - return "\"get raw\" needs at least a parameter" if (@a < 2); - if ($a[1] =~ /^M[CcSU];.*/) - { - $a[1]="\002$a[1]\003"; ## Add start end end marker if not already there - $hash->{logMethod}->($hash->{NAME}, 5, "$hash->{NAME}: msg adding start and endmarker to message"); - } +sub SIGNALduino_Get_RawMsg { + my ($hash, @a) = @_; + return "\"get raw\" needs at least a parameter" if (@a < 2); + if ($a[1] =~ /^M[CcSUN];.+/) + { + $a[1]="\002$a[1]\003"; ## Add start end end marker if not already there + $hash->{logMethod}->($hash->{NAME}, 5, "$hash->{NAME}: msg adding start and endmarker to message"); + } - if ($a[1] =~ /\002M.;.*;\003$/) - { - $hash->{logMethod}->( $hash->{NAME}, 4, "$hash->{NAME}: msg get raw: $a[1]"); - return SIGNALduino_Parse($hash, $hash, $hash->{NAME}, $a[1]); - } else { - return "This command is not supported via get raw."; - } - + if ($a[1] =~ /\002M\w;.+;\003$/) + { + $hash->{logMethod}->( $hash->{NAME}, 4, "$hash->{NAME}: get rawmsg: $a[1]"); + my $cnt = SIGNALduino_Parse($hash, $hash, $hash->{NAME}, $a[1]); + if (defined $cnt) { + return "Parse raw msg, number of messages passed to modules: $cnt"; + } else { + return "Parse raw msg, no suitable protocol recognized."; + } + } else { + return 'This command is not supported via get rawmsg.'; + } +} + +############################# package main, test exists +sub SIGNALduino_GetResponseUpdateReading { + return ($_[1],1); } ############################# package main -sub SIGNALduino_GetResponseUpdateReading -{ - return ($_[1],1); -} - -############################# package main -sub SIGNALduino_Get_delayed($) { - my(undef,$name,@cmds) = split(':', shift); - my $hash = $defs{$name}; +sub SIGNALduino_Get_delayed { + my(undef,$name,@cmds) = split(':', shift); + my $hash = $defs{$name}; - if ( exists($hash->{ucCmd}) && !exists($hash->{ucCmd}->{timenow}) ) { - $hash->{ucCmd}->{timenow}=time(); - Log3 ($hash->{NAME}, 5, "$name: Get_delayed, timenow was missing, set ".$hash->{ucCmd}->{timenow}); - } - - if (exists($hash->{ucCmd}) && $hash->{ucCmd}->{timenow}+10 > time() ) { - $hash->{logMethod}->($hash->{NAME}, 5, "$name: Get_delayed, ".join(" ",@cmds)." delayed"); - main::InternalTimer(main::gettimeofday() + main::SDUINO_GET_CONFIGQUERY_DELAY, \&SIGNALduino_Get_delayed, "SIGNALduino_Get_delayed:$name:".join(" ",@cmds), 0); - } else { - delete($hash->{ucCmd}); - $hash->{logMethod}->($hash->{NAME}, 5, "$name: Get_delayed, ".join(" ",@cmds)." executed"); - RemoveInternalTimer("SIGNALduino_Get_delayed:$name:".join(" ",@cmds)); - SIGNALduino_Get($hash,$name,$cmds[0]); - } + if ( exists($hash->{ucCmd}) && !exists($hash->{ucCmd}->{timenow}) ) { + $hash->{ucCmd}->{timenow}=time(); + Log3 ($hash->{NAME}, 5, "$name: Get_delayed, timenow was missing, set ".$hash->{ucCmd}->{timenow}); + } + + if (exists($hash->{ucCmd}) && $hash->{ucCmd}->{timenow}+10 > time() ) { + $hash->{logMethod}->($hash->{NAME}, 5, "$name: Get_delayed, ".join(' ',@cmds).' delayed'); + main::InternalTimer(main::gettimeofday() + main::SDUINO_GET_CONFIGQUERY_DELAY, \&SIGNALduino_Get_delayed, "SIGNALduino_Get_delayed:$name:".join(' ',@cmds), 0); + } else { + delete($hash->{ucCmd}); + $hash->{logMethod}->($hash->{NAME}, 5, "$name: Get_delayed, ".join(' ',@cmds).' executed'); + RemoveInternalTimer("SIGNALduino_Get_delayed:$name:".join(' ',@cmds)); + SIGNALduino_Get($hash,$name,$cmds[0]); + } } -############################# package main -sub SIGNALduino_CheckUptimeResponse -{ - my $msg = sprintf("%d %02d:%02d:%02d", $_[1]/86400, ($_[1]%86400)/3600, ($_[1]%3600)/60, $_[1]%60); - #readingsSingleUpdate($_[0], $_[0]->{ucCmd}->{cmd}, $msg, 0); - return ($msg,0); +############################# package main, test exists +sub SIGNALduino_CheckUptimeResponse { + my $msg = sprintf("%d %02d:%02d:%02d", $_[1]/86400, ($_[1]%86400)/3600, ($_[1]%3600)/60, $_[1]%60); + #readingsSingleUpdate($_[0], $_[0]->{ucCmd}->{cmd}, $msg, 0); + return ($msg,0); } -############################# package main -sub SIGNALduino_CheckCmdsResponse -{ - my $hash = shift; - my $msg = shift; - my $name=$hash->{NAME}; +############################# package main, test exists +sub SIGNALduino_CheckCmdsResponse { + my $hash = shift; + my $msg = shift; + my $name=$hash->{NAME}; - $msg =~ s/$name cmds =>//g; - $msg =~ s/.*Use one of//g; + $msg =~ s/$name cmds =>//g; + $msg =~ s/.*Use one of//g; - return ($msg,0); + return ($msg,0); } -############################# package main +############################# package main, test exists sub SIGNALduino_CheckccConfResponse { - my (undef,$str) = split('=', $_[1]); - my $var; - my %r = ( "0D"=>1,"0E"=>1,"0F"=>1,"10"=>1,"11"=>1,"12"=>1,"1B"=>1,"1D"=>1, "15"=>1); - foreach my $a (sort keys %r) { - $var = substr($str,(hex($a)-13)*2, 2); - $r{$a} = hex($var); - } - my $msg = sprintf("Freq: %.3f MHz, Bandwidth: %d KHz, rAmpl: %d dB, sens: %d dB, DataRate: %.2f Baud", - 26*(($r{"0D"}*256+$r{"0E"})*256+$r{"0F"})/65536, #Freq | Register 0x0D,0x0E,0x0F - 26000/(8 * (4+(($r{"10"}>>4)&3)) * (1 << (($r{"10"}>>6)&3))), #Bw | Register 0x10 - $ampllist[$r{"1B"}&7], #rAmpl | Register 0x1B - 4+4*($r{"1D"}&3), #Sens | Register 0x1D - ((256+$r{"11"})*(2**($r{"10"} & 15 )))*26000000/(2**28) #DataRate | Register 0x10,0x11 - ); + my (undef,$str) = split('=', $_[1]); + my $var; - my $msg2 = sprintf("Modulation: %s, Syncmod: %s", - $modformat[$r{"12"}>>4], #Modulation | Register 0x12 - $syncmod[($r{"12"})&7], #Syncmod | Register 0x12 - ); + # https://github.com/RFD-FHEM/RFFHEM/issues/1015 | value can arise due to an incorrect transmission from serial + # $str = "216%E857C43023B900070018146C040091"; + return ('invalid value from uC. Only hexadecimal values are allowed. Please query again.',undef) if($str !~ /^[A-F0-9a-f]+$/); - readingsBeginUpdate($_[0]); - readingsBulkUpdate($_[0], "cc1101_config", $msg); - readingsBulkUpdate($_[0], "cc1101_config_ext", $msg2); - readingsEndUpdate($_[0], 1); + my %r = ( '0D'=>1,'0E'=>1,'0F'=>1,'10'=>1,'11'=>1,'12'=>1,'1B'=>1,'1D'=>1, '15'=>1); + foreach my $a (sort keys %r) { + $var = substr($str,(hex($a)-13)*2, 2); + $r{$a} = hex($var); + } + my $msg = sprintf("Freq: %.3f MHz, Bandwidth: %d kHz, rAmpl: %d dB, sens: %d dB, DataRate: %.2f kBaud", + 26*(($r{"0D"}*256+$r{"0E"})*256+$r{"0F"})/65536, #Freq | Register 0x0D,0x0E,0x0F + 26000/(8 * (4+(($r{"10"}>>4)&3)) * (1 << (($r{"10"}>>6)&3))), #Bw | Register 0x10 + $ampllist[$r{"1B"}&7], #rAmpl | Register 0x1B + 4+4*($r{"1D"}&3), #Sens | Register 0x1D + (((256+$r{"11"})*(2**($r{"10"} & 15 )))*26000000/(2**28) / 1000) #DataRate | Register 0x10,0x11 + ); - return ($msg.", ".$msg2,undef); + my $msg2 = sprintf("Modulation: %s", + $modformat[$r{"12"}>>4], #Modulation | Register 0x12 + ); + + if ($msg2 !~ /Modulation:\sASK\/OOK/) { + $msg2 .= ", Syncmod: ".$syncmod[($r{"12"})&7]; #Syncmod | Register 0x12 + $msg2 .= ", Deviation: ".round((8+($r{"15"}&7))*(2**(($r{"15"}>>4)&7)) *26000/(2**17),2) .' kHz'; #Deviation | Register 0x15 + } + + readingsBeginUpdate($_[0]); + readingsBulkUpdate($_[0], 'cc1101_config', $msg); + readingsBulkUpdate($_[0], 'cc1101_config_ext', $msg2); + readingsEndUpdate($_[0], 1); + + return ($msg.', '.$msg2,undef); } -############################# package main +############################# package main, test exists sub SIGNALduino_CheckccPatableResponse { - my $hash = shift; - my $msg = shift; - my $name=$hash->{NAME}; + my $hash = shift; + my $msg = shift; + my $name=$hash->{NAME}; - my $CC1101Frequency=AttrVal($name,"cc1101_frequency",433); - $CC1101Frequency = 433 if ($CC1101Frequency >= 433 && $CC1101Frequency <= 435); - $CC1101Frequency = 868 if ($CC1101Frequency >= 863 && $CC1101Frequency <= 870); - my $dBn = substr($msg,9,2); - $hash->{logMethod}->($name, 3, "$name: CheckCcpatableResponse, patable: $dBn"); - foreach my $dB (keys %{ $patable{$CC1101Frequency} }) { - if ($dBn eq $patable{$CC1101Frequency}{$dB}) { - $hash->{logMethod}->($name, 5, "$name: CheckCcpatableResponse, patable: $dB"); - $msg .= " => $dB"; - last; - } - } - readingsSingleUpdate($hash, "cc1101_patable", $msg,1); - return ($msg,undef); + my $CC1101Frequency=AttrVal($name,'cc1101_frequency',433); + $CC1101Frequency = 433 if ($CC1101Frequency >= 433 && $CC1101Frequency <= 435); + $CC1101Frequency = 868 if ($CC1101Frequency >= 863 && $CC1101Frequency <= 870); + my $dBn = substr($msg,9,2); + $hash->{logMethod}->($name, 3, "$name: CheckCcpatableResponse, patable: $dBn"); + foreach my $dB (keys %{ $patable{$CC1101Frequency} }) { + if ($dBn eq $patable{$CC1101Frequency}{$dB}) { + $hash->{logMethod}->($name, 5, "$name: CheckCcpatableResponse, patable: $dB"); + $msg .= " => $dB"; + last; + } + } + readingsSingleUpdate($hash, 'cc1101_patable', $msg,1); + return ($msg,undef); } -############################# package main -sub SIGNALduino_CheckCcregResponse -{ - my $hash = shift; - my $msg = shift; - my $name=$hash->{NAME}; - - if ($msg =~ /^ccreg/) { - - $msg =~ s/\s\sccreg/\nccreg/g; - $msg =~ s/ccreg\s\d0:\s//g; - - my @ccreg = split(/\s/,$msg); - - $msg.= "\n\n"; - $msg.= "Configuration Register Detail (address, name, value):\n"; - - my $reg_idx = 0; - foreach my $key (sort keys %cc1101_register) { - $msg.= "0x".$key." ".$cc1101_register{$key}. " - 0x".$ccreg[$reg_idx]."\n"; - $reg_idx++; - } - } else { - $msg =~ /^C([A-Fa-f0-9]{2}) = ([A-Fa-f0-9]{2})$/; - my $reg = $1; - my $val = $2; - $msg = "Configuration Register Detail address (name) = value:\n"; - $msg .= "0x$reg ( $cc1101_register{$reg}) = 0x$val\n"; - } - return ("\n".$msg,undef); +############################# package main, test exists +sub SIGNALduino_CheckCcregResponse { + my $hash = shift; + my $msg = shift; + my $name=$hash->{NAME}; + $hash->{logMethod}->($name, 5, "$name: CheckCcregResponse, msg $msg"); + if ($msg =~ /^ccreg/) { + my $msg1 = $msg; + $msg =~ s/\s\s/\n/g; + $msg = "\nConfiguration register overview:\n---------------------------------------------------------\n" . $msg; + $msg.= "\n\nConfiguration register detail:\n---------------------------------------------------------\nadd. name def. cur.\n"; + $msg1 =~ s/ccreg\s\d0:\s//g; + $msg1 =~ s/\s\s/ /g; + my @ccreg = split(/\s/,$msg1); + my $reg_idx = 0; + foreach my $key (sort keys %cc1101_register) { + $msg.= '0x'.$key.' '.$cc1101_register{$key}. ' - 0x'.$ccreg[$reg_idx]."\n"; + $reg_idx++; + } + } else { + $msg =~ /^C([A-Fa-f0-9]{2}) = ([A-Fa-f0-9]{2})$/; + my $reg = $1; + my $val = $2; + if ( $reg =~ /^3[0-9a-dA-D]$/ ) { # Status register + $msg = "\nStatus register detail:\n---------------------------\nadd. name cur.\n"; + $msg .= "0x$reg $cc1101::cc1101_status_register{$reg} - 0x$val"; + if ( $reg eq '31' && exists $cc1101::cc1101_version{$val}) { # VERSION – Chip ID + $msg .= " Chip $cc1101::cc1101_version{$val}"; + } + } else { # Configuration Register + $msg = "\nConfiguration register detail:\n------------------------------\nadd. name def. cur.\n"; + $msg .= "0x$reg $cc1101_register{$reg} - 0x$val"; + } + $msg .= "\n"; + } + return ("\n".$msg,undef); } ############################# package main ### Unused ??? ### in use -sub SIGNALduino_CheckSendRawResponse -{ - my $hash = shift; - my $msg = shift; +sub SIGNALduino_CheckSendRawResponse { + my $hash = shift; + my $msg = shift; - if ($msg =~ /^S[RCM];/ ) - { - my $name=$hash->{NAME}; - - # zu testen der sendeQueue, kann wenn es funktioniert auf verbose 5 - $hash->{logMethod}->($name, 4, "$name: CheckSendrawResponse, sendraw answer: $msg"); - #RemoveInternalTimer("HandleWriteQueue:$name"); - delete($hash->{ucCmd}); - #SIGNALduino_HandleWriteQueue("x:$name"); # Todo #823 on github - InternalTimer(gettimeofday() + 0.1, \&SIGNALduino_HandleWriteQueue, "HandleWriteQueue:$name") if (scalar @{$hash->{QUEUE}} > 0 && InternalVal($name,"sendworking",0) == 0); - } - return (undef); + if ($msg =~ /^S[RCMN];/ ) + { + my $name=$hash->{NAME}; + # zu testen der sendeQueue, kann wenn es funktioniert auf verbose 5 + $hash->{logMethod}->($name, 4, "$name: CheckSendrawResponse, sendraw answer: $msg"); + delete($hash->{ucCmd}); + if ($msg =~ /D=[A-Za-z0-9]+;/ ) + { + RemoveInternalTimer("HandleWriteQueue:$name"); + SIGNALduino_HandleWriteQueue("x:$name"); # Todo #823 on github + } else { + InternalTimer(gettimeofday() , \&SIGNALduino_HandleWriteQueue, "HandleWriteQueue:$name") if (scalar @{$hash->{QUEUE}} > 0 && InternalVal($name,'sendworking',0) == 0); + } + } + return (undef); } ############################# package main -sub SIGNALduino_ResetDevice($) { - my $hash = shift; - my $name = $hash->{NAME}; +sub SIGNALduino_ResetDevice { + my $hash = shift; + my $name = $hash->{NAME}; - if (!defined($hash->{helper}{resetInProgress})) { - my $hardware = AttrVal($name,"hardware",""); - $hash->{logMethod}->($name, 3, "$name: ResetDevice, $hardware"); + if (!defined($hash->{helper}{resetInProgress})) { + my $hardware = AttrVal($name,'hardware',''); + $hash->{logMethod}->($name, 3, "$name: ResetDevice, $hardware"); - if (IsDummy($name)) { # for dummy device - $hash->{DevState} = "initialized"; - readingsSingleUpdate($hash, "state", "opened", 1); - return ; - } + if (IsDummy($name)) { # for dummy device + $hash->{DevState} = 'initialized'; + readingsSingleUpdate($hash, 'state', 'opened', 1); + return ; + } - DevIo_CloseDev($hash); - if ($hardware eq "radinoCC1101" && $^O eq 'linux') { - # The reset is triggered when the Micro's virtual (CDC) serial / COM port is opened at 1200 baud and then closed. - # When this happens, the processor will reset, breaking the USB connection to the computer (meaning that the virtual serial / COM port will disappear). - # After the processor resets, the bootloader starts, remaining active for about 8 seconds. - # The bootloader can also be initiated by pressing the reset button on the Micro. - # Note that when the board first powers up, it will jump straight to the user sketch, if present, rather than initiating the bootloader. - my ($dev, $baudrate) = split("@", $hash->{DeviceName}); - $hash->{logMethod}->($name, 3, "$name: ResetDevice, forcing special reset for $hardware on $dev"); - # Mit dem Linux-Kommando 'stty' die Port-Einstellungen setzen - system("stty -F $dev ospeed 1200 ispeed 1200"); - $hash->{helper}{resetInProgress}=1; - InternalTimer(gettimeofday()+10,\&SIGNALduino_ResetDevice,$hash); - $hash->{logMethod}->($name, 3, "$name: ResetDevice, reopen delayed for 10 second"); - return ; - } - } else { - delete($hash->{helper}{resetInProgress}); - } - DevIo_OpenDev($hash, 0, \&SIGNALduino_DoInit, \&SIGNALduino_Connect); - return ; + DevIo_CloseDev($hash); + if ($hardware eq 'radinoCC1101' && $^O eq 'linux') { + # The reset is triggered when the Micro's virtual (CDC) serial / COM port is opened at 1200 baud and then closed. + # When this happens, the processor will reset, breaking the USB connection to the computer (meaning that the virtual serial / COM port will disappear). + # After the processor resets, the bootloader starts, remaining active for about 8 seconds. + # The bootloader can also be initiated by pressing the reset button on the Micro. + # Note that when the board first powers up, it will jump straight to the user sketch, if present, rather than initiating the bootloader. + my ($dev, $baudrate) = split("@", $hash->{DeviceName}); + $hash->{logMethod}->($name, 3, "$name: ResetDevice, forcing special reset for $hardware on $dev"); + # Mit dem Linux-Kommando 'stty' die Port-Einstellungen setzen + system("stty -F $dev ospeed 1200 ispeed 1200"); + $hash->{helper}{resetInProgress}=1; + InternalTimer(gettimeofday()+10,\&SIGNALduino_ResetDevice,$hash); + $hash->{logMethod}->($name, 3, "$name: ResetDevice, reopen delayed for 10 second"); + return ; + } + } else { + delete($hash->{helper}{resetInProgress}); + } + DevIo_OpenDev($hash, 0, \&SIGNALduino_DoInit, \&SIGNALduino_Connect); + return ; } ############################# package main -sub SIGNALduino_CloseDevice($) { - my ($hash) = @_; +sub SIGNALduino_CloseDevice { + my ($hash) = @_; - $hash->{logMethod}->($hash->{NAME}, 2, "$hash->{NAME}: CloseDevice, closed"); - RemoveInternalTimer($hash); - DevIo_CloseDev($hash); - readingsSingleUpdate($hash, "state", "closed", 1); + $hash->{logMethod}->($hash->{NAME}, 2, "$hash->{NAME}: CloseDevice, closed"); + RemoveInternalTimer($hash); + DevIo_CloseDev($hash); + readingsSingleUpdate($hash, 'state', 'closed', 1); - return ; + return ; } ############################# package main -sub SIGNALduino_DoInit($) { - my $hash = shift; - my $name = $hash->{NAME}; - my $err; - my $msg = undef; +sub SIGNALduino_DoInit { + my $hash = shift; + my $name = $hash->{NAME}; + my $err; + my $msg = undef; - my ($ver, $try) = ("", 0); - #Dirty hack to allow initialisation of DirectIO Device for some debugging and tesing + my ($ver, $try) = ('', 0); + #Dirty hack to allow initialisation of DirectIO Device for some debugging and tesing - delete($hash->{disConnFlag}) if defined($hash->{disConnFlag}); + delete($hash->{disConnFlag}) if defined($hash->{disConnFlag}); - RemoveInternalTimer("HandleWriteQueue:$name"); - @{$hash->{QUEUE}} = (); - $hash->{sendworking} = 0; + RemoveInternalTimer("HandleWriteQueue:$name"); + @{$hash->{QUEUE}} = (); + $hash->{sendworking} = 0; - if (($hash->{DEF} !~ m/\@directio/) and ($hash->{DEF} !~ m/none/) ) - { - $hash->{logMethod}->($hash, 1, "$name: DoInit, ".$hash->{DEF}); - $hash->{initretry} = 0; - RemoveInternalTimer($hash); + if (($hash->{DEF} !~ m/\@directio/) and ($hash->{DEF} !~ m/none/) ) + { + $hash->{logMethod}->($hash, 1, "$name: DoInit, ".$hash->{DEF}); + $hash->{initretry} = 0; + RemoveInternalTimer($hash); - #SIGNALduino_SimpleWrite($hash, "XQ"); # Disable receiver - InternalTimer(gettimeofday() + SDUINO_INIT_WAIT_XQ, \&SIGNALduino_SimpleWrite_XQ, $hash, 0); - InternalTimer(gettimeofday() + SDUINO_INIT_WAIT, \&SIGNALduino_StartInit, $hash, 0); - } - # Reset the counter - delete($hash->{XMIT_TIME}); - delete($hash->{NR_CMD_LAST_H}); + #SIGNALduino_SimpleWrite($hash, 'XQ'); # Disable receiver + InternalTimer(gettimeofday() + SDUINO_INIT_WAIT_XQ, \&SIGNALduino_SimpleWrite_XQ, $hash, 0); + InternalTimer(gettimeofday() + SDUINO_INIT_WAIT, \&SIGNALduino_StartInit, $hash, 0); + } + # Reset the counter + delete($hash->{XMIT_TIME}); + delete($hash->{NR_CMD_LAST_H}); - return; - return ; + return; } ############################# package main # Disable receiver -sub SIGNALduino_SimpleWrite_XQ($) { - my ($hash) = @_; - my $name = $hash->{NAME}; +sub SIGNALduino_SimpleWrite_XQ { + my ($hash) = @_; + my $name = $hash->{NAME}; - $hash->{logMethod}->($hash, 3, "$name: SimpleWrite_XQ, disable receiver (XQ)"); - SIGNALduino_SimpleWrite($hash, "XQ"); - #DevIo_SimpleWrite($hash, "XQ\n",2); + $hash->{logMethod}->($hash, 3, "$name: SimpleWrite_XQ, disable receiver (XQ)"); + SIGNALduino_SimpleWrite($hash, 'XQ'); + #DevIo_SimpleWrite($hash, "XQ\n",2); } -############################# package main -sub SIGNALduino_StartInit($) { - my ($hash) = @_; - my $name = $hash->{NAME}; - $hash->{version} = undef; +############################# package main, test exists +sub SIGNALduino_StartInit { + my ($hash) = @_; + my $name = $hash->{NAME}; + $hash->{version} = undef; - $hash->{logMethod}->($name,3 , "$name: StartInit, get version, retry = " . $hash->{initretry}); - if ($hash->{initretry} >= SDUINO_INIT_MAXRETRY) { - $hash->{DevState} = 'INACTIVE'; - # einmaliger reset, wenn danach immer noch 'init retry count reached', dann SIGNALduino_CloseDevice() - if (!defined($hash->{initResetFlag})) { - $hash->{logMethod}->($name,2 , "$name: StartInit, retry count reached. Reset"); - $hash->{initResetFlag} = 1; - SIGNALduino_ResetDevice($hash); - } else { - $hash->{logMethod}->($name,2 , "$name: StartInit, init retry count reached. Closed"); - SIGNALduino_CloseDevice($hash); - } - return; - } - else { - $hash->{ucCmd}->{cmd} = "version"; - $hash->{ucCmd}->{responseSub} = \&SIGNALduino_CheckVersionResp; - $hash->{ucCmd}->{timenow} = time(); - SIGNALduino_SimpleWrite($hash, "V"); - #DevIo_SimpleWrite($hash, "V\n",2); - $hash->{DevState} = 'waitInit'; - RemoveInternalTimer($hash); - InternalTimer(gettimeofday() + SDUINO_CMD_TIMEOUT, \&SIGNALduino_CheckVersionResp, $hash, 0); - } + $hash->{logMethod}->($name,3 , "$name: StartInit, get version, retry = " . $hash->{initretry}); + if ($hash->{initretry} >= SDUINO_INIT_MAXRETRY) { + $hash->{DevState} = 'INACTIVE'; + # einmaliger reset, wenn danach immer noch 'init retry count reached', dann SIGNALduino_CloseDevice() + if (!defined($hash->{initResetFlag})) { + $hash->{logMethod}->($name,2 , "$name: StartInit, retry count reached. Reset"); + $hash->{initResetFlag} = 1; + SIGNALduino_ResetDevice($hash); + } else { + $hash->{logMethod}->($name,2 , "$name: StartInit, init retry count reached. Closed"); + SIGNALduino_CloseDevice($hash); + } + return; + } + else { + $hash->{ucCmd}->{cmd} = 'version'; + $hash->{ucCmd}->{responseSub} = \&SIGNALduino_CheckVersionResp; + $hash->{ucCmd}->{timenow} = time(); + SIGNALduino_SimpleWrite($hash, 'V'); + #DevIo_SimpleWrite($hash, "V\n",2); + $hash->{DevState} = 'waitInit'; + RemoveInternalTimer($hash); + InternalTimer(gettimeofday() + SDUINO_CMD_TIMEOUT, \&SIGNALduino_CheckVersionResp, $hash, 0); + } } -############################# package main -sub SIGNALduino_CheckVersionResp -{ - my ($hash,$msg) = @_; - my $name = $hash->{NAME}; +############################# package main, test exists +sub SIGNALduino_CheckVersionResp { + my ($hash,$msg) = @_; + my $name = $hash->{NAME}; + ### ToDo, manchmal kommen Mu Nachrichten in $msg und somit ist keine Version feststellbar !!! + if (defined($msg)) { + $hash->{logMethod}->($hash, 5, "$name: CheckVersionResp, called with $msg"); + if ($msg =~ m/($gets{$hash->{ucCmd}->{cmd}}[4])/ ) { + $hash->{version} = $1; + } else { + delete $hash->{version}; + } + } else { + $hash->{logMethod}->($hash, 5, "$name: CheckVersionResp, called without msg"); + # Aufruf durch Timeout! + $msg='undef'; + delete($hash->{ucCmd}); + } - ### ToDo, manchmal kommen Mu Nachrichten in $msg und somit ist keine Version feststellbar !!! - if (defined($msg)) { - $hash->{logMethod}->($hash, 5, "$name: CheckVersionResp, called with $msg"); - $msg =~ m/($gets{$hash->{ucCmd}->{cmd}}[4])/; - $hash->{version} = $1; - } else { - $hash->{logMethod}->($hash, 5, "$name: CheckVersionResp, called without msg"); - # Aufruf durch Timeout! - $msg="undef"; - delete($hash->{ucCmd}); - } + if (!defined($hash->{version}) ) { + $msg = "$name: CheckVersionResp, Not an SIGNALduino device, got for V: $msg"; + $hash->{logMethod}->($hash, 1, $msg); + readingsSingleUpdate($hash, 'state', 'no SIGNALduino found', 1); #uncoverable statement because state is overwritten by SIGNALduino_CloseDevice + $hash->{initretry} ++; + SIGNALduino_StartInit($hash); + } elsif($hash->{version} =~ m/^V 3\.1\./) { + $msg = "$name: CheckVersionResp, Version of your arduino is not compatible, please flash new firmware. (device closed) Got for V: $msg"; + readingsSingleUpdate($hash, 'state', 'unsupported firmware found', 1); #uncoverable statement because state is overwritten by SIGNALduino_CloseDevice + $hash->{logMethod}->($hash, 1, $msg); + $hash->{DevState} = 'INACTIVE'; + SIGNALduino_CloseDevice($hash); + } else { + if (exists($hash->{DevState}) && $hash->{DevState} eq 'waitInit') { + RemoveInternalTimer($hash); + } - if (!defined($hash->{version}) ) { - $msg = "$name: CheckVersionResp, Not an SIGNALduino device, got for V: $msg"; - $hash->{logMethod}->($hash, 1, $msg); - readingsSingleUpdate($hash, "state", "no SIGNALduino found", 1); #uncoverable statement because state is overwritten by SIGNALduino_CloseDevice - $hash->{initretry} ++; - SIGNALduino_StartInit($hash); - } elsif($hash->{version} =~ m/^V 3\.1\./) { - $msg = "$name: CheckVersionResp, Version of your arduino is not compatible, please flash new firmware. (device closed) Got for V: $msg"; - readingsSingleUpdate($hash, "state", "unsupported firmware found", 1); #uncoverable statement because state is overwritten by SIGNALduino_CloseDevice - $hash->{logMethod}->($hash, 1, $msg); - $hash->{DevState} = 'INACTIVE'; - SIGNALduino_CloseDevice($hash); - } else { - if (exists($hash->{DevState}) && $hash->{DevState} eq 'waitInit') { - RemoveInternalTimer($hash); - } + readingsSingleUpdate($hash, 'state', 'opened', 1); + $hash->{logMethod}->($name, 2, "$name: CheckVersionResp, initialized " . SDUINO_VERSION); + delete($hash->{initResetFlag}) if defined($hash->{initResetFlag}); + SIGNALduino_SimpleWrite($hash, 'XE'); # Enable receiver + $hash->{logMethod}->($hash, 3, "$name: CheckVersionResp, enable receiver (XE) "); + delete($hash->{initretry}); + # initialize keepalive + $hash->{keepalive}{ok} = 0; + $hash->{keepalive}{retry} = 0; + InternalTimer(gettimeofday() + SDUINO_KEEPALIVE_TIMEOUT, \&SIGNALduino_KeepAlive, $hash, 0); + if ($hash->{version} =~ m/cc1101/) { + $hash->{cc1101_available} = 1; + $hash->{logMethod}->($name, 5, "$name: CheckVersionResp, cc1101 available"); + SIGNALduino_Get($hash, $name,'ccconf'); + SIGNALduino_Get($hash, $name,'ccpatable'); + } else { + # connect device without cc1101 to port where a device with cc1101 was previously connected (example DEF with /dev/ttyUSB0@57600) # + $hash->{logMethod}->($hash, 5, "$name: CheckVersionResp, delete old READINGS from cc1101 device"); + if ( exists($hash->{cc1101_available}) ) { + delete($hash->{cc1101_available}); + }; - readingsSingleUpdate($hash, "state", "opened", 1); - $hash->{logMethod}->($name, 2, "$name: CheckVersionResp, initialized " . SDUINO_VERSION); - delete($hash->{initResetFlag}) if defined($hash->{initResetFlag}); - SIGNALduino_SimpleWrite($hash, "XE"); # Enable receiver - $hash->{logMethod}->($hash, 3, "$name: CheckVersionResp, enable receiver (XE) "); - delete($hash->{initretry}); - # initialize keepalive - $hash->{keepalive}{ok} = 0; - $hash->{keepalive}{retry} = 0; - InternalTimer(gettimeofday() + SDUINO_KEEPALIVE_TIMEOUT, \&SIGNALduino_KeepAlive, $hash, 0); - if ($hash->{version} =~ m/cc1101/) { - $hash->{cc1101_available} = 1; - $hash->{logMethod}->($name, 5, "$name: CheckVersionResp, cc1101 available"); - SIGNALduino_Get($hash, $name,"ccconf"); - SIGNALduino_Get($hash, $name,"ccpatable"); - } - $hash->{DevState} = 'initialized'; - $msg = $hash->{version}; - } - return ($msg,undef); + for my $readingName ( qw(cc1101_config cc1101_config_ext cc1101_patable) ) { + readingsDelete($hash,$readingName); + } + } + $hash->{DevState} = 'initialized'; + $msg = $hash->{version}; + } + return ($msg,undef); } -############################# package main +############################# package main, test exists # Todo: SUB kann entfernt werden -sub SIGNALduino_CheckCmdResp($) { - my ($hash) = @_; - my $name = $hash->{NAME}; - my $msg = undef; - my $ver; +sub SIGNALduino_CheckCmdResp { + my ($hash) = @_; + my $name = $hash->{NAME}; + my $msg = undef; + my $ver; - if ($hash->{version}) { - $ver = $hash->{version}; - if ($ver !~ m/SIGNAL(duino|ESP)/) { - $msg = "$name: CheckCmdResp, Not an SIGNALduino device, setting attribute dummy=1 got for V: $ver"; - $hash->{logMethod}->($hash, 1, $msg); - readingsSingleUpdate($hash, "state", "no SIGNALduino found", 1); #uncoverable statement because state is overwritten by SIGNALduino_CloseDevice - $hash->{DevState} = 'INACTIVE'; - SIGNALduino_CloseDevice($hash); - } - elsif($ver =~ m/^V 3\.1\./) { - $msg = "$name: CheckCmdResp, Version of your arduino is not compatible, pleas flash new firmware. (device closed) Got for V: $ver"; - readingsSingleUpdate($hash, "state", "unsupported firmware found", 1); #uncoverable statement because state is overwritten by SIGNALduino_CloseDevice - $hash->{logMethod}->($hash, 1, $msg); - $hash->{DevState} = 'INACTIVE'; - SIGNALduino_CloseDevice($hash); - } - else { - readingsSingleUpdate($hash, "state", "opened", 1); - $hash->{logMethod}->($name, 2, "$name: CheckCmdResp, initialized " . SDUINO_VERSION); - $hash->{DevState} = 'initialized'; - delete($hash->{initResetFlag}) if defined($hash->{initResetFlag}); - SIGNALduino_SimpleWrite($hash, "XE"); # Enable receiver - $hash->{logMethod}->($hash, 3, "$name: CheckCmdResp, enable receiver (XE) "); - delete($hash->{initretry}); - # initialize keepalive - $hash->{keepalive}{ok} = 0; - $hash->{keepalive}{retry} = 0; - InternalTimer(gettimeofday() + SDUINO_KEEPALIVE_TIMEOUT, \&SIGNALduino_KeepAlive, $hash, 0); - $hash->{cc1101_available} = 1 if ($ver =~ m/cc1101/); - } - } - else { - delete($hash->{ucCmd}); - $hash->{initretry} ++; - #InternalTimer(gettimeofday()+1, "SIGNALduino_StartInit", $hash, 0); - SIGNALduino_StartInit($hash); - } + if ($hash->{version}) { + $ver = $hash->{version}; + if ($ver !~ m/SIGNAL(duino|ESP)/) { + $msg = "$name: CheckCmdResp, Not an SIGNALduino device, setting attribute dummy=1 got for V: $ver"; + $hash->{logMethod}->($hash, 1, $msg); + readingsSingleUpdate($hash, 'state', 'no SIGNALduino found', 1); #uncoverable statement because state is overwritten by SIGNALduino_CloseDevice + $hash->{DevState} = 'INACTIVE'; + SIGNALduino_CloseDevice($hash); + } + elsif($ver =~ m/^V 3\.1\./) { + $msg = "$name: CheckCmdResp, Version of your arduino is not compatible, pleas flash new firmware. (device closed) Got for V: $ver"; + readingsSingleUpdate($hash, 'state', 'unsupported firmware found', 1); #uncoverable statement because state is overwritten by SIGNALduino_CloseDevice + $hash->{logMethod}->($hash, 1, $msg); + $hash->{DevState} = 'INACTIVE'; + SIGNALduino_CloseDevice($hash); + } + else { + readingsSingleUpdate($hash, 'state', 'opened', 1); + $hash->{logMethod}->($name, 2, "$name: CheckCmdResp, initialized " . SDUINO_VERSION); + $hash->{DevState} = 'initialized'; + delete($hash->{initResetFlag}) if defined($hash->{initResetFlag}); + SIGNALduino_SimpleWrite($hash, 'XE'); # Enable receiver + $hash->{logMethod}->($hash, 3, "$name: CheckCmdResp, enable receiver (XE) "); + delete($hash->{initretry}); + # initialize keepalive + $hash->{keepalive}{ok} = 0; + $hash->{keepalive}{retry} = 0; + InternalTimer(gettimeofday() + SDUINO_KEEPALIVE_TIMEOUT, \&SIGNALduino_KeepAlive, $hash, 0); + $hash->{cc1101_available} = 1 if ($ver =~ m/cc1101/); + } + } + else { + delete($hash->{ucCmd}); + $hash->{initretry} ++; + #InternalTimer(gettimeofday()+1, 'SIGNALduino_StartInit', $hash, 0); + SIGNALduino_StartInit($hash); + } } ############################# package main # Check if the 1% limit is reached and trigger notifies -sub SIGNALduino_XmitLimitCheck($$) { +sub SIGNALduino_XmitLimitCheck { my ($hash,$fn) = @_; return if ($fn !~ m/^(is|S[RCM]).*/); @@ -1423,15 +1569,11 @@ sub SIGNALduino_XmitLimitCheck($$) { my @b = grep { $_ > $nowM1h } @{$hash->{XMIT_TIME}}; if(@b > 163) { # Maximum nr of transmissions per hour (unconfirmed). - my $name = $hash->{NAME}; $hash->{logMethod}->($name, 2, "$name: XmitLimitCheck, TRANSMIT LIMIT EXCEEDED"); - DoTrigger($name, "TRANSMIT LIMIT EXCEEDED"); - + DoTrigger($name, 'TRANSMIT LIMIT EXCEEDED'); } else { - push(@b, $now); - } $hash->{XMIT_TIME} = \@b; $hash->{NR_CMD_LAST_H} = int(@b); @@ -1439,22 +1581,62 @@ sub SIGNALduino_XmitLimitCheck($$) { ############################# package main ## API to logical modules: Provide as Hash of IO Device, type of function ; command to call ; message to send -sub SIGNALduino_Write($$$) { - my ($hash,$fn,$msg) = @_; +sub SIGNALduino_Write { + my $hash = shift // carp 'must be called with hash of iodevice as first param'; + my $fn = shift // 'RAW'; + my $msg = shift // return; my $name = $hash->{NAME}; - if ($fn eq "") { - $fn="RAW" ; - } - elsif($fn eq "04" && substr($msg,0,6) eq "010101") { # FS20 - $fn="sendMsg"; - $msg = substr($msg,6); - $msg = SIGNALduino_PreparingSend_FS20_FHT(74, 6, $msg); - } - elsif($fn eq "04" && substr($msg,0,6) eq "020183") { # FHT - $fn="sendMsg"; - $msg = substr($msg,6,4) . substr($msg,10); # was ist der Unterschied zu "$msg = substr($msg,6);" ? - $msg = SIGNALduino_PreparingSend_FS20_FHT(73, 12, $msg); + if ($fn eq '') { + $fn='RAW' ; + } elsif($fn eq '04') { + my $id; + my $sum; + $fn='sendMsg'; + if (substr($msg,0,6) eq '010101') { # FS20 + $msg = substr($msg,6); + $id = 74; + $sum = 6; + } elsif(substr($msg,0,6) eq '020183') { # FHT + $msg = substr($msg,6,4) . substr($msg,10); + $id = 73; + $sum = 12; + } + $msg = $hash->{protocolObject}->PreparingSend_FS20_FHT($id, $sum, $msg); + } elsif($fn eq 'k') { # KOPP_FC (one part outsourcing in SD_Protocols.pm, main part here due to loop and set hash values) + $hash->{logMethod}->($name, 4, "$name: Write, cmd $fn sending KOPP_FC"); + $fn='raw'; + + my $Keycode = substr($msg,1,2); + my $TransCode1 = substr($msg,3,4); + my $TransCode2 = substr($msg,7,2); + + ### The device to be sent stores something in own hash. Search for names to access them ### + #### The variant with devspec2array does not require any adjustment in the original Kopp module. #### + + my @Liste = devspec2array("TYPE=KOPP_FC:FILTER=TRANSMITTERCODE1=$TransCode1:FILTER=TRANSMITTERCODE2=$TransCode2:FILTER=KEYCODE=$Keycode"); + my $KOPPname = $Liste[0]; + + if (scalar @Liste != 1) { + $hash->{logMethod}->($name, 4, "$name: Write, PreparingSend KOPP_FC found ". scalar @Liste ." device\'s with same DEF (SIGNALduino used $KOPPname)"); + } else { + $hash->{logMethod}->($name, 5, "$name: Write, PreparingSend KOPP_FC found device with name $KOPPname"); + } + + ## Internals blkctr initialize if not available + if (!exists($defs{$KOPPname}->{blkctr})) { + $defs{$KOPPname}->{blkctr} = 0; + $hash->{logMethod}->($name, 5, "$name: Write, PreparingSend KOPP_FC set Internals blkctr on device $KOPPname to 0"); + } + + $msg = $hash->{protocolObject}->PreparingSend_KOPP_FC(sprintf("%02x",$defs{$KOPPname}->{blkctr}),$Keycode,$TransCode1,$TransCode2); + + if (!defined $msg) { + return; + }; + + $defs{$KOPPname}->{blkctr}++; # Internals blkctr increases with each send + $hash->{logMethod}->($name, 5, "$name: Write, PreparingSend KOPP_FC set Internals blkctr on device $KOPPname to ".$defs{$KOPPname}->{blkctr}); } $hash->{logMethod}->($name, 5, "$name: Write, sending via Set $fn $msg"); @@ -1462,7 +1644,7 @@ sub SIGNALduino_Write($$$) { } ############################# package main -sub SIGNALduino_AddSendQueue($$) { +sub SIGNALduino_AddSendQueue { my ($hash, $msg) = @_; my $name = $hash->{NAME}; @@ -1470,35 +1652,40 @@ sub SIGNALduino_AddSendQueue($$) { #SIGNALduino_Log3 $hash , 5, Dumper($hash->{QUEUE}); - $hash->{logMethod}->($hash, 5,"$name: AddSendQueue, " . $hash->{NAME} . ": $msg (" . @{$hash->{QUEUE}} . ")"); - InternalTimer(gettimeofday() + 0.1, \&SIGNALduino_HandleWriteQueue, "HandleWriteQueue:$name") if (scalar @{$hash->{QUEUE}} == 1 && InternalVal($name,"sendworking",0) == 0); + $hash->{logMethod}->($hash, 5,"$name: AddSendQueue, " . $hash->{NAME} . ": $msg (" . @{$hash->{QUEUE}} . ')'); + InternalTimer(gettimeofday(), \&SIGNALduino_HandleWriteQueue, "HandleWriteQueue:$name") if (scalar @{$hash->{QUEUE}} == 1 && InternalVal($name,'sendworking',0) == 0); } -############################# package main -sub SIGNALduino_SendFromQueue($$) { +############################# package main, test exists +sub SIGNALduino_SendFromQueue { my ($hash, $msg) = @_; my $name = $hash->{NAME}; - $hash->{logMethod}->($name, 4, "$name: SendFromQueue, called"); - if($msg ne "") { - SIGNALduino_XmitLimitCheck($hash,$msg); + $hash->{logMethod}->($name, 4, "$name: SendFromQueue, called"); + if($msg ne '') { + SIGNALduino_XmitLimitCheck($hash,$msg); #DevIo_SimpleWrite($hash, $msg . "\n", 2); $hash->{sendworking} = 1; SIGNALduino_SimpleWrite($hash,$msg); - if ($msg =~ m/^S[RCM];/) { - $hash->{ucCmd}->{cmd} = 'sendraw'; - $hash->{ucCmd}->{timenow} = time(); - $hash->{ucCmd}->{responseSub} = \&SIGNALduino_CheckSendRawResponse; - $hash->{logMethod}->($name, 4, "$name: SendFromQueue, msg=$msg"); # zu testen der Queue, kann wenn es funktioniert auskommentiert werden - } elsif ($msg =~ "^e") { # Werkseinstellungen - SIGNALduino_Get($hash,$name,"ccconf"); - SIGNALduino_Get($hash,$name,"ccpatable"); - } elsif ($msg =~ "^W(?:0F|10|11|1D|12|1F)") { # SetFreq, setrAmpl, Set_bWidth, SetSens - SIGNALduino_Get($hash,$name,"ccconf"); - } elsif ($msg =~ "^x") { # patable - SIGNALduino_Get($hash,$name,"ccpatable"); + if ($msg =~ m/^S[RCMN];/) { + $hash->{ucCmd}->{cmd} = 'sendraw'; + $hash->{ucCmd}->{timenow} = time(); + $hash->{ucCmd}->{responseSub} = \&SIGNALduino_CheckSendRawResponse; + $hash->{logMethod}->($name, 4, "$name: SendFromQueue, msg=$msg"); # zu testen der Queue, kann wenn es funktioniert auskommentiert werden + } elsif ($msg =~ "^e") { # Werkseinstellungen + SIGNALduino_Get($hash,$name,'ccconf'); + SIGNALduino_Get($hash,$name,'ccpatable'); + + ## set rfmode to default from uC + my $rfmode = AttrVal($name, 'rfmode', undef); + CommandAttr($hash,"$name rfmode SlowRF") if (defined $rfmode && $rfmode ne 'SlowRF'); # option with save question mark + + } elsif ($msg =~ "^W(?:0F|10|11|1D|12|17|1F)") { # SetFreq, setrAmpl, Set_bWidth, SetDeviatn, SetSens + SIGNALduino_Get($hash,$name,'ccconf'); + } elsif ($msg =~ "^x") { # patable + SIGNALduino_Get($hash,$name,'ccpatable'); } -# elsif ($msg eq "C99") { +# elsif ($msg eq 'C99') { # $hash->{ucCmd}->{cmd} = 'ccregAll'; # $hash->{ucCmd}->{responseSub} = \&SIGNALduino_CheckCcregResponse; # @@ -1517,7 +1704,7 @@ sub SIGNALduino_SendFromQueue($$) { } ############################# package main -sub SIGNALduino_HandleWriteQueue($) { +sub SIGNALduino_HandleWriteQueue { my($param) = @_; my(undef,$name) = split(':', $param); my $hash = $defs{$name}; @@ -1535,26 +1722,26 @@ sub SIGNALduino_HandleWriteQueue($) { if(exists($hash->{QUEUE}) && @{$hash->{QUEUE}}) { my $msg= shift(@{$hash->{QUEUE}}); - if($msg eq "") { + if($msg eq '') { SIGNALduino_HandleWriteQueue("x:$name"); } else { SIGNALduino_SendFromQueue($hash, $msg); } } else { - $hash->{logMethod}->($name, 4, "$name: HandleWriteQueue, nothing to send, stopping timer"); - RemoveInternalTimer("HandleWriteQueue:$name"); + $hash->{logMethod}->($name, 4, "$name: HandleWriteQueue, nothing to send, stopping timer"); + RemoveInternalTimer("HandleWriteQueue:$name"); } } -############################# package main +############################# package main, test exists # called from the global loop, when the select for hash->{FD} reports data -sub SIGNALduino_Read($) { +sub SIGNALduino_Read { my ($hash) = @_; my $buf = DevIo_SimpleRead($hash); - return "" if(!defined($buf)); + return '' if(!defined($buf)); my $name = $hash->{NAME}; - my $debug = AttrVal($name,"debug",0); + my $debug = AttrVal($name,'debug',0); my $SIGNALduinodata = $hash->{PARTIAL}; $hash->{logMethod}->($name, 5, "$name: Read, RAW: $SIGNALduinodata/$buf") if ($debug); @@ -1566,148 +1753,150 @@ sub SIGNALduino_Read($) { $rmsg =~ s/\r//; if ($rmsg =~ m/^\002(M(s|u|o);.*;)\003/) { - $rmsg =~ s/^\002//; # \002 am Anfang entfernen - my @msg_parts = split(";",$rmsg); - my $m0; - my $mnr0; - my $m1; - my $mL; - my $mH; - my $part = ""; - my $partD; - $hash->{logMethod}->($name, 5, "$name: Read, RAW rmsg: $rmsg"); + $rmsg =~ s/^\002//; # \002 am Anfang entfernen + my @msg_parts = split(';',$rmsg); + my $m0; + my $mnr0; + my $m1; + my $mL; + my $mH; + my $part = ''; + my $partD; + $hash->{logMethod}->($name, 5, "$name: Read, RAW rmsg: $rmsg"); - foreach my $msgPart (@msg_parts) { - next if ($msgPart eq ""); - $m0 = substr($msgPart,0,1); - $mnr0 = ord($m0); - $m1 = substr($msgPart,1); - if ($m0 eq "M") { - $part .= "M" . uc($m1) . ";"; - } - elsif ($mnr0 > 127) { - $part .= "P" . sprintf("%u", ($mnr0 & 7)) . "="; - if (length($m1) == 2) { - $mL = ord(substr($m1,0,1)) & 127; # Pattern low - $mH = ord(substr($m1,1,1)) & 127; # Pattern high - if (($mnr0 & 0b00100000) != 0) { # Vorzeichen 0b00100000 = 32 - $part .= "-"; - } - if ($mnr0 & 0b00010000) { # Bit 7 von Pattern low - $mL += 128; - } - $part .= ($mH * 256) + $mL; - } - $part .= ";"; - } - elsif (($m0 eq "D" || $m0 eq "d") && length($m1) > 0) { - my @arrayD = split(//, $m1); - $part .= "D="; - $partD = ""; - foreach my $D (@arrayD) { - $mH = ord($D) >> 4; - $mL = ord($D) & 7; - $partD .= "$mH$mL"; - } - #SIGNALduino_Log3 $name, 3, "$name: Read, msg READredu1$m0: $partD"; - if ($m0 eq "d") { - $partD =~ s/.$//; # letzte Ziffer entfernen wenn Anzahl der Ziffern ungerade - } - $partD =~ s/^8//; # 8 am Anfang entfernen - #SIGNALduino_Log3 $name, 3, "$name: Read, msg READredu2$m0: $partD"; - $part = $part . $partD . ';'; - } - elsif (($m0 eq "C" || $m0 eq "S") && length($m1) == 1) { - $part .= "$m0" . "P=$m1;"; - } - elsif ($m0 eq "o" || $m0 eq "m") { - $part .= "$m0$m1;"; - } - elsif ($m1 =~ m/^[0-9A-Z]{1,2}$/) { # bei 1 oder 2 Hex Ziffern nach Dez wandeln - $part .= "$m0=" . hex($m1) . ";"; - } - elsif ($m0 =~m/[0-9a-zA-Z]/) { - $part .= "$m0"; - if ($m1 ne "") { - $part .= "=$m1"; - } - $part .= ";"; - } - } - $hash->{logMethod}->($name, 4, "$name: Read, msg READredu: $part"); - $rmsg = "\002$part\003"; - } - else { - $hash->{logMethod}->($name, 4, "$name: Read, msg: $rmsg"); - } + foreach my $msgPart (@msg_parts) { + next if ($msgPart eq ''); + $m0 = substr($msgPart,0,1); + $mnr0 = ord($m0); + $m1 = substr($msgPart,1); + if ($m0 eq 'M') { + $part .= 'M' . uc($m1) . ';'; + } + elsif ($mnr0 > 127) { + $part .= 'P' . sprintf("%u", ($mnr0 & 7)) . '='; + if (length($m1) == 2) { + $mL = ord(substr($m1,0,1)) & 127; # Pattern low + $mH = ord(substr($m1,1,1)) & 127; # Pattern high + if (($mnr0 & 0b00100000) != 0) { # Vorzeichen 0b00100000 = 32 + $part .= '-'; + } + if ($mnr0 & 0b00010000) { # Bit 7 von Pattern low + $mL += 128; + } + $part .= ($mH * 256) + $mL; + } + $part .= ';'; + } + elsif (($m0 eq 'D' || $m0 eq 'd') && length($m1) > 0) { + my @arrayD = split(//, $m1); + $part .= 'D='; + $partD = ''; + foreach my $D (@arrayD) { + $mH = ord($D) >> 4; + $mL = ord($D) & 7; + $partD .= "$mH$mL"; + } + #SIGNALduino_Log3 $name, 3, "$name: Read, msg READredu1$m0: $partD"; + if ($m0 eq 'd') { + $partD =~ s/.$//; # letzte Ziffer entfernen wenn Anzahl der Ziffern ungerade + } + $partD =~ s/^8//; # 8 am Anfang entfernen + #SIGNALduino_Log3 $name, 3, "$name: Read, msg READredu2$m0: $partD"; + $part = $part . $partD . ';'; + } + elsif (($m0 eq 'C' || $m0 eq 'S') && length($m1) == 1) { + $part .= "$m0" . "P=$m1;"; + } + elsif ($m0 eq 'o' || $m0 eq 'm') { + $part .= "$m0$m1;"; + } + elsif ($m1 =~ m/^[0-9A-Z]{1,2}$/) { # bei 1 oder 2 Hex Ziffern nach Dez wandeln + $part .= "$m0=" . hex($m1) . ';'; + } + elsif ($m0 =~m/[0-9a-zA-Z]/) { + $part .= "$m0"; + if ($m1 ne '') { + $part .= "=$m1"; + } + $part .= ';'; + } + } + $hash->{logMethod}->($name, 4, "$name: Read, msg READredu: $part"); + $rmsg = "\002$part\003"; + } + else { + $hash->{logMethod}->($name, 4, "$name: Read, msg: $rmsg"); + } - if ( $rmsg && !SIGNALduino_Parse($hash, $hash, $name, $rmsg) && exists($hash->{ucCmd}) && defined($hash->{ucCmd}->{cmd})) - { - my $regexp = exists($gets{$hash->{ucCmd}->{cmd}}) && exists($gets{$hash->{ucCmd}->{cmd}}[4]) ? $gets{$hash->{ucCmd}->{cmd}}[4] : ".*"; - if (exists($hash->{ucCmd}->{responseSub}) && ref $hash->{ucCmd}->{responseSub} eq "CODE") { - $hash->{logMethod}->($name, 5, "$name: Read, msg: regexp=$regexp cmd=$hash->{ucCmd}->{cmd} msg=$rmsg"); - my $returnMessage ; - my $event; - if (!exists($gets{$hash->{ucCmd}->{cmd}}) || !exists($gets{$hash->{ucCmd}->{cmd}}[4]) || $rmsg =~ /$regexp/) - { - ($returnMessage,$event) = $hash->{ucCmd}->{responseSub}->($hash,$rmsg) ; - readingsSingleUpdate($hash, $hash->{ucCmd}->{cmd}, $returnMessage, $event) if (defined($returnMessage) && defined($event)); - if (exists($hash->{ucCmd}->{asyncOut})) { - $hash->{logMethod}->($name, 5, "$name: Read, try asyncOutput of message $returnMessage"); - my $ao = undef; - $ao = asyncOutput( $hash->{ucCmd}->{asyncOut}, $hash->{ucCmd}->{cmd}.": " . $returnMessage ) if (defined($returnMessage)); - $hash->{logMethod}->($name, 5, "$name: Read, asyncOutput failed $ao") if (defined($ao)); - } - delete($hash->{ucCmd}); - } + if ( $rmsg && !SIGNALduino_Parse($hash, $hash, $name, $rmsg) && exists($hash->{ucCmd}) && defined($hash->{ucCmd}->{cmd})) + { + my $regexp = exists($gets{$hash->{ucCmd}->{cmd}}) && exists($gets{$hash->{ucCmd}->{cmd}}[4]) ? $gets{$hash->{ucCmd}->{cmd}}[4] : ".*"; + if (exists($hash->{ucCmd}->{responseSub}) && ref $hash->{ucCmd}->{responseSub} eq 'CODE') { + $hash->{logMethod}->($name, 5, "$name: Read, msg: regexp=$regexp cmd=$hash->{ucCmd}->{cmd} msg=$rmsg"); + my $returnMessage ; + my $event; + if (!exists($gets{$hash->{ucCmd}->{cmd}}) || !exists($gets{$hash->{ucCmd}->{cmd}}[4]) || $rmsg =~ /$regexp/) + { + ($returnMessage,$event) = $hash->{ucCmd}->{responseSub}->($hash,$rmsg) ; + readingsSingleUpdate($hash, $hash->{ucCmd}->{cmd}, $returnMessage, $event) if (defined($returnMessage) && defined($event)); + if (exists($hash->{ucCmd}->{asyncOut})) { + $hash->{logMethod}->($name, 5, "$name: Read, try asyncOutput of message $returnMessage"); + my $ao = undef; + $ao = asyncOutput( $hash->{ucCmd}->{asyncOut}, $hash->{ucCmd}->{cmd}.': ' . $returnMessage ) if (defined($returnMessage)); + $hash->{logMethod}->($name, 5, "$name: Read, asyncOutput failed $ao") if (defined($ao)); + } + if ( exists $hash->{ucCmd} && defined $hash->{ucCmd}->{cmd} && $hash->{ucCmd}->{cmd} ne "sendraw" ) { + delete $hash->{ucCmd} ; + } + } - if (exists($hash->{keepalive})) { - $hash->{keepalive}{ok} = 1; - $hash->{keepalive}{retry} = 0; - } - } else { - $hash->{logMethod}->($name, 4, "$name: Read, msg: Received answer ($rmsg) for ". $hash->{ucCmd}->{cmd}." does not match $regexp / coderef"); - } - } + if (exists($hash->{keepalive})) { + $hash->{keepalive}{ok} = 1; + $hash->{keepalive}{retry} = 0; + } + } else { + $hash->{logMethod}->($name, 4, "$name: Read, msg: Received answer ($rmsg) for ". $hash->{ucCmd}->{cmd}." does not match $regexp / coderef"); + } + } } $hash->{PARTIAL} = $SIGNALduinodata; } ############################# package main -sub SIGNALduino_KeepAlive($){ - my ($hash) = @_; - my $name = $hash->{NAME}; +sub SIGNALduino_KeepAlive{ + my ($hash) = @_; + my $name = $hash->{NAME}; - return if ($hash->{DevState} eq 'disconnected'); + return if ($hash->{DevState} eq 'disconnected'); - #SIGNALduino_Log3 $name,4 , "$name: KeepAliveOk, " . $hash->{keepalive}{ok}; - if (!$hash->{keepalive}{ok}) { - delete($hash->{ucCmd}); - if ($hash->{keepalive}{retry} >= SDUINO_KEEPALIVE_MAXRETRY) { - $hash->{logMethod}->($name,3 , "$name: KeepAlive, not ok, retry count reached. Reset"); - $hash->{DevState} = 'INACTIVE'; - SIGNALduino_ResetDevice($hash); - return; - } - else { - my $logLevel = 3; - $hash->{keepalive}{retry} ++; - if ($hash->{keepalive}{retry} == 1) { - $logLevel = 4; - } - $hash->{logMethod}->($name, $logLevel, "$name: KeepAlive, not ok, retry = " . $hash->{keepalive}{retry} . " -> get ping"); - $hash->{ucCmd}->{cmd} = "ping"; - $hash->{ucCmd}->{timenow} = time(); - $hash->{ucCmd}->{responseSub} = \&SIGNALduino_GetResponseUpdateReading; - SIGNALduino_AddSendQueue($hash, "P"); - } - } - else { - $hash->{logMethod}->($name,4 , "$name: KeepAlive, ok, retry = " . $hash->{keepalive}{retry}); - } - $hash->{keepalive}{ok} = 0; + #SIGNALduino_Log3 $name,4 , "$name: KeepAliveOk, " . $hash->{keepalive}{ok}; + if (!$hash->{keepalive}{ok}) { + delete($hash->{ucCmd}); + if ($hash->{keepalive}{retry} >= SDUINO_KEEPALIVE_MAXRETRY) { + $hash->{logMethod}->($name,3 , "$name: KeepAlive, not ok, retry count reached. Reset"); + $hash->{DevState} = 'INACTIVE'; + SIGNALduino_ResetDevice($hash); + return; + } + else { + my $logLevel = 3; + $hash->{keepalive}{retry} ++; + if ($hash->{keepalive}{retry} == 1) { + $logLevel = 4; + } + $hash->{logMethod}->($name, $logLevel, "$name: KeepAlive, not ok, retry = " . $hash->{keepalive}{retry} . ' -> get ping'); + $hash->{ucCmd}->{cmd} = 'ping'; + $hash->{ucCmd}->{timenow} = time(); + $hash->{ucCmd}->{responseSub} = \&SIGNALduino_GetResponseUpdateReading; + SIGNALduino_AddSendQueue($hash, 'P'); + } + } + else { + $hash->{logMethod}->($name,4 , "$name: KeepAlive, ok, retry = " . $hash->{keepalive}{retry}); + } + $hash->{keepalive}{ok} = 0; - InternalTimer(gettimeofday() + SDUINO_KEEPALIVE_TIMEOUT, \&SIGNALduino_KeepAlive, $hash); + InternalTimer(gettimeofday() + SDUINO_KEEPALIVE_TIMEOUT, \&SIGNALduino_KeepAlive, $hash); } @@ -1716,51 +1905,48 @@ sub SIGNALduino_KeepAlive($){ ############################# package main ## Parses a HTTP Response for example for flash via http download sub SIGNALduino_ParseHttpResponse { + my ($param, $err, $data) = @_; + my $hash = $param->{hash}; + my $name = $hash->{NAME}; - my ($param, $err, $data) = @_; - my $hash = $param->{hash}; - my $name = $hash->{NAME}; - - if($err ne "") # wenn ein Fehler bei der HTTP Abfrage aufgetreten ist - { - $hash->{logMethod}->($name, 3, "$name: ParseHttpResponse, error while requesting ".$param->{url}." - $err"); # Eintrag fuers Log - } - elsif($param->{code} eq "200" && $data ne "") # wenn die Abfrage erfolgreich war ($data enthaelt die Ergebnisdaten des HTTP Aufrufes) + if($err ne '') # wenn ein Fehler bei der HTTP Abfrage aufgetreten ist + { + $hash->{logMethod}->($name, 3, "$name: ParseHttpResponse, error while requesting ".$param->{url}." - $err"); # Eintrag fuers Log + } + elsif($param->{code} eq '200' && $data ne '') # wenn die Abfrage erfolgreich war ($data enthaelt die Ergebnisdaten des HTTP Aufrufes) { + $hash->{logMethod}->($name, 3, "$name: ParseHttpResponse, url ".$param->{url}.' returned: '.length($data).' bytes Data'); # Eintrag fuers Log - $hash->{logMethod}->($name, 3, "$name: ParseHttpResponse, url ".$param->{url}." returned: ".length($data)." bytes Data"); # Eintrag fuers Log + if ($param->{command} eq 'flash') + { + my $filename; - if ($param->{command} eq "flash") - { - my $filename; + if ($param->{httpheader} =~ /Content-Disposition: attachment;.?filename=\"?([-+.\w]+)?\"?/) + { + $filename = $1; + } else { # Filename via path if not specifyied via Content-Disposition + $param->{path} =~ /\/([-+.\w]+)$/; #(?:[^\/][\d\w\.]+)+$ \/([-+.\w]+)$ + $filename = $1; + } + $hash->{logMethod}->($name, 3, "$name: ParseHttpResponse, Downloaded $filename firmware from ".$param->{host}); + $hash->{logMethod}->($name, 5, "$name: ParseHttpResponse, Header = ".$param->{httpheader}); - if ($param->{httpheader} =~ /Content-Disposition: attachment;.?filename=\"?([-+.\w]+)?\"?/) - { - $filename = $1; - } else { # Filename via path if not specifyied via Content-Disposition - $param->{path} =~ /\/([-+.\w]+)$/; #(?:[^\/][\d\w\.]+)+$ \/([-+.\w]+)$ - $filename = $1; - } - $hash->{logMethod}->($name, 3, "$name: ParseHttpResponse, Downloaded $filename firmware from ".$param->{host}); - $hash->{logMethod}->($name, 5, "$name: ParseHttpResponse, Header = ".$param->{httpheader}); + $filename = 'FHEM/firmware/' . $filename; + open(my $file, '>', $filename) or die $!; + print $file $data; + close $file; + # Den Flash Befehl mit der soebene heruntergeladenen Datei ausfuehren + #SIGNALduino_Log3 $name, 3, "$name: ParseHttpResponse, calling set ".$param->{command}." $filename"; # Eintrag fuers Log - $filename = "FHEM/firmware/" . $filename; - open(my $file, ">", $filename) or die $!; - print $file $data; - close $file; - - # Den Flash Befehl mit der soebene heruntergeladenen Datei ausfuehren - #SIGNALduino_Log3 $name, 3, "$name: ParseHttpResponse, calling set ".$param->{command}." $filename"; # Eintrag fuers Log - - my $set_return = SIGNALduino_Set($hash,$name,$param->{command},$filename); # $hash->{SetFn} - if (defined($set_return)) - { - $hash->{logMethod}->($name ,3, "$name: ParseHttpResponse, Error while flashing: $set_return"); - } - } + my $set_return = SIGNALduino_Set($hash,$name,$param->{command},$filename); # $hash->{SetFn} + if (defined($set_return)) + { + $hash->{logMethod}->($name ,3, "$name: ParseHttpResponse, Error while flashing: $set_return"); + } + } } else { - $hash->{logMethod}->($name, 3, "$name: ParseHttpResponse, undefined error while requesting ".$param->{url}." - $err - code=".$param->{code}); # Eintrag fuers Log + $hash->{logMethod}->($name, 3, "$name: ParseHttpResponse, undefined error while requesting ".$param->{url}." - $err - code=".$param->{code}); # Eintrag fuers Log } } @@ -1775,9 +1961,9 @@ sub SIGNALduino_splitMsg { ############################# package main # $value - $set <= $tolerance -sub SIGNALduino_inTol($$$) { - #Debug "sduino abs \($_[0] - $_[1]\) <= $_[2] "; - return (abs($_[0]-$_[1])<=$_[2]); +sub SIGNALduino_inTol { + #Debug "sduino abs \($_[0] - $_[1]\) <= $_[2] "; + return (abs($_[0]-$_[1])<=$_[2]); } @@ -1787,18 +1973,18 @@ sub SIGNALduino_inTol($$$) { # Retruns 1 on success or 0 if symbol was not found sub SIGNALduino_FillPatternLookupTable { - my ($hash,$symbol,$representation,$patternList,$rawData,$patternLookupHash,$endPatternLookupHash,$rtext) = @_; - my $pstr=undef; - if (($pstr=SIGNALduino_PatternExists($hash, $symbol,$patternList,$rawData)) >=0) { - ${$rtext} = $pstr; - $patternLookupHash->{$pstr}=${$representation}; ## Append to lookuptable - chop $pstr; - $endPatternLookupHash->{$pstr} = ${$representation} if (!exists($endPatternLookupHash->{$pstr})); ## Append shortened string to lookuptable - return 1; - } else { - ${$rtext} = ""; - return 0; - } + my ($hash,$symbol,$representation,$patternList,$rawData,$patternLookupHash,$endPatternLookupHash,$rtext) = @_; + my $pstr=undef; + if (($pstr=SIGNALduino_PatternExists($hash, $symbol,$patternList,$rawData)) >=0) { + ${$rtext} = $pstr; + $patternLookupHash->{$pstr}=${$representation}; ## Append to lookuptable + chop $pstr; + $endPatternLookupHash->{$pstr} = ${$representation} if (!exists($endPatternLookupHash->{$pstr})); ## Append shortened string to lookuptable + return 1; + } else { + ${$rtext} = ''; + return 0; + } } @@ -1812,305 +1998,286 @@ sub SIGNALduino_FillPatternLookupTable { # 01232323242423 while ($message =~ /$pstr/g) { $count++ } sub SIGNALduino_PatternExists { - my ($hash,$search,$patternList,$data) = @_; - #my %patternList=$arg3; - #Debug "plist: ".Dumper($patternList) if($debug); - #Debug "searchlist: ".Dumper($search) if($debug); + my ($hash,$search,$patternList,$data) = @_; + #my %patternList=$arg3; + #Debug 'plist: '.Dumper($patternList) if($debug); + #Debug 'searchlist: '.Dumper($search) if($debug); - my $valid=1; - my @pstr; - my $debug = AttrVal($hash->{NAME},"debug",0); + my $debug = AttrVal($hash->{NAME},'debug',0); + my $i=0; + my @indexer; + my @sumlist; + my %plist=(); - my $i=0; + for my $searchpattern (@{$search}) # z.B. [1, -4] + { + next if (exists $plist{$searchpattern}); - my $maxcol=0; + # Calculate tolernace for search + #my $tol=abs(abs($searchpattern)>=2 ?$searchpattern*0.3:$searchpattern*1.5); + my $tol=abs(abs($searchpattern)>3 ? abs($searchpattern)>16 ? $searchpattern*0.18 : $searchpattern*0.3 : 1); #tol is minimum 1 or higer, depending on our searched pulselengh - foreach my $searchpattern (@{$search}) # z.B. [1, -4] - { - #my $patt_id; - # Calculate tolernace for search - #my $tol=abs(abs($searchpattern)>=2 ?$searchpattern*0.3:$searchpattern*1.5); - my $tol=abs(abs($searchpattern)>3 ? abs($searchpattern)>16 ? $searchpattern*0.18 : $searchpattern*0.3 : 1); #tol is minimum 1 or higer, depending on our searched pulselengh + Debug "tol: looking for ($searchpattern +- $tol)" if($debug); + my %pattern_gap ; #= {}; + # Find and store the gap of every pattern, which is in tolerance + %pattern_gap = map { $_ => abs($patternList->{$_}-$searchpattern) } grep { abs($patternList->{$_}-$searchpattern) <= $tol} (keys %$patternList); + if (scalar keys %pattern_gap > 0) + { + Debug "index => gap in tol (+- $tol) of pulse ($searchpattern) : ".Dumper(\%pattern_gap) if($debug); + # Extract fist pattern, which is nearst to our searched value + my @closestidx = (sort {$pattern_gap{$a} <=> $pattern_gap{$b}} keys %pattern_gap); - Debug "tol: looking for ($searchpattern +- $tol)" if($debug); + $plist{$searchpattern} = 1; + push @indexer, $searchpattern; + push @sumlist, [@closestidx]; + } else { + # search is not found, return -1 + return -1; + } + $i++; + } - my %pattern_gap ; #= {}; - # Find and store the gap of every pattern, which is in tolerance - %pattern_gap = map { $_ => abs($patternList->{$_}-$searchpattern) } grep { abs($patternList->{$_}-$searchpattern) <= $tol} (keys %$patternList); - if (scalar keys %pattern_gap > 0) - { - Debug "index => gap in tol (+- $tol) of pulse ($searchpattern) : ".Dumper(\%pattern_gap) if($debug); - # Extract fist pattern, which is nearst to our searched value - my @closestidx = (sort {$pattern_gap{$a} <=> $pattern_gap{$b}} keys %pattern_gap); + sub cartesian_product { ## no critic + use List::Util qw(reduce); + reduce { + [ map { + my $item = $_; + map [ @$_, $item ], @$a + } @$b ] + } [[]], @_ + } + my @res = cartesian_product @sumlist; + Debug qq[sumlists is: ].Dumper @sumlist if($debug); + Debug qq[res is: ].Dumper $res[0] if($debug); + Debug qq[indexer is: ].Dumper \@indexer if($debug); - my $idxstr=""; - my $r=0; + OUTERLOOP: + for my $i (0..$#{$res[0]}) + { - while (my ($item) = splice(@closestidx, 0, 1)) - { - $pstr[$i][$r]=$item; - $r++; - Debug "closest pattern has index: $item" if($debug); - } - $valid=1; - } else { - # search is not found, return -1 - return -1; - last; - } - $i++; - #return ($valid ? $pstr : -1); # return $pstr if $valid or -1 + ## Check if we have same patternindex for different values and skip this invalid ones + my %count; + for (@{$res[0][$i]}) + { + $count{$_}++; + next OUTERLOOP if ($count{$_} > 1) + }; + + # Create a mapping table to exchange the values later on + for (my $x=0;$x <= $#indexer;$x++) + { + $plist{$indexer[$x]} = $res[0][$i][$x]; + } + Debug qq[plist is for this check ].Dumper(\%plist) if($debug); + # Create our searchstring with our mapping table + my @patternVariant= @{$search}; + for my $v (@patternVariant) + { + #Debug qq[value before is: $v ] if($debug); + $v = $plist{$v}; + #Debug qq[after: $v ] if($debug); + } + Debug qq[patternVariant is ].Dumper(\@patternVariant) if($debug); + my $search_pattern = join '', @patternVariant; - #foreach $patt_id (keys %$patternList) { - #Debug "$patt_id. chk ->intol $patternList->{$patt_id} $searchpattern $tol"; - #$valid = SIGNALduino_inTol($patternList->{$patt_id}, $searchpattern, $tol); - #if ( $valid) #one pulse found in tolerance, search next one - #{ - # $pstr="$pstr$patt_id"; - # # provide this index for further lookup table -> {$patt_id = $searchpattern} - # Debug "pulse found"; - # last ; ## Exit foreach loop if searched pattern matches pattern in list - #} - #} - #last if (!$valid); ## Exit loop if a complete iteration has not found anything - } - my @results = (''); + (index ($$data, $search_pattern) > -1) ? return $search_pattern : next; + } - foreach my $subarray (@pstr) - { - @results = map {my $res = $_; map $res.$_, @$subarray } @results; - } - - foreach my $search (@results) - { - Debug "looking for substr $search" if($debug); - - return $search if (index( ${$data}, $search) >= 0); - } - - return -1; - - #return ($valid ? @results : -1); # return @pstr if $valid or -1 + return -1; } ############################# package main #SIGNALduino_MatchSignalPattern{$hash,@array, %hash, @array, $scalar}; not used >v3.1.3 sub SIGNALduino_MatchSignalPattern($\@\%\@$){ - - my ( $hash, $signalpattern, $patternList, $data_array, $idx) = @_; + my ( $hash, $signalpattern, $patternList, $data_array, $idx) = @_; my $name = $hash->{NAME}; - #print Dumper($patternList); - #print Dumper($idx); - #Debug Dumper($signalpattern) if ($debug); - my $tol="0.2"; # Tolerance factor - my $found=0; - my $debug = AttrVal($hash->{NAME},"debug",0); + #print Dumper($patternList); + #print Dumper($idx); + #Debug Dumper($signalpattern) if ($debug); + my $tol='0.2'; # Tolerance factor + my $found=0; + my $debug = AttrVal($hash->{NAME},'debug',0); - foreach ( @{$signalpattern} ) - { - #Debug " $idx check: ".$patternList->{$data_array->[$idx]}." == ".$_; - Debug "$name: idx: $idx check: abs(". $patternList->{$data_array->[$idx]}." - ".$_.") > ". ceil(abs($patternList->{$data_array->[$idx]}*$tol)) if ($debug); + foreach ( @{$signalpattern} ) + { + #Debug " $idx check: ".$patternList->{$data_array->[$idx]}." == ".$_; + Debug "$name: idx: $idx check: abs(". $patternList->{$data_array->[$idx]}.' - '.$_.') > '. ceil(abs($patternList->{$data_array->[$idx]}*$tol)) if ($debug); - #print "\n";; - #if ($patternList->{$data_array->[$idx]} ne $_ ) - ### Nachkommastelle von ceil!!! - if (!defined( $patternList->{$data_array->[$idx]})){ - Debug "$name: Error index ($idx) does not exist!!" if ($debug); - - return -1; - } - if (abs($patternList->{$data_array->[$idx]} - $_) > ceil(abs($patternList->{$data_array->[$idx]}*$tol))) - { - return -1; ## Pattern does not match, return -1 = not matched - } - $found=1; - $idx++; - } - if ($found) - { - return $idx; ## Return new Index Position - } + #print "\n";; + #if ($patternList->{$data_array->[$idx]} ne $_ ) + ### Nachkommastelle von ceil!!! + if (!defined( $patternList->{$data_array->[$idx]})){ + Debug "$name: Error index ($idx) does not exist!!" if ($debug); + return -1; + } + if (abs($patternList->{$data_array->[$idx]} - $_) > ceil(abs($patternList->{$data_array->[$idx]}*$tol))) + { + return -1; ## Pattern does not match, return -1 = not matched + } + $found=1; + $idx++; + } + if ($found) + { + return $idx; ## Return new Index Position + } } ############################# package main -sub SIGNALduino_b2h { - my $num = shift; - my $WIDTH = 4; - my $index = length($num) - $WIDTH; - my $hex = ''; - do { - my $width = $WIDTH; - if ($index < 0) { - $width += $index; - $index = 0; - } - my $cut_string = substr($num, $index, $width); - $hex = sprintf('%X', oct("0b$cut_string")) . $hex; - $index -= $WIDTH; - } while ($index > (-1 * $WIDTH)); - return $hex; +sub SIGNALduino_Split_Message { + my $rmsg = shift; + my $name = shift; + my %patternList; + my $clockidx; + my $syncidx; + my $rawData; + my $clockabs; + my $mcbitnum; + my $rssi; + + my @msg_parts = SIGNALduino_splitMsg($rmsg,';'); ## Split message parts by ';' + my %ret; + my $debug = AttrVal($name,'debug',0); + + foreach (@msg_parts) + { + #Debug "$name: checking msg part:( $_ )" if ($debug); + + #if ($_ =~ m/^MS/ or $_ =~ m/^MC/ or $_ =~ m/^Mc/ or $_ =~ m/^MU/) #### Synced Message start + if ($_ =~ m/^M./) + { + $ret{messagetype} = $_; + } + elsif ($_ =~ m/^P\d=-?\d{2,}/ or $_ =~ m/^[SL][LH]=-?\d{2,}/) #### Extract Pattern List from array + { + $_ =~ s/^P+//; + $_ =~ s/^P\d//; + my @pattern = split(/=/,$_); + + $patternList{$pattern[0]} = $pattern[1]; + Debug "$name: extracted pattern @pattern \n" if ($debug); + } + elsif($_ =~ m/D=\d+/ or $_ =~ m/^D=[A-F0-9]+/) #### Message from array + { + $_ =~ s/D=//; + $rawData = $_ ; + Debug "$name: extracted data $rawData\n" if ($debug); + $ret{rawData} = $rawData; + } + elsif($_ =~ m/^SP=([0-9])$/) #### Sync Pulse Index + { + Debug "$name: extracted syncidx $1\n" if ($debug); + #return undef if (!defined($patternList{$syncidx})); + $ret{syncidx} = $1; + } + elsif($_ =~ m/^CP=([0-9])$/) #### Clock Pulse Index + { + Debug "$name: extracted clockidx $1\n" if ($debug);; + $ret{clockidx} = $1; + } + elsif($_ =~ m/^L=\d/) #### MC bit length + { + (undef, $mcbitnum) = split(/=/,$_); + Debug "$name: extracted number of $mcbitnum bits\n" if ($debug);; + $ret{mcbitnum} = $mcbitnum; + } + elsif($_ =~ m/^C=\d+/) #### Message from array + { + $_ =~ s/C=//; + $clockabs = $_ ; + Debug "$name: extracted absolute clock $clockabs \n" if ($debug); + $ret{clockabs} = $clockabs; + } + elsif($_ =~ m/^R=\d+/) #### RSSI + { + $_ =~ s/R=//; + $rssi = $_ ; + Debug "$name: extracted RSSI $rssi \n" if ($debug); + $ret{rssi} = $rssi; + } else { + Debug "$name: unknown Message part $_" if ($debug);; + } + #print "$_\n"; + } + $ret{pattern} = {%patternList}; + return %ret; } -############################# package main -sub SIGNALduino_Split_Message($$) { - my $rmsg = shift; - my $name = shift; - my %patternList; - my $clockidx; - my $syncidx; - my $rawData; - my $clockabs; - my $mcbitnum; - my $rssi; - - my @msg_parts = SIGNALduino_splitMsg($rmsg,';'); ## Split message parts by ";" - my %ret; - my $debug = AttrVal($name,"debug",0); - - foreach (@msg_parts) - { - #Debug "$name: checking msg part:( $_ )" if ($debug); - - #if ($_ =~ m/^MS/ or $_ =~ m/^MC/ or $_ =~ m/^Mc/ or $_ =~ m/^MU/) #### Synced Message start - if ($_ =~ m/^M./) - { - $ret{messagetype} = $_; - } - elsif ($_ =~ m/^P\d=-?\d{2,}/ or $_ =~ m/^[SL][LH]=-?\d{2,}/) #### Extract Pattern List from array - { - $_ =~ s/^P+//; - $_ =~ s/^P\d//; - my @pattern = split(/=/,$_); - - $patternList{$pattern[0]} = $pattern[1]; - Debug "$name: extracted pattern @pattern \n" if ($debug); - } - elsif($_ =~ m/D=\d+/ or $_ =~ m/^D=[A-F0-9]+/) #### Message from array - - { - $_ =~ s/D=//; - $rawData = $_ ; - Debug "$name: extracted data $rawData\n" if ($debug); - $ret{rawData} = $rawData; - - } - elsif($_ =~ m/^SP=\d{1}/) #### Sync Pulse Index - { - (undef, $syncidx) = split(/=/,$_); - Debug "$name: extracted syncidx $syncidx\n" if ($debug); - #return undef if (!defined($patternList{$syncidx})); - $ret{syncidx} = $syncidx; - - } - elsif($_ =~ m/^CP=\d{1}/) #### Clock Pulse Index - { - (undef, $clockidx) = split(/=/,$_); - Debug "$name: extracted clockidx $clockidx\n" if ($debug);; - #return undef if (!defined($patternList{$clockidx})); - $ret{clockidx} = $clockidx; - } - elsif($_ =~ m/^L=\d/) #### MC bit length - { - (undef, $mcbitnum) = split(/=/,$_); - Debug "$name: extracted number of $mcbitnum bits\n" if ($debug);; - $ret{mcbitnum} = $mcbitnum; - } - - elsif($_ =~ m/^C=\d+/) #### Message from array - { - $_ =~ s/C=//; - $clockabs = $_ ; - Debug "$name: extracted absolute clock $clockabs \n" if ($debug); - $ret{clockabs} = $clockabs; - } - elsif($_ =~ m/^R=\d+/) ### RSSI ### - { - $_ =~ s/R=//; - $rssi = $_ ; - Debug "$name: extracted RSSI $rssi \n" if ($debug); - $ret{rssi} = $rssi; - } else { - Debug "$name: unknown Message part $_" if ($debug);; - } - #print "$_\n"; - } - $ret{pattern} = {%patternList}; - return %ret; -} - -############################# package main +############################# package main, test exists # Function which dispatches a message if needed. -sub SIGNALduno_Dispatch($$$$$) { - my ($hash, $rmsg, $dmsg, $rssi, $id) = @_; - my $name = $hash->{NAME}; +sub SIGNALduno_Dispatch { + my ($hash, $rmsg, $dmsg, $rssi, $id) = @_; + my $name = $hash->{NAME}; - if (!defined($dmsg)) - { - $hash->{logMethod}->($name, 5, "$name: Dispatch, dmsg is undef. Skipping dispatch call"); - return; - } + if (!defined($dmsg)) + { + $hash->{logMethod}->($name, 5, "$name: Dispatch, dmsg is undef. Skipping dispatch call"); + return; + } - #SIGNALduino_Log3 $name, 5, "$name: Dispatch, DMSG: $dmsg"; + #SIGNALduino_Log3 $name, 5, "$name: Dispatch, DMSG: $dmsg"; - my $DMSGgleich = 1; - if ($dmsg eq $hash->{LASTDMSG}) { - $hash->{logMethod}->($name, SDUINO_DISPATCH_VERBOSE, "$name: Dispatch, $dmsg, test gleich"); - } else { - if (defined($hash->{DoubleMsgIDs}{$id})) { - $DMSGgleich = 0; - $hash->{logMethod}->($name, SDUINO_DISPATCH_VERBOSE, "$name: Dispatch, $dmsg, test ungleich"); - } - else { - $hash->{logMethod}->($name, SDUINO_DISPATCH_VERBOSE, "$name: Dispatch, $dmsg, test ungleich: disabled"); - } - $hash->{LASTDMSG} = $dmsg; - $hash->{LASTDMSGID} = $id; - } + my $DMSGgleich = 1; + if ($dmsg eq $hash->{LASTDMSG}) { + $hash->{logMethod}->($name, SDUINO_DISPATCH_VERBOSE, "$name: Dispatch, $dmsg, test gleich"); + } else { + if ( defined $hash->{DoubleMsgIDs}{$id} ) { + $DMSGgleich = 0; + $hash->{logMethod}->($name, SDUINO_DISPATCH_VERBOSE, "$name: Dispatch, $dmsg, test ungleich"); + } else { + $hash->{logMethod}->($name, SDUINO_DISPATCH_VERBOSE, "$name: Dispatch, $dmsg, test ungleich: disabled"); + } + $hash->{LASTDMSG} = $dmsg; + $hash->{LASTDMSGID} = $id; + } - if ($DMSGgleich) { - #Dispatch if dispatchequals is provided in protocol definition or only if $dmsg is different from last $dmsg, or if 2 seconds are between transmits - if ( (SIGNALduino_getProtoProp($id,'dispatchequals',0) eq 'true') || ($hash->{DMSG} ne $dmsg) || ($hash->{TIME}+2 < time() ) ) { - $hash->{MSGCNT}++; - $hash->{TIME} = time(); - $hash->{DMSG} = $dmsg; - #my $event = 0; - if (substr(ucfirst($dmsg),0,1) eq 'U') { # u oder U - #$event = 1; - DoTrigger($name, "DMSG " . $dmsg); - return if (substr($dmsg,0,1) eq 'U'); # Fuer $dmsg die mit U anfangen ist kein Dispatch notwendig, da es dafuer kein Modul gibt klein u wird dagegen dispatcht - } - #readingsSingleUpdate($hash, "state", $hash->{READINGS}{state}{VAL}, $event); + if ($DMSGgleich) { + #Dispatch if dispatchequals is provided in protocol definition or only if $dmsg is different from last $dmsg, or if 2 seconds are between transmits + if ( ( $hash->{protocolObject}->checkProperty($id,'dispatchequals','false') eq 'true') + || ($hash->{DMSG} ne $dmsg) + || ($hash->{TIME}+2 < time() ) ) + { + $hash->{MSGCNT}++; + $hash->{TIME} = time(); + $hash->{DMSG} = $dmsg; + #my $event = 0; + if (substr(ucfirst($dmsg),0,1) eq 'U') { # u oder U + #$event = 1; + DoTrigger($name, 'DMSG ' . $dmsg); + return if (substr($dmsg,0,1) eq 'U'); # Fuer $dmsg die mit U anfangen ist kein Dispatch notwendig, da es dafuer kein Modul gibt klein u wird dagegen dispatcht + } + #readingsSingleUpdate($hash, 'state', $hash->{READINGS}{state}{VAL}, $event); - $hash->{RAWMSG} = $rmsg; - my %addvals = ( - DMSG => $dmsg, - Protocol_ID => $id - ); - if (AttrVal($name,"suppressDeviceRawmsg",0) == 0) { - $addvals{RAWMSG} = $rmsg - } - if(defined($rssi)) { - $hash->{RSSI} = $rssi; - $addvals{RSSI} = $rssi; - $rssi .= " dB," - } - else { - $rssi = ""; - } - $dmsg = lc($dmsg) if ($id eq '74' or $id eq '74.1'); # 10_FS20.pm accepted only lower case hex - $hash->{logMethod}->($name, SDUINO_DISPATCH_VERBOSE, "$name: Dispatch, $dmsg, $rssi dispatch"); - Dispatch($hash, $dmsg, \%addvals); ## Dispatch to other Modules + $hash->{RAWMSG} = $rmsg; + my %addvals = ( + DMSG => $dmsg, + Protocol_ID => $id + ); + if (AttrVal($name,'suppressDeviceRawmsg',0) == 0) { + $addvals{RAWMSG} = $rmsg + } + if(defined($rssi)) { + $hash->{RSSI} = $rssi; + $addvals{RSSI} = $rssi; + $rssi .= ' dB,' + } + else { + $rssi = ''; + } + $dmsg = lc($dmsg) if ($id eq '74' or $id eq '74.1'); # 10_FS20.pm accepted only lower case hex + $hash->{logMethod}->($name, SDUINO_DISPATCH_VERBOSE, "$name: Dispatch, $dmsg, $rssi dispatch"); + Dispatch($hash, $dmsg, \%addvals); ## Dispatch to other Modules - } else { - $hash->{logMethod}->($name, 4, "$name: Dispatch, $dmsg, Dropped due to short time or equal msg"); - } - } + } else { + $hash->{logMethod}->($name, 4, "$name: Dispatch, $dmsg, Dropped due to short time or equal msg"); + } + } } -############################# package main +############################# package main todo: move to lib::SD_Protocols # param #1 is name of definition # param #2 is protocol id # param #3 is dispatched message to check against @@ -2119,651 +2286,750 @@ sub SIGNALduno_Dispatch($$$$$) { # returns 0 if message does not match modulematch # return -1 if message is not activated via whitelistIDs but has developID=m flag sub SIGNALduino_moduleMatch { - my $name = shift; - my $id = shift; - my $dmsg = shift; - my $debug = AttrVal($name,"debug",0); - my $modMatchRegex=SIGNALduino_getProtoProp($id,"modulematch",undef); + my $name = shift // carp q[arg name must be provided]; + my $id = shift; + my $dmsg = shift; + my $debug = AttrVal($name,'debug',0); + my $hash = $defs{$name} // carp q[$name does not exist]; + my $modMatchRegex=$hash->{protocolObject}->checkProperty($id,'modulematch',undef); - if (!defined($modMatchRegex) || $dmsg =~ m/$modMatchRegex/) { - Debug "$name: modmatch passed for: $dmsg" if ($debug); - my $developID = SIGNALduino_getProtoProp($id,"developId",""); - my $IDsNoDispatch = "," . InternalVal($name,"IDsNoDispatch","") . ","; - if ($IDsNoDispatch ne ",," && index($IDsNoDispatch, ",$id,") >= 0) { # kein dispatch wenn die Id im Internal IDsNoDispatch steht - Log3 $name, 3, "$name: moduleMatch, ID=$id skipped dispatch (developId=m). To use, please add $id to the attr whitelist_IDs"; - - return -1; - } - return 1; # return 1 da modulematch gefunden wurde - } - return 0; + if (!defined($modMatchRegex) || $dmsg =~ m/$modMatchRegex/) { + Debug "$name: modmatch passed for: $dmsg" if ($debug); + my $developID = $hash->{protocolObject}->checkProperty($id,'developId',''); + my $IDsNoDispatch = ',' . InternalVal($name,'IDsNoDispatch','') . ','; + if ($IDsNoDispatch ne ',,' && index($IDsNoDispatch, ",$id,") >= 0) { # kein dispatch wenn die Id im Internal IDsNoDispatch steht + Log3 $name, 3, "$name: moduleMatch, ID=$id skipped dispatch (developId=m). To use, please add $id to the attr whitelist_IDs"; + return -1; + } + return 1; # return 1 da modulematch gefunden wurde + } + return 0; } +############################# package main, test exists +# calculated RSSI and RSSI value and RSSI string (-77,'RSSI = -77') +sub SIGNALduino_calcRSSI { + my $rssi = shift // return ; + my $rssiStr = ''; + $rssi = ($rssi>=128 ? (($rssi-256)/2-74) : ($rssi/2-74)); + $rssiStr = "RSSI = $rssi"; + return ($rssi,$rssiStr); +} + + + + +=item SIGNALduino_Parse_MS + +This sub parses a MS rawdata string and dispatches it if a protocol matched the cirteria. + +Input: $iohash, $rawMessage + +Output: { Number of times dispatch was called, 0 if dispatch isn't called } + +=cut ############################# package main -sub SIGNALduino_Parse_MS($$$$%) { - my ($hash, $iohash, $name, $rmsg,%msg_parts) = @_; - my $syncidx=$msg_parts{syncidx}; - my $clockidx=$msg_parts{clockidx}; - my $rssi=$msg_parts{rssi}; - my $rawData=$msg_parts{rawData}; - my %patternList; - my $rssiStr= ""; +sub SIGNALduino_Parse_MS { + my $hash = shift // return; #return if no hash is provided + my $rmsg = shift // return; #return if no rmsg is provided - if (defined($rssi)) { - $rssi = ($rssi>=128 ? (($rssi-256)/2-74) : ($rssi/2-74)); # todo: passt dies so? habe ich vom 00_cul.pm - $rssiStr= " RSSI = $rssi" - } + if ($rmsg !~ /^MS;(?:P[0-7]=-?\d+;){3,8}D=[0-7]+;(?:[CS]P=[0-7];){2}((?:R=\d+;)|(?:O;)?|(?:m=?[0-9];)|(?:[sbeECA=0-9]+;))*$/){ + $hash->{logMethod}->($hash->{NAME}, 3, qq[$hash->{NAME}: Parse_MS, faulty msg: $rmsg]); + return ; # Abort here if not successfull + } - #Debug "Message splitted:"; - #Debug Dumper(\@msg_parts); + # Extract Data from rmsg: + my %msg_parts = SIGNALduino_Split_Message($rmsg, $hash->{NAME}); - my $debug = AttrVal($iohash->{NAME},"debug",0); + # Verify if extracted hash has the correct values: + my $clockidx = _limit_to_number($msg_parts{clockidx}) // $hash->{logMethod}->($hash->{NAME}, 3, qq[$hash->{NAME}: Parse_MS, faulty clock: $msg_parts{clockidx}]) // return ; + my $syncidx = _limit_to_number($msg_parts{syncidx}) // $hash->{logMethod}->($hash->{NAME}, 3, qq[$hash->{NAME}: Parse_MS, faulty sync: $msg_parts{syncidx}]) // return ; + my $rawData = _limit_to_number($msg_parts{rawData}) // $hash->{logMethod}->($hash->{NAME}, 3, qq[$hash->{NAME}: Parse_MS, faulty rawData D=: $msg_parts{rawData}]) // return ; + my $rssi; + my $rssiStr= ''; + if ( defined $msg_parts{rssi} ){ + $rssi = _limit_to_number($msg_parts{rssi}) // $hash->{logMethod}->($hash->{NAME}, 3, qq[$hash->{NAME}: Parse_MS, faulty rssi R=: $msg_parts{rssi}]) // return ; + ($rssi,$rssiStr) = SIGNALduino_calcRSSI($rssi); + }; + my $messagetype=$msg_parts{messagetype}; + my $name = $hash->{NAME}; + my %patternList; - if (defined($clockidx) and defined($syncidx)) - { + #Debug 'Message splitted:'; + #Debug Dumper(\@msg_parts); - ## Make a lookup table for our pattern index ids - #Debug "List of pattern:"; - my $clockabs= $msg_parts{pattern}{$msg_parts{clockidx}}; - return if ($clockabs == 0); - $patternList{$_} = round($msg_parts{pattern}{$_}/$clockabs,1) for keys %{$msg_parts{pattern}}; + my $debug = AttrVal($hash->{NAME},'debug',0); + if (defined($clockidx) and defined($syncidx)) + { + ## Make a lookup table for our pattern index ids + #Debug 'List of pattern:'; + my $clockabs= $msg_parts{pattern}{$msg_parts{clockidx}}; + return if ($clockabs == 0); + $patternList{$_} = round($msg_parts{pattern}{$_}/$clockabs,1) for keys %{$msg_parts{pattern}}; - #Debug Dumper(\%patternList); + #Debug Dumper(\%patternList); - #my $syncfact = $patternList{$syncidx}/$patternList{$clockidx}; - #$syncfact=$patternList{$syncidx}; - #Debug "SF=$syncfact"; - #### Convert rawData in Message - my $signal_length = length($rawData); # Length of data array + #my $syncfact = $patternList{$syncidx}/$patternList{$clockidx}; + #$syncfact=$patternList{$syncidx}; + #Debug 'SF=$syncfact'; + #### Convert rawData in Message + my $signal_length = length($rawData); # Length of data array - ## Iterate over the data_array and find zero, one, float and sync bits with the signalpattern - ## Find matching protocols - my $message_dispatched=0; + ## Iterate over the data_array and find zero, one, float and sync bits with the signalpattern + ## Find matching protocols + my $message_dispatched=0; - IDLOOP: - foreach my $id (@{$hash->{msIdList}}) { + IDLOOP: + foreach my $id (@{$hash->{msIdList}}) { - Debug "Testing against protocol id $id -> $ProtocolListSIGNALduino{$id}{name}" if ($debug); + Debug qq[Testing against protocol id $id -> ].$hash->{protocolObject}->getProperty($id,'name') if ($debug); - # Check Clock if is it in range - if ($ProtocolListSIGNALduino{$id}{clockabs} > 0) { - if (!SIGNALduino_inTol($ProtocolListSIGNALduino{$id}{clockabs},$clockabs,$clockabs*0.30)) { - Debug "protocClock=$ProtocolListSIGNALduino{$id}{clockabs}, msgClock=$clockabs is not in tol=" . $clockabs*0.30 if ($debug); - next; - } elsif ($debug) { - Debug "protocClock=$ProtocolListSIGNALduino{$id}{clockabs}, msgClock=$clockabs is in tol=" . $clockabs*0.30; - } - } + # Check Clock if is it in range + if ($hash->{protocolObject}->checkProperty($id,'clockabs',0) > 0) { + if (!SIGNALduino_inTol($hash->{protocolObject}->getProperty($id,'clockabs'),$clockabs,$clockabs*0.30)) { + Debug qq[protocClock=].$hash->{protocolObject}->getProperty($id,'clockabs').qq[, msgClock=$clockabs is not in tol=].$clockabs*0.30 if ($debug); + next; + } elsif ($debug) { + Debug qq[protocClock=].$hash->{protocolObject}->getProperty($id,'clockabs').qq[, msgClock=$clockabs is in tol="] . $clockabs*0.30; + } + } - Debug "Searching in patternList: ".Dumper(\%patternList) if($debug); + Debug 'Searching in patternList: '.Dumper(\%patternList) if($debug); - my %patternLookupHash=(); - my %endPatternLookupHash=(); - my $signal_width= @{$ProtocolListSIGNALduino{$id}{one}}; - my $return_text; - my $message_start; - foreach my $key (qw(sync one zero float) ) { - next if (!exists($ProtocolListSIGNALduino{$id}{$key})); + my %patternLookupHash=(); + my %endPatternLookupHash=(); + my $signal_width= @{$hash->{protocolObject}->getProperty($id,'one')}; + my $return_text; + my $message_start; + foreach my $key (qw(sync one zero float) ) { + next if (!defined($hash->{protocolObject}->getProperty($id,$key))); - if (!SIGNALduino_FillPatternLookupTable($hash,\@{$ProtocolListSIGNALduino{$id}{$key}},\$symbol_map{$key},\%patternList,\$rawData,\%patternLookupHash,\%endPatternLookupHash,\$return_text)) - { - Debug sprintf("%s pattern not found",$key) if ($debug); - next IDLOOP if ($key ne "float") ; - } + if (!SIGNALduino_FillPatternLookupTable($hash,\@{$hash->{protocolObject}->getProperty($id,$key)},\$symbol_map{$key},\%patternList,\$rawData,\%patternLookupHash,\%endPatternLookupHash,\$return_text)) + { + Debug sprintf("%s pattern not found",$key) if ($debug); + next IDLOOP if ($key ne 'float') ; + } - if ($key eq "sync") - { - $message_start =index($rawData,$return_text)+length($return_text); - my $bit_length = ($signal_length-$message_start) / $signal_width; - if (exists($ProtocolListSIGNALduino{$id}{length_min}) && $ProtocolListSIGNALduino{$id}{length_min} > $bit_length) { - Debug "bit_length=$bit_length to short" if ($debug); - next IDLOOP; - } - Debug "expecting $bit_length bits in signal" if ($debug); - %endPatternLookupHash=(); - } - Debug sprintf("Found matched %s with indexes: (%s)",$key,$return_text) if ($debug); - } - next if (scalar keys %patternLookupHash == 0); # Keine Eingträge im patternLookupHash + if ($key eq 'sync') + { + $message_start =index($rawData,$return_text)+length($return_text); + my $bit_length = ($signal_length-$message_start) / $signal_width; + if ($hash->{protocolObject}->checkProperty($id,'length_min',-1) > $bit_length) { + Debug "bit_length=$bit_length to short" if ($debug); + next IDLOOP; + } + Debug "expecting $bit_length bits in signal" if ($debug); + %endPatternLookupHash=(); + } + Debug sprintf("Found matched %s with indexes: (%s)",$key,$return_text) if ($debug); + } + next if (scalar keys %patternLookupHash == 0); # Keine Eingträge im patternLookupHash + $hash->{logMethod}->($name, 4, qq[$name: Parse_MS, Matched MS protocol id $id -> ].$hash->{protocolObject}->getProperty($id,'name')); + my @bit_msg; # array to store decoded signal bits + $hash->{logMethod}->($name, 5, qq[$name: Parse_MS, Starting demodulation at Position $message_start]); + for (my $i=$message_start;$i{protocolObject}->getProperty($id,'reconstructBit'))) { + if (length($sigStr) == $signal_width) { # ist $sigStr zu lang? + chop($sigStr); + } + if (exists($endPatternLookupHash{$sigStr})) { + push(@bit_msg,$endPatternLookupHash{$sigStr}); + $hash->{logMethod}->($name, 4, "$name: Parse_MS, last part pair=$sigStr reconstructed, last bit=$endPatternLookupHash{$sigStr}"); + } + else { + $hash->{logMethod}->($name, 5, "$name: Parse_MS, can't reconstruct last part pair=$sigStr"); + } + last; + } else { + $hash->{logMethod}->($name, 5, "$name: Parse_MS, Found wrong signalpattern $sigStr, catched ".scalar @bit_msg.' bits, aborting demodulation'); + last; + } + } - $hash->{logMethod}->($name, 4, "$name: Parse_MS, Matched MS protocol id $id -> $ProtocolListSIGNALduino{$id}{name}"); - my @bit_msg; # array to store decoded signal bits - $hash->{logMethod}->($name, 5, "$name: Parse_MS, Starting demodulation at Position $message_start"); - for (my $i=$message_start;$i{logMethod}->($name, 4, "$name: Parse_MS, last part pair=$sigStr reconstructed, last bit=$endPatternLookupHash{$sigStr}"); - } - else { - $hash->{logMethod}->($name, 5, "$name: Parse_MS, can't reconstruct last part pair=$sigStr"); - } - last; - } else { - $hash->{logMethod}->($name, 5, "$name: Parse_MS, Found wrong signalpattern $sigStr, catched ".scalar @bit_msg." bits, aborting demodulation"); - last; - } - } + Debug "$name: decoded message raw (@bit_msg), ".@bit_msg." bits\n" if ($debug); + #Check converted message against lengths + my ($rcode, $rtxt) = $hash->{protocolObject}->LengthInRange($id,scalar @bit_msg); + if (!$rcode) + { + Debug "$name: decoded $rtxt" if ($debug); + next; + } + my $padwith = $hash->{protocolObject}->checkProperty($id,'paddingbits',4); - Debug "$name: decoded message raw (@bit_msg), ".@bit_msg." bits\n" if ($debug); + my $i=0; + while (scalar @bit_msg % $padwith > 0) ## will pad up full nibbles per default or full byte if specified in protocol + { + push(@bit_msg,'0'); + $i++; + } + Debug "$name padded $i bits to bit_msg array" if ($debug); - #Check converted message against lengths - my ($rcode, $rtxt) = SIGNALduino_TestLength(undef,$id,scalar @bit_msg,undef); - if (!$rcode) - { - Debug "$name: decoded $rtxt" if ($debug); - next; - } - my $padwith = lib::SD_Protocols::checkProperty($id,'paddingbits',4); + if ($i == 0) { + $hash->{logMethod}->($name, 5, "$name: Parse_MS, dispatching bits: @bit_msg"); + } else { + $hash->{logMethod}->($name, 5, "$name: Parse_MS, dispatching bits: @bit_msg with $i Paddingbits 0"); + } - my $i=0; - while (scalar @bit_msg % $padwith > 0) ## will pad up full nibbles per default or full byte if specified in protocol - { - push(@bit_msg,'0'); - $i++; - } - Debug "$name padded $i bits to bit_msg array" if ($debug); + my $evalcheck = ($hash->{protocolObject}->checkProperty($id,'developId','') =~ 'p') ? 1 : undef; - if ($i == 0) { - $hash->{logMethod}->($name, 5, "$name: Parse_MS, dispatching bits: @bit_msg"); - } else { - $hash->{logMethod}->($name, 5, "$name: Parse_MS, dispatching bits: @bit_msg with $i Paddingbits 0"); - } + ($rcode,my @retvalue) = SIGNALduino_callsub($hash->{protocolObject},'postDemodulation',$hash->{protocolObject}->checkProperty($id,'postDemodulation',undef),$evalcheck,$name,@bit_msg); + next if ($rcode < 1 ); + #SIGNALduino_Log3 $name, 5, "$name: Parse_MS, postdemodulation value @retvalue"; - my $evalcheck = (SIGNALduino_getProtoProp($id,"developId","") =~ 'p') ? 1 : undef; - ($rcode,my @retvalue) = SIGNALduino_callsub('postDemodulation',$ProtocolListSIGNALduino{$id}{postDemodulation},$evalcheck,$name,@bit_msg); - next if ($rcode < 1 ); - #SIGNALduino_Log3 $name, 5, "$name: Parse_MS, postdemodulation value @retvalue"; + @bit_msg = @retvalue; + undef(@retvalue); undef($rcode); - @bit_msg = @retvalue; - undef(@retvalue); undef($rcode); + my $dmsg = lib::SD_Protocols::binStr2hexStr(join '', @bit_msg); + my $postamble = $hash->{protocolObject}->checkProperty($id,'postamble',''); + $dmsg = $hash->{protocolObject}->checkProperty($id,'preamble','').qq[$dmsg$postamble]; + + #my ($rcode,@retvalue) = SIGNALduino_callsub('preDispatchfunc',$ProtocolListSIGNALduino{$id}{preDispatchfunc},$name,$dmsg); + #next if (!$rcode); + #$dmsg = @retvalue; + #undef(@retvalue); undef($rcode); - my $dmsg = SIGNALduino_b2h(join "", @bit_msg); - my $postamble = $ProtocolListSIGNALduino{$id}{postamble}; - $dmsg = "$dmsg".$postamble if (defined($postamble)); - $dmsg = "$ProtocolListSIGNALduino{$id}{preamble}"."$dmsg" if (defined($ProtocolListSIGNALduino{$id}{preamble})); + if ( SIGNALduino_moduleMatch($name,$id,$dmsg) == 1) + { + $message_dispatched++; + $hash->{logMethod}->($name, 4, "$name: Parse_MS, Decoded matched MS protocol id $id dmsg $dmsg length " . scalar @bit_msg . " $rssiStr"); + SIGNALduno_Dispatch($hash,$rmsg,$dmsg,$rssi,$id); + } + } - - #my ($rcode,@retvalue) = SIGNALduino_callsub('preDispatchfunc',$ProtocolListSIGNALduino{$id}{preDispatchfunc},$name,$dmsg); - #next if (!$rcode); - #$dmsg = @retvalue; - #undef(@retvalue); undef($rcode); - - if ( SIGNALduino_moduleMatch($name,$id,$dmsg) == 1) - { - $message_dispatched++; - $hash->{logMethod}->($name, 4, "$name: Parse_MS, Decoded matched MS protocol id $id dmsg $dmsg length " . scalar @bit_msg . " $rssiStr"); - SIGNALduno_Dispatch($hash,$rmsg,$dmsg,$rssi,$id); - } - - } - - return 0 if (!$message_dispatched); - - return $message_dispatched; - - } + return 0 if (!$message_dispatched); + return $message_dispatched; + } } ############################# package main ## //Todo: check list as reference +# // Todo: Make this sub robust and use it sub SIGNALduino_padbits(\@$) { - my $i=@{$_[0]} % $_[1]; - while (@{$_[0]} % $_[1] > 0) ## will pad up full nibbles per default or full byte if specified in protocol - { - push(@{$_[0]},'0'); - } - return " padded $i bits to bit_msg array"; + my $i=@{$_[0]} % $_[1]; + while (@{$_[0]} % $_[1] > 0) ## will pad up full nibbles per default or full byte if specified in protocol + { + push(@{$_[0]},'0'); + } + return " padded $i bits to bit_msg array"; } -############################# package main -#=item SIGNALduino_getProtoProp() -#This functons, will return a value from the protocolist and check if the key exists and a value is defined optional you can specify a optional default value that will be reurned -# -# returns "" if the var is not defined -# =cut -# $id, $propertyname, +=item SIGNALduino_Parse_MU -sub SIGNALduino_getProtoProp { - my ($id,$propNameLst,$default) = @_; +This sub parses a MU rawdata string and dispatches it if a protocol matched the cirteria. - #my $id = shift; - #my $propNameLst = shift; - return $ProtocolListSIGNALduino{$id}{$propNameLst} if exists($ProtocolListSIGNALduino{$id}{$propNameLst}) && defined($ProtocolListSIGNALduino{$id}{$propNameLst}); - return $default; # Will return undef if $default is not provided - #return ; +Input: $iohash, $rawMessage + +Output: { Number of times dispatch was called, 0 if dispatch isn't called } + +=cut + +############################# package main, test exists +sub SIGNALduino_Parse_MU { + my $hash = shift // return; #return if no hash is provided + my $rmsg = shift // return; #return if no rmsg is provided + + if ($rmsg !~ /^(?=.*D=\d+)(?:MU;(?:P[0-7]=-?[0-9]{1,5};){2,8}((?:D=\d{2,};)|(?:CP=\d;)|(?:R=\d+;)?|(?:O;)?|(?:e;)?|(?:p;)?|(?:w=\d;)?)*)$/){ + $hash->{logMethod}->($hash->{NAME}, 3, qq[$hash->{NAME}: Parse_MU, faulty msg: $rmsg]); + return ; # Abort here if not successfull + } + + # Extract Data from rmsg: + my %msg_parts = SIGNALduino_Split_Message($rmsg, $hash->{NAME}); + + # Verify if extracted hash has the correct values: + my $clockidx = _limit_to_number($msg_parts{clockidx}) // $hash->{logMethod}->($hash->{NAME}, 3, qq[$hash->{NAME}: Parse_MU, faulty clock: $rmsg]) // return ; + my $rawData = _limit_to_number($msg_parts{rawData}) // $hash->{logMethod}->($hash->{NAME}, 3, qq[$hash->{NAME}: Parse_MU, faulty rawData D=: $msg_parts{rawData}]) // return ; + my $rssi; + my $rssiStr= ''; + if ( defined $msg_parts{rssi} ){ + $rssi = _limit_to_number($msg_parts{rssi}) // $hash->{logMethod}->($hash->{NAME}, 3, qq[$hash->{NAME}: Parse_MU, faulty rssi R=: $msg_parts{rssi}]) // return ; + ($rssi,$rssiStr) = SIGNALduino_calcRSSI($rssi); + }; + my $messagetype=$msg_parts{messagetype}; + my $name = $hash->{NAME}; + + + my $protocolid; + my %patternListRaw; + my $message_dispatched=0; + my $debug = AttrVal($hash->{NAME},'debug',0); + + Debug "$name: processing unsynced message\n" if ($debug); + + my $clockabs = 1; #Clock will be fetched from protocol if possible + $patternListRaw{$_} = $msg_parts{pattern}{$_} for keys %{$msg_parts{pattern}}; + + if (defined($clockidx)) + { + ## Make a lookup table for our pattern index ids + #Debug 'List of pattern:'; #Debug Dumper(\%patternList); + + ## Find matching protocols + + IDLOOP: + for my $id (@{$hash->{muIdList}}) { + $clockabs= $hash->{protocolObject}->getProperty($id,'clockabs'); + my %patternList; + $rawData=$msg_parts{rawData}; + if (defined($hash->{protocolObject}->getProperty($id,'filterfunc'))) + { + my $method =$hash->{protocolObject}->getProperty($id,'filterfunc'); + if (!exists &$method) + { + $hash->{logMethod}->($name, 5, "$name: Parse_MU, Error: Unknown filtermethod=$method. Please define it in file $0"); + next; + } else { + $hash->{logMethod}->($name, 5, "$name: Parse_MU, for MU protocol id $id, applying filterfunc $method"); + + no strict "refs"; + (my $count_changes,$rawData,my %patternListRaw_tmp) = $method->($name,$id,$rawData,%patternListRaw); + use strict "refs"; + + %patternList = map { $_ => round($patternListRaw_tmp{$_}/$clockabs,1) } keys %patternListRaw_tmp; + } + } else { + %patternList = map { $_ => round($patternListRaw{$_}/$clockabs,1) } keys %patternListRaw; + } + + Debug qq[Testing against protocol id $id -> ]. $hash->{protocolObject}->getProperty($id,'name') if ($debug); + Debug qq[Searching in patternList: ].Dumper(\%patternList) if($debug); + + my $startStr=''; # Default match if there is no start pattern available + my $message_start=0 ; + my $startLogStr=''; + + if (defined($hash->{protocolObject}->getProperty($id,'start')) && ref($hash->{protocolObject}->getProperty($id,'start')) eq 'ARRAY') # wenn start definiert ist, dann startStr ermitteln und in rawData suchen und in der rawData alles bis zum startStr abschneiden + { + Debug 'msgStartLst: '.Dumper(\@{$hash->{protocolObject}->getProperty($id,'start')}) if ($debug); + + if ( ($startStr=SIGNALduino_PatternExists($hash,\@{$hash->{protocolObject}->getProperty($id,'start')},\%patternList,\$rawData)) eq -1) + { + $hash->{logMethod}->($name, 5, qq[$name: Parse_MU, start pattern for MU protocol id $id -> ].$hash->{protocolObject}->getProperty($id,'name'). qq[ not found, aborting]); + next; + } + Debug "startStr is: $startStr" if ($debug); + $message_start = index($rawData, $startStr); + if ( $message_start == -1) + { + Debug "startStr $startStr not found." if ($debug); + next; + } else { + $rawData = substr($rawData, $message_start); + $startLogStr = "StartStr: $startStr first found at $message_start"; + Debug "rawData = $rawData" if ($debug); + Debug "startStr $startStr found. Message starts at $message_start" if ($debug); + #SIGNALduino_Log3 $name, 5, "$name: Parse_MU, substr: $rawData"; # todo: entfernen + } + } + + my %patternLookupHash=(); + my %endPatternLookupHash=(); + my $pstr=''; + my $zeroRegex =''; + my $oneRegex =''; + my $floatRegex =''; + my $return_text=''; + my $signalRegex='(?:'; + + for my $key (qw(one zero float) ) { + next if (!defined($hash->{protocolObject}->getProperty($id,$key))); + if (!SIGNALduino_FillPatternLookupTable($hash,\@{$hash->{protocolObject}->getProperty($id,$key)},\$symbol_map{$key},\%patternList,\$rawData,\%patternLookupHash,\%endPatternLookupHash,\$return_text)) + { + Debug sprintf("%s pattern not found",$key) if ($debug); + next IDLOOP if ($key ne "float"); + } + Debug sprintf("Found matched %s with indexes: (%s)",$key,$return_text) if ($debug); + if ($key eq "one") + { + $signalRegex .= $return_text; + } + else { + $signalRegex .= "|$return_text" if($return_text); + } + } + $signalRegex .= ')'; + + $hash->{logMethod}->($name, 4, qq[$name: Parse_MU, Fingerprint for MU protocol id $id -> ].$hash->{protocolObject}->getProperty($id,'name').q[ matches, trying to demodulate]); + + my $signal_width= @{$hash->{protocolObject}->getProperty($id,'one')}; + my $length_min = $hash->{protocolObject}->getProperty($id,'length_min'); + my $length_max = $hash->{protocolObject}->checkProperty($id,'length_max',''); + + $signalRegex .= qq[{$length_min,}]; + + if (defined($hash->{protocolObject}->getProperty($id,'reconstructBit'))) { + $signalRegex .= '(?:' . join('|',keys %endPatternLookupHash) . ')?'; + } + Debug "signalRegex is $signalRegex " if ($debug); + + my $nrRestart=0; + my $nrDispatch=0; + my $regex="(?:$startStr)($signalRegex)"; + + while ( $rawData =~ m/$regex/g) { + my $length_str=''; + $nrRestart++; + $hash->{logMethod}->($name, 5, qq{$name: Parse_MU, part is $1 starts at position $-[0] and ends at }.pos $rawData); + + my @pairs = unpack "(a$signal_width)*", $1; + + if ($length_max && scalar @pairs > $length_max) # ist die Nachricht zu lang? + { + $hash->{logMethod}->($name, 5, "$name: Parse_MU, $nrRestart. skip demodulation (length ".scalar @pairs." is to long) at Pos $-[0] regex ($regex)"); + next; + } + + if ($nrRestart == 1) { + $hash->{logMethod}->($name, 5, qq[$name: Parse_MU, Starting demodulation ($startLogStr regex: $regex Pos $message_start) length_min_max ($length_min..$length_max) length=].scalar @pairs); + } else { + $hash->{logMethod}->($name, 5, qq{$name: Parse_MU, $nrRestart. try demodulation$length_str at Pos $-[0]}); + } + + my @bit_msg=(); # array to store decoded signal bits + + for my $sigStr (@pairs) + { + if (exists $patternLookupHash{$sigStr}) { + push(@bit_msg,$patternLookupHash{$sigStr}) ## Add the bits to our bit array + } elsif (defined($hash->{protocolObject}->getProperty($id,'reconstructBit')) && exists($endPatternLookupHash{$sigStr})) { + my $lastbit = $endPatternLookupHash{$sigStr}; + push(@bit_msg,$lastbit); + $hash->{logMethod}->($name, 4, "$name: Parse_MU, last part pair=$sigStr reconstructed, bit=$lastbit"); + } + } + + Debug "$name: demodulated message raw (@bit_msg), ".@bit_msg." bits\n" if ($debug); + + my $evalcheck = ($hash->{protocolObject}->checkProperty($id,'developId','') =~ 'p') ? 1 : undef; + my ($rcode,@retvalue) = SIGNALduino_callsub($hash->{protocolObject},'postDemodulation',$hash->{protocolObject}->checkProperty($id,'postDemodulation',undef),$evalcheck,$name,@bit_msg); + + next if ($rcode < 1 ); + @bit_msg = @retvalue; + undef(@retvalue); undef($rcode); + + my $dispmode='hex'; + $dispmode='bin' if ($hash->{protocolObject}->checkProperty($id,'dispatchBin',0) == 1 ); + + my $padwith = $hash->{protocolObject}->checkProperty($id,'paddingbits',4); + while (scalar @bit_msg % $padwith > 0) ## will pad up full nibbles per default or full byte if specified in protocol + { + push(@bit_msg,'0'); + Debug "$name: padding 0 bit to bit_msg array" if ($debug); + } + my $dmsg = join ('', @bit_msg); + my $bit_length=scalar @bit_msg; + @bit_msg=(); # clear bit_msg array + + $dmsg = lib::SD_Protocols::binStr2hexStr($dmsg) if ($hash->{protocolObject}->checkProperty($id,'dispatchBin',0) == 0 ); + + $dmsg =~ s/^0+// if ( $hash->{protocolObject}->checkProperty($id,'remove_zero',0) ); + + $dmsg=sprintf("%s%s%s",$hash->{protocolObject}->checkProperty($id,'preamble',''),$dmsg,$hash->{protocolObject}->checkProperty($id,'postamble','')); + $hash->{logMethod}->($name, 5, "$name: Parse_MU, dispatching $dispmode: $dmsg"); + + if ( SIGNALduino_moduleMatch($name,$id,$dmsg) == 1) + { + $nrDispatch++; + $hash->{logMethod}->($name, 4, "$name: Parse_MU, Decoded matched MU protocol id $id dmsg $dmsg length $bit_length dispatch($nrDispatch/". AttrVal($name,'maxMuMsgRepeat', 4) . ") $rssiStr"); + SIGNALduno_Dispatch($hash,$rmsg,$dmsg,$rssi,$id); + if ( $nrDispatch == AttrVal($name,'maxMuMsgRepeat', 4)) + { + last; + } + } + } + $hash->{logMethod}->($name, 5, "$name: Parse_MU, $nrRestart. try, regex ($regex) did not match") if ($nrRestart == 0); + $message_dispatched=$message_dispatched+$nrDispatch; + } + return $message_dispatched; + } } -############################# package main -sub SIGNALduino_Parse_MU($$$$@) { - my ($hash, $iohash, $name, $rmsg,%msg_parts) = @_; +=item SIGNALduino_Parse_MC - my $protocolid; - my $clockidx=$msg_parts{clockidx}; - my $rssi=$msg_parts{rssi}; - my $rawData; - my %patternListRaw; - my $message_dispatched=0; - my $debug = AttrVal($iohash->{NAME},"debug",0); - my $rssiStr= ""; +This sub parses a MC rawdata string and dispatches it if a protocol matched the cirteria. - if (defined($rssi)) { - $rssi = ($rssi>=128 ? (($rssi-256)/2-74) : ($rssi/2-74)); # todo: passt dies so? habe ich vom 00_cul.pm - $rssiStr= " RSSI = $rssi" - } +Input: $iohash, $rawMessage - Debug "$name: processing unsynced message\n" if ($debug); +Output: { Number of times dispatch was called, 0 if dispatch isn't called } - my $clockabs = 1; #Clock will be fetched from protocol if possible - #$patternListRaw{$_} = floor($msg_parts{pattern}{$_}/$clockabs) for keys $msg_parts{pattern}; - $patternListRaw{$_} = $msg_parts{pattern}{$_} for keys %{$msg_parts{pattern}}; +=cut + +############################# package main, test exists +sub SIGNALduino_Parse_MC { + my $hash = shift // return; #return if no hash is provided + my $rmsg = shift // return; #return if no rmsg is provided + + if ($rmsg !~ /^M[cC];LL=-\d+;LH=\d+;SL=-\d+;SH=\d+;D=[0-9A-F]+;C=\d+;L=\d+;(?:R=\d+;)?$/){ + $hash->{logMethod}->($hash->{NAME}, 3, qq[$hash->{NAME}: Parse_MC, faulty msg: $rmsg]); + return ; # Abort here if not successfull + } + + # Extract Data from rmsg: + my %msg_parts = SIGNALduino_Split_Message($rmsg, $hash->{NAME}); + + # Verify if extracted hash has the correct values: + my $clock = _limit_to_number($msg_parts{clockabs}) // $hash->{logMethod}->($hash->{NAME}, 3, qq[$hash->{NAME}: Parse_MC, faulty clock: $msg_parts{clockabs}]) // return ; + my $mcbitnum = _limit_to_number($msg_parts{mcbitnum}) // $hash->{logMethod}->($hash->{NAME}, 3, qq[$hash->{NAME}: Parse_MC, faulty mcbitnum: $msg_parts{mcbitnum}]) // return ; + my $rawData = _limit_to_hex($msg_parts{rawData}) // $hash->{logMethod}->($hash->{NAME}, 3, qq[$hash->{NAME}: Parse_MC, faulty rawData D=: $msg_parts{rawData}]) // return ; + my $rssi; + my $rssiStr= ''; + if ( defined $msg_parts{rssi} ){ + $rssi = _limit_to_number($msg_parts{rssi}) // $hash->{logMethod}->($hash->{NAME}, 3, qq[$hash->{NAME}: Parse_MC, faulty rssi R=: $msg_parts{rssi}]) // return ; + ($rssi,$rssiStr) = SIGNALduino_calcRSSI($rssi); + }; + my $messagetype=$msg_parts{messagetype}; + my $name = $hash->{NAME}; + + + my $bitData; + my $dmsg; + my $message_dispatched=0; + my $debug = AttrVal($hash->{NAME},'debug',0); - if (defined($clockidx)) - { + Debug "$name: processing manchester messag len:".length($rawData) if ($debug); - ## Make a lookup table for our pattern index ids - #Debug "List of pattern:"; #Debug Dumper(\%patternList); + my $hlen = length($rawData); + my $blen; + #if (defined($mcbitnum)) { + # $blen = $mcbitnum; + #} else { + $blen = $hlen * 4; + #} - ## Find matching protocols + my $rawDataInverted; + ($rawDataInverted = $rawData) =~ tr/0123456789ABCDEF/FEDCBA9876543210/; # Some Manchester Data is inverted - IDLOOP: - foreach my $id (@{$hash->{muIdList}}) { + for my $id (@{$hash->{mcIdList}}) { - $clockabs= $ProtocolListSIGNALduino{$id}{clockabs}; - my %patternList; - $rawData=$msg_parts{rawData}; - if (exists($ProtocolListSIGNALduino{$id}{filterfunc})) - { - my $method = $ProtocolListSIGNALduino{$id}{filterfunc}; - if (!exists &$method) - { - $hash->{logMethod}->($name, 5, "$name: Parse_MU, Error: Unknown filtermethod=$method. Please define it in file $0"); - next; - } else { - $hash->{logMethod}->($name, 5, "$name: Parse_MU, for MU protocol id $id, applying filterfunc $method"); + #next if ($blen < $ProtocolListSIGNALduino{$id}{length_min} || $blen > $ProtocolListSIGNALduino{$id}{length_max}); + #if ( $clock >$ProtocolListSIGNALduino{$id}{clockrange}[0] and $clock <$ProtocolListSIGNALduino{$id}{clockrange}[1]); + my @clockrange = @{$hash->{protocolObject}->getProperty($id,'clockrange')}; + if ( $clock > $clockrange[0] && $clock < $clockrange[1] && length($rawData)*4 >= $hash->{protocolObject}->getProperty($id,'length_min') ) + { + Debug "clock and min length matched" if ($debug); - no strict "refs"; - (my $count_changes,$rawData,my %patternListRaw_tmp) = $method->($name,$id,$rawData,%patternListRaw); - use strict "refs"; + (defined $rssi ) ? $hash->{logMethod}->($name, 4, qq[$name: Parse_MC, Found manchester protocol id $id clock $clock $rssiStr -> ].$hash->{protocolObject}->getProperty($id,'name')) + : $hash->{logMethod}->($name, 4, qq[$name: Parse_MC, Found manchester protocol id $id clock $clock -> ].$hash->{protocolObject}->getProperty($id,'name')); - %patternList = map { $_ => round($patternListRaw_tmp{$_}/$clockabs,1) } keys %patternListRaw_tmp; - } - } else { - %patternList = map { $_ => round($patternListRaw{$_}/$clockabs,1) } keys %patternListRaw; - } + my $polarityInvert = ( $hash->{protocolObject}->checkProperty($id,'polarity','') eq 'invert' ) ? 1 : 0; + Debug "$name: polarityInvert=$polarityInvert" if ($debug); + if ( $messagetype eq 'Mc' + || ( defined $hash->{version} && substr $hash->{version},0,6 eq 'V 3.2.') ) + { + $polarityInvert = $polarityInvert ^ 1; + } + $bitData = ($polarityInvert == 1 ) + ? unpack("B$blen", pack("H$hlen", $rawDataInverted)) + : unpack("B$blen", pack("H$hlen", $rawData)); - Debug "Testing against protocol id $id -> $ProtocolListSIGNALduino{$id}{name}" if ($debug); - Debug "Searching in patternList: ".Dumper(\%patternList) if($debug); + Debug "$name: extracted data $bitData (bin)\n" if ($debug); ## Convert Message from hex to bits + $hash->{logMethod}->($name, 5, "$name: Parse_MC, extracted data $bitData (bin)"); - my $startStr=""; # Default match if there is no start pattern available - my $message_start=0 ; - my $startLogStr=""; + my $method = $hash->{protocolObject}->getProperty($id,'method'); + if (!exists &$method || !defined &{ $method }) + { + $hash->{logMethod}->($name, 5, "$name: Parse_MC, Error: Unknown function=$method. Please define it in file SD_ProtocolData.pm"); + } else { + $mcbitnum = length($bitData) if ($mcbitnum > length($bitData)); + my ($rcode,$res) = $method->($hash->{protocolObject},$name,$bitData,$id,$mcbitnum); + if ($rcode != -1) { + $dmsg = sprintf('%s%s',$hash->{protocolObject}->checkProperty($id,'preamble',''),$res); + my $modulematch = $hash->{protocolObject}->checkProperty($id,'modulematch',undef); - if (exists($ProtocolListSIGNALduino{$id}{start}) && defined($ProtocolListSIGNALduino{$id}{start}) && ref($ProtocolListSIGNALduino{$id}{start}) eq 'ARRAY') # wenn start definiert ist, dann startStr ermitteln und in rawData suchen und in der rawData alles bis zum startStr abschneiden - { - Debug "msgStartLst: ".Dumper(\@{$ProtocolListSIGNALduino{$id}{start}}) if ($debug); + if (!defined $modulematch || $dmsg =~ m/$modulematch/) { + if (substr($hash->{protocolObject}->checkProperty($id,'developId',' '),0,1) eq 'm') { - if ( ($startStr=SIGNALduino_PatternExists($hash,\@{$ProtocolListSIGNALduino{$id}{start}},\%patternList,\$rawData)) eq -1) - { - $hash->{logMethod}->($name, 5, "$name: Parse_MU, start pattern for MU protocol id $id -> $ProtocolListSIGNALduino{$id}{name} not found, aborting"); - next; - } - Debug "startStr is: $startStr" if ($debug); - $message_start = index($rawData, $startStr); - if ( $message_start == -1) - { - Debug "startStr $startStr not found." if ($debug); - next; - } else { - $rawData = substr($rawData, $message_start); - $startLogStr = "StartStr: $startStr first found at $message_start"; - Debug "rawData = $rawData" if ($debug); - Debug "startStr $startStr found. Message starts at $message_start" if ($debug); - #SIGNALduino_Log3 $name, 5, "$name: Parse_MU, substr: $rawData"; # todo: entfernen - } - - } - - my %patternLookupHash=(); - my %endPatternLookupHash=(); - my $pstr=""; - my $zeroRegex =""; - my $oneRegex =""; - my $floatRegex =""; - my $return_text=""; - my $signalRegex="(?:"; - - foreach my $key (qw(one zero float) ) { - next if (!exists($ProtocolListSIGNALduino{$id}{$key})); - if (!SIGNALduino_FillPatternLookupTable($hash,\@{$ProtocolListSIGNALduino{$id}{$key}},\$symbol_map{$key},\%patternList,\$rawData,\%patternLookupHash,\%endPatternLookupHash,\$return_text)) - { - Debug sprintf("%s pattern not found",$key) if ($debug); - next IDLOOP if ($key ne "float"); - } - Debug sprintf("Found matched %s with indexes: (%s)",$key,$return_text) if ($debug); - if ($key eq "one") - { - $signalRegex .= $return_text; - } - else { - $signalRegex .= "|$return_text" if($return_text); - } - } - $signalRegex .= ")"; - - $hash->{logMethod}->($name, 4, "$name: Parse_MU, Fingerprint for MU protocol id $id -> $ProtocolListSIGNALduino{$id}{name} matches, trying to demodulate"); - - my $signal_width= @{$ProtocolListSIGNALduino{$id}{one}}; - my $length_min = $ProtocolListSIGNALduino{$id}{length_min}; - my $length_max = ""; - $length_max = $ProtocolListSIGNALduino{$id}{length_max} if (exists($ProtocolListSIGNALduino{$id}{length_max})); - - $signalRegex .= "{$length_min,}"; - - if (exists($ProtocolListSIGNALduino{$id}{reconstructBit})) { - - $signalRegex .= "(?:" . join("|",keys %endPatternLookupHash) . ")?"; - } - Debug "signalRegex is $signalRegex " if ($debug); - - my $nrRestart=0; - my $nrDispatch=0; - my $regex="(?:$startStr)($signalRegex)"; - - while ( $rawData =~ m/$regex/g) { - my $length_str=""; - $nrRestart++; - $hash->{logMethod}->($name, 5, "$name: Parse_MU, part is $1 starts at position $-[0] and ends at ". pos $rawData); - - my @pairs = unpack "(a$signal_width)*", $1; - - if (exists($ProtocolListSIGNALduino{$id}{length_max}) && scalar @pairs > $ProtocolListSIGNALduino{$id}{length_max}) # ist die Nachricht zu lang? - { - $hash->{logMethod}->($name, 5, "$name: Parse_MU, $nrRestart. skip demodulation (length ".scalar @pairs." is to long) at Pos $-[0] regex ($regex)"); - next; - } - - if ($nrRestart == 1) { - $hash->{logMethod}->($name, 5, "$name: Parse_MU, Starting demodulation ($startLogStr " . "regex: $regex Pos $message_start) length_min_max (".$length_min."..".$length_max.") length=".scalar @pairs); - } else { - $hash->{logMethod}->($name, 5, "$name: Parse_MU, $nrRestart. try demodulation$length_str at Pos $-[0]"); - } - - - my @bit_msg=(); # array to store decoded signal bits - - foreach my $sigStr (@pairs) - { - if (exists $patternLookupHash{$sigStr}) { - push(@bit_msg,$patternLookupHash{$sigStr}) ## Add the bits to our bit array - } - elsif (exists($ProtocolListSIGNALduino{$id}{reconstructBit}) && exists($endPatternLookupHash{$sigStr})) { - my $lastbit = $endPatternLookupHash{$sigStr}; - push(@bit_msg,$lastbit); - $hash->{logMethod}->($name, 4, "$name: Parse_MU, last part pair=$sigStr reconstructed, bit=$lastbit"); - } - } - - Debug "$name: demodulated message raw (@bit_msg), ".@bit_msg." bits\n" if ($debug); - - my $evalcheck = (SIGNALduino_getProtoProp($id,"developId","") =~ 'p') ? 1 : undef; - my ($rcode,@retvalue) = SIGNALduino_callsub('postDemodulation',$ProtocolListSIGNALduino{$id}{postDemodulation},$evalcheck,$name,@bit_msg); - - next if ($rcode < 1 ); - @bit_msg = @retvalue; - undef(@retvalue); undef($rcode); - - my $dispmode="hex"; - $dispmode="bin" if (SIGNALduino_getProtoProp($id,"dispatchBin",0) == 1 ); - - my $padwith = lib::SD_Protocols::checkProperty($id,'paddingbits',4); - while (scalar @bit_msg % $padwith > 0) ## will pad up full nibbles per default or full byte if specified in protocol - { - push(@bit_msg,'0'); - Debug "$name: padding 0 bit to bit_msg array" if ($debug); - } - my $dmsg = join ("", @bit_msg); - my $bit_length=scalar @bit_msg; - @bit_msg=(); # clear bit_msg array - - $dmsg = SIGNALduino_b2h($dmsg) if (SIGNALduino_getProtoProp($id,"dispatchBin",0) == 0 ); - - - $dmsg =~ s/^0+// if ( SIGNALduino_getProtoProp($id,"remove_zero",0) ); - - $dmsg=sprintf("%s%s%s",SIGNALduino_getProtoProp($id,"preamble",""),$dmsg,SIGNALduino_getProtoProp($id,"postamble","")); - $hash->{logMethod}->($name, 5, "$name: Parse_MU, dispatching $dispmode: $dmsg"); - - if ( SIGNALduino_moduleMatch($name,$id,$dmsg) == 1) - { - $nrDispatch++; - $hash->{logMethod}->($name, 4, "$name: Parse_MU, Decoded matched MU protocol id $id dmsg $dmsg length $bit_length dispatch($nrDispatch/". AttrVal($name,'maxMuMsgRepeat', 4) . ")$rssiStr"); - SIGNALduno_Dispatch($hash,$rmsg,$dmsg,$rssi,$id); - if ( $nrDispatch == AttrVal($name,"maxMuMsgRepeat", 4)) - { - last; - } - } - - - } - $hash->{logMethod}->($name, 5, "$name: Parse_MU, $nrRestart. try, regex ($regex) did not match") if ($nrRestart == 0); - $message_dispatched=$message_dispatched+$nrDispatch; - } - return $message_dispatched; - - } + my $devid = "m$id"; + my $develop = lc(AttrVal($name,'development','')); + if ($develop !~ m/$devid/) { # kein dispatch wenn die Id nicht im Attribut development steht + $hash->{logMethod}->($name, 3, qq[$name: Parse_MC, ID=$devid skipped dispatch (developId=m). To use, please add m$id to the attr development]); + next; + } + } + if ( SDUINO_MC_DISPATCH_VERBOSE < 5 + && (SDUINO_MC_DISPATCH_LOG_ID eq '' || SDUINO_MC_DISPATCH_LOG_ID eq $id) ) + { + defined($rssi) ? $hash->{logMethod}->($name, SDUINO_MC_DISPATCH_VERBOSE, qq[$name: Parse_MC, $id, $rmsg $rssiStr]) + : $hash->{logMethod}->($name, SDUINO_MC_DISPATCH_VERBOSE, qq[$name: Parse_MC, $id, $rmsg]); + } + SIGNALduno_Dispatch($hash,$rmsg,$dmsg,$rssi,$id); + $message_dispatched=1; + } + } else { + $res='undef' if (!defined($res)); + $hash->{logMethod}->($name, 5, qq[$name: Parse_MC, protocol does not match return from method: ($res)]) ; + } + } + } + } + return 0 if (!$message_dispatched); + return 1; } -############################# package main -sub SIGNALduino_Parse_MC($$$$@) { +############################# package main, test exists +sub SIGNALduino_Parse_MN { - my ($hash, $iohash, $name, $rmsg,%msg_parts) = @_; - my $clock=$msg_parts{clockabs}; ## absolute clock - my $rawData=$msg_parts{rawData}; - my $rssi=$msg_parts{rssi}; - my $mcbitnum=$msg_parts{mcbitnum}; - my $messagetype=$msg_parts{messagetype}; - my $bitData; - my $dmsg; - my $message_dispatched=0; - my $debug = AttrVal($iohash->{NAME},"debug",0); - if (defined($rssi)) { - $rssi = ($rssi>=128 ? (($rssi-256)/2-74) : ($rssi/2-74)); # todo: passt dies so? habe ich vom 00_cul.pm - } + my $hash = shift // return; #return if no hash is provided + my $rmsg = shift // return; #return if no rmsg is provided + + if ($rmsg !~ /^MN;D=[0-9A-F]+;(?:R=[0-9]+;)?$/){ + $hash->{logMethod}->($hash->{NAME}, 3, qq[$hash->{NAME}: Parse_MN, faulty msg: $rmsg]); + return ; # Abort here if not successfull + } - return if (!$clock); - #my $protocol=undef; - #my %patternListRaw = %msg_parts{patternList}; + # Extract Data from rmsg: + my %msg_parts = SIGNALduino_Split_Message($rmsg, $hash->{NAME}); - Debug "$name: processing manchester messag len:".length($rawData) if ($debug); + # Verify if extracted hash has the correct values: + my $rawData = _limit_to_hex($msg_parts{rawData}) // $hash->{logMethod}->($hash->{NAME}, 3, qq[$hash->{NAME}: Parse_MN, faulty rawData D=: $msg_parts{rawData}]) // return ; + my $rssi; + my $rssiStr= ''; + if ( defined $msg_parts{rssi} ){ + $rssi = _limit_to_number($msg_parts{rssi}) // $hash->{logMethod}->($hash->{NAME}, 3, qq[$hash->{NAME}: Parse_MN, faulty rssi R=: $msg_parts{rssi}]) // return ; + ($rssi,$rssiStr) = SIGNALduino_calcRSSI($rssi); + }; + my $messagetype=$msg_parts{messagetype}; + my $name = $hash->{NAME}; - my $hlen = length($rawData); - my $blen; - #if (defined($mcbitnum)) { - # $blen = $mcbitnum; - #} else { - $blen = $hlen * 4; - #} + my $dmsg; - my $rawDataInverted; - ($rawDataInverted = $rawData) =~ tr/0123456789ABCDEF/FEDCBA9876543210/; # Some Manchester Data is inverted + my $match; + my $modulation; + my $message_dispatched=0; - foreach my $id (@{$hash->{mcIdList}}) { + mnIDLoop: + for my $id (@{$hash->{mnIdList}}) { + my $rfmode = $hash->{protocolObject}->getProperty($id,'rfmode'); + if (!defined $rfmode) { + $hash->{logMethod}->($name, 5, qq[$name: Parse_MN, Error! id $id has no rfmode. Please define it in file SD_ProtocolData.pm]); + next mnIDLoop; + } - #next if ($blen < $ProtocolListSIGNALduino{$id}{length_min} || $blen > $ProtocolListSIGNALduino{$id}{length_max}); - #if ( $clock >$ProtocolListSIGNALduino{$id}{clockrange}[0] and $clock <$ProtocolListSIGNALduino{$id}{clockrange}[1]); - if ( $clock >$ProtocolListSIGNALduino{$id}{clockrange}[0] and $clock <$ProtocolListSIGNALduino{$id}{clockrange}[1] and length($rawData)*4 >= $ProtocolListSIGNALduino{$id}{length_min} ) - { - Debug "clock and min length matched" if ($debug); + my ($rcode, $rtxt) = $hash->{protocolObject}->LengthInRange($id,length($rawData)); # Check message length + if (!$rcode) { + $hash->{logMethod}->($name, 4, qq[$name: Parse_MN, Error! id $id msg=$rawData, $rtxt]); + next mnIDLoop; + } - if (defined($rssi)) { - $hash->{logMethod}->($name, 4, "$name: Parse_MC, Found manchester protocol id $id clock $clock RSSI $rssi -> $ProtocolListSIGNALduino{$id}{name}"); - } else { - $hash->{logMethod}->($name, 4, "$name: Parse_MC, Found manchester protocol id $id clock $clock -> $ProtocolListSIGNALduino{$id}{name}"); - } + $match = $hash->{protocolObject}->checkProperty($id,'regexMatch',undef); + $modulation = $hash->{protocolObject}->checkProperty($id,'modulation',undef); + if ( defined($match) && $rawData =~ m/$match/x ) { + $hash->{logMethod}->($name, 4, qq[$name: Parse_MN, Found $modulation Protocol id $id -> ].$hash->{protocolObject}->getProperty($id,'name').qq[ with match $match]); + } elsif (!defined($match) ) { + $hash->{logMethod}->($name, 4, qq[$name: Parse_MN, Found $modulation Protocol id $id -> ].$hash->{protocolObject}->getProperty($id,'name')); + } else { + $hash->{logMethod}->($name, 4, qq[$name: Parse_MN, $modulation Protocol id $id ].$hash->{protocolObject}->getProperty($id,'name').qq[ msg $rawData not match $match]); + next mnIDLoop; + } - my $polarityInvert = 0; - if (exists($ProtocolListSIGNALduino{$id}{polarity}) && ($ProtocolListSIGNALduino{$id}{polarity} eq 'invert')) - { - $polarityInvert = 1; - } - if ($messagetype eq 'Mc' || (defined($hash->{version}) && substr($hash->{version},0,6) eq 'V 3.2.')) - { - $polarityInvert = $polarityInvert ^ 1; - } - if ($polarityInvert == 1) - { - $bitData= unpack("B$blen", pack("H$hlen", $rawDataInverted)); - - } else { - $bitData= unpack("B$blen", pack("H$hlen", $rawData)); - } - Debug "$name: extracted data $bitData (bin)\n" if ($debug); ## Convert Message from hex to bits - $hash->{logMethod}->($name, 5, "$name: Parse_MC, extracted data $bitData (bin)"); - - my $method = lib::SD_Protocols::getProperty($id,"method"); - if (!exists &$method || !defined &{ $method }) - { - $hash->{logMethod}->($name, 5, "$name: Parse_MC, Error: Unknown function=$method. Please define it in file $0"); - } else { - $mcbitnum = length($bitData) if ($mcbitnum > length($bitData)); - my ($rcode,$res) = $method->($name,$bitData,$id,$mcbitnum); - if ($rcode != -1) { - $dmsg = $res; - $dmsg=$ProtocolListSIGNALduino{$id}{preamble}.$dmsg if (defined($ProtocolListSIGNALduino{$id}{preamble})); - my $modulematch; - if (defined($ProtocolListSIGNALduino{$id}{modulematch})) { - $modulematch = $ProtocolListSIGNALduino{$id}{modulematch}; - } - if (!defined($modulematch) || $dmsg =~ m/$modulematch/) { - if (defined($ProtocolListSIGNALduino{$id}{developId}) && substr($ProtocolListSIGNALduino{$id}{developId},0,1) eq "m") { - my $devid = "m$id"; - my $develop = lc(AttrVal($name,"development","")); - if ($develop !~ m/$devid/) { # kein dispatch wenn die Id nicht im Attribut development steht - $hash->{logMethod}->($name, 3, "$name: Parse_MC, ID=$devid skipped dispatch (developId=m). To use, please add m$id to the attr development"); - next; - } - } - if (SDUINO_MC_DISPATCH_VERBOSE < 5 && (SDUINO_MC_DISPATCH_LOG_ID eq '' || SDUINO_MC_DISPATCH_LOG_ID eq $id)) - { - if (defined($rssi)) { - $hash->{logMethod}->($name, SDUINO_MC_DISPATCH_VERBOSE, "$name: Parse_MC, $id, $rmsg RSSI=$rssi"); - } else - { - $hash->{logMethod}->($name, SDUINO_MC_DISPATCH_VERBOSE, "$name: Parse_MC, $id, $rmsg"); - } - } - SIGNALduno_Dispatch($hash,$rmsg,$dmsg,$rssi,$id); - $message_dispatched=1; - } - } else { - $res="undef" if (!defined($res)); - $hash->{logMethod}->($name, 5, "$name: Parse_MC, protocol does not match return from method: ($res)") ; - - } - } - } - - } - return 0 if (!$message_dispatched); - return 1; + my $method = $hash->{protocolObject}->getProperty($id,'method',undef); + my @methodReturn = defined $method ? $method->($hash->{protocolObject},$rawData) : ($rawData); + if ($#methodReturn != 0) { + $hash->{logMethod}->($name, 4, qq{$name: Parse_MN, Error! method $methodReturn[1]}); + next mnIDLoop; + } + $dmsg = sprintf('%s%s',$hash->{protocolObject}->checkProperty($id,'preamble',''),$methodReturn[0]); + $hash->{logMethod}->($name, 5, qq[$name: Parse_MN, Decoded matched MN Protocol id $id dmsg=$dmsg $rssiStr]); + SIGNALduno_Dispatch($hash,$rmsg,$dmsg,$rssi,$id); + $message_dispatched++; + + } + return $message_dispatched; } ############################# package main sub SIGNALduino_Parse($$$$@) { my ($hash, $iohash, $name, $rmsg, $initstr) = @_; - #print Dumper(\%ProtocolListSIGNALduino); + #print Dumper(\%ProtocolListSIGNALduino); + if (!($rmsg=~ s/^\002(M.;.*;)\003/$1/)) # Check if a Data Message arrived and if it's complete (start & end control char are received) + { # cut off start end end character from message for further processing they are not needed + $hash->{logMethod}->($name, AttrVal($name,'noMsgVerbose',5), "$name: Parse, noMsg: $rmsg"); + return ; + } - if (!($rmsg=~ s/^\002(M.;.*;)\003/$1/)) # Check if a Data Message arrived and if it's complete (start & end control char are received) - { # cut off start end end character from message for further processing they are not needed - $hash->{logMethod}->($name, AttrVal($name,"noMsgVerbose",5), "$name: Parse, noMsg: $rmsg"); - return ; - } + if (defined($hash->{keepalive})) { + $hash->{keepalive}{ok} = 1; + $hash->{keepalive}{retry} = 0; + } - if (defined($hash->{keepalive})) { - $hash->{keepalive}{ok} = 1; - $hash->{keepalive}{retry} = 0; - } + my $debug = AttrVal($iohash->{NAME},'debug',0); - my $debug = AttrVal($iohash->{NAME},"debug",0); + Debug "$name: incoming message: ($rmsg)\n" if ($debug); + if (AttrVal($name, 'rawmsgEvent', 0)) { + DoTrigger($name, 'RAWMSG ' . $rmsg); + } - Debug "$name: incoming message: ($rmsg)\n" if ($debug); + my $dispatched; + + # Message Synced type -> MS + my $mType = uc substr $rmsg,0,2 ; - if (AttrVal($name, "rawmsgEvent", 0)) { - DoTrigger($name, "RAWMSG " . $rmsg); - } + if (@{$hash->{msIdList}} && $mType eq 'MS' ) + { + $dispatched= SIGNALduino_Parse_MS($hash, $rmsg); + } + # Message unsynced type -> MU + elsif (@{$hash->{muIdList}} && $mType eq 'MU') + { + $dispatched= SIGNALduino_Parse_MU($hash, $rmsg); + } + # Manchester encoded Data -> MC + elsif (@{$hash->{mcIdList}} && $mType eq 'MC') + { + $dispatched= SIGNALduino_Parse_MC($hash, $rmsg); + } + # Message xFSK -> MN + elsif (@{$hash->{mnIdList}} && $mType eq 'MN') + { + $dispatched= SIGNALduino_Parse_MN($hash, $rmsg); + } + else { + Debug "$name: unknown Messageformat, aborting\n" if ($debug); + return ; + } - my %signal_parts=SIGNALduino_Split_Message($rmsg,$name); ## Split message and save anything in an hash %signal_parts - #Debug "raw data ". $signal_parts{rawData}; + if ( AttrVal($hash->{NAME},'verbose','0') > 4 && !$dispatched) + { + my $notdisplist; + my @lines; + if (defined($hash->{unknownmessages})) + { + $notdisplist=$hash->{unknownmessages}; + @lines = split ('#', $notdisplist); # or whatever + } + push(@lines,FmtDateTime(time()).'-'.$rmsg); + shift(@lines)if (scalar @lines >25); + $notdisplist = join('#',@lines); - - my $dispatched; - # Message Synced type -> M# - - if (@{$hash->{msIdList}} && $rmsg=~ m/^MS;(P\d=-?\d+;){3,8}D=\d+;CP=\d;SP=\d;/) - { - $dispatched= SIGNALduino_Parse_MS($hash, $iohash, $name, $rmsg,%signal_parts); - } - # Message unsynced type -> MU - elsif (@{$hash->{muIdList}} && $rmsg=~ m/^MU;(P\d=-?\d+;){3,8}((CP|R)=\d+;){0,2}D=\d+;/) - { - $dispatched= SIGNALduino_Parse_MU($hash, $iohash, $name, $rmsg,%signal_parts); - } - # Manchester encoded Data -> MC - elsif (@{$hash->{mcIdList}} && $rmsg=~ m/^M[cC];.*;/) - { - $dispatched= SIGNALduino_Parse_MC($hash, $iohash, $name, $rmsg,%signal_parts); - } - else { - Debug "$name: unknown Messageformat, aborting\n" if ($debug); - return ; - } - - if ( AttrVal($hash->{NAME},"verbose","0") > 4 && !$dispatched) - { - my $notdisplist; - my @lines; - if (defined($hash->{unknownmessages})) - { - $notdisplist=$hash->{unknownmessages}; - @lines = split ('#', $notdisplist); # or whatever - } - push(@lines,FmtDateTime(time())."-".$rmsg); - shift(@lines)if (scalar @lines >25); - $notdisplist = join('#',@lines); - - $hash->{unknownmessages}=$notdisplist; - return ; - #Todo compare Sync/Clock fact and length of D= if equal, then it's the same protocol! - } - return $dispatched; + $hash->{unknownmessages}=$notdisplist; + return ; + #Todo compare Sync/Clock fact and length of D= if equal, then it's the same protocol! + } + return $dispatched; } ############################# package main -sub SIGNALduino_Ready($) { +sub SIGNALduino_Ready { my ($hash) = @_; if ($hash->{STATE} eq 'disconnected') { @@ -2781,19 +3047,19 @@ sub SIGNALduino_Ready($) { } ############################# package main -sub SIGNALduino_WriteInit($) { +sub SIGNALduino_WriteInit { my ($hash) = @_; # todo: ist dies so ausreichend, damit die Aenderungen uebernommen werden? - SIGNALduino_AddSendQueue($hash,"WS36"); # SIDLE, Exit RX / TX, turn off frequency synthesizer - SIGNALduino_AddSendQueue($hash,"WS34"); # SRX, Enable RX. Perform calibration first if coming from IDLE and MCSM0.FS_AUTOCAL=1. + SIGNALduino_AddSendQueue($hash,'WS36'); # SIDLE, Exit RX / TX, turn off frequency synthesizer + SIGNALduino_AddSendQueue($hash,'WS34'); # SRX, Enable RX. Perform calibration first if coming from IDLE and MCSM0.FS_AUTOCAL=1. } ############################# package main sub SIGNALduino_SimpleWrite(@) { my ($hash, $msg, $nonl) = @_; return if(!$hash); - if($hash->{TYPE} eq "SIGNALduino_RFR") { + if($hash->{TYPE} eq 'SIGNALduino_RFR') { # Prefix $msg with RRBBU and return the corresponding SIGNALduino hash. ($hash, $msg) = SIGNALduino_RFR_AddPrefix($hash, $msg); } @@ -2813,114 +3079,140 @@ sub SIGNALduino_SimpleWrite(@) { ############################# package main sub SIGNALduino_Attr(@) { - my ($cmd,$name,$aName,$aVal) = @_; - my $hash = $defs{$name}; - my $debug = AttrVal($name,"debug",0); + my ($cmd,$name,$aName,$aVal) = @_; + my $hash = $defs{$name}; + my $debug = AttrVal($name,'debug',0); - $aVal= "" if (!defined($aVal)); - $hash->{logMethod}->($name, 4, "$name: Attr, Calling sub with args: $cmd $aName = $aVal"); + $aVal= '' if (!defined($aVal)); + $hash->{logMethod}->($name, 4, "$name: Attr, Calling sub with args: $cmd $aName = $aVal"); - if( $aName eq "Clients" ) { ## Change clientList - $hash->{Clients} = $aVal; - $hash->{Clients} = $clientsSIGNALduino if( !$hash->{Clients}) ; ## Set defaults - return "Setting defaults"; - } elsif( $aName eq "MatchList" ) { ## Change matchList - my $match_list; - if( $cmd eq "set" ) { - $match_list = eval {$aVal}; - if( $@ ) { - $hash->{logMethod}->($name, 2, $name .": Attr, $aVal: ". $@); - } - } + ## Change Clients + if( $aName eq 'Clients' ) { + $hash->{Clients} = $aVal; + $hash->{Clients} = $clientsSIGNALduino if( !$hash->{Clients}) ; ## Set defaults + return 'Setting defaults'; + } + ## Change MatchList + elsif( $aName eq 'MatchList' ) { + my $match_list; + if( $cmd eq 'set' ) { + $match_list = eval $aVal; ## Allow evaluation of hash object from "attr" string f.e. { '34:MYMODULE' => '^u99#.{9}' } + if( $@ ) { + $hash->{logMethod}->($name, 2, $name .": Attr, $aVal: ". $@); + } + } - if( ref($match_list) eq 'HASH' ) { - $hash->{MatchList} = $match_list; - } else { - $hash->{MatchList} = \%matchListSIGNALduino; ## Set defaults - $hash->{logMethod}->($name, 2, $name .": Attr, $aVal: not a HASH using defaults") if( $aVal ); - } - } - elsif ($aName eq "verbose") - { - $hash->{logMethod}->($name, 3, "$name: Attr, setting Verbose to: " . $aVal); - $hash->{unknownmessages}="" if $aVal <4; - - } - elsif ($aName eq "debug") - { - $debug = $aVal; - $hash->{logMethod}->($name, 3, "$name: Attr, setting debug to: " . $debug); - } - elsif ($aName eq "whitelist_IDs") - { - if ($init_done) { # beim fhem Start wird das SIGNALduino_IdList nicht aufgerufen, da es beim define aufgerufen wird - SIGNALduino_IdList("x:$name",$aVal); - } - } - elsif ($aName eq "blacklist_IDs") - { - if ($init_done) { # beim fhem Start wird das SIGNALduino_IdList nicht aufgerufen, da es beim define aufgerufen wird - SIGNALduino_IdList("x:$name",undef,$aVal); - } - } - elsif ($aName eq "development") - { - if ($init_done) { # beim fhem Start wird das SIGNALduino_IdList nicht aufgerufen, da es beim define aufgerufen wird - SIGNALduino_IdList("x:$name",undef,undef,$aVal); - } - } - elsif ($aName eq "doubleMsgCheck_IDs") - { - if (defined($aVal)) { - if (length($aVal)>0) { - if (substr($aVal,0 ,1) eq '#') { - $hash->{logMethod}->($name, 3, "$name: Attr, doubleMsgCheck_IDs disabled: $aVal"); - delete $hash->{DoubleMsgIDs}; - } - else { - $hash->{logMethod}->($name, 3, "$name: Attr, doubleMsgCheck_IDs enabled: $aVal"); - my %DoubleMsgiD = map { $_ => 1 } split(",", $aVal); - $hash->{DoubleMsgIDs} = \%DoubleMsgiD; - #print Dumper $hash->{DoubleMsgIDs}; - } - } - else { - $hash->{logMethod}->($name, 3, "$name: Attr, delete doubleMsgCheck_IDs"); - delete $hash->{DoubleMsgIDs}; - } - } - } - ####### Beginn kann wahrscheinlich weg ####### - # elsif ($aName eq "cc1101_frequency") - # { - # if ($aVal eq "" || $aVal < 800) { - # $hash->{logMethod}->($name, 3, "$name: Attr, delete cc1101_frequency"); - # delete ($hash->{cc1101_frequency}) if (defined($hash->{cc1101_frequency})); - # } else { - # $hash->{logMethod}->($name, 3, "$name: Attr, setting cc1101_frequency to 868"); - # $hash->{cc1101_frequency} = 868; - # } - # } - ####### Ende kann wahrscheinlich weg ####### - elsif ($aName eq "hardware") # to set flashCommand if hardware def or change - { - # to delete flashCommand if hardware delete - if ($cmd eq "del") { - if (exists $attr{$name}{flashCommand}) { delete $attr{$name}{flashCommand};} - } - } - elsif ($aName eq "eventlogging") # enable / disable eventlogging - { - if ($aVal == 1) { - $hash->{logMethod} = \&::SIGNALduino_Log3; - Log3 $name, 3, "$name: Attr, Enable eventlogging"; - } else { - $hash->{logMethod} = \&::Log3; - Log3 $name, 3, "$name: Attr, Disable eventlogging"; - } - } - - return ; + if( ref($match_list) eq 'HASH' ) { + $hash->{MatchList} = { %matchListSIGNALduino , %$match_list }; ## Allow incremental addition of an entry to existing hash list + } else { + $hash->{MatchList} = \%matchListSIGNALduino; ## Set defaults + $hash->{logMethod}->($name, 2, $name .": Attr, $aVal: not a HASH using defaults") if( $aVal ); + } + } + ## Change verbose + elsif ($aName eq 'verbose') { + $hash->{logMethod}->($name, 3, "$name: Attr, setting Verbose to: " . $aVal); + $hash->{unknownmessages}='' if $aVal <4; + } + ## Change debug + elsif ($aName eq 'debug') + { + $debug = $aVal; + $hash->{logMethod}->($name, 3, "$name: Attr, setting debug to: " . $debug); + } + ## Change whitelist_IDs + elsif ($aName eq 'whitelist_IDs') + { + if ($init_done) { # beim fhem Start wird das SIGNALduino_IdList nicht aufgerufen, da es beim define aufgerufen wird + SIGNALduino_IdList("x:$name",$aVal); + } + } + ## Change blacklist_IDs + elsif ($aName eq 'blacklist_IDs') + { + if ($init_done) { # beim fhem Start wird das SIGNALduino_IdList nicht aufgerufen, da es beim define aufgerufen wird + SIGNALduino_IdList("x:$name",undef,$aVal); + } + } + ## Change development + elsif ($aName eq 'development') + { + if ($init_done) { # beim fhem Start wird das SIGNALduino_IdList nicht aufgerufen, da es beim define aufgerufen wird + SIGNALduino_IdList("x:$name",undef,undef,$aVal); + } + } + ## Change doubleMsgCheck_IDs + elsif ($aName eq 'doubleMsgCheck_IDs') + { + if (defined($aVal)) { + if (length($aVal)>0) { + if (substr($aVal,0 ,1) eq '#') { + $hash->{logMethod}->($name, 3, "$name: Attr, doubleMsgCheck_IDs disabled: $aVal"); + delete $hash->{DoubleMsgIDs}; + } + else { + $hash->{logMethod}->($name, 3, "$name: Attr, doubleMsgCheck_IDs enabled: $aVal"); + my %DoubleMsgiD = map { $_ => 1 } split(',', $aVal); + $hash->{DoubleMsgIDs} = \%DoubleMsgiD; + #print Dumper $hash->{DoubleMsgIDs}; + } + } + else { + $hash->{logMethod}->($name, 3, "$name: Attr, delete doubleMsgCheck_IDs"); + delete $hash->{DoubleMsgIDs}; + } + } + } + ## Change hardware + elsif ($aName eq 'hardware') # to set flashCommand if hardware def or change + { + if ($cmd eq 'del') { # to delete flashCommand if hardware delete + if (exists $attr{$name}{flashCommand}) { delete $attr{$name}{flashCommand};} + } + } + ## Change eventlogging + elsif ($aName eq 'eventlogging') # enable / disable eventlogging + { + if ($cmd eq 'set' && $aVal == 1) { + $hash->{logMethod} = \&::SIGNALduino_Log3; + Log3 $name, 3, "$name: Attr, Enable eventlogging"; + } else { + $hash->{logMethod} = \&::Log3; + Log3 $name, 3, "$name: Attr, Disable eventlogging"; + } + } + ## Change userReadings + elsif ($aName eq 'userReadings') # look reserved cc1101 readings + { + return "Note, please use other userReadings names.\nReserved names from $name are: cc1101_config, cc1101_config_ext, cc1101_patable" + if ($aVal =~ /cc1101_(?:config(?:_ext)?|patable)(?:\s|{)/); + } + ## Change cc1101_reg_user + elsif ($aName eq 'cc1101_reg_user' && $cmd eq 'set') # set default register + { + return 'ERROR: This attribute is only available for a receiver with CC1101.' if ( ($init_done == 1) && (InternalVal($hash->{NAME},"cc1101_available",0) == 0) ); + $aVal = $aVal.',' if ($aVal !~ /,$/gx); + return 'ERROR: Your attribute value is wrong!' if ( $aVal !~ /^([0-2]{1}[0-9a-fA-F]{3},)+$/gx); + } + ## Change rfmode + elsif ($aName eq 'rfmode') # change receive mode + { + if( $cmd eq 'set' ) { + if (!first { $_ eq $aVal } @rfmode) { + $hash->{logMethod}->($name, 1, "$name: Attr, $aName $aVal is not supported"); + return 'ERROR: The rfmode is not supported'; + } + if ($init_done) { + my $ret = main::SIGNALduino_Attr_rfmode($hash,$aVal); + if (defined $ret) { + return $ret; + } else { + $hash->{logMethod}->($name, 3, "$name: Attr, $aName switched to $aVal"); + } + } + } + } + return ; } ############################# package main @@ -2928,7 +3220,6 @@ sub SIGNALduino_FW_Detail($@) { my ($FW_wname, $name, $room, $pageHash) = @_; my $hash = $defs{$name}; - my @dspec=devspec2array("DEF=.*fakelog"); my $lfn = $dspec[0]; my $fn=$defs{$name}->{TYPE}."-Flash.log"; @@ -2937,15 +3228,14 @@ sub SIGNALduino_FW_Detail($@) { "; - - if (-s AttrVal("global", "logdir", "./log/") .$fn) + if (-s AttrVal('global', 'logdir', './log/') .$fn) { - my $flashlogurl="$FW_ME/FileLog_logWrapper?dev=$lfn&type=text&file=$fn"; + my $flashlogurl="$FW_ME/FileLog_logWrapper?dev=$lfn&type=text&file=$fn"; - $ret .= ""; - #return $ret; + $ret .= ""; + #return $ret; } my $protocolURL="$FW_ME/FileLog_logWrapper?dev=$lfn&type=text&file=$fn"; @@ -2955,8 +3245,8 @@ sub SIGNALduino_FW_Detail($@) { '; return $ret; } ############################# package main sub SIGNALduino_FW_saveWhitelist { - my $name = shift; - my $wl_attr = shift; + my $name = shift; + my $wl_attr = shift; + my $hash = $defs{$name}; - if (!IsDevice($name)) { - Log3 undef, 3, "$name: FW_saveWhitelist, is not a valid definition, operation aborted."; - return; - } + if (!IsDevice($name)) { + Log3 undef, 3, "$name: FW_saveWhitelist, is not a valid definition, operation aborted."; + return; + } - if ($wl_attr eq "") { # da ein Attribut nicht leer sein kann, kommt ein Komma rein - $wl_attr = ','; - } - elsif ($wl_attr !~ /\d+(?:,\d.?\d?)*$/ ) { - Log3 $name, 3, "$name: FW_saveWhitelist, attr whitelist_IDs can not be updated"; - return; - } - else { - $wl_attr =~ s/,$//; # Komma am Ende entfernen - } - $attr{$name}{whitelist_IDs} = $wl_attr; - Log3 $name, 3, "$name: FW_saveWhitelist, $wl_attr"; - SIGNALduino_IdList("x:$name", $wl_attr); + if ($wl_attr eq '') { # da ein Attribut nicht leer sein kann, kommt ein Komma rein + $wl_attr = ','; + } + elsif ($wl_attr !~ /\d+(?:,\d.?\d?)*$/ ) { + Log3 $name, 3, "$name: FW_saveWhitelist, attr whitelist_IDs can not be updated"; + return; + } + else { + $wl_attr =~ s/,$//; # Komma am Ende entfernen + } + CommandAttr($hash,"$name whitelist_IDs $wl_attr"); + Log3 $name, 3, "$name: FW_saveWhitelist, $wl_attr"; + SIGNALduino_IdList("x:$name", $wl_attr); } -############################# package main +############################# package main - test is missing sub SIGNALduino_IdList($@) { - my ($param, $aVal, $blacklist, $develop0) = @_; - my (undef,$name) = split(':', $param); - my $hash = $defs{$name}; + my ($param, $aVal, $blacklist, $develop0) = @_; + my (undef,$name) = split(':', $param); + my $hash = $defs{$name}; - my @msIdList = (); - my @muIdList = (); - my @mcIdList = (); - my @skippedDevId = (); - my @skippedBlackId = (); - my @skippedWhiteId = (); - my @devModulId = (); - my %WhitelistIDs; - my %BlacklistIDs; - my $wflag = 0; # whitelist flag, 0=disabled + my @msIdList = (); + my @muIdList = (); + my @mcIdList = (); + my @mnIdList = (); + my @skippedDevId = (); + my @skippedBlackId = (); + my @skippedWhiteId = (); + my @devModulId = (); + my %WhitelistIDs; + my %BlacklistIDs; + my $wflag = 0; # whitelist flag, 0=disabled - delete ($hash->{IDsNoDispatch}) if (defined($hash->{IDsNoDispatch})); + delete ($hash->{IDsNoDispatch}) if (defined($hash->{IDsNoDispatch})); - if (!defined($aVal)) { - $aVal = AttrVal($name,"whitelist_IDs",""); - } + if (!defined($aVal)) { + $aVal = AttrVal($name,'whitelist_IDs',''); + } - my ($develop,$devFlag) = SIGNALduino_getAttrDevelopment($name, $develop0); # $devFlag = 1 -> alle developIDs y aktivieren - $hash->{logMethod}->($name, 3, "$name: IdList, development version active, development attribute = $develop") if ($devFlag == 1); + my ($develop,$devFlag) = SIGNALduino_getAttrDevelopment($name, $develop0); # $devFlag = 1 -> alle developIDs y aktivieren + $hash->{logMethod}->($name, 3, "$name: IdList, development version active, development attribute = $develop") if ($devFlag == 1); - if ($aVal eq "" || substr($aVal,0 ,1) eq '#') { # whitelist nicht aktiv - if ($devFlag == 1) { - $hash->{logMethod}->($name, 3, "$name: IdList, attr whitelist disabled or not defined (all IDs are enabled, except blacklisted): $aVal"); - } - else { - $hash->{logMethod}->($name, 3, "$name: IdList, attr whitelist disabled or not defined (all IDs are enabled, except blacklisted and instable IDs): $aVal"); - } - } - else { - %WhitelistIDs = map {$_ => undef} split(",", $aVal); # whitelist in Hash wandeln - #my $w = join ',' => map "$_" => keys %WhitelistIDs; - $hash->{logMethod}->($name, 3, "$name: IdList, attr whitelist: $aVal"); - $wflag = 1; - } - #SIGNALduino_Log3 $name, 3, "$name IdList: attr whitelistIds=$aVal" if ($aVal); + if ($aVal eq '' || substr($aVal,0 ,1) eq '#') { # whitelist nicht aktiv + ($devFlag == 1) + ? $hash->{logMethod}->($name, 3, "$name: IdList, attr whitelist disabled or not defined (all IDs are enabled, except blacklisted): $aVal") + : $hash->{logMethod}->($name, 3, "$name: IdList, attr whitelist disabled or not defined (all IDs are enabled, except blacklisted and instable IDs): $aVal"); + } else { + %WhitelistIDs = map {$_ => undef} split(',', $aVal); # whitelist in Hash wandeln + #my $w = join ',' => map "$_" => keys %WhitelistIDs; + $hash->{logMethod}->($name, 3, "$name: IdList, attr whitelist: $aVal"); + $wflag = 1; + } + #SIGNALduino_Log3 $name, 3, "$name IdList: attr whitelistIds=$aVal" if ($aVal); - if ($wflag == 0) { # whitelist not aktive - if (!defined($blacklist)) { - $blacklist = AttrVal($name,"blacklist_IDs",""); - } - if (length($blacklist) > 0) { # Blacklist in Hash wandeln - $hash->{logMethod}->($name, 3, "$name: IdList, attr blacklistIds=$blacklist"); - %BlacklistIDs = map { $_ => 1 } split(",", $blacklist); - #my $w = join ', ' => map "$_" => keys %BlacklistIDs; - #SIGNALduino_Log3 $name, 3, "$name IdList, Attr blacklist $w"; - } - } + if ($wflag == 0) { # whitelist not aktive + if (!defined($blacklist)) { + $blacklist = AttrVal($name,'blacklist_IDs',''); + } + if (length($blacklist) > 0) { # Blacklist in Hash wandeln + $hash->{logMethod}->($name, 3, "$name: IdList, attr blacklistIds=$blacklist"); + %BlacklistIDs = map { $_ => 1 } split(',', $blacklist); + #my $w = join ', ' => map "$_" => keys %BlacklistIDs; + #SIGNALduino_Log3 $name, 3, "$name IdList, Attr blacklist $w"; + } + } + for my $id ($hash->{protocolObject}->getKeys()) + { + if ($wflag == 1) # whitelist active + { + if (!exists($WhitelistIDs{$id})) # Id wurde in der whitelist nicht gefunden + { + push (@skippedWhiteId, $id); + next; + } + } + else { # whitelist not active + if (exists($BlacklistIDs{$id})) { + #SIGNALduino_Log3 $name, 3, "$name: IdList, skip Blacklist ID $id"; + push (@skippedBlackId, $id); + next; + } + # wenn es keine developId gibt, dann die folgenden Abfragen ueberspringen + if (defined $hash->{protocolObject}->getProperty($id,'developId')) + { + if ($hash->{protocolObject}->getProperty($id,'developId') eq 'm') { + if ($develop !~ m/m$id/) { # ist nur zur Abwaertskompatibilitaet und kann in einer der naechsten Versionen entfernt werden + push (@devModulId, $id); + if ($devFlag == 0) { + push (@skippedDevId, $id); + next; + } + } + } + elsif ($hash->{protocolObject}->getProperty($id,'developId') eq 'p') { + $hash->{logMethod}->($name, 5, "$name: IdList, ID=$id skipped (developId=p), caution, protocol can cause crashes, use only if advised to do"); + next; + } + elsif ($devFlag == 0 && $hash->{protocolObject}->getProperty($id,'developId') eq 'y' && $develop !~ m/y$id/) { + #SIGNALduino_Log3 $name, 3, "$name: IdList, ID=$id skipped (developId=y)"; + push (@skippedDevId, $id); + next; + } + } + } - foreach my $id (keys %ProtocolListSIGNALduino) - { - if ($wflag == 1) # whitelist active - { - if (!exists($WhitelistIDs{$id})) # Id wurde in der whitelist nicht gefunden - { - push (@skippedWhiteId, $id); - next; - } - } - else { # whitelist not active - if (exists($BlacklistIDs{$id})) { - #SIGNALduino_Log3 $name, 3, "$name: IdList, skip Blacklist ID $id"; - push (@skippedBlackId, $id); - next; - } + if (defined($hash->{protocolObject}->getProperty($id,'format')) && $hash->{protocolObject}->getProperty($id,'format') eq 'manchester') + { + push (@mcIdList, $id); + } + elsif (defined $hash->{protocolObject}->getProperty($id,'modulation')) + { + push (@mnIdList, $id); + } + elsif (defined $hash->{protocolObject}->getProperty($id,'sync')) + { + push (@msIdList, $id); + } + elsif (defined $hash->{protocolObject}->getProperty($id,'clockabs')) + { + # $ProtocolListSIGNALduino{$id}{length_min} = SDUINO_PARSE_DEFAULT_LENGHT_MIN if (!exists($ProtocolListSIGNALduino{$id}{length_min})); + push (@muIdList, $id); + } + } - # wenn es keine developId gibt, dann die folgenden Abfragen ueberspringen - if (exists($ProtocolListSIGNALduino{$id}{developId})) - { - if ($ProtocolListSIGNALduino{$id}{developId} eq "m") { - if ($develop !~ m/m$id/) { # ist nur zur Abwaertskompatibilitaet und kann in einer der naechsten Versionen entfernt werden - push (@devModulId, $id); - if ($devFlag == 0) { - push (@skippedDevId, $id); - next; - } - } - } - elsif ($ProtocolListSIGNALduino{$id}{developId} eq "p") { - $hash->{logMethod}->($name, 5, "$name: IdList, ID=$id skipped (developId=p), caution, protocol can cause crashes, use only if advised to do"); - next; - } - elsif ($devFlag == 0 && $ProtocolListSIGNALduino{$id}{developId} eq "y" && $develop !~ m/y$id/) { - #SIGNALduino_Log3 $name, 3, "$name: IdList, ID=$id skipped (developId=y)"; - push (@skippedDevId, $id); - next; - } - } - } + @msIdList = sort {$a <=> $b} @msIdList; + @muIdList = sort {$a <=> $b} @muIdList; + @mcIdList = sort {$a <=> $b} @mcIdList; + @mnIdList = sort {$a <=> $b} @mnIdList; + @skippedDevId = sort {$a <=> $b} @skippedDevId; + @skippedBlackId = sort {$a <=> $b} @skippedBlackId; + @skippedWhiteId = sort {$a <=> $b} @skippedWhiteId; - if (exists ($ProtocolListSIGNALduino{$id}{format}) && $ProtocolListSIGNALduino{$id}{format} eq "manchester") - { - push (@mcIdList, $id); - } - elsif (exists $ProtocolListSIGNALduino{$id}{sync}) - { - push (@msIdList, $id); - } - elsif (exists ($ProtocolListSIGNALduino{$id}{clockabs})) - { - $ProtocolListSIGNALduino{$id}{length_min} = SDUINO_PARSE_DEFAULT_LENGHT_MIN if (!exists($ProtocolListSIGNALduino{$id}{length_min})); - push (@muIdList, $id); - } - } + @devModulId = sort {$a <=> $b} @devModulId; - @msIdList = sort {$a <=> $b} @msIdList; - @muIdList = sort {$a <=> $b} @muIdList; - @mcIdList = sort {$a <=> $b} @mcIdList; - @skippedDevId = sort {$a <=> $b} @skippedDevId; - @skippedBlackId = sort {$a <=> $b} @skippedBlackId; - @skippedWhiteId = sort {$a <=> $b} @skippedWhiteId; + $hash->{logMethod}->($name, 3, "$name: IdList, MS @msIdList"); + $hash->{logMethod}->($name, 3, "$name: IdList, MU @muIdList"); + $hash->{logMethod}->($name, 3, "$name: IdList, MC @mcIdList"); + $hash->{logMethod}->($name, 3, "$name: IdList, MN @mnIdList"); # ToDo: nur wenn Internal cc1101_available 1 ??? + $hash->{logMethod}->($name, 5, "$name: IdList, not whitelisted skipped = @skippedWhiteId") if (scalar @skippedWhiteId > 0); + $hash->{logMethod}->($name, 4, "$name: IdList, blacklistId skipped = @skippedBlackId") if (scalar @skippedBlackId > 0); + $hash->{logMethod}->($name, 4, "$name: IdList, development skipped = @skippedDevId") if (scalar @skippedDevId > 0); + if (scalar @devModulId > 0) + { + $hash->{logMethod}->($name, 3, "$name: IdList, development protocol is active (to activate dispatch to not finshed logical module, enable desired protocol via whitelistIDs) = @devModulId"); + $hash->{IDsNoDispatch} = join(',', @devModulId); + } - @devModulId = sort {$a <=> $b} @devModulId; - - $hash->{logMethod}->($name, 3, "$name: IdList, MS @msIdList"); - $hash->{logMethod}->($name, 3, "$name: IdList, MU @muIdList"); - $hash->{logMethod}->($name, 3, "$name: IdList, MC @mcIdList"); - $hash->{logMethod}->($name, 5, "$name: IdList, not whitelisted skipped = @skippedWhiteId") if (scalar @skippedWhiteId > 0); - $hash->{logMethod}->($name, 4, "$name: IdList, blacklistId skipped = @skippedBlackId") if (scalar @skippedBlackId > 0); - $hash->{logMethod}->($name, 4, "$name: IdList, development skipped = @skippedDevId") if (scalar @skippedDevId > 0); - if (scalar @devModulId > 0) - { - $hash->{logMethod}->($name, 3, "$name: IdList, development protocol is active (to activate dispatch to not finshed logical module, enable desired protocol via whitelistIDs) = @devModulId"); - $hash->{IDsNoDispatch} = join(",", @devModulId); - } - - $hash->{msIdList} = \@msIdList; - $hash->{muIdList} = \@muIdList; - $hash->{mcIdList} = \@mcIdList; + $hash->{msIdList} = \@msIdList; + $hash->{muIdList} = \@muIdList; + $hash->{mcIdList} = \@mcIdList; + $hash->{mnIdList} = \@mnIdList; } -############################# package main +############################# package main, test exists sub SIGNALduino_getAttrDevelopment { - my $name = shift; - my $develop = shift; - my $devFlag = 0; - if (index(SDUINO_VERSION, "dev") >= 0) { # development version - $develop = AttrVal($name,"development", 0) if (!defined($develop)); - $devFlag = 1 if ($develop eq "1" || (substr($develop,0,1) eq "y" && $develop !~ m/^y\d/)); # Entwicklerversion, y ist nur zur Abwaertskompatibilitaet und kann in einer der naechsten Versionen entfernt werden - } - else { - $develop = "0"; - Log3 $name, 3, "$name: getAttrDevelopment, IdList ### Attribute development is in this version ignored ###"; - } - return ($develop,$devFlag); + my $name = shift; + my $develop = shift; + my $devFlag = 0; + if (index(SDUINO_VERSION, 'dev') >= 0) { # development version + $develop = AttrVal($name,'development', 0) if (!defined($develop)); + $devFlag = 1 if ($develop eq '1' || (substr($develop,0,1) eq 'y' && $develop !~ m/^y\d/)); # Entwicklerversion, y ist nur zur Abwaertskompatibilitaet und kann in einer der naechsten Versionen entfernt werden + } else { + $develop = '0'; + Log3 $name, 3, "$name: getAttrDevelopment, IdList ### Attribute development is in this version ignored ###"; + } + return ($develop,$devFlag); } -############################# package main +############################# package main, test exists sub SIGNALduino_callsub { - my $funcname =shift; - my $method = shift; - my $evalFirst = shift; - my $name = shift; + my $obj=shift; #comatibility thing + my $funcname =shift // carp 'to less arguments,functionname is required';; + my $method = shift // undef; + my $evalFirst = shift // undef; + my $name = shift // carp 'to less arguments, name is required'; - my @args = @_; + my @args = @_; - my $hash = $defs{$name}; - if ( defined $method && defined &$method ) - { - if (defined($evalFirst) && $evalFirst) - { - eval( $method->($name, @args)); - if($@) { - $hash->{logMethod}->($name, 5, "$name: callsub, Error: $funcname, has an error and will not be executed: $@ please report at github."); - return (0,undef); - } - } - #my $subname = @{[eval {&$method}, $@ =~ /.*/]}; - $hash->{logMethod}->($hash, 5, "$name: callsub, applying $funcname, value before: @args"); # method $subname" - - my ($rcode, @returnvalues) = $method->($name, @args) ; - - if (@returnvalues && defined($returnvalues[0])) { - $hash->{logMethod}->($name, 5, "$name: callsub, rcode=$rcode, modified value after $funcname: @returnvalues"); - } else { - $hash->{logMethod}->($name, 5, "$name: callsub, rcode=$rcode, after calling $funcname"); - } - return ($rcode, @returnvalues); - } elsif (defined $method ) { - $hash->{logMethod}->($name, 5, "$name: callsub, Error: Unknown method $funcname pease report at github"); - return (0,undef); - } - return (1,@args); -} - -############################# package main -# calculates the hex (in bits) and adds it at the beginning of the message -# input = @list -# output = @list -sub SIGNALduino_lengtnPrefix { - my ($name, @bit_msg) = @_; - - my $msg = join("",@bit_msg); - - #$msg = unpack("B8", pack("N", length($msg))).$msg; - $msg=sprintf('%08b', length($msg)).$msg; - - return (1,split("",$msg)); -} - -############################# package main -sub SIGNALduino_PreparingSend_FS20_FHT($$$) { - my ($id, $sum, $msg) = @_; - my $temp = 0; - my $newmsg = "P$id#0000000000001"; # 12 Bit Praeambel, 1 bit - - for (my $i=0; $i 01 1 -> 10 to be compatible with IT Module - $msg =~ s/0/z/g; - $msg =~ s/1/10/g; - $msg =~ s/z/01/g; - return (1,split("",$msg)); -} - -############################# package main -sub SIGNALduino_bit2itv1 { - my ($name, @bit_msg) = @_; - my $msg = join("",@bit_msg); - - $msg =~ s/0F/01/g; # Convert 0F -> 01 (F) to be compatible with CUL -# $msg =~ s/0F/11/g; # Convert 0F -> 11 (1) float - if (index($msg,'F') == -1) { - return (1,split("",$msg)); - } else { - return (0,0); - } -} - -############################# package main -sub SIGNALduino_ITV1_tristateToBit($) { - my ($msg) = @_; - # Convert 0 -> 00 1 -> 11 F => 01 to be compatible with IT Module - $msg =~ s/0/00/g; - $msg =~ s/1/11/g; - $msg =~ s/F/01/g; - $msg =~ s/D/10/g; - - return (1,$msg); -} - -############################# package main -sub SIGNALduino_HE800($@) { - my ($name, @bit_msg) = @_; - my $protolength = scalar @bit_msg; - - if ($protolength < 40) { - for (my $i=0; $i<(40-$protolength); $i++) { - push(@bit_msg, 0); - } - } - return (1,@bit_msg); -} - -############################# package main -sub SIGNALduino_HE_EU($@) { - my ($name, @bit_msg) = @_; - my $protolength = scalar @bit_msg; - - if ($protolength < 72) { - for (my $i=0; $i<(72-$protolength); $i++) { - push(@bit_msg, 0); - } - } - return (1,@bit_msg); -} - -############################# package main -sub SIGNALduino_postDemo_EM($@) { - my ($name, @bit_msg) = @_; - my $msg = join("",@bit_msg); - my $msg_start = index($msg, "0000000001"); # find start - my $count; - $msg = substr($msg,$msg_start + 10); # delete preamble + 1 bit - my $new_msg = ""; - my $crcbyte; - my $msgcrc = 0; - my $hash = $defs{$name}; - - if ($msg_start > 0 && length $msg == 89) { - for ($count = 0; $count < length ($msg) ; $count +=9) { - $crcbyte = substr($msg,$count,8); - if ($count < (length($msg) - 10)) { - $new_msg.= join "", reverse @bit_msg[$msg_start + 10 + $count.. $msg_start + 17 + $count]; - $msgcrc = $msgcrc ^ oct( "0b$crcbyte" ); - } - } - if ($msgcrc == oct( "0b$crcbyte" )) { - $hash->{logMethod}->($name, 4, "$name: EM, protocol - CRC OK"); - return (1,split("",$new_msg)); - } else { - $hash->{logMethod}->($name, 3, "$name: EM, protocol - CRC ERROR"); - return 0, undef; - } - } - - $hash->{logMethod}->($name, 3, "$name: EM, protocol - Start not found or length msg (".length $msg.") not correct"); - return 0, undef; -} - -############################# package main -sub SIGNALduino_postDemo_FS20($@) { - my ($name, @bit_msg) = @_; - my $datastart = 0; - my $protolength = scalar @bit_msg; - my $sum = 6; - my $b = 0; - my $i = 0; - for ($datastart = 0; $datastart < $protolength; $datastart++) { # Start bei erstem Bit mit Wert 1 suchen - last if $bit_msg[$datastart] eq "1"; - } - my $hash = $defs{$name}; - if ($datastart == $protolength) { # all bits are 0 - $hash->{logMethod}->($name, 3, "$name: FS20, ERROR message all bit are zeros"); - return 0, undef; - } - splice(@bit_msg, 0, $datastart + 1); # delete preamble + 1 bit - $protolength = scalar @bit_msg; - $hash->{logMethod}->($name, 5, "$name: FS20, pos=$datastart length=$protolength"); - if ($protolength == 46 || $protolength == 55) { # If it 1 bit too long, then it will be removed (EOT-Bit) - pop(@bit_msg); - $protolength--; - } - if ($protolength == 45 || $protolength == 54) { ### FS20 length 45 or 54 - for(my $b = 0; $b < $protolength - 9; $b += 9) { # build sum over first 4 or 5 bytes - $sum += oct( "0b".(join "", @bit_msg[$b .. $b + 7])); + my $hash = $defs{$name}; + if ( defined $method && defined &$method ) + { + if (defined($evalFirst) && $evalFirst) + { + eval( $method->($obj,$name, @args)); + if($@) { + $hash->{logMethod}->($name, 5, "$name: callsub, Error: $funcname, has an error and will not be executed: $@ please report at github."); + return (0,undef); } - my $checksum = oct( "0b".(join "", @bit_msg[$protolength - 9 .. $protolength - 2])); # Checksum Byte 5 or 6 - if ((($sum + 6) & 0xFF) == $checksum) { # Message from FHT80 roothermostat - $hash->{logMethod}->($name, 5, "$name: FS20, Detection aborted, checksum matches FHT code"); - return 0, undef; - } - if (($sum & 0xFF) == $checksum) { ## FH20 remote control - for(my $b = 0; $b < $protolength; $b += 9) { # check parity over 5 or 6 bytes - my $parity = 0; # Parity even - for(my $i = $b; $i < $b + 9; $i++) { # Parity over 1 byte + 1 bit - $parity += $bit_msg[$i]; - } - if ($parity % 2 != 0) { - $hash->{logMethod}->($name, 3, "$name: FS20, ERROR - Parity not even"); - return 0, undef; - } - } # parity ok - for(my $b = $protolength - 1; $b > 0; $b -= 9) { # delete 5 or 6 parity bits - splice(@bit_msg, $b, 1); - } - if ($protolength == 45) { ### FS20 length 45 - splice(@bit_msg, 32, 8); # delete checksum - splice(@bit_msg, 24, 0, (0,0,0,0,0,0,0,0)); # insert Byte 3 - } else { ### FS20 length 54 - splice(@bit_msg, 40, 8); # delete checksum - } - my $dmsg = SIGNALduino_b2h(join "", @bit_msg); - $hash->{logMethod}->($name, 4, "$name: FS20, remote control post demodulation $dmsg length $protolength"); - return (1, @bit_msg); ## FHT80TF ok - } - else { - $hash->{logMethod}->($name, 4, "$name: FS20, ERROR - wrong checksum"); - } - } - else { - $hash->{logMethod}->($name, 5, "$name: FS20, ERROR - wrong length=$protolength (must be 45 or 54)"); - } - return 0, undef; -} - -############################# package main -sub SIGNALduino_postDemo_FHT80($@) { - my ($name, @bit_msg) = @_; - my $datastart = 0; - my $protolength = scalar @bit_msg; - my $sum = 12; - my $b = 0; - my $i = 0; - my $hash=$defs{$name}; - for ($datastart = 0; $datastart < $protolength; $datastart++) { # Start bei erstem Bit mit Wert 1 suchen - last if $bit_msg[$datastart] eq "1"; - } - if ($datastart == $protolength) { # all bits are 0 - $hash->{logMethod}->($name, 3, "$name: FHT80, ERROR message all bit are zeros"); - return 0, undef; - } - splice(@bit_msg, 0, $datastart + 1); # delete preamble + 1 bit - $protolength = scalar @bit_msg; - $hash->{logMethod}->($name, 5, "$name: FHT80, pos=$datastart length=$protolength"); - if ($protolength == 55) { # If it 1 bit too long, then it will be removed (EOT-Bit) - pop(@bit_msg); - $protolength--; - } - if ($protolength == 54) { ### FHT80 fixed length - for($b = 0; $b < 45; $b += 9) { # build sum over first 5 bytes - $sum += oct( "0b".(join "", @bit_msg[$b .. $b + 7])); - } - my $checksum = oct( "0b".(join "", @bit_msg[45 .. 52])); # Checksum Byte 6 - if ((($sum - 6) & 0xFF) == $checksum) { ## Message from FS20 remote control - $hash->{logMethod}->($name, 5, "$name: FHT80, Detection aborted, checksum matches FS20 code"); - return 0, undef; - } - if (($sum & 0xFF) == $checksum) { ## FHT80 Raumthermostat - for($b = 0; $b < 54; $b += 9) { # check parity over 6 byte - my $parity = 0; # Parity even - for($i = $b; $i < $b + 9; $i++) { # Parity over 1 byte + 1 bit - $parity += $bit_msg[$i]; - } - if ($parity % 2 != 0) { - $hash->{logMethod}->($name, 3, "$name: FHT80, ERROR - Parity not even"); - return 0, undef; - } - } # parity ok - for($b = 53; $b > 0; $b -= 9) { # delete 6 parity bits - splice(@bit_msg, $b, 1); - } - if ($bit_msg[26] != 1) { # Bit 5 Byte 3 must 1 - $hash->{logMethod}->($name, 3, "$name: FHT80, ERROR - byte 3 bit 5 not 1"); - return 0, undef; - } - splice(@bit_msg, 40, 8); # delete checksum - splice(@bit_msg, 24, 0, (0,0,0,0,0,0,0,0));# insert Byte 3 - my $dmsg = SIGNALduino_b2h(join "", @bit_msg); - $hash->{logMethod}->($name, 4, "$name: FHT80, roomthermostat post demodulation $dmsg"); - return (1, @bit_msg); ## FHT80 ok - } - else { - $hash->{logMethod}->($name, 4, "$name: FHT80, ERROR - wrong checksum"); - } - } - else { - $hash->{logMethod}->($name, 5, "$name: FHT80, ERROR - wrong length=$protolength (must be 54)"); - } - return 0, undef; -} - -############################# package main -sub SIGNALduino_postDemo_FHT80TF($@) { - my ($name, @bit_msg) = @_; - my $datastart = 0; - my $protolength = scalar @bit_msg; - my $sum = 12; - my $b = 0; - my $hash=$defs{$name}; - if ($protolength < 46) { # min 5 bytes + 6 bits - $hash->{logMethod}->($name, 4, "$name: FHT80TF, ERROR lenght of message < 46"); - return 0, undef; - } - for ($datastart = 0; $datastart < $protolength; $datastart++) { # Start bei erstem Bit mit Wert 1 suchen - last if $bit_msg[$datastart] eq "1"; - } - if ($datastart == $protolength) { # all bits are 0 - $hash->{logMethod}->($name, 3, "$name: FHT80TF, ERROR message all bit are zeros"); - return 0, undef; - } - splice(@bit_msg, 0, $datastart + 1); # delete preamble + 1 bit - $protolength = scalar @bit_msg; - if ($protolength == 45) { ### FHT80TF fixed length - for(my $b = 0; $b < 36; $b += 9) { # build sum over first 4 bytes - $sum += oct( "0b".(join "", @bit_msg[$b .. $b + 7])); - } - my $checksum = oct( "0b".(join "", @bit_msg[36 .. 43])); # Checksum Byte 5 - if (($sum & 0xFF) == $checksum) { ## FHT80TF Tuer-/Fensterkontakt - for(my $b = 0; $b < 45; $b += 9) { # check parity over 5 byte - my $parity = 0; # Parity even - for(my $i = $b; $i < $b + 9; $i++) { # Parity over 1 byte + 1 bit - $parity += $bit_msg[$i]; - } - if ($parity % 2 != 0) { - $hash->{logMethod}->($name, 4, "$name: FHT80TF, ERROR - Parity not even"); - return 0, undef; - } - } # parity ok - for(my $b = 44; $b > 0; $b -= 9) { # delete 5 parity bits - splice(@bit_msg, $b, 1); - } - if ($bit_msg[26] != 0) { # Bit 5 Byte 3 must 0 - $hash->{logMethod}->($name, 3, "$name: FHT80TF, ERROR - byte 3 bit 5 not 0"); - return 0, undef; - } - splice(@bit_msg, 32, 8); # delete checksum - my $dmsg = SIGNALduino_b2h(join "", @bit_msg); - $hash->{logMethod}->($name, 4, "$name: FHT80TF, door/window switch post demodulation $dmsg"); - return (1, @bit_msg); ## FHT80TF ok - } - } - return 0, undef; -} - -############################# package main -sub SIGNALduino_postDemo_WS7035($@) { - my ($name, @bit_msg) = @_; - my $msg = join("",@bit_msg); - my $parity = 0; # Parity even - my $sum = 0; # checksum - my $hash=$defs{$name}; - $hash->{logMethod}->($name, 4, "$name: WS7035, $msg"); - if (substr($msg,0,8) ne "10100000") { # check ident - $hash->{logMethod}->($name, 3, "$name: WS7035, ERROR - Ident not 1010 0000"); - return 0, undef; - } else { - for(my $i = 15; $i < 28; $i++) { # Parity over bit 15 and 12 bit temperature - $parity += substr($msg, $i, 1); - } - if ($parity % 2 != 0) { - $hash->{logMethod}->($name, 3, "$name: WS7035, ERROR - Parity not even"); - return 0, undef; - } else { - for(my $i = 0; $i < 39; $i += 4) { # Sum over nibble 0 - 9 - $sum += oct("0b".substr($msg,$i,4)); - } - if (($sum &= 0x0F) != oct("0b".substr($msg,40,4))) { - $hash->{logMethod}->($name, 3, "$name: WS7035, ERROR - wrong checksum"); - return 0, undef; - } else { - $hash->{logMethod}->($name, 4, "$name: WS7035, " . substr($msg,0,4) ." ". substr($msg,4,4) ." ". substr($msg,8,4) ." ". substr($msg,12,4) ." ". substr($msg,16,4) ." ". substr($msg,20,4) ." ". substr($msg,24,4) ." ". substr($msg,28,4) ." ". substr($msg,32,4) ." ". substr($msg,36,4) ." ". substr($msg,40)); - substr($msg, 27, 4, ''); # delete nibble 8 - return (1,split("",$msg)); - } - } - } -} - -############################# package main -sub SIGNALduino_postDemo_WS2000($@) { - my ($name, @bit_msg) = @_; - my @new_bit_msg = ""; - my $protolength = scalar @bit_msg; - my @datalenghtws = (35,50,35,50,70,40,40,85); - my $datastart = 0; - my $datalength = 0; - my $datalength1 = 0; - my $index = 0; - my $data = 0; - my $dataindex = 0; - my $check = 0; - my $sum = 5; - my $typ = 0; - my $adr = 0; - my $hash=$defs{$name}; - my @sensors = ( - "Thermo", - "Thermo/Hygro", - "Rain", - "Wind", - "Thermo/Hygro/Baro", - "Brightness", - "Pyrano", - "Kombi" - ); - - for ($datastart = 0; $datastart < $protolength; $datastart++) { # Start bei erstem Bit mit Wert 1 suchen - last if $bit_msg[$datastart] eq "1"; - } - if ($datastart == $protolength) { # all bits are 0 - $hash->{logMethod}->($name, 4, "$name: WS2000, ERROR message all bit are zeros"); - return 0, undef; - } - $datalength = $protolength - $datastart; - $datalength1 = $datalength - ($datalength % 5); # modulo 5 - $hash->{logMethod}->($name, 5, "$name: WS2000, protolength: $protolength, datastart: $datastart, datalength $datalength"); - $typ = oct( "0b".(join "", reverse @bit_msg[$datastart + 1.. $datastart + 4])); # Sensortyp - if ($typ > 7) { - $hash->{logMethod}->($name, 4, "$name: WS2000, Sensortyp $typ - ERROR typ to big (0-7)"); - return 0, undef; - } - if ($typ == 1 && ($datalength == 45 || $datalength == 46)) {$datalength1 += 5;} # Typ 1 ohne Summe - if ($datalenghtws[$typ] != $datalength1) { # check lenght of message - $hash->{logMethod}->($name, 4, "$name: WS2000, Sensortyp $typ - ERROR lenght of message $datalength1 ($datalenghtws[$typ])"); - return 0, undef; - } elsif ($datastart > 10) { # max 10 Bit preamble - $hash->{logMethod}->($name, 4, "$name: WS2000, ERROR preamble > 10 ($datastart)"); - return 0, undef; - } else { - do { - if ($bit_msg[$index + $datastart] != 1) { # jedes 5. Bit muss 1 sein - $hash->{logMethod}->($name, 4, "$name: WS2000, Sensortyp $typ - ERROR checking bit $index"); - return (0, undef); - } - $dataindex = $index + $datastart + 1; - $data = oct( "0b".(join "", reverse @bit_msg[$dataindex .. $dataindex + 3])); - if ($index == 5) {$adr = ($data & 0x07)} # Sensoradresse - if ($datalength == 45 || $datalength == 46) { # Typ 1 ohne Summe - if ($index <= $datalength - 5) { - $check = $check ^ $data; # Check - Typ XOR Adresse XOR bis XOR Check muss 0 ergeben - } - } else { - if ($index <= $datalength - 10) { - $check = $check ^ $data; # Check - Typ XOR Adresse XOR bis XOR Check muss 0 ergeben - $sum += $data; - } - } - $index += 5; - } until ($index >= $datalength -1 ); - } - if ($check != 0) { - $hash->{logMethod}->($name, 4, "$name: WS2000, Sensortyp $typ Adr $adr - ERROR check XOR"); - return (0, undef); - } else { - if ($datalength < 45 || $datalength > 46) { # Summe pruefen, außer Typ 1 ohne Summe - $data = oct( "0b".(join "", reverse @bit_msg[$dataindex .. $dataindex + 3])); - if ($data != ($sum & 0x0F)) { - $hash->{logMethod}->($name, 4, "$name: WS2000, Sensortyp $typ Adr $adr - ERROR sum"); - return (0, undef); - } - } - $hash->{logMethod}->($name, 4, "$name: WS2000, Sensortyp $typ Adr $adr - $sensors[$typ]"); - $datastart += 1; # [x] - 14_CUL_WS - @new_bit_msg[4 .. 7] = reverse @bit_msg[$datastart .. $datastart+3]; # [2] Sensortyp - @new_bit_msg[0 .. 3] = reverse @bit_msg[$datastart+5 .. $datastart+8]; # [1] Sensoradresse - @new_bit_msg[12 .. 15] = reverse @bit_msg[$datastart+10 .. $datastart+13]; # [4] T 0.1, R LSN, Wi 0.1, B 1, Py 1 - @new_bit_msg[8 .. 11] = reverse @bit_msg[$datastart+15 .. $datastart+18]; # [3] T 1, R MID, Wi 1, B 10, Py 10 - if ($typ == 0 || $typ == 2) { # Thermo (AS3), Rain (S2000R, WS7000-16) - @new_bit_msg[16 .. 19] = reverse @bit_msg[$datastart+20 .. $datastart+23]; # [5] T 10, R MSN - } else { - @new_bit_msg[20 .. 23] = reverse @bit_msg[$datastart+20 .. $datastart+23]; # [6] T 10, Wi 10, B 100, Py 100 - @new_bit_msg[16 .. 19] = reverse @bit_msg[$datastart+25 .. $datastart+28]; # [5] H 0.1, Wr 1, B Fak, Py Fak - if ($typ == 1 || $typ == 3 || $typ == 4 || $typ == 7) { # Thermo/Hygro, Wind, Thermo/Hygro/Baro, Kombi - @new_bit_msg[28 .. 31] = reverse @bit_msg[$datastart+30 .. $datastart+33]; # [8] H 1, Wr 10 - @new_bit_msg[24 .. 27] = reverse @bit_msg[$datastart+35 .. $datastart+38]; # [7] H 10, Wr 100 - if ($typ == 4) { # Thermo/Hygro/Baro (S2001I, S2001ID) - @new_bit_msg[36 .. 39] = reverse @bit_msg[$datastart+40 .. $datastart+43]; # [10] P 1 - @new_bit_msg[32 .. 35] = reverse @bit_msg[$datastart+45 .. $datastart+48]; # [9] P 10 - @new_bit_msg[44 .. 47] = reverse @bit_msg[$datastart+50 .. $datastart+53]; # [12] P 100 - @new_bit_msg[40 .. 43] = reverse @bit_msg[$datastart+55 .. $datastart+58]; # [11] P Null - } - } - } - return (1, @new_bit_msg); - } - -} - -############################# package main -sub SIGNALduino_postDemo_WS7053($@) { - my ($name, @bit_msg) = @_; - my $msg = join("",@bit_msg); - my $parity = 0; # Parity even - my $hash=$defs{$name}; - $hash->{logMethod}->($name, 4, "$name: WS7053, MSG = $msg"); - my $msg_start = index($msg, "10100000"); - if ($msg_start > 0) { # start not correct - $msg = substr($msg, $msg_start); - $msg .= "0"; - $hash->{logMethod}->($name, 5, "$name: WS7053, cut $msg_start char(s) at begin"); - } - if ($msg_start < 0) { # start not found - $hash->{logMethod}->($name, 3, "$name: WS7053, ERROR - Ident 10100000 not found"); - return 0, undef; - } else { - if (length($msg) < 32) { # msg too short - $hash->{logMethod}->($name, 3, "$name: WS7053, ERROR - msg too short, length " . length($msg)); - return 0, undef; - } else { - for(my $i = 15; $i < 28; $i++) { # Parity over bit 15 and 12 bit temperature - $parity += substr($msg, $i, 1); - } - if ($parity % 2 != 0) { - $hash->{logMethod}->($name, 3, "$name: WS7053, ERROR - Parity not even"); - return 0, undef; - } else { - $hash->{logMethod}->($name, 5, "$name: WS7053, before: " . substr($msg,0,4) ." ". substr($msg,4,4) ." ". substr($msg,8,4) ." ". substr($msg,12,4) ." ". substr($msg,16,4) ." ". substr($msg,20,4) ." ". substr($msg,24,4) ." ". substr($msg,28,4)); - # Format from 7053: Bit 0-7 Ident, Bit 8-15 Rolling Code/Parity, Bit 16-27 Temperature (12.3), Bit 28-31 Zero - my $new_msg = substr($msg,0,28) . substr($msg,16,8) . substr($msg,28,4); - # Format for CUL_TX: Bit 0-7 Ident, Bit 8-15 Rolling Code/Parity, Bit 16-27 Temperature (12.3), Bit 28 - 35 Temperature (12), Bit 36-39 Zero - $hash->{logMethod}->($name, 5, "$name: WS7053, after: " . substr($new_msg,0,4) ." ". substr($new_msg,4,4) ." ". substr($new_msg,8,4) ." ". substr($new_msg,12,4) ." ". substr($new_msg,16,4) ." ". substr($new_msg,20,4) ." ". substr($new_msg,24,4) ." ". substr($new_msg,28,4) ." ". substr($new_msg,32,4) ." ". substr($new_msg,36,4)); - return (1,split("",$new_msg)); - } - } - } -} - -# manchester method -############################# package main -sub SIGNALduino_GROTHE() { - my ($name,$bitData,$id,$mcbitnum) = @_; - #my $debug = AttrVal($name,"debug",0); - my $bitLength; - $bitData = substr($bitData, 0, $mcbitnum); - my $preamble = "01000111"; - my $pos = index($bitData, $preamble); - my $hash=$defs{$name}; - - if ($pos < 0 || $pos > 5) { - $hash->{logMethod}->( $name, 3, "$name: GROTHE, protocol id $id, start pattern ($preamble) not found"); - return (-1,"Start pattern ($preamble) not found"); - } else { - if ($pos == 1) { # eine Null am Anfang zuviel - $bitData =~ s/^0//; # eine Null am Anfang entfernen - } - $bitLength = length($bitData); - my ($rcode, $rtxt) = SIGNALduino_TestLength($name, $id, $bitLength, "GROTHE ID=$id"); - if (!$rcode) { - $hash->{logMethod}->( $name, 3, "$name: GROTHE, protocol id $id, $rtxt"); - return (-1,"$rtxt"); - } - } - my $hex=SIGNALduino_b2h($bitData); - $hash->{logMethod}->( $name, 4, "$name: GROTHE, protocol id $id detected, $bitData ($bitLength)"); - return (1,$hex); ## Return the bits unchanged in hex -} - -############################# package main -sub SIGNALduino_MCTFA { - my ($name,$bitData,$id,$mcbitnum) = @_; - - my $preamble_pos; - my $message_end; - my $message_length; - - #if ($bitData =~ m/^.?(1){16,24}0101/) { - if ($bitData =~ m/(1{9}101)/ ) - { - my $hash=$defs{$name}; - $preamble_pos=$+[1]; - $hash->{logMethod}->($name, 4, "$name: MCTFA, 30.3208.0 preamble_pos = $preamble_pos"); - return return (-1," sync not found") if ($preamble_pos <=0); - my @messages; - - my $i=1; - my $retmsg = ""; - do - { - $message_end = index($bitData,"1111111111101",$preamble_pos); - if ($message_end < $preamble_pos) - { - $message_end=$mcbitnum; # length($bitData); - } - $message_length = ($message_end - $preamble_pos); - - my $part_str=substr($bitData,$preamble_pos,$message_length); - #$part_str = substr($part_str,0,52) if (length($part_str)) > 52; - - $hash->{logMethod}->($name, 4, "$name: MCTFA, message start($i)=$preamble_pos end=$message_end with length=$message_length"); - $hash->{logMethod}->($name, 5, "$name: MCTFA, message part($i)=$part_str"); - - my ($rcode, $rtxt) = SIGNALduino_TestLength($name, $id, $message_length, "TFA message part($i)"); - if ($rcode) { - my $hex=SIGNALduino_b2h($part_str); - push (@messages,$hex); - $hash->{logMethod}->($name, 4, "$name: MCTFA, message part($i)=$hex"); - } - else { - $retmsg = ", " . $rtxt; - } - - $preamble_pos=index($bitData,"1101",$message_end)+4; - $i++; - } while ($message_end < $mcbitnum); - - my %seen; - my @dupmessages = map { 1==$seen{$_}++ ? $_ : () } @messages; - - return ($i,"loop error, please report this data $bitData") if ($i==10); - if (scalar(@dupmessages) > 0 ) { - $hash->{logMethod}->($name, 4, "$name: MCTFA, repeated hex ".$dupmessages[0]." found ".$seen{$dupmessages[0]}." times"); - return (1,$dupmessages[0]); - } else { - return (-1," no duplicate found$retmsg"); - } - } - return (-1,undef); -} - -############################# package main -sub SIGNALduino_OSV2 { - my ($name,$bitData,$id,$mcbitnum) = @_; - - my $preamble_pos; - my $message_end; - my $message_length; - my $msg_start; - my $hash=$defs{$name}; - - #$bitData =~ tr/10/01/; - if ($bitData =~ m/^.?(01){12,17}.?10011001/) - { - # Valid OSV2 detected! - #$preamble_pos=index($bitData,"10011001",24); - $preamble_pos=$+[1]; - - $hash->{logMethod}->($name, 4, "$name: OSV2, protocol detected: preamble_pos = $preamble_pos"); - return return (-1," sync not found") if ($preamble_pos <24); - - $message_end=$-[1] if ($bitData =~ m/^.{44,}(01){16,17}.?10011001/); #Todo regex .{44,} 44 should be calculated from $preamble_pos+ min message lengh (44) - if (!defined($message_end) || $message_end < $preamble_pos) { - $message_end = length($bitData); - } else { - $message_end += 16; - $hash->{logMethod}->($name, 4, "$name: OSV2, message end pattern found at pos $message_end lengthBitData=".length($bitData)); - } - $message_length = ($message_end - $preamble_pos)/2; - - return (-1," message is to short") if (defined($ProtocolListSIGNALduino{$id}{length_min}) && $message_length < $ProtocolListSIGNALduino{$id}{length_min} ); - return (-1," message is to long") if (defined($ProtocolListSIGNALduino{$id}{length_max}) && $message_length > $ProtocolListSIGNALduino{$id}{length_max} ); - - my $idx=0; - my $osv2bits=""; - my $osv2hex =""; - - for ($idx=$preamble_pos;$idx<$message_end;$idx=$idx+16) - { - if ($message_end-$idx < 8 ) - { - last; - } - my $osv2byte = ""; - $osv2byte=NULL; - $osv2byte=substr($bitData,$idx,16); - - my $rvosv2byte=""; - - for (my $p=0;$p{logMethod}->($name, 4, "$name: OSV2, protocol converted to hex: ($osv2hex) with length (".(length($osv2hex)*4).") bits"); - #$found=1; - #$dmsg=$osv2hex; - return (1,$osv2hex); - } - elsif ($bitData =~ m/1{12,24}(0101)/g) { # min Preamble 12 x 1, Valid OSV3 detected! - $preamble_pos = $-[1]; - $msg_start = $preamble_pos + 4; - if ($bitData =~ m/\G.+?(1{24})0101/) { # preamble + sync der zweiten Nachricht - $message_end = $-[1]; - $hash->{logMethod}->($name, 4, "$name: OSV2, protocol OSV3 with two messages detected: length of second message = " . ($mcbitnum - $message_end - 28)); - } - else { # es wurde keine zweite Nachricht gefunden - $message_end = $mcbitnum; - } - $message_length = $message_end - $msg_start; - #SIGNALduino_Log3 $name, 4, "$name: OSV3: bitdata=$bitData"; - $hash->{logMethod}->($name, 4, "$name: OSV2, protocol OSV3 detected: msg_start = $msg_start, message_length = $message_length"); - return (-1," message with length ($message_length) is to short") if (defined($ProtocolListSIGNALduino{$id}{length_min}) && $message_length < $ProtocolListSIGNALduino{$id}{length_min} ); - - my $idx=0; - #my $osv3bits=""; - my $osv3hex =""; - - for ($idx=$msg_start; $idx<$message_end; $idx=$idx+4) - { - if (length($bitData)-$idx < 4 ) - { - last; - } - my $osv3nibble = ""; - $osv3nibble=NULL; - $osv3nibble=substr($bitData,$idx,4); - - my $rvosv3nibble=""; - - for (my $p=0;$p{logMethod}->($name, 4, "$name: OSV2, protocol OSV3 = $osv3hex"); - my $korr = 10; - # Check if nibble 1 is A - if (substr($osv3hex,1,1) ne 'A') - { - my $n1=substr($osv3hex,1,1); - $korr = hex(substr($osv3hex,3,1)); - substr($osv3hex,1,1,'A'); # nibble 1 = A - substr($osv3hex,3,1,$n1); # nibble 3 = nibble1 - } - # Korrektur nibble - my $insKorr = sprintf('%X', $korr); - # Check for ending 00 - if (substr($osv3hex,-2,2) eq '00') - { - #substr($osv3hex,1,-2); # remove 00 at end - $osv3hex = substr($osv3hex, 0, length($osv3hex)-2); - } - my $osv3len = length($osv3hex); - $osv3hex .= '0'; - my $turn0 = substr($osv3hex,5, $osv3len-4); - my $turn = ''; - for ($idx=0; $idx<$osv3len-5; $idx=$idx+2) { - $turn = $turn . substr($turn0,$idx+1,1) . substr($turn0,$idx,1); - } - $osv3hex = substr($osv3hex,0,5) . $insKorr . $turn; - $osv3hex = substr($osv3hex,0,$osv3len+1); - $osv3hex = sprintf("%02X", length($osv3hex)*4).$osv3hex; - $hash->{logMethod}->($name, 4, "$name: OSV2, protocol OSV3 converted to hex: ($osv3hex) with length (".((length($osv3hex)-2)*4).") bits"); - #$found=1; - #$dmsg=$osv2hex; - return (1,$osv3hex); - - } - return (-1,undef); -} - -############################# package main -sub SIGNALduino_OSV1() { - my ($name,$bitData,$id,$mcbitnum) = @_; - return (-1," message is to short") if (defined($ProtocolListSIGNALduino{$id}{length_min}) && $mcbitnum < $ProtocolListSIGNALduino{$id}{length_min} ); - return (-1," message is to long") if (defined($ProtocolListSIGNALduino{$id}{length_max}) && $mcbitnum > $ProtocolListSIGNALduino{$id}{length_max} ); - - if (substr($bitData,20,1) != 0) { - $bitData =~ tr/01/10/; # invert message and check if it is possible to deocde now - } - my $hash=$defs{$name}; - my $calcsum = oct( "0b" . reverse substr($bitData,0,8)); - $calcsum += oct( "0b" . reverse substr($bitData,8,8)); - $calcsum += oct( "0b" . reverse substr($bitData,16,8)); - $calcsum = ($calcsum & 0xFF) + ($calcsum >> 8); - my $checksum = oct( "0b" . reverse substr($bitData,24,8)); - - if ($calcsum != $checksum) { # Checksum - return (-1,"OSV1 - ERROR checksum not equal: $calcsum != $checksum"); - } - - $hash->{logMethod}->($name, 4, "$name: OSV1, input data: $bitData"); - my $newBitData = "00001010"; # Byte 0: Id1 = 0x0A - $newBitData .= "01001101"; # Byte 1: Id2 = 0x4D - my $channel = substr($bitData,6,2); # Byte 2 h: Channel - if ($channel eq "00") { # in 0 LSB first - $newBitData .= "0001"; # out 1 MSB first - } elsif ($channel eq "10") { # in 4 LSB first - $newBitData .= "0010"; # out 2 MSB first - } elsif ($channel eq "01") { # in 4 LSB first - $newBitData .= "0011"; # out 3 MSB first - } else { # in 8 LSB first - return (-1,"$name: OSV1 - ERROR channel not valid: $channel"); } - $newBitData .= "0000"; # Byte 2 l: ???? - $newBitData .= "0000"; # Byte 3 h: address - $newBitData .= reverse substr($bitData,0,4); # Byte 3 l: address (Rolling Code) - $newBitData .= reverse substr($bitData,8,4); # Byte 4 h: T 0,1 - $newBitData .= "0" . substr($bitData,23,1) . "00"; # Byte 4 l: Bit 2 - Batterie 0=ok, 1=low (< 2,5 Volt) - $newBitData .= reverse substr($bitData,16,4); # Byte 5 h: T 10 - $newBitData .= reverse substr($bitData,12,4); # Byte 5 l: T 1 - $newBitData .= "0000"; # Byte 6 h: immer 0000 - $newBitData .= substr($bitData,21,1) . "000"; # Byte 6 l: Bit 3 - Temperatur 0=pos | 1=neg, Rest 0 - $newBitData .= "00000000"; # Byte 7: immer 0000 0000 - # calculate new checksum over first 16 nibbles - $checksum = 0; - for (my $i = 0; $i < 64; $i = $i + 4) { - $checksum += oct( "0b" . substr($newBitData, $i, 4)); + #my $subname = @{[eval {&$method}, $@ =~ /.*/]}; + $hash->{logMethod}->($hash, 5, "$name: callsub, applying $funcname, value before: @args"); # method $subname" + + my ($rcode, @returnvalues) = $method->($obj,$name, @args) ; + + if (@returnvalues && defined($returnvalues[0])) { + $hash->{logMethod}->($name, 5, "$name: callsub, rcode=$rcode, modified value after $funcname: @returnvalues"); + } else { + $hash->{logMethod}->($name, 5, "$name: callsub, rcode=$rcode, after calling $funcname"); } - $checksum = ($checksum - 0xa) & 0xff; - $newBitData .= sprintf("%08b",$checksum); # Byte 8: new Checksum - $newBitData .= "00000000"; # Byte 9: immer 0000 0000 - my $osv1hex = "50" . SIGNALduino_b2h($newBitData); # output with length before - $hash->{logMethod}->($name, 4, "$name: OSV1, protocol id $id translated to RFXSensor format"); - $hash->{logMethod}->($name, 4, "$name: OSV1, converted to hex: $osv1hex"); - return (1,$osv1hex); + return ($rcode, @returnvalues); + } elsif (defined $method ) { + $hash->{logMethod}->($name, 5, "$name: callsub, Error: Unknown method $funcname pease report at github"); + return (0,undef); + } + return (1,@args); } -############################# package main -sub SIGNALduino_AS() { - my ($name,$bitData,$id,$mcbitnum) = @_; - my $debug = AttrVal($name,"debug",0); - - if(index($bitData,"1100",16) >= 0) # $rawData =~ m/^A{2,3}/) - { # Valid AS detected! - my $message_start = index($bitData,"1100",16); - Debug "$name: AS protocol detected \n" if ($debug); - - my $message_end=index($bitData,"1100",$message_start+16); - $message_end = length($bitData) if ($message_end == -1); - my $message_length = $message_end - $message_start; - - return (-1," message is to short") if (defined($ProtocolListSIGNALduino{$id}{length_min}) && $message_length < $ProtocolListSIGNALduino{$id}{length_min} ); - return (-1," message is to long") if (defined($ProtocolListSIGNALduino{$id}{length_max}) && $message_length > $ProtocolListSIGNALduino{$id}{length_max} ); - - - my $msgbits =substr($bitData,$message_start); - - my $ashex=sprintf('%02X', oct("0b$msgbits")); - my $hash=$defs{$name}; - $hash->{logMethod}->($name, 5, "$name: AS, protocol converted to hex: ($ashex) with length ($message_length) bits \n"); - - return (1,$bitData); - } - return (-1,undef); -} - -############################# package main -sub SIGNALduino_Hideki() { - my ($name,$bitData,$id,$mcbitnum) = @_; - my $debug = AttrVal($name,"debug",0); - - Debug "$name: search in $bitData \n" if ($debug); - my $message_start = index($bitData,"10101110"); - my $invert = 0; - - if ($message_start < 0) { - $bitData =~ tr/01/10/; # invert message - $message_start = index($bitData,"10101110"); # 0x75 but in reverse order - $invert = 1; - } - - my $hash=$defs{$name}; - if ($message_start >= 0 ) # 0x75 but in reverse order - { - Debug "$name: Hideki protocol (invert=$invert) detected \n" if ($debug); - - # Todo: Mindest Laenge fuer startpunkt vorspringen - # Todo: Wiederholung auch an das Modul weitergeben, damit es dort geprueft werden kann - my $message_end = index($bitData,"10101110",$message_start+71); # pruefen auf ein zweites 0x75, mindestens 72 bit nach 1. 0x75, da der Regensensor minimum 8 Byte besitzt je byte haben wir 9 bit - $message_end = length($bitData) if ($message_end == -1); - my $message_length = $message_end - $message_start; - - return (-1,"message is to short") if (defined($ProtocolListSIGNALduino{$id}{length_min}) && $message_length < $ProtocolListSIGNALduino{$id}{length_min} ); - return (-1,"message is to long") if (defined($ProtocolListSIGNALduino{$id}{length_max}) && $message_length > $ProtocolListSIGNALduino{$id}{length_max} ); - - - my $hidekihex = ""; - my $idx; - - for ($idx=$message_start; $idx<$message_end; $idx=$idx+9) - { - my $byte = ""; - $byte= substr($bitData,$idx,8); ## Ignore every 9th bit - Debug "$name: byte in order $byte " if ($debug); - $byte = scalar reverse $byte; - Debug "$name: byte reversed $byte , as hex: ".sprintf('%X', oct("0b$byte"))."\n" if ($debug); - - $hidekihex=$hidekihex.sprintf('%02X', oct("0b$byte")); - } - - if ($invert == 0) { - $hash->{logMethod}->($name, 4, "$name: Hideki, receive protocol not inverted"); - } else { - $hash->{logMethod}->($name, 4, "$name: Hideki, receive protocol inverted"); - } - $hash->{logMethod}->($name, 4, "$name: Hideki, protocol converted to hex: $hidekihex with " .$message_length ." bits, messagestart $message_start"); - - return (1,$hidekihex); ## Return only the original bits, include length - } - $hash->{logMethod}->($name, 4, "$name: Hideki, start pattern (10101110) not found"); - return (-1,"Start pattern (10101110) not found"); -} - -############################# package main -sub SIGNALduino_Maverick() { - my ($name,$bitData,$id,$mcbitnum) = @_; - my $debug = AttrVal($name,"debug",0); - - - if ($bitData =~ m/^.*(101010101001100110010101).*/) - { # Valid Maverick header detected - my $header_pos=$+[1]; - my $hash=$defs{$name}; - - $hash->{logMethod}->($name, 4, "$name: Maverick, protocol detected: header_pos = $header_pos"); - - my $hex=SIGNALduino_b2h(substr($bitData,$header_pos,26*4)); - - return (1,$hex); ## Return the bits unchanged in hex - } else { - return return (-1," header not found"); - } -} - -############################# package main -sub SIGNALduino_OSPIR() { - my ($name,$bitData,$id,$mcbitnum) = @_; - my $debug = AttrVal($name,"debug",0); - - - if ($bitData =~ m/^.*(1{14}|0{14}).*/) - { # Valid Oregon PIR detected - my $header_pos=$+[1]; - my $hash=$defs{$name}; - $hash->{logMethod}->($name, 4, "$name: OSPIR, protocol detected: header_pos = $header_pos"); - - my $hex=SIGNALduino_b2h($bitData); - - return (1,$hex); ## Return the bits unchanged in hex - } else { - return return (-1," header not found"); - } -} - -############################# package main -sub SIGNALduino_SomfyRTS() { - my ($name, $bitData,$id,$mcbitnum) = @_; - - #(my $negBits = $bitData) =~ tr/10/01/; # Todo: eventuell auf pack umstellen - - if (defined($mcbitnum)) { - my $hash=$defs{$name}; - $hash->{logMethod}->($name, 4, "$name: SomfyRTS, bitdata: $bitData ($mcbitnum)"); - if ($mcbitnum == 57) { - $bitData = substr($bitData, 1, 56); - $hash->{logMethod}->($name, 4, "$name: SomfyRTS, bitdata: _$bitData (" . length($bitData) . "). Bit am Anfang entfernt"); - } - } - my $encData = SIGNALduino_b2h($bitData); - - #SIGNALduino_Log3 $name, 4, "$name: SomfyRTS, protocol enc: $encData"; - return (1, $encData); -} - -############################# package main -sub SIGNALduino_TestLength { - my ($name, $id, $message_length, $logMsg) = @_; - my $hash = undef; - $hash = $defs{$name} if (defined($name) && exists($defs{$name})); - if (defined($ProtocolListSIGNALduino{$id}{length_min}) && $message_length < $ProtocolListSIGNALduino{$id}{length_min}) { - $hash->{logMethod}->($name, 4, "$name: $logMsg: message with length=$message_length is to short") if (defined($logMsg)); - return (0, "message is to short"); - } - elsif (defined($ProtocolListSIGNALduino{$id}{length_max}) && $message_length > $ProtocolListSIGNALduino{$id}{length_max}) { - $hash->{logMethod}->($name, 4, "$name: $logMsg: message with length=$message_length is to long") if (defined($logMsg)); - return (0, "message is to long"); - } - return (1,""); -} # - - - - - - - - - - - - @@ -4202,65 +3531,64 @@ sub SIGNALduino_TestLength { # =cut ############################# package main sub SIGNALduino_filterMC($$$%) { + ## Warema Implementierung : Todo variabel gestalten + my ($name,$id,$rawData,%patternListRaw) = @_; + my $hash=$defs{$name}; + my $debug = AttrVal($name,'debug',0); - ## Warema Implementierung : Todo variabel gestalten - my ($name,$id,$rawData,%patternListRaw) = @_; - my $debug = AttrVal($name,"debug",0); + my ($ht, $hasbit, $value) = 0; + $value=1 if (!$debug); + my @bitData; + my @sigData = split '',$rawData; + my $clockabs; - my ($ht, $hasbit, $value) = 0; - $value=1 if (!$debug); - my @bitData; - my @sigData = split "",$rawData; + foreach my $pulse (@sigData) + { + next if (!defined($patternListRaw{$pulse})); + #SIGNALduino_Log3 $name, 4, "$name: pulese: ".$patternListRaw{$pulse}; + $clockabs = $hash->{protocolObject}->getProperty($id,'clockabs'); - foreach my $pulse (@sigData) - { - next if (!defined($patternListRaw{$pulse})); - #SIGNALduino_Log3 $name, 4, "$name: pulese: ".$patternListRaw{$pulse}; + if (SIGNALduino_inTol($clockabs,abs($patternListRaw{$pulse}),$clockabs*0.5)) + { + # Short + $hasbit=$ht; + $ht = $ht ^ 0b00000001; + $value='S' if($debug); + #SIGNALduino_Log3 $name, 4, "$name: filter S "; + } elsif ( SIGNALduino_inTol($clockabs*2,abs($patternListRaw{$pulse}),$clockabs*0.5)) { + # Long + $hasbit=1; + $ht=1; + $value='L' if($debug); + #SIGNALduino_Log3 $name, 4, "$name: filter L "; + } elsif ( SIGNALduino_inTol($hash->{protocolObject}->getProperty($id,'syncabs')+(2*$clockabs),abs($patternListRaw{$pulse}),$clockabs*0.5)) { + $hasbit=1; + $ht=1; + $value='L' if($debug); + #SIGNALduino_Log3 $name, 4, "$name: sync L "; + } else { + # No Manchester Data + $ht=0; + $hasbit=0; + #SIGNALduino_Log3 $name, 4, "$name: filter n "; + } - if (SIGNALduino_inTol($ProtocolListSIGNALduino{$id}{clockabs},abs($patternListRaw{$pulse}),$ProtocolListSIGNALduino{$id}{clockabs}*0.5)) - { - # Short - $hasbit=$ht; - $ht = $ht ^ 0b00000001; - $value='S' if($debug); - #SIGNALduino_Log3 $name, 4, "$name: filter S "; - } elsif ( SIGNALduino_inTol($ProtocolListSIGNALduino{$id}{clockabs}*2,abs($patternListRaw{$pulse}),$ProtocolListSIGNALduino{$id}{clockabs}*0.5)) { - # Long - $hasbit=1; - $ht=1; - $value='L' if($debug); - #SIGNALduino_Log3 $name, 4, "$name: filter L "; - } elsif ( SIGNALduino_inTol($ProtocolListSIGNALduino{$id}{syncabs}+(2*$ProtocolListSIGNALduino{$id}{clockabs}),abs($patternListRaw{$pulse}),$ProtocolListSIGNALduino{$id}{clockabs}*0.5)) { - $hasbit=1; - $ht=1; - $value='L' if($debug); - #SIGNALduino_Log3 $name, 4, "$name: sync L "; + if ($hasbit && $value) { + $value = lc($value) if($debug && $patternListRaw{$pulse} < 0); + my $bit=$patternListRaw{$pulse} > 0 ? 1 : 0; + #SIGNALduino_Log3 $name, 5, "$name: adding value: ".$bit; - } else { - # No Manchester Data - $ht=0; - $hasbit=0; - #SIGNALduino_Log3 $name, 4, "$name: filter n "; - } + push @bitData, $bit ; + } + } - if ($hasbit && $value) { - $value = lc($value) if($debug && $patternListRaw{$pulse} < 0); - my $bit=$patternListRaw{$pulse} > 0 ? 1 : 0; - #SIGNALduino_Log3 $name, 5, "$name: adding value: ".$bit; - - push @bitData, $bit ; - } - } - - my %patternListRawFilter; - - $patternListRawFilter{0} = 0; - $patternListRawFilter{1} = $ProtocolListSIGNALduino{$id}{clockabs}; - - #SIGNALduino_Log3 $name, 5, "$name: filterbits: ".@bitData; - $rawData = join "", @bitData; - return (undef ,$rawData, %patternListRawFilter); + my %patternListRawFilter; + $patternListRawFilter{0} = 0; + $patternListRawFilter{1} = $clockabs; + #SIGNALduino_Log3 $name, 5, "$name: filterbits: ".@bitData; + $rawData = join '', @bitData; + return (undef ,$rawData, %patternListRawFilter); } @@ -4272,65 +3600,64 @@ sub SIGNALduino_filterMC($$$%) { # =cut ############################# package main sub SIGNALduino_filterSign($$$%) { - my ($name,$id,$rawData,%patternListRaw) = @_; - my $debug = AttrVal($name,"debug",0); + my ($name,$id,$rawData,%patternListRaw) = @_; + my $debug = AttrVal($name,'debug',0); + my %buckets; + # Remove Sign + %patternListRaw = map { $_ => abs($patternListRaw{$_})} keys %patternListRaw; ## remove sign from all - my %buckets; - # Remove Sign - %patternListRaw = map { $_ => abs($patternListRaw{$_})} keys %patternListRaw; ## remove sign from all + my $intol=0; + my $cnt=0; - my $intol=0; - my $cnt=0; + # compress pattern hash + foreach my $key (keys %patternListRaw) { - # compress pattern hash - foreach my $key (keys %patternListRaw) { + #print 'chk:'.$patternListRaw{$key}; + #print "\n"; - #print "chk:".$patternListRaw{$key}; - #print "\n"; + $intol=0; + foreach my $b_key (keys %buckets){ + #print 'with:'.$buckets{$b_key}; + #print "\n"; - $intol=0; - foreach my $b_key (keys %buckets){ - #print "with:".$buckets{$b_key}; - #print "\n"; + # $value - $set <= $tolerance + if (SIGNALduino_inTol($patternListRaw{$key},$buckets{$b_key},$buckets{$b_key}*0.25)) + { + #print"\t". $patternListRaw{$key}."($key) is intol of ".$buckets{$b_key}."($b_key) \n"; + $cnt++; + eval "\$rawData =~ tr/$key/$b_key/"; - # $value - $set <= $tolerance - if (SIGNALduino_inTol($patternListRaw{$key},$buckets{$b_key},$buckets{$b_key}*0.25)) - { - #print"\t". $patternListRaw{$key}."($key) is intol of ".$buckets{$b_key}."($b_key) \n"; - $cnt++; - eval "\$rawData =~ tr/$key/$b_key/"; + #if ($key == $msg_parts{clockidx}) + #{ + # $msg_pats{syncidx} = $buckets{$key}; + # } + # elsif ($key == $msg_parts{syncidx}) + # { + # $msg_pats{syncidx} = $buckets{$key}; + # } - #if ($key == $msg_parts{clockidx}) - #{ - # $msg_pats{syncidx} = $buckets{$key}; - # } - # elsif ($key == $msg_parts{syncidx}) - # { - # $msg_pats{syncidx} = $buckets{$key}; - # } + $buckets{$b_key} = ($buckets{$b_key} + $patternListRaw{$key}) /2; + #print"\t recalc to ". $buckets{$b_key}."\n"; - $buckets{$b_key} = ($buckets{$b_key} + $patternListRaw{$key}) /2; - #print"\t recalc to ". $buckets{$b_key}."\n"; + delete ($patternListRaw{$key}); # deletes the compressed entry + $intol=1; + last; + } + } + if ($intol == 0) { + $buckets{$key}=abs($patternListRaw{$key}); + } + } - delete ($patternListRaw{$key}); # deletes the compressed entry - $intol=1; - last; - } - } - if ($intol == 0) { - $buckets{$key}=abs($patternListRaw{$key}); - } - } + return ($cnt,$rawData, %patternListRaw); + #print 'rdata: '.$msg_parts{rawData}."\n"; - return ($cnt,$rawData, %patternListRaw); - #print "rdata: ".$msg_parts{rawData}."\n"; + #print Dumper (%buckets); + #print Dumper (%msg_parts); - #print Dumper (%buckets); - #print Dumper (%msg_parts); - - #modify msg_parts pattern hash - #$patternListRaw = \%buckets; + #modify msg_parts pattern hash + #$patternListRaw = \%buckets; } @@ -4342,305 +3669,371 @@ sub SIGNALduino_filterSign($$$%) { # =cut ############################# package main sub SIGNALduino_compPattern($$$%) { - my ($name,$id,$rawData,%patternListRaw) = @_; - my $debug = AttrVal($name,"debug",0); + my ($name,$id,$rawData,%patternListRaw) = @_; + my $debug = AttrVal($name,'debug',0); + my %buckets; + # Remove Sign + #%patternListRaw = map { $_ => abs($patternListRaw{$_})} keys %patternListRaw; ## remove sing from all - my %buckets; - # Remove Sign - #%patternListRaw = map { $_ => abs($patternListRaw{$_})} keys %patternListRaw; ## remove sing from all + my $intol=0; + my $cnt=0; - my $intol=0; - my $cnt=0; + # compress pattern hash + foreach my $key (keys %patternListRaw) { - # compress pattern hash - foreach my $key (keys %patternListRaw) { + #print 'chk:'.$patternListRaw{$key}; + #print "\n"; - #print "chk:".$patternListRaw{$key}; - #print "\n"; + $intol=0; + foreach my $b_key (keys %buckets){ + #print 'with:'.$buckets{$b_key}; + #print "\n"; - $intol=0; - foreach my $b_key (keys %buckets){ - #print "with:".$buckets{$b_key}; - #print "\n"; + # $value - $set <= $tolerance + if (SIGNALduino_inTol($patternListRaw{$key},$buckets{$b_key},$buckets{$b_key}*0.4)) + { + #print"\t". $patternListRaw{$key}."($key) is intol of ".$buckets{$b_key}."($b_key) \n"; + $cnt++; + eval "\$rawData =~ tr/$key/$b_key/"; - # $value - $set <= $tolerance - if (SIGNALduino_inTol($patternListRaw{$key},$buckets{$b_key},$buckets{$b_key}*0.4)) - { - #print"\t". $patternListRaw{$key}."($key) is intol of ".$buckets{$b_key}."($b_key) \n"; - $cnt++; - eval "\$rawData =~ tr/$key/$b_key/"; + #if ($key == $msg_parts{clockidx}) + #{ + # $msg_pats{syncidx} = $buckets{$key}; + # } + # elsif ($key == $msg_parts{syncidx}) + # { + # $msg_pats{syncidx} = $buckets{$key}; + # } - #if ($key == $msg_parts{clockidx}) - #{ - # $msg_pats{syncidx} = $buckets{$key}; - # } - # elsif ($key == $msg_parts{syncidx}) - # { - # $msg_pats{syncidx} = $buckets{$key}; - # } + $buckets{$b_key} = ($buckets{$b_key} + $patternListRaw{$key}) /2; + #print"\t recalc to ". $buckets{$b_key}."\n"; - $buckets{$b_key} = ($buckets{$b_key} + $patternListRaw{$key}) /2; - #print"\t recalc to ". $buckets{$b_key}."\n"; + delete ($patternListRaw{$key}); # deletes the compressed entry + $intol=1; + last; + } + } + if ($intol == 0) { + $buckets{$key}=$patternListRaw{$key}; + } + } - delete ($patternListRaw{$key}); # deletes the compressed entry - $intol=1; - last; - } - } - if ($intol == 0) { - $buckets{$key}=$patternListRaw{$key}; - } - } + return ($cnt,$rawData, %patternListRaw); + #print 'rdata: '.$msg_parts{rawData}."\n"; - return ($cnt,$rawData, %patternListRaw); - #print "rdata: ".$msg_parts{rawData}."\n"; + #print Dumper (%buckets); + #print Dumper (%msg_parts); - #print Dumper (%buckets); - #print Dumper (%msg_parts); - - #modify msg_parts pattern hash - #$patternListRaw = \%buckets; + #modify msg_parts pattern hash + #$patternListRaw = \%buckets; } ############################# package main # the new Log with integrated loglevel checking -sub SIGNALduino_Log3($$$) { - +sub SIGNALduino_Log3 { my ($dev, $loglevel, $text) = @_; my $name =$dev; $name= $dev->{NAME} if(defined($dev) && ref($dev) eq "HASH"); - DoTrigger($dev,"$name $loglevel: $text"); + my $textEventlogging = $text; + ### DoTrigger for eventlogging event + #DoTrigger($dev,"$name $loglevel: $text"); + #2020-07-14_12:47:01 sduino_USB_SB_Test sduino_USB_SB_Test 4: sduino_USB_SB_Test: HandleWriteQueue, called + + #DoTrigger($dev,"$loglevel: $text"); + #2020-07-14_12:47:01 sduino_USB_SB_Test 4: sduino_USB_SB_Test: HandleWriteQueue, called + + ### $text may not be changed for return value + if ($textEventlogging =~ /^$dev:\s/) { + my $textCut = length($dev)+2; # length receivername and ': " + $textEventlogging = substr($textEventlogging,$textCut); # cut $textCut from $textEventlogging + } + + ### DoTrigger for eventlogging event with adapted structure + DoTrigger($dev,"$loglevel: $textEventlogging"); + #2020-07-16_12:40:07 sduino_USB_SB_Test 4: HandleWriteQueue, called + + ### return for normal logfile | unchangeable + #2020.07.16 11:35:40.676 4: sduino_USB_SB_Test: HandleWriteQueue, called return Log3($name,$loglevel,$text); } ############################# package main # Helper to get a reference of the protocolList Hash +# ?? ToDo - wird diese Sub noch beoetigt ??? sub SIGNALduino_getProtocolList() { - return \%ProtocolListSIGNALduino + #return \%ProtocolListSIGNALduino } +############################# package main +# Helper to create a individual callback per definition which can receive log output from perl modules +sub SIGNALduino_createLogCallback { + my $hash = shift // return ; + (ref $hash ne 'HASH') // return ; + + return sub { + my $message = shift // carp 'message must be provided'; + my $level = shift // 0; + + $hash->{logMethod}->($hash->{NAME}, $level,qq[$hash->{NAME}: $message]); + }; +}; + + ############################# package main sub SIGNALduino_FW_getProtocolList { - my $name = shift; + my $name = shift; - my $hash = $defs{$name}; - my $ret; - my $devText = ""; - my $blackTxt = ""; - my %BlacklistIDs; - my @IdList = (); - my $comment; + my $hash = $defs{$name}; + my $ret; + my $devText = ''; + my $blackTxt = ''; + my %BlacklistIDs; + my @IdList = (); + my $comment; + my $knownFreqs; - my $blacklist = AttrVal($name,"blacklist_IDs",""); - if (length($blacklist) > 0) { # Blacklist in Hash wandeln - #SIGNALduino_Log3 $name, 5, "$name getProtocolList: attr blacklistIds=$blacklist"; - %BlacklistIDs = map { $_ => 1 } split(",", $blacklist);; - } + my $blacklist = AttrVal($name,'blacklist_IDs',''); + if (length($blacklist) > 0) { # Blacklist in Hash wandeln + #SIGNALduino_Log3 $name, 5, "$name getProtocolList: attr blacklistIds=$blacklist"; + %BlacklistIDs = map { $_ => 1 } split(',', $blacklist);; + } - my $whitelist = AttrVal($name,"whitelist_IDs","#"); - if (AttrVal($name,"blacklist_IDs","") ne "") { # wenn es eine blacklist gibt, dann "." an die Ueberschrift anhaengen - $blackTxt = "."; - } + my $whitelist = AttrVal($name,'whitelist_IDs','#'); + if (AttrVal($name,'blacklist_IDs','') ne '') { # wenn es eine blacklist gibt, dann '.' an die Ueberschrift anhaengen + $blackTxt = '.'; + } - my ($develop,$devFlag) = SIGNALduino_getAttrDevelopment($name); # $devFlag = 1 -> alle developIDs y aktivieren - $devText = "development version - " if ($devFlag == 1); + my ($develop,$devFlag) = SIGNALduino_getAttrDevelopment($name); # $devFlag = 1 -> alle developIDs y aktivieren + $devText = 'development version - ' if ($devFlag == 1); - my %activeIdHash; - @activeIdHash{@{$hash->{msIdList}}, @{$hash->{muIdList}}, @{$hash->{mcIdList}}} = (undef); - #SIGNALduino_Log3 $name,4, "$name IdList: $mIdList"; + my %activeIdHash; + @activeIdHash{@{$hash->{msIdList}}, @{$hash->{muIdList}}, @{$hash->{mcIdList}}, @{$hash->{mnIdList}}} = (undef); + #SIGNALduino_Log3 $name,4, "$name IdList: $mIdList"; - my %IDsNoDispatch; - if (defined($hash->{IDsNoDispatch})) { - %IDsNoDispatch = map { $_ => 1 } split(",", $hash->{IDsNoDispatch}); - #SIGNALduino_Log3 $name,4, "$name IdList IDsNoDispatch=" . join ', ' => map "$_" => keys %IDsNoDispatch; - } + my %IDsNoDispatch; + if (defined($hash->{IDsNoDispatch})) { + %IDsNoDispatch = map { $_ => 1 } split(',', $hash->{IDsNoDispatch}); + #SIGNALduino_Log3 $name,4, "$name IdList IDsNoDispatch=" . join ', ' => map "$_" => keys %IDsNoDispatch; + } - foreach my $id (keys %ProtocolListSIGNALduino) - { - push (@IdList, $id); - } - @IdList = sort { $a <=> $b } @IdList; + for my $id ($hash->{protocolObject}->getKeys()) + { + push (@IdList, $id); + } + @IdList = sort { $a <=> $b } @IdList; - $ret = "
"; - $ret .= "Last Flashlog<\/a>"; - $ret .= ""; + $ret .= "Last Flashlog<\/a>"; + $ret .= "
"; + $ret = "
"; - $ret .=""; - } - else { - $ret .="whitelist not active (save activate it)$blackTxt"; - } - $ret .= ""; - $ret .=""; - my $oddeven="odd"; - my $checked; - my $checkAll; + $ret .=""; + } + else { + $ret .="whitelist not active (save activate it)$blackTxt"; + } + $ret .= ""; + $ret .=""; + my $oddeven="odd"; + my $checked; + my $checkAll; - foreach my $id (@IdList) - { - my $msgtype = ""; - my $chkbox; + foreach my $id (@IdList) + { + my $msgtype = ''; + my $chkbox; - if (exists ($ProtocolListSIGNALduino{$id}{format}) && $ProtocolListSIGNALduino{$id}{format} eq "manchester") - { - $msgtype = "MC"; - } - elsif (exists $ProtocolListSIGNALduino{$id}{sync}) - { - $msgtype = "MS"; - } - elsif (exists ($ProtocolListSIGNALduino{$id}{clockabs})) - { - $msgtype = "MU"; - } + if (defined $hash->{protocolObject}->getProperty($id,'format') && $hash->{protocolObject}->getProperty($id,'format') eq 'manchester') + { + $msgtype = 'MC'; + } + elsif (defined $hash->{protocolObject}->getProperty($id,'modulation')) + { + $msgtype = 'MN'; + } + elsif (defined $hash->{protocolObject}->getProperty($id,'sync')) + { + $msgtype = 'MS'; + } + elsif (defined $hash->{protocolObject}->getProperty($id,'clockabs')) + { + $msgtype = 'MU'; + } - $checked=""; + $checked=''; - if (substr($whitelist,0,1) ne "#") { # whitelist aktiv, dann ermitteln welche ids bei select all nicht checked sein sollen - $checkAll = "SDcheck"; - if (exists($BlacklistIDs{$id})) { - $checkAll = "SDnotCheck"; - } - elsif (exists($ProtocolListSIGNALduino{$id}{developId})) { - if ($devFlag == 1 && $ProtocolListSIGNALduino{$id}{developId} eq "p") { - $checkAll = "SDnotCheck"; - } - elsif ($devFlag == 0 && $ProtocolListSIGNALduino{$id}{developId} eq "y" && $develop !~ m/y$id/) { - $checkAll = "SDnotCheck"; - } - elsif ($devFlag == 0 && $ProtocolListSIGNALduino{$id}{developId} eq "m") { - $checkAll = "SDnotCheck"; - } - } - } - else { - $checkAll = "SDnotCheck"; - } + if (substr($whitelist,0,1) ne '#') { # whitelist aktiv, dann ermitteln welche ids bei select all nicht checked sein sollen + $checkAll = 'SDcheck'; + if (exists($BlacklistIDs{$id})) { + $checkAll = 'SDnotCheck'; + } + elsif (defined $hash->{protocolObject}->getProperty($id,'developId')) { + if ($devFlag == 1 && $hash->{protocolObject}->getProperty($id,'developId') eq 'p') { + $checkAll = 'SDnotCheck'; + } + elsif ($devFlag == 0 && $hash->{protocolObject}->getProperty($id,'developId') eq 'y' && $develop !~ m/y$id/) { + $checkAll = 'SDnotCheck'; + } + elsif ($devFlag == 0 && $hash->{protocolObject}->getProperty($id,'developId') eq 'm') { + $checkAll = 'SDnotCheck'; + } + } + } + else { + $checkAll = 'SDnotCheck'; + } - if (exists($activeIdHash{$id})) - { - $checked="checked"; - if (substr($whitelist,0,1) eq "#") { # whitelist nicht aktiv, dann entspricht select all dem $activeIdHash - $checkAll = "SDcheck"; - } - } + if (exists($activeIdHash{$id})) + { + $checked='checked'; + if (substr($whitelist,0,1) eq '#') { # whitelist nicht aktiv, dann entspricht select all dem $activeIdHash + $checkAll = 'SDcheck'; + } + } - if ($devFlag == 0 && exists($ProtocolListSIGNALduino{$id}{developId}) && $ProtocolListSIGNALduino{$id}{developId} eq "p") { - $chkbox="
"; - } - else { - $chkbox=sprintf("", $checkAll, $id, $checked); - } + if ($devFlag == 0 && defined $hash->{protocolObject}->getProperty($id,'developId') && $hash->{protocolObject}->getProperty($id,'developId') eq 'p') { + $chkbox="
"; + } + else { + $chkbox=sprintf("", $checkAll, $id, $checked); + } - $comment = SIGNALduino_getProtoProp($id,"comment",""); - if (exists($IDsNoDispatch{$id})) { - $comment .= " (dispatch is only with a active whitelist possible)"; - } + $comment = $hash->{protocolObject}->checkProperty($id,'comment',''); + if (exists($IDsNoDispatch{$id})) { + $comment .= ' (dispatch is only with a active whitelist possible)'; + } - $ret .= sprintf("",$oddeven,$chkbox,SIGNALduino_getProtoProp($id,"developId",""),$id,$msgtype,SIGNALduino_getProtoProp($id,"clientmodule",""),SIGNALduino_getProtoProp($id,"name",""),$comment); - $oddeven= $oddeven eq "odd" ? "even" : "odd" ; + $knownFreqs = $hash->{protocolObject}->checkProperty($id,'knownFreqs',''); - $ret .= "\n"; - } - $ret .= "
$devText"; - if (substr($whitelist,0,1) ne "#") { - $ret .="whitelist active$blackTxt
act.devIDMsg Typemodulnameprotocolname # comment
$devText"; + if (substr($whitelist,0,1) ne '#') { + $ret .="whitelist active$blackTxt
act.devIDMsg Typemodulnameprotocolname # comment
%s
%s
%3s
%s
%s
%s
%s
"; - return $ret; + if ($msgtype eq 'MN') { # xFSK + $comment .= ' (Mod. ' . $hash->{protocolObject}->checkProperty($id,'modulation','') . ', DataRate=' . $hash->{protocolObject}->checkProperty($id,'datarate','') . ', Sync Word=' . $hash->{protocolObject}->checkProperty($id,'sync',''); + if (length($knownFreqs) > 2) { + $comment .= ', Freq. ' . $knownFreqs . 'MHz'; + } + $comment .= ')'; + } + + $ret .= sprintf("%s
%s
%3s
%s
%s
%s
%s
",$oddeven,$chkbox,$hash->{protocolObject}->checkProperty($id,'developId',''),$id,$msgtype,$hash->{protocolObject}->checkProperty($id,'clientmodule',''),$hash->{protocolObject}->checkProperty($id,'name',''),$comment); + $oddeven= $oddeven eq "odd" ? "even" : "odd" ; + + $ret .= "\n"; + } + $ret .= ""; + return $ret; } ############################# package main sub SIGNALduino_querygithubreleases { - my ($hash) = @_; - my $name = $hash->{NAME}; - my $param = { - url => "https://api.github.com/repos/RFD-FHEM/SIGNALDuino/releases", - timeout => 5, - hash => $hash, # Muss gesetzt werden, damit die Callback funktion wieder $hash hat - method => "GET", # Lesen von Inhalten - header => "User-Agent: perl_fhem\r\nAccept: application/json", # Den Header gemaess abzufragender Daten aendern - callback => \&SIGNALduino_githubParseHttpResponse, # Diese Funktion soll das Ergebnis dieser HTTP Anfrage bearbeiten - command => "queryReleases" + my ($hash) = @_; + my $name = $hash->{NAME}; + my $param = { + url => 'https://api.github.com/repos/RFD-FHEM/SIGNALDuino/releases', + timeout => 5, + hash => $hash, # Muss gesetzt werden, damit die Callback funktion wieder $hash hat + method => 'GET', # Lesen von Inhalten + header => "User-Agent: perl_fhem\r\nAccept: application/json", # Den Header gemaess abzufragender Daten aendern + callback => \&SIGNALduino_githubParseHttpResponse, # Diese Funktion soll das Ergebnis dieser HTTP Anfrage bearbeiten + command => "queryReleases" + }; - }; - HttpUtils_NonblockingGet($param); # Starten der HTTP Abfrage. Es gibt keinen Return-Code. + HttpUtils_NonblockingGet($param); # Starten der HTTP Abfrage. Es gibt keinen Return-Code. } ############################# package main #return -10 = hardeware attribute is not set -sub SIGNALduino_githubParseHttpResponse($$$) { - my ($param, $err, $data) = @_; - my $hash = $param->{hash}; - my $name = $hash->{NAME}; - my $hardware=AttrVal($name,"hardware",undef); +sub SIGNALduino_githubParseHttpResponse { + my ($param, $err, $data) = @_; + my $hash = $param->{hash}; + my $name = $hash->{NAME}; + my $hardware=AttrVal($name,'hardware',undef); + + if($err ne '') # wenn ein Fehler bei der HTTP Abfrage aufgetreten ist + { + Log3 $name, 3, "$name: githubParseHttpResponse, error while requesting ".$param->{url}." - $err (command: $param->{command}"; # Eintrag fuers Log + #readingsSingleUpdate($hash, 'fullResponse', 'ERROR'); # Readings erzeugen + } + elsif($data ne '' && defined($hardware)) # wenn die Abfrage erfolgreich war ($data enthaelt die Ergebnisdaten des HTTP Aufrufes) + { + my $json_array = decode_json($data); + #print Dumper($json_array); + if ($param->{command} eq 'queryReleases') { + #Log3 $name, 3, "$name: githubParseHttpResponse, url ".$param->{url}." returned: $data"; # Eintrag fuers Log + + my $releaselist=''; + if (ref($json_array) eq "ARRAY") { + foreach my $item( @$json_array ) { + next if (AttrVal($name,'updateChannelFW','stable') eq 'stable' && $item->{prerelease}); + + #Debug ' item = '.Dumper($item); + + foreach my $asset (@{$item->{assets}}) + { + next if ($asset->{name} !~ m/$hardware/i); + $releaselist.=$item->{tag_name}.',' ; + last; + } + } + } + + $releaselist =~ s/,$//; + $hash->{additionalSets}{flash} = $releaselist; + } elsif ($param->{command} eq 'getReleaseByTag' && defined($hardware)) { + #Debug ' json response = '.Dumper($json_array); + + my @fwfiles; + foreach my $asset (@{$json_array->{assets}}) + { + my %fileinfo; + if ( $asset->{name} =~ m/$hardware/i) + { + $fileinfo{filename} = $asset->{name}; + $fileinfo{dlurl} = $asset->{browser_download_url}; + $fileinfo{create_date} = $asset->{created_at}; + #Debug ' firmwarefiles = '.Dumper(@fwfiles); + push @fwfiles, \%fileinfo; + + my $set_return = SIGNALduino_Set($hash,$name,'flash',$asset->{browser_download_url}); # $hash->{SetFn + if(defined($set_return)) + { + $hash->{logMethod}->($name, 3, "$name: githubParseHttpResponse, Error while trying to download firmware: $set_return"); + } + last; + } + } - if($err ne "") # wenn ein Fehler bei der HTTP Abfrage aufgetreten ist - { - Log3 $name, 3, "$name: githubParseHttpResponse, error while requesting ".$param->{url}." - $err (command: $param->{command}"; # Eintrag fuers Log - #readingsSingleUpdate($hash, "fullResponse", "ERROR"); # Readings erzeugen } - elsif($data ne "" && defined($hardware)) # wenn die Abfrage erfolgreich war ($data enthaelt die Ergebnisdaten des HTTP Aufrufes) - { + } elsif (!defined($hardware)) { + $hash->{logMethod}->($name, 5, "$name: githubParseHttpResponse, hardware is not defined"); + } + # wenn + # Damit ist die Abfrage zuende. + # Evtl. einen InternalTimer neu schedulen + if (defined $FW_wname) + { + FW_directNotify("FILTER=$name", "#FHEMWEB:$FW_wname", "location.reload('true')", ''); + } + return 0; +} - my $json_array = decode_json($data); - #print Dumper($json_array); - if ($param->{command} eq "queryReleases") { - #Log3 $name, 3, "$name: githubParseHttpResponse, url ".$param->{url}." returned: $data"; # Eintrag fuers Log - my $releaselist=""; - if (ref($json_array) eq "ARRAY") { - foreach my $item( @$json_array ) { - next if (AttrVal($name,"updateChannelFW","stable") eq "stable" && $item->{prerelease}); - #Debug " item = ".Dumper($item); +############################# package main, candidate for fhem core utility lib +sub _limit_to_number { + my $number = shift // return; + return $number if ($number =~ /^[0-9]+$/); + return ; +} - foreach my $asset (@{$item->{assets}}) - { - next if ($asset->{name} !~ m/$hardware/i); - $releaselist.=$item->{tag_name}."," ; - last; - } - } - } - - $releaselist =~ s/,$//; - $hash->{additionalSets}{flash} = $releaselist; - } elsif ($param->{command} eq "getReleaseByTag" && defined($hardware)) { - #Debug " json response = ".Dumper($json_array); - - my @fwfiles; - foreach my $asset (@{$json_array->{assets}}) - { - my %fileinfo; - if ( $asset->{name} =~ m/$hardware/i) - { - $fileinfo{filename} = $asset->{name}; - $fileinfo{dlurl} = $asset->{browser_download_url}; - $fileinfo{create_date} = $asset->{created_at}; - #Debug " firmwarefiles = ".Dumper(@fwfiles); - push @fwfiles, \%fileinfo; - - my $set_return = SIGNALduino_Set($hash,$name,"flash",$asset->{browser_download_url}); # $hash->{SetFn - if(defined($set_return)) - { - $hash->{logMethod}->($name, 3, "$name: githubParseHttpResponse, Error while trying to download firmware: $set_return"); - } - last; - - } - } - - } - } elsif (!defined($hardware)) { - $hash->{logMethod}->($name, 5, "$name: githubParseHttpResponse, hardware is not defined"); - } # wenn - # Damit ist die Abfrage zuende. - # Evtl. einen InternalTimer neu schedulen - FW_directNotify("FILTER=$name", "#FHEMWEB:$FW_wname", "location.reload('true')", ""); - return 0; +############################# package main, candidate for fhem core utility lib +sub _limit_to_hex { + my $hex = shift // return; + return $hex if ($hex =~ /^[0-9A-F]+$/i); + return; } @@ -4648,128 +4041,278 @@ sub SIGNALduino_githubParseHttpResponse($$$) { ########## Section & functions cc1101 ########## package cc1101; +our %cc1101_status_register = ( # for get ccreg 30-3D status registers + '30' => 'PARTNUM ', + '31' => 'VERSION ', + '32' => 'FREQEST ', + '33' => 'LQI ', + '34' => 'RSSI ', + '35' => 'MARCSTATE ', + '36' => 'WORTIME1 ', + '37' => 'WORTIME0 ', + '38' => 'PKTSTATUS ', + '39' => 'VCO_VC_DAC ', + '3A' => 'TXBYTES ', + '3B' => 'RXBYTES ', + '3C' => 'RCCTRL1_STATUS', + '3D' => 'RCCTRL0_STATUS', +); + +our %cc1101_version = ( # Status register 0x31 (0xF1): VERSION – Chip ID + '03' => 'CC1100', + '04' => 'CC1101', + '14' => 'CC1101', + '05' => 'CC1100E', + '07' => 'CC110L', + '17' => 'CC110L', + '08' => 'CC113L', + '18' => 'CC113L', + '15' => 'CC115L', +); + ############################# package cc1101 #### for set function to change the patable for 433 or 868 Mhz supported #### 433.05–434.79 MHz, 863–870 MHz sub SetPatable { - my ($hash,@a) = @_; - my $paFreq = main::AttrVal($hash->{NAME},"cc1101_frequency","433"); - $paFreq = 433 if ($paFreq >= 433 && $paFreq <= 435); - $paFreq = 868 if ($paFreq >= 863 && $paFreq <= 870); - if ( exists($patable{$paFreq}) ) - { - my $pa = "x" . $patable{$paFreq}{$a[1]}; - $hash->{logMethod}->($hash->{NAME}, 3, "$hash->{NAME}: SetPatable, Setting patable $paFreq $a[1] $pa"); - main::SIGNALduino_AddSendQueue($hash,$pa); - main::SIGNALduino_WriteInit($hash); - return ; - } else { - return "$hash->{NAME}: Frequency $paFreq MHz not supported (supported frequency ranges: 433.05-434.79 MHz, 863.00-870.00 MHz)."; - } + my ($hash,@a) = @_; + my $paFreq = main::AttrVal($hash->{NAME},'cc1101_frequency','433'); + $paFreq = 433 if ($paFreq >= 433 && $paFreq <= 435); + $paFreq = 868 if ($paFreq >= 863 && $paFreq <= 870); + if ( exists($patable{$paFreq}) ) + { + my $pa = "x" . $patable{$paFreq}{$a[1]}; + $hash->{logMethod}->($hash->{NAME}, 3, "$hash->{NAME}: SetPatable, Setting patable $paFreq $a[1] $pa"); + main::SIGNALduino_AddSendQueue($hash,$pa); + main::SIGNALduino_WriteInit($hash); + return ; + } else { + return "$hash->{NAME}: Frequency $paFreq MHz not supported (supported frequency ranges: 433.05-434.79 MHz, 863.00-870.00 MHz)."; + } } ############################# package cc1101 sub SetRegisters { - my ($hash, @a) = @_; + my ($hash, @a) = @_; - ## check for four hex digits - my @nonHex = grep (!/^[0-9A-Fa-f]{4}$/,@a[1..$#a]) ; - return "$hash->{NAME} ERROR: wrong parameter value @nonHex, only hexadecimal ​​four digits allowed" if (@nonHex); - - ## check allowed register position - my (@wrongRegisters) = grep { !exists($cc1101_register{uc(substr($_,0,2))}) } @a[1..$#a] ; - return "$hash->{NAME} ERROR: unknown register position ".substr($wrongRegisters[0],0,2) if (@wrongRegisters); - - $hash->{logMethod}->($hash->{NAME}, 4, "$hash->{NAME}: SetRegisters, cc1101_reg @a[1..$#a]"); - my @tmpSendQueue=(); - foreach my $argcmd (@a[1..$#a]) { - $argcmd = sprintf("W%02X%s",hex(substr($argcmd,0,2)) + 2,substr($argcmd,2,2)); - main::SIGNALduino_AddSendQueue($hash,$argcmd); - } - main::SIGNALduino_WriteInit($hash); - return ; + ## check for four hex digits + my @nonHex = grep (!/^[0-9A-Fa-f]{4}$/,@a[1..$#a]) ; + return "$hash->{NAME} ERROR: wrong parameter value @nonHex, only hexadecimal ​​four digits allowed" if (@nonHex); + + ## check allowed register position + my (@wrongRegisters) = grep { !exists($cc1101_register{uc(substr($_,0,2))}) } @a[1..$#a] ; + return "$hash->{NAME} ERROR: unknown register position ".substr($wrongRegisters[0],0,2) if (@wrongRegisters); + + $hash->{logMethod}->($hash->{NAME}, 4, "$hash->{NAME}: SetRegisters, cc1101_reg @a[1..$#a]"); + my @tmpSendQueue=(); + foreach my $argcmd (@a[1..$#a]) { + $argcmd = sprintf("W%02X%s",hex(substr($argcmd,0,2)) + 2,substr($argcmd,2,2)); + main::SIGNALduino_AddSendQueue($hash,$argcmd); + } + main::SIGNALduino_WriteInit($hash); + return ; +} + +############################# package cc1101 +sub SetRegistersUser { + my ($hash) = @_; + + my $cc1101User = main::AttrVal($hash->{NAME}, 'cc1101_reg_user', undef); + + ## look, user defined self default register values via attribute + if (defined $cc1101User) { + $hash->{logMethod}->($hash->{NAME}, 3, "$hash->{NAME}: SetRegistersUser, write CC1101 defaults from attribute"); + $cc1101User = '0815,'.$cc1101User; # for SetRegisters, value for register starts on pos 1 in array + cc1101::SetRegisters($hash, split(',', $cc1101User) ); + } + return ; +} + +############################# package cc1101 +sub SetDataRate { + my ($hash, @a) = @_; + my $arg = $a[1]; + + if (exists($hash->{ucCmd}->{cmd}) && $hash->{ucCmd}->{cmd} eq 'set_dataRate' && $a[0] =~ /^C10\s=\s([A-Fa-f0-9]{2})$/) { + my ($ob1,$ob2) = cc1101::CalcDataRate($hash,$1,$hash->{ucCmd}->{arg}); + main::SIGNALduino_AddSendQueue($hash,"W12$ob1"); + main::SIGNALduino_AddSendQueue($hash,"W13$ob2"); + main::SIGNALduino_WriteInit($hash); + return ("Setting MDMCFG4..MDMCFG3 to $ob1 $ob2 = $hash->{ucCmd}->{arg} kHz" ,undef); + } else { + if ($arg !~ m/\d/) { return qq[$hash->{NAME}: ERROR, unsupported DataRate value]; } + if ($arg > 1621.83) { $arg = 1621.83; } # max 1621.83 kBaud DataRate + if ($arg < 0.0247955) { $arg = 0.0247955; } # min 0.0247955 kBaud DataRate + + cc1101::GetRegister($hash,10); # Get Register 10 + + $hash->{ucCmd}->{cmd} = 'set_dataRate'; + $hash->{ucCmd}->{arg} = $arg; # ZielDataRate + $hash->{ucCmd}->{responseSub} = \&cc1101::SetDataRate; # Callback auf sich selbst setzen + $hash->{ucCmd}->{asyncOut} = $hash->{CL} if (defined($hash->{CL})); + $hash->{ucCmd}->{timenow} = time(); + } + return ; +} + +############################# package cc1101 +sub CalcDataRate { + # register 0x10 3:0 & register 0x11 7:0 + my ($hash, $ob10, $dr) = @_; + $ob10 = hex($ob10) & 0xf0; + + my $DRATE_E = ($dr*1000) * (2**20) / 26000000; + $DRATE_E = log($DRATE_E) / log(2); + $DRATE_E = int($DRATE_E); + + my $DRATE_M = (($dr*1000) * (2**28) / (26000000 * (2**$DRATE_E))) - 256; + my $DRATE_Mr = main::round($DRATE_M,0); + $DRATE_M = int($DRATE_M); + + my $datarate0 = ( ((256+$DRATE_M)*(2**($DRATE_E & 15 )))*26000000/(2**28) / 1000); + my $DRATE_M1 = $DRATE_M + 1; + my $DRATE_E1 = $DRATE_E; + + if ($DRATE_M1 == 256) { + $DRATE_M1 = 0; + $DRATE_E1++; + } + + my $datarate1 = ( ((256+$DRATE_M1)*(2**($DRATE_E1 & 15 )))*26000000/(2**28) / 1000); + + if ($DRATE_Mr != $DRATE_M) { + $DRATE_M = $DRATE_M1; + $DRATE_E = $DRATE_E1; + } + + my $ob11 = sprintf("%02x",$DRATE_M); + $ob10 = sprintf("%02x", $ob10+$DRATE_E); + + $hash->{logMethod}->($hash->{NAME}, 5, qq[$hash->{NAME}: CalcDataRate, DataRate $hash->{ucCmd}->{arg} kHz step from $datarate0 to $datarate1 kHz]); + $hash->{logMethod}->($hash->{NAME}, 3, qq[$hash->{NAME}: CalcDataRate, DataRate MDMCFG4..MDMCFG3 to $ob10 $ob11 = $hash->{ucCmd}->{arg} kHz]); + + return ($ob10,$ob11); +} + +############################# package cc1101 +sub SetDeviatn { + my ($hash, @a) = @_; + my $arg = $a[1]; + + if ($arg !~ m/\d/) { return qq[$hash->{NAME}: ERROR, unsupported Deviation value]; } + if ($arg > 380.859375) { $arg = 380.859375; } # max 380.859375 kHz Deviation + if ($arg < 1.586914) { $arg = 1.586914; } # min 1.586914 kHz Deviation + + my $deviatn_val; + my $bits; + my $devlast = 0; + my $bitlast = 0; + + CalcDeviatn: + for (my $DEVIATION_E=0; $DEVIATION_E<8; $DEVIATION_E++) { + for (my $DEVIATION_M=0; $DEVIATION_M<8; $DEVIATION_M++) { + $deviatn_val = (8+$DEVIATION_M)*(2**$DEVIATION_E) *26000/(2**17); + $bits = $DEVIATION_M + ($DEVIATION_E << 4); + if ($arg > $deviatn_val) { + $devlast = $deviatn_val; + $bitlast = $bits; + } else { + if (($deviatn_val - $arg) < ($arg - $devlast)) { + $devlast = $deviatn_val; + $bitlast = $bits; + } + last CalcDeviatn; + } + } + } + + my $reg15 = sprintf("%02x",$bitlast); + my $deviatn_str = sprintf("% 5.2f",$devlast); + $hash->{logMethod}->($hash->{NAME}, 3, qq[$hash->{NAME}: SetDeviatn, Setting DEVIATN (15) to $reg15 = $deviatn_str kHz]); + + main::SIGNALduino_AddSendQueue($hash,"W17$reg15"); + main::SIGNALduino_WriteInit($hash); + + return; } ############################# package cc1101 sub SetFreq { - my ($hash, @a) = @_; + my ($hash, @a) = @_; - my $arg = $a[1]; - if (!defined($arg)) { - $arg = main::AttrVal($hash->{NAME},"cc1101_frequency", 433.92); - } - my $f = $arg/26*65536; - my $f2 = sprintf("%02x", $f / 65536); - my $f1 = sprintf("%02x", int($f % 65536) / 256); - my $f0 = sprintf("%02x", $f % 256); - $arg = sprintf("%.3f", (hex($f2)*65536+hex($f1)*256+hex($f0))/65536*26); - $hash->{logMethod}->($hash->{NAME}, 3, "$hash->{NAME}: SetFreq, Setting FREQ2..0 (0D,0E,0F) to $f2 $f1 $f0 = $arg MHz"); - main::SIGNALduino_AddSendQueue($hash,"W0F$f2"); - main::SIGNALduino_AddSendQueue($hash,"W10$f1"); - main::SIGNALduino_AddSendQueue($hash,"W11$f0"); - main::SIGNALduino_WriteInit($hash); - return ; + my $arg = $a[1]; + if (!defined($arg)) { + $arg = main::AttrVal($hash->{NAME},'cc1101_frequency', 433.92); + } + my $f = $arg/26*65536; + my $f2 = sprintf("%02x", $f / 65536); + my $f1 = sprintf("%02x", int($f % 65536) / 256); + my $f0 = sprintf("%02x", $f % 256); + $arg = sprintf("%.3f", (hex($f2)*65536+hex($f1)*256+hex($f0))/65536*26); + $hash->{logMethod}->($hash->{NAME}, 3, "$hash->{NAME}: SetFreq, Setting FREQ2..0 (0D,0E,0F) to $f2 $f1 $f0 = $arg MHz"); + main::SIGNALduino_AddSendQueue($hash,"W0F$f2"); + main::SIGNALduino_AddSendQueue($hash,"W10$f1"); + main::SIGNALduino_AddSendQueue($hash,"W11$f0"); + main::SIGNALduino_WriteInit($hash); + return ; } ############################# package cc1101 sub setrAmpl { - my ($hash, @a) = @_; - return "$hash->{NAME}: A numerical value between 24 and 42 is expected." if($a[1] !~ m/^\d+$/ || $a[1] < 24 ||$a[1] > 42); - my $v; - for($v = 0; $v < @ampllist; $v++) { - last if($ampllist[$v] > $a[1]); - } - $v = sprintf("%02d", $v-1); - my $w = $ampllist[$v]; - $hash->{logMethod}->($hash->{NAME}, 3, "$hash->{NAME}: setrAmpl, Setting AGCCTRL2 (1B) to $v / $w dB"); - main::SIGNALduino_AddSendQueue($hash,"W1D$v"); - main::SIGNALduino_WriteInit($hash); - return ; + my ($hash, @a) = @_; + return "$hash->{NAME}: A numerical value between 24 and 42 is expected." if($a[1] !~ m/^\d+$/ || $a[1] < 24 ||$a[1] > 42); + my $v; + for($v = 0; $v < @ampllist; $v++) { + last if($ampllist[$v] > $a[1]); + } + $v = sprintf("%02d", $v-1); + my $w = $ampllist[$v]; + $hash->{logMethod}->($hash->{NAME}, 3, "$hash->{NAME}: setrAmpl, Setting AGCCTRL2 (1B) to $v / $w dB"); + main::SIGNALduino_AddSendQueue($hash,"W1D$v"); + main::SIGNALduino_WriteInit($hash); + return ; } ############################# package cc1101 sub GetRegister { - my ($hash, $reg) = @_; - main::SIGNALduino_AddSendQueue($hash,"C".$reg); - return ; + my ($hash, $reg) = @_; + main::SIGNALduino_AddSendQueue($hash,'C'.$reg); + return ; } ############################# package cc1101 sub CalcbWidthReg { - my ($hash, $reg10, $bWith) = @_; - # Beispiel Rückmeldung, mit Ergebnis von Register 10: C10 = 57 - my $ob = hex($reg10) & 0x0f; - my ($bits, $bw) = (0,0); - OUTERLOOP: - for (my $e = 0; $e < 4; $e++) { - for (my $m = 0; $m < 4; $m++) { - $bits = ($e<<6)+($m<<4); - $bw = int(26000/(8 * (4+$m) * (1 << $e))); # KHz - last OUTERLOOP if($bWith >= $bw); - } - } - $ob = sprintf("%02x", $ob+$bits); + my ($hash, $reg10, $bWith) = @_; + # Beispiel Rückmeldung, mit Ergebnis von Register 10: C10 = 57 + my $ob = hex($reg10) & 0x0f; + my ($bits, $bw) = (0,0); + OUTERLOOP: + for (my $e = 0; $e < 4; $e++) { + for (my $m = 0; $m < 4; $m++) { + $bits = ($e<<6)+($m<<4); + $bw = int(26000/(8 * (4+$m) * (1 << $e))); # KHz + last OUTERLOOP if($bWith >= $bw); + } + } + $ob = sprintf("%02x", $ob+$bits); - return ($ob,$bw); + return ($ob,$bw); } ############################# package cc1101 sub SetSens { - my ($hash, @a) = @_; + my ($hash, @a) = @_; - # Todo: Abfrage in Grep auf Array ändern - return "a numerical value between 4 and 16 is expected" if($a[1] !~ m/^\d+$/ || $a[1] < 4 || $a[1] > 16); - my $w = int($a[1]/4)*4; - my $v = sprintf("9%d",$a[1]/4-1); - $hash->{logMethod}->($hash->{NAME}, 3, "$hash->{NAME}: SetSens, Setting AGCCTRL0 (1D) to $v / $w dB"); - main::SIGNALduino_AddSendQueue($hash,"W1F$v"); - main::SIGNALduino_WriteInit($hash); - return ; + # Todo: Abfrage in Grep auf Array ändern + return 'a numerical value between 4 and 16 is expected' if($a[1] !~ m/^\d+$/ || $a[1] < 4 || $a[1] > 16); + my $w = int($a[1]/4)*4; + my $v = sprintf("9%d",$a[1]/4-1); + $hash->{logMethod}->($hash->{NAME}, 3, "$hash->{NAME}: SetSens, Setting AGCCTRL0 (1D) to $v / $w dB"); + main::SIGNALduino_AddSendQueue($hash,"W1F$v"); + main::SIGNALduino_WriteInit($hash); + return ; } - - -################################################################################################ +################################################################################################ 1; =pod @@ -4781,420 +4324,558 @@ sub SetSens {

SIGNALduino

- - - -
- The SIGNALduino ia based on an idea from mdorenka published at FHEM Forum. With the opensource firmware (see this link) it is capable to receive and send different protocols over different medias. Currently are 433Mhz protocols implemented.

- The following device support is currently available:

- Wireless switches
-
    -
  • ITv1 & ITv3/Elro and other brands using pt2263 or arctech protocol--> uses IT.pm
    In the ITv1 protocol is used to sent a default ITclock from 250 and it may be necessary in the IT-Modul to define the attribute ITclock
  • -
  • ELV FS10 -> 10_FS10
  • -
  • ELV FS20 -> 10_FS20
  • -
-
- Temperature / humidity sensors -
    -
  • PEARL NC7159, LogiLink WS0002,GT-WT-02,AURIOL,TCM97001, TCM27 and many more -> 14_CUL_TCM97001
  • -
  • Oregon Scientific v2 and v3 Sensors -> 41_OREGON.pm
  • -
  • Temperatur / humidity sensors suppored -> 14_SD_WS07
  • -
  • technoline WS 6750 and TX70DTH -> 14_SD_WS07
  • -
  • Eurochon EAS 800z -> 14_SD_WS07
  • -
  • CTW600, WH1080 -> 14_SD_WS09
  • -
  • Hama TS33C, Bresser Thermo/Hygro Sensor -> 14_Hideki
  • -
  • FreeTec Aussenmodul NC-7344 -> 14_SD_WS07
  • -
  • La Crosse WS-7035, WS-7053, WS-7054 -> 14_CUL_TX
  • -
  • ELV WS-2000, La Crosse WS-7000 -> 14_CUL_WS
  • -
-
- It is possible to attach more than one device in order to get better reception, fhem will filter out duplicate messages. See more at the global section with attribute dupTimeout

- Note: this module require the Device::SerialPort or Win32::SerialPort module. It can currently only attatched via USB. -
-
- - Define -
    define <name> SIGNALduino <device>
- USB-connected devices (SIGNALduino):
-
    -
  • - <device> specifies the serial port to communicate with the SIGNALduino. The name of the serial-device depends on your distribution, under linux the cdc_acm kernel module is responsible, and usually a /dev/ttyACM0 or /dev/ttyUSB0 device will be created. If your distribution does not have a cdc_acm module, you can force usbserial to handle the SIGNALduino by the following command: -
      -
    • modprobe usbserial
    • -
    • vendor=0x03eb
    • -
    • product=0x204b
    • -
    - In this case the device is most probably /dev/ttyUSB0.

    - You can also specify a baudrate if the device name contains the @ character, e.g.: /dev/ttyACM0@57600

    This is also the default baudrate.
    - It is recommended to specify the device via a name which does not change:
    - e.g. via by-id devicename: /dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0@57600
    - If the baudrate is "directio" (e.g.: /dev/ttyACM0@directio), then the perl module Device::SerialPort is not needed, and fhem opens the device with simple file io. This might work if the operating system uses sane defaults for the serial parameters, e.g. some Linux distributions and OSX.

    -
  • -
- - Internals -
    -
  • IDsNoDispatch: Here are protocols entryls listed by their numeric id for which not communication to a logical module is enabled. To enable, look at the menu option Display protocollist.
  • -
  • LASTDMSGID: This shows the last dispatched Protocol ID.
  • -
  • NR_CMD_LAST_H: Number of messages sent within the last hour.
  • -
  • RAWMSG: last received RAWMSG
  • -
  • cc1101_available: If a CC1101 was detected, this internal is displayed with the value 1.
  • -
  • version: This shows the version of the SIGNALduino microcontroller.
  • -
  • versionProtocols: This shows the version of SIGNALduino protocol file.
  • -
  • versionmodule: This shows the version of the SIGNALduino FHEM module itself.
  • -
- - - Set -
    -
  • freq / bWidth / patable / rAmpl / sens / registers
    - Only with CC1101 receiver.
    - Set the sduino frequency / bandwidth / PA table / receiver-amplitude / sensitivity
    - - Use it with care, it may destroy your hardware and it even may be - illegal to do so. Note: The parameters used for RFR transmission are - not affected.
    -
      - -
    • cc1101_freq sets both the reception and transmission frequency. Note: Although the CC1101 can be set to frequencies between 315 and 915 MHz, the antenna interface and the antenna is tuned for exactly one frequency. Default is 433.920 MHz (or 868.350 MHz). If not set, frequency from cc1101_frequency will be used.
    • - -
    • cc1101_bWidth can be set to values between 58 kHz and 812 kHz. Large values are susceptible to interference, but make possible to receive inaccurately calibrated transmitters. It affects tranmission too. Default is 325 kHz.
    • - -
    • cc1101_patable change the PA table (power amplification for RF sending)
    • - -
    • cc1101_rAmpl is receiver amplification, with values between 24 and 42 dB. Bigger values allow reception of weak signals. Default is 42.
    • - -
    • cc1101_sens is the decision boundary between the on and off values, and it is 4, 8, 12 or 16 dB. Smaller values allow reception of less clear signals. Default is 4 dB.
    • - -
    • cc1101_reg You can set multiple registers at one. Specify the register with its two digit hex code followed by the register value separate multiple registers via space.
    • -
    -

  • - -
  • close
    - Closes the connection to the device. -

  • - -
  • disableMessagetype
    - Allows you to disable the message processing for -
      -
    • messages with sync (syncedMS),
    • -
    • messages without a sync pulse (unsyncedMU)
    • -
    • manchester encoded messages (manchesterMC)
    • -
    - The new state will be saved into the eeprom of your arduino. -

  • - -
  • enableMessagetype
    - Allows you to enable the message processing for -
      -
    • messages with sync (syncedMS)
    • -
    • messages without a sync pulse (unsyncedMU)
    • -
    • manchester encoded messages (manchesterMC)
    • -
    - The new state will be saved into the eeprom of your arduino. -

  • - -
  • flash [hexFile|url]
    - The SIGNALduino needs the right firmware to be able to receive and deliver the sensor data to fhem. In addition to the way using the arduino IDE to flash the firmware into the SIGNALduino this provides a way to flash it directly from FHEM. You can specify a file on your fhem server or specify a url from which the firmware is downloaded There are some requirements: -
      -
    • avrdude must be installed on the host
      On a Raspberry PI this can be done with: sudo apt-get install avrdude
    • -
    • the hardware attribute must be set if using any other hardware as an Arduino nano
      This attribute defines the command, that gets sent to avrdude to flash the uC.
    • -
    • If you encounter a problem, look into the logfile
    • -
    - Example: -
      -
    • flash via Version Name: Versions are provided via get availableFirmware
    • -
    • flash via hexFile: set sduino flash ./FHEM/firmware/SIGNALduino_mega2560.hex
    • -
    • flash via url for Nano with CC1101: set sduino flash https://github.com/RFD-FHEM/SIGNALDuino/releases/download/3.3.1-RC7/SIGNALDuino_nanocc1101.hex
    • -
    - note model radino: -
      -
    • Sometimes there can be problems flashing radino on Linux. Here in the wiki under point "radino & Linux" is a patch!
    • -
    • If the Radino is defined in this way /dev/ttyACM0, the flashing of the firmware should be done automatically. If this fails, the boot loader must be activated manually:
    • -
    • To activate the bootloader of the radino there are 2 variants. -
        -
      • 1) modules that contain a BSL-button: -
          -
        • apply supply voltage
        • -
        • press & hold BSL- and RESET-Button
        • -
        • release RESET-button, release BSL-button
        • -
        • (repeat these steps if your radino doesn't enter bootloader mode right away.)
        • -
        -
      • -
      • 2) force bootloader: -
          -
        • pressing reset button twice
        • -
        -
      • -
      - In bootloader mode, the radino gets a different USB ID. This must be entered in the "flashCommand" attribute.
      - If the bootloader is enabled, it signals with a flashing LED. Then you have 8 seconds to flash. -
    • -
    -

  • - -
  • reset
    - This will do a reset of the usb port and normaly causes to reset the uC connected. -

  • - -
  • raw
    - Issue a SIGNALduino firmware command, without waiting data returned by - the SIGNALduino. See the SIGNALduino firmware code for details on SIGNALduino - commands. With this line, you can send almost any signal via a transmitter connected - - To send some raw data look at these examples: - P#binarydata#R#C (#C is optional)
    -
    Example 1: set sduino raw SR;R=3;P0=500;P1=-9000;P2=-4000;P3=-2000;D=0302030 sends the data in raw mode 3 times repeated -
    Example 2: set sduino raw SM;R=3;P0=500;C=250;D=A4F7FDDE sends the data manchester encoded with a clock of 250uS -
    Example 3: set sduino raw SC;R=3;SR;P0=5000;SM;P0=500;C=250;D=A4F7FDDE sends a combined message of raw and manchester encoded repeated 3 times -

      - note: The wrong use of the upcoming options can lead to malfunctions of the SIGNALduino!

      - Register commands for a CC1101
      -
    • e -> default settings
    • -
    • W -> writes a value to the EEPROM and the CC1101 register
      -          note: The EEPROM address has an offset of 2. example: set sduino raw W041D write 1D to Register 0x02 -
    • -
    -

    -
  • - -
  • sendMsg
    - This command will create the needed instructions for sending raw data via the signalduino. Insteaf of specifying the signaldata by your own you specify - a protocol and the bits you want to send. The command will generate the needed command, that the signalduino will send this. - It is also supported to specify the data in hex. prepend 0x in front of the data part. -

    - Please note, that this command will work only for MU or MS protocols. You can't transmit manchester data this way. -

    - Input args are: -

    -

    • P#binarydata#R#C (#C is optional) -
      Example binarydata: set sduino sendMsg P0#0101#R3#C500 -
      Will generate the raw send command for the message 0101 with protocol 0 and instruct the arduino to send this three times and the clock is 500. -
      SR;R=3;P0=500;P1=-9000;P2=-4000;P3=-2000;D=03020302;

    -
    • P#0xhexdata#R#C (#C is optional) -
      Example 0xhexdata: set sduino sendMsg P29#0xF7E#R4 -
      Generates the raw send command with the hex message F7E with protocl id 29 . The message will be send four times. -
      SR;R=4;P0=-8360;P1=220;P2=-440;P3=-220;P4=440;D=01212121213421212121212134;

    -
    • P#0xhexdata#R#C#F (#C #F is optional) -
      Example 0xhexdata: set sduino sendMsg P36#0xF7#R6#Fxxxxxxxxxx (xxxxxxxxxx = register from CC1101) -
      Generates the raw send command with the hex message F7 with protocl id 36 . The message will be send six times. -
      SR;R=6;P0=-8360;P1=220;P2=-440;P3=-220;P4=440;D=012323232324232323;F= (register from CC1101);
    -

- - - - Get -
    - -
  • availableFirmware
    - Retrieves available firmware versions from github and displays them in set flash command. -

  • - -
  • ccconf
    - Read some CUL radio-chip (cc1101) registers (frequency, bandwidth, etc.), - and display them in human readable form.
    - Only with cc1101 receiver. -

  • - -
  • ccpatable
    - read cc1101 PA table (power amplification for RF sending)
    - Only with cc1101 receiver. -

  • - -
  • ccreg
    - read cc1101 registers (99 reads all cc1101 registers)
    - Only with cc1101 receiver. -

  • - -
  • cmds
    - Depending on the firmware installed, SIGNALduinos have a different set of - possible commands. Please refer to the sourcecode of the firmware of your - SIGNALduino to interpret the response of this command. See also the raw- - command. -

  • - -
  • config
    - Displays the configuration of the SIGNALduino protocol category. | example: MS=1;MU=1;MC=1;Mred=0 -

  • - -
  • freeram
    - Displays the free RAM. -

  • - -
  • ping
    - Check the communication with the SIGNALduino. -

  • - -
  • raw
    - Only for manual processing of messages (MS, MC, MU, ...). The get raw command does not send any commands to the microcontroller! -

  • - -
  • uptime
    - Displays information how long the SIGNALduino is running. A FHEM reboot resets the timer. -

  • - -
  • version
    - return the SIGNALduino firmware version -

  • -
+ + + +
+ The SIGNALduino ia based on an idea from mdorenka published at FHEM Forum.
+ With the opensource firmware (see this link) it is capable to receive and send different protocols over different medias. +

+ The following device support is currently available:

+ Wireless switches
+
    +
  • ITv1 & ITv3/Elro and other brands using pt2263 or arctech protocol--> uses IT.pm
    In the ITv1 protocol is used to sent a default ITclock from 250 and it may be necessary in the IT-Modul to define the attribute ITclock +
  • +
  • ELV FS10 -> 10_FS10
  • +
  • ELV FS20 -> 10_FS20
  • +
+ Temperature / humidity sensors +
    +
  • CTW600, WH1080 -> 14_SD_WS09
  • +
  • ELV WS-2000, La Crosse WS-7000 -> 14_CUL_WS
  • +
  • Eurochon EAS 800z -> 14_SD_WS07
  • +
  • FreeTec Aussenmodul NC-7344 -> 14_SD_WS07
  • +
  • Hama TS33C, Bresser Thermo/Hygro Sensor -> 14_Hideki
  • +
  • La Crosse WS-7035, WS-7053, WS-7054 -> 14_CUL_TX
  • +
  • Oregon Scientific v2 and v3 Sensors -> 41_OREGON.pm
  • +
  • PEARL NC7159, LogiLink WS0002,GT-WT-02,AURIOL,TCM97001, TCM27 and many more -> 14_CUL_TCM97001
  • +
  • Temperatur / humidity sensors suppored -> 14_SD_WS07
  • +
  • technoline WS 6750 and TX70DTH -> 14_SD_WS07
  • +
+
+ It is possible to attach more than one device in order to get better reception, fhem will filter out duplicate messages. See more at the global section with attribute dupTimeout

+ Note: this module require the Device::SerialPort or Win32::SerialPort module. It can currently only attatched via USB. +
+
- - Attributes -
    -
  • addvaltrigger
    - Create triggers for additional device values. Right now these are RSSI, RAWMSG, DMSG and ID. -

  • - -
  • blacklist_IDs
    - The blacklist works only if a whitelist not exist. -

  • - -
  • cc1101_frequency
    - Specify the frequency of your SIGNALduino. Default is 433 Mhz.
    - Since the PA table values are frequency-dependent,the specified frequency will be used. -

  • - -
  • debug
    - This will bring the module in a very verbose debug output. Usefull to find new signals and verify if the demodulation works correctly. -

  • - -
  • development
    - The development attribute is only available in development version of this Module for backwart compatibility. Use the whitelistIDs Attribute instead. Setting this attribute to 1 will enable all protocols which are flagged with developID=Y. -
    - To check which protocols are flagged, open via FHEM webinterface in the section "Information menu" the option "Display protocollist". Look at the column "dev" where the flags are noted. -
    -
  • -
  • do_not_notify

  • -
  • dummy

  • - -
  • doubleMsgCheck_IDs
    - This attribute allows it, to specify protocols which must be received two equal messages to call dispatch to the modules.
    - You can specify multiple IDs wih a colon : 0,3,7,12
    -

  • - -
  • eventlogging
    - With this attribute you can control if every logmessage is also provided as event. This allows to generate event for every log messages. - Set this to 0 and logmessages are only saved to the global fhem logfile if the loglevel is higher or equal to the verbose attribute. - Set this to 1 and every logmessages is also dispatched as event. This allows you to log the events in a seperate logfile. -

  • - -
  • flashCommand
    - This is the command, that is executed to performa the firmware flash. Do not edit, if you don't know what you are doing.
    - If the attribute not defined, it uses the default settings. If the user defines the attribute manually, the system uses the specifications!
    -
      -
    • default for nano, nanoCC1101, miniculCC1101, promini: avrdude -c arduino -b [BAUDRATE] -P [PORT] -p atmega328p -vv -U flash:w:[HEXFILE] 2>[LOGFILE]
    • -
    • default for radinoCC1101: avrdude -c avr109 -b [BAUDRATE] -P [PORT] -p atmega32u4 -vv -D -U flash:w:[HEXFILE] 2>[LOGFILE]
    • -
    - It contains some place-holders that automatically get filled with the according values:
    -
      -
    • [BAUDRATE]
      - is the speed (e.g. 57600)
    • -
    • [PORT]
      - is the port the Signalduino is connectd to (e.g. /dev/ttyUSB0) and will be used from the defenition
    • -
    • [HEXFILE]
      - is the .hex file that shall get flashed. There are three options (applied in this order):
      - - passed in set flash as first argument
      - - taken from the hexFile attribute
      - - the default value defined in the module
      -
    • -
    • [LOGFILE]
      - The logfile that collects information about the flash process. It gets displayed in FHEM after finishing the flash process
    • -

    - note: ! Sometimes there can be problems flashing radino on Linux. Here in the wiki under the point "radino & Linux" is a patch! -

  • - -
  • hardware
    - Currently, there are serval hardware options with different receiver options available. - The simple single wire option, consists of a single wire connected receiver and a single wire connected transmitter which are connected over a single digital port with the microcontroller. The receiver only sends data and the transmitter receives only from the microcontroller. - The other option consists of the cc1101 (sub 1 GHZ) chip, which can transmit and receiver. It's a transceiver which is connected via spi. - ESP8266 hardware type, currently doesn't support flashing out of the modu and needs at leat 1 MB of flash. -
      -
    • ESP32: ESP32
    • -
    • ESP8266: ESP8266 simple single wire receiver
    • -
    • ESP8266cc1101: ESP8266 with CC1101 (spi connected) receiver
    • -
    • miniculCC1101: Arduino pro Mini with CC110x (spi connected) receiver and cables as a minicul
    • -
    • nano: Arduino Nano 328 with simple single wired receiver
    • -
    • nanoCC1101: Arduino Nano 328 with CC110x (spi connected) receiver
    • -
    • promini: Arduino Pro Mini 328 with simple single receiver
    • -
    • radinoCC1101: Arduino compatible radino with cc1101 (spi connected) receiver
    • -
    -

  • -
  • maxMuMsgRepeat
    - MU signals can contain multiple repeats of the same message. The results are all send to a logical module. You can limit the number of scanned repetitions. Defaukt is 4, so after found 4 repeats, the demoduation is aborted. -
  • - -
  • minsecs
    + +Define +
      define <name> SIGNALduino <device>
    +USB-connected devices (SIGNALduino):
    +
      +
    • + <device> specifies the serial port to communicate with the SIGNALduino. The name of the serial-device depends on your distribution, under linux the cdc_acm kernel module is responsible, and usually a /dev/ttyACM0 or /dev/ttyUSB0 device will be created. If your distribution does not have a cdc_acm module, you can force usbserial to handle the SIGNALduino by the following command: +
        +
      • modprobe usbserial
      • +
      • vendor=0x03eb
      • +
      • product=0x204b
      • +
      + In this case the device is most probably /dev/ttyUSB0.

      + You can also specify a baudrate if the device name contains the @ character, e.g.: /dev/ttyACM0@57600

      This is also the default baudrate.
      + It is recommended to specify the device via a name which does not change:
      + e.g. via by-id devicename: /dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0@57600
      + If the baudrate is "directio" (e.g.: /dev/ttyACM0@directio), then the perl module Device::SerialPort is not needed, and fhem opens the device with simple file io. This might work if the operating system uses sane defaults for the serial parameters, e.g. some Linux distributions and OSX.

      +
    • +
    + + + +Internals +
      +
    • IDsNoDispatch: Here are protocols entryls listed by their numeric id for which not communication to a logical module is enabled. To enable, look at the menu option Display protocollist.
    • +
    • LASTDMSGID: This shows the last dispatched Protocol ID.
    • +
    • NR_CMD_LAST_H: Number of messages sent within the last hour.
    • +
    • RAWMSG: last received RAWMSG
    • +
    • cc1101_available: If a CC1101 was detected, this internal is displayed with the value 1.
    • +
    • version: This shows the version of the SIGNALduino microcontroller.
    • +
    • versionProtocols: This shows the version of SIGNALduino protocol file.
    • +
    • versionmodule: This shows the version of the SIGNALduino FHEM module itself.
    • +

    + + + +Set +
      +
    • LaCrossePairForSec
    • + (Only with CC1101 receiver)
      + Enable autocreate of new LaCrosse sensors for x seconds. If ignore_battery is not given only sensors sending the 'new battery' flag will be created.

      +
    • cc1101_bWidth / cc1101_dataRate / cc1101_deviatn / cc1101_freq / cc1101_patable / cc1101_rAmpl / cc1101_reg / cc1101_sens
      + (Only with CC1101 receiver)
      + Set the sduino frequency / bandwidth / PA table / receiver-amplitude / sensitivity
      + + Use it with care, it may destroy your hardware and it even may be + illegal to do so. Note: The parameters used for RFR transmission are + not affected.
      +
        + +
      • cc1101_bWidth can be set to values between 58 kHz and 812 kHz. Large values are susceptible to interference, but make possible to receive inaccurately calibrated transmitters. It affects tranmission too. Default is 325 kHz. +
      • + +
      • cc1101_dataRate , can be set to values ​​between 0.0247955 kBaud and 1621.83 kBaud. +
      • + +
      • cc1101_deviatn , can be set to values ​​between 1.586914 kHz and 380.859375 kHz. +
      • + +
      • cc1101_freq sets both the reception and transmission frequency. Note: Although the CC1101 can be set to frequencies between 315 and 915 MHz, the antenna interface and the antenna is tuned for exactly one frequency. Default is 433.920 MHz (or 868.350 MHz). If not set, frequency from cc1101_frequency will be used. +
      • + +
      • cc1101_patable change the PA table (power amplification for RF sending) +
      • + +
      • cc1101_rAmpl is receiver amplification, with values between 24 and 42 dB. Bigger values allow reception of weak signals. Default is 42. +
      • + +
      • cc1101_reg You can set multiple registers at one. Specify the register with its two digit hex code followed by the register value separate multiple registers via space. +
      • + +
      • cc1101_sens is the decision boundary between the on and off values, and it is 4, 8, 12 or 16 dB. Smaller values allow reception of less clear signals. Default is 4 dB. +
      • +
      +

    • + +
    • close
      + Closes the connection to the device. +

    • + +
    • disableMessagetype
      + Allows you to disable the message processing for +
        +
      • messages with sync (syncedMS)
      • +
      • messages without a sync pulse (unsyncedMU)
      • +
      • manchester encoded messages (manchesterMC)
      • +
      + The new state will be saved into the eeprom of your arduino. +

    • + +
    • enableMessagetype
      + Allows you to enable the message processing for +
        +
      • messages with sync (syncedMS)
      • +
      • messages without a sync pulse (unsyncedMU)
      • +
      • manchester encoded messages (manchesterMC)
      • +
      + The new state will be saved into the eeprom of your arduino. +

    • + +
    • flash [hexFile|url]
      + The SIGNALduino needs the right firmware to be able to receive and deliver the sensor data to fhem. In addition to the way using the arduino IDE to flash the firmware into the SIGNALduino this provides a way to flash it directly from FHEM. You can specify a file on your fhem server or specify a url from which the firmware is downloaded.

      + There are some requirements: +
        +
      • avrdude must be installed on the host
        On a Raspberry PI this can be done with: sudo apt-get install avrdude
      • +
      • the hardware attribute must be set if using any other hardware as an Arduino nano
        This attribute defines the command, that gets sent to avrdude to flash the uC.
      • +
      • If you encounter a problem, look into the logfile
      • +

      + Example: +
        +
      • flash via Version Name: Versions are provided via get availableFirmware
      • +
      • flash via hexFile: set sduino flash ./FHEM/firmware/SIGNALduino_mega2560.hex
      • +
      • flash via url for Nano with CC1101: set sduino flash https://github.com/RFD-FHEM/SIGNALDuino/releases/download/3.3.1-RC7/SIGNALDuino_nanocc1101.hex
      • +

      + note model radino: +
        +
      • Sometimes there can be problems flashing radino on Linux. Here in the wiki under point "radino & Linux" is a patch! +
      • +
      • If the Radino is defined in this way /dev/ttyACM0, the flashing of the firmware should be done automatically. If this fails, the boot loader must be activated manually: +
      • +
      • To activate the bootloader of the radino there are 2 variants. +
          +
        • 1) modules that contain a BSL-button: +
            +
          • apply supply voltage
          • +
          • press & hold BSL- and RESET-Button
          • +
          • release RESET-button, release BSL-button
          • +
          • (repeat these steps if your radino doesn't enter bootloader mode right away.)
          • +
          +
        • +
        • 2) force bootloader: +
            +
          • pressing reset button twice
          • +
          +
        • +
        + In bootloader mode, the radino gets a different USB ID. This must be entered in the "flashCommand" attribute.
        + If the bootloader is enabled, it signals with a flashing LED. Then you have 8 seconds to flash. +
      • +
      +

    • + + +
    • raw
      + Issue a SIGNALduino firmware command, without waiting data returned by + the SIGNALduino. See the SIGNALduino firmware code for details on SIGNALduino + commands. With this line, you can send almost any signal via a transmitter connected + + To send some raw data look at these examples: + P#binarydata#R#C (#C is optional)
      +
      Example 1: set sduino raw SR;R=3;P0=500;P1=-9000;P2=-4000;P3=-2000;D=0302030; sends the data in raw mode 3 times repeated +
      Example 2: set sduino raw SM;R=3;P0=500;C=250;D=A4F7FDDE; sends the data manchester encoded with a clock of 250uS +
      Example 3: set sduino raw SC;R=3;SR;P0=5000;SM;P0=500;C=250;D=A4F7FDDE; sends a combined message of raw and manchester encoded repeated 3 times +
      Example 4: set sduino raw SN;R=3;D=9A46036AC8D3923EAEB470AB; sends a xFSK message of raw and repeated 3 times +

        + note: The wrong use of the upcoming options can lead to malfunctions of the SIGNALduino!

        +
      • CER -> turn on data compression (config: Mred=1)
      • +
      • CDR -> disable data compression (config: Mred=0)

      • + + Register commands for a CC1101 +
      • e -> default settings
      • +
      • x -> returns the ccpatable
      • +
      • C -> reads a value from the CC1101 register
        +
          example: set sduino raw C04 reads the value from register address 0x04
        +
      • +
      • W -> writes a value to the EEPROM and the CC1101 register (note: The EEPROM address has an offset of 2)
        +
          example 1: set sduino raw W041D write 1D to register 0x02
        +
          example 2: set sduino raw W041D#W0604 write 1D to register 0x02 and write 04 to register 0x04
        +
      • +
        + other commands from uC +
      • ? -> returns the available commands
      • +
      • P -> sends a PING
      • +
      • R -> returns the free RAM
      • +
      • V -> returns the version
      • +
      • s -> returns the status
      • +
      • t -> returns the uptime
      • +

      +
    • + + +
    • reset
      + This will do a reset of the usb port and normaly causes to reset the uC connected. +

    • + + +
    • sendMsg
      + This command will create the needed instructions for sending raw data via the signalduino. Insteaf of specifying the signaldata by your own you specify + a protocol and the bits you want to send. The command will generate the needed command, that the signalduino will send this. + It is also supported to specify the data in hex. prepend 0x in front of the data part. +

      + Please note, that this command will work only for MU or MS protocols. You can't transmit manchester data this way. +

      + Input args are: +

      +

        +
      • P#binarydata#R#C (#C is optional) +
        Example binarydata: set sduino sendMsg P0#0101#R3#C500 +
        Will generate the raw send command for the message 0101 with protocol 0 and instruct the arduino to send this three times and the clock is 500. +
        SR;R=3;P0=500;P1=-9000;P2=-4000;P3=-2000;D=03020302; +
      • +

      +
        +
      • P#0xhexdata#R#C (#C is optional) +
        Example 0xhexdata: set sduino sendMsg P29#0xF7E#R4 +
        Generates the raw send command with the hex message F7E with protocl id 29 . The message will be send four times. +
        SR;R=4;P0=-8360;P1=220;P2=-440;P3=-220;P4=440;D=01212121213421212121212134; +
      • +

      +
        +
      • P#0xhexdata#R#C#F (#C #F is optional) +
        Example 0xhexdata: set sduino sendMsg P36#0xF7#R6#Fxxxxxxxxxx (xxxxxxxxxx = register from CC1101) +
        Generates the raw send command with the hex message F7 with protocl id 36 . The message will be send six times. +
        SR;R=6;P0=-8360;P1=220;P2=-440;P3=-220;P4=440;D=012323232324232323;F= (register from CC1101); +
      • +
      +

      +
    • +
    + + + +Get +
      + +
    • availableFirmware
      + Retrieves available firmware versions from github and displays them in set flash command. +

    • + +
    • ccconf
      + Read some CUL radio-chip (cc1101) registers (frequency, bandwidth, etc.), + and display them in human readable form.
      + Only with cc1101 receiver. +

    • + +
    • ccpatable
      + read cc1101 PA table (power amplification for RF sending)
      + Only with cc1101 receiver. +

    • + +
    • ccreg
      + read cc1101 registers (99 reads all cc1101 registers)
      + Only with cc1101 receiver. +

    • + +
    • close
      + Close the connection to the SIGNALduino. +

    • + +
    • cmds
      + Depending on the firmware installed, SIGNALduinos have a different set of + possible commands. Please refer to the sourcecode of the firmware of your + SIGNALduino to interpret the response of this command. See also the raw-command. +

    • + +
    • config
      + Displays the configuration of the SIGNALduino protocol category. | example: MS=1;MU=1;MC=1;Mred=0 +

    • + +
    • freeram
      + Displays the free RAM. +

    • + +
    • ping
      + Check the communication with the SIGNALduino. +

    • + +
    • rawmsg
      + Processes messages (MS, MC, MU, ...) as if they were received by the SIGNALduino. The get raw command does not send any commands to the microcontroller!

      + For example, this message would: + MS;P0=-7871;P2=-1960;P3=578;P4=-3954;D=030323232323434343434323232323234343434323234343234343234343232323432323232323232343234;CP=3;SP=0;R=0;m=0;
      + after executing the command several times, create a sensor SD_WS_33_TH_1. +

    • + +
    • uptime
      + Displays information how long the SIGNALduino is running. A FHEM reboot resets the timer. +

    • + +
    • version
      + return the SIGNALduino firmware version +

    • +
    + + + +Attributes +
      +
    • addvaltrigger
      + Create triggers for additional device values. Right now these are RSSI, RAWMSG, DMSG and ID. +

    • + +
    • blacklist_IDs
      + The blacklist works only if a whitelist not exist. +

    • + +
    • cc1101_frequency
      + Specify the frequency of your SIGNALduino. Default is 433 Mhz.
      + Since the PA table values are frequency-dependent,the specified frequency will be used. +

    • + +
    • cc1101_reg_user
      + Storage space for individual register configurations or values. One or more values ​​can be saved.
      + note: The value consists of the register address followed by the value. Multiple values ​​are separated by commas. example: 04D3,0591 +

    • + +
    • debug
      + This will bring the module in a very verbose debug output. Usefull to find new signals and verify if the demodulation works correctly. +

    • + +
    • development
      + The development attribute is only available in development version of this Module for backwart compatibility. Use the whitelistIDs Attribute instead. Setting this attribute to 1 will enable all protocols which are flagged with developID=Y. +
      + To check which protocols are flagged, open via FHEM webinterface in the section "Information menu" the option "Display protocollist". Look at the column "dev" where the flags are noted. +

      +
    • +
    • do_not_notify

    • + +
    • doubleMsgCheck_IDs
      + This attribute allows it, to specify protocols which must be received two equal messages to call dispatch to the modules.
      + You can specify multiple IDs wih a colon : 0,3,7,12
      +

    • +
    • dummy

    • + +
    • eventlogging
      + With this attribute you can control if every logmessage is also provided as event. This allows to generate event for every log messages. + Set this to 0 and logmessages are only saved to the global fhem logfile if the loglevel is higher or equal to the verbose attribute. + Set this to 1 and every logmessages is also dispatched as event. This allows you to log the events in a seperate logfile. +

    • + +
    • flashCommand
      + This is the command, that is executed to performa the firmware flash. Do not edit, if you don't know what you are doing.
      + If the attribute not defined, it uses the default settings. If the user defines the attribute manually, the system uses the specifications!
      +
        +
      • default for nano, nanoCC1101, miniculCC1101, promini: avrdude -c arduino -b [BAUDRATE] -P [PORT] -p atmega328p -vv -U flash:w:[HEXFILE] 2>[LOGFILE]
      • +
      • default for radinoCC1101: avrdude -c avr109 -b [BAUDRATE] -P [PORT] -p atmega32u4 -vv -D -U flash:w:[HEXFILE] 2>[LOGFILE]
      • +
      + It contains some place-holders that automatically get filled with the according values:
      +
        +
      • [BAUDRATE]
        + is the speed (e.g. 57600) +
      • +
      • [PORT]
        + is the port the Signalduino is connectd to (e.g. /dev/ttyUSB0) and will be used from the defenition +
      • +
      • [HEXFILE]
        + is the .hex file that shall get flashed. There are three options (applied in this order):
        + - passed in set flash as first argument
        + - taken from the hexFile attribute
        + - the default value defined in the module
        +
      • +
      • [LOGFILE]
        + The logfile that collects information about the flash process. It gets displayed in FHEM after finishing the flash process +
      • +

      + note: ! Sometimes there can be problems flashing radino on Linux. Here in the wiki under the point "radino & Linux" is a patch! +

    • + +
    • hardware
      + Currently, there are serval hardware options with different receiver options available. + The simple single wire option, consists of a single wire connected receiver and a single wire connected transmitter which are connected over a single digital port with the microcontroller. The receiver only sends data and the transmitter receives only from the microcontroller. + The other option consists of the cc1101 (sub 1 GHZ) chip, which can transmit and receiver. It's a transceiver which is connected via spi. + ESP8266 hardware type, currently doesn't support flashing out of the modu and needs at leat 1 MB of flash. +
        +
      • ESP32: ESP32 with simple single wire receiver
      • +
      • ESP32cc1101: ESP32 with CC1101 (spi connected) receiver
      • +
      • ESP8266: ESP8266 with simple single wire receiver
      • +
      • ESP8266cc1101: ESP8266 with CC1101 (spi connected) receiver
      • +
      • MAPLEMINI_F103CB: MapleMini F103CB (STM32 family) with simple single wire receiver
      • +
      • MAPLEMINI_F103CBcc1101: MapleMini F103CB (STM32 family) with CC1101 (spi connected) receiver
      • +
      • miniculCC1101: Arduino pro Mini with CC110x (spi connected) receiver and cables as a minicul
      • +
      • nano: Arduino Nano 328 with simple single wired receiver
      • +
      • nanoCC1101: Arduino Nano 328 with CC110x (spi connected) receiver
      • +
      • promini: Arduino Pro Mini 328 with simple single receiver
      • +
      • radinoCC1101: Arduino compatible radino with cc1101 (spi connected) receiver
      • +
      +

    • + +
    • longids
      + Comma separated list of device-types for SIGNALduino that should be handled using long IDs. This additional ID allows it to differentiate some weather sensors, if they are sending on the same channel. Therfor a random generated id is added. If you choose to use longids, then you'll have to define a different device after battery change.
      + Default is to not to use long IDs for all devices. +

      + Examples:
      +      # Do not use any long IDs for any devices:
      +      attr sduino longids 0
      +      # Use any long IDs for all devices (this is default):
      +      attr sduino longids 1
      +      # Use longids for BTHR918N devices.
      +      # Will generate devices names like BTHR918N_f3.
      +      attr sduino longids BTHR918N
      +    
      +
    • + +
    • maxMuMsgRepeat
      + MU signals can contain multiple repeats of the same message. The results are all send to a logical module. You can limit the number of scanned repetitions. Defaukt is 4, so after found 4 repeats, the demoduation is aborted. +

    • + +
    • minsecs
      This is a very special attribute. It is provided to other modules. minsecs should act like a threshold. All logic must be done in the logical module. If specified, then supported modules will discard new messages if minsecs isn't past. -

    • - -
    • noMsgVerbose
      +

    • + +
    • noMsgVerbose
      With this attribute you can control the logging of debug messages from the io device. If set to 3, this messages are logged if global verbose is set to 3 or higher. -

    • - -
    • longids
      - Comma separated list of device-types for SIGNALduino that should be handled using long IDs. This additional ID allows it to differentiate some weather sensors, if they are sending on the same channel. Therfor a random generated id is added. If you choose to use longids, then you'll have to define a different device after battery change.
      - Default is to not to use long IDs for all devices. -

      - Examples:
      -# Do not use any long IDs for any devices:
      -attr sduino longids 0
      -# Use any long IDs for all devices (this is default):
      -attr sduino longids 1
      -# Use longids for BTHR918N devices.
      -# Will generate devices names like BTHR918N_f3.
      -attr sduino longids BTHR918N
      -
    • - -
    • rawmsgEvent
      -When set to "1" received raw messages triggers events -

    • - -
    • suppressDeviceRawmsg
      -When set to 1, the internal "RAWMSG" will not be updated with the received messages -

    • - -
    • updateChannelFW
      - The module can search for new firmware versions (SIGNALDuino and SIGNALESP). Depending on your choice, only stable versions are displayed or also prereleases are available for flash. The option testing does also provide the stable ones. -
        -
      • stable: only versions marked as stable are available. These releases are provided very infrequently
      • -
      • testing: These versions needs some verifications and are provided in shorter intervals
      • -
      -
      Reload the available Firmware via get availableFirmware manually. -

    • - -
    • whitelist_IDs
      - This attribute allows it, to specify whichs protocos are considured from this module. Protocols which are not considured, will not generate logmessages or events. They are then completly ignored. This makes it possible to lower ressource usage and give some better clearnes in the logs. You can specify multiple whitelistIDs wih a colon : 0,3,7,12
      With a # at the beginnging whitelistIDs can be deactivated. -
      - Not using this attribute or deactivate it, will process all stable protocol entrys. Protocols which are under development, must be activated explicit via this Attribute. -

    • - -
    • WS09_CRCAUS
      -
        -
      • 0: CRC-Check WH1080 CRC = 0 on, default
      • -
      • 2: CRC = 49 (x031) WH1080, set OK
      • -
      -
    • -
    - - Information menu -
      - -
    • Display protocollist
      - Shows the current implemented protocols from the SIGNALduino and to what logical FHEM Modul data is sent.
      - Additional there is an checkbox symbol, which shows you if a protocol will be processed. This changes the Attribute whitlistIDs for you in the background. The attributes whitelistIDs and blacklistIDs affects this state. - Protocols which are flagged in the row dev, are under development -
        -
      • If a row is flagged via 'm', then the logical module which provides you with an interface is still under development. Per default, these protocols will not send data to logcial module. To allow communication to a logical module you have to enable the protocol.
      • -
      • If a row is flagged via 'p', then this protocol entry is reserved or in early development state.
      • -
      • If a row is flalged via 'y' then this protocol isn't fully tested or reviewed.
      • -
      -
      - If you are using blacklistIDs, then you also can not activate them via the button, delete the attribute blacklistIDs if you want to control enabled protocols via this menu. -

    • -
    +

  • + +
  • rawmsgEvent
    + When set to "1" received raw messages triggers events +

  • + +
  • rfmode
    + Configures the RF transceiver of the SIGNALduino (CC1101). The available arguments: +
      +
    • Avantek
      + Modulation 2-FSK, Datarate=50.087 kbps, Sync Word=0869, FIFO-THR=8 Byte, Frequency 433.3 MHz +
        Example: AVANTEK Wireless Digital Door Bell
      +
    • +
    • Bresser_5in1
      + Modulation 2-FSK, Datarate=8.23 kbps, Sync Word=2DD4, Packet Length=26 Byte, Frequency 868.35 MHz +
        Example: BRESSER 5-in-1 weather center, BRESSER rain gauge, Fody E42, Fody E43
      +
    • +
    • Bresser_6in1
      + modulation 2-FSK, Datarate=8.23 kbps, Sync Word=2DD4, FIFO-THR=20 Byte, frequency 868.35 MHz +
    • +
    • Fine_Offset_WH51_434
      + Modulation 2-FSK, Datarate=17.26 kbps, Sync Word=2DD4, Packet Length=14 Byte, Frequency 433.92 MHz +
        Example: Soil moisture sensor Fine Offset WH51, ECOWITT WH51, MISOL/1, Froggit DP100
      +
    • +
    • Fine_Offset_WH51_868
      + Modulation 2-FSK, Datarate=17.26 kbps, Sync Word=2DD4, Packet Length=14 Byte, Frequency 868.35 MHz +
        Example: Soil moisture sensor Fine Offset WH51, ECOWITT WH51, MISOL/1, Froggit DP100
      +
    • +
    • Fine_Offset_WH57_434
      + Modulation 2-FSK, Datarate=17.26 kbps, Sync Word=2DD4, Packet Length=9 Byte, Frequency 433.92 MHz +
        Example: Thunder and lightning sensor Fine Offset WH57, Froggit DP60, Ambient Weather WH31L
      +
    • +
    • Fine_Offset_WH57_868
      + Modulation 2-FSK, Datarate=17.26 kbps, Sync Word=2DD4, Packet Length= Byte, Frequency 868.35 MHz +
        Example: Thunder and lightning sensor Fine Offset WH57, Froggit DP60, Ambient Weather WH31L
      +
    • +
    • KOPP_FC
      + modulation GFSK, Datarate=4.7855 kbps, Sync Word=AA54, frequency 868.3MHz +
    • +
    • Lacrosse_mode1
      + modulation 2-FSK, Datarate=17.25769 kbps, Sync Word=2DD4, frequency 868.3MHz
      +
        example: TX25-IT, TX27-IT, TX29-IT, TX29DTH-IT, TX37, 30.3143.IT, 30.3144.IT
      +
    • +
    • Lacrosse_mode2
      + modulation 2-FSK, Datarate=9.579 kbps, Sync Word=2DD4, frequency 868.3MHz
      +
        example: TX35TH-IT, TX35DTH-IT, TX38-IT, 30.3155WD, 30.3156WD
      +
    • +
    • PCA301
      + modulation 2-FSK, Datarate=6.62041 kbps, Sync Word=2DD4, frequency 868.950 MHz +
    • +
    • Rojaflex
      + modulation GFSK, Datarate=9.99 kbps, Sync Word=D391D391, frequency 433.920 MHz +
    • +
    • SlowRF
      + modulation ASK/OOK, loads the standard setting from the uC +
    • +
    +

  • + +
  • suppressDeviceRawmsg
    + When set to 1, the internal "RAWMSG" will not be updated with the received messages +

  • + +
  • updateChannelFW
    + The module can search for new firmware versions (SIGNALDuino and SIGNALESP). Depending on your choice, only stable versions are displayed or also prereleases are available for flash. The option testing does also provide the stable ones. +
      +
    • stable: only versions marked as stable are available. These releases are provided very infrequently
    • +
    • testing: These versions needs some verifications and are provided in shorter intervals
    • +
    +
    Reload the available Firmware via get availableFirmware manually. +

  • + +
  • whitelist_IDs
    + This attribute allows it, to specify whichs protocos are considured from this module. Protocols which are not considured, will not generate logmessages or events. They are then completly ignored. This makes it possible to lower ressource usage and give some better clearnes in the logs. You can specify multiple whitelistIDs wih a colon : 0,3,7,12
    With a # at the beginnging whitelistIDs can be deactivated. +
    + Not using this attribute or deactivate it, will process all stable protocol entrys. Protocols which are under development, must be activated explicit via this Attribute. +

  • + +
  • WS09_CRCAUS
    +
      +
    • 0: CRC-Check WH1080 CRC = 0 on, default
    • +
    • 2: CRC = 49 (x031) WH1080, set OK
    • +
    +

  • + +
  • MatchList
    + This attribute adds additional items to the module matchlist. Items has to be described in a PERL Hash format: +
      +
    • Format: { 'number:module' => 'protocol-pattern' , 'nextNumber:nextModule' => 'protocol-pattern' , ... }
    • +
    • Example: { '34:MyModule' => '^u98#.{8}' , '35:MyModule2' => '^u99#.{10}' }
    • +
    +

  • +
+ + + +Information menu +
    + +
  • Display protocollist
    + Shows the current implemented protocols from the SIGNALduino and to what logical FHEM Modul data is sent.
    + Additional there is an checkbox symbol, which shows you if a protocol will be processed. This changes the Attribute whitlistIDs for you in the background. The attributes whitelistIDs and blacklistIDs affects this state. + Protocols which are flagged in the row dev, are under development +
      +
    • If a row is flagged via 'm', then the logical module which provides you with an interface is still under development. Per default, these protocols will not send data to logcial module. To allow communication to a logical module you have to enable the protocol. +
    • +
    • If a row is flagged via 'p', then this protocol entry is reserved or in early development state.
    • +
    • If a row is flalged via 'y' then this protocol isn't fully tested or reviewed.
    • +
    +
    + If you are using blacklistIDs, then you also can not activate them via the button, delete the attribute blacklistIDs if you want to control enabled protocols via this menu. +

  • +
=end html =begin html_DE @@ -5202,561 +4883,699 @@ When set to 1, the internal "RAWMSG" will not be updated with the received messa

SIGNALduino

- - - -
- Der SIGNALduino ist basierend auf einer Idee von "mdorenka" und veröffentlicht im FHEM Forum.
- - Mit der OpenSource-Firmware (SIGNALDuino und SIGNALESP) ist dieser fähig zum Empfangen und Senden verschiedener Protokolle auf 433 und 868 Mhz. -

- Folgende Geräte werden zur Zeit unterstützt: -

- Funk-Schalter
-
    -
  • ITv1 & ITv3/Elro und andere Marken mit dem pt2263-Chip oder welche das arctech Protokoll nutzen --> IT.pm
    Das ITv1 Protokoll benutzt einen Standard ITclock von 250 und es kann vorkommen, das in dem IT-Modul das Attribut "ITclock" zu setzen ist.
  • -
  • ELV FS10 -> 10_FS10
  • -
  • ELV FS20 -> 10_FS20
  • -
- Temperatur-, Luftfeuchtigkeits-, Luftdruck-, Helligkeits-, Regen- und Windsensoren: -
    -
  • PEARL NC7159, LogiLink WS0002,GT-WT-02,AURIOL,TCM97001, TCM27 und viele anderen -> 14_CUL_TCM97001.pm
  • -
  • Oregon Scientific v2 und v3 Sensoren -> 41_OREGON.pm
  • -
  • Temperatur / Feuchtigkeits Sensoren unterstützt -> 14_SD_WS07.pm
  • -
  • technoline WS 6750 und TX70DTH -> 14_SD_WS07.pm
  • -
  • Eurochon EAS 800z -> 14_SD_WS07.pm
  • -
  • CTW600, WH1080 -> 14_SD_WS09.pm
  • -
  • Hama TS33C, Bresser Thermo/Hygro Sensoren -> 14_Hideki.pm
  • -
  • FreeTec Aussenmodul NC-7344 -> 14_SD_WS07.pm
  • -
  • La Crosse WS-7035, WS-7053, WS-7054 -> 14_CUL_TX
  • -
  • ELV WS-2000, La Crosse WS-7000 -> 14_CUL_WS
  • -
-
- Es ist möglich, mehr als ein Gerät anzuschließen, um beispielsweise besseren Empfang zu erhalten. FHEM wird doppelte Nachrichten herausfiltern. - Mehr dazu im dem global Abschnitt unter dem Attribut dupTimeout

- Hinweis: Dieses Modul erfordert das Device::SerialPort oder Win32::SerialPort - Modul. Es kann derzeit nur über USB angeschlossen werden. -
-
- - Define - define <name> SIGNALduino <device> - USB-connected devices (SIGNALduino):
-
  • - <device> spezifiziert den seriellen Port für die Kommunikation mit dem SIGNALduino. - Der Name des seriellen Geräts hängt von Ihrer Distribution ab. In Linux ist das cdc_acm Kernel_Modul dafür verantwortlich und es wird ein /dev/ttyACM0 oder /dev/ttyUSB0 Gerät angelegt. Wenn deine Distribution kein cdc_acm Module besitzt, kannst du usbserial nutzen um den SIGNALduino zu betreiben mit folgenden Kommandos: -
      -
    • modprobe usbserial
    • -
    • vendor=0x03eb
    • -
    • product=0x204b
    • -
    - In diesem Fall ist das Gerät höchstwahrscheinlich /dev/ttyUSB0.

    - - Sie können auch eine Baudrate angeben, wenn der Gerätename das @ enthält, Beispiel: /dev/ttyACM0@57600
    Dies ist auch die Standard-Baudrate.

    - Es wird empfohlen, das Gerät über einen Namen anzugeben, der sich nicht ändert. Beispiel via by-id devicename: /dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0@57600
    - Wenn die Baudrate "directio" (Bsp: /dev/ttyACM0@directio), dann benutzt das Perl Modul nicht Device::SerialPort und FHEM öffnet das Gerät mit einem file io. Dies kann funktionieren, wenn das Betriebssystem die Standardwerte für die seriellen Parameter verwendet. Bsp: einige Linux Distributionen und - OSX.

    -
  • -
- - - Internals -
    -
  • IDsNoDispatch: Hier werden Protokolleinträge mit ihrer numerischen ID aufgelistet, für welche keine Weitergabe von Daten an logische Module aktiviert wurde. Um die Weitergabe zu aktivieren, kann die Menüoption Display protocollist verwendet werden.
  • -
  • LASTDMSGID: Hier wird die zuletzt dispatchte Protocol ID angezeigt.
  • -
  • NR_CMD_LAST_H: Anzahl der gesendeten Nachrichten innerhalb der letzten Stunde.
  • -
  • RAWMSG: zuletzt empfangene RAWMSG
  • -
  • cc1101_available: Wenn ein CC1101 erkannt wurde, so wird dieses Internal angezeigt mit dem Wert 1.
  • -
  • version: Hier wird die Version des SIGNALduino microcontrollers angezeigt.
  • -
  • versionProtocols: Hier wird die Version der SIGNALduino Protokolldatei angezeigt.
  • -
  • versionmodule: Hier wird die Version des SIGNALduino FHEM Modules selbst angezeigt.
  • -
+ + + +
+ Der SIGNALduino ist basierend auf einer Idee von "mdorenka" und veröffentlicht im FHEM Forum.
+ Mit der OpenSource-Firmware (SIGNALDuino und SIGNALESP) ist dieser fähig zum Empfangen und Senden verschiedener Protokolle auf 433 und 868 Mhz. +

+ Folgende Geräte werden zur Zeit unterstützt: +

+ Funk-Schalter
+
    +
  • ITv1 & ITv3/Elro und andere Marken mit dem pt2263-Chip oder welche das arctech Protokoll nutzen --> IT.pm
    Das ITv1 Protokoll benutzt einen Standard ITclock von 250 und es kann vorkommen, das in dem IT-Modul das Attribut "ITclock" zu setzen ist. +
  • +
  • ELV FS10 -> 10_FS10 +
  • +
  • ELV FS20 -> 10_FS20 +
  • +
+ Temperatur-, Luftfeuchtigkeits-, Luftdruck-, Helligkeits-, Regen- und Windsensoren +
    +
  • CTW600, WH1080 -> 14_SD_WS09.pm
  • +
  • ELV WS-2000, La Crosse WS-7000 -> 14_CUL_WS
  • +
  • Eurochon EAS 800z -> 14_SD_WS07.pm
  • +
  • FreeTec Aussenmodul NC-7344 -> 14_SD_WS07.pm
  • +
  • Hama TS33C, Bresser Thermo/Hygro Sensoren -> 14_Hideki.pm
  • +
  • La Crosse WS-7035, WS-7053, WS-7054 -> 14_CUL_TX
  • +
  • Oregon Scientific v2 und v3 Sensoren -> 41_OREGON.pm
  • +
  • PEARL NC7159, LogiLink WS0002,GT-WT-02,AURIOL,TCM97001, TCM27 und viele anderen -> 14_CUL_TCM97001.pm
  • +
  • Temperatur / Feuchtigkeits Sensoren unterstützt -> 14_SD_WS07.pm
  • +
  • technoline WS 6750 und TX70DTH -> 14_SD_WS07.pm
  • +
+
+ Es ist möglich, mehr als ein Gerät anzuschließen, um beispielsweise besseren Empfang zu erhalten. FHEM wird doppelte Nachrichten herausfiltern. + Mehr dazu im dem global Abschnitt unter dem Attribut dupTimeout

+ Hinweis: Dieses Modul erfordert das Device::SerialPort oder Win32::SerialPort + Modul. Es kann derzeit nur über USB angeschlossen werden. +
+
- - SET -
    -
  • cc1101_freq / cc1101_bWidth / cc1101_patable / cc1101_rAmpl / cc1101_sens / register
    - (NUR bei Verwendung eines cc110x Funk-Moduls)

    - Stellt die SIGNALduino-Frequenz / Bandbreite / PA-Tabelle / Empfänger-Amplitude / Empfindlichkeit ein.
    - Verwenden Sie es mit Vorsicht. Es kann Ihre Hardware zerstören und es kann sogar illegal sein, dies zu tun.
    - Hinweis: Die für die RFR-Übertragung verwendeten Parameter sind nicht betroffen.
  • -
      - -
    • cc1101_freq , legt sowohl die Empfangsfrequenz als auch die Übertragungsfrequenz fest.
      - Hinweis: Obwohl der CC1101 auf Frequenzen zwischen 315 und 915 MHz eingestellt werden kann, ist die Antennenschnittstelle und die Antenne auf genau eine Frequenz abgestimmt. Standard ist 433.920 MHz (oder 868.350 MHz). Wenn keine Frequenz angegeben wird, dann wird die Frequenz aus dem Attribut cc1101_frequency geholt.
    • - -
    • cc1101_bWidth , kann auf Werte zwischen 58 kHz und 812 kHz eingestellt werden. Große Werte sind störanfällig, ermöglichen jedoch den Empfang von ungenau kalibrierten Sendern. Es wirkt sich auch auf die Übertragung aus. Standard ist 325 kHz.
    • - -
    • cc1101_patable , Änderung der PA-Tabelle (Leistungsverstärkung für HF-Senden)
    • - -
    • cc1101_rAmpl , ist die Empfängerverstärkung mit Werten zwischen 24 und 42 dB. Größere Werte erlauben den Empfang schwacher Signale. Der Standardwert ist 42.
    • - -
    • cc1101_sens , ist die Entscheidungsgrenze zwischen den Ein- und Aus-Werten und beträgt 4, 8, 12 oder 16 dB. Kleinere Werte erlauben den Empfang von weniger klaren Signalen. Standard ist 4 dB.
    • - -
    • cc1101_reg Es können mehre Register auf einmal gesetzt werden. Das Register wird über seinen zweistelligen Hexadezimalwert angegeben, gefolgt von einem zweistelligen Wert. Mehrere Register werden via Leerzeichen getrennt angegeben
    • -
    -
    - -
  • close
    - Beendet die Verbindung zum Gerät.

  • - -
  • enableMessagetype
    - Ermöglicht die Aktivierung der Nachrichtenverarbeitung für -
      -
    • Nachrichten mit sync (syncedMS),
    • -
    • Nachrichten ohne einen sync pulse (unsyncedMU)
    • -
    • Manchester codierte Nachrichten (manchesterMC)
    • -
    - Der neue Status wird in den eeprom vom Arduino geschrieben. -

  • - -
  • disableMessagetype
    - Ermöglicht das Deaktivieren der Nachrichtenverarbeitung für -
      -
    • Nachrichten mit sync (syncedMS)
    • -
    • Nachrichten ohne einen sync pulse (unsyncedMU)
    • -
    • Manchester codierte Nachrichten (manchesterMC)
    • -
    - Der neue Status wird in den eeprom vom Arduino geschrieben. -

  • - -
  • flash [hexFile|url]
    - Der SIGNALduino benötigt die richtige Firmware, um die Sensordaten zu empfangen und zu liefern. Unter Verwendung der Arduino IDE zum Flashen der Firmware in den SIGNALduino bietet dies eine Möglichkeit, ihn direkt von FHEM aus zu flashen. Sie können eine Datei auf Ihrem fhem-Server angeben oder eine URL angeben, von der die Firmware heruntergeladen wird. Es gibt einige Anforderungen: -
      -
    • avrdude muss auf dem Host installiert sein. Auf einem Raspberry PI kann dies getan werden mit: sudo apt-get install avrdude
    • -
    • Das Hardware-Attribut muss festgelegt werden, wenn eine andere Hardware als Arduino Nano verwendet wird. Dieses Attribut definiert den Befehl, der an avrdude gesendet wird, um den uC zu flashen.
    • -
    • Bei Problem mit dem Flashen, können im Logfile interessante Informationen zu finden sein.
    • -
    - Beispiele: -
      -
    • flash mittels Versionsnummer: Versionen können mit get availableFirmware abgerufen werden
    • -
    • flash via hexFile: set sduino flash ./FHEM/firmware/SIGNALduino_mega2560.hex
    • -
    • flash via url für einen Nano mit CC1101: set sduino flash https://github.com/RFD-FHEM/SIGNALDuino/releases/download/3.3.1-RC7/SIGNALDuino_nanocc1101.hex
    • -
    - Hinweise Modell radino: -
      -
    • Teilweise kann es beim flashen vom radino unter Linux Probleme geben. Hier im Wiki unter dem Punkt "radino & Linux" gibt es einen Patch!
    • -
    • Wenn der Radino in dieser Art /dev/ttyACM0 definiert wurde, sollte das Flashen der Firmware automatisch erfolgen. Wenn das nicht gelingt, muss der Bootloader manuell aktiviert werden:
    • -
    • Um den Bootloader vom radino manuell zu aktivieren gibt es 2 Varianten. -
        -
      • 1) Module welche einen BSL-Button besitzen: -
          -
        • Spannung anlegen
        • -
        • druecke & halte BSL- und RESET-Button
        • -
        • RESET-Button loslassen und danach den BSL-Button loslassen
        • -
        • (Wiederholen Sie diese Schritte, wenn Ihr radino nicht sofort in den Bootloader-Modus wechselt.)
        • -
        -
      • -
      • 2) Bootloader erzwingen: -
          -
        • durch zweimaliges druecken der Reset-Taste
        • -
        -
      • -
      - Im Bootloader-Modus erhält der radino eine andere USB ID. Diese muss im Attribut "flashCommand" eingetragen werden.
      - Wenn der Bootloader aktiviert ist, signalisiert er das mit dem Blinken einer LED. Dann hat man ca. 8 Sekunden Zeit zum flashen. -
    • -
    -

  • - -
  • raw
    - Geben Sie einen SIGNALduino-Firmware-Befehl aus, ohne auf die vom SIGNALduino zurückgegebenen Daten zu warten. Ausführliche Informationen zu SIGNALduino-Befehlen finden Sie im SIGNALduino-Firmware-Code. Mit dieser Linie können Sie fast jedes Signal über einen angeschlossenen Sender senden.
    - Um einige Rohdaten zu senden, schauen Sie sich diese Beispiele an: P#binarydata#R#C (#C is optional) -
      -
    • Beispiel 1: set sduino raw SR;R=3;P0=500;P1=-9000;P2=-4000;P3=-2000;D=0302030 , sendet die Daten im Raw-Modus dreimal wiederholt
    • -
    • Beispiel 2: set sduino raw SM;R=3;P0=500;C=250;D=A4F7FDDE , sendet die Daten Manchester codiert mit einem clock von 250µS
    • -
    • Beispiel 3: set sduino raw SC;R=3;SR;P0=5000;SM;P0=500;C=250;D=A4F7FDDE , sendet eine kombinierte Nachricht von Raw und Manchester codiert 3 mal wiederholt
    • -

    -
      - Hinweis: Die falsche Benutzung der kommenden Optionen kann zu Fehlfunktionen des SIGNALduinos führen!

      - NUR für DEBUG Nutzung | Befehle sind abhänging vom Firmwarestand!
      -
    • CED -> Debugausgaben ein
    • -
    • CDD -> Debugausgaben aus
    • -
    • CDL -> LED aus
    • -
    • CEL -> LED ein
    • -
    • CER -> Einschalten der Datenkomprimierung (config: Mred=1)
    • -
    • CDR -> Abschalten der Datenkomprimierung (config: Mred=0)
    • -
    • CSmscnt=[Wert] -> Wiederholungszaehler fuer den split von MS Nachrichten
    • -
    • CSmuthresh=[Wert] -> Schwellwert fuer den split von MU Nachrichten (0=aus)
    • -
    • CSmcmbl=[Wert] -> minbitlen fuer MC-Nachrichten
    • -
    • CSfifolimit=[Wert] -> Schwellwert fuer debug Ausgabe der Pulsanzahl im FIFO Puffer
    • -

      - Register Befehle bei einem CC1101
      -
    • e -> Werkseinstellungen
    • -
    • W -> schreibt einen Wert ins EEPROM und ins CC1101 Register
      -          Hinweis: Die EEPROM Adresse hat einen Offset von 2. z.Bsp: set sduino raw W041D schreibt 1D ins Register 0x02 -
    • -

    -
  • - -
  • reset
    - Öffnet die Verbindung zum Gerät neu und initialisiert es.

  • - -
  • sendMsg
    - Dieser Befehl erstellt die erforderlichen Anweisungen zum Senden von Rohdaten über den SIGNALduino. Sie können die Signaldaten wie Protokoll und die Bits angeben, die Sie senden möchten.
    - Alternativ ist es auch moeglich, die zu sendenden Daten in hexadezimaler Form zu uebergeben. Dazu muss ein 0x vor den Datenteil geschrieben werden. -

    - Bitte beachte, dieses Kommando funktioniert nur fuer MU oder MS Protokolle nach dieser Vorgehensweise: -

    - Argumente sind: -

    -

      -
    • P#binarydata#R#C (#C is optional) -
      Beispiel binarydata: set sduino sendMsg P0#0101#R3#C500 -
      Wird eine sende Kommando fuer die Bitfolge 0101 anhand der protocol id 0 erzeugen. Als Takt wird 500 verwendet. -
      SR;R=3;P0=500;P1=-9000;P2=-4000;P3=-2000;D=03020302;

    -
    • P#0xhexdata#R#C (#C is optional) -
      Beispiel 0xhexdata: set sduino sendMsg P29#0xF7E#R4 -
      Wird eine sende Kommando fuer die Hexfolge F7E anhand der protocol id 29 erzeugen. Die Nachricht soll 4x gesendet werden. -
      SR;R=4;P0=-8360;P1=220;P2=-440;P3=-220;P4=440;D=01212121213421212121212134;

    -
    • P#0xhexdata#R#C#F (#C #F is optional) -
      Beispiel 0xhexdata: set sduino sendMsg P36#0xF7#R6#Fxxxxxxxxxx (xxxxxxxxxx = Registerwert des CC1101) -
      Wird eine sende Kommando fuer die Hexfolge F7 anhand der protocol id 36 erzeugen. Die Nachricht soll 6x gesendet werden mit der angegebenen Frequenz. -
      SR;R=6;P0=-8360;P1=220;P2=-440;P3=-220;P4=440;D=012323232324232323;F= (Registerwert des CC1101);
    -

  • -
- -
+ +Define +
    define <name> SIGNALduino <device>
+USB-connected devices (SIGNALduino):
+
    +
  • <device> spezifiziert den seriellen Port für die Kommunikation mit dem SIGNALduino. + Der Name des seriellen Geräts hängt von Ihrer Distribution ab. In Linux ist das cdc_acm Kernel_Modul dafür verantwortlich und es wird ein /dev/ttyACM0 oder /dev/ttyUSB0 Gerät angelegt. Wenn deine Distribution kein cdc_acm Module besitzt, kannst du usbserial nutzen um den SIGNALduino zu betreiben mit folgenden Kommandos: +
      +
    • modprobe usbserial
    • +
    • vendor=0x03eb
    • +
    • product=0x204b
    • +
    + In diesem Fall ist das Gerät höchstwahrscheinlich /dev/ttyUSB0.

    - - Get -
      - -
    • availableFirmware
      - Ruft die verfügbaren Firmware-Versionen von Github ab und macht diese im set flash Befehl auswählbar. -

    • - -
    • ccconf
      - Liest sämtliche radio-chip (cc1101) Register (Frequenz, Bandbreite, etc.) aus und zeigt die aktuelle Konfiguration an.
      - (NUR bei Verwendung eines cc1101 Empfänger) -

    • - -
    • ccpatable
      - Liest die cc1101 PA Tabelle aus (power amplification for RF sending).
      - (NUR bei Verwendung eines cc1101 Empfänger) -

    • - -
    • ccreg
      - Liest das cc1101 Register aus (99 liest alle aus).
      - (NUR bei Verwendung eines cc1101 Empfänger) -

    • - -
    • close
      - Beendet die Verbindung zum SIGNALduino. -

    • - -
    • cmds
      - Abhängig von der installierten Firmware besitzt der SIGNALduino verschiedene Befehle. Bitte beachten Sie den Quellcode der Firmware Ihres SIGNALduino, um die Antwort dieses Befehls zu interpretieren. -

    • - -
    • config
      - Zeigt Ihnen die aktuelle Konfiguration der SIGNALduino Protokollkathegorie an. | Bsp: MS=1;MU=1;MC=1;Mred=0 -

    • - -
    • freeram
      - Zeigt den freien RAM an. -

    • - -
    • ping
      - Prüft die Kommunikation mit dem SIGNALduino. -

    • - -
    • raw
      - Nur um Nachrichten (MS, MC, MU, ...) manuell verarbeiten zu können. Der get raw Befehl übergibt keine Kommandos an den verbundenen Microcontroller! -

    • - -
    • uptime
      - Zeigt Ihnen die Information an, wie lange der SIGNALduino läuft. Ein FHEM Neustart setzt den Timer zurück. -

    • - -
    • version
      - Zeigt Ihnen die Information an, welche aktuell genutzte Software Sie mit dem SIGNALduino verwenden. -

    • -
    + Sie können auch eine Baudrate angeben, wenn der Gerätename das @ enthält, Beispiel: /dev/ttyACM0@57600
    Dies ist auch die Standard-Baudrate.

    + Es wird empfohlen, das Gerät über einen Namen anzugeben, der sich nicht ändert. Beispiel via by-id devicename: /dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0@57600
    + Wenn die Baudrate "directio" (Bsp: /dev/ttyACM0@directio), dann benutzt das Perl Modul nicht Device::SerialPort und FHEM öffnet das Gerät mit einem file io. Dies kann funktionieren, wenn das Betriebssystem die Standardwerte für die seriellen Parameter verwendet. Bsp: einige Linux Distributionen und + OSX.

    +
  • +
- - Attributes -
    - -
  • addvaltrigger
    - Generiert Trigger für zusätzliche Werte. Momentan werden DMSG, ID, RAWMSG und RSSI unterstüzt. -

  • - -
  • blacklist_IDs
    - Dies ist eine durch Komma getrennte Liste. Die Blacklist funktioniert nur, wenn keine Whitelist existiert! Hier kann man ID´s eintragen welche man nicht ausgewertet haben möchte. -

  • - -
  • cc1101_frequency
    - Legt die Frequenz des SIGNALduino fest. Standard is 433 Mhz.
    - Da die Werte für PA Werte Frequenzabhängig sind, wird für das Setzen der Register die hier hinterlegte Frequenz verwendet. -

  • - -
  • debug
    - Dies bringt das Modul in eine sehr ausführliche Debug-Ausgabe im Logfile. Somit lassen sich neue Signale finden und Signale überprüfen, ob die Demodulation korrekt funktioniert. -

  • - -
  • development
    - Das development Attribut ist nur in den Entwicklungsversionen des FHEM Modules aus Grüden der Abwärtskompatibilität vorhanden. Bei Setzen des Attributes auf "1" werden alle Protokolle aktiviert, welche mittels developID=y markiert sind. -
    - Wird das Attribut auf 1 gesetzt, so werden alle in Protokolle die mit dem developID Flag "y" markiert sind aktiviert. Die Flags (Spalte dev) können über das Webfrontend im Abschnitt "Information menu" mittels "Display protocollist" eingesehen werden. -
  • -
    -
  • do_not_notify

  • - -
  • doubleMsgCheck_IDs
    - Dieses Attribut erlaubt es, Protokolle anzugeben, die zwei gleiche Nachrichten enthalten müssen, um diese an die Module zu übergeben. Sie können mehrere IDs mit einem Komma angeben: 0,3,7,12 -

  • -
  • dummy

  • - -
  • flashCommand
    - Dies ist der Befehl, der ausgeführt wird, um den Firmware-Flash auszuführen. Nutzen Sie dies nicht, wenn Sie nicht wissen, was Sie tun!
    - Wurde das Attribut nicht definiert, so verwendet es die Standardeinstellungen.
    Sobald der User das Attribut manuell definiert, nutzt das System diese Vorgaben!
    -
      -
    • Standard nano, nanoCC1101, miniculCC1101, promini:
      avrdude -c arduino -b [BAUDRATE] -P [PORT] -p atmega328p -vv -U flash:w:[HEXFILE] 2>[LOGFILE]
    • -
    • Standard radinoCC1101:
      avrdude -c avr109 -b [BAUDRATE] -P [PORT] -p atmega32u4 -vv -D -U flash:w:[HEXFILE] 2>[LOGFILE]
    • -
    - Es enthält einige Platzhalter, die automatisch mit den entsprechenden Werten gefüllt werden: -
      -
    • [BAUDRATE]
      - Ist die Schrittgeschwindigkeit. (z.Bsp: 57600)
    • -
    • [PORT]
      - Ist der Port, an dem der SIGNALduino angeschlossen ist (z.Bsp: /dev/ttyUSB0) und wird von der Definition verwendet.
    • -
    • [HEXFILE]
      - Ist die .hex-Datei, die geflasht werden soll. Es gibt drei Optionen (angewendet in dieser Reihenfolge):
      -
        -
      • in set SIGNALduino flash als erstes Argument übergeben
      • -
      • aus dem Hardware-Attribut genommen
      • -
      • der im Modul definierte Standardwert
      • -
      -
    • -
    • [LOGFILE]
      - Die Logdatei, die Informationen über den Flash-Prozess sammelt. Es wird nach Abschluss des Flash-Prozesses in FHEM angezeigt
    • -

    - Hinweis: ! Teilweise kann es beim Flashen vom radino unter Linux Probleme geben. Hier im Wiki unter dem Punkt "radino & Linux" gibt es einen Patch! -

  • - -
  • hardware
    - Derzeit mögliche Hardware Varianten mit verschiedenen Empfänger Optionen. - Die einfache Variante besteht aus einem Empfänger und einen Sender, die über je eine einzige digitale Signalleitung Datem mit dem Microcontroller austauschen. Der Empfänger sendet dabei und der Sender empfängt dabei ausschließlich. - Weiterhin existiert der den sogenannten cc1101 (sub 1 GHZ) Chip, welche empfangen und senden kann. Dieser wird über die SPI Verbindung angebunden. - ESP8266 Hardware Typen, unterstützen derzeit kein flashen aus dem Modul und benötigen mindestens 1 MB Flash Speicher. -
      -
    • ESP32: ESP32
    • -
    • ESP8266: ESP8266 für einfachen eindraht Empfänger
    • -
    • ESP8266cc1101: ESP8266 mit einem CC110x-Empfänger (SPI Verbindung)
    • -
    • miniculCC1101: Arduino pro Mini mit einem CC110x-Empfänger (SPI Verbindung) entsprechend dem minicul verkabelt
    • -
    • nano: Arduino Nano 328 für einfachen eindraht Empfänger
    • -
    • nanoCC1101: Arduino Nano für einen CC110x-Empfänger (SPI Verbindung)
    • -
    • promini: Arduino Pro Mini 328 für einfachen eindraht Empfänger
    • -
    • radinoCC1101: Ein Arduino Kompatibler Radino mit cc1101 Empfänger (SPI Verbindung)
    • -

    - Notwendig für den Befehl flash. Hier sollten Sie angeben, welche Hardware Sie mit dem usbport verbunden haben. Andernfalls kann es zu Fehlfunktionen des Geräts kommen. Wichtig ist auch das Attribut updateChannelFW
    -

  • - -
  • longids
    - Durch Komma getrennte Liste von Device-Typen für Empfang von langen IDs mit dem SIGNALduino. Diese zusätzliche ID erlaubt es Wettersensoren, welche auf dem gleichen Kanal senden zu unterscheiden. Hierzu wird eine zufällig generierte ID hinzugefügt. Wenn Sie longids verwenden, dann wird in den meisten Fällen nach einem Batteriewechsel ein neuer Sensor angelegt. Standardmäßig werden keine langen IDs verwendet.
    - Folgende Module verwenden diese Funktionalität: 14_Hideki, 41_OREGON, 14_CUL_TCM97001, 14_SD_WS07.
    - Beispiele:
    -	    		# Keine langen IDs verwenden (Default Einstellung):
    -	    		attr sduino longids 0
    -	    		# Immer lange IDs verwenden:
    -	    		attr sduino longids 1
    -	    		# Verwende lange IDs für SD_WS07 Devices.
    -	    		# Device Namen sehen z.B. so aus: SD_WS07_TH_3.
    -	    		attr sduino longids SD_WS07
    -		

  • - -
  • maxMuMsgRepeat
    - In MU Signalen können mehrere Wiederholungen stecken. Diese werden einzeln ausgewertet und an ein logisches Modul uebergeben. Mit diesem Attribut kann angepasst werden, wie viele Wiederholungen gesucht werden. Standard ist 4. -

  • - -
  • minsecs
    - Es wird von anderen Modulen bereitgestellt. Minsecs sollte wie eine Schwelle wirken. Wenn angegeben, werden unterstützte Module neue Nachrichten verworfen, wenn minsecs nicht vergangen sind. -

  • - -
  • noMsgVerbose
    - Mit diesem Attribut können Sie die Protokollierung von Debug-Nachrichten vom io-Gerät steuern. Wenn dieser Wert auf 3 festgelegt ist, werden diese Nachrichten protokolliert, wenn der globale Verbose auf 3 oder höher eingestellt ist. -

  • - -
  • eventlogging
    - Mit diesem Attribut können Sie steuern, ob jede Logmeldung auch als Ereignis bereitgestellt wird. Dies ermöglicht das Erzeugen eines Ereignisses fuer jede Protokollnachricht. - Setze dies auf 0 und Logmeldungen werden nur in der globalen Fhem-Logdatei gespeichert, wenn der Loglevel höher oder gleich dem Verbose-Attribut ist. - Setze dies auf 1 und jede Logmeldung wird auch als Ereignis versendet. Dadurch können Sie die Ereignisse in einer separaten Protokolldatei protokollieren. -

  • - -
  • rawmsgEvent
    - Bei der Einstellung "1", lösen empfangene Rohnachrichten Ereignisse aus. -

  • - -
  • suppressDeviceRawmsg
    - Bei der Einstellung "1" wird das interne "RAWMSG" nicht mit den empfangenen Nachrichten aktualisiert. -

  • - -
  • updateChannelFW
    - Das Modul sucht nach Verfügbaren Firmware Versionen (GitHub) und bietet diese via dem Befehl flash zum Flashen an. Mit dem Attribut kann festgelegt werden, ob nur stabile Versionen ("Latest Release") angezeigt werden oder auch Vorabversionen ("Pre-release") einer neuen Firmware.
    - Die Option testing inkludiert auch die stabilen Versionen. -
      -
    • stable: Als stabil getestete Versionen, erscheint nur sehr selten
    • -
    • testing: Neue Versionen, welche noch getestet werden muss
    • -
    -
    Die Liste der verfügbaren Versionen muss manuell mittels get availableFirmware neu geladen werden. + +Internals +
      +
    • + IDsNoDispatch: Hier werden Protokolleinträge mit ihrer numerischen ID aufgelistet, für welche keine Weitergabe von Daten an logische Module aktiviert wurde. Um die Weitergabe zu aktivieren, kann die Menüoption Display protocollist verwendet werden. +
    • +
    • + LASTDMSGID: Hier wird die zuletzt dispatchte Protocol ID angezeigt. +
    • +
    • + NR_CMD_LAST_H: Anzahl der gesendeten Nachrichten innerhalb der letzten Stunde. +
    • +
    • + RAWMSG: zuletzt empfangene RAWMSG +
    • +
    • + cc1101_available: Wenn ein CC1101 erkannt wurde, so wird dieses Internal angezeigt mit dem Wert 1. +
    • +
    • + version: Hier wird die Version des SIGNALduino microcontrollers angezeigt. +
    • +
    • + versionProtocols: Hier wird die Version der SIGNALduino Protokolldatei angezeigt. +
    • +
    • + versionmodule: Hier wird die Version des SIGNALduino FHEM Modules selbst angezeigt. +
    • +

    -

  • - Notwendig für den Befehl flash. Hier sollten Sie angeben, welche Hardware Sie mit dem USB-Port verbunden haben. Andernfalls kann es zu Fehlfunktionen des Geräts kommen.

    - -
  • whitelist_IDs
    - Dieses Attribut erlaubt es, festzulegen, welche Protokolle von diesem Modul aus verwendet werden. Protokolle, die nicht beachtet werden, erzeugen keine Logmeldungen oder Ereignisse. Sie werden dann vollständig ignoriert. Dies ermöglicht es, die Ressourcennutzung zu reduzieren und bessere Klarheit in den Protokollen zu erzielen. Sie können mehrere WhitelistIDs mit einem Komma angeben: 0,3,7,12. Mit einer # am Anfang können WhitelistIDs deaktiviert werden. -
    - Wird dieses Attribut nicht verwrndet oder deaktiviert, werden alle stabilen Protokolleinträge verarbeitet. Protokolleinträge, welche sich noch in Entwicklung befinden müssen explizit über dieses Attribut aktiviert werden. -

  • - -
  • WS09_CRCAUS
    -
      -
    • 0: CRC-Check WH1080 CRC = 0 on, Standard
    • -
    • 2: CRC = 49 (x031) WH1080, set OK
    • -
    -

  • -
- - Information menu -
    - -
  • Display protocollist
    - Zeigt Ihnen die aktuell implementierten Protokolle des SIGNALduino an und an welches logische FHEM Modul Sie übergeben werden.
    - Außerdem wird mit checkbox Symbolen angezeigt ob ein Protokoll verarbeitet wird. Durch Klick auf das Symbol, wird im Hintergrund das Attribut whitlelistIDs angepasst. Die Attribute whitelistIDs und blacklistIDs beeinflussen den dargestellten Status. - Protokolle die in der Spalte dev markiert sind, befinden sich in Entwicklung. -
      -
    • Wemm eine Zeile mit 'm' markiert ist, befindet sich das logische Modul, welches eine Schnittstelle bereitstellt in Entwicklung. Im Standard übergeben diese Protokolle keine Daten an logische Module. Um die Kommunikation zu ermöglichenm muss der Protokolleintrag aktiviert werden.
    • -
    • Wemm eine Zeile mit 'p' markiert ist, wurde der Protokolleintrag reserviert oder befindet sich in einem frühen Entwicklungsstadium.
    • -
    • Wemm eine Zeile mit 'y' markiert ist, wurde das Protkokoll noch nicht ausgiebig getestet und überprüft.
    • -
    -
    - Protokolle, welche in dem blacklistIDs Attribut eingetragen sind, können nicht über das Menü aktiviert werden. Dazu bitte das Attribut blacklistIDs entfernen. -

  • -
+ +Set +
    +
  • LaCrossePairForSec
  • + (NUR bei Verwendung eines cc110x Funk-Moduls)
    + Aktivieren Sie die automatische Erstellung neuer LaCrosse-Sensoren für "x" Sekunden. Wenn ignore_battery nicht angegeben wird, werden nur Sensoren erstellt, die das Flag 'Neue Batterie' senden.

    +
  • + cc1101_bWidth / cc1101_dataRate / cc1101_deviatn / cc1101_freq / cc1101_patable / cc1101_rAmpl / cc1101_reg / cc1101_sens
    + (NUR bei Verwendung eines cc110x Funk-Moduls)

    + Stellt die SIGNALduino-Frequenz / Bandbreite / PA-Tabelle / Empfänger-Amplitude / Empfindlichkeit ein.
    + Verwenden Sie es mit Vorsicht. Es kann Ihre Hardware zerstören und es kann sogar illegal sein, dies zu tun.
    + Hinweis: Die für die RFR-Übertragung verwendeten Parameter sind nicht betroffen.
    +
  • +
      + +
    • cc1101_bWidth , kann auf Werte zwischen 58 kHz und 812 kHz eingestellt werden. Große Werte sind störanfällig, ermöglichen jedoch den Empfang von ungenau kalibrierten Sendern. Es wirkt sich auch auf die Übertragung aus. Standard ist 325 kHz. +
    • + +
    • cc1101_dataRate , kann auf Werte zwischen 0.0247955 kBaud und 1621.83 kBaud eingestellt werden. +
    • + +
    • cc1101_deviatn , kann auf Werte zwischen 1.586914 kHz und 380.859375 kHz eingestellt werden. +
    • + +
    • cc1101_freq , legt sowohl die Empfangsfrequenz als auch die Übertragungsfrequenz fest.
      + Hinweis: Obwohl der CC1101 auf Frequenzen zwischen 315 und 915 MHz eingestellt werden kann, ist die Antennenschnittstelle und die Antenne auf genau eine Frequenz abgestimmt. Standard ist 433.920 MHz (oder 868.350 MHz). Wenn keine Frequenz angegeben wird, dann wird die Frequenz aus dem Attribut cc1101_frequency geholt. +
    • + +
    • cc1101_patable , Änderung der PA-Tabelle (Leistungsverstärkung für HF-Senden) +
    • + +
    • cc1101_rAmpl , ist die Empfängerverstärkung mit Werten zwischen 24 und 42 dB. Größere Werte erlauben den Empfang schwacher Signale. Der Standardwert ist 42. +
    • + +
    • cc1101_reg Es können mehrere Register auf einmal gesetzt werden. Das Register wird über seinen zweistelligen Hexadezimalwert angegeben, gefolgt von einem zweistelligen Wert. Mehrere Register werden via Leerzeichen getrennt angegeben +
    • + +
    • cc1101_sens , ist die Entscheidungsgrenze zwischen den Ein- und Aus-Werten und beträgt 4, 8, 12 oder 16 dB. Kleinere Werte erlauben den Empfang von weniger klaren Signalen. Standard ist 4 dB. +
    • +
    +
    + +
  • close
    + Beendet die Verbindung zum Gerät. +

  • + +
  • + disableMessagetype
    + Ermöglicht das Deaktivieren der Nachrichtenverarbeitung für +
      +
    • Nachrichten mit sync (syncedMS)
    • +
    • Nachrichten ohne einen sync pulse (unsyncedMU)
    • +
    • Manchester codierte Nachrichten (manchesterMC)
    • +
    + Der neue Status wird in den eeprom vom Arduino geschrieben. +

  • + +
  • enableMessagetype
    + Ermöglicht die Aktivierung der Nachrichtenverarbeitung für +
      +
    • Nachrichten mit sync (syncedMS)
    • +
    • Nachrichten ohne einen sync pulse (unsyncedMU)
    • +
    • Manchester codierte Nachrichten (manchesterMC)
    • +
    + Der neue Status wird in den eeprom vom Arduino geschrieben. +

  • + +
  • + flash [hexFile|url]
    + Der SIGNALduino benötigt die richtige Firmware, um die Sensordaten zu empfangen und zu liefern. Unter Verwendung der Arduino IDE zum Flashen der Firmware in den SIGNALduino bietet dies eine Möglichkeit, ihn direkt von FHEM aus zu flashen. Sie können eine Datei auf Ihrem fhem-Server angeben oder eine URL angeben, von der die Firmware heruntergeladen wird.

    + Es gibt einige Anforderungen: +
      +
    • avrdude muss auf dem Host installiert sein. Auf einem Raspberry PI kann dies getan werden mit: sudo apt-get install avrdude +
    • +
    • Das Hardware-Attribut muss festgelegt werden, wenn eine andere Hardware als Arduino Nano verwendet wird. Dieses Attribut definiert den Befehl, der an avrdude gesendet wird, um den uC zu flashen. +
    • +
    • Bei Problem mit dem Flashen, können im Logfile interessante Informationen zu finden sein. +
    • +

    + Beispiele: +
      +
    • flash mittels Versionsnummer: Versionen können mit get availableFirmware abgerufen werden
    • +
    • flash via hexFile: set sduino flash ./FHEM/firmware/SIGNALduino_mega2560.hex
    • +
    • flash via url für einen Nano mit CC1101: set sduino flash https://github.com/RFD-FHEM/SIGNALDuino/releases/download/3.3.1-RC7/SIGNALDuino_nanocc1101.hex
    • +

    + Hinweise Modell radino: +
      +
    • Teilweise kann es beim flashen vom radino unter Linux Probleme geben. Hier im Wiki unter dem Punkt "radino & Linux" gibt es einen Patch!
    • +
    • Wenn der Radino in dieser Art /dev/ttyACM0 definiert wurde, sollte das Flashen der Firmware automatisch erfolgen. Wenn das nicht gelingt, muss der Bootloader manuell aktiviert werden:
    • +
    • Um den Bootloader vom radino manuell zu aktivieren gibt es 2 Varianten. +
        +
      • 1) Module welche einen BSL-Button besitzen: +
          +
        • Spannung anlegen
        • +
        • druecke & halte BSL- und RESET-Button
        • +
        • RESET-Button loslassen und danach den BSL-Button loslassen
        • +
        • (Wiederholen Sie diese Schritte, wenn Ihr radino nicht sofort in den Bootloader-Modus wechselt.)
        • +
        +
      • +
      • 2) Bootloader erzwingen: +
          +
        • durch zweimaliges druecken der Reset-Taste
        • +
        +
      • +
      + Im Bootloader-Modus erhält der radino eine andere USB ID. Diese muss im Attribut "flashCommand" eingetragen werden.
      + Wenn der Bootloader aktiviert ist, signalisiert er das mit dem Blinken einer LED. Dann hat man ca. 8 Sekunden Zeit zum flashen. +
    • +
    +

  • + + +
  • raw
    + Geben Sie einen SIGNALduino-Firmware-Befehl aus, ohne auf die vom SIGNALduino zurückgegebenen Daten zu warten. Ausführliche Informationen zu SIGNALduino-Befehlen finden Sie im SIGNALduino-Firmware-Code. Mit dieser Linie können Sie fast jedes Signal über einen angeschlossenen Sender senden.
    + Um einige Rohdaten zu senden, schauen Sie sich diese Beispiele an: P#binarydata#R#C (#C is optional)

    + + Beispiel 1: set sduino raw SR;R=3;P0=500;P1=-9000;P2=-4000;P3=-2000;D=0302030; , sendet die Daten im Raw-Modus dreimal wiederholt
    + Beispiel 2: set sduino raw SM;R=3;P0=500;C=250;D=A4F7FDDE; , sendet die Daten Manchester codiert mit einem clock von 250µS
    + Beispiel 3: set sduino raw SC;R=3;SR;P0=5000;SM;P0=500;C=250;D=A4F7FDDE; , sendet eine kombinierte Nachricht von Raw und Manchester codiert 3 mal wiederholt
    + Beispiel 4: set sduino raw SN;R=3;D=9A46036AC8D3923EAEB470AB; , sendet die xFSK - Daten dreimal wiederholt
    +
    + +
      + Hinweis: Die falsche Benutzung der kommenden Optionen kann zu Fehlfunktionen des SIGNALduinos führen!

      +
    • CER -> Einschalten der Datenkomprimierung (config: Mred=1)
    • +
    • CDR -> Abschalten der Datenkomprimierung (config: Mred=0)

    • + Register Befehle bei einem CC1101 +
    • e -> Werkseinstellungen
    • +
    • x -> gibt die ccpatable zurück
    • +
    • C -> liest einen Wert aus dem CC1101 Register
      +
        Beispiel: set sduino raw C04 liest den Wert aus der Registeradresse 0x04
      +
    • +
    • W -> schreibt einen Wert ins EEPROM und ins CC1101 Register (Hinweis: Die EEPROM Adresse hat einen Offset von 2)
      +
        Beispiel 1: set sduino raw W041D schreibt 1D ins Register 0x02
      +
        Beispiel 2: set sduino raw W041D#W0604 schreibt 1D ins Register 0x02 und 04 ins Register 0x04
      +
    • +
      + andere Befehle des uC +
    • ? -> gibt die verfügbaren Kommandos zurück
    • +
    • P -> sendet ein PING
    • +
    • R -> gibt den freien RAM zurück
    • +
    • V -> gibt die Version zurück
    • +
    • s -> gibt den Status zurück
    • +
    • t -> gibt die Uptime zurück
    • +

    +
  • + + +
  • reset
    + Öffnet die Verbindung zum Gerät neu und initialisiert es. +

  • + + +
  • sendMsg
    + Dieser Befehl erstellt die erforderlichen Anweisungen zum Senden von Rohdaten über den SIGNALduino. Sie können die Signaldaten wie Protokoll und die Bits angeben, die Sie senden möchten.
    + Alternativ ist es auch moeglich, die zu sendenden Daten in hexadezimaler Form zu uebergeben. Dazu muss ein 0x vor den Datenteil geschrieben werden. +

    + Bitte beachte, dieses Kommando funktioniert nur fuer MU oder MS Protokolle nach dieser Vorgehensweise: +

    + Argumente sind: +

    +

      +
    • P#binarydata#R#C (#C is optional) +
      Beispiel binarydata: set sduino sendMsg P0#0101#R3#C500 +
      Dieser Befehl erzeugt ein Sendekommando fuer die Bitfolge 0101 anhand der protocol id 0. Als Takt wird 500 verwendet. +
      SR;R=3;P0=500;P1=-9000;P2=-4000;P3=-2000;D=03020302;
      +
    • +

    +
      +
    • P#0xhexdata#R#C (#C is optional) +
      Beispiel 0xhexdata: set sduino sendMsg P29#0xF7E#R4 +
      Dieser Befehl erzeugt ein Sendekommando fuer die Hexfolge F7E anhand der protocol id 29. Die Nachricht soll 4x gesendet werden. +
      SR;R=4;P0=-8360;P1=220;P2=-440;P3=-220;P4=440;D=01212121213421212121212134; +
    • +

    +
      +
    • P#0xhexdata#R#C#F (#C #F is optional) +
      Beispiel 0xhexdata: set sduino sendMsg P36#0xF7#R6#Fxxxxxxxxxx (xxxxxxxxxx = Registerwert des CC1101) +
      Dieser Befehl erzeugt ein Sendekommando fuer die Hexfolge F7 anhand der protocol id 36. Die Nachricht soll 6x gesendet werden mit der angegebenen Frequenz. +
      SR;R=6;P0=-8360;P1=220;P2=-440;P3=-220;P4=440;D=012323232324232323;F= (Registerwert des CC1101); +
    • +
    +

    +
  • +
+
+ + + +Get +
    + +
  • availableFirmware
    + Ruft die verfügbaren Firmware-Versionen von Github ab und macht diese im set flash Befehl auswählbar. +

  • + +
  • ccconf
    + Liest sämtliche radio-chip (cc1101) Register (Frequenz, Bandbreite, etc.) aus und zeigt die aktuelle Konfiguration an.
    + (NUR bei Verwendung eines cc1101 Empfänger) +

  • + +
  • ccpatable
    + Liest die cc1101 PA Tabelle aus (power amplification for RF sending).
    + (NUR bei Verwendung eines cc1101 Empfänger) +

  • + +
  • ccreg
    + Liest das cc1101 Register aus (99 liest alle aus).
    + (NUR bei Verwendung eines cc1101 Empfänger) +

  • + +
  • close
    + Beendet die Verbindung zum SIGNALduino. +

  • + +
  • cmds
    + Abhängig von der installierten Firmware besitzt der SIGNALduino verschiedene Befehle. Bitte beachten Sie den Quellcode der Firmware Ihres SIGNALduino, um die Antwort dieses Befehls zu interpretieren. +

  • + +
  • config
    + Zeigt Ihnen die aktuelle Konfiguration der SIGNALduino Protokollkathegorie an. | Bsp: MS=1;MU=1;MC=1;Mred=0 +

  • + +
  • freeram
    + Zeigt den freien RAM an. +

  • + +
  • ping
    + Prüft die Kommunikation mit dem SIGNALduino. +

  • + +
  • rawmsg
    + Verarbeitet Nachrichten (MS, MC, MU, ...), als ob sie vom SIGNALduino empfangen wurden. Der Befehl "get raw" übergibt keine Kommandos an den verbundenen Microcontroller!

    + Beispielsweise würde diese Nachricht:
    + MS;P0=-7871;P2=-1960;P3=578;P4=-3954;D=030323232323434343434323232323234343434323234343234343234343232323432323232323232343234;CP=3;SP=0;R=0;m=0;
    + nach mehrmaligem Ausführen des Befehles einen Sensor SD_WS_33_TH_1 anlegen. +

  • + +
  • uptime
    + Zeigt Ihnen die Information an, wie lange der SIGNALduino läuft. Ein FHEM Neustart setzt den Timer zurück. +

  • + +
  • version
    + Zeigt Ihnen die Information an, welche aktuell genutzte Software Sie mit dem SIGNALduino verwenden. +

  • +
+ + + +Attributes +
    + +
  • addvaltrigger
    + Generiert Trigger für zusätzliche Werte. Momentan werden DMSG, ID, RAWMSG und RSSI unterstüzt. +

  • + +
  • blacklist_IDs
    + Dies ist eine durch Komma getrennte Liste. Die Blacklist funktioniert nur, wenn keine Whitelist existiert! Hier kann man ID´s eintragen welche man nicht ausgewertet haben möchte. +

  • + +
  • cc1101_frequency
    + Legt die Frequenz des SIGNALduino fest. Standard is 433 Mhz.
    + Da die Werte für PA Werte Frequenzabhängig sind, wird für das Setzen der Register die hier hinterlegte Frequenz verwendet. +

  • + +
  • cc1101_reg_user
    + Speicherplatz für individuelle Registerkonfigurationen bzw. Werte. Es können einzelne oder mehrere Werte gespeichert werden.
    + Hinweis: Der Wert ist bestehend aus der Registeradresse gefolgt vom Wert. Mehrere Werte werden mit Komma getrennt. Beispiel: 04D3,0591 +

  • + +
  • debug
    + Dies bringt das Modul in eine sehr ausführliche Debug-Ausgabe im Logfile. Somit lassen sich neue Signale finden und Signale überprüfen, ob die Demodulation korrekt funktioniert. +

  • + +
  • development
    + Das development Attribut ist nur in den Entwicklungsversionen des FHEM Modules aus Grüden der Abwärtskompatibilität vorhanden. Bei Setzen des Attributes auf "1" werden alle Protokolle aktiviert, welche mittels developID=y markiert sind. +
    + Wird das Attribut auf 1 gesetzt, so werden alle in Protokolle die mit dem developID Flag "y" markiert sind aktiviert. Die Flags (Spalte dev) können über das Webfrontend im Abschnitt "Information menu" mittels "Display protocollist" eingesehen werden. +

  • +
  • do_not_notify

  • + +
  • doubleMsgCheck_IDs
    + Dieses Attribut erlaubt es, Protokolle anzugeben, die zwei gleiche Nachrichten enthalten müssen, um diese an die Module zu übergeben. Sie können mehrere IDs mit einem Komma angeben: 0,3,7,12 +

  • +
  • dummy

  • + +
  • eventlogging
    + Mit diesem Attribut können Sie steuern, ob jede Logmeldung auch als Ereignis bereitgestellt wird. Dies ermöglicht das Erzeugen eines Ereignisses fuer jede Protokollnachricht. + Setze dies auf 0 und Logmeldungen werden nur in der globalen Fhem-Logdatei gespeichert, wenn der Loglevel höher oder gleich dem Verbose-Attribut ist. + Setze dies auf 1 und jede Logmeldung wird auch als Ereignis versendet. Dadurch können Sie die Ereignisse in einer separaten Protokolldatei protokollieren. +

  • + +
  • flashCommand
    + Dies ist der Befehl, der ausgeführt wird, um den Firmware-Flash auszuführen. Nutzen Sie dies nicht, wenn Sie nicht wissen, was Sie tun!
    + Wurde das Attribut nicht definiert, so verwendet es die Standardeinstellungen.
    Sobald der User das Attribut manuell definiert, nutzt das System diese Vorgaben!
    +
      +
    • Standard nano, nanoCC1101, miniculCC1101, promini:
      avrdude -c arduino -b [BAUDRATE] -P [PORT] -p atmega328p -vv -U flash:w:[HEXFILE] 2>[LOGFILE]
    • +
    • Standard radinoCC1101:
      avrdude -c avr109 -b [BAUDRATE] -P [PORT] -p atmega32u4 -vv -D -U flash:w:[HEXFILE] 2>[LOGFILE]
    • +
    + Es enthält einige Platzhalter, die automatisch mit den entsprechenden Werten gefüllt werden: +
      +
    • [BAUDRATE]
      + Ist die Schrittgeschwindigkeit. (z.Bsp: 57600) +
    • +
    • [PORT]
      + Ist der Port, an dem der SIGNALduino angeschlossen ist (z.Bsp: /dev/ttyUSB0) und wird von der Definition verwendet. +
    • +
    • [HEXFILE]
      + Ist die .hex-Datei, die geflasht werden soll. Es gibt drei Optionen (angewendet in dieser Reihenfolge):
      +
        +
      • in set SIGNALduino flash als erstes Argument übergeben
      • +
      • aus dem Hardware-Attribut genommen
      • +
      • der im Modul definierte Standardwert
      • +
      +
    • +
    • [LOGFILE]
      + Die Logdatei, die Informationen über den Flash-Prozess sammelt. Es wird nach Abschluss des Flash-Prozesses in FHEM angezeigt +
    • +

    + Hinweis: ! Teilweise kann es beim Flashen vom radino unter Linux Probleme geben. Hier im Wiki unter dem Punkt "radino & Linux" gibt es einen Patch! +

  • + +
  • hardware
    + Derzeit mögliche Hardware Varianten mit verschiedenen Empfänger Optionen. + Die einfache Variante besteht aus einem Empfänger und einen Sender, die über je eine einzige digitale Signalleitung Datem mit dem Microcontroller austauschen. Der Empfänger sendet dabei und der Sender empfängt dabei ausschließlich. + Weiterhin existiert der den sogenannten cc1101 (sub 1 GHZ) Chip, welche empfangen und senden kann. Dieser wird über die SPI Verbindung angebunden. + ESP8266 Hardware Typen, unterstützen derzeit kein flashen aus dem Modul und benötigen mindestens 1 MB Flash Speicher. +
      +
    • ESP32: ESP32 für einfachen eindraht Empfänger
    • +
    • ESP32cc1101: ESP32 mit einem CC110x-Empfänger (SPI Verbindung)
    • +
    • ESP8266: ESP8266 für einfachen eindraht Empfänger
    • +
    • ESP8266cc1101: ESP8266 mit einem CC110x-Empfänger (SPI Verbindung)
    • +
    • MAPLEMINI_F103CB: MapleMini F103CB (STM32) für einfachen eindraht Empfänger
    • +
    • MAPLEMINI_F103CBcc1101: MapleMini F103CB (STM32) mit einem CC110x-Empfänger (SPI Verbindung)
    • +
    • miniculCC1101: Arduino pro Mini mit einem CC110x-Empfänger (SPI Verbindung) entsprechend dem minicul verkabelt
    • +
    • nano: Arduino Nano 328 für einfachen eindraht Empfänger
    • +
    • nanoCC1101: Arduino Nano für einen CC110x-Empfänger (SPI Verbindung)
    • +
    • promini: Arduino Pro Mini 328 für einfachen eindraht Empfänger
    • +
    • radinoCC1101: Ein Arduino kompatibler Radino mit CC110x-Empfänger (SPI Verbindung)
    • +

    + Notwendig für den Befehl flash. Hier sollten Sie angeben, welche Hardware Sie mit dem usbport verbunden haben. Andernfalls kann es zu Fehlfunktionen des Geräts kommen. Wichtig ist auch das Attribut updateChannelFW
    +

  • + +
  • longids
    + Durch Komma getrennte Liste von Device-Typen für Empfang von langen IDs mit dem SIGNALduino. Diese zusätzliche ID erlaubt es Wettersensoren, welche auf dem gleichen Kanal senden zu unterscheiden. Hierzu wird eine zufällig generierte ID hinzugefügt. Wenn Sie longids verwenden, dann wird in den meisten Fällen nach einem Batteriewechsel ein neuer Sensor angelegt. Standardmäßig werden keine langen IDs verwendet.
    + Folgende Module verwenden diese Funktionalität: 14_Hideki, 41_OREGON, 14_CUL_TCM97001, 14_SD_WS07.
    + Beispiele:
    +      # Keine langen IDs verwenden (Default Einstellung):
    +      attr sduino longids 0
    +      # Immer lange IDs verwenden:
    +      attr sduino longids 1
    +      # Verwende lange IDs für SD_WS07 Devices.
    +      # Device Namen sehen z.B. so aus: SD_WS07_TH_3.
    +      attr sduino longids SD_WS07
    +    
    +
  • + +
  • maxMuMsgRepeat
    + In MU Signalen können mehrere Wiederholungen stecken. Diese werden einzeln ausgewertet und an ein logisches Modul uebergeben. Mit diesem Attribut kann angepasst werden, wie viele Wiederholungen gesucht werden. Standard ist 4. +

  • + +
  • minsecs
    + Es wird von anderen Modulen bereitgestellt. Minsecs sollte wie eine Schwelle wirken. Wenn angegeben, werden unterstützte Module neue Nachrichten verworfen, wenn minsecs nicht vergangen sind. +

  • + +
  • noMsgVerbose
    + Mit diesem Attribut können Sie die Protokollierung von Debug-Nachrichten vom io-Gerät steuern. Wenn dieser Wert auf 3 festgelegt ist, werden diese Nachrichten protokolliert, wenn der globale Verbose auf 3 oder höher eingestellt ist. +

  • + +
  • rawmsgEvent
    + Bei der Einstellung "1", lösen empfangene Rohnachrichten Ereignisse aus. +

  • + +
  • rfmode
    + Konfiguriert den RF Transceiver des SIGNALduino (CC1101). Verfügbare Argumente sind: +
      +
    • Avantek
      + Modulation 2-FSK, Datarate=50.087 kbps, Sync Word=0869, FIFO-THR=8 Byte, Frequenz 433.3 MHz +
        Example: AVANTEK Funk-Türklingel
      +
    • +
    • Bresser_5in1
      + Modulation 2-FSK, Datenrate=8.23 kbps, Sync Word=2DD4, Packet Length=26 Byte, Frequenz 868.35 MHz +
        Beispiel: BRESSER 5-in-1 Wetter Center, BRESSER Profi Regenmesser, Fody E42, Fody E43
      +
    • +
    • Bresser_6in1
      + Modulation 2-FSK, Datenrate=8.23 kbps, Sync Word=2DD4, FIFO-THR=20 Byte, Frequenz 868.35 MHz +
    • +
    • Fine_Offset_WH51_434
      + Modulation 2-FSK, Datenrate=17.26 kbps, Sync Word=2DD4, Packet Length=14 Byte, Frequenz 433.92 MHz +
        Beispiel: Bodenfeuchtesensor Fine Offset WH51, ECOWITT WH51, MISOL/1, Froggit DP100
      +
    • +
    • Fine_Offset_WH51_868
      + Modulation 2-FSK, Datenrate=17.26 kbps, Sync Word=2DD4, Packet Length=14 Byte, Frequenz 868.35 MHz +
        Beispiel: Bodenfeuchtesensor Fine Offset WH51, ECOWITT WH51, MISOL/1, Froggit DP100
      +
    • +
    • Fine_Offset_WH57_434
      + Modulation 2-FSK, Datenrate=17.26 kbps, Sync Word=2DD4, Packet Length=9 Byte, Frequenz 433.92 MHz +
        Beispiel: Gewittersensor Fine Offset WH57, Froggit DP60, Ambient Weather WH31L
      +
    • +
    • Fine_Offset_WH57_868
      + Modulation 2-FSK, Datenrate=17.26 kbps, Sync Word=2DD4, Packet Length=9 Byte, Frequenz 868.35 MHz +
        Beispiel: Gewittersensor Fine Offset WH57, Froggit DP60, Ambient Weather WH31L
      +
    • +
    • KOPP_FC
      + Modulation GFSK, Datenrate=4.7855 kbps, Sync Word=AA54, Frequenz 868.3MHz +
    • +
    • Lacrosse_mode1
      + Modulation 2-FSK, Datenrate=17.25769 kbps, Sync Word=2DD4, Frequenz 868.3MHz
      +
        Beispiel: TX25-IT, TX27-IT, TX29-IT, TX29DTH-IT, TX37, 30.3143.IT, 30.3144.IT
      +
    • +
    • Lacrosse_mode2
      + Modulation 2-FSK, Datenrate=9.579 kbps, Sync Word=2DD4, Frequenz 868.3MHz
      +
        Beispiel: TX35TH-IT, TX35DTH-IT, TX38-IT, 30.3155WD, 30.3156WD
      +
    • +
    • PCA301
      + Modulation 2-FSK, Datenrate=6.62041 kbps, Sync Word=2DD4, Frequenz 868.950 MHz +
    • +
    • Rojaflex
      + Modulation GFSK, Datenrate=9.99 kbps, Sync Word=D391D391, Frequenz 433.920 MHz +
    • +
    • SlowRF
      + Modulation ASK/OOK, läd die Standard Einstellung vom uC +
    • +
    +

  • + +
  • suppressDeviceRawmsg
    + Bei der Einstellung "1" wird das interne "RAWMSG" nicht mit den empfangenen Nachrichten aktualisiert. +

  • + +
  • updateChannelFW
    + Das Modul sucht nach Verfügbaren Firmware Versionen (GitHub) und bietet diese via dem Befehl flash zum Flashen an. Mit dem Attribut kann festgelegt werden, ob nur stabile Versionen ("Latest Release") angezeigt werden oder auch Vorabversionen ("Pre-release") einer neuen Firmware.
    + Die Option testing inkludiert auch die stabilen Versionen. +
      +
    • stable: Als stabil getestete Versionen, erscheint nur sehr selten
    • +
    • testing: Neue Versionen, welche noch getestet werden muss
    • +
    +
    Die Liste der verfügbaren Versionen muss manuell mittels get availableFirmware neu geladen werden. +

  • + Notwendig für den Befehl flash. Hier sollten Sie angeben, welche Hardware Sie mit dem USB-Port verbunden haben. Andernfalls kann es zu Fehlfunktionen des Geräts kommen.

    + +
  • whitelist_IDs
    + Dieses Attribut erlaubt es, festzulegen, welche Protokolle von diesem Modul aus verwendet werden. Protokolle, die nicht beachtet werden, erzeugen keine Logmeldungen oder Ereignisse. Sie werden dann vollständig ignoriert. Dies ermöglicht es, die Ressourcennutzung zu reduzieren und bessere Klarheit in den Protokollen zu erzielen. Sie können mehrere WhitelistIDs mit einem Komma angeben: 0,3,7,12. Mit einer # am Anfang können WhitelistIDs deaktiviert werden. +
    + Wird dieses Attribut nicht verwrndet oder deaktiviert, werden alle stabilen Protokolleinträge verarbeitet. Protokolleinträge, welche sich noch in Entwicklung befinden müssen explizit über dieses Attribut aktiviert werden. +

  • + +
  • WS09_CRCAUS
    +
      +
    • 0: CRC-Check WH1080 CRC = 0 on, Standard
    • +
    • 2: CRC = 49 (x031) WH1080, set OK
    • +
    +

  • + +
  • MatchList
    + Dieses Attribut ermöglicht es die Modul Match Tabelle um weitere Einträge zu erweitern. Dazu müssen die weiteren Einträge im PERL Hash format angegeben werden: +
      +
    • Format: { 'Nummer:Modul' => 'Protokoll-Pattern' , 'NächsteNummer:NächstesModul' => 'Protokoll-Pattern' , ... }
    • +
    • Beispiel: { '34:MyModule' => '^u98#.{8}' , '35:MyModule2' => '^u99#.{10}' }
    • +
    +

  • +
+ + + +Information menu +
    + +
  • Display protocollist
    + Zeigt Ihnen die aktuell implementierten Protokolle des SIGNALduino an und an welches logische FHEM Modul Sie übergeben werden.
    + Außerdem wird mit checkbox Symbolen angezeigt ob ein Protokoll verarbeitet wird. Durch Klick auf das Symbol, wird im Hintergrund das Attribut whitlelistIDs angepasst. Die Attribute whitelistIDs und blacklistIDs beeinflussen den dargestellten Status. + Protokolle die in der Spalte dev markiert sind, befinden sich in Entwicklung. +
      +
    • Wemm eine Zeile mit 'm' markiert ist, befindet sich das logische Modul, welches eine Schnittstelle bereitstellt in Entwicklung. Im Standard übergeben diese Protokolle keine Daten an logische Module. Um die Kommunikation zu ermöglichenm muss der Protokolleintrag aktiviert werden.
    • +
    • Wemm eine Zeile mit 'p' markiert ist, wurde der Protokolleintrag reserviert oder befindet sich in einem frühen Entwicklungsstadium.
    • +
    • Wemm eine Zeile mit 'y' markiert ist, wurde das Protkokoll noch nicht ausgiebig getestet und überprüft.
    • +
    +
    + Protokolle, welche in dem blacklistIDs Attribut eingetragen sind, können nicht über das Menü aktiviert werden. Dazu bitte das Attribut blacklistIDs entfernen. +

  • +
=end html_DE =for :application/json;q=META.json 00_SIGNALduino.pm { - "abstract": "supports the same low-cost receiver for digital signals", - "author": [ - "Sidey <>", - "homeautouser", - "elektron-bbs", - "ralf9" - ], - "x_fhem_maintainer": [ - "Sidey", - "homeautouser", - "elektron-bbs" - ], - "x_fhem_maintainer_github": [ - "Sidey", - "homeautouser", - "elektron-bbs" - ], - "description": "This module interprets digitals signals provided from the signalduino hardware device and provides it to logical modules", - "dynamic_config": 1, - "keywords": [ - "fhem-sonstige-systeme", - "fhem-hausautomations-systeme", - "fhem-mod", - "signalduino" - ], - "license": [ - "GPL_2" - ], - "meta-spec": { - "url": "https://metacpan.org/pod/CPAN::Meta::Spec", - "version": 2 - }, - "name": "FHEM::SIGNALduino", - "prereqs": { - "runtime": { - "requires": { - "HttpUtils": 0, - "perl": 5.018, - "IPC::Open3": "0", - "Symbol": "0", - "constant": "0", - "lib::SD_Protocols": "0", - "strict": "0", - "warnings": "0", - "Time::HiRes": "0", - "JSON": "0" - }, - "recommends": { - "Data::Dumper": "0" - }, - "suggests": { - "Scalar::Util": "0" - } - }, - "develop": { - "requires": { - "IPC::Open3": "0", - "Symbol": "0", - "constant": "0", - "lib::SD_Protocols": "0", - "strict": "0", - "warnings": "0", - "Data::Dumper": "0", - "Time::HiRes": "0", - "JSON": "0" - }, - "suggests": { - "Scalar::Util": "0" - } - } - }, - "release_status": "stable", - "resources": { - "bugtracker": { - "web": "https://github.com/RFD-FHEM/RFFHEM/issues/" - }, - "repository": { - "x_master": { - "type": "git", - "url": "https://github.com/RFD-FHEM/RFFHEM.git", - "web": "https://github.com/RFD-FHEM/RFFHEM/tree/dev-r34" - }, - "type": "svn", - "url": "https://svn.fhem.de/fhem", - "web": "https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/00_SIGNALduino.pm", - "x_branch": "trunk", - "x_filepath": "fhem/FHEM/", - "x_raw": "https://svn.fhem.de/trac/export/latest/trunk/fhem/FHEM/00_SIGNALduino.pm", - "x_dev": { - "type": "git", - "url": "https://github.com/RFD-FHEM/RFFHEM.git", - "web": "https://github.com/RFD-FHEM/RFFHEM/tree/dev-r34", - "x_branch": "dev-r34", - "x_filepath": "FHEM/", - "x_raw": "https://raw.githubusercontent.com/RFD-FHEM/RFFHEM/master/FHEM/00_SIGNALduino.pm" - } - }, - "x_commandref": { - "web": "https://commandref.fhem.de/#SIGNALduino" - }, - "x_support_community": { - "board": "Sonstige Systeme", - "boardId": "29", - "cat": "FHEM - Hausautomations-Systeme", - "description": "Sonstige Hausautomations-Systeme", - "forum": "FHEM Forum", - "rss": "https://forum.fhem.de/index.php?action=.xml;type=rss;board=29", - "title": "FHEM Forum: Sonstige Systeme", - "web": "https://forum.fhem.de/index.php/board,29.0.html" - }, - "x_wiki": { - "web": "https://wiki.fhem.de/wiki/SIGNALduino" - } - }, - "version": "v3.4.2" + "abstract": "supports the same low-cost receiver for digital signals", + "author": [ + "Sidey <>", + "homeautouser", + "elektron-bbs", + "ralf9" + ], + "x_fhem_maintainer": [ + "Sidey", + "homeautouser", + "elektron-bbs" + ], + "x_fhem_maintainer_github": [ + "Sidey", + "homeautouser", + "elektron-bbs" + ], + "description": "This module interprets digitals signals provided from the signalduino hardware device and provides it to logical modules", + "dynamic_config": 1, + "keywords": [ + "fhem-sonstige-systeme", + "fhem-hausautomations-systeme", + "fhem-mod", + "signalduino" + ], + "license": [ + "GPL_2" + ], + "meta-spec": { + "url": "https://metacpan.org/pod/CPAN::Meta::Spec", + "version": 2 + }, + "name": "FHEM::SIGNALduino", + "prereqs": { + "runtime": { + "requires": { + "HttpUtils": 0, + "perl": 5.018, + "IPC::Open3": "0", + "Symbol": "0", + "constant": "0", + "lib::SD_Protocols": "0", + "strict": "0", + "warnings": "0", + "Time::HiRes": "0", + "JSON": "0" + }, + "recommends": { + "Data::Dumper": "0" + }, + "suggests": { + "Scalar::Util": "0" + } + }, + "develop": { + "requires": { + "IPC::Open3": "0", + "Symbol": "0", + "constant": "0", + "lib::SD_Protocols": "0", + "strict": "0", + "warnings": "0", + "Data::Dumper": "0", + "Time::HiRes": "0", + "JSON": "0" + }, + "suggests": { + "Scalar::Util": "0" + } + } + }, + "release_status": "stable", + "resources": { + "bugtracker": { + "web": "https://github.com/RFD-FHEM/RFFHEM/issues/" + }, + "repository": { + "x_master": { + "type": "git", + "url": "https://github.com/RFD-FHEM/RFFHEM.git", + "web": "https://github.com/RFD-FHEM/RFFHEM/tree/master" + }, + "type": "svn", + "url": "https://svn.fhem.de/fhem", + "web": "https://svn.fhem.de/trac/browser/trunk/fhem/FHEM/00_SIGNALduino.pm", + "x_branch": "trunk", + "x_filepath": "fhem/FHEM/", + "x_raw": "https://svn.fhem.de/trac/export/latest/trunk/fhem/FHEM/00_SIGNALduino.pm", + "x_dev": { + "type": "git", + "url": "https://github.com/RFD-FHEM/RFFHEM.git", + "web": "https://github.com/RFD-FHEM/RFFHEM/tree/master", + "x_branch": "dev-r34", + "x_filepath": "FHEM/", + "x_raw": "https://raw.githubusercontent.com/RFD-FHEM/RFFHEM/master/FHEM/00_SIGNALduino.pm" + } + }, + "x_commandref": { + "web": "https://commandref.fhem.de/#SIGNALduino" + }, + "x_support_community": { + "board": "Sonstige Systeme", + "boardId": "29", + "cat": "FHEM - Hausautomations-Systeme", + "description": "Sonstige Hausautomations-Systeme", + "forum": "FHEM Forum", + "rss": "https://forum.fhem.de/index.php?action=.xml;type=rss;board=29", + "title": "FHEM Forum: Sonstige Systeme", + "web": "https://forum.fhem.de/index.php/board,29.0.html" + }, + "x_wiki": { + "web": "https://wiki.fhem.de/wiki/SIGNALduino" + } + }, + "version": "v3.5.1" } =end :application/json;q=META.json =cut diff --git a/fhem/FHEM/lib/SD_ProtocolData.pm b/fhem/FHEM/lib/SD_ProtocolData.pm index 789d2fc6c..c30b2ab89 100644 --- a/fhem/FHEM/lib/SD_ProtocolData.pm +++ b/fhem/FHEM/lib/SD_ProtocolData.pm @@ -1,2740 +1,3260 @@ -################################################################################ -# The file is part of the SIGNALduino project +########################################################################################################################################### +# $Id$ +# The file is part of the SIGNALduino project. +# All protocol definitions are contained in this file. +# +# 2016-2019 S.Butzek, Ralf9 +# 2019-2020 S.Butzek, HomeAutoUser, elektron-bbs # # !!! useful hints !!! # -------------------- -# name => ' ' # name of device or group of all devices -# comment => ' ' # exact description or example of devices -# id => ' ' # number of the protocol definition, each number only once use (accepted no .) -# knownFreqs => ' ' # known receiver frequency 433.92 | 868.35 (some sensor families or remote send on more frequencies) +# name => ' ' # name of device or group of all devices +# comment => ' ' # exact description or example of devices +# id => ' ' # number of the protocol definition, each number only once use (accepted no .) +# knownFreqs => ' ' # known receiver frequency 433.92 | 868.35 (some sensor families or remote send on more frequencies) # # Time for one, zero, start, sync, float, end and pause are calculated by clockabs * value = result in microseconds, positive value stands for high signal, negative value stands for low signal -# clockrange => [ , ] # only MC signals | min , max of pulse / pause times in microseconds -# clockabs => ' ' # only MU + MS signals | value for calculation of pulse / pause times in microseconds -# clockabs => '-1' # only MS signals | value pulse / pause times is automatically -# one => [ , ] # only MU + MS signals | value pair for a one bit, must be always a positive and negative factor of clockabs (accepted . | example 1.5) -# zero => [ , ] # only MU + MS signals | value pair for a zero bit, must be always a positive and negative factor of clockabs (accepted . | example -1.5) -# start => [ , ] # only MU - value pair or more for start message -# preSync => [ , ] # only MU + MS - value pair or more for preamble pulse of signal -# sync => [ , ] # only MS - value pair or more for sync pulse of signal -# float => [ , ] # only MU + MS signals | Convert 0F -> 01 (F) to be compatible with CUL -# pause => [ ] # only MU + MS signals, delay when sending between two repeats (clockabs * pause must be < 32768) -# end => [ ] # only MU + MS - value or more for end pulse of signal for sending -# msgIntro => ' ' # only MC - make combined message msgIntro.MC for sending ('SR;P0=-2560;P1=2560;P3=-640;D=10101010101010113;',) -# msgOutro => ' ' # only MC - make combined message MC.msgOutro for sending ('SR;P0=-8500;D=0;',) +# clockrange => [ , ] # only MC signals | min , max of pulse / pause times in microseconds +# clockabs => ' ' # only MU + MS signals | value for calculation of pulse / pause times in microseconds +# clockabs => '-1' # only MS signals | value pulse / pause times is automatically +# one => [ , ] # only MU + MS signals | value pair for a one bit, must be always a positive and negative factor of clockabs (accepted . | example 1.5) +# zero => [ , ] # only MU + MS signals | value pair for a zero bit, must be always a positive and negative factor of clockabs (accepted . | example -1.5) +# start => [ , ] # only MU - value pair or more for start message +# preSync => [ , ] # only MU + MS - value pair or more for preamble pulse of signal +# sync => [ , ] # only MS - value pair or more for sync pulse of signal +# float => [ , ] # only MU + MS signals | Convert 0F -> 01 (F) to be compatible with CUL +# pause => [ ] # only MU + MS signals, delay when sending between two repeats (clockabs * pause must be < 32768) +# end => [ ] # only MU + MS - value or more for end pulse of signal for sending +# msgIntro => ' ' # only MC - make combined message msgIntro.MC for sending ('SR;P0=-2560;P1=2560;P3=-640;D=10101010101010113;',) +# msgOutro => ' ' # only MC - make combined message MC.msgOutro for sending ('SR;P0=-8500;D=0;',) # -# length_min => ' ' # minimum number of bits of message length -# length_max => ' ' # maximum number of bits of message length -# paddingbits => ' ' # pad up to x bits before call module, default is 4. | --> option is active if paddingbits not defined in message definition ! -# paddingbits => '1' # will disable padding, use this setting when using dispatchBin -# paddingbits => '2' # is padded to an even number, that is a maximum of 1 bit -# remove_zero => 1 # removes leading zeros from output -# reconstructBit => 1 # if set, then the last bit is reconstructed if the rest is missing +# length_min => ' ' # minimum number of bits (MC, MS, MU) or nibbles (MN) of message length (MU, MS: If reconstructBit is set, then set length_min=length_min-1) +# length_max => ' ' # maximum number of bits (MC, MS, MU) or nibbles (MN) of message length +# paddingbits => ' ' # pad up to x bits before call module, default is 4. | --> option is active if paddingbits not defined in message definition ! +# paddingbits => '1' # will disable padding, use this setting when using dispatchBin +# paddingbits => '2' # is padded to an even number, that is a maximum of 1 bit +# remove_zero => 1 # removes leading zeros from output +# reconstructBit => 1 # If set, then the last bit is reconstructed if the rest is missing. (If reconstructBit is set, then set length_min=length_min-1) # -# developId => 'm' # logical module is under development -# developId => 'p' # protocol is under development or to reserve IDs, the ID in the development attribute with developId => 'p' are only used without the other entries -# developId => 'y' # protocol is under development, all IDs in the development attribute with developId => 'y' are used +# developId => 'm' # logical module is under development +# developId => 'p' # protocol is under development or to reserve IDs, the ID in the development attribute with developId => 'p' are only used without the other entries +# developId => 'y' # protocol is under development, all IDs in the development attribute with developId => 'y' are used # -# preamble => ' ' # prepend to converted message -# preamble => 'u..' # message is unknown and without module, forwarding SIGNALduino_un or FHEM DOIF -# preamble => 'U..' # message can be unknown and without module, no forwarding SIGNALduino_un but forwarding can FHEM DOIF -# postamble => ' ' # appends a string to the demodulated signal +# preamble => ' ' # prepend to converted message +# preamble => 'u..' # message is unknown and without module, forwarding SIGNALduino_un or FHEM DOIF +# preamble => 'U..' # message can be unknown and without module, no forwarding SIGNALduino_un but forwarding can FHEM DOIF +# postamble => ' ' # appends a string to the demodulated signal # -# clientmodule => ' ' # FHEM module for processing -# filterfunc => ' ' # SIGNALduino_filterSign | SIGNALduino_compPattern --> SIGNALduino internal filter function, it remove the sign from the pattern, and compress message and pattern -# # SIGNALduino_filterMC --> SIGNALduino internal filter function, it will decode MU data via Manchester encoding -# dispatchBin => 1, # If set to 1, data will be dispatched in binary representation to other logcial modules. -# If not set (default) or set to 0, data will be dispatched in hex mode to other logical modules. -# postDemodulation => \& # only MU - SIGNALduino internal sub for processing before dispatching to a logical module -# method => \& # call to process this message -# system method: lib::SD_Protocols::MCRAW -> returns bits without editing and length check included +# clientmodule => ' ' # FHEM module for processing +# filterfunc => ' ' # SIGNALduino_filterSign | SIGNALduino_compPattern --> SIGNALduino internal filter function, it remove the sign from the pattern, and compress message and pattern +# # SIGNALduino_filterMC --> SIGNALduino internal filter function, it will decode MU data via Manchester encoding +# dispatchBin => 1 # If set to 1, data will be dispatched in binary representation to other logcial modules. +# If not set (default) or set to 0, data will be dispatched in hex mode to other logical modules. +# dispatchequals => 'true' # Dispatch if dispatchequals is provided in protocol definition or only if $dmsg is different from last $dmsg, or if 2 seconds are between transmits +# postDemodulation => \& # only MU - SIGNALduino internal sub for processing before dispatching to a logical module +# method => \& # call to process this message +# system method: lib::SD_Protocols::MCRAW -> returns bits without editing and length check included # -# frequency => ' ' # frequency to set register cc1101 to send | example: 10AB85550A -# format => ' ' # twostate | pwm | manchester --> modulation type of the signal, only manchester use SIGNALduino internal, other types only comment -# modulematch => ' ' # RegEx on the exact message including preamble | if defined, it will be evaluated -# polarity => 'invert' # only MC signals | invert bits of the signal +# frequency => ' ' # frequency to set register cc1101 to send | example: 10AB85550A +# format => ' ' # twostate | pwm | manchester --> modulation type of the signal, only manchester use SIGNALduino internal, other types only comment +# modulematch => ' ' # RegEx on the exact message including preamble | if defined, it will be evaluated +# polarity => 'invert' # only MC signals | invert bits of the signal +# +# xFSK - Information +# datarate => ' ' # transmission speed signal +# modulation => ' ' # modulation type of the signal +# regexMatch => ' ' # Regex objct which must match on the raw message qr// +# register => ' ' # specifics cc1101 settings [$adr$value] +# rfmode => ' ' # receive mode, default SlowRF -> ASK/OOK +# sync => ' ' # sync parameter of signal in hex (example, 2DD4) # ##### notice #### or #### info ############################################################################################################ # !!! Between the keys and values ​​no tabs, please use spaces !!! # !!! Please use first unused id for new protocols !!! -# ID´s are currently unused: 78 -# ID´s need to be revised (preamble u): 5|19|21|22|23|24|25|28|31|36|40|52|54|56|59|63 +# ID´s are currently unused: 118 - +# ID´s need to be revised (preamble u): 5|19|21|22|23|25|28|31|36|40|52|59|63 ########################################################################################################################################### -# Please provide at least three messages for each new MU/MC/MS protocol and a URL of issue in GitHub or discussion in FHEM Forum +# Please provide at least three messages for each new MU/MC/MS/MN protocol and a URL of issue in GitHub or discussion in FHEM Forum # https://forum.fhem.de/index.php/topic,58396.975.html | https://github.com/RFD-FHEM/RFFHEM ########################################################################################################################################### -# $Id$ + +use strict; +use warnings; + package lib::SD_ProtocolData; -{ - use strict; - use warnings; - - our $VERSION = '1.21'; - our %protocols = ( - "0" => ## various weather sensors (500 | 9100) - # Mebus | Id:237 Ch:1 T: 1.9 Bat:low MS;P0=-9298;P1=495;P2=-1980;P3=-4239;D=1012121312131313121313121312121212121212131212131312131212;CP=1;SP=0;R=223;O;m2; - # GT_WT_02 | Id:163 Ch:1 T: 2.9 H: 86 Bat:ok MS;P0=531;P1=-9027;P3=-4126;P4=-2078;D=0103040304040403030404040404040404040404030303040303040304030304030304040403;CP=0;SP=1;R=249;O;m2; - # Prologue | Id:145 Ch:0 T: 2.6, Bat:ok MS;P0=-4152;P1=643;P2=-2068;P3=-9066;D=1310121210121212101210101212121212121212121212121010121012121212121012101212;CP=1;SP=3;R=220;O;m2; - # Prologue | Id:145 Ch:0 T: 2.7, Bat:ok MS;P0=-4149;P2=-9098;P3=628;P4=-2076;D=3230343430343434303430303434343434343434343434343030343030343434343034303434;CP=3;SP=2;R=218;O;m2; - { - name => 'weather (v1)', - comment => 'temperature / humidity or other sensors', - id => '0', - knownFreqs => '433.92', - one => [1,-7], - zero => [1,-3], - sync => [1,-16], - clockabs => -1, - format => 'twostate', # not used now - preamble => 's', # prepend to converted message - postamble => '00', # Append to converted message - clientmodule => 'CUL_TCM97001', - #modulematch => '^s[A-Fa-f0-9]+', - length_min => '24', - length_max => '40', - paddingbits => '8', # pad up to 8 bits, default is 4 - }, - "0.1" => ## other Sensors (380 | 9650) - # Mebus | Id:237 Ch:1 T: 1.3 Bat:low MS;P1=416;P2=-9618;P3=-4610;P4=-2036;D=1213141313131313141313141314141414141414141313141314131414;CP=1;SP=2;R=220;O;m0; - # Mebus | Id:151 Ch:1 T: 1.2 Bat:low MS;P0=-9690;P3=354;P4=-4662;P5=-2107;D=3034343434343535343534343435353535353535353434353535343535;CP=3;SP=0;R=209;O;m2; - # https://github.com/RFD-FHEM/RFFHEM/issues/63 @localhosthack0r - # AURIOL | Id:255 T: 0.0 Bat:ok | LIDL Wetterstation MS;P1=367;P2=-2077;P4=-9415;P5=-4014;D=141515151515151515121512121212121212121212121212121212121212121212;CP=1;SP=4;O; - { - name => 'weather (v2)', - comment => 'temperature / humidity or other sensors', - id => '0.1', - knownFreqs => '433.92', - one => [1,-12], - zero => [1,-6], - sync => [1,-26], - clockabs => -1, - format => 'twostate', # not used now - preamble => 's', # prepend to converted message - postamble => '00', # Append to converted message - clientmodule => 'CUL_TCM97001', - #modulematch => '^s[A-Fa-f0-9]+', - length_min => '24', - length_max => '32', - paddingbits => '8', - }, - "0.2" => ## other Sensors | for sensors how tol is runaway (260+tol | 9650) - # Mebus | Id:151 Ch:1 T: 0.4 Bat:low MS;P1=-2140;P2=309;P3=-4690;P4=-9695;D=2421232323232121232123232321212121212121212123212121232121;CP=2;SP=4;R=211;m1; - # Mebus | Id:151 Ch:1 T: 0.3 Bat:low MS;P0=-9703;P1=304;P2=-2133;P3=-4689;D=1012131312131212131213131312121212121212121212131312131212;CP=1;SP=0;R=208; - { - name => 'weather (v3)', - comment => 'temperature / humidity or other sensors', - id => '0.2', - knownFreqs => '433.92', - one => [1,-18], - zero => [1,-9], - sync => [1,-37], - clockabs => -1, - format => 'twostate', # not used now - preamble => 's', # prepend to converted message - postamble => '00', # Append to converted message - clientmodule => 'CUL_TCM97001', - #modulematch => '^s[A-Fa-f0-9]+', - length_min => '24', - length_max => '32', - paddingbits => '8', - }, - "0.3" => ## Pollin PFR-130 - # CUL_TCM97001_Unknown MS;P0=-3890;P1=386;P2=-2191;P3=-8184;D=1312121212121012121212121012121212101012101010121012121210121210101210101012;CP=1;SP=3;R=20;O; - # CUL_TCM97001_Unknown MS;P0=-2189;P1=371;P2=-3901;P3=-8158;D=1310101010101210101010101210101010121210121212101210101012101012121012121210;CP=1;SP=3;R=20;O; - # Ventus W174 | Id:17 R: 103.25 Bat:ok MS;P3=-2009;P4=479;P5=-9066;P6=-4047;D=45434343464343434643464643464643434643464646434346464343434343434346464643;CP=4;SP=5;R=55;O;m2; - { - name => 'weather (v4)', - comment => 'temperature / humidity or other sensors | Pollin PFR-130, Ventus W174 ...', - id => '0.3', - knownFreqs => '433.92', - one => [1,-10], - zero => [1,-5], - sync => [1,-21], - clockabs => -1, - preamble => 's', # prepend to converted message - postamble => '00', # Append to converted message - clientmodule => 'CUL_TCM97001', - length_min => '36', - length_max => '42', - paddingbits => '8', # pad up to 8 bits, default is 4 - }, - "0.4" => ## Auriol Z31092 (450 | 9200) - # AURIOL | Id:95 T: 6.1 Bat:low MS;P0=443;P3=-9169;P4=-1993;P5=-3954;D=030405040505050505050404040404040404040505050504050405050504040405;CP=0;SP=3;R=14;O;m0; - # AURIOL | Id:190 T: 2.8 Bat:low MS;P0=-9102;P1=446;P2=-3956;P3=-2008;D=10121312121212121312131213131313131313131212121313121213121213121314;CP=1;SP=0;R=212;O;m2; - { - name => 'weather (v5)', - comment => 'temperature / humidity or other sensors | Auriol Z31092', - id => '0.4', - knownFreqs => '433.92', - one => [1,-9], - zero => [1,-4], - sync => [1,-20], - clockabs => 450, - preamble => 's', # prepend to converted message - postamble => '00', # Append to converted message - clientmodule => 'CUL_TCM97001', - length_min => '32', - length_max => '36', - paddingbits => '8', # pad up to 8 bits, default is 4 - }, - "0.5" => ## various weather sensors (475 | 8000) - # ABS700 | Id:79 T: 3.3 Bat:low MS;P1=-7949;P2=492;P3=-1978;P4=-3970;D=21232423232424242423232323232324242423232323232424;CP=2;SP=1;R=245;O; - # ABS700 | Id:69 T: 9.3 Bat:low MS;P1=-7948;P2=471;P3=-1997;P4=-3964;D=21232423232324232423232323242323242423232323232424;CP=2;SP=1;R=246;O;m2; - { - name => 'weather (v6)', - comment => 'temperature / humidity or other sensors | ABS700', - id => '0.5', - knownFreqs => '433.92', - one => [1,-8], - zero => [1,-4], - sync => [1,-16], - clockabs => 475, - format => 'twostate', # not used now - preamble => 's', # prepend to converted message - postamble => '00', # Append to converted message - clientmodule => 'CUL_TCM97001', - #modulematch => '^s[A-Fa-f0-9]+', - length_min => '24', - length_max => '24', - paddingbits => '8', # pad up to 8 bits, default is 4 - }, - "1" => ## Conrad RSL - # on MS;P1=1154;P2=-697;P3=559;P4=-1303;P5=-7173;D=351234341234341212341212123412343412341234341234343434343434343434;CP=3;SP=5;R=247;O; - # on MS;P0=561;P1=-1291;P2=-7158;P3=1174;P4=-688;D=023401013401013434013434340134010134013401013401010101010101010101;CP=0;SP=2;R=248;m1; - { - name => 'Conrad RSL v1', - comment => 'remotes and switches', - id => '1', - knownFreqs => '', - one => [2,-1], - zero => [1,-2], - sync => [1,-12], - clockabs => '560', - format => 'twostate', # not used now - preamble => 'P1#', # prepend to converted message - postamble => '', # Append to converted message - clientmodule => 'SD_RSL', - modulematch => '^P1#[A-Fa-f0-9]{8}', - length_min => '20', # 23 | userMSG 32 ? - length_max => '40', # 24 | userMSG 32 ? - }, - "2" => ## Self build arduino sensor - { - name => 'Arduino', - comment => 'self build arduino sensor (developModule. SD_AS module only in github)', - developId => 'm', - id => '2', - knownFreqs => '', - one => [1,-2], - zero => [1,-1], - sync => [1,-20], - clockabs => '500', - format => 'twostate', - preamble => 'P2#', # prepend to converted message - clientmodule => 'SD_AS', - modulematch => '^P2#.{7,8}', - length_min => '32', - length_max => '34', # Don't know maximal lenth of a valid message - paddingbits => '8', # pad up to 8 bits, default is 4 - }, - "3" => ## itv1 - remote with IC PT2262 example: ELRO | REWE | Intertek Modell 1946518 | WOFI Lamp // PIR JCHENG with Wireless Coding EV1527 - ## (real CP=300 | repeatpause=9300) - # REWE Model: 0175926R -> on | v1 MS;P1=-905;P2=896;P3=-317;P4=303;P5=-9299;D=45412341414123412341414123412341234141412341414123;CP=4;SP=5;R=91;A;#; - ## (real CP=330 | repeatpause=10100) - # ELRO AB440R -> on | v1 MS;P1=-991;P2=953;P3=-356;P4=303;P5=-10033;D=45412341234141414141234123412341234141412341414123;CP=4;SP=5;R=93;m1;A;A; - ## (real CP=300 | repeatpause=9400) - # Kangtai Model Nr.: 6899 -> on | v1 MS;P0=-328;P1=263;P2=-954;P3=888;P5=-9430;D=15123012121230123012121230123012301212123012121230;CP=1;SP=5;R=35;m2;0;0; - # door/window switch from CHN (PT2262 compatible) from amazon & ebay | itswitch_CHN model - # open MS;P1=-478;P2=1360;P3=468;P4=-1366;P5=-14045;D=35212134212134343421212134213434343434343421342134;CP=3;SP=5;R=30;O;m2;4; - # close MS;P1=-474;P2=1373;P3=455;P4=-1367;P5=-14044;D=35212134212134343421212134213434343434343421212134;CP=3;SP=5;R=37;O;m2; - ## JCHENG SECURITY Wireless PIR - # (only autocreate -> J2 Data setting D0 open | D1 closed | D2 closed | D3 open) - # on MS;P1=-12541;P2=1227;P3=-405;P4=407;P5=-1209;D=41232323232345452323454523452323234545234545232345;CP=4;SP=1;R=35;O;m2;E; - ## benon (Semexo OHG) | remote BH-P with 5 Channels, switch B2112 | Amazon - ## (real CP=160) chip HS2260C-R4 | length 24 - # on MS;P0=160;P4=-542;P5=515;P6=-174;P7=-5406;D=07040404560404045604560456045604560404565604045656;CP=0;SP=7;R=24;O;m2; - # off MS;P1=-538;P2=163;P3=518;P4=-175;P5=-5396;D=25212121342121213421342134213421342121343434342121;CP=2;SP=5;R=31;O;m2;4; - { - name => 'chip xx2260 / xx2262', - comment => 'remote for benon|ELRO|Kangtai|Intertek|REWE|WOFI / PIR JCHENG', - id => '3', - knownFreqs => '433.92', - one => [3,-1], - zero => [1,-3], - #float => [-1,3], # not full supported now later use - sync => [1,-31], - clockabs => -1, # -1=auto - format => 'twostate', # not used now - preamble => 'i', - clientmodule => 'IT', - modulematch => '^i......', - length_min => '24', - length_max => '24', # Don't know maximal lenth of a valid message - }, - "3.1" => ## itv1_sync40 | Intertek Modell 1946518 | ELRO - # no decode! MS;P0=-11440;P1=-1121;P2=-416;P5=309;P6=1017;D=150516251515162516251625162516251515151516251625151;CP=5;SP=0;R=66; - # on | v1 MS;P1=309;P2=-1130;P3=1011;P4=-429;P5=-11466;D=15123412121234123412141214121412141212123412341234;CP=1;SP=5;R=38; Gruppentaste, siehe Kommentar in sub SIGNALduino_bit2itv1 - # need more Device Infos / User Message - { - name => 'itv1_sync40', - comment => 'IT remote control PAR 1000, ITS-150, AB440R', - id => '3', - knownFreqs => '', - one => [3.5,-1], - zero => [1,-3.8], - float => [1,-1], # fuer Gruppentaste (nur bei ITS-150,ITR-3500 und ITR-300), siehe Kommentar in sub SIGNALduino_bit2itv1 - sync => [1,-44], - clockabs => -1, # -1=auto - format => 'twostate', # not used now - preamble => 'i', - clientmodule => 'IT', - modulematch => '^i......', - length_min => '24', - length_max => '24', # Don't know maximal lenth of a valid message - postDemodulation => \&main::SIGNALduino_bit2itv1, - }, - "4" => ## arctech2 - # need more Device Infos / User Message - { - name => 'arctech2', - id => '4', - knownFreqs => '', - #one => [1,-5,1,-1], - #zero => [1,-1,1,-5], - one => [1,-5], - zero => [1,-1], - #float => [-1,3], # not full supported now, for later use - sync => [1,-14], - clockabs => -1, # -1 = auto - format => 'twostate', # tristate can't be migrated from bin into hex! - preamble => 'i', # Append to converted message - postamble => '00', # Append to converted message - clientmodule => 'IT', - modulematch => '^i......', - length_min => '39', - length_max => '44', # Don't know maximal lenth of a valid message - }, - "5" => # Unitec, Modellnummer 6899/45108 - # https://github.com/RFD-FHEM/RFFHEM/pull/389#discussion_r237232347 @sidey79 | https://github.com/RFD-FHEM/RFFHEM/pull/389#discussion_r237245943 - # no decode! MU;P0=-31960;P1=660;P2=401;P3=-1749;P5=276;D=232353232323232323232323232353535353232323535353535353535353535010;CP=5;R=38; - # no decode! MU;P0=-1757;P1=124;P2=218;P3=282;P5=-31972;P6=644;P7=-9624;D=010201020303030202030303020303030202020202020203030303035670;CP=2;R=32; - # no decode! MU;P0=-1850;P1=172;P3=-136;P5=468;P6=236;D=010101010101310506010101010101010101010101010101010101010;CP=1;R=30; - # A AN MU;P0=132;P1=-4680;P2=508;P3=-1775;P4=287;P6=192;D=123434343434343634343436363434343636343434363634343036363434343;CP=4;R=2; - # A AUS MU;P0=-1692;P1=132;P2=194;P4=355;P5=474;P7=-31892;D=010202040505050505050404040404040404040470;CP=4;R=27; - { - name => 'Unitec', - comment => 'remote control model 6899/45108', - id => '5', - knownFreqs => '', - one => [3,-1], # ? - zero => [1,-3], # ? - clockabs => 500, # ? - developId => 'y', - format => 'twostate', - preamble => 'u5#', - #clientmodule => '', - #modulematch => '', - length_min => '24', # ? - length_max => '24', # ? - }, - "6" => ## TCM 218943, Eurochron - # https://github.com/RFD-FHEM/RFFHEM/issues/692 @ Ralf9 2019-11-15 - # T:22.9, H:24 MS;P0=-970;P1=254;P3=-1983;P4=-8045;D=14101310131010101310101010101010101010101313101010101010101313131010131013;CP=1;SP=4; - # T:22.7, H:23, tx MS;P0=-2054;P1=236;P2=-1032;P3=-7760;D=13121012101212121012121210121212121212121012101010121212121010101212121010;CP=1;SP=3; - { - name => 'TCM 218943', - comment => 'Weatherstation TCM 218943, Eurochron', - id => '6', - knownFreqs => '433.92', - one => [1,-5], - zero => [1,-10], - sync => [1,-32], - clockabs => 248, - format => 'twostate', - preamble => 's', # prepend to converted message - postamble => '00', # append to converted message - clientmodule => 'CUL_TCM97001', - length_min => '36', # sync, postamble und paddingbits werden nicht mitgezaehlt - length_max => '36', # sync, postamble und paddingbits werden nicht mitgezaehlt - paddingbits => '8', # pad up to 8 bits, default is 4 - }, - "7" => ## weather sensors like EAS800z - # Ch:1 T: 19.8 H: 11 Bat:low MS;P1=-3882;P2=504;P3=-957;P4=-1949;D=21232424232323242423232323232323232424232323242423242424242323232324232424;CP=2;SP=1;R=249;m=2; - # https://forum.fhem.de/index.php/topic,101682.0.html (Auriol AFW 2 A1, IAN: 297514) - # Ch:1 T: 28.2 H: 44 Bat:ok MS;P0=494;P1=-1949;P2=-967;P3=-3901;D=03010201010202020101020202020202010202020101020102010201020202010201010202;CP=0;SP=3;R=37;m0; - # Ch:1 T: 24.4 H: 56 Bat:ok MS;P1=-1940;P2=495;P3=-957;P4=-3878;D=24212321212323232121232323232323232121212123212323212321232323212121232323;CP=2;SP=4;R=20;O;m1; - { - name => 'Weather', - comment => 'EAS800z, FreeTec NC-7344, HAMA TS34A, Auriol AFW 2 A1', - id => '7', - knownFreqs => '433.92', - one => [1,-4], - zero => [1,-2], - sync => [1,-8], - clockabs => 484, - format => 'twostate', - preamble => 'P7#', # prepend to converted message - clientmodule => 'SD_WS07', - modulematch => '^P7#.{6}[AFaf].{2}', - length_min => '35', - length_max => '40', - }, - "8" => ## TX3 (ITTX) Protocol - # Id:97 T: 24.4 MU;P0=-1046;P1=1339;P2=524;P3=-28696;D=010201010101010202010101010202010202020102010101020101010202020102010101010202310101010201020101010101020201010101020201020202010201010102010101020202010201010101020;CP=2;R=4; - { - name => 'TX3 Protocol', - id => '8', - knownFreqs => '', - one => [1,-2], - zero => [2,-2], - #sync => [1,-8], # - clockabs => 470, - format => 'pwm', # - preamble => 'TX', # prepend to converted message - clientmodule => 'CUL_TX', - modulematch => '^TX......', - length_min => '43', - length_max => '44', - remove_zero => 1, # Removes leading zeros from output - }, - "9" => ## Funk Wetterstation CTW600 - ### ! some message are decode as protocol 42 and 75 ! - ## WH3080 | UV: 4 Lux: 57970 | @Ralf - # MU;P0=-1424;P1=1417;P2=-1058;P3=453;P4=-24774;P6=288;P7=-788;D=01212121232343232323232323232123232323232121232121212123212121232123212321232121212123212121232321232321212121232323212321212121212121212323467323232323232323212323232323212123212121212321212123212321232123212121212321212123232123232121212123232321232121;CP=3;R=247;O; - ## WH1080 - # https://forum.fhem.de/index.php/topic,39451.msg844155.html#msg844155 | https://forum.fhem.de/index.php/topic,39451.msg848667.html#msg848667 @maddinthebrain - # MU;P0=-31072;P1=486;P2=-986;P3=1454;D=01212121212121212321232321232123232121232323212121212123232123232123212321232123232323232321232323232323212323232323232323232123212121212321232323232323232323212321212321232301212121212121212321232321232123232121232323212121212123232123232123212321232123;CP=1;R=29;O; - ## CTW600 - # https://forum.fhem.de/index.php/topic,39451.msg917042.html#msg917042 @greewoo - # MU;P0=-96;P1=800;P2=-985;P3=485;P4=1421;P5=-8608;D=0123232323232323242324232324242324232324242324242324232323242324242323232324242424242424242424242424242424242424242424242424242424242424242424242424242424242324242424232323235;CP=4;R=0; - { - name => 'weather', - comment => 'Weatherstation WH1080, WH3080, WH5300SE, CTW600', - id => '9', - knownFreqs => '433.92 | 868.35', - zero => [3,-2], - one => [1,-2], - clockabs => 480, # -1 = auto undef=noclock - format => 'pwm', # tristate can't be migrated from bin into hex! - preamble => 'P9#', # prepend to converted message - clientmodule => 'SD_WS09', - #modulematch => '^u9#.....', - length_min => '60', - length_max => '120', - reconstructBit => '1', - }, - "10" => ## Oregon Scientific 2 - # https://forum.fhem.de/index.php/topic,60170.msg875919.html#msg875919 @David1 - # MC;LL=-973;LH=984;SL=-478;SH=493;D=EF7E2DCC00000283AF5DF7CFEFEF7E2DCC;C=487;L=134;R=33;s5;b0; - # MC;LL=-975;LH=976;SL=-491;SH=491;D=BEF9FDFDEFC5B98000005075EBBEF9FDFDEFC5;C=488;L=152;R=34;s1;b0;O;w; - { - name => 'Oregon Scientific v2|v3', - comment => 'temperature / humidity or other sensors', - id => '10', - knownFreqs => '', - clockrange => [300,520], # min , max - format => 'manchester', # tristate can't be migrated from bin into hex! - clientmodule => 'OREGON', - modulematch => '^(3[8-9A-F]|[4-6][0-9A-F]|7[0-8]).*', - length_min => '64', - length_max => '220', - method => \&main::SIGNALduino_OSV2, # Call to process this message - polarity => 'invert', - }, - "11" => ## Arduino Sensor - { - name => 'Arduino', - comment => 'for Arduino based sensors', - id => '11', - knownFreqs => '', - clockrange => [380,425], # min , max - format => 'manchester', # tristate can't be migrated from bin into hex! - preamble => 'P2#', # prepend to converted message - clientmodule => 'SD_AS', - modulematch => '^P2#.{7,8}', - length_min => '52', - length_max => '56', - method => \&main::SIGNALduino_AS # Call to process this message - }, - "12" => ## Hideki - # Id:31 Ch:1 T: 22.7 Bat:ok MC;LL=-1040;LH=904;SL=-542;SH=426;D=A8C233B53A3E0A0783;C=485;L=72;R=213; - { - name => 'Hideki', - comment => 'temperature / humidity or other sensors', - id => '12', - knownFreqs => '433.92', - clockrange => [420,510], # min, max better for Bresser Sensors, OK for hideki/Hideki/TFA too - format => 'manchester', - preamble => 'P12#', # prepend to converted message - clientmodule => 'Hideki', - modulematch => '^P12#75.+', - length_min => '71', - length_max => '128', - method => \&main::SIGNALduino_Hideki, # Call to process this message - #polarity => 'invert', - }, - "13" => ## FLAMINGO FA21 - # https://github.com/RFD-FHEM/RFFHEM/issues/21 @sidey79 - # https://github.com/RFD-FHEM/RFFHEM/issues/233 - # 32E44F | Alarm MS;P0=-1413;P1=757;P2=-2779;P3=-16079;P4=8093;P5=-954;D=1345121210101212101210101012121012121210121210101010;CP=1;SP=3;R=33;O; - { - name => 'FLAMINGO FA21', - comment => 'FLAMINGO FA21 smoke detector (message decode as MS)', - id => '13', - knownFreqs => '433.92', - one => [1,-2], - zero => [1,-4], - sync => [1,-20,10,-1], - clockabs => 800, - format => 'twostate', - preamble => 'P13#', # prepend to converted message - clientmodule => 'FLAMINGO', - #modulematch => 'P13#.*', - length_min => '24', - length_max => '26', - }, - "13.1" => ## FLAMINGO FA20RF - # B67C3B | Alarm MU;P0=-1384;P1=815;P2=-2725;P3=-20001;P4=8159;P5=-891;D=01010121212121010101210101345101210101210101212101010101012121212101010121010134510121010121010121210101010101212121210101012101013451012101012101012121010101010121212121010101210101345101210101210101212101010101012121212101010121010134510121010121010121;CP=1;O; - # 1B61BB | Alarm MU;P0=-17201;P1=112;P2=-1419;P3=-28056;P4=8092;P5=-942;P6=777;P7=-2755;D=12134567676762626762626762626767676762626762626267626260456767676262676262676262676767676262676262626762626045676767626267626267626267676767626267626262676262604567676762626762626762626767676762626762626267626260456767676262676262676262676767676262676262;CP=6;O; - ## FLAMINGO FA22RF (only MU Message) @HomeAutoUser - # CBFAD2 | Alarm MU;P0=-5684;P1=8149;P2=-887;P3=798;P4=-1393;P5=-2746;P6=-19956;D=0123434353534353434343434343435343534343534353534353612343435353435343434343434343534353434353435353435361234343535343534343434343434353435343435343535343536123434353534353434343434343435343534343534353534353612343435353435343434343434343534353434353435;CP=3;R=0; - # Times measured - # Sync 8100 microSec, 900 microSec | Bit1 2700 microSec low - 800 microSec high | Bit0 1400 microSec low - 800 microSec high | Pause Repeat 20000 microSec | 1 Sync + 24Bit, Totaltime 65550 microSec without Sync - { - name => 'FLAMINGO FA22RF / FA21RF / LM-101LD', - comment => 'FLAMINGO | Unitec smoke detector (message decode as MU)', - id => '13.1', - knownFreqs => '433.92', - one => [1,-1.8], - zero => [1,-3.5], - start => [10,-1], - pause => [-25], - clockabs => 800, - format => 'twostate', - preamble => 'P13.1#', # prepend to converted message - clientmodule => 'FLAMINGO', - #modulematch => '^P13\.?1?#[A-Fa-f0-9]+', - length_min => '24', - length_max => '24', - }, - "13.2" => ## LM-101LD Rauchm - # https://github.com/RFD-FHEM/RFFHEM/issues/233 @Ralf9 - # B0FFAF | Alarm MS;P1=-2708;P2=796;P3=-1387;P4=-8477;P5=8136;P6=-904;D=2456212321212323232321212121212121212123212321212121;CP=2;SP=4; - { - name => 'LM-101LD', - comment => 'Unitec smoke detector (message decode as MS)', - id => '13', - knownFreqs => '433.92', - zero => [1,-1.8], - one => [1,-3.5], - sync => [1,-11,10,-1.2], - clockabs => 790, - format => 'twostate', - preamble => 'P13#', # prepend to converted message - clientmodule => 'FLAMINGO', - #modulematch => '', - length_min => '24', - length_max => '24', - }, - "14" => ## LED X-MAS Chilitec model 22640 - # https://github.com/RFD-FHEM/RFFHEM/issues/421 | https://forum.fhem.de/index.php/topic,94211.msg869214.html#msg869214 @privat58 - # power_on MS;P0=988;P1=-384;P2=346;P3=-1026;P4=-4923;D=240123012301230123012323232323232301232323;CP=2;SP=4;R=0;O;m=1; - # brightness_plus MS;P0=-398;P1=974;P3=338;P4=-1034;P6=-4939;D=361034103410341034103434343434343410103434;CP=3;SP=6;R=0; - { - name => 'LED X-MAS', - comment => 'Chilitec model 22640', - id => '14', - knownFreqs => '433.92', - one => [3,-1], - zero => [1,-3], - sync => [1,-14], - clockabs => 350, - format => 'twostate', - preamble => 'P14#', # prepend to converted message - clientmodule => 'SD_UT', - #modulematch => '^P14#.*', - length_min => '20', - length_max => '20', - }, - "15" => ## TCM 234759 - { - name => 'TCM 234759 Bell', - comment => 'wireless doorbell TCM 234759 Tchibo', - id => '15', - knownFreqs => '', - one => [1,-1], - zero => [1,-2], - sync => [1,-45], - clockabs => 700, - format => 'twostate', - preamble => 'P15#', # prepend to converted message - clientmodule => 'SD_BELL', - modulematch => '^P15#.*', - length_min => '10', - length_max => '20', - }, - "16" => ## Rohrmotor24 und andere Funk Rolladen / Markisen Motoren - # ! same definition how ID 72 ! - # https://forum.fhem.de/index.php/topic,49523.0.html - # closed MU;P0=-1608;P1=-785;P2=288;P3=650;P4=-419;P5=4676;D=1212121213434212134213434212121343434212121213421213434212134345021213434213434342121212121343421213421343421212134343421212121342121343421213432;CP=2; - # closed MU;P0=-1562;P1=-411;P2=297;P3=-773;P4=668;P5=4754;D=1232341234141234141234141414123414123232341232341412323414150234123234123232323232323234123414123414123414141412341412323234123234141232341415023412323412323232323232323412341412341412341414141234141232323412323414123234142;CP=2; - { - name => 'Dooya', - comment => 'Rohrmotor24 and other radio shutters / awnings motors', - id => '16', - knownFreqs => '', - one => [2,-1], - zero => [1,-3], - start => [17,-5], - clockabs => 280, - format => 'twostate', - preamble => 'P16#', # prepend to converted message - clientmodule => 'Dooya', - #modulematch => '', - length_min => '39', - length_max => '40', - }, - "17" => ## arctech / intertechno - # need more Device Infos / User Message - { - name => 'arctech / Intertechno', - id => '17', - knownFreqs => '', - one => [1,-5,1,-1], - zero => [1,-1,1,-5], - #one => [1,-5], - #zero => [1,-1], - sync => [1,-10], - float => [1,-1,1,-1], - end => [1,-40], - clockabs => -1, # -1 = auto - format => 'twostate', # tristate can't be migrated from bin into hex! - preamble => 'i', # Append to converted message - postamble => '00', # Append to converted message - clientmodule => 'IT', - modulematch => '^i......', - length_min => '32', - length_max => '34', # Don't know maximal lenth of a valid message - postDemodulation => \&main::SIGNALduino_bit2Arctec, - }, - "17.1" => ## intertechno --> MU anstatt sonst MS (ID 17) - # no decode! MU;P0=344;P1=-1230;P2=-200;D=01020201020101020102020102010102010201020102010201020201020102010201020101020102020102010201020102010201010200;CP=0;R=0; - # no decode! MU;P0=346;P1=-1227;P2=-190;P4=-10224;P5=-2580;D=0102010102020101020201020101020102020102010102010201020102010201020201020102010201020101020102020102010102020102010201020104050201020102010102020101020201020101020102020102010102010201020102010201020201020102010201020101020102020102010102020102010201020;CP=0;R=0; - # no decode! MU;P0=351;P1=-1220;P2=-185;D=01 0201 0102 020101020201020101020102020102010102010201020102010201020201020102010201020101020102020102010201020102010201020100;CP=0;R=0; - # off | v3 MU;P0=355;P1=-189;P2=-1222;P3=-10252;P4=-2604;D=01020201010201020201020101020102020102010201020102010201010201020102010201020201020101020102010201020102010201020 304 0102 01020102020101020201010201020201020101020102020102010201020102010201010201020102010201020201020101020102010201020102010201020 304 01020;CP=0;R=0; - # https://www.sweetpi.de/blog/329/ein-ueberblick-ueber-433mhz-funksteckdosen-und-deren-protokolle - { - name => 'Intertechno', - comment => 'PIR-1000 | ITT-1500', - id => '17.1', - knownFreqs => '433.92', - one => [1,-5,1,-1], - zero => [1,-1,1,-5], - clockabs => 230, # -1 = auto - format => 'twostate', # tristate can't be migrated from bin into hex! - preamble => 'i', # Append to converted message - postamble => '00', # Append to converted message - clientmodule => 'IT', - modulematch => '^i......', - length_min => '32', - length_max => '34', # Don't know maximal lenth of a valid message - postDemodulation => \&main::SIGNALduino_bit2Arctec, - }, - "18" => ## Oregon Scientific v1 - # Id:3 T: 7.5 BAT:ok MC;LL=-2721;LH=3139;SL=-1246;SH=1677;D=1A51FF47;C=1463;L=32;R=12; - { - name => 'Oregon Scientific v1', - comment => 'temperature / humidity or other sensors', - id => '18', - knownFreqs => '', - clockrange => [1400,1500], # min , max - format => 'manchester', # tristate can't be migrated from bin into hex! - preamble => '', - clientmodule => 'OREGON', - modulematch => '^[0-9A-F].*', - length_min => '32', - length_max => '32', - polarity => 'invert', # invert bits - method => \&main::SIGNALduino_OSV1 # Call to process this message - }, - "19" => ## minify Funksteckdose - # https://github.com/RFD-FHEM/RFFHEM/issues/114 @zag-o-mat - # u19#E2CA7C MU;P0=293;P1=-887;P2=-312;P6=-1900;P7=872;D=6727272010101720172720101720172010172727272720;CP=0; - # u19#E2CA7C MU;P0=9078;P1=-308;P2=180;P3=-835;P4=881;P5=309;P6=-1316;D=0123414141535353415341415353415341535341414141415603;CP=5; - { - name => 'minify', - comment => 'remote control RC202', - id => '19', - knownFreqs => '', - one => [3,-1], - zero => [1,-3], - clockabs => 300, - format => 'twostate', - preamble => 'u19#', # prepend to converted message - #clientmodule => '', - #modulematch => '', - length_min => '19', - length_max => '23', # not confirmed, length one more as MU Message - }, - "20" => ## Remote control with 4 buttons for diesel heating - # https://forum.fhem.de/index.php/topic,58397.msg999475.html#msg999475 @ fhem_user0815 2019-12-04 - # RCnoName20_17E9 on MS;P0=-740;P2=686;P3=-283;P5=229;P6=-7889;D=5650505023502323232323235023505023505050235050502323502323505050;CP=5;SP=6;R=67;O;m2; - # RCnoName20_17E9 off MS;P1=-754;P2=213;P4=681;P5=-283;P6=-7869;D=2621212145214545454545452145212145212121212145214521212121452121;CP=2;SP=6;R=69;O;m2; - # RCnoName20_17E9 plus MS;P1=-744;P2=221;P3=679;P4=-278;P5=-7860;D=2521212134213434343434342134212134212121213421212134343434212121;CP=2;SP=5;R=66;O;m2; - # RCnoName20_17E9 minus MS;P0=233;P1=-7903;P3=-278;P5=-738;P6=679;D=0105050563056363636363630563050563050505050505630563050505630505;CP=0;SP=1;R=71;O;m1; - { - name => 'RCnoName20', - comment => 'Remote control with 4 buttons for diesel heating', - id => '20', - knownFreqs => '433.92', - one => [3,-1], # 720,-240 - zero => [1,-3], # 240,-720 - sync => [1,-33], # 240,-7920 - clockabs => 240, - format => 'twostate', - preamble => 'P20#', - clientmodule => 'SD_UT', - modulematch => '^P20#.{8}', - length_min => '31', - length_max => '32', - }, - "21" => ## Einhell Garagentor - # https://forum.fhem.de/index.php?topic=42373.0 @Ellert | user have no RAWMSG - # static adress: Bit 1-28 | channel remote Bit 29-32 | repeats 31 | pause 20 ms - # Channelvalues dez - # 1 left 1x kurz | 2 left 2x kurz | 3 left 3x kurz | 5 right 1x kurz | 6 right 2x kurz | 7 right 3x kurz ... gedrückt - { - name => 'Einhell Garagedoor', - comment => 'remote control ISC HS 434/6', - id => '21', - knownFreqs => '', - one => [-3,1], - zero => [-1,3], - #sync => [-50,1], - start => [-50,1], - clockabs => 400, #ca 400us - format => 'twostate', - preamble => 'u21#', # prepend to converted message - #clientmodule => '', - #modulematch => '', - length_min => '32', - length_max => '32', - paddingbits => '1', # This will disable padding - }, - "22" => ## HAMULiGHT LED Trafo - # https://forum.fhem.de/index.php?topic=89301.0 - # u22#8F995F34 MU;P0=-589;P1=209;P2=-336;P3=32001;P4=-204;P5=1194;P6=-1200;P7=602;D=0123414145610747474101010101074741010747410741074101010101074741010741074741414141456107474741010101010747410107474107410741010101010747410107410747414141414561074747410101010107474101074741074107410101010107474101074107474141414145610747474101010101074;CP=1;R=25; - # u22#8F995F34 MU;P0=204;P1=-596;P2=598;P3=-206;P4=1199;P5=-1197;D=0123230123012301010101012323010123012323030303034501232323010101010123230101232301230123010101010123230101230123230303030345012323230101010101232301012323012301230101010101232301012301232303030303450123232301010101012323010123230123012301010101012323010;CP=0;R=25; - { - name => 'HAMULiGHT', - comment => 'remote control for LED Transformator', - id => '22', - knownFreqs => '433.92', - one => [1,-3], - zero => [3,-1], - start => [6,-6], - clockabs => 200, # ca 200us - format => 'twostate', - preamble => 'u22#', # prepend to converted message - #clientmodule => '', - #modulematch => '', - length_min => '32', - length_max => '32', - }, - "23" => ## Pearl Sensor - { - name => 'Pearl', - comment => 'unknown sensortyp', - id => '23', - knownFreqs => '', - one => [1,-6], - zero => [1,-1], - sync => [1,-50], - clockabs => 200, #ca 200us - format => 'twostate', - preamble => 'u23#', # prepend to converted message - #clientmodule => '', - #modulematch => '', - length_min => '36', - length_max => '44', - }, - "24" => ## visivon - # https://github.com/RFD-FHEM/RFFHEM/issues/39 @sidey79 - # u24#9F7DF825029C10 MU;P0=132;P1=500;P2=-233;P3=-598;P4=-980;P5=4526;D=012120303030303120303030453120303121212121203121212121203121212121212030303030312030312031203030303030312031203031212120303030303120303030453120303121212121203121212121203121212121212030303030312030312031203030303030312031203031212120303030;CP=0;O; - { - name => 'visivon remote', - id => '24', - knownFreqs => '', - one => [3,-2], - zero => [1,-5], - #one => [3,-2], - #zero => [1,-1], - start => [30,-5], - clockabs => 150, #ca 150us - format => 'twostate', - preamble => 'u24#', # prepend to converted message - #clientmodule => '', - #modulematch => '', - length_min => '54', - length_max => '58', - }, - "25" => ## LES remote for led lamp - # https://github.com/RFD-FHEM/RFFHEM/issues/40 @sidey79 - # u25#45A06B MS;P0=-376;P1=697;P2=-726;P3=322;P4=-13188;P5=-15982;D=3530123010101230123230123010101010101232301230123234301230101012301232301230101010101012323012301232;CP=3;SP=5;O; - { - name => 'les led remote', - id => '25', - knownFreqs => '', - one => [-2,1], - zero => [-1,2], - sync => [-46,1], # this is a end marker, but we use this as a start marker - clockabs => 350, #ca 350us - format => 'twostate', - preamble => 'u25#', # prepend to converted message - #clientmodule => '', - #modulematch => '', - length_min => '24', - length_max => '50', # message has only 24 bit, but we get more than one message, calculation has to be corrected - }, - "26" => ## xavax 00111939 Funksteckdosen Set - # https://github.com/RFD-FHEM/RFFHEM/issues/717 @codeartisan-de 2019-12-14 - # xavax_DAAB2554 Ch1_on MU;P0=412;P1=-534;P2=-1356;P3=-20601;P4=3360;P5=-3470;D=01020102010201020201010201010201020102010201020101020101010102020203010145020201020201020102010201020102020101020101020102010201020102010102010101010202020301014502020102020102010201020102010202010102010102010201020102010201010201010101020202030101450202;CP=0;R=0;O; - # xavax_DAAB2554 Ch1_off MU;P0=-3504;P1=416;P2=-1356;P3=-535;P4=-20816;P5=3324;D=01212131212131213121312131213121213131213131213121312131213121313131212121213131314131350121213121213121312131213121312121313121313121312131213121312131313121212121313131413135012121312121312131213121312131212131312131312131213121312131213131312121212131;CP=1;R=50;O; - # xavax_DAAB2554 Ch2_on MU;P0=5656;P1=-21857;P2=413;P3=-1354;P4=-536;P6=3350;P7=-3487;D=01232423232424232424232423242324232423242424232424232423232124246723232423232423242324232423242323242423242423242324232423242324242423242423242323212424672323242323242324232423242324232324242324242324232423242324232424242324242324232321242467232324232324;CP=2;R=0;O; - # xavax_DAAB2554 Ch2_off MU;P0=3371;P1=-3479;P2=420;P3=-31868;P4=-541;P5=272;P6=-1343;P7=-20621;D=23245426242426242624262426242624242624262624262424272424012626242626242624262426242624262624242624242624262426242624262424262426262426242427242401262624262624262426242624262426262424262424262426242624262426242426242626242624242724240126262426262426242624;CP=2;R=45;O; - { - name => 'xavax', - comment => 'Remote control xavax 00111939', - id => '26', - knownFreqs => '433.92', - one => [1,-3], # 460,-1380 - zero => [1,-1], # 460,-460 - start => [1,-1,1,-1,7,-7], # 460,-460,460,-460,3220,-3220 - # end => [1], # 460 - end funktioniert nicht (wird erst nach pause angehangen), ein bit ans Ende haengen geht, dann aber pause 44 statt 45 - pause => [-44], # -20700 mit end, 20240 mit bit 0 am Ende - clockabs => 460, - format => 'twostate', - preamble => 'P26#', - clientmodule => 'SD_UT', - modulematch => '^P26#.{10}', - length_min => '40', - length_max => '40', - }, - "27" => ## Temperatur-/Feuchtigkeitssensor EuroChron EFTH-800 (433 MHz) - https://github.com/RFD-FHEM/RFFHEM/issues/739 - # SD_WS_27_TH_2 - T: 15.5 H: 48 - MU;P0=-224;P1=258;P2=-487;P3=505;P4=-4884;P5=743;P6=-718;D=0121212301212303030301212123012123012123030123030121212121230121230121212121212121230301214565656561212123012121230121230303030121212301212301212303012303012121212123012123012121212121212123030121;CP=1;R=53; - # SD_WS_27_TH_3 - T: 3.8 H: 76 - MU;P0=-241;P1=251;P2=-470;P3=500;P4=-4868;P5=743;P6=-718;D=012121212303030123012301212123012121212301212303012121212121230303012303012123030303012123014565656561212301212121230303012301230121212301212121230121230301212121212123030301230301212303030301212301;CP=1;R=23; - # SD_WS_27_TH_3 - T: 5.3 H: 75 - MU;P0=-240;P1=253;P2=-487;P3=489;P4=-4860;P5=746;P6=-725;D=012121212303030123012301212123012121212303012301230121212121230303012301230303012303030301214565656561212301212121230303012301230121212301212121230301230123012121212123030301230123030301230303030121;CP=1;R=19; - # Eurochron Zusatzsensor fuer EFS-3110A - https://github.com/RFD-FHEM/RFFHEM/issues/889 - # short pulse of 244 us followed by a 488 us gap is a 0 bit - # long pulse of 488 us followed by a 244 us gap is a 1 bit - # sync preamble of pulse, gap, 732 us each, repeated 4 times - # sensor sends two messages at intervals of about 57-58 seconds - { - name => 'EFTH-800', - comment => 'EuroChron weatherstation EFTH-800, EFS-3110A', - id => '27', - knownFreqs => '433.92', - one => [2,-1], - zero => [1,-2], - start => [3,-3,3,-3,3,-3,3,-3], - clockabs => '244', - format => 'twostate', - preamble => 'W27#', - clientmodule => 'SD_WS', - modulematch => '^W27#.{12}', - length_min => '48', # 48 Bit + 1 Puls am Ende - length_max => '48', - }, - "28" => ## some remote code, send by aldi IC Ledspots - { - name => 'IC Ledspot', - id => '28', - knownFreqs => '', - one => [1,-1], - zero => [1,-2], - start => [4,-5], - clockabs => 600, #ca 600 - format => 'twostate', - preamble => 'u28#', # prepend to converted message - #clientmodule => '', - #modulematch => '', - length_min => '8', - length_max => '8', - }, - "29" => ## example remote control with HT12E chip - # fan_off MU;P0=250;P1=-492;P2=166;P3=-255;P4=491;P5=-8588;D=052121212121234121212121234521212121212341212121212345212121212123412121212123452121212121234121212121234;CP=0; - # https://forum.fhem.de/index.php/topic,58397.960.html - { - name => 'HT12e', - comment => 'remote control for example Westinghouse airfan with 5 buttons', - id => '29', - knownFreqs => '', - one => [-2,1], - zero => [-1,2], - start => [-35,1], # Message is not provided as MS, worakround is start - clockabs => 235, # ca 220 - format => 'twostate', # there is a pause puls between words - preamble => 'P29#', # prepend to converted message - clientmodule => 'SD_UT', - modulematch => '^P29#.{3}', - length_min => '12', - length_max => '12', - }, - "30" => ## a unitec remote door reed switch - # https://forum.fhem.de/index.php?topic=43346.0 @Dr.E.Witz - # unknown MU;P0=-10026;P1=-924;P2=309;P3=-688;P4=-361;P5=637;D=123245453245324532453245320232454532453245324532453202324545324532453245324532023245453245324532453245320232454532453245324532453202324545324532453245324532023245453245324532453245320232454532453245324532453202324545324532453245324532023240;CP=2;O; - # unknown MU;P0=307;P1=-10027;P2=-691;P3=-365;P4=635;D=0102034342034203420342034201020343420342034203420342010203434203420342034203420102034342034203420342034201020343420342034203420342010203434203420342034203420102034342034203420342034201;CP=0; - { - name => 'diverse', - comment => 'remote control unitec | door reed switch 47031', - id => '30', - knownFreqs => '', - one => [-2,1], - zero => [-1,2], - start => [-30,1], # Message is not provided as MS, worakround is start - clockabs => 330, # ca 300 us - format => 'twostate', # there is a pause puls between words - preamble => 'P30#', # prepend to converted message - clientmodule => 'SD_UT', - modulematch => '^P30#.{3}', - length_min => '12', - length_max => '12', # message has only 10 bit but is paddet to 12 - }, - "31" => ## LED Controller LTECH, LED M Serie RF RGBW - M4 & M4-5A - # https://forum.fhem.de/index.php/topic,107868.msg1018434.html#msg1018434 | https://forum.fhem.de/index.php/topic,107868.msg1020521.html#msg1020521 @Devirex - ## note: command length 299, now - not supported by all firmware versions - # MU;P0=-16118;P1=315;P2=-281;P4=-1204;P5=-563;P6=618;P7=1204;D=01212121212121212121214151562151515151515151515621515621515626262156262626262626262626215626262626262626262626262626262151515151515151515151515151515151515151515151515626262626262626215151515151515156215156262626262626262626262621570121212121212121212121;CP=1;R=26;O; - # MU;P0=-32001;P1=314;P2=-285;P3=-1224;P4=-573;P5=601;P6=1204;P7=-15304;CP=1;R=31;D=012121212121212121212131414521414141414141414145214145214145252521452525252525252525252145252525252525252525252525252521414141414141414141414141414141452141414141414145252525252525252141414141414141414525252141452525252525214145214671212121212121212121213141452;p;i; - { - name => 'LTECH', - comment => 'remote control for LED Controller M4-5A', - id => '31', - knownFreqs => '433.92', - one => [1,-1.8], - zero => [2,-0.9], - start => [1,-0.9, 1,-0.9, 1,-3.8], - preSync => [1,-0.9, 1,-0.9, 1,-0.9, 1,-0.9, 1,-0.9, 1,-0.9, 1,-0.9, 1,-0.9], - end => [3.8, -51], - clockabs => 315, - format => 'twostate', - preamble => 'u31#', - }, - "32" => ## FreeTec PE-6946 - # ! some message are decode as protocol 40 and protocol 62 ! - # http://www.free-tec.de/Funkklingel-mit-Voic-PE-6946-919.shtml - # OLD # https://github.com/RFD-FHEM/RFFHEM/issues/49 - # NEW # https://github.com/RFD-FHEM/RFFHEM/issues/315 - # P32#154FFF | ring MU;P0=-6676;P1=578;P2=-278;P4=-680;P5=176;P6=-184;D=541654165412545412121212121212121212121250545454125412541254125454121212121212121212121212;CP=1;R=0; - # P32#154FFF | ring MU;P0=146;P1=245;P3=571;P4=-708;P5=-284;P7=-6689;D=14351435143514143535353535353535353535350704040435043504350435040435353535353535353535353507040404350435043504350404353535353535353535353535070404043504350435043504043535353535353535353535350704040435043504350435040435353535353535353535353507040404350435;CP=3;R=0;O; - # P32#154FFF | ring MU;P0=-6680;P1=162;P2=-298;P4=253;P5=-699;P6=555;D=45624562456245456262626262626262626262621015151562156215621562151562626262626262626262626210151515621562156215621515626262626262626262626262;CP=6;R=0; - ## VLOXO Wireless Türklingel - # https://github.com/RFD-FHEM/RFFHEM/issues/655 @schwatter - # P32#7ED403 | ring MU;P0=130;P1=-666;P2=533;P3=-273;P5=-6200;CP=0;R=15;D=01232301230123010101010101010123230501232323232323012323012301230101010101010101232305012323232323230123230123012301010101010101012323050123232323232301232301230123010101010101010123230501232323232323012323012301230101010101010101232305012323232323230123;O; - { - name => 'wireless doorbell', - comment => 'FreeTec PE-6946 / VLOXO', - id => '32', - knownFreqs => '433.92', - one => [4,-2], - zero => [1,-5], - start => [1,-45], # neuerdings MU Erknnung - #sync => [1,-49], # old MS Erkennung - clockabs => 150, - format => 'twostate', - preamble => 'P32#', # prepend to converted message - clientmodule => 'SD_BELL', - modulematch => '^P32#.*', - length_min => '24', - length_max => '24', - }, - "33" => ## Thermo-/Hygrosensor S014, renkforce E0001PA, Conrad S522, TX-EZ6 (Weatherstation TZS First Austria) - # https://forum.fhem.de/index.php?topic=35844.0 @BrainHunter - # Id:62 Ch:1 T: 21.1 H: 76 Bat:ok MS;P0=-7871;P2=-1960;P3=578;P4=-3954;D=030323232323434343434323232323234343434323234343234343234343232323432323232323232343234;CP=3;SP=0;R=0;m=0; - { - name => 'weather', - comment => 'S014, TFA 30.3200, TCM, Conrad S522, renkforce E0001PA, TX-EZ6', - id => '33', - knownFreqs => '433.92', - one => [1,-8], - zero => [1,-4], - sync => [1,-16], - clockabs => '500', - format => 'twostate', # not used now - preamble => 'W33#', # prepend to converted message - postamble => '', # Append to converted message - clientmodule => 'SD_WS', - #modulematch => '', - length_min => '42', - length_max => '44', - }, - "33.1" => ## Thermo-/Hygrosensor TFA 30.3200 - # https://github.com/RFD-FHEM/SIGNALDuino/issues/113 - # SD_WS_33_TH_1 T: 18.8 H: 53 MS;P1=-7796;P2=745;P3=-1976;P4=-3929;D=21232323242324232324242323232323242424232323242324242323242324232324242323232323232424;CP=2;SP=1;R=30;O;m2; - # SD_WS_33_TH_2 T: 21.9 H: 49 MS;P1=-7762;P2=747;P3=-1976;P4=-3926;D=21232324232324242323242323232424242424232423232324242323232324232324242323232324242424;CP=2;SP=1;R=32;O;m1; - # SD_WS_33_TH_3 T: 19.7 H: 53 MS;P1=758;P2=-1964;P3=-3929;P4=-7758;D=14121213121313131213121212131212131313121213121213131212131213121213131212121212121212;CP=1;SP=4;R=48;O;m1; - { - name => 'TFA 30.3200', - comment => 'Thermo-/Hygrosensor TFA 30.3200 (CP=750)', - id => '33.1', - knownFreqs => '433.92', - one => [1,-5.6], # 736,-4121 - zero => [1,-2.8], # 736,-2060 - sync => [1,-11], # 736,-8096 - clockabs => 736, - format => 'twostate', # not used now - preamble => 'W33#', - clientmodule => 'SD_WS', - length_min => '42', - length_max => '44', - }, - "33.2" => ## Tchibo Wetterstation - # https://forum.fhem.de/index.php/topic,58397.msg880339.html#msg880339 @Doublefant - # passt bei 33 und 33.2: - # SD_WS_33_TH_1 T: 5.1 H: 41 MS;P1=399;P2=-7743;P3=-2038;P4=-3992;D=12131314141414141313131413131314141414131313141314131414131314131314131313131314131314;CP=1;SP=2;R=230;O;m2; - # SD_WS_33_TH_1 T: 5.1 H: 41 MS;P1=399;P2=-7733;P3=-2043;P4=-3991;D=12131314141414141313131413131314141414131313141314131414131314131314131313131314131314;CP=1;SP=2;R=230;O; - # passt nur bei 33.2: - # SD_WS_33_TH_1 T: 5.1 H: 41 MS;P1=393;P2=-7752;P3=-2047;P4=-3993;D=12131314141414141313131413131314141414131313141314131414131314131314131313131314131314;CP=1;SP=2;R=230;O;m1; - # SD_WS_33_TH_1 T: 5.1 H: 41 MS;P1=396;P2=-7759;P3=-2045;P4=-4000;D=12131314141414141313131413131314141414131313141314131414131314131314131313131314131314;CP=1;SP=2;R=230;O;m0; - { - name => 'Tchibo', - comment => 'Tchibo weatherstation (CP=400)', - id => '33.2', - knownFreqs => '433.92', - one => [1,-10], # 400,-4000 - zero => [1,-5], # 400,-2000 - sync => [1,-19], # 400,-7600 - clockabs => 400, - format => 'twostate', - preamble => 'W33#', - postamble => '', - clientmodule => 'SD_WS', - length_min => '42', - length_max => '44', - }, - "34" => ## QUIGG GT-7000 Funk-Steckdosendimmer | transmitter DMV-7000 - receiver DMV-7009AS - # https://github.com/RFD-FHEM/RFFHEM/issues/195 | https://forum.fhem.de/index.php/topic,38831.msg361341.html#msg361341 @StefanW - # Ch1_on MU;P0=-5284;P1=583;P2=-681;P3=1216;P4=-1319;D=012341412323232341412341412323234123232341;CP=1;R=16; - # Ch1_off MU;P0=-9812;P1=589;P2=-671;P3=1261;P4=-1320;D=012341412323232341412341412323232323232323;CP=3;R=19; - # Ch2_on MU;P0=-9832;P1=577;P2=-670;P3=1219;P4=-1331;D=012341412323232341412341414123234123234141;CP=1;R=16; - # Ch2_off MU;P0=-8816;P1=594;P2=-662;P3=1263;P4=-1330;D=012341412323232341412341414123232323234123;CP=1;R=16; - # Ch3_on MU;P0=-677;P1=581;P2=1250;P3=-1319;D=010231310202020231310231310231023102020202;CP=1;R=18; - # Ch3_off MU;P0=-29120;P1=603;P2=-666;P3=1235;P4=-1307;D=012341412323232341412341412341232323232341;CP=1;R=16; - ## LIBRA GmbH (LIDL) TR-502MSV - # no decode! MU;P0=-12064;P1=71;P2=-669;P3=1351;P4=-1319;D=012323414141234123232323232323232323232323; - # Ch1_off MU;P0=697;P1=-1352;P2=-679;P3=1343;D=01010101010231023232323232323232323232323;CP=0;R=27; - ## Mandolyn Funksteckdosen Set - # https://github.com/RFD-FHEM/RFFHEM/issues/716 @codeartisan-de - ## Pollin ISOTRONIC - 12 Tasten remote | model 58608 | SD_UT model QUIGG_DMV ??? - # remote basicadresse with 12bit -> changed if push reset behind battery cover - # https://github.com/RFD-FHEM/RFFHEM/issues/44 @kaihs - # Ch1_on MU;P0=-9584;P1=592;P2=-665;P3=1223;P4=-1311;D=01234141412341412341414123232323412323234;CP=1;R=0; - # Ch1_off MU;P0=-12724;P1=597;P2=-667;P3=1253;P4=-1331;D=01234141412341412341414123232323232323232;CP=1;R=0; - { - name => 'QUIGG | LIBRA | Mandolyn | Pollin ISOTRONIC', - comment => 'remote control DMV-7000, TR-502MSV, 58608', - id => '34', - knownFreqs => '433.92', - one => [-1,2], - zero => [-2,1], - start => [1], - pause => [-15], # 9900 - clockabs => '635', - format => 'twostate', - preamble => 'P34#', - clientmodule => 'SD_UT', - reconstructBit => '1', - #modulematch => '', - length_min => '19', - length_max => '20', - }, - "35" => ## Homeeasy - # off | vHE800 MS;P0=907;P1=-376;P2=266;P3=-1001;P6=-4860;D=2601010123230123012323230101012301230101010101230123012301;CP=2;SP=6; - { - name => 'HomeEasy HE800', - id => '35', - knownFreqs => '', - one => [1,-4], - zero => [3.4,-1], - sync => [1,-18], - clockabs => '280', - format => 'twostate', # not used now - preamble => 'ih', # prepend to converted message - postamble => '', # Append to converted message - clientmodule => 'IT', - #modulematch => '', - length_min => '28', - length_max => '40', - postDemodulation => \&main::SIGNALduino_HE800, - }, - "36" => ## remote - cheap wireless dimmer - # https://forum.fhem.de/index.php/topic,38831.msg394238.html#msg394238 @Steffenm - # u36#CE8501 MU;P0=499;P1=-1523;P2=-522;P3=10220;P4=-10047;D=01020202020202020134010102020101010201020202020102010202020202020201340101020201010102010202020201020102020202020202013401010202010101020102020202010201020202020202020134010102020101010201020202020102010202020202020201340101020201010102010;CP=0;O; - # u36#CE8501 MU;P0=-520;P1=500;P2=-1523;P3=10220;P4=-10043;D=01010101210121010101010101012341212101012121210121010101012101210101010101010123412121010121212101210101010121012101010101010101234121210101212121012101010101210121010101010101012341212101012121210121010101012101210101010101010123412121010;CP=1;O; - # u36#CE8501 MU;P0=498;P1=-1524;P2=-521;P3=10212;P4=-10047;D=01010102010202020201020102020202020202013401010202010101020102020202010201020202020202020134010102020101010201020202020102010202020202020201340101020201010102010202020201020102020202020202013401010202010101020102020202010201020202020202020;CP=0;O; - { - name => 'remote', - comment => 'cheap wireless dimmer', - id => '36', - knownFreqs => '433.92', - one => [1,-3], - zero => [1,-1], - start => [20,-20], - clockabs => '500', - format => 'twostate', # not used now - preamble => 'u36#', # prepend to converted message - postamble => '', # Append to converted message - #clientmodule => '', - #modulematch => '', - length_min => '24', - length_max => '24', - }, - "37" => ## Bresser 7009994 - # ! some message are decode as protocol 61 and protocol 84 ! - # Ch:1 T: 22.7 H: 48 Bat:ok MU;P0=729;P1=-736;P2=483;P3=-251;P4=238;P5=-491;D=010101012323452323454523454545234523234545234523232345454545232345454545452323232345232340;CP=4; - # Ch:3 T: 16.2 H: 51 Bat:ok MU;P0=-790;P1=-255;P2=474;P4=226;P6=722;P7=-510;D=721060606060474747472121212147472121472147212121214747212147474721214747212147214721212147214060606060474747472121212140;CP=4;R=216; - # short pulse of 250 us followed by a 500 us gap is a 0 bit - # long pulse of 500 us followed by a 250 us gap is a 1 bit - # sync preamble of pulse, gap, 750 us each, repeated 4 times - { - name => 'Bresser 7009994', - comment => 'temperature / humidity sensor', - id => '37', - knownFreqs => '', - one => [2,-1], - zero => [1,-2], - start => [3,-3,3,-3], - clockabs => '250', - format => 'twostate', # not used now - preamble => 'W37#', # prepend to converted message - clientmodule => 'SD_WS', - length_min => '40', - length_max => '41', - }, - "38" => ## Rosenstein & Soehne, PEARL NC-3911, NC-3912, refrigerator thermometer - 2 channels - # https://github.com/RFD-FHEM/RFFHEM/issues/504 - Support for NC-3911 Fridge Temp, @MoskitoHorst, 2019-02-05 - # Id:8B Ch:1 T: 6.3 MU;P0=-747;P1=-493;P2=231;P3=484;P4=-248;P6=-982;P7=718;D=1213434212134343421342121343434343434212670707070342121213421343434212134212134212121343421213434342134212134343434343421267070707034212121342134343421213421213421212134342121343434213421213434343434342126707070703421212134213434342121342121342121;CP=2; - # Id:A8 Ch:2 T:-1.8 MU;P0=-241;P1=491;P2=249;P3=-482;P4=-962;P5=743;P6=-723;D=01023102323232310101010232323102310232323232310101010231024565656561023102310232323102310232323231010101023232310231023232323231010101023102456565656102310231023232310231023232323101010102323231023102323232323101010102310245656565610231023102323231023102;CP=2;O; - # Id:A8 Ch:2 T: 5.4 MU;P0=-971;P1=733;P2=-731;P3=488;P4=-244;P5=248;P6=-480;P7=-368;D=01212121234563456345656563456345656563456575634563456345634345656345634343434345650121212123456345634565656345634565656345656563456345634563434565634563434343434565012121212345634563456565634563456565634565656345634563456343456563456343434343456501212121;CP=5;O; - { - name => 'NC-3911', - comment => 'Refrigerator thermometer', - id => '38', - knownFreqs => '433.92', - one => [2,-1], - zero => [1,-2], - start => [3,-3,3,-3,3,-3,3,-3], - clockabs => 250, - format => 'twostate', - preamble => 'W38#', - clientmodule => 'SD_WS', - modulematch => '^W38#.*', - length_min => '36', - length_max => '36', - }, - "39" => ## X10 Protocol - # https://github.com/RFD-FHEM/RFFHEM/issues/65 @wherzig - # Closed | Bat:ok MU;P0=10530;P1=-2908;P2=533;P3=-598;P4=-1733;P5=767;D=0123242323232423242324232324232423242323232324232323242424242324242424232423242424232501232423232324232423242323242324232423232323242323232424242423242424242324232424242325012324232323242324232423232423242324232323232423232324242424232424242423242324242;CP=2;O; - { - name => 'X10 Protocol', - id => '39', - knownFreqs => '', - one => [1,-3], - zero => [1,-1], - start => [17,-7], - clockabs => 560, - format => 'twostate', - preamble => '', # prepend to converted message - clientmodule => 'RFXX10REC', - #modulematch => '^TX......', - length_min => '32', - length_max => '44', - paddingbits => '8', - postDemodulation => \&main::SIGNALduino_lengtnPrefix, - filterfunc => 'SIGNALduino_compPattern', - }, - "40" => ## Romotec - # ! some message are decode as protocol 19 and protocol 40 not decode ! - # https://github.com/RFD-FHEM/RFFHEM/issues/71 @111apieper - # u19#6B3190 MU;P0=300;P1=-772;P2=674;P3=-397;P4=4756;P5=-1512;D=4501232301230123230101232301010123230101230103;CP=0; - # no decode! MU;P0=-132;P1=-388;P2=675;P4=271;P5=-762;D=012145212145452121454545212145452145214545454521454545452145454541;CP=4; - { - name => 'Romotec ', - comment => 'Tubular motor', - id => '40', - knownFreqs => '', - one => [3,-2], - zero => [1,-3], - start => [1,-2], - clockabs => 270, - preamble => 'u40#', # prepend to converted message - #clientmodule => '', - #modulematch => '', - length_min => '12', - #length_max => '', # missing - }, - "41" => ## Elro (Smartwares) Doorbell DB200 / 16 melodies - # https://github.com/RFD-FHEM/RFFHEM/issues/70 @beatz0001 - # P41#F813D593 | doubleCode_part1 MS;P0=-526;P1=1450;P2=467;P3=-6949;P4=-1519;D=231010101010242424242424102424101010102410241024101024241024241010;CP=2;SP=3;O; - # P41#219D85D3 | doubleCode_part2 MS;P0=468;P1=-1516;P2=1450;P3=-533;P4=-7291;D=040101230101010123230101232323012323010101012301232323012301012323;CP=0;SP=4;O; - # unitec Modell:98156+98YK / 36 melodies - # repeats 15, change two codes every 15 repeats --> one button push, 2 codes - # P41#08E8D593 | doubleCode_part1 MS;P0=1474;P1=-521;P2=495;P3=-1508;P4=-6996;D=242323232301232323010101230123232301012301230123010123230123230101;CP=2;SP=4;R=51;m=0; - # P41#754485D3 | doubleCode_part2 MS;P1=-7005;P2=482;P3=-1511;P4=1487;P5=-510;D=212345454523452345234523232345232345232323234523454545234523234545;CP=2;SP=1;R=47;m=2; - ## KANGTAI Doorbell (Pollin 94-550405) - # https://github.com/RFD-FHEM/RFFHEM/issues/365 @trosenda - # The bell button alternately sends two different codes - # P41#BA2885D3 | doubleCode_part1 MS;P0=1390;P1=-600;P2=409;P3=-1600;P4=-7083;D=240123010101230123232301230123232301232323230123010101230123230101;CP=2;SP=4;R=248;O;m0; - # P41#1791D593 | doubleCode_part2 MS;P1=403;P2=-7102;P3=-1608;P4=1378;P5=-620;D=121313134513454545451313451313134545451345134513454513134513134545;CP=1;SP=2;R=5;O;m0; - { - name => 'wireless doorbell', - comment => 'Elro (DB200) / KANGTAI (Pollin 94-550405) / unitec', - id => '41', - knownFreqs => '433.92', - zero => [1,-3], - one => [3,-1], - sync => [1,-14], - clockabs => 500, - format => 'twostate', - preamble => 'P41#', # prepend to converted message - clientmodule => 'SD_BELL', - modulematch => '^P41#.*', - length_min => '32', - length_max => '32', - }, - "42" => ## Pollin 551227 - # https://github.com/RFD-FHEM/RFFHEM/issues/390 @trosenda - # FE1FF87 | ring MU;P0=1446;P1=-487;P2=477;D=0101012121212121212121212101010101212121212121212121210101010121212121212121212121010101012121212121212121212101010101212121212121212121210101010121212121212121212121010101012121212121212121212101010101212121212121212121210101010121212121212121212121010;CP=2;R=93;O; - # FE1FF87 | ring MU;P0=-112;P1=1075;P2=-511;P3=452;P5=1418;D=01212121232323232323232323232525252523232323232323232323252525252323232323232323232325252525;CP=3;R=77; - { - name => 'wireless doorbell', - comment => 'Pollin 551227', - id => '42', - knownFreqs => '433.92', - one => [1,-1], - zero => [3,-1], - start => [1,-1,1,-1,1,-1,], - clockabs => 500, - format => 'twostate', - preamble => 'P42#', - clientmodule => 'SD_BELL', - #modulematch => '^P42#.*', - length_min => '28', - length_max => '120', - }, - "43" => ## Somfy RTS - # received=40, parsestate=on MC;LL=-1405;LH=1269;SL=-723;SH=620;D=98DBD153D631BB;C=669;L=56;R=229; - { - name => 'Somfy RTS', - id => '43', - knownFreqs => '', - clockrange => [610,680], # min , max - format => 'manchester', - preamble => 'Ys', - clientmodule => 'SOMFY', # not used now - modulematch => '^Ys[0-9A-F]{14}', - length_min => '56', - length_max => '57', - method => \&main::SIGNALduino_SomfyRTS, # Call to process this message - msgIntro => 'SR;P0=-2560;P1=2560;P3=-640;D=10101010101010113;', - #msgOutro => 'SR;P0=-30415;D=0;', - frequency => '10AB85550A', - }, - "44" => ## Bresser Temeo Trend - # MU;P0=32001;P1=-1939;P2=1967;P3=3896;P4=-3895;D=01213424242124212121242121242121212124212424212121212121242421212421242121242124242421242421242424242124212124242424242421212424212424212121242121212;CP=2;R=39; - { - name => 'BresserTemeo', - comment => 'temperature / humidity sensor', - id => '44', - knownFreqs => '', - clockabs => 500, - zero => [4,-4], - one => [4,-8], - start => [8,-8], - preamble => 'W44#', - clientmodule => 'SD_WS', - modulematch => '^W44#[A-F0-9]{18}', - length_min => '64', - length_max => '72', - }, - "44.1" => ## Bresser Temeo Trend - { - name => 'BresserTemeo', - comment => 'temperature / humidity sensor', - id => '44', - knownFreqs => '', - clockabs => 500, - zero => [4,-4], - one => [4,-8], - start => [8,-12], - preamble => 'W44x#', - clientmodule => 'SD_WS', - modulematch => '^W44x#[A-F0-9]{18}', - length_min => '64', - length_max => '72', - }, - "45" => ## Revolt - # P:126.8 E:35.88 V:232 C:0.68 Pf:0.8 MU;P0=-8320;P1=9972;P2=-376;P3=117;P4=-251;P5=232;D=012345434345434345454545434345454545454543454343434343434343434343434543434345434343434545434345434343434343454343454545454345434343454345434343434343434345454543434343434345434345454543454343434543454345434545;CP=3;R=2; - { - name => 'Revolt', - id => '45', - knownFreqs => '', - one => [2,-2], - zero => [1,-2], - start => [83,-3], - clockabs => 120, - preamble => 'r', # prepend to converted message - clientmodule => 'Revolt', - modulematch => '^r[A-Fa-f0-9]{22}', - length_min => '84', - length_max => '120', - postDemodulation => sub { my ($name, @bit_msg) = @_; my @new_bitmsg = splice @bit_msg, 0,88; return 1,@new_bitmsg; }, - }, - "46" => ## Tedsen Fernbedienungen u.a. für Berner Garagentorantrieb GA401 und Geiger Antriebstechnik Rolladensteuerung - # https://github.com/RFD-FHEM/RFFHEM/issues/91 - # remote TEDSEN SKX1MD 433.92 MHz - 1 button | settings via 9 switch on battery compartment - # compatible with doors: BERNER SKX1MD, ELKA SKX1MD, TEDSEN SKX1LC, TEDSEN SKX1 - 1 Button - # Tedsen_SKX1xx | Button_1 MU;P0=-15829;P1=-3580;P2=1962;P3=-330;P4=245;P5=-2051;D=1234523232345234523232323234523234540 0 2345 2323 2345 2345 2323 2323 2345 2323 454 023452323234523452323232323452323454023452323234523452323232323452323454023452323234523452323232323452323454023452323234523452323;CP=2; - # Tedsen_SKX1xx | Button_1 MU;P0=-1943;P1=1966;P2=-327;P3=247;P5=-15810;D=012301212123012301212121212301212303 5 1230 1212 1230 1230 1212 1212 1230 1212 303 5 1230 1212 1230 1230 1212 1212 1230 1212 303 51230121212301230121212121230121230351230121212301230121212121230121230351230;CP=1; - ## GEIGER GF0001, 2 Button, DIP-Schalter: + 0 + - + + - 0 0 - # https://forum.fhem.de/index.php/topic,39153.0.html - # Tedsen_SKX2xx | Button_1 MU;P0=-15694;P1=2009;P2=-261;P3=324;P4=-2016;D=01212123412123434121212123434123434301212123412123434121212123434123434301212123412123434121212123434123434301212123412123434121212123434123434301212123412123434121212123434123434301;CP=3;R=30; - # Tedsen_SKX2xx | Button_2 MU;P0=-32001;P1=2072;P2=-260;P3=326;P4=-2015;P5=-15769;D=01212123412123434121212123434123412351212123412123434121212123434123412351212123412123434121212123434123412351212123412123434121212123434123412351212123412123434121212123434123412351212123412123434121212123434123412351212123412123434121212123434123412351;CP=3;R=37;O; - # ? - # P46#CC0A0 MU;P0=313;P1=1212;P2=-309;P4=-2024;P5=-16091;P6=2014;D=01204040562620404626204040404040462046204040562620404626204040404040462046204040562620404626204040404040462046204040562620404626204040404040462046204040;CP=0;R=236; - # P46#ECF20 MU;P0=-15770;P1=2075;P2=-264;P3=326;P4=-2016;P5=948;D=012121234121234341212121234341234343012125;CP=3;R=208; - { - name => 'SKXxxx, GF0x0x', - comment => 'remote controls Tedsen SKXxxx, GEIGER GF0x0x', - id => '46', - knownFreqs => '433.92', - one => [7,-1], - zero => [1,-7], - start => [-55], - clockabs => 290, - reconstructBit => '1', - format => 'tristate', # not used now - preamble => 'P46#', - clientmodule => 'SD_UT', - modulematch => '^P46#.*', - length_min => '14', # ??? - length_max => '18', - }, - "47" => ## Maverick ET-732, ET-733; TFA 14.1504 - # https://github.com/RFD-FHEM/RFFHEM/issues/61 - # Food: 23 BBQ: 22 MC;LL=-507;LH=490;SL=-258;SH=239;D=AA9995599599A959996699A969;C=248;L=104; - # https://github.com/RFD-FHEM/RFFHEM/issues/167 - { - name => 'Maverick', - comment => 'BBQ / food thermometer', - id => '47', - knownFreqs => '433.92', - clockrange => [180,260], - format => 'manchester', - preamble => 'P47#', # prepend to converted message - clientmodule => 'SD_WS_Maverick', - modulematch => '^P47#[569A]{12}.*', - length_min => '100', - length_max => '108', - method => \&main::SIGNALduino_Maverick, # Call to process this message - #polarity => 'invert' - }, - "48" => ## Joker Dostmann TFA 30.3055.01 - # ! some message are decode as protocol 42 and protocol 50 ! - # https://github.com/RFD-FHEM/RFFHEM/issues/92 @anphiga - # U48#016C7E18004C MU;P0=591;P1=-1488;P2=-3736;P3=1338;P4=-372;P6=-988;D=23406060606063606363606363606060636363636363606060606363606060606060606060606060636060636360106060606060606063606363606363606060636363636363606060606363606060606060606060606060636060636360106060606060606063606363606363606060636363636363606060606363606060;CP=0;O; - # U48#01657EB80034 MU;P0=96;P1=-244;P2=510;P3=-1000;P4=1520;P5=-1506;D=01232323232343234343232343234323434343434343234323434343232323232323232323232323234343234325232323232323232343234343232343234323434343434343234323434343232323232323232323232323234343234325232323232323232343234343232343234323434343434343234323434343232323;CP=2;O; - { - name => 'TFA Dostmann', - comment => 'Funk-Thermometer Joker TFA 30.3055.01', - id => '48', - knownFreqs => '', - clockabs => 250, # In real it is 500 but this leads to unprceise demodulation - one => [-4,6], - zero => [-4,2], - start => [-6,2], - format => 'twostate', - preamble => 'U48#', # prepend to converted message - #clientmodule => '', - modulematch => '^U48#.*', - length_min => '47', - length_max => '48', - }, - "49" => ## QUIGG GT-9000, EASY HOME RCT DS1 CR-A, uniTEC 48110 and other - # The remote sends 8 messages in 2 different formats. - # SIGNALduino decodes 4 messages from remote control as MS then ... - # https://github.com/RFD-FHEM/RFFHEM/issues/667 - Oct 19, 2019 - # DMSG: 5A98B0 MS;P0=-437;P3=-1194;P4=1056;P6=297;P7=-2319;D=67634063404063406340636340406363634063404063636363;CP=6;SP=7;R=37; - # DMSG: 887F92 MS;P1=-2313;P2=1127;P3=-405;P4=379;P5=-1154;D=41234545452345454545232323232323232345452345452345;CP=4;SP=1;R=251; - # DMSG: E6D12E MS;P0=1062;P1=-1176;P2=315;P3=-2283;P4=-433;D=23040404212104042104042104212121042121042104040421;CP=2;SP=3;R=26; - { - name => 'GT-9000', - comment => 'Remote control EASY HOME RCT DS1 CR-A', - id => '49', - knownFreqs => '433.92', - clockabs => 383, - one => [3,-1], # 1150,-385 (timings from salae logic) - zero => [1,-3], # 385,-1150 (timings from salae logic) - sync => [1,-6], # 385,-2295 (timings from salae logic) - format => 'twostate', - preamble => 'P49#', - clientmodule => 'SD_GT', - modulematch => '^P49.*', - length_min => '24', - length_max => '24', - }, - "49.1" => ## QUIGG GT-9000 - # ... decodes 4 messages as MU - # https://github.com/RFD-FHEM/RFFHEM/issues/667 @Ralf9 from https://forum.fhem.de/index.php/topic,104506.msg985295.html - # DMSG: 8B2DB0 MU;P0=-563;P1=479;P2=991;P3=-423;P4=361;P5=-1053;P6=3008;P7=-7110;D=2345454523452323454523452323452323452323454545456720151515201520201515201520201520201520201515151567201515152015202015152015202015202015202015151515672015151520152020151520152020152020152020151515156720151515201520201515201520201520201520201515151;CP=1;R=21; - # DMSG: 887F90 MU;P0=-565;P1=489;P2=991;P3=-423;P4=359;P5=-1047;P6=3000;P7=-7118;D=2345454523454545452323232323232323454523454545456720151515201515151520202020202020201515201515151567201515152015151515202020202020202015152015151515672015151520151515152020202020202020151520151515156720151515201515151520202020202020201515201515151;CP=1;R=17; - { - name => 'GT-9000', - comment => 'Remote control is traded under different names', - id => '49.1', - knownFreqs => '433.92', - clockabs => 515, - one => [2,-1], # 1025,-515 (timings from salae logic) - zero => [1,-2], # 515,-1030 (timings from salae logic) - start => [6,-14], # 3075,-7200 (timings from salae logic) - format => 'twostate', - preamble => 'P49#', - clientmodule => 'SD_GT', - modulematch => '^P49.*', - length_min => '24', - length_max => '24', - }, - "49.2" => ## Tec Star Modell 2335191R - # SIGNALduino decodes 4 messages from remote control as MU then ... 49.1 - # https://forum.fhem.de/index.php/topic,43292.msg352982.html#msg352982 - Nov 01, 2015 - # message was receive with older firmware - # DMSG: CA627C MU;P0=1092;P1=-429;P2=335;P3=-1184;P4=-2316;P5=2996;D=010123230123012323010123232301232301010101012323240101232301230123230101232323012323010101010123232401012323012301232301012323230123230101010101232355;CP=2; - # DMSG: C9AFAC MU;P0=328;P1=-428;P3=1090;P4=-1190;P5=-2310;D=010131040431310431043131313131043104313104040531310404310404313104310431313131310431043131040405313104043104043131043104313131313104310431310404053131040431040431310431043131313131043104313104042;CP=0; - { - name => 'GT-9000', - comment => 'Remote control Tec Star Modell 2335191R', - id => '49.2', - knownFreqs => '433.92', - clockabs => 383, - one => [3,-1], - zero => [1,-3], - start => [1,-6], # Message is not provided as MS - format => 'twostate', - preamble => 'P49#', - clientmodule => 'SD_GT', - modulematch => '^P49.*', - length_min => '24', - length_max => '24', - }, - "50" => ## Opus XT300 - # https://github.com/RFD-FHEM/RFFHEM/issues/99 @sidey79 - # Ch:1 T: 25 H: 5 MU;P0=248;P1=-21400;P2=545;P3=-925;P4=1368;P5=-12308;D=01232323232323232343234323432343234343434343234323432343434343432323232323232323232343432323432345232323232323232343234323432343234343434343234323432343434343432323232323232323232343432323432345232323232323232343234323432343234343434343234323432343434343;CP=2;O; - # CH:1 T: 18 H: 5 W50#FF55053AFF93 MU;P2=-962;P4=508;P5=1339;P6=-12350;D=46424242424242424252425242524252425252525252425242525242424252425242424242424242424252524252524240;CP=4;R=0; - # CH:3 T: 18 H: 5 W50#FF57053AFF95 MU;P2=510;P3=-947;P5=1334;P6=-12248;D=26232323232323232353235323532323235353535353235323535323232353235323232323232323232353532353235320;CP=2;R=0; - { - name => 'Opus_XT300', - comment => 'sensor for ground humidity', - id => '50', - knownFreqs => '433.92', - clockabs => 500, - zero => [3,-2], - one => [1,-2], - # start => [-25], # Wenn das startsignal empfangen wird, fehlt das 1 bit - reconstructBit => '1', - format => 'twostate', - preamble => 'W50#', # prepend to converted message - clientmodule => 'SD_WS', - modulematch => '^W50#.*', - length_min => '47', - length_max => '48', - }, - "51" => ## weather sensors - # https://github.com/RFD-FHEM/RFFHEM/issues/118 @Stertzi - # IAN 275901 Id:08 Ch:3 T:6.3 H:95 MS;P0=-4074;P1=608;P2=-1825;P3=-15980;P4=1040;P5=-975;P6=-7862;D=16121212121012121212101212101212101210121012121010121010121012121012101210121210101345454545;CP=1;SP=6; - # IAN 275901 Id:08 Ch:3 T:8.5 H:95 MS;P0=611;P1=-4073;P2=-1825;P3=-15980;P4=1041;P5=-974;P6=-7860;D=06020202020102020202020201010202010201020102010201010102010102020102010201020201010345454545;CP=0;SP=6; - # https://github.com/RFD-FHEM/RFFHEM/issues/122 @6040 - # IAN 114324 Id:11 Ch:1 T:17.3 H:40 MS;P0=-1848;P1=577;P2=-4066;P3=-15997;P4=1013;P5=-1001;P6=-7875;D=16101010121010101210101210101012101012101212121212121012121012101010101010101010121345454545;CP=1;SP=6;O; - # IAN 114324 Id:71 Ch:1 T:17.3 H:41 MS;P0=-16000;P1=1002;P2=-1010;P3=572;P4=-7884;P5=-1817;P6=-4102;D=34353636363535353635363535353535353536353636363636363536363536353535353536353535363012121212;CP=3;SP=4;O; - # https://github.com/RFD-FHEM/RFFHEM/issues/161 - # IAN 60107 Id:F0 Ch:1 T:-2.9 H:76 MS;P2=594;P3=-7386;P4=-4081;P5=-1873;D=2324242424252525252525242425252525252425252425252524242424252424242524242525252524;CP=2;SP=3;R=242; - # IAN 60107 Id:F0 Ch:1 T:0.9 H:81 MS;P2=604;P3=-7258;P4=-4179;P5=-1852;D=2324242424252525252525242525252524252425252424252425242524242525252525252425252524;CP=2;SP=3;R=242; - # IAN 60107 Id:F0 Ch:1 T:13.6 H:51 MS;P2=634;P3=-8402;P4=-4079;P5=-1832;D=2324242424252525252425252425252524252425242425242424252524252425242525252425252524;CP=2;SP=3;R=244; - { - name => 'weather', - comment => 'Lidl Weatherstation IAN60107, IAN 114324, IAN 275901', - id => '51', - knownFreqs => '433.92', - one => [1,-8], - zero => [1,-4], - sync => [1,-16], - clockabs => '500', - format => 'twostate', # not used now - preamble => 'W51#', # prepend to converted message - postamble => '', # Append to converted message - clientmodule => 'SD_WS', - modulematch => '^W51#.*', - length_min => '40', - length_max => '45', - }, - "52" => ## Oregon Scientific PIR Protocol - # https://forum.fhem.de/index.php/topic,63604.msg548256.html#msg548256 @Ralf_W. - # u52#00012AE7 MC;LL=-1045;LH=1153;SL=-494;SH=606;D=FFFED518;C=549;L=30; - ## note: unfortunately, the user is no longer in possession of a SIGNALduino - # - # FFFED5 = Adresse, die per DIP einstellt wird, FFF ändert sich nie - # 1 = Kanal, per gesondertem DIP, bei mir bei beiden 1 (CH 1) oder 3 (CH 2) - # C = wechselt, 0, 4, 8, C - dann fängt es wieder mit 0 an und wiederholt sich bei jeder Bewegung - { - name => 'Oregon Scientific PIR', - comment => 'JMR868 / NR868', - id => '52', - knownFreqs => '433.92', - clockrange => [470,640], # min , max - format => 'manchester', # tristate can't be migrated from bin into hex! - #clientmodule => '', # OREGON module not for Motion Detectors - modulematch => '^u52#F{3}|0{3}.*', - preamble => 'u52#', - length_min => '30', - length_max => '30', - method => \&main::SIGNALduino_OSPIR, # Call to process this message - polarity => 'invert', - }, - "53" => ## Lidl AURIOL AHFL 433 B2 IAN 314695 - # https://github.com/RFD-FHEM/RFFHEM/issues/663 @Kreidler1221 05.10.2019 - # IAN 314695 Id:07 Ch:1 T:24.2 H:59 MS;P1=611;P2=-2075;P3=-4160;P4=-9134;D=14121212121213131312121212121212121313131312121312121313131213131212131212131213121213;CP=1;SP=4;R=0;O;m2; - # IAN 314695 Id:07 Ch:1 T:22.3 H:61 MS;P1=608;P2=-2074;P3=-4138;P4=-9138;D=14121212121213131312121212121212121313121313131313121313131312131212131212131313121212;CP=1;SP=4;R=0;O;m1; - # IAN 314695 Id:07 Ch:2 T:18.4 H:70 MS;P0=606;P1=-2075;P2=-4136;P3=-9066;D=03010101010102020201010102010101010201020202010101020101010202010101020101020201010202;CP=0;SP=3;R=0;O;m2; - { - name => 'AHFL 433 B2', - comment => 'Auriol weatherstation IAN 314695', - id => '53', - knownFreqs => '433.92', - one => [1,-7], - zero => [1,-3.5], - sync => [1,-15], - clockabs => 600, - format => 'twostate', # not used now - preamble => 'W53#', - clientmodule => 'SD_WS', - modulematch => '^W53#.*', - length_min => '42', - length_max => '44', - }, - "54" => ## TFA Drop 30.3233.01 - Rain gauge - # Rain sensor 30.3233.01 for base station 47.3005.01 - # https://github.com/merbanan/rtl_433/blob/master/src/devices/tfa_drop_30.3233.c | https://forum.fhem.de/index.php/topic,107998.0.html @sido - # @sido - # SD_WS_54_R_D9C43 R: 73.66 MU;P1=247;P2=-750;P3=722;P4=-489;P5=491;P6=-236;P7=-2184;D=1232141456565656145656141456565614141456141414145656141414141456561414141456561414145614561456145614141414141414145614145656145614141732321414565656561456561414565656141414561414141456561414141414565614141414565614141456145614561456141414141414141456141;CP=1;R=55;O; - # SD_WS_54_R_D9C43 R: 74.422 MU;P0=-1672;P1=740;P2=-724;P3=260;P4=-468;P5=504;P6=-230;D=012123434565656563456563434565656343434563434343456563434343456345634343434565634565656345634563456343434343434343456563434345634345656;CP=3;R=4; - # @punker - # SD_WS_54_R_896E1 R: 28.702 MU;P0=-242;P1=-2076;P2=-13292;P3=242;P4=-718;P5=748;P6=-494;P7=481;CP=3;R=29;D=23454363670707036363670363670367070367070703636363670363636363670363636707036367070707036703670367036363636363636363636707036703636363154543636707070363636703636703670703670707036363636703636363636703636367070363670707070367036703670363636363636363636367;O; - # SD_WS_54_R_896E1 R: 29.464 MU;P0=-236;P1=493;P2=235;P3=-503;P4=-2076;P5=734;P6=-728;CP=2;R=11;D=0101023101023245656232310101023232310232310231010231010102323232310232323232310102323101023102310231023102310231023232323232323232323101010231010232;e;i; - { - name => 'TFA 30.3233.01', - comment => 'Rain sensor', - id => '54', - knownFreqs => '433.92', - one => [2,-1], - zero => [1,-2], - start => [3,-3], # message provided as MU - clockabs => 250, - reconstructBit => '1', - clientmodule => 'SD_WS', - format => 'twostate', - preamble => 'W54#', - length_min => '64', - length_max => '68', - }, - "54.1" => ## TFA Drop 30.3233.01 - Rain gauge - # Rain sensor 30.3233.01 for base station 47.3005.01 - # https://github.com/merbanan/rtl_433/blob/master/src/devices/tfa_drop_30.3233.c | https://forum.fhem.de/index.php/topic,107998.0.html @punker - # @punker - # SD_WS_54_R_896E1 R: 28.702 MS;P0=-241;P1=486;P2=241;P3=-488;P4=-2098;P5=738;P6=-730;D=24565623231010102323231023231023101023101010232323231023232323231023232310102323101010102310231023102323232323232323232310102310232323;CP=2;SP=4;R=30;O;b=19;s=1;m0; - # SD_WS_54_R_896E1 R: 29.464 MS;P0=-491;P1=242;P2=476;P3=-248;P4=-2096;P5=721;P6=-745;D=14565610102323231010102310102310232310232323101010102310101010102323101023231023102310231023102310231010101010101010101023232310232310;CP=1;SP=4;R=10;O;b=135;s=1;m0; - { - name => 'TFA 30.3233.01', - comment => 'Rain sensor', - id => '54.1', - knownFreqs => '433.92', - one => [2,-1], - zero => [1,-2], - sync => [3,-3], # message provided as MS - clockabs => 250, - clientmodule => 'SD_WS', - format => 'twostate', - preamble => 'W54#', - length_min => '64', - length_max => '68', - }, - "55" => ## QUIGG GT-1000 - { - name => 'QUIGG_GT-1000', - comment => 'remote control', - id => '55', - knownFreqs => '', - clockabs => 300, - zero => [1,-4], - one => [4,-2], - sync => [1,-8], - format => 'twostate', - preamble => 'i', # prepend to converted message - clientmodule => 'IT', - modulematch => '^i.*', - length_min => '24', - length_max => '24', - }, - "56" => ## Celexon Motorleinwand - # https://forum.fhem.de/index.php/topic,52025.0.html @Horst12345 - # MU;P0=5036;P1=-624;P2=591;P3=-227;P4=187;P5=-5048;D=0123412341414123234141414141414141412341232341414141232323234123234141414141414123414141414141414141234141414123234141412341232323250123412341414123234141414141414141412341232341414141232323234123234141414141414123414141414141414141234141414123234141412;CP=4;O; - # MU;P0=-228;P1=185;P2=-625;P3=593;P4=-5050;P5=5050;D=012121234523012301212123030121212121212121212301230301212121230303030123030303030301212123452301230121212303012121212121212121230123030121212123030303012303012121212121212301212121212121212121230121230121230303030301212123;CP=1; - { - name => 'Celexon', - id => '56', - knownFreqs => '', - clockabs => 200, - zero => [1,-3], - one => [3,-1], - start => [25,-3], - format => 'twostate', - preamble => 'u56#', # prepend to converted message - #clientmodule => '', - #modulematch => '', - length_min => '56', - length_max => '68', - }, - "57" => ## m-e doorbell fuer FG- und Basic-Serie - # https://forum.fhem.de/index.php/topic,64251.0.html @rippi46 - # P57#2AA4A7 | ring MC;LL=-653;LH=665;SL=-317;SH=348;D=D55B58;C=330;L=21; - # P57#2AA4A7 | ring MC;LL=-654;LH=678;SL=-314;SH=351;D=D55B58;C=332;L=21; - # P57#2AA4A7 | ring MC;LL=-653;LH=679;SL=-310;SH=351;D=D55B58;C=332;L=21; - { - name => 'm-e', - comment => 'radio gong transmitter for FG- and Basic-Serie', - id => '57', - knownFreqs => '', - clockrange => [300,360], # min , max - format => 'manchester', # tristate can't be migrated from bin into hex! - clientmodule => 'SD_BELL', - modulematch => '^P57#.*', - preamble => 'P57#', - length_min => '21', - length_max => '24', - method => \&lib::SD_Protocols::MCRAW, # Call to process this message - polarity => 'invert', - }, - "58" => ## TFA 30.3208.02, 30.3228.02, 30.3229.02, Froggit/Renkforce FT007TH, FT007PF, FT007T, FT007TP, Ambient Weather F007-TH, F007-T, F007-TP - # SD_WS_58_TH_200_2 Ch: 2 T: 18.9 H: 69 Bat: ok MC;LL=-981;LH=964;SL=-480;SH=520;D=002BA37EBDBBA24F0015D1BF5EDDD127800AE8DFAF6EE893C;C=486;L=194; - # Froggit FT007T - https://forum.fhem.de/index.php/topic,58397.msg1023517.html#msg1023517 - # SD_WS_58_T_135_2 Ch: 2 T: 22.2 Bat: ok MC;LL=-1047;LH=903;SL=-545;SH=449;D=800AE5E3AE7FD44BC00572F1D73FEA25E002B9788;C=494;L=161; - # SD_WS_58_T_135_2 Ch: 2 T: 22.3 Bat: ok MC;LL=-1047;LH=902;SL=-546;SH=452;D=0015CBC75CF7AA8F800AE5E3AE7BD547C00572F1D0;C=487;L=165; - # Renkforce FT007TH - https://forum.fhem.de/index.php/topic,65680.msg963889.html#msg963889 - # SD_WS_58_TH_84_2 Ch: 2 T: 23.9 H: 58 Bat: ok MC;LL=-1005;LH=946;SL=-505;SH=496;D=0015D55F5C0E2B47800AEAAFAE0715A3C0057557D7;C=487;L=168;R=0; - { - name => 'TFA 30.3208.0', - comment => 'Temperature/humidity sensors (TFA 30.3208.02, 30.3228.02, 30.3229.02, Froggit/Renkforce FT007xx, Ambient Weather F007-xx)', - id => '58', - knownFreqs => '433.92', - clockrange => [460,520], - format => 'manchester', - clientmodule => 'SD_WS', - modulematch => '^W58*', - preamble => 'W58#', - length_min => '52', # 54 - length_max => '52', # 136 - method => \&main::SIGNALduino_MCTFA, - polarity => 'invert', - }, - "59" => ## AK-HD-4 remote | 4 Buttons - # https://github.com/RFD-FHEM/RFFHEM/issues/133 @stevedee78 - # u59#6DCAFB MU;P0=819;P1=-919;P2=234;P3=-320;P4=8602;P6=156;D=01230301230301230303012123012301230303030301230303412303012303012303030121230123012303030303012303034123030123030123030301212301230123030303030123030341230301230301230303012123012301230303030301230303412303012303012303030121230123012303030303012303034163;CP=0;O; - # u59#6DCAFB MU;P0=-334;P2=8581;P3=237;P4=-516;P5=782;P6=-883;D=23456305056305050563630563056305050505056305050263050563050563050505636305630563050505050563050502630505630505630505056363056305630505050505630505026305056305056305050563630563056305050505056305050263050563050563050505636305630563050505050563050502630505;CP=5;O; - { - name => 'AK-HD-4', - comment => 'remote control with 4 buttons', - id => '59', - knownFreqs => '433.92', - clockabs => 230, - zero => [-4,1], - one => [-1,4], - start => [-1,37], - format => 'twostate', # tristate can't be migrated from bin into hex! - preamble => 'u59#', # Append to converted message - postamble => '', # Append to converted message - #clientmodule => '', - #modulematch => '', - length_min => '24', - length_max => '24', - }, - "60" => ## ELV, LA CROSSE (WS2000/WS7000) - # Id:11 T: 21.3 MU;P0=32001;P1=-381;P2=835;P3=354;P4=-857;D=01212121212121212121343421212134342121213434342121343421212134213421213421212121342121212134212121213421212121343421343430;CP=2;R=53; - # tested sensors: WS-7000-20, AS2000, ASH2000, S2000, S2000I, S2001A, S2001IA, - # ASH2200, S300IA, S2001I, S2000ID, S2001ID, S2500H - # not tested: AS3, S2000W, S2000R, WS7000-15, WS7000-16, WS2500-19, S300TH, S555TH - # das letzte Bit (1) und mehrere Bit (0) Preambel fehlen meistens - # ___ _ - # | |_ | |___ - # Bit 0 Bit 1 - # kurz 366 mikroSek / lang 854 mikroSek / gesamt 1220 mikroSek - Sollzeiten - { - name => 'WS2000', - comment => 'Series WS2000/WS7000 of various sensors', - id => '60', - knownFreqs => '', - one => [3,-7], - zero => [7,-3], - clockabs => 122, - preamble => 'K', # prepend to converted message - postamble => '', # Append to converted message - clientmodule => 'CUL_WS', - length_min => '38', # 46, letztes Bit fehlt = 45, 10 Bit Preambel = 35 Bit Daten - length_max => '82', - postDemodulation => \&main::SIGNALduino_postDemo_WS2000, - }, - "61" => ## ELV FS10 - # tested transmitter: FS10-S8, FS10-S4, FS10-ZE - # tested receiver: FS10-ST, FS10-MS, WS3000-TV, PC-Wettersensor-Empfaenger - # sends 2 messages with 43 or 48 bits in distance of 100 mS (on/off) , last bit 1 is missing - # sends x messages with 43 or 48 bits in distance of 200 mS (dimm) , repeats second message - # 2_13 | on MU;P0=1776;P1=-410;P2=383;P3=-820;D=01212121212121212121212123212121232323212323232121212323232121212321212123232123212120;CP=2;R=74; - # __ __ - # | |__ | |____ - # Bit 0 Bit 1 - # kurz 400 mikroSek / lang 800 mikroSek / gesamt 800 mikroSek = 0, gesamt 1200 mikroSek = 1 - Sollzeiten - { - name => 'FS10', - comment => 'remote control', - id => '61', - knownFreqs => '433.92', - one => [1,-2], - zero => [1,-1], - clockabs => 400, - pause => [-81], # 400*81=32400*6=194400 - pause between repeats of send messages (clockabs*pause must be < 32768) - format => 'twostate', - preamble => 'P61#', # prepend to converted message - postamble => '', # Append to converted message - clientmodule => 'FS10', - length_min => '30', # 43-1=42 (letztes Bit fehlt) 42-12=30 (12 Bit Preambel) - length_max => '48', - }, - "62" => ## Clarus_Switch - # ! some message are decode as protocol 32 ! - # Unknown code i415703, help me! MU;P0=-5893;P4=-634;P5=498;P6=-257;P7=116;D=45656567474747474745656707456747474747456745674567456565674747474747456567074567474747474567456745674565656747474747474565670745674747474745674567456745656567474747474745656707456747474747456745674567456565674747474747456567074567474747474567456745674567;CP=7;O; - { - name => 'Clarus_Switch', - id => '62', - knownFreqs => '', - one => [3,-1], - zero => [1,-3], - start => [1,-35], # ca 30-40 - clockabs => 189, - preamble => 'i', # prepend to converted message - clientmodule => 'IT', - #modulematch => '', - length_min => '24', - length_max => '24', - }, - "63" => ## Warema MU - # https://forum.fhem.de/index.php/topic,38831.msg395978/topicseen.html#msg395978 @Totte10 | https://www.mikrocontroller.net/topic/264063 - # no decode! MU;P0=-2988;P1=1762;P2=-1781;P3=-902;P4=871;P5=6762;P6=5012;D=0121342434343434352434313434243521342134343436; - # no decode! MU;P0=6324;P1=-1789;P2=864;P3=-910;P4=1756;D=0123234143212323232323032321234141032323232323232323;CP=2; - { - name => 'Warema', - comment => 'radio shutter switch (is still experimental)', - id => '63', - knownFreqs => '', - developId => 'y', - one => [1], - zero => [0], - clockabs => 800, - syncabs => '6700', # Special field for filterMC function - preamble => 'u63#', # prepend to converted message - #clientmodule => '', - #modulematch => '', - length_min => '24', - #length_max => '', # missing - filterfunc => 'SIGNALduino_filterMC', - }, - "64" => ## WH2 - # no decode! MU;P0=-32001;P1=457;P2=-1064;P3=1438;D=0123232323212121232123232321212121212121212323212121232321;CP=1;R=63; - # no decode! MU;P0=-32001;P1=473;P2=-1058;P3=1454;D=0123232323212121232123232121212121212121212121232321212321;CP=1;R=51; - # no value! MU;P0=134;P1=-113;P3=412;P4=-1062;P5=1379;D=01010101013434343434343454345454345454545454345454545454343434545434345454345454545454543454543454345454545434545454345;CP=3; - { - name => 'WH2', - comment => 'temperature / humidity sensor', - id => '64', - knownFreqs => '', - one => [1,-2], - zero => [3,-2], - clockabs => 490, - clientmodule => 'SD_WS', - modulematch => '^W64*', - preamble => 'W64#', # prepend to converted message - postamble => '', # Append to converted message - #clientmodule => '', - length_min => '48', - length_max => '54', - }, - "65" => ## Homeeasy - # on | vHE_EU MS;P1=231;P2=-1336;P4=-312;P5=-8920;D=15121214141412121212141414121212121414121214121214141212141212141212121414121414141212121214141214121212141412141212;CP=1;SP=5; - { - name => 'HomeEasy HE_EU', - id => '65', - knownFreqs => '', - one => [1,-5.5], - zero => [1,-1.2], - sync => [1,-38], - clockabs => 230, - format => 'twostate', # not used now - preamble => 'ih', - clientmodule => 'IT', - length_min => '57', - length_max => '72', - postDemodulation => \&main::SIGNALduino_HE_EU, - }, - "66" => ## TX2 Protocol (Remote Temp Transmitter & Remote Thermo Model 7035) - # https://github.com/RFD-FHEM/RFFHEM/issues/160 @elektron-bbs - # Id:66 T: 23.2 MU;P0=13312;P1=-2785;P2=4985;P3=1124;P4=-6442;P5=3181;P6=-31980;D=0121345434545454545434545454543454545434343454543434545434545454545454343434545434343434545621213454345454545454345454545434545454343434545434345454345454545454543434345454343434345456212134543454545454543454545454345454543434345454343454543454545454545;CP=3;R=73;O; - # Id:49 T: 25.2 MU;P0=32001;P1=-2766;P2=4996;P3=1158;P4=-6416;P5=3203;P6=-31946;D=01213454345454545454543434545454345454343434543454345454345454545454543434345434543434345456212134543454545454545434345454543454543434345434543454543454545454545434343454345434343454562121345434545454545454343454545434545434343454345434545434545454545454;CP=3;R=72;O; - { - name => 'WS7035', - comment => 'temperature sensor', - id => '66', - knownFreqs => '', - one => [10,-52], - zero => [27,-52], - start => [-21,42,-21], - clockabs => 122, - reconstructBit => '1', - format => 'pwm', # not used now - preamble => 'TX', - clientmodule => 'CUL_TX', - modulematch => '^TX......', - length_min => '43', - length_max => '44', - postDemodulation => \&main::SIGNALduino_postDemo_WS7035, - }, - "67" => ## TX2 Protocol (Remote Datalink & Remote Thermo Model 7053, 7054) - # https://github.com/RFD-FHEM/RFFHEM/issues/162 @elektron-bbs - # Id:72 T: 26.0 MU;P0=3381;P1=-672;P2=-4628;P3=1142;P4=-30768;D=010 2320232020202020232020232020202320232323202323202020202020202020 4 010 2320232020202020232020232020202320232323202323202020202020202020 0;CP=0;R=45; - # Id:72 T: 24.3 MU;P0=1148;P1=3421;P6=-664;P7=-4631;D=161 7071707171717171707171707171717171707070717071717171707071717171 0;CP=1;R=29; - # Message repeats 4 x with pause of ca. 30-34 mS - # __ ____ - # ________| | ________| | - # Bit 1 Bit 0 - # 4630 1220 4630 3420 mikroSek - mit Oszi gemessene Zeiten - { - name => 'WS7053', - comment => 'temperature sensor', - id => '67', - knownFreqs => '', - one => [-38,10], # -4636, 1220 - zero => [-38,28], # -4636, 3416 - clockabs => 122, - preamble => 'TX', # prepend to converted message - clientmodule => 'CUL_TX', - modulematch => '^TX......', - length_min => '32', - length_max => '34', - postDemodulation => \&main::SIGNALduino_postDemo_WS7053, - }, - "68" => ## Medion OR28V RF Vista Remote Control (Made in china by X10) - # sendet zwei verschiedene Codes pro Taste - # Taste ok 739E0 MS;P1=-1746;P2=513;P3=-571;P4=-4612;P5=2801;D=24512321212123232121212323212121212323232323;CP=2;SP=4;R=58;#;#; - # Taste ok F31E0 MS;P1=-1712;P2=518;P3=-544;P4=-4586;P5=2807;D=24512121212123232121232323212121212323232323;CP=2;SP=4;R=58;m2;#;#; - # Taste Vol+ E00B0 MS;P1=-1620;P2=580;P3=-549;P4=-4561;P5=2812;D=24512121212323232323232323232123212123232323;CP=2;SP=4;R=69;O;m2;#;#; - # Taste Vol+ 608B0 MS;P1=-1645;P2=574;P3=-535;P4=-4556;P5=2811;D=24512321212323232323212323232123212123232323;CP=2;SP=4;R=57;m2;#;#; - { - name => 'OR28V', - comment => 'Medion OR28V RF Vista Remote Control', - id => '68', - knownFreqs => '433.92', - one => [1,-3], - zero => [1,-1], - sync => [1,-8,5,-3], - clockabs => 550, - format => 'twostate', - preamble => 'P68#', - clientmodule => 'SD_UT', - modulematch => '^P68#.{5}', - length_min => '20', - length_max => '20', - }, - "69" => ## Hoermann HSM2, HSM4, HS1-868-BS (868 MHz) - # https://github.com/RFD-FHEM/RFFHEM/issues/149 - # HSM4 | button_1 MU;P0=-508;P1=1029;P2=503;P3=-1023;P4=12388;D=01010232323232310104010101010101010102323231010232310231023232323231023101023101010231010101010232323232310104010101010101010102323231010232310231023232323231023101023101010231010101010232323232310104010101010101010102323231010232310231023232323231023101;CP=2;R=37;O; - # Remote control HS1-868-BS (one button): - # https://github.com/RFD-FHEM/RFFHEM/issues/344 - # HS1_868_BS | receive MU;P0=-578;P1=1033;P2=506;P3=-1110;P4=13632;D=0101010232323101040101010101010101023232323102323101010231023102310231010232323101010101010101010232323101040101010101010101023232323102323101010231023102310231010232323101010101010101010232323101040101010101010101023232323102323101010231023102310231010;CP=2;R=77; - # HS1_868_BS | receive MU;P0=-547;P1=1067;P2=553;P3=-1066;P4=13449;D=0101010101010232323101040101010101010101023232323102323101010231023102310231010232323101010101010101010232323101040101010101010101023232323102323101010231023102310231010232323101010101010101010232323101040101010101010101023232323102323101010231023102310;CP=2;R=71; - # https://forum.fhem.de/index.php/topic,71877.msg642879.html (HSM4, Taste 1-4) - # HSM4 | button_1 MU;P0=-332;P1=92;P2=-1028;P3=12269;P4=-510;P5=1014;P6=517;D=01234545454545454545462626254546262546254626262626254625454625454546254545454546262626262545434545454545454545462626254546262546254626262626254625454625454546254545454546262626262545434545454545454545462626254546262546254626262626254625454625454546254545;CP=6;R=37;O; - # HSM4 | button_2 MU;P0=509;P1=-10128;P2=1340;P3=-517;P4=1019;P5=-1019;P6=12372;D=01234343434343434343050505434305054305430505050505430543430543434305434343430543050505054343634343434343434343050505434305054305430505050505430543430543434305434343430543050505054343634343434343434343050505434305054305430505050505430543430543434305434343;CP=0;R=52;O; - # HSM4 | button_3 MU;P0=12376;P1=360;P2=-10284;P3=1016;P4=-507;P6=521;P7=-1012;D=01234343434343434343467676734346767346734676767676734673434673434346734343434676767346767343404343434343434343467676734346767346734676767676734673434673434346734343434676767346767343404343434343434343467676734346767346734676767676734673434673434346734343;CP=6;R=55;O; - # HSM4 | button_4 MU;P0=-3656;P1=12248;P2=-519;P3=1008;P4=506;P5=-1033;D=01232323232323232324545453232454532453245454545453245323245323232453232323245453245454532321232323232323232324545453232454532453245454545453245323245323232453232323245453245454532321232323232323232324545453232454532453245454545453245323245323232453232323;CP=4;R=48;O; - { - name => 'Hoermann', - comment => 'remote control HS1-868-BS, HSM4', - id => '69', - knownFreqs => '433.92 | 868.35', - zero => [2,-1], # 1020,510 - one => [1,-2], # 510,1020 - start => [25,-1], # 12750,510 - clockabs => 510, - format => 'twostate', - clientmodule => 'SD_UT', - modulematch => '^P69#.{11}', - preamble => 'P69#', - length_min => '44', - length_max => '44', - }, - "70" => ## FHT80TF (Funk-Tuer-Fenster-Melder FHT 80TF und FHT 80TF-2) - # https://github.com/RFD-FHEM/RFFHEM/issues/171 @HomeAutoUser - # closed MU;P0=-24396;P1=417;P2=-376;P3=610;P4=-582;D=012121212121212121212121234123434121234341212343434121234123434343412343434121234341212121212341212341234341234123434;CP=1;R=35; - # open MU;P0=-21652;P1=429;P2=-367;P4=634;P5=-555;D=012121212121212121212121245124545121245451212454545121245124545454512454545121245451212121212124512451245451245121212;CP=1;R=38; - { - name => 'FHT80TF', - comment => 'door/window switch', - id => '70', - knownFreqs => '868.35', - one => [1.5,-1.5], # 600 - zero => [1,-1], # 400 - clockabs => 400, - format => 'twostate', # not used now - clientmodule => 'CUL_FHTTK', - preamble => 'T', - length_min => '50', - length_max => '58', - postDemodulation => \&main::SIGNALduino_postDemo_FHT80TF, - }, - "71" => ## PEARL infactory Poolthermometer (PV-8644) - # Ch:1 T: 24.2 MU;P0=1735;P1=-1160;P2=591;P3=-876;D=0123012323010101230101232301230123010101010123012301012323232323232301232323232323232323012301012;CP=2;R=97; - { - name => 'PEARL', - comment => 'infactory Poolthermometer (PV-8644)', - id => '71', - knownFreqs => '433.92', - clockabs => 580, - zero => [3,-2], - one => [1,-1.5], - format => 'twostate', - preamble => 'W71#', # prepend to converted message - clientmodule => 'SD_WS', - #modulematch => '^W71#.*' - length_min => '48', - length_max => '48', - }, - "72" => ## Siro blinds MU @Dr.Smag - # ! same definition how ID 16 ! - # module ERROR after delete and parse without save!!! - # >Siro_5B417081< returned by the Siro ParseFn is invalid, notify the module maintainer - # https://forum.fhem.de/index.php?topic=77167.0 - # MU;P0=-760;P1=334;P2=693;P3=-399;P4=-8942;P5=4796;P6=-1540;D=01010102310232310101010102310232323101010102310101010101023102323102323102323102310101010102310232323101010102310101010101023102310231023102456102310232310232310231010101010231023232310101010231010101010102310231023102310245610231023231023231023101010101;CP=1;R=45;O; - # MU;P0=-8848;P1=4804;P2=-1512;P3=336;P4=-757;P5=695;P6=-402;D=0123456345656345656345634343434345634565656343434345634343434343456345634563456345;CP=3;R=49; - { - name => 'Siro shutter', - comment => 'message decode as MU', - id => '72', - knownFreqs => '', - dispatchequals => 'true', - one => [2,-1.2], # 680, -400 - zero => [1,-2.2], # 340, -750 - start => [14,-4.4], # 4800,-1520 - clockabs => 340, - format => 'twostate', - preamble => 'P72#', # prepend to converted message - clientmodule => 'Siro', - #modulematch => '', - length_min => '39', - length_max => '40', - msgOutro => 'SR;P0=-8500;D=0;', - }, - "72.1" => ## Siro blinds MS @Dr.Smag - # Id:5B41708 state:0 MS;P0=4803;P1=-1522;P2=333;P3=-769;P4=699;P5=-393;P6=-9190;D=2601234523454523454523452323232323452345454523232323452323232323234523232345454545;CP=2;SP=6;R=61; - { - name => 'Siro shutter', - comment => 'message decode as MS', - id => '72', - knownFreqs => '', - developId => 'm', - dispatchequals => 'true', - one => [2,-1.2], # 680, -400 - zero => [1,-2.2], # 340, -750 - sync => [14,-4.4], # 4800,-1520 - clockabs => 340, - format => 'twostate', - preamble => 'P72#', # prepend to converted message - clientmodule => 'Siro', - #modulematch => '', - length_min => '39', - length_max => '40', - #msgOutro => 'SR;P0=-8500;D=0;', - }, - "73" => ## FHT80 - Raumthermostat (868Mhz) @HomeAutoUser - # actuator:0% MU;P0=136;P1=-112;P2=631;P3=-392;P4=402;P5=-592;P6=-8952;D=0123434343434343434343434325434343254325252543432543434343434325434343434343434343254325252543254325434343434343434343434343252525432543464343434343434343434343432543434325432525254343254343434343432543434343434343434325432525254325432543434343434343434;CP=4;R=250; - { - name => 'FHT80', - comment => 'roomthermostat (only receive)', - id => '73', - knownFreqs => '868.35', - one => [1.5,-1.5], # 600 - zero => [1,-1], # 400 - pause => [-25], - clockabs => 400, - format => 'twostate', # not used now - clientmodule => 'FHT', - preamble => '810c04xx0909a001', - length_min => '59', - length_max => '67', - postDemodulation => \&main::SIGNALduino_postDemo_FHT80, - }, - "74" => ## FS20 - Remote Control (868Mhz) @HomeAutoUser - # dim100% MU;P0=-10420;P1=-92;P2=398;P3=-417;P5=596;P6=-592;D=1232323232323232323232323562323235656232323232356232356232623232323232323232323232323235623232323562356565623565623562023232323232323232323232356232323565623232323235623235623232323232323232323232323232323562323232356235656562356562356202323232323232323;CP=2;R=72; - { - name => 'FS20', - comment => 'remote control (decode as MU)', - id => '74', - knownFreqs => '868.35', - one => [1.5,-1.5], # 600 - zero => [1,-1], # 400 - pause => [-25], - clockabs => 400, - #reconstructBit => '1', - format => 'twostate', # not used now - clientmodule => 'FS20', - preamble => '810b04f70101a001', - length_min => '50', - length_max => '67', - postDemodulation => \&main::SIGNALduino_postDemo_FS20, - }, - "74.1" => ## FS20 - Remote Control (868Mhz) @HomeAutoUser - # dim100% MS;P1=-356;P2=448;P3=653;P4=-551;P5=-10412;D=2521212121212121212121212134212121343421212121213421213421212121212121212121212121212121342121212134213434342134342134;CP=2;SP=5;R=72;O;!;4; - { - name => 'FS20', - comment => 'remote control (decode as MS)', - id => '74.1', - knownFreqs => '868.35', - one => [1.5,-1.5], # 600 - zero => [1,-1], # 400 - sync => [-25], - clockabs => 400, - #reconstructBit => '1', - format => 'twostate', # not used now - clientmodule => 'FS20', - preamble => '810b04f70101a001', - paddingbits => '1', # disable padding - length_min => '50', - length_max => '67', - postDemodulation => \&main::SIGNALduino_postDemo_FS20, - }, - "75" => ## Conrad RSL (Erweiterung v2) @litronics https://github.com/RFD-FHEM/SIGNALDuino/issues/69 - # ! same definition how ID 5, but other length ! - # !! protocol needed revision - start or sync failed !! https://github.com/RFD-FHEM/SIGNALDuino/issues/69#issuecomment-440349328 - # on MU;P0=-1365;P1=477;P2=1145;P3=-734;P4=-6332;D=01023202310102323102423102323102323101023232323101010232323231023102323102310102323102423102323102323101023232323101010232323231023102323102310102323102;CP=1;R=12; - { - name => 'Conrad RSL v2', - comment => 'remotes and switches', - id => '75', - knownFreqs => '', - one => [3,-1], - zero => [1,-3], - clockabs => 500, - format => 'twostate', - developId => 'y', - clientmodule => 'SD_RSL', - preamble => 'P1#', - modulematch => '^P1#[A-Fa-f0-9]{8}', - length_min => '32', - length_max => '40', - }, - "76" => ## Kabellose LED-Weihnachtskerzen XM21-0 - # ! min length not work - must CHECK ! - # https://github.com/RFD-FHEM/RFFHEM/pull/437#issuecomment-448019192 @sidey79 - # on -> P76#FFFFFFFFFFFFFFFF - # LED_XM21_0 | on MU;P0=-205;P1=113;P3=406;D=010101010101010101010101010101010101010101010101010101010101030303030101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010103030303010101010101010101010100;CP=1;R=69; - # LED_XM21_0 | on MU;P0=-198;P1=115;P4=424;D=0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010404040401010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101040404040;CP=1;R=60;O; - # LED_XM21_0 | on MU;P0=114;P1=-197;P2=419;D=0121212121010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101012121212101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010;CP=0;R=54;O; - # off -> P76#FFFFFFFFFFFFFFC - # LED_XM21_0 | off MU;P0=-189;P1=115;P4=422;D=0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101040404040101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010104040404010101010;CP=1;R=73;O; - # LED_XM21_0 | off MU;P0=-203;P1=412;P2=114;D=01010101020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020101010102020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020200;CP=2;R=74; - # LED_XM21_0 | off MU;P0=-210;P1=106;P3=413;D=0101010101010101010303030301010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101030303030100;CP=1;R=80; - { - name => 'LED XM21', - comment => 'remote with 2-buttons for LED X-MAS light string', - id => '76', - knownFreqs => '433.92', - one => [1.2,-2], # 120,-200 - #zero => [], # existiert nicht - start => [4.5,-2,4.5,-2,4.5,-2,4.5,-2], # 450,-200 Starsequenz - clockabs => 100, - format => 'twostate', # not used now - clientmodule => 'SD_UT', - preamble => 'P76#', - length_min => 58, - length_max => 64, - }, - "77" => ## NANO_DS1820_4Fach - # https://github.com/juergs/NANO_DS1820_4Fach - # Id:105 T: 22.8 MU;P0=-1483;P1=239;P2=970;P3=-21544;D=01020202010132020202010201020202020201010201020201020201010102020102010202020201010102020102020201013202020201020102020202020101020102020102020101010202010201020202020101010202010202020101;CP=1; - # Id:106 T: 0.0 MU;P0=-168;P1=420;P2=-416;P3=968;P4=-1491;P5=242;P6=-21536;D=01234343434543454343434343454543454345434543454345434343434343434343454345434343434345454363434343454345434343434345454345434543454345434543434343434343434345434543434343434545436343434345434543434343434545434543454345434543454343434343434343434543454343;CP=3;O; - # Id:106 T: 0.0 MU;P0=-1483;P1=969;P2=236;P3=-21542;D=01010102020131010101020102010101010102020102010201020102010201010101010101010102010201010101010202013101010102010201010101010202010201020102010201020101010101010101010201020101010101020201;CP=1; - # Id:107 T: 0.0 MU;P0=-32001;P1=112;P2=-8408;P3=968;P4=-1490;P5=239;P6=-21542;D=01234343434543454343434343454543454345454343454345434343434343434343454345434343434345454563434343454345434343434345454345434545434345434543434343434343434345434543434343434545456343434345434543434343434545434543454543434543454343434343434343434543454343;CP=3;O; - # Id:107 T: 0.0 MU;P0=-1483;P1=968;P2=240;P3=-21542;D=01010102020231010101020102010101010102020102010202010102010201010101010101010102010201010101010202023101010102010201010101010202010201020201010201020101010101010101010201020101010101020202;CP=1; - # Id:108 T: 0.0 MU;P0=-32001;P1=969;P2=-1483;P3=237;P4=-21542;D=01212121232123212121212123232123232121232123212321212121212121212123212321212121232123214121212123212321212121212323212323212123212321232121212121212121212321232121212123212321412121212321232121212121232321232321212321232123212121212121212121232123212121;CP=1;O; - # Id:108 T: 0.0 MU;P0=-1485;P1=967;P2=236;P3=-21536;D=010201020131010101020102010101010102020102020101020102010201010101010101010102010201010101020102013101010102010201010101010202010202010102010201020101010101010101010201020101010102010201;CP=1; - { - name => 'NANO_DS1820_4Fach', - comment => 'self build sensor', - id => '77', - knownFreqs => '', - developId => 'y', - zero => [4,-6], - one => [1,-6], - clockabs => 250, - format => 'pwm', # - preamble => 'TX', # prepend to converted message - clientmodule => 'CUL_TX', - modulematch => '^TX......', - length_min => '43', - length_max => '44', - remove_zero => 1, # Removes leading zeros from output - }, - # "78" => ## GEIGER blind motors - # # https://forum.fhem.de/index.php/topic,39153.0.html @fasch - # # MU;P0=313;P1=1212;P2=-309;P4=-2024;P5=-16091;P6=2014;D=01204040562620404626204040404040462046204040562620404626204040404040462046204040562620404626204040404040462046204040562620404626204040404040462046204040;CP=0;R=236; - # # MU;P0=-15770;P1=2075;P2=-264;P3=326;P4=-2016;P5=948;D=012121234121234341212121234341234343012125;CP=3;R=208; - # { - # name => 'GEIGER blind motors', - # comment => 'example remote control GF0001', - # id => '78', - # knownFreqs => '', - # developId => 'y', - # zero => [1,-6.6], - # one => [6.6,-1], - # start => [-53], - # clockabs => 300, - # format => 'twostate', - # preamble => 'u78#', # prepend to converted message - # clientmodule => 'SIGNALduino_un', - # #modulematch => '^TX......', - # length_min => '14', - # length_max => '18', - # paddingbits => '2' # pad 1 bit, default is 4 - # }, - "79" => ## Heidemann | Heidemann HX | VTX-BELL - # https://github.com/RFD-FHEM/SIGNALDuino/issues/84 - # P79#A5E | ring MU;P0=656;P1=-656;P2=335;P3=-326;P4=-5024;D=0123012123012303030301 24 230123012123012303030301 24 230123012123012303030301 24 2301230121230123030303012423012301212301230303030124230123012123012303030301242301230121230123030303012423012301212301230303030124230123012123012303030301242301230121230123030303;CP=2;O; - # https://forum.fhem.de/index.php/topic,64251.0.html - # P79#4FC | ring MU;P0=540;P1=-421;P2=-703;P3=268;P4=-4948;D=4 323102323101010101010232 34 323102323101010101010232 34 323102323101010101010232 34 3231023231010101010102323432310232310101010101023234323102323101010101010232343231023231010101010102323432310232310101010101023234323102323101010101010232343231023231010101010;CP=3;O; - # https://github.com/RFD-FHEM/RFFHEM/issues/252 - # P79#A0E | ring MU;P0=-24096;P1=314;P2=-303;P3=615;P4=-603;P5=220;P6=-4672;D=0123456123412341414141412323234 16 123412341414141412323234 16 12341234141414141232323416123412341414141412323234161234123414141414123232341612341234141414141232323416123412341414141412323234161234123414141414123232341612341234141414141232323416123412341414;CP=1;R=26;O; - # P79#A0E | ring MU;P0=-10692;P1=602;P2=-608;P3=311;P4=-305;P5=-4666;D=01234123232323234141412 35 341234123232323234141412 35 341234123232323234141412 35 34123412323232323414141235341234123232323234141412353412341232323232341414123534123412323232323414141235341234123232323234141412353412341232323232341414123534123412323232323414;CP=3;R=47;O; - # P79#A0E | ring MU;P0=-7152;P1=872;P2=-593;P3=323;P4=-296;P5=622;P6=-4650;D=01234523232323234545452 36 345234523232323234545452 36 345234523232323234545452 36 34523452323232323454545236345234523232323234545452363452345232323232345454523634523452323232323454545236345234523232323234545452363452345232323232345454523634523452323232323454;CP=3;R=26;O; - # https://forum.fhem.de/index.php/topic,58397.msg879878.html#msg879878 @rcmcronny - # P79#3FC | ring MU;P0=-421;P1=344;P2=-699;P4=659;P6=-5203;P7=259;D=1612121040404040404040421216121210404040404040404212161212104040404040404042121612121040404040404040421216121210404040404040404272761212104040404040404042121612121040404040404040421216121210404040404040404212167272104040404040404042721612127040404040404;CP=4;R=0;O; - { - name => 'wireless doorbell', - comment => 'Heidemann | Heidemann HX | VTX-BELL', - id => '79', - knownFreqs => '', - zero => [-2,1], - one => [-1,2], - start => [-15,1], - clockabs => 330, - format => 'twostate', # - preamble => 'P79#', # prepend to converted message - clientmodule => 'SD_BELL', - modulematch => '^P79#.*', - length_min => '12', - length_max => '12', - }, - "80" => ## EM1000WZ (Energy-Monitor) Funkprotokoll (868Mhz) @HomeAutoUser | Derwelcherichbin - # https://github.com/RFD-FHEM/RFFHEM/issues/253 - # CNT:91 CUM:14.560 5MIN:0.240 TOP:0.170 MU;P1=-417;P2=385;P3=-815;P4=-12058;D=42121212121212121212121212121212121232321212121212121232321212121212121232323212323212321232121212321212123232121212321212121232323212121212121232121212121212121232323212121212123232321232121212121232123232323212321;CP=2;R=87; - { - name => 'EM1000WZ', - comment => 'EM (Energy-Monitor)', - id => '80', - knownFreqs => '868.35', - one => [1,-2], # 800 - zero => [1,-1], # 400 - clockabs => 400, - format => 'twostate', # not used now - clientmodule => 'CUL_EM', - preamble => 'E', - length_min => '104', - length_max => '114', - postDemodulation => \&main::SIGNALduino_postDemo_EM, - }, - "81" => ## Remote control SA-434-1 based on HT12E @elektron-bbs - # P86#115 | receive MU;P0=-485;P1=188;P2=-6784;P3=508;P5=1010;P6=-974;P7=-17172;D=0123050505630505056305630563730505056305050563056305637305050563050505630563056373050505630505056305630563730505056305050563056305637305050563050505630563056373050505630505056305630563730505056305050563056305637305050563050505630563056373050505630505056;CP=3;R=0; - # P86#115 | receive MU;P0=-1756;P1=112;P2=-11752;P3=496;P4=-495;P5=998;P6=-988;P7=-17183;D=0123454545634545456345634563734545456345454563456345637345454563454545634563456373454545634545456345634563734545456345454563456345637345454563454545634563456373454545634545456345634563734545456345454563456345637345454563454545634563456373454545634545456;CP=3;R=0; - # __ ____ - # ____| | __| | - # Bit 1 Bit 0 - # short 500 microSec / long 1000 microSec / bittime 1500 mikroSek / pilot 12 * bittime, from that 1/3 bitlength high - { - name => 'SA-434-1', - comment => 'remote control SA-434-1 mini 923301 based on HT12E', - id => '81', - knownFreqs => '433.92', - one => [-2,1], # i.O. - zero => [-1,2], # i.O. - start => [-35,1], # Message is not provided as MS, worakround is start - clockabs => 500, - format => 'twostate', - preamble => 'P81#', # prepend to converted message - modulematch => '^P81#.{3}', - clientmodule => 'SD_UT', - length_min => '12', - length_max => '12', - }, - "82" => ## Fernotron shutters and light switches - # https://github.com/RFD-FHEM/RFFHEM/issues/257 @zwiebert - # down | MU;P0=-200;P1=21748;P2=-25008;P3=410;P4=-388;P5=-3189;P6=811;P7=-785;CP=3;D=012343434343434343564646464376464646437356464646437646464376435643737373764376464373564373737376437643764356437373737373737643735643737373737373737643564376464376464646464356437646437646464373735376437646464646464643537643764646464643737353737646464646437643735373764646464643737643;e; - # stop | MU;P0=-32001;P1=441;P2=-355;P3=-3153;P4=842;P5=-757;CP=1;D=0121212121212121342424242154242424215134242424215424242154213421515151542154242151342151515154215421542134215151515151515421513421515151515151515421342154242421542424242134215424242154242151513151542424242424242421315154242424242421515131542424215424215421513154242421542421515421;e; - # the messages received are usual missing 12 bits at the end for some reason. So the checksum byte is missing. - # Fernotron protocol is unidirectional. Here we can only receive messages from controllers send to receivers. - { - name => 'Fernotron', - comment => 'shutters and light switches', - id => '82', - knownFreqs => '', - developId => 'm', - dispatchBin => '1', - paddingbits => '1', # disable padding - one => [1,-2], # on=400us, off=800us - zero => [2,-1], # on=800us, off=400us - float => [1,-8], # on=400us, off=3200us. the preamble and each 10bit word has one [1,-8] in front - pause => [1,-1], # preamble (5x) - clockabs => 400, # 400us - format => 'twostate', - preamble => 'P82#', # prepend our protocol number to converted message - clientmodule => 'Fernotron', - length_min => '100', # actual 120 bit (12 x 10bit words to decode 6 bytes data), but last 20 are for checksum - length_max => '3360', # 3360 bit (336 x 10bit words to decode 168 bytes data) for full timer message - }, - "83" => ## Remote control RH787T based on MOSDESIGN SEMICONDUCTOR CORP (CMOS ASIC encoder) M1EN compatible HT12E - # for example Westinghouse Deckenventilator Delancey, 6 speed buttons, @zwiebelxxl - # https://github.com/RFD-FHEM/RFFHEM/issues/250 - # 1_fan_minimum_speed MU;P0=388;P1=-112;P2=267;P3=-378;P5=585;P6=-693;P7=-11234;D=0123035353535356262623562626272353535353562626235626262723535353535626262356262627235353535356262623562626272353535353562626235626262723535353535626262356262627235353535356262623562626272353535353562626235626262723535353535626262356262627235353535356262;CP=2;R=43;O; - # 2_fan_low_speed MU;P0=-176;P1=262;P2=-11240;P3=112;P5=-367;P6=591;P7=-695;D=0123215656565656717171567156712156565656567171715671567121565656565671717156715671215656565656717171567156712156565656567171715671567121565656565671717156715671215656565656717171567156712156565656567171715671567121565656565671717171717171215656565656717;CP=1;R=19;O; - # 3_fan_medium_low_speed MU;P0=564;P1=-392;P2=-713;P3=245;P4=-11247;D=0101010101023231023232323431010101010232310232323234310101010102323102323232343101010101023231023232323431010101010232310232323234310101010102323102323232343101010101023231023232323431010101010232310232323234310101010102323102323232343101010101023231023;CP=3;R=40;O; - { - name => 'RH787T', - comment => 'remote control for example Westinghouse Delancey 7800140', - id => '83', - knownFreqs => '433.92', - one => [-2,1], - zero => [-1,2], - start => [-35,1], # calculated 12126,31579 µS - clockabs => 335, # calculated ca 336,8421053 µS short - 673,6842105µS long - format => 'twostate', # there is a pause puls between words - preamble => 'P83#', # prepend to converted message - clientmodule => 'SD_UT', - modulematch => '^P83#.{3}', - length_min => '12', - length_max => '12', - }, - "84" => ## Funk Wetterstation Auriol IAN 283582 Version 06/2017 (Lidl), Modell-Nr.: HG02832D, 09/2018 @roobbb - # ! some message are decode as protocol 40 ! - # https://github.com/RFD-FHEM/RFFHEM/issues/263 - # Ch:1 T: 25.3 H: 53 Bat:ok MU;P0=-28796;P1=376;P2=-875;P3=834;P4=220;P5=-632;P6=592;P7=-268;D=0123232324545454545456767454567674567456745674545454545456767676767674567674567676767456;CP=4;R=22; - # Ch:2 T: 13.1 H: 78 Bat:ok MU;P0=-28784;P1=340;P2=-903;P3=814;P4=223;P5=-632;P6=604;P7=-248;D=0123232324545454545456767456745456767674545674567454545456745454545456767454545456745676;CP=4;R=22; - # Ch:1 T: 6.9 H: 66 Bat:ok MU;P0=-21520;P1=235;P2=-855;P3=846;P4=620;P5=-236;P7=-614;D=012323232454545454545451717451717171745171717171717171717174517171745174517174517174545;CP=1;R=217; - ## Sempre 92596/65395, Hofer/Aldi, WS97210-1, WS97230-1, WS97210-2, WS97230-2 - # https://github.com/RFD-FHEM/RFFHEM/issues/223 - # Ch:3 T: 21.3 H: 77 Bat:ok MU;P0=-30004;P1=815;P2=-910;P3=599;P4=-263;P5=234;P6=-621;D=0121212345634565634345656345656343456345656345656565656343456345634563456343434565656;CP=5;R=5; - ## TECVANCE TV-4848 (Amazon) @HomeAutoUser - # Ch:1 T: 26.4 H: 49 (L39) MU;P0=-218;P1=254;P2=-605;P4=616;P5=907;P6=-799;P7=-1536;D=012121212401212124012401212121240125656565612401240404040121212404012121240121212121212124012121212401212124012401212121247;CP=1; - # Ch:1 T: 26.6 H: 49 (L41) MU;P0=239;P1=-617;P2=612;P3=-245;P4=862;P5=-842;D=01230145454545012301232323230101012323010101230123010101010123010101012301230123232301012301230145454545012301232323230101012323010101230123010101010123010101012301230123232301012301230145454545012301232323230101012323010101230123010101010123010101012301;CP=0;R=89;O; - { - name => 'IAN 283582 / TV-4848', - comment => 'Weatherstation Auriol IAN 283582 / Sempre 92596/65395 / TECVANCE', - id => '84', - knownFreqs => '433.92', - one => [3,-1], - zero => [1,-3], - start => [4,-4,4,-4,4,-4], - clockabs => 215, - format => 'twostate', - preamble => 'W84#', # prepend to converted message - postamble => '', # append to converted message - clientmodule => 'SD_WS', - length_min => '39', # das letzte Bit fehlt meistens - length_max => '41', - }, - "85" => ## Funk Wetterstation TFA 35.1140.01 mit Temperatur-/Feuchte- und Windsensor TFA 30.3222.02 09/2018 @Iron-R - # https://github.com/RFD-FHEM/RFFHEM/issues/266 - # Ch:1 T: 8.7 H: 85 Bat:ok MU;P0=-509;P1=474;P2=-260;P3=228;P4=718;P5=-745;D=01212303030303012301230123012301230301212121230454545453030303012123030301230303012301212123030301212303030303030303012303012303012303012301212303030303012301230123012301230301212121212454545453030303012123030301230303012301212123030301212303030303030303;CP=3;R=46;O; - # Ch:1 T: 7.6 H: 89 Bat:ok MU;P0=7944;P1=-724;P2=742;P3=241;P4=-495;P5=483;P6=-248;D=01212121343434345656343434563434345634565656343434565634343434343434345634345634345634343434343434343434345634565634345656345634343456563421212121343434345656343434563434345634565656343434565634343434343434345634345634345634343434343434343434345634565634;CP=3;R=47;O; - { - name => 'TFA 30.3222.02', - comment => 'Combisensor for Weatherstation TFA 35.1140.01', - id => '85', - knownFreqs => '', - one => [2,-1], - zero => [1,-2], - start => [3,-3,3,-3,3,-3], - clockabs => 250, - format => 'twostate', - preamble => 'W85#', # prepend to converted message - postamble => '', # append to converted message - clientmodule => 'SD_WS', - length_min => '64', - length_max => '68', - }, - "86" => ### for remote controls: Novy 840029, CAME TOP 432EV, BOSCH & Neff Transmitter SF01 01319004 - ### CAME TOP 432EV 433,92 MHz für z.B. Drehtor Antrieb: - # https://forum.fhem.de/index.php/topic,63370.msg849400.html#msg849400 - # https://github.com/RFD-FHEM/RFFHEM/issues/151 @andreasloe - # CAME TOP 432EV | right_button MU;P0=711;P1=-15288;P4=132;P5=-712;P6=316;P7=-313;D=4565656705656567056567056 16 565656705656567056567056 16 56565670565656705656705616565656705656567056567056165656567056565670565670561656565670565656705656705616565656705656567056567056165656567056565670565670561656565670565656705656705616565656705656567056;CP=6;R=52; - # CAME TOP 432EV | left_button MU;P0=-322;P1=136;P2=-15241;P3=288;P4=-735;P6=723;D=012343434306434343064343430623434343064343430643434306 2343434306434343064343430 623434343064343430643434306234343430643434306434343062343434306434343064343430623434343064343430643434306234343430643434306434343062343434306434343064343430;CP=3;R=27; - # CAME TOP 432EV | right_button MU;P0=-15281;P1=293;P2=-745;P3=-319;P4=703;P5=212;P6=152;P7=-428;D=0 1212121342121213421213421 01 212121342121213421213421 01 21212134212121342121342101212121342121213421213421012121213421212134212134210121243134212121342121342101252526742121213425213421012121213421212134212134210121212134212;CP=1;R=23; - # rechteTaste: 0x112 (000100010010), linkeTaste: 0x111 (000100010001), the least significant bits distinguish the keys - ### remote control Novy 840029 for Novy Pureline 6830 kitchen hood: - # https://github.com/RFD-FHEM/RFFHEM/issues/331 @Garfonso - # Novy 840029 | light on/off button MU;P0=710;P1=353;P2=-403;P4=-761;P6=-16071;D=20204161204120412041204120414141204120202041612041204120412041204141412041202020416120412041204120412041414120412020204161204120412041204120414141204120202041;CP=1;R=40; - # Novy 840029 | plus button MU;P0=22808;P1=-24232;P2=701;P3=-765;P4=357;P5=-15970;P7=-406;D=012345472347234723472347234723454723472347234723472347234547234723472347234723472345472347234723472347234723454723472347234723472347234;CP=4;R=39; - # Novy 840029 | minus button MU;P0=-8032;P1=364;P2=-398;P3=700;P4=-760;P5=-15980;D=0123412341234123412341412351234123412341234123414123512341234123412341234141235123412341234123412341412351234123412341234123414123;CP=1;R=40; - # Novy 840029 | power button MU;P0=-756;P1=718;P2=354;P3=-395;P4=-16056;D=01020202310231310202 42 310231023102310231020202310231310202 42 31023102310231023102020231023131020242310231023102310231020202310231310202;CP=2;R=41; - # Novy 840029 | novy button MU;P0=706;P1=-763;P2=370;P3=-405;P4=-15980;D=0123012301230304230123012301230123012303042;CP=2;R=42; - ### remote control Novy 840039 for Novy Cloud 230 kitchen hood: - # https://github.com/RFD-FHEM/RFFHEM/issues/792 | https://forum.fhem.de/index.php/topic,107867.0.html @Devirex - # note: !! Clockpulse is 375, value from ID 86 350 it does not work !! - # Novy 840039 | power_button MU;P0=-749;P1=378;P2=-456;P3=684;P4=-16081;D=01230101012301232301014123012301230123012301010123012323010141230123012301230123010101230123230101412;CP=1;R=66; - # Novy 840039 | cooking_light on MU;P0=-750;P1=375;P2=-418;P3=682;P4=-16059;P5=290;P6=-5060;D=0123010123010123010123412305230123012301230101230101230101234123012301230123012301012301012301012341230123012301230123010123010123010123416505230123010123010123010123412; - ### Neff Transmitter SF01 01319004 (SF01_01319004) 433,92 MHz - # https://github.com/RFD-FHEM/RFFHEM/issues/376 @fhemjcm - # SF01_01319004 | light_on_off MU;P0=-707;P1=332;P2=-376;P3=670;P5=-15243;D=01012301232323230123012301232301010123510123012323232301230123012323010101235101230123232323012301230123230101012351012301232323230123012301232301010123510123012323232301230123012323010101235101230123232323012301230123230101012351012301232323230123012301;CP=1;R=3;O; - # SF01_01319004 | plus MU;P0=-32001;P1=348;P2=-704;P3=-374;P4=664;P5=-15255;D=01213421343434342134213421343421213434512134213434343421342134213434212134345121342134343434213421342134342121343451213421343434342134213421343421213434512134213434343421342134213434212134345121342134343434213421342134342121343451213421343434342134213421;CP=1;R=15;O; - # SF01_01319004 | minus MU;P0=-32001;P1=326;P2=-721;P3=-385;P4=656;P5=-15267;D=01213421343434342134213421343421342134512134213434343421342134213434213421345121342134343434213421342134342134213451213421343434342134213421343421342134512134213434343421342134213434213421345121342134343434213421342134342134213451213421343434342134213421;CP=1;R=10;O; - # SF01_01319004 | interval MU;P0=-372;P1=330;P2=684;P3=-699;P4=-14178;D=010231020202023102310231020231310231413102310202020231023102310202313102314;CP=1;R=253; - # SF01_01319004 | delay MU;P0=-710;P1=329;P2=-388;P3=661;P4=-14766;D=01232301410123012323232301230123012323012323014;CP=1;R=1; - ### BOSCH Transmitter SF01 01319004 (SF01_01319004_Typ2) 433,92 MHz - # SF01_01319004_Typ2 | light_on_off MU;P0=706;P1=-160;P2=140;P3=-335;P4=-664;P5=385;P6=-15226;P7=248;D=01210103045303045453030304545453030454530653030453030454530303045454530304747306530304530304545303030454545303045453065303045303045453030304545453030454530653030453030454530303045454530304545306530304530304545303030454545303045453065303045303045453030304;CP=5;O; - # SF01_01319004_Typ2 | plus MU;P0=-15222;P1=379;P2=-329;P3=712;P6=-661;D=30123236123236161232323616161232361232301232361232361612323236161612323612323012323612323616123232361616123236123230123236123236161232323616161232361232301232361232361612323236161612323612323012323612323616123232361616123236123230123236123236161232323616;CP=1;O; - # SF01_01319004_Typ2 | delay MU;P0=705;P1=-140;P2=-336;P3=-667;P4=377;P5=-15230;P6=248;D=01020342020343420202034343420202020345420203420203434202020343434202020203654202034202034342020203434342020202034542020342020343420202034343420202020345420203420203434202020343434202020203454202034202034342020203434342020202034542020342020343420202034343;CP=4;O; - # SF01_01319004_Typ2 | minus MU;P0=704;P1=-338;P2=-670;P3=378;P4=-15227;P5=244;D=01023231010102323231010102310431010231010232310101023232310101025104310102310102323101010232323101010231043101023101023231010102323231010102310431010231010232310101023232310101023104310102310102323101010232323101010231043101023101023231010102323231010102;CP=3;O; - # SF01_01319004_Typ2 | interval MU;P0=-334;P1=709;P2=-152;P3=-663;P4=379;P5=-15226;P6=250;D=01210134010134340101013434340101340134540101340101343401010134343401013601365401013401013434010101343434010134013454010134010134340101013434340101340134540101340101343401010134343401013401345401013401013434010101343434010134013454010134010134340101013434;CP=4;O; - { - name => 'BOSCH | CAME | Novy | Neff | Refsta Topdraft', - comment => 'remote control CAME TOP 432EV, Novy 840029 & 840039, BOSCH / Neff or Refsta Topdraft SF01 01319004', - id => '86', - knownFreqs => '433.92', - one => [-2,1], - zero => [-1,2], - start => [-44,1], - clockabs => 350, - format => 'twostate', - preamble => 'P86#', # prepend to converted message - clientmodule => 'SD_UT', - #modulematch => '^P86#.*', - length_min => '12', - length_max => '18', - }, - "87" => ## JAROLIFT Funkwandsender TDRC 16W / TDRCT 04W - # https://github.com/RFD-FHEM/RFFHEM/issues/380 @bismosa - # P87#E8119A34200065F100 | button=up MS;P1=1524;P2=-413;P3=388;P4=-3970;P5=-815;P6=778;P7=-16024;D=34353535623562626262626235626262353562623535623562626235356235626262623562626262626262626262626262623535626235623535353535626262356262626262626267123232323232323232323232;CP=3;SP=4;R=226;O;m2; - # P87#CD287247200065F100 | button=up MS;P0=-15967;P1=1530;P2=-450;P3=368;P4=-3977;P5=-835;P6=754;D=34353562623535623562623562356262626235353562623562623562626235353562623562626262626262626262626262623535626235623535353535626262356262626262626260123232323232323232323232;CP=3;SP=4;R=229;O; - # KeeLoq is a registered trademark of Microchip Technology Inc. - { - name => 'JAROLIFT', - comment => 'remote control JAROLIFT TDRC_16W / TDRCT_04W', - id => '87', - knownFreqs => '433.92', - one => [1,-2], - zero => [2,-1], - preSync => [3.8,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1], - sync => [1,-10], # this is a end marker, but we use this as a start marker - pause => [-40], - clockabs => 400, # ca 400us - reconstructBit => '1', - format => 'twostate', - preamble => 'P87#', # prepend to converted message - clientmodule => 'SD_Keeloq', - #modulematch => '', - length_min => '72', # 72 - length_max => '85', # 85 - }, - "88" => ## Roto Dachfensterrolladen | Aurel Fernbedienung "TX-nM-HCS" (HCS301 chip) | three buttons -> up, stop, down - # https://forum.fhem.de/index.php/topic,91244.0.html @bruen985 - # P88#AC3895D790EAFEF2C | button=0100 MS;P1=361;P2=-435;P4=-4018;P5=-829;P6=759;P7=-16210;D=141562156215156262626215151562626215626215621562151515621562151515156262156262626215151562156215621515151515151562151515156262156215171212121212121212121212;CP=1;SP=4;R=66;O;m0; - # P88#9451E57890EAFEF24 | button=0100 MS;P0=-16052;P1=363;P2=-437;P3=-4001;P4=-829;P5=755;D=131452521452145252521452145252521414141452521452145214141414525252145252145252525214141452145214521414141414141452141414145252145252101212121212121212121212;CP=1;SP=3;R=51;O;m1; - ## remote control Waeco MA650_TX (HCS300 chip) | two buttons - # P88#4A823F65482822040 | button=blue MS;P0=344;P3=-429;P4=-3926;P5=719;P6=-823;P7=-15343;D=045306535306530653065353535353065353530606060606065306065353065306530653530653535353530653065353535353065353530653535353535306535353570303030303030303030303;CP=0;SP=4;R=38;O;m2;0;0; - ## remote control RADEMACHER RP-S1-HS-RF11 (HCS301 chip) fuer Garagentorantrieb RolloPort S1 with two buttons - # https://github.com/RFD-FHEM/RFFHEM/issues/612 @ D3ltorohd 20.07.2019 - # Firmware: Signalduino V 3.3.2.1-rc8 SIGNALduino cc1101 - compiled at Jan 10 2019 20:13:56 - # P88#7EFDFFDDF9C284E4C | button=0010 MS;P1=735;P2=-375;P3=377;P4=-752;P6=-3748;D=3612343434343434123434343434341234343434343434343434341234343412343434343434121234343412121212341234121212123412123434341212341212343;CP=3;SP=6;R=42;e;m1; - # P88#C2C85435F9C284E18 | button=1000 MS;P1=385;P2=-375;P3=-3756;P4=-745;P5=766;P6=-15000;D=131414525252521452141452521452525252145214521452525252141452145214141414141452521414145252525214521452525252145252141414525252521414561212121212121212121212;CP=1;SP=3;R=54;O;s=36;m0; - ## remote control SCS Sentinel - PR3-4207-002 (HCS300 chip) | four buttons - # https://github.com/RFD-FHEM/RFFHEM/issues/616 - # P88#0A8423F39D6020044 | button=one MS;P0=844;P1=-4230;P2=420;P4=-860;P6=-17704;P7=-439;D=210707070724072407240707070724070707072407070724242424242407072424240707242424072407242407070707070707240707070707070707070724070707262727272727272727272727;CP=2;SP=1;R=18;O;s=36;m0; - # P88#00C7922B9D6020024 | button=two MS;P1=417;P3=847;P4=-442;P5=-858;P7=-4258;D=1734343434343434341515343434151515153434153434153434341534153415151534341515153415341515343434343434341534343434343434343434341534341;CP=1;SP=7;R=25;e;m1; - # P88#F82542039D6020014 | button=three MS;P0=-855;P1=852;P2=-433;P3=432;P5=-17236;P6=-4250;D=363030303030121212121230121230123012301212121230121212121212123030301212303030123012303012121212121212301212121212121212121212123012353232323232323232323232;CP=3;SP=6;R=29;O;s=36;m0; - # P88#DB06531F9D6020084 | button=four MS;P0=-17496;P1=435;P2=-438;P4=-4269;P5=-845;P6=850;D=141515621515621515626262626215156262156215626215156262621515151515156262151515621562151562626262626262156262626262626262621562626262101212121212121212121212;CP=1;SP=4;R=34;O;m1; - ## remote enjoy motors HS-8, HS-1 / RIO HS-8 | three buttons - # Modulation = GFSK | Frequenz = 868.302 MHz | Bandwidth = 58.036 kHz | Deviation = 25.391 kHz | Datarate = 24.796 kHz - # https://forum.fhem.de/index.php/topic,107239.0.html | https://github.com/fhem/SD_Keeloq/issues/19 - # P88#31EB8B8A008B48058 | button=up MS;P1=399;P2=-421;P3=-4034;P4=800;P5=-815;P6=-15516;D=1342421515424242151515154215421515154242421542151515424242154215424242424242424242154242421542151542154242154242424242424242154215161212121212121212121212;CP=1;SP=3;R=86;O;m2; - # P88#54F58AA3008B48038 | button=down MS;P1=415;P2=-400;P3=-4034;P4=810;P5=-803;P6=-15468;D=1342154215421542421515151542154215154242421542154215421542424215154242424242424242154242421542151542154242154242424242424242421515161212121212121212121212;CP=1;SP=3;R=84;O;m2; - # P88#CBDA84D2008B48018 | button=stop MS;P1=417;P2=-400;P3=-4032;P4=-789;P5=811;P6=-15540;D=1314145252145214141414521414521452145252525214525214145214525214525252525252525252145252521452141452145252145252525252525252525214161212121212121212121212;CP=1;SP=3;R=86;O;m2; - ## KeeLoq is a registered trademark of Microchip Technology Inc. - { - name => 'HCS300/HCS301', - comment => 'remote controls Aurel TX-nM-HCS, enjoy motors HS, Rademacher RP-S1-HS-RF11, SCS Sentinel PR3-4207-002, Waeco MA650_TX', - id => '88', - knownFreqs => '433.92 | 868.35', - one => [1,-2], # PWM bit pulse width typ. 1.2 mS - zero => [2,-1], # PWM bit pulse width typ. 1.2 mS - preSync => [1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,], # 11 pulses preambel, 1 sync, 66 data, pause ... repeat - sync => [1,-10], # Header duration typ. 4 mS - pause => [-39], # Guard Time typ. 15.6 mS - clockabs => 400, # Basic pulse element typ. 0.4 mS (Timings from table CODE WORD TRANSMISSION TIMING REQUIREMENTS in PDF) - reconstructBit => '1', - format => 'twostate', - preamble => 'P88#', - clientmodule => 'SD_Keeloq', - length_min => '65', - length_max => '78', - }, - "89" => ## Funk Wetterstation TFA 35.1140.01 mit Temperatur-/Feuchtesensor TFA 30.3221.02 12/2018 @Iron-R - # ! some message are decode as protocol 37 and 61 ! - # https://github.com/RFD-FHEM/RFFHEM/issues/266 - # Ch:3 T: 5.5 H: 58 Bat:low MU;P0=-900;P1=390;P2=-499;P3=-288;P4=193;P7=772;D=1213424213131342134242424213134242137070707013424213134242131342134242421342424213421342131342421313134213424242421313424213707070701342421313424213134213424242134242421342134213134242131313421342424242131342421;CP=4;R=43; - # Ch:3 T: 5.4 H: 58 Bat:low MU;P0=-491;P1=382;P2=-270;P3=179;P4=112;P5=778;P6=-878;D=01212304012123012303030123030301230123012303030121212301230301230121212121256565656123030121230301212301230303012303030123012301230303012121230123030123012121212125656565612303012123030121230123030301230303012301230123030301212123012303012301212121212565;CP=3;R=43;O; - # Ch:3 T: 5 H: 60 Bat:low MU;P0=-299;P1=384;P2=169;P3=-513;P5=761;P6=-915;D=01023232310101010101023565656561023231010232310102310232323102323231023231010232323101010102323231010101010102356565656102323101023231010231023232310232323102323101023232310101010232323101010101010235656565610232310102323101023102323231023232310232310102;CP=2;R=43;O; - # Ch:2 T: 6.5 H: 62 Bat:ok MU;P0=-32001;P1=412;P2=-289;P3=173;P4=-529;P5=777;P6=-899;D=01234345656541212341234123434121212121234123412343412343456565656121212123434343434343412343412343434121234123412343412121212123412341234341234345656565612121212343434343434341234341234343412123412341234341212121212341234123434123434565656561212121234343;CP=3;R=22;O; - # Ch:2 T: 6.3 H: 62 Bat:ok MU;P0=22960;P1=-893;P2=775;P3=409;P4=-296;P5=182;P6=-513;D=01212121343434345656565656565634565634565656343456563434565634343434345656565656565656342121212134343434565656565656563456563456565634345656343456563434343434565656565656565634212121213434343456565656565656345656345656563434565634345656343434343456565656;CP=5;R=22;O; - # Ch:2 T: 6.1 H: 66 Bat:ok MU;P0=172;P1=-533;P2=401;P3=-296;P5=773;P6=-895;D=01230101230101012323010101230123010101010101230101230101012323010101230123010301230101010101012301012301010123230101012301230101010123010101010101012301565656562323232301010101010101230101230101012323010101230123010101012301010101010101230156565656232323;CP=0;R=23;O; - { - name => 'TFA 30.3221.02', - comment => 'temperature / humidity sensor for weatherstation TFA 35.1140.01', - id => '89', - knownFreqs => '433.92', - one => [2,-1], - zero => [1,-2], - start => [3,-3,3,-3,3,-3], - clockabs => 250, - format => 'twostate', - preamble => 'W89#', - postamble => '', - clientmodule => 'SD_WS', - length_min => '40', - length_max => '40', - }, - "90" => ## mumbi AFS300-s / manax MX-RCS250 (CP 258-298) - # https://forum.fhem.de/index.php/topic,94327.15.html @my-engel @peterboeckmann - # A AN MS;P0=-9964;P1=273;P4=-866;P5=792;P6=-343;D=10145614141414565656561414561456561414141456565656561456141414145614;CP=1;SP=0;R=35;O;m2; - # A AUS MS;P0=300;P1=-330;P2=-10160;P3=804;P7=-840;D=02073107070707313131310707310731310707070731313107310731070707070707;CP=0;SP=2;R=23;O;m1; - # B AN MS;P1=260;P2=-873;P3=788;P4=-351;P6=-10157;D=16123412121212343434341212341234341212121234341234341234121212341212;CP=1;SP=6;R=21;O;m2; - # B AUS MS;P1=268;P3=793;P4=-337;P6=-871;P7=-10159;D=17163416161616343434341616341634341616161634341616341634161616343416;CP=1;SP=7;R=24;O;m2; - { - name => 'mumbi | MANAX', - comment => 'remote control mumbi RC-10, MANAX MX-RCS250', - id => '90', - knownFreqs => '433.92', - one => [3,-1], - zero => [1,-3], - sync => [1,-36], - clockabs => 280, # -1=auto - format => 'twostate', - preamble => 'P90#', - length_min => '33', - length_max => '36', - clientmodule => 'SD_UT', - modulematch => '^P90#.*', - }, - "91" => ## Atlantic Security / Focus Security China Devices - # https://forum.fhem.de/index.php/topic,58397.msg876862.html#msg876862 @Harst @jochen_f - # normal MU;P0=800;P1=-813;P2=394;P3=-410;P4=-3992;D=0123030303030303012121230301212304230301212301230301212123012301212303012301230303030303030121212303012123042303012123012303012121230123012123030123012303030303030301212123030121230;CP=2;R=46; - # normal MU;P0=406;P1=-402;P2=802;P3=-805;P4=-3994;D=012123012301212121212121230303012123030124012123030123012123030301230123030121230123012121212121212303030121230301240121230301230121230303012301230301212301230121212121212123030301212303012;CP=0;R=52; - # warning MU;P0=14292;P1=-10684;P2=398;P3=-803;P4=-406;P5=806;P6=-4001;D=01232324532453232454532453245454532324545323232453245324562454532324532454532323245324532324545324532454545323245453232324532453245624545323245324545323232453245323245453245324545453232454532323245324532456245453232453245453232324532453232454532453245454;CP=2;R=50;O; - { - name => 'Atlantic security', - comment => 'example sensor MD-210R | MD-2018R | MD-2003R (MU decode)', - id => '91', - knownFreqs => '433.92 | 868.35', - one => [-2,1], - zero => [-1,2], - start => [-10,1], - clockabs => 400, - format => 'twostate', # - preamble => 'P91#', # prepend to converted message - length_min => '36', - length_max => '36', - clientmodule => 'SD_UT', - #modulematch => '^P91#.*', - reconstructBit => '1', - }, - "91.1" => ## Atlantic Security / Focus Security China Devices - # https://forum.fhem.de/index.php/topic,58397.msg878008.html#msg878008 @Harst @jochen_f - # warning MS;P0=-399;P1=407;P2=820;P3=-816;P4=-4017;D=14131020231020202313131023131313131023102023131313131310202313131020202313;CP=1;SP=4;O;m0; - # warning MS;P1=392;P2=-824;P3=-416;P4=804;P5=-4034;D=15121343421343434212121342121212121342134342121212121213434212121343434212;CP=1;SP=5;e;m2; - { - name => 'Atlantic security', - comment => 'example sensor MD-210R | MD-2018R | MD-2003R (MS decode)', - id => '91.1', - knownFreqs => '433.92 | 868.35', - one => [-2,1], - zero => [-1,2], - sync => [-10,1], - clockabs => 400, - reconstructBit => '1', - format => 'twostate', # - preamble => 'P91#', # prepend to converted message - length_min => '32', - length_max => '36', - clientmodule => 'SD_UT', - #modulematch => '^P91.1#.*', - }, - "92" => ## KRINNER Lumix - LED X-MAS - # https://github.com/RFD-FHEM/RFFHEM/issues/452 | https://forum.fhem.de/index.php/topic,94873.msg876477.html?PHPSESSID=khp4ja64pcqa5gsf6gb63l1es5#msg876477 @gestein - # on MU;P0=24188;P1=-16308;P2=993;P3=-402;P4=416;P5=-967;P6=-10162;D=0123234545454523234523234545454545454545232623452345454545454523234523234545454523234523234545454545454545232623452345454545454523234523234545454523234523234545454545454545232623452345454545454523234523234545454523234523234545454545454545232;CP=4;R=25; - # off MU;P0=11076;P1=-20524;P2=281;P3=-980;P4=982;P5=-411;P6=408;P7=-10156;D=0123232345456345456363636363636363634745634563636363636345456345456363636345456345456363636363636363634745634563636363636345456345456363636345456345456363636363636363634745634563636363636345456345456363636345456345456363636363636363634;CP=6;R=38; - { - name => 'KRINNER Lumix', - comment => 'remote control LED X-MAS', - id => '92', - knownFreqs => '433.92', - zero => [1,-2], - one => [2,-1], - start => [2,-24], - clockabs => 420, - format => 'twostate', # - preamble => 'P92#', # prepend to converted message - length_min => '32', - length_max => '32', - clientmodule => 'SD_UT', - #modulematch => '^P92#.*', - }, - "93" => ## ESTO Lighting GmbH | remote control KL-RF01 with 9 buttons (CP 375-395) - # https://github.com/RFD-FHEM/RFFHEM/issues/449 @daniel89fhem - # light_color_cold_white MS;P1=376;P4=-1200;P5=1170;P6=-409;P7=-12224;D=17141414561456561456565656145656141414145614141414565656145656565614;CP=1;SP=7;R=231;e;m0; - # dimup MS;P1=393;P2=-1174;P4=1180;P5=-401;P6=-12222;D=16121212451245451245454545124545124545451212121212121212454545454512;CP=1;SP=6;R=243;e;m0; - # dimdown MS;P0=397;P1=-385;P2=-1178;P3=1191;P4=-12230;D=04020202310231310231313131023131023131020202020202020231313131313102;CP=0;SP=4;R=250;e;m0; - { - name => 'ESTO Lighting GmbH', - comment => 'remote control KL-RF01', - id => '93', - knownFreqs => '433.92', - one => [3,-1], - zero => [1,-3], - sync => [1,-32], - clockabs => 385, # -1=auto - format => 'twostate', - preamble => 'P93#', - length_min => '32', # 2. MSG: 32 Bit, bleibt so - length_max => '36', # 1. MSG: 33 Bit, wird verlängert auf 36 Bit - clientmodule => 'SD_UT', - #modulematch => '^P93#.*', - }, - "94" => # Atech wireless weather station (vermutlicher Name: WS-308) - # https://github.com/RFD-FHEM/RFFHEM/issues/547 @Kreidler1221 2019-03-15 - # Sensor sends Bit 0 as "0", Bit 1 as "110" - # Id:0C T:-14.6 MU;P0=-32001;P1=1525;P2=-303;P3=-7612;P4=-2008;D=01212121212121213141414141212141212141414141412121414141414121214141212141414141212141212141412121412121414121214121;CP=1; - # Id:0C T:-0.4 MU;P0=-32001;P1=1533;P2=-297;P3=-7612;P4=-2005;D=0121212121212121314141414121214121214141414141212141414141414141414141412121414141212141412121414121;CP=1; - # Id:0C T:0.2 MU;P0=-32001;P1=1532;P2=-299;P3=-7608;P4=-2005;D=0121212121212121314141414121214121214141414141414141414141414141414141212141412121412121412121414121;CP=1; - # Id:0C T:10.2 MU;P0=-31292;P1=1529;P2=-300;P3=-7610;P4=-2009;D=012121212121212131414141412121412121414141414141414141412121414141414141412121414121214121214121214121214121012121212121212131414141412121412121414141414141414141412121414141414141412121414121214121214121214121214121;CP=1; - # Id:0C T:27 MU;P0=-31290;P1=1533;P2=-297;P3=-7608;P4=-2006;D=012121212121212131414141412121412121414141414141414141212141414121214121214121214141414141212141414121214121012121212121212131414141412121412121414141414141414141212141414121214121214121214141414141212141414121214121;CP=1; - { - name => 'Atech', - comment => 'Temperature sensor', - id => '94', - knownFreqs => '433.92', - one => [5.3,-1], # 1537, 290 - zero => [5.3,-6.9], # 1537, 2001 - start => [5.3,-26.1], # 1537, 7569 - clockabs => 290, - reconstructBit => '1', - format => 'twostate', - preamble => 'W94#', - clientmodule => 'SD_WS', - length_min => '24', # minimal 24*0=24 Bit, kuerzeste bekannte aus Userlog: 36 - length_max => '96', # maximal 24*110=96 Bit, laengste bekannte aus Userlog: 60 - }, - "95" => # Techmar / Garden Lights Fernbedienung, 6148011 Remote control + 12V Outdoor receiver - # https://github.com/RFD-FHEM/RFFHEM/issues/558 @BlackcatSandy - # Group_1_on MU;P0=-972;P1=526;P2=-335;P3=-666;D=01213131312131313121212121312121313131313121312131313121313131312121212121312121313131313121313121212101213131312131313121212121312121313131313121312131313121313131312121212121312121313131313121313121212101213131312131313121212121312121313131313121312131;CP=1;R=44;O; - # Group_5_on MU;P0=-651;P1=530;P2=-345;P3=-969;D=01212121312101010121010101212121210121210101010101210121010101210101010121212121012121210101010121010101212101312101010121010101212121210121210101010101210121010101210101010121212121012121210101010121010101212121312101010121010101212121210121210101010101;CP=1;R=24;O; - # Group_8_off MU;P0=538;P1=-329;P2=-653;P3=-964;D=01020301020202010202020101010102010102020202020102010202020102020202010101010101010201020202020202010202010301020202010202020101010102010102020202020102010202020102020202010101010101010201020202020202010201010301020202010202020101010102010102020202020102;CP=0;R=19;O; - { - name => 'Techmar', - comment => 'Garden Lights remote control', - id => '95', - knownFreqs => '433.92', - one => [5,-6], # 550,-660 - zero => [5,-3], # 550,-330 - start => [5,-9], # 550,-990 - clockabs => 110, - format => 'twostate', - preamble => 'P95#', - clientmodule => 'SD_UT', - length_min => '50', - length_max => '50', - }, - "96" => # Funk-Gong | Taster Grothe Mistral SE 03.1 / 01.1, Innenteil Grothe Mistral 200M(E) - # https://forum.fhem.de/index.php/topic,64251.msg940593.html?PHPSESSID=nufcvvjobdd8r7rgr0cq3qkrv0#msg940593 @coolheizer - # SD_BELL_104762 Alarm MC;LL=-430;LH=418;SL=-216;SH=226;D=23C823B1401F8;C=214;L=49;R=53; - # SD_BELL_104762 ring MC;LL=-439;LH=419;SL=-221;SH=212;D=238823B1001F8;C=215;L=49;R=69; - # SD_BELL_104762 ring low bat MC;LL=-433;LH=424;SL=-214;SH=210;D=238823B100248;C=213;L=49;R=65; - # SD_BELL_0253B3 Alarm MC;LL=-407;LH=451;SL=-195;SH=239;D=23C129D9E78;C=215;L=41;R=241; - # SD_BELL_0253B3 ring MC;LL=-412;LH=458;SL=-187;SH=240;D=238129D9A78;C=216;L=41;R=241; - # SD_BELL_024DB5 Alarm MC;LL=-415;LH=454;SL=-200;SH=226;D=23C126DAE58;C=215;L=41;R=246; - # SD_BELL_024DB5 ring MC;LL=-409;LH=448;SL=-172;SH=262;D=238126DAA58;C=215;L=41;R=238; - { - name => 'Grothe Mistral SE', - comment => 'Wireless doorbell Grothe Mistral SE 01.1 or 03.1', - id => '96', - knownFreqs => '868.35', - clockrange => [170,260], - format => 'manchester', - clientmodule => 'SD_BELL', - modulematch => '^P96#', - preamble => 'P96#', - length_min => '40', - length_max => '49', - method => \&main::SIGNALduino_GROTHE, - }, - "97" => # Momento, remote control for wireless digital picture frame - elektron-bbs 2020-03-21 - # Short press repeatedly message 3 times, long press repeatedly until release. - # When sending, the original message is not reproduced, but the recipient also reacts to the messages generated in this way. - # Momento_0000064 play/pause MU;P0=-294;P1=237;P2=5829;P3=-3887;P4=1001;P5=-523;P6=504;P7=-995;D=01010101010101010101010234545454545454545454545454545454545454545456767454567454545456745456745456745454523454545454545454545454545454545454545454545676745456745454545674545674545674545452345454545454545454545454545454545454545454567674545674545454567454;CP=4;R=45;O; - # Momento_0000064 power MU;P0=-998;P1=-273;P2=256;P3=5830;P4=-3906;P5=991;P6=-527;P7=508;D=12121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121345656565656565656565656565656565656565656567070565670565656565670567056565670707034565656565656565656565656565656565656565656707056567;CP=2;R=40;O; - # Momento_0000064 up MU;P0=-1005;P1=-272;P2=258;P3=5856;P4=-3902;P5=1001;P6=-520;P7=508;D=0121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121213456565656565656565656565656565656565656565670705656705656567056565670565670567056345656565656565656565656565656565656565656567070565;CP=2;R=63;O; - { - name => 'Momento', - comment => 'Remote control for wireless digital picture frame', - id => '97', - knownFreqs => '433.92', - one => [2,-4], # 500, -1000 - zero => [4,-2], # 1000, -500 - start => [23,-15], # 5750, -3750 - clockabs => 250, - format => 'twostate', - preamble => 'P97#', - clientmodule => 'SD_UT', - length_min => '40', - length_max => '40', - }, - "98" => # Funk-Tuer-Gong: Modell GEA-028DB, Ningbo Rui Xiang Electrical Co.,Ltd., Vertrieb durch Walter Werkzeuge Salzburg GmbH, Art. Nr. K612021A - # https://forum.fhem.de/index.php/topic,109952.0.html 2020-04-12 - # SD_BELL_6A2C MU;P0=1488;P1=-585;P2=520;P3=-1509;P4=1949;P5=-5468;CP=2;R=38;D=01232301230123010101230123230101454501232301230123010101230123230101454501232301230123010101230123230101454501232301230123010101230123230101454501232301230123010101230123230101454501232301230123010101230123230101454501232301230123010101230123230101454501;O; - # SD_BELL_6A2C MU;P0=-296;P1=-1542;P2=1428;P3=-665;P4=483;P5=1927;P6=-5495;P7=92;CP=4;R=31;D=1234141232356562341412341234123232341234141232356562341412341234123232341234141232356562341412341234123232341234141232356562341412341234123232341234141232356562341412341234123232341234141232356562341412341234123232341234141232370;e;i; - { - name => 'GEA-028DB', - comment => 'Wireless doorbell', - knownFreqs => '433.92', - id => '98', - one => [1,-3], - zero => [3,-1], - start => [4,-11,4,-11], - clockabs => 500, - format => 'twostate', - clientmodule => 'SD_BELL', - modulematch => '^P98#', - preamble => 'P98#', - length_min => '16', - length_max => '16', - }, - "99" => # NAVARIS touch light switch Model No.: 44344.04 - # https://github.com/RFD-FHEM/RFFHEM/issues/828 - # Navaris_211073 MU;P0=-302;P1=180;P2=294;P3=-208;P4=419;P5=-423;D=01023101010101023232310102323451010231010101023101010231010101010232323101023234510102310101010231010102310101010102323231010232345101023101010102310101023101010101023232310102323451010231010101023101010231010101010232323101023234510102310101010231010102;CP=1;R=36;O; - # Navaris_13F8E3 MU;P0=406;P1=-294;P2=176;P3=286;P4=-191;P6=-415;D=01212134212134343434343434212121343434212121343406212121342121343434343434342121213434342121213434062121213421213434343434343421212134343421212134340621212134212134343434343434212121343434212121343406212121342121343434343434342121213434342121213434062121;CP=2;R=67;O; - { - name => 'Navaris 44344.04', - comment => 'Wireless touch light switch', - knownFreqs => '433.92', - id => '99', - one => [3,-2], - zero => [2,-3], - start => [4,-4], - clockabs => 100, - format => 'twostate', - clientmodule => 'SD_UT', - modulematch => '^P99#', - preamble => 'P99#', - length_min => '24', - length_max => '24', - }, - "104" => # Remote control TR60C-1 with touch screen from Satellite Electronic (Zhongshan) Ltd., Importer Westinghouse Lighting for ceiling fan Bendan - # https://forum.fhem.de/index.php?topic=53282.msg1045428#msg1045428 phoenix-anasazi 2020-04-21 - # TR60C1_0 light_off_fan_off MU;P0=18280;P1=-737;P2=419;P3=-331;P4=799;P5=-9574;P6=-7080;D=012121234343434341212121212121252121212123434343434121212121212125212121212343434343412121212121212521212121234343434341212121212121252121212123434343434121212121212126;CP=2;R=2; - # TR60C1_9 light_off_fan_4 MU;P0=14896;P1=-751;P2=394;P3=-370;P4=768;P5=-9572;P6=-21472;D=0121234123434343412121212121212523412123412343434341212121212121252341212341234343434121212121212125234121234123434343412121212121212523412123412343434341212121212121252341212341234343434121212121212126;CP=2;R=4; - # TR60C1_B light_on_fan_2 MU;P0=-96;P1=152;P2=-753;P3=389;P4=-374;P5=769;P6=-9566;P7=-19920;D=012345454523232345454545634523454523234545452323234545454563452345452323454545232323454545456345234545232345454523232345454545634523454523234545452323234545454563452345452323454545232323454545457;CP=3;R=1; - # https://github.com/RFD-FHEM/RFFHEM/issues/842 - { - name => 'TR60C-1', - comment => 'Remote control for example Westinghouse Bendan 77841B', - id => '104', - knownFreqs => '433.92', - one => [-1,2], # -380,760 - zero => [-2,1], # -760,380 - start => [-25,1], # -9500,380 - clockabs => 380, - format => 'twostate', - clientmodule => 'SD_UT', - modulematch => '^P104#', - preamble => 'P104#', - length_min => '16', - length_max => '16', - }, - "105" => # Remote control BF-301 from Shenzhen BOFU Mechanic & Electronic Co., Ltd. - # Protocol description found on https://github.com/akirjavainen/markisol/blob/master/Markisol.ino - # original remotes repeat 8 (multi) or 10 (single) times by default - # https://github.com/RFD-FHEM/RFFHEM/issues/861 stsirakidis 2020-06-27 - # BF_301_FAD0 down MU;P0=-697;P1=5629;P2=291;P3=3952;P4=-2459;P5=1644;P6=-298;P7=689;D=34567676767676207620767620762020202076202020762020207620202020207676762076202020767614567676767676207620767620762020202076202020762020207620202020207676762076202020767614567676767676207620767620762020202076202020762020207620202020207676762076202020767614;CP=2;R=41;O; - # BF_301_FAD0 stop MU;P0=5630;P1=3968;P2=-2458;P3=1642;P4=-285;P5=690;P6=282;P7=-704;D=12345454545454675467545467546767676754676767546754675467676767675454546754676767675402345454545454675467545467546767676754676767546754675467676767675454546754676767675402345454545454675467545467546767676754676767546754675467676767675454546754676767675402;CP=6;R=47;O; - # BF_301_FAD0 up MU;P0=-500;P1=5553;P2=-2462;P3=1644;P4=-299;P5=679;P6=298;P7=-687;D=01234545454545467546754546754676767675467676767675454546767676767545454675467546767671234545454545467546754546754676767675467676767675454546767676767545454675467546767671234545454545467546754546754676767675467676767675454546767676767545454675467546767671;CP=6;R=48;O; - { - name => 'BF-301', - comment => 'Remote control', - id => '105', - knownFreqs => '433.92', - one => [2,-1], # 660,-330 - zero => [1,-2], # 330,-660 - start => [17,-7,5,-1], # 5610,-2310,1650,-330 - clockabs => 330, - format => 'twostate', - clientmodule => 'SD_UT', - modulematch => '^P105#', - preamble => 'P105#', - length_min => '40', - length_max => '40', - }, - ######################################################################## - #### ### old information from incomplete implemented protocols #### #### +{ + use strict; + use warnings; - # "" => ## Livolo - # https://github.com/RFD-FHEM/RFFHEM/issues/29 - # MU;P0=-195;P1=151;P2=475;P3=-333;D=0101010101 02 01010101010101310101310101010101310101 02 01010101010101010101010101010101010101 02 01010101010101010101010101010101010101 02 010101010101013101013101;CP=1; - # - # protocol sends 24 to 47 pulses per message. - # First pulse is the header and is 595 μs long. All subsequent pulses are either 170 μs (short pulse) or 340 μs (long pulse) long. - # Two subsequent short pulses correspond to bit 0, one long pulse corresponds to bit 1. There is no footer. The message is repeated for about 1 second. - # - # Start bit: | |___| bit 0: | |___| bit 1: | |___| - # { - # name => 'Livolo', - # comment => 'remote control / dimmmer / switch ...', - # id => '', - # knownFreqs => '', - # one => [3], - # zero => [1], - # start => [5], - # clockabs => 110, #can be 90-140 - # format => 'twostate', - # preamble => 'uXX#', # prepend to converted message - # #clientmodule => '', - # #modulematch => '', - # length_min => '16', - # #length_max => '', # missing - # filterfunc => 'SIGNALduino_filterSign', - # }, + our $VERSION = '1.42'; - ######################################################################## + our %protocols = ( + "0" => ## various weather sensors (500 | 9100) + # Mebus | Id:237 Ch:1 T: 1.9 Bat:low MS;P0=-9298;P1=495;P2=-1980;P3=-4239;D=1012121312131313121313121312121212121212131212131312131212;CP=1;SP=0;R=223;O;m2; + # GT_WT_02 | Id:163 Ch:1 T: 2.9 H: 86 Bat:ok MS;P0=531;P1=-9027;P3=-4126;P4=-2078;D=0103040304040403030404040404040404040404030303040303040304030304030304040403;CP=0;SP=1;R=249;O;m2; + # Prologue | Id:145 Ch:0 T: 2.6, Bat:ok MS;P0=-4152;P1=643;P2=-2068;P3=-9066;D=1310121210121212101210101212121212121212121212121010121012121212121012101212;CP=1;SP=3;R=220;O;m2; + # Prologue | Id:145 Ch:0 T: 2.7, Bat:ok MS;P0=-4149;P2=-9098;P3=628;P4=-2076;D=3230343430343434303430303434343434343434343434343030343030343434343034303434;CP=3;SP=2;R=218;O;m2; + { + name => 'weather (v1)', + comment => 'temperature / humidity or other sensors', + id => '0', + knownFreqs => '433.92', + one => [1,-7], + zero => [1,-3], + sync => [1,-16], + clockabs => -1, + format => 'twostate', # not used now + preamble => 's', + postamble => '00', + clientmodule => 'CUL_TCM97001', + #modulematch => '^s[A-Fa-f0-9]+', + length_min => '24', + length_max => '40', + paddingbits => '8', # pad up to 8 bits, default is 4 + }, + "0.1" => ## other Sensors (380 | 9650) + # Mebus | Id:237 Ch:1 T: 1.3 Bat:low MS;P1=416;P2=-9618;P3=-4610;P4=-2036;D=1213141313131313141313141314141414141414141313141314131414;CP=1;SP=2;R=220;O;m0; + # Mebus | Id:151 Ch:1 T: 1.2 Bat:low MS;P0=-9690;P3=354;P4=-4662;P5=-2107;D=3034343434343535343534343435353535353535353434353535343535;CP=3;SP=0;R=209;O;m2; + # https://github.com/RFD-FHEM/RFFHEM/issues/63 @localhosthack0r + # AURIOL | Id:255 T: 0.0 Bat:ok | LIDL Wetterstation MS;P1=367;P2=-2077;P4=-9415;P5=-4014;D=141515151515151515121512121212121212121212121212121212121212121212;CP=1;SP=4;O; + { + name => 'weather (v2)', + comment => 'temperature / humidity or other sensors', + id => '0.1', + knownFreqs => '433.92', + one => [1,-12], + zero => [1,-6], + sync => [1,-26], + clockabs => -1, + format => 'twostate', # not used now + preamble => 's', + postamble => '00', + clientmodule => 'CUL_TCM97001', + #modulematch => '^s[A-Fa-f0-9]+', + length_min => '24', + length_max => '32', + paddingbits => '8', + }, + "0.2" => ## other Sensors | for sensors how tol is runaway (260+tol | 9650) + # Mebus | Id:151 Ch:1 T: 0.4 Bat:low MS;P1=-2140;P2=309;P3=-4690;P4=-9695;D=2421232323232121232123232321212121212121212123212121232121;CP=2;SP=4;R=211;m1; + # Mebus | Id:151 Ch:1 T: 0.3 Bat:low MS;P0=-9703;P1=304;P2=-2133;P3=-4689;D=1012131312131212131213131312121212121212121212131312131212;CP=1;SP=0;R=208; + { + name => 'weather (v3)', + comment => 'temperature / humidity or other sensors', + id => '0.2', + knownFreqs => '433.92', + one => [1,-18], + zero => [1,-9], + sync => [1,-37], + clockabs => -1, + format => 'twostate', # not used now + preamble => 's', + postamble => '00', + clientmodule => 'CUL_TCM97001', + #modulematch => '^s[A-Fa-f0-9]+', + length_min => '24', + length_max => '32', + paddingbits => '8', + }, + "0.3" => ## Pollin PFR-130 + # CUL_TCM97001_Unknown MS;P0=-3890;P1=386;P2=-2191;P3=-8184;D=1312121212121012121212121012121212101012101010121012121210121210101210101012;CP=1;SP=3;R=20;O; + # CUL_TCM97001_Unknown MS;P0=-2189;P1=371;P2=-3901;P3=-8158;D=1310101010101210101010101210101010121210121212101210101012101012121012121210;CP=1;SP=3;R=20;O; + # Ventus W174 | Id:17 R: 103.25 Bat:ok MS;P3=-2009;P4=479;P5=-9066;P6=-4047;D=45434343464343434643464643464643434643464646434346464343434343434346464643;CP=4;SP=5;R=55;O;m2; + { + name => 'weather (v4)', + comment => 'temperature / humidity or other sensors | Pollin PFR-130, Ventus W174 ...', + id => '0.3', + knownFreqs => '433.92', + one => [1,-10], + zero => [1,-5], + sync => [1,-21], + clockabs => -1, + preamble => 's', + postamble => '00', + clientmodule => 'CUL_TCM97001', + length_min => '36', + length_max => '42', + paddingbits => '8', # pad up to 8 bits, default is 4 + }, + "0.4" => ## Auriol Z31092 (450 | 9200) + # AURIOL | Id:95 T: 6.1 Bat:low MS;P0=443;P3=-9169;P4=-1993;P5=-3954;D=030405040505050505050404040404040404040505050504050405050504040405;CP=0;SP=3;R=14;O;m0; + # AURIOL | Id:190 T: 2.8 Bat:low MS;P0=-9102;P1=446;P2=-3956;P3=-2008;D=10121312121212121312131213131313131313131212121313121213121213121314;CP=1;SP=0;R=212;O;m2; + { + name => 'weather (v5)', + comment => 'temperature / humidity or other sensors | Auriol Z31092', + id => '0.4', + knownFreqs => '433.92', + one => [1,-9], + zero => [1,-4], + sync => [1,-20], + clockabs => 450, + preamble => 's', + postamble => '00', + clientmodule => 'CUL_TCM97001', + length_min => '32', + length_max => '36', + paddingbits => '8', # pad up to 8 bits, default is 4 + }, + "0.5" => ## various weather sensors (475 | 8000) + # ABS700 | Id:79 T: 3.3 Bat:low MS;P1=-7949;P2=492;P3=-1978;P4=-3970;D=21232423232424242423232323232324242423232323232424;CP=2;SP=1;R=245;O; + # ABS700 | Id:69 T: 9.3 Bat:low MS;P1=-7948;P2=471;P3=-1997;P4=-3964;D=21232423232324232423232323242323242423232323232424;CP=2;SP=1;R=246;O;m2; + { + name => 'weather (v6)', + comment => 'temperature / humidity or other sensors | ABS700', + id => '0.5', + knownFreqs => '433.92', + one => [1,-8], + zero => [1,-4], + sync => [1,-16], + clockabs => 475, + format => 'twostate', # not used now + preamble => 's', + postamble => '00', + clientmodule => 'CUL_TCM97001', + #modulematch => '^s[A-Fa-f0-9]+', + length_min => '24', + length_max => '24', + paddingbits => '8', # pad up to 8 bits, default is 4 + }, + "1" => ## Conrad RSL + # on MS;P1=1154;P2=-697;P3=559;P4=-1303;P5=-7173;D=351234341234341212341212123412343412341234341234343434343434343434;CP=3;SP=5;R=247;O; + # on MS;P0=561;P1=-1291;P2=-7158;P3=1174;P4=-688;D=023401013401013434013434340134010134013401013401010101010101010101;CP=0;SP=2;R=248;m1; + { + name => 'Conrad RSL v1', + comment => 'remotes and switches', + id => '1', + knownFreqs => '', + one => [2,-1], + zero => [1,-2], + sync => [1,-12], + clockabs => '560', + format => 'twostate', # not used now + preamble => 'P1#', + postamble => '', + clientmodule => 'SD_RSL', + modulematch => '^P1#[A-Fa-f0-9]{8}', + length_min => '20', # 23 | userMSG 32 ? + length_max => '40', # 24 | userMSG 32 ? + }, + "2" => ## Self build arduino sensor + # ArduinoSensor_temp_2 T: 21.0 MS;P1=-463;P2=468;P3=-1043;P5=-9981;D=252121212121232321232321212121232123232123212123212321212121212121232321212123212324;CP=2;SP=5;R=16;O;m2; + # ArduinoSensor_humidity_2 H: 61.9 MS;P0=-491;P2=523;P4=-991;P7=-9972;D=272020202024202024242420202020242020242420242024242420202020202420202424242420242426;CP=2;SP=7;m2; + # ArduinoSensor_voltage_2 V: 3.65 MS;P0=-10406;P1=513;P2=-437;P4=-1013;D=10121212121412121214141212121214121212141414141214121212121414141212141214141214121;CP=1;SP=0; + { + name => 'Arduino', + comment => 'self build arduino sensor (developModule. SD_AS module only in github)', + developId => 'm', + id => '2', + knownFreqs => '', + one => [1,-2], + zero => [1,-1], + sync => [1,-20], + clockabs => '500', + format => 'twostate', + preamble => 'P2#', + clientmodule => 'SD_AS', + modulematch => '^P2#.{8,10}', + length_min => '32', # without CRC + length_max => '40', # with CRC + }, + "3" => ## itv1 - remote with IC PT2262 example: ELRO | REWE | Intertek Modell 1946518 | WOFI Lamp // PIR JCHENG with Wireless Coding EV1527 + ## (real CP=300 | repeatpause=9300) + # REWE Model: 0175926R -> on | v1 MS;P1=-905;P2=896;P3=-317;P4=303;P5=-9299;D=45412341414123412341414123412341234141412341414123;CP=4;SP=5;R=91;A;#; + ## (real CP=330 | repeatpause=10100) + # ELRO AB440R -> on | v1 MS;P1=-991;P2=953;P3=-356;P4=303;P5=-10033;D=45412341234141414141234123412341234141412341414123;CP=4;SP=5;R=93;m1;A;A; + ## (real CP=300 | repeatpause=9400) + # Kangtai Model Nr.: 6899 -> on | v1 MS;P0=-328;P1=263;P2=-954;P3=888;P5=-9430;D=15123012121230123012121230123012301212123012121230;CP=1;SP=5;R=35;m2;0;0; + # door/window switch from CHN (PT2262 compatible) from amazon & ebay | itswitch_CHN model + # open MS;P1=-478;P2=1360;P3=468;P4=-1366;P5=-14045;D=35212134212134343421212134213434343434343421342134;CP=3;SP=5;R=30;O;m2;4; + # close MS;P1=-474;P2=1373;P3=455;P4=-1367;P5=-14044;D=35212134212134343421212134213434343434343421212134;CP=3;SP=5;R=37;O;m2; + ## JCHENG SECURITY Wireless PIR + # (only autocreate -> J2 Data setting D0 open | D1 closed | D2 closed | D3 open) + # on MS;P1=-12541;P2=1227;P3=-405;P4=407;P5=-1209;D=41232323232345452323454523452323234545234545232345;CP=4;SP=1;R=35;O;m2;E; + ## benon (Semexo OHG) | remote BH-P with 5 Channels, switch B2112 | Amazon + ## (real CP=160) chip HS2260C-R4 | length 24 + # on MS;P0=160;P4=-542;P5=515;P6=-174;P7=-5406;D=07040404560404045604560456045604560404565604045656;CP=0;SP=7;R=24;O;m2; + # off MS;P1=-538;P2=163;P3=518;P4=-175;P5=-5396;D=25212121342121213421342134213421342121343434342121;CP=2;SP=5;R=31;O;m2;4; + { + name => 'chip xx2260 / xx2262', + comment => 'remote for benon|ELRO|Kangtai|Intertek|REWE|WOFI / PIR JCHENG', + id => '3', + knownFreqs => '433.92', + one => [3,-1], + zero => [1,-3], + #float => [-1,3], # not full supported now later use + sync => [1,-31], + clockabs => -1, + format => 'twostate', # not used now + preamble => 'i', + clientmodule => 'IT', + modulematch => '^i......', + length_min => '24', + length_max => '24', # Don't know maximal lenth of a valid message + }, + "3.1" => ## itv1_sync40 | Intertek Modell 1946518 | ELRO + # no decode! MS;P0=-11440;P1=-1121;P2=-416;P5=309;P6=1017;D=150516251515162516251625162516251515151516251625151;CP=5;SP=0;R=66; + # on | v1 MS;P1=309;P2=-1130;P3=1011;P4=-429;P5=-11466;D=15123412121234123412141214121412141212123412341234;CP=1;SP=5;R=38; Gruppentaste, siehe Kommentar in sub SIGNALduino_bit2itv1 + # need more Device Infos / User Message + { + name => 'itv1_sync40', + comment => 'IT remote control PAR 1000, ITS-150, AB440R', + id => '3', + knownFreqs => '433.92', + one => [3.5,-1], + zero => [1,-3.8], + float => [1,-1], # fuer Gruppentaste (nur bei ITS-150,ITR-3500 und ITR-300), siehe Kommentar in sub SIGNALduino_bit2itv1 + sync => [1,-44], + clockabs => -1, + format => 'twostate', # not used now + preamble => 'i', + clientmodule => 'IT', + modulematch => '^i......', + length_min => '24', + length_max => '24', # Don't know maximal lenth of a valid message + postDemodulation => \&lib::SD_Protocols::Convbit2itv1, + }, + "4" => ## arctech2 + # need more Device Infos / User Message + { + name => 'arctech2', + id => '4', + knownFreqs => '', + #one => [1,-5,1,-1], + #zero => [1,-1,1,-5], + one => [1,-5], + zero => [1,-1], + #float => [-1,3], # not full supported now, for later use + sync => [1,-14], + clockabs => -1, + format => 'twostate', # tristate can't be migrated from bin into hex! + preamble => 'i', + postamble => '00', + clientmodule => 'IT', + modulematch => '^i......', + length_min => '39', + length_max => '44', # Don't know maximal lenth of a valid message + }, + "5" => # Unitec, Modellnummer 6899/45108 + # https://github.com/RFD-FHEM/RFFHEM/pull/389#discussion_r237232347 @sidey79 | https://github.com/RFD-FHEM/RFFHEM/pull/389#discussion_r237245943 + # no decode! MU;P0=-31960;P1=660;P2=401;P3=-1749;P5=276;D=232353232323232323232323232353535353232323535353535353535353535010;CP=5;R=38; + # no decode! MU;P0=-1757;P1=124;P2=218;P3=282;P5=-31972;P6=644;P7=-9624;D=010201020303030202030303020303030202020202020203030303035670;CP=2;R=32; + # no decode! MU;P0=-1850;P1=172;P3=-136;P5=468;P6=236;D=010101010101310506010101010101010101010101010101010101010;CP=1;R=30; + # A AN MU;P0=132;P1=-4680;P2=508;P3=-1775;P4=287;P6=192;D=123434343434343634343436363434343636343434363634343036363434343;CP=4;R=2; + # A AUS MU;P0=-1692;P1=132;P2=194;P4=355;P5=474;P7=-31892;D=010202040505050505050404040404040404040470;CP=4;R=27; + { + name => 'Unitec', + comment => 'remote control model 6899/45108', + id => '5', + knownFreqs => '', + one => [3,-1], # ? + zero => [1,-3], # ? + clockabs => 500, # ? + developId => 'y', + format => 'twostate', + preamble => 'u5#', + #clientmodule => '', + #modulematch => '', + length_min => '24', # ? + length_max => '24', # ? + }, + "6" => ## TCM 218943, Eurochron + # https://github.com/RFD-FHEM/RFFHEM/issues/692 @ Ralf9 2019-11-15 + # T:22.9, H:24 MS;P0=-970;P1=254;P3=-1983;P4=-8045;D=14101310131010101310101010101010101010101313101010101010101313131010131013;CP=1;SP=4; + # T:22.7, H:23, tx MS;P0=-2054;P1=236;P2=-1032;P3=-7760;D=13121012101212121012121210121212121212121012101010121212121010101212121010;CP=1;SP=3; + { + name => 'TCM 218943', + comment => 'Weatherstation TCM 218943, Eurochron', + id => '6', + knownFreqs => '433.92', + one => [1,-5], + zero => [1,-10], + sync => [1,-32], + clockabs => 248, + format => 'twostate', + preamble => 's', + postamble => '00', + clientmodule => 'CUL_TCM97001', + length_min => '36', # sync, postamble und paddingbits werden nicht mitgezaehlt + length_max => '36', # sync, postamble und paddingbits werden nicht mitgezaehlt + paddingbits => '8', # pad up to 8 bits, default is 4 + }, + "7" => ## weather sensors like EAS800z + # Ch:1 T: 19.8 H: 11 Bat:low MS;P1=-3882;P2=504;P3=-957;P4=-1949;D=21232424232323242423232323232323232424232323242423242424242323232324232424;CP=2;SP=1;R=249;m=2; + # https://forum.fhem.de/index.php/topic,101682.0.html (Auriol AFW 2 A1, IAN: 297514) + # Ch:1 T: 28.2 H: 44 Bat:ok MS;P0=494;P1=-1949;P2=-967;P3=-3901;D=03010201010202020101020202020202010202020101020102010201020202010201010202;CP=0;SP=3;R=37;m0; + # Ch:1 T: 24.4 H: 56 Bat:ok MS;P1=-1940;P2=495;P3=-957;P4=-3878;D=24212321212323232121232323232323232121212123212323212321232323212121232323;CP=2;SP=4;R=20;O;m1; + { + name => 'Weather', + comment => 'EAS800z, FreeTec NC-7344, HAMA TS34A, Auriol AFW 2 A1', + id => '7', + knownFreqs => '433.92', + one => [1,-4], + zero => [1,-2], + sync => [1,-8], + clockabs => 484, + format => 'twostate', + preamble => 'P7#', + clientmodule => 'SD_WS07', + modulematch => '^P7#.{6}[AFaf].{2}', + length_min => '35', + length_max => '40', + }, + "7.1" => ## Mebus Modell Number HQ7312-2 + # https://github.com/RFD-FHEM/RFFHEM/issues/1024 @ rpsVerni 2021-10-06 + # Ch:3 T: 23.8 H: 11 Bat:ok MS;P0=332;P1=-1114;P2=-2106;P3=-4055;D=03010201010202010202010201010101010202020102020201020202020101010102010202;CP=0;SP=3;R=56;m0; + # Ch:3 T: 24.5 H: 10 Bat:ok MS;P0=-2128;P1=320;P5=-1159;P6=-4084;D=16151015151010151010151015151515151010101015101510101010101515151510151015;CP=1;SP=6;R=66;O;m2; + # Ch:3 T: 25.3 H: 11 Bat:ok MS;P1=303;P4=-1153;P5=-2138;P6=-4102;D=16141514141515141515141514141414141515151515151415151515151414141415141515;CP=1;SP=6;R=50;O;m2; + { + name => 'Weather', + comment => 'Mebus HQ7312-2', + id => '7.1', + knownFreqs => '433.92', + one => [1,-7], # 300,-2100 + zero => [1,-4], # 300,-1200 + sync => [1,-14], # 300,-4200 + clockabs => 300, + format => 'twostate', + preamble => 'P7#', + clientmodule => 'SD_WS07', + modulematch => '^P7#.{6}[AFaf].{2}', + length_min => '36', + length_max => '36', + }, + "8" => ## TX3 (ITTX) Protocol + # Id:97 T: 24.4 MU;P0=-1046;P1=1339;P2=524;P3=-28696;D=010201010101010202010101010202010202020102010101020101010202020102010101010202310101010201020101010101020201010101020201020202010201010102010101020202010201010101020;CP=2;R=4; + { + name => 'TX3 Protocol', + id => '8', + knownFreqs => '', + one => [1,-2], + zero => [2,-2], + #sync => [1,-8], + clockabs => 470, + format => 'pwm', + preamble => 'TX', + clientmodule => 'CUL_TX', + modulematch => '^TX......', + length_min => '43', + length_max => '44', + remove_zero => 1, # Removes leading zeros from output + }, + "9" => ## Funk Wetterstation CTW600 + ### ! some message are decode as protocol 42 and 75 ! + ## WH3080 | UV: 4 Lux: 57970 | @Ralf + # MU;P0=-1424;P1=1417;P2=-1058;P3=453;P4=-24774;P6=288;P7=-788;D=01212121232343232323232323232123232323232121232121212123212121232123212321232121212123212121232321232321212121232323212321212121212121212323467323232323232323212323232323212123212121212321212123212321232123212121212321212123232123232121212123232321232121;CP=3;R=247;O; + ## WH1080 + # https://forum.fhem.de/index.php/topic,39451.msg844155.html#msg844155 | https://forum.fhem.de/index.php/topic,39451.msg848667.html#msg848667 @maddinthebrain + # MU;P0=-31072;P1=486;P2=-986;P3=1454;D=01212121212121212321232321232123232121232323212121212123232123232123212321232123232323232321232323232323212323232323232323232123212121212321232323232323232323212321212321232301212121212121212321232321232123232121232323212121212123232123232123212321232123;CP=1;R=29;O; + ## CTW600 + # https://forum.fhem.de/index.php/topic,39451.msg917042.html#msg917042 @greewoo + # MU;P0=-96;P1=800;P2=-985;P3=485;P4=1421;P5=-8608;D=0123232323232323242324232324242324232324242324242324232323242324242323232324242424242424242424242424242424242424242424242424242424242424242424242424242424242324242424232323235;CP=4;R=0; + { + name => 'weather', + comment => 'Weatherstation WH1080, WH3080, WH5300SE, CTW600', + id => '9', + knownFreqs => '433.92 | 868.35', + zero => [3,-2], + one => [1,-2], + clockabs => 480, # -1 = auto undef=noclock + format => 'pwm', # tristate can't be migrated from bin into hex! + preamble => 'P9#', + clientmodule => 'SD_WS09', + #modulematch => '^u9#.....', + length_min => '60', + length_max => '120', + reconstructBit => '1', + }, + "10" => ## Oregon Scientific 2 + # https://forum.fhem.de/index.php/topic,60170.msg875919.html#msg875919 @David1 + # MC;LL=-973;LH=984;SL=-478;SH=493;D=EF7E2DCC00000283AF5DF7CFEFEF7E2DCC;C=487;L=134;R=33;s5;b0; + # MC;LL=-975;LH=976;SL=-491;SH=491;D=BEF9FDFDEFC5B98000005075EBBEF9FDFDEFC5;C=488;L=152;R=34;s1;b0;O;w; + { + name => 'Oregon Scientific v2|v3', + comment => 'temperature / humidity or other sensors', + id => '10', + knownFreqs => '', + clockrange => [300,520], # min , max + format => 'manchester', # tristate can't be migrated from bin into hex! + clientmodule => 'OREGON', + modulematch => '^(3[8-9A-F]|[4-6][0-9A-F]|7[0-8]).*', + length_min => '64', + length_max => '220', + method => \&lib::SD_Protocols::mcBit2OSV2o3, # Call to process this message + polarity => 'invert', + }, + "11" => ## Arduino Sensor + { + name => 'Arduino', + comment => 'for Arduino based sensors', + id => '11', + knownFreqs => '', + clockrange => [380,425], # min , max + format => 'manchester', # tristate can't be migrated from bin into hex! + preamble => 'P2#', + clientmodule => 'SD_AS', + modulematch => '^P2#.{7,8}', + length_min => '52', + length_max => '56', + method => \&lib::SD_Protocols::mcBit2AS # Call to process this message + }, + "12" => ## Hideki + # Id:31 Ch:1 T: 22.7 Bat:ok MC;LL=-1040;LH=904;SL=-542;SH=426;D=A8C233B53A3E0A0783;C=485;L=72;R=213; + { + name => 'Hideki', + comment => 'temperature / humidity or other sensors', + id => '12', + knownFreqs => '433.92', + clockrange => [420,510], # min, max better for Bresser Sensors, OK for hideki/Hideki/TFA too + format => 'manchester', + preamble => 'P12#', + clientmodule => 'Hideki', + modulematch => '^P12#75.+', + length_min => '71', + length_max => '128', + method => \&lib::SD_Protocols::mcBit2Hideki, # Call to process this message + #polarity => 'invert', + }, + "13" => ## FLAMINGO FA21 + # https://github.com/RFD-FHEM/RFFHEM/issues/21 @sidey79 + # https://github.com/RFD-FHEM/RFFHEM/issues/233 + # 32E44F | Alarm MS;P0=-1413;P1=757;P2=-2779;P3=-16079;P4=8093;P5=-954;D=1345121210101212101210101012121012121210121210101010;CP=1;SP=3;R=33;O; + { + name => 'FLAMINGO FA21', + comment => 'FLAMINGO FA21 smoke detector (message decode as MS)', + id => '13', + knownFreqs => '433.92', + one => [1,-2], + zero => [1,-4], + sync => [1,-20,10,-1], + clockabs => 800, + format => 'twostate', + preamble => 'P13#', + clientmodule => 'FLAMINGO', + #modulematch => 'P13#.*', + length_min => '24', + length_max => '26', + }, + "13.1" => ## FLAMINGO FA20RF + # B67C3B | Alarm MU;P0=-1384;P1=815;P2=-2725;P3=-20001;P4=8159;P5=-891;D=01010121212121010101210101345101210101210101212101010101012121212101010121010134510121010121010121210101010101212121210101012101013451012101012101012121010101010121212121010101210101345101210101210101212101010101012121212101010121010134510121010121010121;CP=1;O; + # 1B61BB | Alarm MU;P0=-17201;P1=112;P2=-1419;P3=-28056;P4=8092;P5=-942;P6=777;P7=-2755;D=12134567676762626762626762626767676762626762626267626260456767676262676262676262676767676262676262626762626045676767626267626267626267676767626267626262676262604567676762626762626762626767676762626762626267626260456767676262676262676262676767676262676262;CP=6;O; + ## FLAMINGO FA22RF (only MU Message) @HomeAutoUser + # CBFAD2 | Alarm MU;P0=-5684;P1=8149;P2=-887;P3=798;P4=-1393;P5=-2746;P6=-19956;D=0123434353534353434343434343435343534343534353534353612343435353435343434343434343534353434353435353435361234343535343534343434343434353435343435343535343536123434353534353434343434343435343534343534353534353612343435353435343434343434343534353434353435;CP=3;R=0; + # Times measured + # Sync 8100 microSec, 900 microSec | Bit1 2700 microSec low - 800 microSec high | Bit0 1400 microSec low - 800 microSec high | Pause Repeat 20000 microSec | 1 Sync + 24Bit, Totaltime 65550 microSec without Sync + { + name => 'FLAMINGO FA22RF / FA21RF / LM-101LD', + comment => 'FLAMINGO | Unitec smoke detector (message decode as MU)', + id => '13.1', + knownFreqs => '433.92', + one => [1,-1.8], + zero => [1,-3.5], + start => [10,-1], + pause => [-25], + clockabs => 800, + format => 'twostate', + preamble => 'P13.1#', + clientmodule => 'FLAMINGO', + #modulematch => '^P13\.?1?#[A-Fa-f0-9]+', + length_min => '24', + length_max => '24', + }, + "13.2" => ## LM-101LD Rauchm + # https://github.com/RFD-FHEM/RFFHEM/issues/233 @Ralf9 + # B0FFAF | Alarm MS;P1=-2708;P2=796;P3=-1387;P4=-8477;P5=8136;P6=-904;D=2456212321212323232321212121212121212123212321212121;CP=2;SP=4; + { + name => 'LM-101LD', + comment => 'Unitec smoke detector (message decode as MS)', + id => '13', + knownFreqs => '433.92', + zero => [1,-1.8], + one => [1,-3.5], + sync => [1,-11,10,-1.2], + clockabs => 790, + format => 'twostate', + preamble => 'P13#', + clientmodule => 'FLAMINGO', + #modulematch => '', + length_min => '24', + length_max => '24', + }, + "14" => ## LED X-MAS Chilitec model 22640 + # https://github.com/RFD-FHEM/RFFHEM/issues/421 | https://forum.fhem.de/index.php/topic,94211.msg869214.html#msg869214 @privat58 + # power_on MS;P0=988;P1=-384;P2=346;P3=-1026;P4=-4923;D=240123012301230123012323232323232301232323;CP=2;SP=4;R=0;O;m=1; + # brightness_plus MS;P0=-398;P1=974;P3=338;P4=-1034;P6=-4939;D=361034103410341034103434343434343410103434;CP=3;SP=6;R=0; + { + name => 'LED X-MAS', + comment => 'Chilitec model 22640', + id => '14', + knownFreqs => '433.92', + one => [3,-1], + zero => [1,-3], + sync => [1,-14], + clockabs => 350, + format => 'twostate', + preamble => 'P14#', + clientmodule => 'SD_UT', + #modulematch => '^P14#.*', + length_min => '20', + length_max => '20', + }, + "15" => ## TCM 234759 + { + name => 'TCM 234759 Bell', + comment => 'wireless doorbell TCM 234759 Tchibo', + id => '15', + knownFreqs => '', + one => [1,-1], + zero => [1,-2], + sync => [1,-45], + clockabs => 700, + format => 'twostate', + preamble => 'P15#', + clientmodule => 'SD_BELL', + modulematch => '^P15#.*', + length_min => '10', + length_max => '20', + }, + "16" => ## Rohrmotor24 und andere Funk Rolladen / Markisen Motoren + # ! same definition how ID 72 ! + # https://forum.fhem.de/index.php/topic,49523.0.html + # closed MU;P0=-1608;P1=-785;P2=288;P3=650;P4=-419;P5=4676;D=1212121213434212134213434212121343434212121213421213434212134345021213434213434342121212121343421213421343421212134343421212121342121343421213432;CP=2; + # closed MU;P0=-1562;P1=-411;P2=297;P3=-773;P4=668;P5=4754;D=1232341234141234141234141414123414123232341232341412323414150234123234123232323232323234123414123414123414141412341412323234123234141232341415023412323412323232323232323412341412341412341414141234141232323412323414123234142;CP=2; + { + name => 'Dooya', + comment => 'Rohrmotor24 and other radio shutters / awnings motors', + id => '16', + knownFreqs => '', + one => [2,-1], + zero => [1,-3], + start => [17,-5], + clockabs => 280, + format => 'twostate', + preamble => 'P16#', + clientmodule => 'Dooya', + #modulematch => '', + length_min => '39', + length_max => '40', + }, + "17" => ## arctech / intertechno + # need more Device Infos / User Message + { + name => 'arctech / Intertechno', + id => '17', + knownFreqs => '433.92', + one => [1,-5,1,-1], + zero => [1,-1,1,-5], + #one => [1,-5], + #zero => [1,-1], + sync => [1,-10], + float => [1,-1,1,-1], + end => [1,-40], + clockabs => -1, # -1 = auto + format => 'twostate', # tristate can't be migrated from bin into hex! + preamble => 'i', + postamble => '00', + clientmodule => 'IT', + modulematch => '^i......', + length_min => '32', + length_max => '34', # Don't know maximal lenth of a valid message + postDemodulation => \&lib::SD_Protocols::Convbit2Arctec, + }, + "17.1" => ## intertechno --> MU anstatt sonst MS (ID 17) + # no decode! MU;P0=344;P1=-1230;P2=-200;D=01020201020101020102020102010102010201020102010201020201020102010201020101020102020102010201020102010201010200;CP=0;R=0; + # no decode! MU;P0=346;P1=-1227;P2=-190;P4=-10224;P5=-2580;D=0102010102020101020201020101020102020102010102010201020102010201020201020102010201020101020102020102010102020102010201020104050201020102010102020101020201020101020102020102010102010201020102010201020201020102010201020101020102020102010102020102010201020;CP=0;R=0; + # no decode! MU;P0=351;P1=-1220;P2=-185;D=01 0201 0102 020101020201020101020102020102010102010201020102010201020201020102010201020101020102020102010201020102010201020100;CP=0;R=0; + # off | v3 MU;P0=355;P1=-189;P2=-1222;P3=-10252;P4=-2604;D=01020201010201020201020101020102020102010201020102010201010201020102010201020201020101020102010201020102010201020 304 0102 01020102020101020201010201020201020101020102020102010201020102010201010201020102010201020201020101020102010201020102010201020 304 01020;CP=0;R=0; + # https://www.sweetpi.de/blog/329/ein-ueberblick-ueber-433mhz-funksteckdosen-und-deren-protokolle + { + name => 'Intertechno', + comment => 'PIR-1000 | ITT-1500', + id => '17.1', + knownFreqs => '433.92', + one => [1,-5,1,-1], + zero => [1,-1,1,-5], + clockabs => 230, # -1 = auto + format => 'twostate', # tristate can't be migrated from bin into hex! + preamble => 'i', + postamble => '00', + clientmodule => 'IT', + modulematch => '^i......', + length_min => '32', + length_max => '34', # Don't know maximal lenth of a valid message + postDemodulation => \&lib::SD_Protocols::Convbit2Arctec, + }, + "18" => ## Oregon Scientific v1 + # Id:3 T: 7.5 BAT:ok MC;LL=-2721;LH=3139;SL=-1246;SH=1677;D=1A51FF47;C=1463;L=32;R=12; + { + name => 'Oregon Scientific v1', + comment => 'temperature / humidity or other sensors', + id => '18', + knownFreqs => '433.92', + clockrange => [1400,1500], # min , max + format => 'manchester', # tristate can't be migrated from bin into hex! + preamble => '', + clientmodule => 'OREGON', + modulematch => '^[0-9A-F].*', + length_min => '32', + length_max => '32', + polarity => 'invert', + method => \&lib::SD_Protocols::mcBit2OSV1 # Call to process this message + }, + "19" => ## minify Funksteckdose + # https://github.com/RFD-FHEM/RFFHEM/issues/114 @zag-o-mat + # u19#E2CA7C MU;P0=293;P1=-887;P2=-312;P6=-1900;P7=872;D=6727272010101720172720101720172010172727272720;CP=0; + # u19#E2CA7C MU;P0=9078;P1=-308;P2=180;P3=-835;P4=881;P5=309;P6=-1316;D=0123414141535353415341415353415341535341414141415603;CP=5; + { + name => 'minify', + comment => 'remote control RC202', + id => '19', + knownFreqs => '', + one => [3,-1], + zero => [1,-3], + clockabs => 300, + format => 'twostate', + preamble => 'u19#', + #clientmodule => '', + #modulematch => '', + length_min => '19', + length_max => '23', # not confirmed, length one more as MU Message + }, + "20" => ## Remote control with 4 buttons for diesel heating + # https://forum.fhem.de/index.php/topic,58397.msg999475.html#msg999475 @ fhem_user0815 2019-12-04 + # RCnoName20_17E9 on MS;P0=-740;P2=686;P3=-283;P5=229;P6=-7889;D=5650505023502323232323235023505023505050235050502323502323505050;CP=5;SP=6;R=67;O;m2; + # RCnoName20_17E9 off MS;P1=-754;P2=213;P4=681;P5=-283;P6=-7869;D=2621212145214545454545452145212145212121212145214521212121452121;CP=2;SP=6;R=69;O;m2; + # RCnoName20_17E9 plus MS;P1=-744;P2=221;P3=679;P4=-278;P5=-7860;D=2521212134213434343434342134212134212121213421212134343434212121;CP=2;SP=5;R=66;O;m2; + # RCnoName20_17E9 minus MS;P0=233;P1=-7903;P3=-278;P5=-738;P6=679;D=0105050563056363636363630563050563050505050505630563050505630505;CP=0;SP=1;R=71;O;m1; + { + name => 'RCnoName20', + comment => 'Remote control with 4 buttons for diesel heating', + id => '20', + knownFreqs => '433.92', + one => [3,-1], # 720,-240 + zero => [1,-3], # 240,-720 + sync => [1,-33], # 240,-7920 + clockabs => 240, + format => 'twostate', + preamble => 'P20#', + clientmodule => 'SD_UT', + modulematch => '^P20#.{8}', + length_min => '31', + length_max => '32', + }, + "21" => ## Einhell Garagentor + # https://forum.fhem.de/index.php?topic=42373.0 @Ellert | user have no RAWMSG + # static adress: Bit 1-28 | channel remote Bit 29-32 | repeats 31 | pause 20 ms + # Channelvalues dez + # 1 left 1x kurz | 2 left 2x kurz | 3 left 3x kurz | 5 right 1x kurz | 6 right 2x kurz | 7 right 3x kurz ... gedrückt + { + name => 'Einhell Garagedoor', + comment => 'remote control ISC HS 434/6', + id => '21', + knownFreqs => '433.92', + one => [-3,1], + zero => [-1,3], + #sync => [-50,1], + start => [-50,1], + clockabs => 400, #ca 400us + format => 'twostate', + preamble => 'u21#', + #clientmodule => '', + #modulematch => '', + length_min => '32', + length_max => '32', + paddingbits => '1', # This will disable padding + }, + "22" => ## HAMULiGHT LED Trafo + # https://forum.fhem.de/index.php?topic=89301.0 | https://forum.fhem.de/index.php/topic,89643.msg822289.html#msg822289 @Michi240281 + # remote with one button on/off + # u22#8F995F34 MU;P0=-196;P1=32001;P3=214;P4=1192;P5=-1200;P6=-595;P7=597;D=0103030453670707036363636367070363670703670367036363636367070363670367070303030304536707070363636363670703636707036703670363636363670703636703670703030303045367070703636363636707036367070367036703636363636707036367036707030303030453670707036363636367070;CP=3;R=15; + # u22#8F995F34 MU;P0=-604;P1=188;P2=583;P3=-224;P4=1199;P5=-1197;D=0102323102310231010101010232310102310232313131313451023232310101010102323101023231023102310101010102323101023102323131313134510232323101010101023231010232310231023101010101023231010231023231313131345102323231010101010232310102323102310231010101010232310;CP=1;R=15; + # u22#8F995F34 MU;P0=-614;P1=597;P2=-228;P3=171;P4=1184;P5=-1215;D=0123012123232323245301212123030303030121230301212301230123030303030121230301230121232323232453012121230303030301212303012123012301230303030301212303012301212323232324530121212303030303012123030121230123012303030303012123030123012;CP=3;R=7; + # u22#8F995F34 MU;P0=604;P1=-197;P2=205;P3=-595;P4=1194;P5=-1197;D=0101012323232323010123230101230123012323232323010123230123010121212121452301010123232323230101232301012301230123232323230101232301230101212121214523010101232323232301012323010123012301232323232301012323012301012121212145230101012323232323010123230101230;CP=2;R=17; + # u22#8F995F34 MU;P0=193;P1=-607;P2=605;P3=-209;P4=1204;P5=-1196;D=0123010101010123230101230123230303030345012323230101010101232301012323012301230101010101232301012301232303030303450123232301010101012323010123230123012301010101012323010123012323030303034501232323010101010123230101232301230123010101010123230101230123230;CP=0;R=18; + # u22#8F995F34 MU;P0=192;P1=-209;P2=1182;P3=-1214;P4=-606;P5=594;D=0101012304515151040404040451510404515104510451040404040451510404510451510101010123045151510404040404515104045151045104510404040404515104045104515101010101230451515104040404045151040451510451045104040404045151040451045150;CP=0;R=17; + { + name => 'HAMULiGHT', + comment => 'remote control for LED Transformator', + id => '22', + knownFreqs => '433.92', + one => [1,-3], + zero => [3,-1], + start => [6,-6], + clockabs => 200, # ca 200us + format => 'twostate', + preamble => 'u22#', + #clientmodule => '', + #modulematch => '', + length_min => '32', + length_max => '32', + }, + "23" => ## Pearl Sensor + { + name => 'Pearl', + comment => 'unknown sensortyp', + id => '23', + knownFreqs => '', + one => [1,-6], + zero => [1,-1], + sync => [1,-50], + clockabs => 200, #ca 200us + format => 'twostate', + preamble => 'u23#', + #clientmodule => '', + #modulematch => '', + length_min => '36', + length_max => '44', + }, + "24" => ## visivo + # https://github.com/RFD-FHEM/RFFHEM/issues/39 @sidey79 + # Visivo_7DF825 up MU;P0=132;P1=500;P2=-233;P3=-598;P4=-980;P5=4526;D=012120303030303120303030453120303121212121203121212121203121212121212030303030312030312031203030303030312031203031212120303030303120303030453120303121212121203121212121203121212121212030303030312030312031203030303030312031203031212120303030;CP=0;O; + # https://forum.fhem.de/index.php/topic,42273.0.html @MikeRoxx + # Visivo_7DF825 up MU;P0=505;P1=140;P2=-771;P3=-225;P5=4558;D=012031212030303030312030303030312030303030303121212121203121203120312121212121203120312120303031212121212031212121252031212030303030312030303030312030303030303121212121203121203120312121212121203120312120303031212121212031212121252031212030;CP=1;O; + # Visivo_7DF825 down MU;P0=147;P1=-220;P2=512;P3=-774;P5=4548;D=001210303210303212121210303030321030303035321030321212121210321212121210321212121212103030303032103032103210303030303210303210303212121210303030321030303035321030321212121210321212121210321212121212103030303032103032103210303030303210303210;CP=0;O; + # Visivo_7DF825 stop MU;P0=-764;P1=517;P2=-216;P3=148;P5=4550;D=012303012121212123012121212123012121212121230303030301230301230123030303012303030123012303030123030303012303030305012303012121212123012121212123012121212121230303030301230301230123030303012303030123012303030123030303012303030305012303012120;CP=3;O; + { + name => 'Visivo remote', + comment => 'Remote control for motorized screen', + id => '24', + knownFreqs => '315', + one => [3,-1], # 546,-182 + zero => [1,-4], # 182,-728 + start => [25,-4], # 4550,-728 + clockabs => 182, + reconstructBit => '1', + format => 'twostate', + preamble => 'P24#', + clientmodule => 'SD_UT', + modulematch => '^P24#', + length_min => '55', + length_max => '56', + }, + "25" => ## LES remote for led lamp + # https://github.com/RFD-FHEM/RFFHEM/issues/40 @sidey79 + # u25#45A06B MS;P0=-376;P1=697;P2=-726;P3=322;P4=-13188;P5=-15982;D=3530123010101230123230123010101010101232301230123234301230101012301232301230101010101012323012301232;CP=3;SP=5;O; + { + name => 'les led remote', + id => '25', + knownFreqs => '', + one => [-2,1], + zero => [-1,2], + sync => [-46,1], # this is a end marker, but we use this as a start marker + clockabs => 350, #ca 350us + format => 'twostate', + preamble => 'u25#', + #clientmodule => '', + #modulematch => '', + length_min => '24', + length_max => '50', # message has only 24 bit, but we get more than one message, calculation has to be corrected + }, + "26" => ## xavax 00111939 Funksteckdosen Set + # https://github.com/RFD-FHEM/RFFHEM/issues/717 @codeartisan-de 2019-12-14 + # xavax_DAAB2554 Ch1_on MU;P0=412;P1=-534;P2=-1356;P3=-20601;P4=3360;P5=-3470;D=01020102010201020201010201010201020102010201020101020101010102020203010145020201020201020102010201020102020101020101020102010201020102010102010101010202020301014502020102020102010201020102010202010102010102010201020102010201010201010101020202030101450202;CP=0;R=0;O; + # xavax_DAAB2554 Ch1_off MU;P0=-3504;P1=416;P2=-1356;P3=-535;P4=-20816;P5=3324;D=01212131212131213121312131213121213131213131213121312131213121313131212121213131314131350121213121213121312131213121312121313121313121312131213121312131313121212121313131413135012121312121312131213121312131212131312131312131213121312131213131312121212131;CP=1;R=50;O; + # xavax_DAAB2554 Ch2_on MU;P0=5656;P1=-21857;P2=413;P3=-1354;P4=-536;P6=3350;P7=-3487;D=01232423232424232424232423242324232423242424232424232423232124246723232423232423242324232423242323242423242423242324232423242324242423242423242323212424672323242323242324232423242324232324242324242324232423242324232424242324242324232321242467232324232324;CP=2;R=0;O; + # xavax_DAAB2554 Ch2_off MU;P0=3371;P1=-3479;P2=420;P3=-31868;P4=-541;P5=272;P6=-1343;P7=-20621;D=23245426242426242624262426242624242624262624262424272424012626242626242624262426242624262624242624242624262426242624262424262426262426242427242401262624262624262426242624262426262424262424262426242624262426242426242626242624242724240126262426262426242624;CP=2;R=45;O; + { + name => 'xavax', + comment => 'Remote control xavax 00111939', + id => '26', + knownFreqs => '433.92', + one => [1,-3], # 460,-1380 + zero => [1,-1], # 460,-460 + start => [1,-1,1,-1,7,-7], # 460,-460,460,-460,3220,-3220 + # end => [1], # 460 - end funktioniert nicht (wird erst nach pause angehangen), ein bit ans Ende haengen geht, dann aber pause 44 statt 45 + pause => [-44], # -20700 mit end, 20240 mit bit 0 am Ende + clockabs => 460, + format => 'twostate', + preamble => 'P26#', + clientmodule => 'SD_UT', + modulematch => '^P26#.{10}', + length_min => '40', + length_max => '40', + }, + "27" => ## Temperatur-/Feuchtigkeitssensor EuroChron EFTH-800 (433 MHz) - https://github.com/RFD-FHEM/RFFHEM/issues/739 + # SD_WS_27_TH_2 - T: 15.5 H: 48 - MU;P0=-224;P1=258;P2=-487;P3=505;P4=-4884;P5=743;P6=-718;D=0121212301212303030301212123012123012123030123030121212121230121230121212121212121230301214565656561212123012121230121230303030121212301212301212303012303012121212123012123012121212121212123030121;CP=1;R=53; + # SD_WS_27_TH_3 - T: 3.8 H: 76 - MU;P0=-241;P1=251;P2=-470;P3=500;P4=-4868;P5=743;P6=-718;D=012121212303030123012301212123012121212301212303012121212121230303012303012123030303012123014565656561212301212121230303012301230121212301212121230121230301212121212123030301230301212303030301212301;CP=1;R=23; + # SD_WS_27_TH_3 - T: 5.3 H: 75 - MU;P0=-240;P1=253;P2=-487;P3=489;P4=-4860;P5=746;P6=-725;D=012121212303030123012301212123012121212303012301230121212121230303012301230303012303030301214565656561212301212121230303012301230121212301212121230301230123012121212123030301230123030301230303030121;CP=1;R=19; + # Eurochron Zusatzsensor fuer EFS-3110A - https://github.com/RFD-FHEM/RFFHEM/issues/889 + # short pulse of 244 us followed by a 488 us gap is a 0 bit + # long pulse of 488 us followed by a 244 us gap is a 1 bit + # sync preamble of pulse, gap, 732 us each, repeated 4 times + # sensor sends two messages at intervals of about 57-58 seconds + { + name => 'EFTH-800', + comment => 'EuroChron weatherstation EFTH-800, EFS-3110A', + id => '27', + knownFreqs => '433.92', + one => [2,-1], + zero => [1,-2], + start => [3,-3,3,-3,3,-3,3,-3], + clockabs => '244', + format => 'twostate', + preamble => 'W27#', + clientmodule => 'SD_WS', + modulematch => '^W27#.{12}', + length_min => '48', # 48 Bit + 1 Puls am Ende + length_max => '48', + }, + "28" => ## some remote code, send by aldi IC Ledspots + { + name => 'IC Ledspot', + id => '28', + knownFreqs => '', + one => [1,-1], + zero => [1,-2], + start => [4,-5], + clockabs => 600, #ca 600 + format => 'twostate', + preamble => 'u28#', + #clientmodule => '', + #modulematch => '', + length_min => '8', + length_max => '8', + }, + "29" => ## example remote control with HT12E chip + # fan_off MU;P0=250;P1=-492;P2=166;P3=-255;P4=491;P5=-8588;D=052121212121234121212121234521212121212341212121212345212121212123412121212123452121212121234121212121234;CP=0; + # https://forum.fhem.de/index.php/topic,58397.960.html + { + name => 'HT12e', + comment => 'remote control for example Westinghouse airfan with 5 buttons', + id => '29', + knownFreqs => '', + one => [-2,1], + zero => [-1,2], + start => [-35,1], # Message is not provided as MS, worakround is start + clockabs => 235, # ca 220 + format => 'twostate', # there is a pause puls between words + preamble => 'P29#', + clientmodule => 'SD_UT', + modulematch => '^P29#.{3}', + length_min => '12', + length_max => '12', + }, + "30" => ## a unitec remote door reed switch + # https://forum.fhem.de/index.php?topic=43346.0 @Dr.E.Witz + # unknown MU;P0=-10026;P1=-924;P2=309;P3=-688;P4=-361;P5=637;D=123245453245324532453245320232454532453245324532453202324545324532453245324532023245453245324532453245320232454532453245324532453202324545324532453245324532023245453245324532453245320232454532453245324532453202324545324532453245324532023240;CP=2;O; + # unknown MU;P0=307;P1=-10027;P2=-691;P3=-365;P4=635;D=0102034342034203420342034201020343420342034203420342010203434203420342034203420102034342034203420342034201020343420342034203420342010203434203420342034203420102034342034203420342034201;CP=0; + { + name => 'diverse', + comment => 'remote control unitec | door reed switch 47031', + id => '30', + knownFreqs => '', + one => [-2,1], + zero => [-1,2], + start => [-30,1], # Message is not provided as MS, worakround is start + clockabs => 330, # ca 300 us + format => 'twostate', # there is a pause puls between words + preamble => 'P30#', + clientmodule => 'SD_UT', + modulematch => '^P30#.{3}', + length_min => '12', + length_max => '12', # message has only 10 bit but is paddet to 12 + }, + "31" => ## LED Controller LTECH, LED M Serie RF RGBW - M4 & M4-5A + # https://forum.fhem.de/index.php/topic,107868.msg1018434.html#msg1018434 | https://forum.fhem.de/index.php/topic,107868.msg1020521.html#msg1020521 @Devirex + ## note: command length 299, now - not supported by all firmware versions + # MU;P0=-16118;P1=315;P2=-281;P4=-1204;P5=-563;P6=618;P7=1204;D=01212121212121212121214151562151515151515151515621515621515626262156262626262626262626215626262626262626262626262626262151515151515151515151515151515151515151515151515626262626262626215151515151515156215156262626262626262626262621570121212121212121212121;CP=1;R=26;O; + # MU;P0=-32001;P1=314;P2=-285;P3=-1224;P4=-573;P5=601;P6=1204;P7=-15304;CP=1;R=31;D=012121212121212121212131414521414141414141414145214145214145252521452525252525252525252145252525252525252525252525252521414141414141414141414141414141452141414141414145252525252525252141414141414141414525252141452525252525214145214671212121212121212121213141452;p;i; + { + name => 'LTECH', + comment => 'remote control for LED Controller M4-5A', + id => '31', + knownFreqs => '433.92', + one => [1,-1.8], + zero => [2,-0.9], + start => [1,-0.9, 1,-0.9, 1,-3.8], + preSync => [1,-0.9, 1,-0.9, 1,-0.9, 1,-0.9, 1,-0.9, 1,-0.9, 1,-0.9, 1,-0.9], + end => [3.8, -51], + clockabs => 315, + format => 'twostate', + preamble => 'u31#', + }, + "32" => ## FreeTec PE-6946 + # ! some message are decode as protocol 40 and protocol 62 ! + # http://www.free-tec.de/Funkklingel-mit-Voic-PE-6946-919.shtml + # OLD # https://github.com/RFD-FHEM/RFFHEM/issues/49 + # NEW # https://github.com/RFD-FHEM/RFFHEM/issues/315 + # P32#154FFF | ring MU;P0=-6676;P1=578;P2=-278;P4=-680;P5=176;P6=-184;D=541654165412545412121212121212121212121250545454125412541254125454121212121212121212121212;CP=1;R=0; + # P32#154FFF | ring MU;P0=146;P1=245;P3=571;P4=-708;P5=-284;P7=-6689;D=14351435143514143535353535353535353535350704040435043504350435040435353535353535353535353507040404350435043504350404353535353535353535353535070404043504350435043504043535353535353535353535350704040435043504350435040435353535353535353535353507040404350435;CP=3;R=0;O; + # P32#154FFF | ring MU;P0=-6680;P1=162;P2=-298;P4=253;P5=-699;P6=555;D=45624562456245456262626262626262626262621015151562156215621562151562626262626262626262626210151515621562156215621515626262626262626262626262;CP=6;R=0; + ## VLOXO Wireless Türklingel + # https://github.com/RFD-FHEM/RFFHEM/issues/655 @schwatter + # P32#7ED403 | ring MU;P0=130;P1=-666;P2=533;P3=-273;P5=-6200;CP=0;R=15;D=01232301230123010101010101010123230501232323232323012323012301230101010101010101232305012323232323230123230123012301010101010101012323050123232323232301232301230123010101010101010123230501232323232323012323012301230101010101010101232305012323232323230123;O; + { + name => 'wireless doorbell', + comment => 'FreeTec PE-6946 / VLOXO', + id => '32', + knownFreqs => '433.92', + one => [4,-2], + zero => [1,-5], + start => [1,-45], # neuerdings MU Erknnung + #sync => [1,-49], # old MS Erkennung + clockabs => 150, + format => 'twostate', + preamble => 'P32#', + clientmodule => 'SD_BELL', + modulematch => '^P32#.*', + length_min => '24', + length_max => '24', + }, + "33" => ## Thermo-/Hygrosensor S014, renkforce E0001PA, Conrad S522, TX-EZ6 (Weatherstation TZS First Austria) + # https://forum.fhem.de/index.php?topic=35844.0 @BrainHunter + # Id:62 Ch:1 T: 21.1 H: 76 Bat:ok MS;P0=-7871;P2=-1960;P3=578;P4=-3954;D=030323232323434343434323232323234343434323234343234343234343232323432323232323232343234;CP=3;SP=0;R=0;m=0; + { + name => 'weather', + comment => 'S014, TFA 30.3200, TCM, Conrad S522, renkforce E0001PA, TX-EZ6', + id => '33', + knownFreqs => '433.92', + one => [1,-8], + zero => [1,-4], + sync => [1,-16], + clockabs => '500', + format => 'twostate', # not used now + preamble => 'W33#', + postamble => '', + clientmodule => 'SD_WS', + #modulematch => '', + length_min => '42', + length_max => '44', + }, + "33.1" => ## Thermo-/Hygrosensor TFA 30.3200 + # https://github.com/RFD-FHEM/SIGNALDuino/issues/113 + # SD_WS_33_TH_1 T: 18.8 H: 53 MS;P1=-7796;P2=745;P3=-1976;P4=-3929;D=21232323242324232324242323232323242424232323242324242323242324232324242323232323232424;CP=2;SP=1;R=30;O;m2; + # SD_WS_33_TH_2 T: 21.9 H: 49 MS;P1=-7762;P2=747;P3=-1976;P4=-3926;D=21232324232324242323242323232424242424232423232324242323232324232324242323232324242424;CP=2;SP=1;R=32;O;m1; + # SD_WS_33_TH_3 T: 19.7 H: 53 MS;P1=758;P2=-1964;P3=-3929;P4=-7758;D=14121213121313131213121212131212131313121213121213131212131213121213131212121212121212;CP=1;SP=4;R=48;O;m1; + { + name => 'TFA 30.3200', + comment => 'Thermo-/Hygrosensor TFA 30.3200 (CP=750)', + id => '33.1', + knownFreqs => '433.92', + one => [1,-5.6], # 736,-4121 + zero => [1,-2.8], # 736,-2060 + sync => [1,-11], # 736,-8096 + clockabs => 736, + format => 'twostate', # not used now + preamble => 'W33#', + clientmodule => 'SD_WS', + length_min => '42', + length_max => '44', + }, + "33.2" => ## Tchibo Wetterstation + # https://forum.fhem.de/index.php/topic,58397.msg880339.html#msg880339 @Doublefant + # passt bei 33 und 33.2: + # SD_WS_33_TH_1 T: 5.1 H: 41 MS;P1=399;P2=-7743;P3=-2038;P4=-3992;D=12131314141414141313131413131314141414131313141314131414131314131314131313131314131314;CP=1;SP=2;R=230;O;m2; + # SD_WS_33_TH_1 T: 5.1 H: 41 MS;P1=399;P2=-7733;P3=-2043;P4=-3991;D=12131314141414141313131413131314141414131313141314131414131314131314131313131314131314;CP=1;SP=2;R=230;O; + # passt nur bei 33.2: + # SD_WS_33_TH_1 T: 5.1 H: 41 MS;P1=393;P2=-7752;P3=-2047;P4=-3993;D=12131314141414141313131413131314141414131313141314131414131314131314131313131314131314;CP=1;SP=2;R=230;O;m1; + # SD_WS_33_TH_1 T: 5.1 H: 41 MS;P1=396;P2=-7759;P3=-2045;P4=-4000;D=12131314141414141313131413131314141414131313141314131414131314131314131313131314131314;CP=1;SP=2;R=230;O;m0; + { + name => 'Tchibo', + comment => 'Tchibo weatherstation (CP=400)', + id => '33.2', + knownFreqs => '433.92', + one => [1,-10], # 400,-4000 + zero => [1,-5], # 400,-2000 + sync => [1,-19], # 400,-7600 + clockabs => 400, + format => 'twostate', + preamble => 'W33#', + postamble => '', + clientmodule => 'SD_WS', + length_min => '42', + length_max => '44', + }, + "34" => ## QUIGG GT-7000 Funk-Steckdosendimmer | transmitter DMV-7000 - receiver DMV-7009AS + # https://github.com/RFD-FHEM/RFFHEM/issues/195 | https://forum.fhem.de/index.php/topic,38831.msg361341.html#msg361341 @StefanW + # Ch1_on MU;P0=-5284;P1=583;P2=-681;P3=1216;P4=-1319;D=012341412323232341412341412323234123232341;CP=1;R=16; + # Ch1_off MU;P0=-9812;P1=589;P2=-671;P3=1261;P4=-1320;D=012341412323232341412341412323232323232323;CP=3;R=19; + # Ch2_on MU;P0=-9832;P1=577;P2=-670;P3=1219;P4=-1331;D=012341412323232341412341414123234123234141;CP=1;R=16; + # Ch2_off MU;P0=-8816;P1=594;P2=-662;P3=1263;P4=-1330;D=012341412323232341412341414123232323234123;CP=1;R=16; + # Ch3_on MU;P0=-677;P1=581;P2=1250;P3=-1319;D=010231310202020231310231310231023102020202;CP=1;R=18; + # Ch3_off MU;P0=-29120;P1=603;P2=-666;P3=1235;P4=-1307;D=012341412323232341412341412341232323232341;CP=1;R=16; + ## LIBRA GmbH (LIDL) TR-502MSV + # no decode! MU;P0=-12064;P1=71;P2=-669;P3=1351;P4=-1319;D=012323414141234123232323232323232323232323; + # Ch1_off MU;P0=697;P1=-1352;P2=-679;P3=1343;D=01010101010231023232323232323232323232323;CP=0;R=27; + ## Mandolyn Funksteckdosen Set + # https://github.com/RFD-FHEM/RFFHEM/issues/716 @codeartisan-de + ## Pollin ISOTRONIC - 12 Tasten remote | model 58608 | SD_UT model QUIGG_DMV ??? + # remote basicadresse with 12bit -> changed if push reset behind battery cover + # https://github.com/RFD-FHEM/RFFHEM/issues/44 @kaihs + # Ch1_on MU;P0=-9584;P1=592;P2=-665;P3=1223;P4=-1311;D=01234141412341412341414123232323412323234;CP=1;R=0; + # Ch1_off MU;P0=-12724;P1=597;P2=-667;P3=1253;P4=-1331;D=01234141412341412341414123232323232323232;CP=1;R=0; + { + name => 'QUIGG | LIBRA | Mandolyn | Pollin ISOTRONIC', + comment => 'remote control DMV-7000, TR-502MSV, 58608', + id => '34', + knownFreqs => '433.92', + one => [-1,2], + zero => [-2,1], + start => [1], + pause => [-15], # 9900 + clockabs => '635', + format => 'twostate', + preamble => 'P34#', + clientmodule => 'SD_UT', + reconstructBit => '1', + #modulematch => '', + length_min => '19', + length_max => '20', + }, + "35" => ## Homeeasy + # off | vHE800 MS;P0=907;P1=-376;P2=266;P3=-1001;P6=-4860;D=2601010123230123012323230101012301230101010101230123012301;CP=2;SP=6; + { + name => 'HomeEasy HE800', + id => '35', + knownFreqs => '', + one => [1,-4], + zero => [3.4,-1], + sync => [1,-18], + clockabs => '280', + format => 'twostate', # not used now + preamble => 'ih', + postamble => '', + clientmodule => 'IT', + #modulematch => '', + length_min => '28', + length_max => '40', + postDemodulation => \&lib::SD_Protocols::ConvHE800, + }, + "36" => ## remote - cheap wireless dimmer + # https://forum.fhem.de/index.php/topic,38831.msg394238.html#msg394238 @Steffenm + # u36#CE8501 MU;P0=499;P1=-1523;P2=-522;P3=10220;P4=-10047;D=01020202020202020134010102020101010201020202020102010202020202020201340101020201010102010202020201020102020202020202013401010202010101020102020202010201020202020202020134010102020101010201020202020102010202020202020201340101020201010102010;CP=0;O; + # u36#CE8501 MU;P0=-520;P1=500;P2=-1523;P3=10220;P4=-10043;D=01010101210121010101010101012341212101012121210121010101012101210101010101010123412121010121212101210101010121012101010101010101234121210101212121012101010101210121010101010101012341212101012121210121010101012101210101010101010123412121010;CP=1;O; + # u36#CE8501 MU;P0=498;P1=-1524;P2=-521;P3=10212;P4=-10047;D=01010102010202020201020102020202020202013401010202010101020102020202010201020202020202020134010102020101010201020202020102010202020202020201340101020201010102010202020201020102020202020202013401010202010101020102020202010201020202020202020;CP=0;O; + { + name => 'remote', + comment => 'cheap wireless dimmer', + id => '36', + knownFreqs => '433.92', + one => [1,-3], + zero => [1,-1], + start => [20,-20], + clockabs => '500', + format => 'twostate', # not used now + preamble => 'u36#', + postamble => '', + #clientmodule => '', + #modulematch => '', + length_min => '24', + length_max => '24', + }, + "37" => ## Bresser 7009994 + # ! some message are decode as protocol 61 and protocol 84 ! + # Ch:1 T: 22.7 H: 48 Bat:ok MU;P0=729;P1=-736;P2=483;P3=-251;P4=238;P5=-491;D=010101012323452323454523454545234523234545234523232345454545232345454545452323232345232340;CP=4; + # Ch:3 T: 16.2 H: 51 Bat:ok MU;P0=-790;P1=-255;P2=474;P4=226;P6=722;P7=-510;D=721060606060474747472121212147472121472147212121214747212147474721214747212147214721212147214060606060474747472121212140;CP=4;R=216; + # short pulse of 250 us followed by a 500 us gap is a 0 bit + # long pulse of 500 us followed by a 250 us gap is a 1 bit + # sync preamble of pulse, gap, 750 us each, repeated 4 times + { + name => 'Bresser 7009994', + comment => 'temperature / humidity sensor', + id => '37', + knownFreqs => '433.92', + one => [2,-1], + zero => [1,-2], + start => [3,-3,3,-3], + clockabs => '250', + format => 'twostate', # not used now + preamble => 'W37#', + clientmodule => 'SD_WS', + length_min => '40', + length_max => '41', + }, + "38" => ## Rosenstein & Soehne, PEARL NC-3911, NC-3912, refrigerator thermometer - 2 channels + # https://github.com/RFD-FHEM/RFFHEM/issues/504 - Support for NC-3911 Fridge Temp, @MoskitoHorst, 2019-02-05 + # Id:8B Ch:1 T: 6.3 MU;P0=-747;P1=-493;P2=231;P3=484;P4=-248;P6=-982;P7=718;D=1213434212134343421342121343434343434212670707070342121213421343434212134212134212121343421213434342134212134343434343421267070707034212121342134343421213421213421212134342121343434213421213434343434342126707070703421212134213434342121342121342121;CP=2; + # Id:A8 Ch:2 T:-1.8 MU;P0=-241;P1=491;P2=249;P3=-482;P4=-962;P5=743;P6=-723;D=01023102323232310101010232323102310232323232310101010231024565656561023102310232323102310232323231010101023232310231023232323231010101023102456565656102310231023232310231023232323101010102323231023102323232323101010102310245656565610231023102323231023102;CP=2;O; + # Id:A8 Ch:2 T: 5.4 MU;P0=-971;P1=733;P2=-731;P3=488;P4=-244;P5=248;P6=-480;P7=-368;D=01212121234563456345656563456345656563456575634563456345634345656345634343434345650121212123456345634565656345634565656345656563456345634563434565634563434343434565012121212345634563456565634563456565634565656345634563456343456563456343434343456501212121;CP=5;O; + { + name => 'NC-3911', + comment => 'Refrigerator thermometer', + id => '38', + knownFreqs => '433.92', + one => [2,-1], + zero => [1,-2], + start => [3,-3,3,-3,3,-3,3,-3], + clockabs => 250, + format => 'twostate', + preamble => 'W38#', + clientmodule => 'SD_WS', + modulematch => '^W38#.*', + length_min => '36', + length_max => '36', + }, + "39" => ## X10 Protocol + # https://github.com/RFD-FHEM/RFFHEM/issues/65 @wherzig + # Closed | Bat:ok MU;P0=10530;P1=-2908;P2=533;P3=-598;P4=-1733;P5=767;D=0123242323232423242324232324232423242323232324232323242424242324242424232423242424232501232423232324232423242323242324232423232323242323232424242423242424242324232424242325012324232323242324232423232423242324232323232423232324242424232424242423242324242;CP=2;O; + { + name => 'X10 Protocol', + id => '39', + knownFreqs => '', + one => [1,-3], + zero => [1,-1], + start => [17,-7], + clockabs => 560, + format => 'twostate', + preamble => '', + clientmodule => 'RFXX10REC', + #modulematch => '^TX......', + length_min => '32', + length_max => '44', + paddingbits => '8', + postDemodulation => \&lib::SD_Protocols::postDemo_lengtnPrefix, + filterfunc => 'SIGNALduino_compPattern', + }, + "40" => ## Romotec + # ! some message are decode as protocol 19 and protocol 40 not decode ! + # https://github.com/RFD-FHEM/RFFHEM/issues/71 @111apieper + # u19#6B3190 MU;P0=300;P1=-772;P2=674;P3=-397;P4=4756;P5=-1512;D=4501232301230123230101232301010123230101230103;CP=0; + # no decode! MU;P0=-132;P1=-388;P2=675;P4=271;P5=-762;D=012145212145452121454545212145452145214545454521454545452145454541;CP=4; + { + name => 'Romotec ', + comment => 'Tubular motor', + id => '40', + knownFreqs => '', + one => [3,-2], + zero => [1,-3], + start => [1,-2], + clockabs => 270, + preamble => 'u40#', + #clientmodule => '', + #modulematch => '', + length_min => '12', + #length_max => '', # missing + }, + "41" => ## Elro (Smartwares) Doorbell DB200 / 16 melodies + # https://github.com/RFD-FHEM/RFFHEM/issues/70 @beatz0001 + # P41#F813D593 | doubleCode_part1 MS;P0=-526;P1=1450;P2=467;P3=-6949;P4=-1519;D=231010101010242424242424102424101010102410241024101024241024241010;CP=2;SP=3;O; + # P41#219D85D3 | doubleCode_part2 MS;P0=468;P1=-1516;P2=1450;P3=-533;P4=-7291;D=040101230101010123230101232323012323010101012301232323012301012323;CP=0;SP=4;O; + # unitec Modell:98156+98YK / 36 melodies + # repeats 15, change two codes every 15 repeats --> one button push, 2 codes + # P41#08E8D593 | doubleCode_part1 MS;P0=1474;P1=-521;P2=495;P3=-1508;P4=-6996;D=242323232301232323010101230123232301012301230123010123230123230101;CP=2;SP=4;R=51;m=0; + # P41#754485D3 | doubleCode_part2 MS;P1=-7005;P2=482;P3=-1511;P4=1487;P5=-510;D=212345454523452345234523232345232345232323234523454545234523234545;CP=2;SP=1;R=47;m=2; + ## KANGTAI Doorbell (Pollin 94-550405) + # https://github.com/RFD-FHEM/RFFHEM/issues/365 @trosenda + # The bell button alternately sends two different codes + # P41#BA2885D3 | doubleCode_part1 MS;P0=1390;P1=-600;P2=409;P3=-1600;P4=-7083;D=240123010101230123232301230123232301232323230123010101230123230101;CP=2;SP=4;R=248;O;m0; + # P41#1791D593 | doubleCode_part2 MS;P1=403;P2=-7102;P3=-1608;P4=1378;P5=-620;D=121313134513454545451313451313134545451345134513454513134513134545;CP=1;SP=2;R=5;O;m0; + { + name => 'wireless doorbell', + comment => 'Elro (DB200) / KANGTAI (Pollin 94-550405) / unitec', + id => '41', + knownFreqs => '433.92', + zero => [1,-3], + one => [3,-1], + sync => [1,-14], + clockabs => 500, + format => 'twostate', + preamble => 'P41#', + clientmodule => 'SD_BELL', + modulematch => '^P41#.*', + length_min => '32', + length_max => '32', + }, + "42" => ## Pollin 551227 + # https://github.com/RFD-FHEM/RFFHEM/issues/390 @trosenda + # FE1FF87 | ring MU;P0=1446;P1=-487;P2=477;D=0101012121212121212121212101010101212121212121212121210101010121212121212121212121010101012121212121212121212101010101212121212121212121210101010121212121212121212121010101012121212121212121212101010101212121212121212121210101010121212121212121212121010;CP=2;R=93;O; + # FE1FF87 | ring MU;P0=-112;P1=1075;P2=-511;P3=452;P5=1418;D=01212121232323232323232323232525252523232323232323232323252525252323232323232323232325252525;CP=3;R=77; + { + name => 'wireless doorbell', + comment => 'Pollin 551227', + id => '42', + knownFreqs => '433.92', + one => [1,-1], + zero => [3,-1], + start => [1,-1,1,-1,1,-1,], + clockabs => 500, + format => 'twostate', + preamble => 'P42#', + clientmodule => 'SD_BELL', + #modulematch => '^P42#.*', + length_min => '28', + length_max => '120', + }, + "43" => ## Somfy RTS + # https://forum.fhem.de/index.php/topic,64141.msg642800.html#msg642800 @Elektrolurch + # received=40, parsestate=on MC;LL=-1405;LH=1269;SL=-723;SH=620;D=98DBD153D631BB;C=669;L=56;R=229; + { + name => 'Somfy RTS', + id => '43', + knownFreqs => '', + clockrange => [610,680], # min , max + format => 'manchester', + preamble => 'Ys', + clientmodule => 'SOMFY', # not used now + modulematch => '^Ys[0-9A-F]{14}', + length_min => '56', + length_max => '57', + method => \&lib::SD_Protocols::mcBit2SomfyRTS, # Call to process this message + msgIntro => 'SR;P0=-2560;P1=2560;P3=-640;D=10101010101010113;', + #msgOutro => 'SR;P0=-30415;D=0;', + frequency => '10AB85550A', + }, + "44" => ## Bresser Temeo Trend + # MU;P0=32001;P1=-1939;P2=1967;P3=3896;P4=-3895;D=01213424242124212121242121242121212124212424212121212121242421212421242121242124242421242421242424242124212124242424242421212424212424212121242121212;CP=2;R=39; + { + name => 'BresserTemeo', + comment => 'temperature / humidity sensor', + id => '44', + knownFreqs => '433.92', + clockabs => 500, + zero => [4,-4], + one => [4,-8], + start => [8,-8], + preamble => 'W44#', + clientmodule => 'SD_WS', + modulematch => '^W44#[A-F0-9]{18}', + length_min => '64', + length_max => '72', + }, + "44.1" => ## Bresser Temeo Trend + { + name => 'BresserTemeo', + comment => 'temperature / humidity sensor', + id => '44', + knownFreqs => '433.92', + clockabs => 500, + zero => [4,-4], + one => [4,-8], + start => [8,-12], + preamble => 'W44x#', + clientmodule => 'SD_WS', + modulematch => '^W44x#[A-F0-9]{18}', + length_min => '64', + length_max => '72', + }, + "45" => ## Revolt + # P:126.8 E:35.88 V:232 C:0.68 Pf:0.8 MU;P0=-8320;P1=9972;P2=-376;P3=117;P4=-251;P5=232;D=012345434345434345454545434345454545454543454343434343434343434343434543434345434343434545434345434343434343454343454545454345434343454345434343434343434345454543434343434345434345454543454343434543454345434545;CP=3;R=2; + { + name => 'Revolt', + id => '45', + knownFreqs => '', + one => [2,-2], + zero => [1,-2], + start => [83,-3], + clockabs => 120, + preamble => 'r', + clientmodule => 'Revolt', + modulematch => '^r[A-Fa-f0-9]{22}', + length_min => '96', + length_max => '120', + postDemodulation => \&lib::SD_Protocols::postDemo_Revolt, + }, + "46" => ## Tedsen Fernbedienungen u.a. für Berner Garagentorantrieb GA401 und Geiger Antriebstechnik Rolladensteuerung + # https://github.com/RFD-FHEM/RFFHEM/issues/91 + # remote TEDSEN SKX1MD 433.92 MHz - 1 button | settings via 9 switch on battery compartment + # compatible with doors: BERNER SKX1MD, ELKA SKX1MD, TEDSEN SKX1LC, TEDSEN SKX1 - 1 Button + # Tedsen_SKX1xx | Button_1 MU;P0=-15829;P1=-3580;P2=1962;P3=-330;P4=245;P5=-2051;D=1234523232345234523232323234523234540 0 2345 2323 2345 2345 2323 2323 2345 2323 454 023452323234523452323232323452323454023452323234523452323232323452323454023452323234523452323232323452323454023452323234523452323;CP=2; + # Tedsen_SKX1xx | Button_1 MU;P0=-1943;P1=1966;P2=-327;P3=247;P5=-15810;D=012301212123012301212121212301212303 5 1230 1212 1230 1230 1212 1212 1230 1212 303 5 1230 1212 1230 1230 1212 1212 1230 1212 303 51230121212301230121212121230121230351230121212301230121212121230121230351230;CP=1; + ## GEIGER GF0001, 2 Button, DIP-Schalter: + 0 + - + + - 0 0 + # https://forum.fhem.de/index.php/topic,39153.0.html + # Tedsen_SKX2xx | Button_1 MU;P0=-15694;P1=2009;P2=-261;P3=324;P4=-2016;D=01212123412123434121212123434123434301212123412123434121212123434123434301212123412123434121212123434123434301212123412123434121212123434123434301212123412123434121212123434123434301;CP=3;R=30; + # Tedsen_SKX2xx | Button_2 MU;P0=-32001;P1=2072;P2=-260;P3=326;P4=-2015;P5=-15769;D=01212123412123434121212123434123412351212123412123434121212123434123412351212123412123434121212123434123412351212123412123434121212123434123412351212123412123434121212123434123412351212123412123434121212123434123412351212123412123434121212123434123412351;CP=3;R=37;O; + # ? + # P46#CC0A0 MU;P0=313;P1=1212;P2=-309;P4=-2024;P5=-16091;P6=2014;D=01204040562620404626204040404040462046204040562620404626204040404040462046204040562620404626204040404040462046204040562620404626204040404040462046204040;CP=0;R=236; + # P46#ECF20 MU;P0=-15770;P1=2075;P2=-264;P3=326;P4=-2016;P5=948;D=012121234121234341212121234341234343012125;CP=3;R=208; + { + name => 'SKXxxx, GF0x0x', + comment => 'remote controls Tedsen SKXxxx, GEIGER GF0x0x', + id => '46', + knownFreqs => '433.92', + one => [7,-1], + zero => [1,-7], + start => [-55], + clockabs => 290, + reconstructBit => '1', + format => 'tristate', # not used now + preamble => 'P46#', + clientmodule => 'SD_UT', + modulematch => '^P46#.*', + length_min => '17', # old 14 -> too short to evaluate + length_max => '18', + }, + "47" => ## Maverick ET-732, ET-733; TFA 14.1504 + # https://github.com/RFD-FHEM/RFFHEM/issues/61 + # Food: 23 BBQ: 22 MC;LL=-507;LH=490;SL=-258;SH=239;D=AA9995599599A959996699A969;C=248;L=104; + # https://github.com/RFD-FHEM/RFFHEM/issues/167 + { + name => 'Maverick', + comment => 'BBQ / food thermometer', + id => '47', + knownFreqs => '433.92', + clockrange => [180,260], + format => 'manchester', + preamble => 'P47#', + clientmodule => 'SD_WS_Maverick', + modulematch => '^P47#[569A]{12}.*', + length_min => '100', + length_max => '108', + method => \&lib::SD_Protocols::mcBit2Maverick, # Call to process this message + #polarity => 'invert' + }, + "48" => ## Joker Dostmann TFA 30.3055.01 + # ! some message are decode as protocol 42 and protocol 50 ! + # https://github.com/RFD-FHEM/RFFHEM/issues/92 @anphiga + # U48#016C7E18004C MU;P0=591;P1=-1488;P2=-3736;P3=1338;P4=-372;P6=-988;D=23406060606063606363606363606060636363636363606060606363606060606060606060606060636060636360106060606060606063606363606363606060636363636363606060606363606060606060606060606060636060636360106060606060606063606363606363606060636363636363606060606363606060;CP=0;O; + # U48#01657EB80034 MU;P0=96;P1=-244;P2=510;P3=-1000;P4=1520;P5=-1506;D=01232323232343234343232343234323434343434343234323434343232323232323232323232323234343234325232323232323232343234343232343234323434343434343234323434343232323232323232323232323234343234325232323232323232343234343232343234323434343434343234323434343232323;CP=2;O; + { + name => 'TFA Dostmann', + comment => 'Funk-Thermometer Joker TFA 30.3055.01', + id => '48', + knownFreqs => '433.92', + clockabs => 250, # In real it is 500 but this leads to unprceise demodulation + one => [-4,6], + zero => [-4,2], + start => [-6,2], + format => 'twostate', + preamble => 'U48#', + #clientmodule => '', + modulematch => '^U48#.*', + length_min => '47', + length_max => '48', + }, + "49" => ## QUIGG GT-9000, EASY HOME RCT DS1 CR-A, uniTEC 48110 and other + # The remote sends 8 messages in 2 different formats. + # SIGNALduino decodes 4 messages from remote control as MS then ... + # https://github.com/RFD-FHEM/RFFHEM/issues/667 - Oct 19, 2019 + # DMSG: 5A98B0 MS;P0=-437;P3=-1194;P4=1056;P6=297;P7=-2319;D=67634063404063406340636340406363634063404063636363;CP=6;SP=7;R=37; + # DMSG: 887F92 MS;P1=-2313;P2=1127;P3=-405;P4=379;P5=-1154;D=41234545452345454545232323232323232345452345452345;CP=4;SP=1;R=251; + # DMSG: E6D12E MS;P0=1062;P1=-1176;P2=315;P3=-2283;P4=-433;D=23040404212104042104042104212121042121042104040421;CP=2;SP=3;R=26; + { + name => 'GT-9000', + comment => 'Remote control EASY HOME RCT DS1 CR-A', + id => '49', + knownFreqs => '433.92', + clockabs => 383, + one => [3,-1], # 1150,-385 (timings from salae logic) + zero => [1,-3], # 385,-1150 (timings from salae logic) + sync => [1,-6], # 385,-2295 (timings from salae logic) + format => 'twostate', + preamble => 'P49#', + clientmodule => 'SD_GT', + modulematch => '^P49.*', + length_min => '24', + length_max => '24', + }, + "49.1" => ## QUIGG GT-9000 + # ... decodes 4 messages as MU + # https://github.com/RFD-FHEM/RFFHEM/issues/667 @Ralf9 from https://forum.fhem.de/index.php/topic,104506.msg985295.html + # DMSG: 8B2DB0 MU;P0=-563;P1=479;P2=991;P3=-423;P4=361;P5=-1053;P6=3008;P7=-7110;D=2345454523452323454523452323452323452323454545456720151515201520201515201520201520201520201515151567201515152015202015152015202015202015202015151515672015151520152020151520152020152020152020151515156720151515201520201515201520201520201520201515151;CP=1;R=21; + # DMSG: 887F90 MU;P0=-565;P1=489;P2=991;P3=-423;P4=359;P5=-1047;P6=3000;P7=-7118;D=2345454523454545452323232323232323454523454545456720151515201515151520202020202020201515201515151567201515152015151515202020202020202015152015151515672015151520151515152020202020202020151520151515156720151515201515151520202020202020201515201515151;CP=1;R=17; + { + name => 'GT-9000', + comment => 'Remote control is traded under different names', + id => '49.1', + knownFreqs => '433.92', + clockabs => 515, + one => [2,-1], # 1025,-515 (timings from salae logic) + zero => [1,-2], # 515,-1030 (timings from salae logic) + start => [6,-14], # 3075,-7200 (timings from salae logic) + format => 'twostate', + preamble => 'P49#', + clientmodule => 'SD_GT', + modulematch => '^P49.*', + length_min => '24', + length_max => '24', + }, + "49.2" => ## Tec Star Modell 2335191R + # SIGNALduino decodes 4 messages from remote control as MU then ... 49.1 + # https://forum.fhem.de/index.php/topic,43292.msg352982.html#msg352982 - Nov 01, 2015 + # message was receive with older firmware + # DMSG: CA627C MU;P0=1092;P1=-429;P2=335;P3=-1184;P4=-2316;P5=2996;D=010123230123012323010123232301232301010101012323240101232301230123230101232323012323010101010123232401012323012301232301012323230123230101010101232355;CP=2; + # DMSG: C9AFAC MU;P0=328;P1=-428;P3=1090;P4=-1190;P5=-2310;D=010131040431310431043131313131043104313104040531310404310404313104310431313131310431043131040405313104043104043131043104313131313104310431310404053131040431040431310431043131313131043104313104042;CP=0; + { + name => 'GT-9000', + comment => 'Remote control Tec Star Modell 2335191R', + id => '49.2', + knownFreqs => '433.92', + clockabs => 383, + one => [3,-1], + zero => [1,-3], + start => [1,-6], # Message is not provided as MS + format => 'twostate', + preamble => 'P49#', + clientmodule => 'SD_GT', + modulematch => '^P49.*', + length_min => '24', + length_max => '24', + }, + "50" => ## Opus XT300 + # https://github.com/RFD-FHEM/RFFHEM/issues/99 @sidey79 + # Ch:1 T: 25 H: 5 MU;P0=248;P1=-21400;P2=545;P3=-925;P4=1368;P5=-12308;D=01232323232323232343234323432343234343434343234323432343434343432323232323232323232343432323432345232323232323232343234323432343234343434343234323432343434343432323232323232323232343432323432345232323232323232343234323432343234343434343234323432343434343;CP=2;O; + # CH:1 T: 18 H: 5 W50#FF55053AFF93 MU;P2=-962;P4=508;P5=1339;P6=-12350;D=46424242424242424252425242524252425252525252425242525242424252425242424242424242424252524252524240;CP=4;R=0; + # CH:3 T: 18 H: 5 W50#FF57053AFF95 MU;P2=510;P3=-947;P5=1334;P6=-12248;D=26232323232323232353235323532323235353535353235323535323232353235323232323232323232353532353235320;CP=2;R=0; + { + name => 'Opus_XT300', + comment => 'sensor for ground humidity', + id => '50', + knownFreqs => '433.92', + clockabs => 500, + zero => [3,-2], + one => [1,-2], + # start => [-25], # Wenn das startsignal empfangen wird, fehlt das 1 bit + reconstructBit => '1', + format => 'twostate', + preamble => 'W50#', + clientmodule => 'SD_WS', + modulematch => '^W50#.*', + length_min => '47', + length_max => '48', + }, + "51" => ## weather sensors + # https://github.com/RFD-FHEM/RFFHEM/issues/118 @Stertzi + # IAN 275901 Id:08 Ch:3 T:6.3 H:95 MS;P0=-4074;P1=608;P2=-1825;P3=-15980;P4=1040;P5=-975;P6=-7862;D=16121212121012121212101212101212101210121012121010121010121012121012101210121210101345454545;CP=1;SP=6; + # IAN 275901 Id:08 Ch:3 T:8.5 H:95 MS;P0=611;P1=-4073;P2=-1825;P3=-15980;P4=1041;P5=-974;P6=-7860;D=06020202020102020202020201010202010201020102010201010102010102020102010201020201010345454545;CP=0;SP=6; + # https://github.com/RFD-FHEM/RFFHEM/issues/122 @6040 + # IAN 114324 Id:11 Ch:1 T:17.3 H:40 MS;P0=-1848;P1=577;P2=-4066;P3=-15997;P4=1013;P5=-1001;P6=-7875;D=16101010121010101210101210101012101012101212121212121012121012101010101010101010121345454545;CP=1;SP=6;O; + # IAN 114324 Id:71 Ch:1 T:17.3 H:41 MS;P0=-16000;P1=1002;P2=-1010;P3=572;P4=-7884;P5=-1817;P6=-4102;D=34353636363535353635363535353535353536353636363636363536363536353535353536353535363012121212;CP=3;SP=4;O; + # https://github.com/RFD-FHEM/RFFHEM/issues/161 + # IAN 60107 Id:F0 Ch:1 T:-2.9 H:76 MS;P2=594;P3=-7386;P4=-4081;P5=-1873;D=2324242424252525252525242425252525252425252425252524242424252424242524242525252524;CP=2;SP=3;R=242; + # IAN 60107 Id:F0 Ch:1 T:0.9 H:81 MS;P2=604;P3=-7258;P4=-4179;P5=-1852;D=2324242424252525252525242525252524252425252424252425242524242525252525252425252524;CP=2;SP=3;R=242; + # IAN 60107 Id:F0 Ch:1 T:13.6 H:51 MS;P2=634;P3=-8402;P4=-4079;P5=-1832;D=2324242424252525252425252425252524252425242425242424252524252425242525252425252524;CP=2;SP=3;R=244; + { + name => 'weather', + comment => 'Lidl Weatherstation IAN60107, IAN 114324, IAN 275901', + id => '51', + knownFreqs => '433.92', + one => [1,-8], + zero => [1,-4], + sync => [1,-16], + clockabs => '500', + format => 'twostate', # not used now + preamble => 'W51#', + postamble => '', + clientmodule => 'SD_WS', + modulematch => '^W51#.*', + length_min => '40', + length_max => '45', + }, + "52" => ## Oregon Scientific PIR Protocol + # https://forum.fhem.de/index.php/topic,63604.msg548256.html#msg548256 @Ralf_W. + # u52#00012AE7 MC;LL=-1045;LH=1153;SL=-494;SH=606;D=FFFED518;C=549;L=30; + ## note: unfortunately, the user is no longer in possession of a SIGNALduino + # + # FFFED5 = Adresse, die per DIP einstellt wird, FFF ändert sich nie + # 1 = Kanal, per gesondertem DIP, bei mir bei beiden 1 (CH 1) oder 3 (CH 2) + # C = wechselt, 0, 4, 8, C - dann fängt es wieder mit 0 an und wiederholt sich bei jeder Bewegung + { + name => 'Oregon Scientific PIR', + comment => 'JMR868 / NR868', + id => '52', + knownFreqs => '433.92', + clockrange => [470,640], # min , max + format => 'manchester', # tristate can't be migrated from bin into hex! + #clientmodule => '', # OREGON module not for Motion Detectors + modulematch => '^u52#F{3}|0{3}.*', + preamble => 'u52#', + length_min => '30', + length_max => '30', + method => \&lib::SD_Protocols::mcBit2OSPIR, # Call to process this message + polarity => 'invert', + }, + "53" => ## Lidl AURIOL AHFL 433 B2 IAN 314695 + # https://github.com/RFD-FHEM/RFFHEM/issues/663 @Kreidler1221 05.10.2019 + # IAN 314695 Id:07 Ch:1 T:24.2 H:59 MS;P1=611;P2=-2075;P3=-4160;P4=-9134;D=14121212121213131312121212121212121313131312121312121313131213131212131212131213121213;CP=1;SP=4;R=0;O;m2; + # IAN 314695 Id:07 Ch:1 T:22.3 H:61 MS;P1=608;P2=-2074;P3=-4138;P4=-9138;D=14121212121213131312121212121212121313121313131313121313131312131212131212131313121212;CP=1;SP=4;R=0;O;m1; + # IAN 314695 Id:07 Ch:2 T:18.4 H:70 MS;P0=606;P1=-2075;P2=-4136;P3=-9066;D=03010101010102020201010102010101010201020202010101020101010202010101020101020201010202;CP=0;SP=3;R=0;O;m2; + { + name => 'AHFL 433 B2', + comment => 'Auriol weatherstation IAN 314695', + id => '53', + knownFreqs => '433.92', + one => [1,-7], + zero => [1,-3.5], + sync => [1,-15], + clockabs => 600, + format => 'twostate', # not used now + preamble => 'W53#', + clientmodule => 'SD_WS', + modulematch => '^W53#.*', + length_min => '42', + length_max => '44', + }, + "54" => ## TFA Drop 30.3233.01 - Rain gauge + # Rain sensor 30.3233.01 for base station 47.3005.01 + # https://github.com/merbanan/rtl_433/blob/master/src/devices/tfa_drop_30.3233.c | https://forum.fhem.de/index.php/topic,107998.0.html @sido + # @sido + # SD_WS_54_R_D9C43 R: 73.66 MU;P1=247;P2=-750;P3=722;P4=-489;P5=491;P6=-236;P7=-2184;D=1232141456565656145656141456565614141456141414145656141414141456561414141456561414145614561456145614141414141414145614145656145614141732321414565656561456561414565656141414561414141456561414141414565614141414565614141456145614561456141414141414141456141;CP=1;R=55;O; + # SD_WS_54_R_D9C43 R: 74.422 MU;P0=-1672;P1=740;P2=-724;P3=260;P4=-468;P5=504;P6=-230;D=012123434565656563456563434565656343434563434343456563434343456345634343434565634565656345634563456343434343434343456563434345634345656;CP=3;R=4; + # @punker + # SD_WS_54_R_896E1 R: 28.702 MU;P0=-242;P1=-2076;P2=-13292;P3=242;P4=-718;P5=748;P6=-494;P7=481;CP=3;R=29;D=23454363670707036363670363670367070367070703636363670363636363670363636707036367070707036703670367036363636363636363636707036703636363154543636707070363636703636703670703670707036363636703636363636703636367070363670707070367036703670363636363636363636367;O; + # SD_WS_54_R_896E1 R: 29.464 MU;P0=-236;P1=493;P2=235;P3=-503;P4=-2076;P5=734;P6=-728;CP=2;R=11;D=0101023101023245656232310101023232310232310231010231010102323232310232323232310102323101023102310231023102310231023232323232323232323101010231010232;e;i; + { + name => 'TFA 30.3233.01', + comment => 'Rain sensor', + id => '54', + knownFreqs => '433.92', + one => [2,-1], + zero => [1,-2], + start => [3,-3], # message provided as MU + clockabs => 250, + reconstructBit => '1', + clientmodule => 'SD_WS', + format => 'twostate', + preamble => 'W54#', + length_min => '64', + length_max => '68', + }, + "54.1" => ## TFA Drop 30.3233.01 - Rain gauge + # Rain sensor 30.3233.01 for base station 47.3005.01 + # https://github.com/merbanan/rtl_433/blob/master/src/devices/tfa_drop_30.3233.c | https://forum.fhem.de/index.php/topic,107998.0.html @punker + # @punker + # SD_WS_54_R_896E1 R: 28.702 MS;P0=-241;P1=486;P2=241;P3=-488;P4=-2098;P5=738;P6=-730;D=24565623231010102323231023231023101023101010232323231023232323231023232310102323101010102310231023102323232323232323232310102310232323;CP=2;SP=4;R=30;O;b=19;s=1;m0; + # SD_WS_54_R_896E1 R: 29.464 MS;P0=-491;P1=242;P2=476;P3=-248;P4=-2096;P5=721;P6=-745;D=14565610102323231010102310102310232310232323101010102310101010102323101023231023102310231023102310231010101010101010101023232310232310;CP=1;SP=4;R=10;O;b=135;s=1;m0; + { + name => 'TFA 30.3233.01', + comment => 'Rain sensor', + id => '54.1', + knownFreqs => '433.92', + one => [2,-1], + zero => [1,-2], + sync => [3,-3], # message provided as MS + clockabs => 250, + clientmodule => 'SD_WS', + format => 'twostate', + preamble => 'W54#', + length_min => '64', + length_max => '68', + }, + "55" => ## QUIGG GT-1000 + { + name => 'QUIGG_GT-1000', + comment => 'remote control', + id => '55', + knownFreqs => '', + clockabs => 300, + zero => [1,-4], + one => [4,-2], + sync => [1,-8], + format => 'twostate', + preamble => 'i', + clientmodule => 'IT', + modulematch => '^i.*', + length_min => '24', + length_max => '24', + }, + "56" => ## Celexon Motorleinwand + # https://forum.fhem.de/index.php/topic,52025.0.html @Horst12345 + # AC114_01B_00587B down MU;P0=5036;P1=-624;P2=591;P3=-227;P4=187;P5=-5048;D=0123412341414123234141414141414141412341232341414141232323234123234141414141414123414141414141414141234141414123234141412341232323250123412341414123234141414141414141412341232341414141232323234123234141414141414123414141414141414141234141414123234141412;CP=4;O; + # Alphavision Slender Line Plus motor canvas, remote control AC114-01B from Shenzhen A-OK Technology Grand Development Co. + # https://github.com/RFD-FHEM/RFFHEM/issues/906 @TheChatty + # AC114_01B_479696 up MU;P0=-16412;P1=5195;P2=-598;P3=585;P4=-208;P5=192;D=01234523452525234345234525252343434345252345234345234525234523434525252525252525234525252525252525252525252345234345234343434343434341234523452525234345234525252343434345252345234345234525234523434525252525252525234525252525252525252525252345234345234343;CP=5;R=105;O; + # AC114_01B_479696 stop MU;P0=-2341;P1=5206;P2=-571;P3=591;P4=-211;P5=207;D=01234523452525234345234525252343434345252345234345234525234523434525252525252525234525252525252525252523452525234343452523452343434341234523452525234345234525252343434345252345234345234525234523434525252525252525234525252525252525252523452525234343452523;CP=5;R=107;O; + { + name => 'AC114-xxB', + comment => 'Remote control for motorized screen from Alphavision, Celexon', + id => '56', + knownFreqs => '433.92', + zero => [1,-3], # 200,-600 + one => [3,-1], # 600,-200 + start => [25,-3], # 5000,-600 + pause => [-25], # -5000, pause between repeats of send messages (clockabs*pause must be < 32768) + clockabs => 200, + reconstructBit => '1', + format => 'twostate', + preamble => 'P56#', + clientmodule => 'SD_UT', + modulematch => '^P56#', + length_min => '64', # 65 - reconstructBit = 64 + length_max => '65', # normal 65 Bit, 3 Bit werden aufgefuellt + }, + "57" => ## m-e doorbell fuer FG- und Basic-Serie + # https://forum.fhem.de/index.php/topic,64251.0.html @rippi46 + # P57#2AA4A7 | ring MC;LL=-653;LH=665;SL=-317;SH=348;D=D55B58;C=330;L=21; + # P57#2AA4A7 | ring MC;LL=-654;LH=678;SL=-314;SH=351;D=D55B58;C=332;L=21; + # P57#2AA4A7 | ring MC;LL=-653;LH=679;SL=-310;SH=351;D=D55B58;C=332;L=21; + { + name => 'm-e', + comment => 'radio gong transmitter for FG- and Basic-Serie', + id => '57', + knownFreqs => '', + clockrange => [300,360], # min , max + format => 'manchester', # tristate can't be migrated from bin into hex! + clientmodule => 'SD_BELL', + modulematch => '^P57#.*', + preamble => 'P57#', + length_min => '21', + length_max => '24', + method => \&lib::SD_Protocols::MCRAW, # Call to process this message + polarity => 'invert', + }, + "58" => ## TFA 30.3208.02, 30.3228.02, 30.3229.02, Froggit/Renkforce FT007TH, FT007PF, FT007T, FT007TP, Ambient Weather F007-TH, F007-T, F007-TP + # SD_WS_58_TH_200_2 Ch: 2 T: 18.9 H: 69 Bat: ok MC;LL=-981;LH=964;SL=-480;SH=520;D=002BA37EBDBBA24F0015D1BF5EDDD127800AE8DFAF6EE893C;C=486;L=194; + # Froggit FT007T - https://forum.fhem.de/index.php/topic,58397.msg1023517.html#msg1023517 + # SD_WS_58_T_135_2 Ch: 2 T: 22.2 Bat: ok MC;LL=-1047;LH=903;SL=-545;SH=449;D=800AE5E3AE7FD44BC00572F1D73FEA25E002B9788;C=494;L=161; + # SD_WS_58_T_135_2 Ch: 2 T: 22.3 Bat: ok MC;LL=-1047;LH=902;SL=-546;SH=452;D=0015CBC75CF7AA8F800AE5E3AE7BD547C00572F1D0;C=487;L=165; + # Renkforce FT007TH - https://forum.fhem.de/index.php/topic,65680.msg963889.html#msg963889 + # SD_WS_58_TH_84_2 Ch: 2 T: 23.9 H: 58 Bat: ok MC;LL=-1005;LH=946;SL=-505;SH=496;D=0015D55F5C0E2B47800AEAAFAE0715A3C0057557D7;C=487;L=168;R=0; + { + name => 'TFA 30.3208.0', + comment => 'Temperature/humidity sensors (TFA 30.3208.02, 30.3228.02, 30.3229.02, Froggit/Renkforce FT007xx, Ambient Weather F007-xx)', + id => '58', + knownFreqs => '433.92', + clockrange => [460,520], + format => 'manchester', + clientmodule => 'SD_WS', + modulematch => '^W58*', + preamble => 'W58#', + length_min => '52', # 54 + length_max => '52', # 136 + method => \&lib::SD_Protocols::mcBit2TFA, + polarity => 'invert', + }, + "59" => ## AK-HD-4 remote | 4 Buttons + # https://github.com/RFD-FHEM/RFFHEM/issues/133 @stevedee78 + # u59#6DCAFB MU;P0=819;P1=-919;P2=234;P3=-320;P4=8602;P6=156;D=01230301230301230303012123012301230303030301230303412303012303012303030121230123012303030303012303034123030123030123030301212301230123030303030123030341230301230301230303012123012301230303030301230303412303012303012303030121230123012303030303012303034163;CP=0;O; + # u59#6DCAFB MU;P0=-334;P2=8581;P3=237;P4=-516;P5=782;P6=-883;D=23456305056305050563630563056305050505056305050263050563050563050505636305630563050505050563050502630505630505630505056363056305630505050505630505026305056305056305050563630563056305050505056305050263050563050563050505636305630563050505050563050502630505;CP=5;O; + { + name => 'AK-HD-4', + comment => 'remote control with 4 buttons', + id => '59', + knownFreqs => '433.92', + clockabs => 230, + zero => [-4,1], + one => [-1,4], + start => [-1,37], + format => 'twostate', # tristate can't be migrated from bin into hex! + preamble => 'u59#', + postamble => '', + #clientmodule => '', + #modulematch => '', + length_min => '24', + length_max => '24', + }, + "60" => ## ELV, LA CROSSE (WS2000/WS7000) + # Id:11 T: 21.3 MU;P0=32001;P1=-381;P2=835;P3=354;P4=-857;D=01212121212121212121343421212134342121213434342121343421212134213421213421212121342121212134212121213421212121343421343430;CP=2;R=53; + # tested sensors: WS-7000-20, AS2000, ASH2000, S2000, S2000I, S2001A, S2001IA, + # ASH2200, S300IA, S2001I, S2000ID, S2001ID, S2500H + # not tested: AS3, S2000W, S2000R, WS7000-15, WS7000-16, WS2500-19, S300TH, S555TH + # das letzte Bit (1) und mehrere Bit (0) Preambel fehlen meistens + # ___ _ + # | |_ | |___ + # Bit 0 Bit 1 + # kurz 366 mikroSek / lang 854 mikroSek / gesamt 1220 mikroSek - Sollzeiten + { + name => 'WS2000', + comment => 'Series WS2000/WS7000 of various sensors', + id => '60', + knownFreqs => '', + one => [3,-7], + zero => [7,-3], + clockabs => 122, + preamble => 'K', + postamble => '', + clientmodule => 'CUL_WS', + length_min => '38', # 46, letztes Bit fehlt = 45, 10 Bit Preambel = 35 Bit Daten + length_max => '82', + postDemodulation => \&lib::SD_Protocols::postDemo_WS2000, + }, + "61" => ## ELV FS10 + # tested transmitter: FS10-S8, FS10-S4, FS10-ZE + # tested receiver: FS10-ST, FS10-MS, WS3000-TV, PC-Wettersensor-Empfaenger + # sends 2 messages with 43 or 48 bits in distance of 100 mS (on/off) , last bit 1 is missing + # sends x messages with 43 or 48 bits in distance of 200 mS (dimm) , repeats second message + # 2_13 | on MU;P0=1776;P1=-410;P2=383;P3=-820;D=01212121212121212121212123212121232323212323232121212323232121212321212123232123212120;CP=2;R=74; + # __ __ + # | |__ | |____ + # Bit 0 Bit 1 + # kurz 400 mikroSek / lang 800 mikroSek / gesamt 800 mikroSek = 0, gesamt 1200 mikroSek = 1 - Sollzeiten + { + name => 'FS10', + comment => 'remote control', + id => '61', + knownFreqs => '433.92', + one => [1,-2], + zero => [1,-1], + clockabs => 400, + pause => [-81], # 400*81=32400*6=194400 - pause between repeats of send messages (clockabs*pause must be < 32768) + format => 'twostate', + preamble => 'P61#', + postamble => '', + clientmodule => 'FS10', + length_min => '30', # 43-1=42 (letztes Bit fehlt) 42-12=30 (12 Bit Preambel) + length_max => '48', # eigentlich 46 + }, + "62" => ## Clarus_Switch + # ! some message are decode as protocol 32 ! + # Unknown code i415703, help me! MU;P0=-5893;P4=-634;P5=498;P6=-257;P7=116;D=45656567474747474745656707456747474747456745674567456565674747474747456567074567474747474567456745674565656747474747474565670745674747474745674567456745656567474747474745656707456747474747456745674567456565674747474747456567074567474747474567456745674567;CP=7;O; + { + name => 'Clarus_Switch', + id => '62', + knownFreqs => '', + one => [3,-1], + zero => [1,-3], + start => [1,-35], # ca 30-40 + clockabs => 189, + preamble => 'i', + clientmodule => 'IT', + #modulematch => '', + length_min => '24', + length_max => '24', + }, + "63" => ## Warema MU + # https://forum.fhem.de/index.php/topic,38831.msg395978/topicseen.html#msg395978 @Totte10 | https://www.mikrocontroller.net/topic/264063 + # no decode! MU;P0=-2988;P1=1762;P2=-1781;P3=-902;P4=871;P5=6762;P6=5012;D=0121342434343434352434313434243521342134343436; + # no decode! MU;P0=6324;P1=-1789;P2=864;P3=-910;P4=1756;D=0123234143212323232323032321234141032323232323232323;CP=2; + { + name => 'Warema', + comment => 'radio shutter switch (is still experimental)', + id => '63', + knownFreqs => '', + developId => 'y', + one => [1], + zero => [0], + clockabs => 800, + syncabs => '6700', # Special field for filterMC function + preamble => 'u63#', + #clientmodule => '', + #modulematch => '', + length_min => '24', + #length_max => '', # missing + filterfunc => 'SIGNALduino_filterMC', + }, + "64" => ## Fine Offset Electronics WH2, WH2A Temperature/Humidity sensor + # T: 17.4 H: 74 MU;P0=-28888;P1=461;P2=-1012;P3=1440;D=01212121212121232123232123212121232121232323232123212321212123232123232123212323232321212123232323232321212121;CP=1;R=202; + # T: 28.3 H: 42 MU;P0=-25696;P1=479;P2=-985;P3=1461;D=01212121212121232123232123212121232121232323212323232121232121232321232123212323232323232121212321232321232323;CP=1;R=215; + # T: 23 H: 64 MU;P0=134;P1=-113;P3=412;P4=-1062;P5=1379;D=01010101013434343434343454345454345454545454345454545454343434545434345454345454545454543454543454345454545434545454345;CP=3; + { + name => 'WH2', + comment => 'temperature / humidity sensor', + id => '64', + knownFreqs => '433.92', + one => [1,-2], + zero => [3,-2], + clockabs => 490, + clientmodule => 'SD_WS', + modulematch => '^W64*', + preamble => 'W64#', + clientmodule => 'SD_WS', + length_min => '48', + length_max => '56', + }, + "65" => ## Homeeasy + # on | vHE_EU MS;P1=231;P2=-1336;P4=-312;P5=-8920;D=15121214141412121212141414121212121414121214121214141212141212141212121414121414141212121214141214121212141412141212;CP=1;SP=5; + { + name => 'HomeEasy HE_EU', + id => '65', + knownFreqs => '', + one => [1,-5.5], + zero => [1,-1.2], + sync => [1,-38], + clockabs => 230, + format => 'twostate', # not used now + preamble => 'ih', + clientmodule => 'IT', + length_min => '57', + length_max => '72', + postDemodulation => \&lib::SD_Protocols::ConvHE_EU, + }, + "66" => ## TX2 Protocol (Remote Temp Transmitter & Remote Thermo Model 7035) + # https://github.com/RFD-FHEM/RFFHEM/issues/160 @elektron-bbs + # Id:66 T: 23.2 MU;P0=13312;P1=-2785;P2=4985;P3=1124;P4=-6442;P5=3181;P6=-31980;D=0121345434545454545434545454543454545434343454543434545434545454545454343434545434343434545621213454345454545454345454545434545454343434545434345454345454545454543434345454343434345456212134543454545454543454545454345454543434345454343454543454545454545;CP=3;R=73;O; + # Id:49 T: 25.2 MU;P0=32001;P1=-2766;P2=4996;P3=1158;P4=-6416;P5=3203;P6=-31946;D=01213454345454545454543434545454345454343434543454345454345454545454543434345434543434345456212134543454545454545434345454543454543434345434543454543454545454545434343454345434343454562121345434545454545454343454545434545434343454345434545434545454545454;CP=3;R=72;O; + { + name => 'WS7035', + comment => 'temperature sensor', + id => '66', + knownFreqs => '', + one => [10,-52], + zero => [27,-52], + start => [-21,42,-21], + clockabs => 122, + reconstructBit => '1', + format => 'pwm', # not used now + preamble => 'TX', + clientmodule => 'CUL_TX', + modulematch => '^TX......', + length_min => '43', + length_max => '44', + postDemodulation => \&lib::SD_Protocols::postDemo_WS7035, + }, + "67" => ## TX2 Protocol (Remote Datalink & Remote Thermo Model 7053, 7054) + # https://github.com/RFD-FHEM/RFFHEM/issues/162 @elektron-bbs + # Id:72 T: 26.0 MU;P0=3381;P1=-672;P2=-4628;P3=1142;P4=-30768;D=010 2320232020202020232020232020202320232323202323202020202020202020 4 010 2320232020202020232020232020202320232323202323202020202020202020 0;CP=0;R=45; + # Id:72 T: 24.3 MU;P0=1148;P1=3421;P6=-664;P7=-4631;D=161 7071707171717171707171707171717171707070717071717171707071717171 0;CP=1;R=29; + # Message repeats 4 x with pause of ca. 30-34 mS + # __ ____ + # ________| | ________| | + # Bit 1 Bit 0 + # 4630 1220 4630 3420 mikroSek - mit Oszi gemessene Zeiten + { + name => 'WS7053', + comment => 'temperature sensor', + id => '67', + knownFreqs => '', + one => [-38,10], # -4636, 1220 + zero => [-38,28], # -4636, 3416 + clockabs => 122, + preamble => 'TX', + clientmodule => 'CUL_TX', + modulematch => '^TX......', + length_min => '32', + length_max => '34', + postDemodulation => \&lib::SD_Protocols::postDemo_WS7053, + }, + "68" => ## Medion OR28V RF Vista Remote Control (Made in china by X10) + # sendet zwei verschiedene Codes pro Taste + # Taste ok 739E0 MS;P1=-1746;P2=513;P3=-571;P4=-4612;P5=2801;D=24512321212123232121212323212121212323232323;CP=2;SP=4;R=58;#;#; + # Taste ok F31E0 MS;P1=-1712;P2=518;P3=-544;P4=-4586;P5=2807;D=24512121212123232121232323212121212323232323;CP=2;SP=4;R=58;m2;#;#; + # Taste Vol+ E00B0 MS;P1=-1620;P2=580;P3=-549;P4=-4561;P5=2812;D=24512121212323232323232323232123212123232323;CP=2;SP=4;R=69;O;m2;#;#; + # Taste Vol+ 608B0 MS;P1=-1645;P2=574;P3=-535;P4=-4556;P5=2811;D=24512321212323232323212323232123212123232323;CP=2;SP=4;R=57;m2;#;#; + { + name => 'OR28V', + comment => 'Medion OR28V RF Vista Remote Control', + id => '68', + knownFreqs => '433.92', + one => [1,-3], + zero => [1,-1], + sync => [1,-8,5,-3], + clockabs => 550, + format => 'twostate', + preamble => 'P68#', + clientmodule => 'SD_UT', + modulematch => '^P68#.{5}', + length_min => '20', + length_max => '20', + }, + "69" => ## Hoermann HSM2, HSM4, HS1-868-BS (868 MHz) + # https://github.com/RFD-FHEM/RFFHEM/issues/149 + # HSM4 | button_1 MU;P0=-508;P1=1029;P2=503;P3=-1023;P4=12388;D=01010232323232310104010101010101010102323231010232310231023232323231023101023101010231010101010232323232310104010101010101010102323231010232310231023232323231023101023101010231010101010232323232310104010101010101010102323231010232310231023232323231023101;CP=2;R=37;O; + # Remote control HS1-868-BS (one button): + # https://github.com/RFD-FHEM/RFFHEM/issues/344 + # HS1_868_BS | receive MU;P0=-578;P1=1033;P2=506;P3=-1110;P4=13632;D=0101010232323101040101010101010101023232323102323101010231023102310231010232323101010101010101010232323101040101010101010101023232323102323101010231023102310231010232323101010101010101010232323101040101010101010101023232323102323101010231023102310231010;CP=2;R=77; + # HS1_868_BS | receive MU;P0=-547;P1=1067;P2=553;P3=-1066;P4=13449;D=0101010101010232323101040101010101010101023232323102323101010231023102310231010232323101010101010101010232323101040101010101010101023232323102323101010231023102310231010232323101010101010101010232323101040101010101010101023232323102323101010231023102310;CP=2;R=71; + # https://forum.fhem.de/index.php/topic,71877.msg642879.html (HSM4, Taste 1-4) + # HSM4 | button_1 MU;P0=-332;P1=92;P2=-1028;P3=12269;P4=-510;P5=1014;P6=517;D=01234545454545454545462626254546262546254626262626254625454625454546254545454546262626262545434545454545454545462626254546262546254626262626254625454625454546254545454546262626262545434545454545454545462626254546262546254626262626254625454625454546254545;CP=6;R=37;O; + # HSM4 | button_2 MU;P0=509;P1=-10128;P2=1340;P3=-517;P4=1019;P5=-1019;P6=12372;D=01234343434343434343050505434305054305430505050505430543430543434305434343430543050505054343634343434343434343050505434305054305430505050505430543430543434305434343430543050505054343634343434343434343050505434305054305430505050505430543430543434305434343;CP=0;R=52;O; + # HSM4 | button_3 MU;P0=12376;P1=360;P2=-10284;P3=1016;P4=-507;P6=521;P7=-1012;D=01234343434343434343467676734346767346734676767676734673434673434346734343434676767346767343404343434343434343467676734346767346734676767676734673434673434346734343434676767346767343404343434343434343467676734346767346734676767676734673434673434346734343;CP=6;R=55;O; + # HSM4 | button_4 MU;P0=-3656;P1=12248;P2=-519;P3=1008;P4=506;P5=-1033;D=01232323232323232324545453232454532453245454545453245323245323232453232323245453245454532321232323232323232324545453232454532453245454545453245323245323232453232323245453245454532321232323232323232324545453232454532453245454545453245323245323232453232323;CP=4;R=48;O; + { + name => 'Hoermann', + comment => 'remote control HS1-868-BS, HSM4', + id => '69', + knownFreqs => '433.92 | 868.35', + zero => [2,-1], # 1020,510 + one => [1,-2], # 510,1020 + start => [25,-1], # 12750,510 + clockabs => 510, + format => 'twostate', + clientmodule => 'SD_UT', + modulematch => '^P69#.{11}', + preamble => 'P69#', + length_min => '44', + length_max => '44', + }, + "70" => ## FHT80TF (Funk-Tuer-Fenster-Melder FHT 80TF und FHT 80TF-2) + # https://github.com/RFD-FHEM/RFFHEM/issues/171 @HomeAutoUser + # closed MU;P0=-24396;P1=417;P2=-376;P3=610;P4=-582;D=012121212121212121212121234123434121234341212343434121234123434343412343434121234341212121212341212341234341234123434;CP=1;R=35; + # open MU;P0=-21652;P1=429;P2=-367;P4=634;P5=-555;D=012121212121212121212121245124545121245451212454545121245124545454512454545121245451212121212124512451245451245121212;CP=1;R=38; + { + name => 'FHT80TF', + comment => 'door/window switch', + id => '70', + knownFreqs => '868.35', + one => [1.5,-1.5], # 600 + zero => [1,-1], # 400 + clockabs => 400, + format => 'twostate', # not used now + clientmodule => 'CUL_FHTTK', + preamble => 'T', + length_min => '50', + length_max => '58', + postDemodulation => \&lib::SD_Protocols::postDemo_FHT80TF, + }, + "71" => ## PEARL infactory Poolthermometer (PV-8644) + # Ch:1 T: 24.2 MU;P0=1735;P1=-1160;P2=591;P3=-876;D=0123012323010101230101232301230123010101010123012301012323232323232301232323232323232323012301012;CP=2;R=97; + { + name => 'PEARL', + comment => 'infactory Poolthermometer (PV-8644)', + id => '71', + knownFreqs => '433.92', + clockabs => 580, + zero => [3,-2], + one => [1,-1.5], + format => 'twostate', + preamble => 'W71#', + clientmodule => 'SD_WS', + #modulematch => '^W71#.*' + length_min => '48', + length_max => '48', + }, + "72" => ## Siro blinds MU @Dr.Smag + # ! same definition how ID 16 ! + # module ERROR after delete and parse without save!!! + # >Siro_5B417081< returned by the Siro ParseFn is invalid, notify the module maintainer + # https://forum.fhem.de/index.php?topic=77167.0 + # MU;P0=-760;P1=334;P2=693;P3=-399;P4=-8942;P5=4796;P6=-1540;D=01010102310232310101010102310232323101010102310101010101023102323102323102323102310101010102310232323101010102310101010101023102310231023102456102310232310232310231010101010231023232310101010231010101010102310231023102310245610231023231023231023101010101;CP=1;R=45;O; + # MU;P0=-8848;P1=4804;P2=-1512;P3=336;P4=-757;P5=695;P6=-402;D=0123456345656345656345634343434345634565656343434345634343434343456345634563456345;CP=3;R=49; + { + name => 'Siro shutter', + comment => 'message decode as MU', + id => '72', + knownFreqs => '', + dispatchequals => 'true', + one => [2,-1.2], # 680, -400 + zero => [1,-2.2], # 340, -750 + start => [14,-4.4], # 4800,-1520 + clockabs => 340, + format => 'twostate', + preamble => 'P72#', + clientmodule => 'Siro', + #modulematch => '', + length_min => '39', + length_max => '40', + msgOutro => 'SR;P0=-8500;D=0;', + }, + "72.1" => ## Siro blinds MS @Dr.Smag + # Id:5B41708 state:0 MS;P0=4803;P1=-1522;P2=333;P3=-769;P4=699;P5=-393;P6=-9190;D=2601234523454523454523452323232323452345454523232323452323232323234523232345454545;CP=2;SP=6;R=61; + { + name => 'Siro shutter', + comment => 'message decode as MS', + id => '72', + knownFreqs => '', + developId => 'm', + dispatchequals => 'true', + one => [2,-1.2], # 680, -400 + zero => [1,-2.2], # 340, -750 + sync => [14,-4.4], # 4800,-1520 + clockabs => 340, + format => 'twostate', + preamble => 'P72#', + clientmodule => 'Siro', + #modulematch => '', + length_min => '39', + length_max => '40', + #msgOutro => 'SR;P0=-8500;D=0;', + }, + "73" => ## FHT80 - Raumthermostat (868Mhz) @HomeAutoUser + # actuator:0% MU;P0=136;P1=-112;P2=631;P3=-392;P4=402;P5=-592;P6=-8952;D=0123434343434343434343434325434343254325252543432543434343434325434343434343434343254325252543254325434343434343434343434343252525432543464343434343434343434343432543434325432525254343254343434343432543434343434343434325432525254325432543434343434343434;CP=4;R=250; + { + name => 'FHT80', + comment => 'roomthermostat (only receive)', + id => '73', + knownFreqs => '868.35', + one => [1.5,-1.5], # 600 + zero => [1,-1], # 400 + pause => [-25], + clockabs => 400, + format => 'twostate', # not used now + clientmodule => 'FHT', + preamble => '810c04xx0909a001', + length_min => '59', + length_max => '67', + postDemodulation => \&lib::SD_Protocols::postDemo_FHT80, + }, + "74" => ## FS20 - Remote Control (868Mhz) @HomeAutoUser + # dim100% MU;P0=-10420;P1=-92;P2=398;P3=-417;P5=596;P6=-592;D=1232323232323232323232323562323235656232323232356232356232623232323232323232323232323235623232323562356565623565623562023232323232323232323232356232323565623232323235623235623232323232323232323232323232323562323232356235656562356562356202323232323232323;CP=2;R=72; + { + name => 'FS20', + comment => 'remote control (decode as MU)', + id => '74', + knownFreqs => '868.35', + one => [1.5,-1.5], # 600 + zero => [1,-1], # 400 + pause => [-25], + clockabs => 400, + #reconstructBit => '1', + format => 'twostate', # not used now + clientmodule => 'FS20', + preamble => '810b04f70101a001', + length_min => '50', + length_max => '67', + postDemodulation => \&lib::SD_Protocols::postDemo_FS20, + }, + "74.1" => ## FS20 - Remote Control (868Mhz) @HomeAutoUser + # dim100% MS;P1=-356;P2=448;P3=653;P4=-551;P5=-10412;D=2521212121212121212121212134212121343421212121213421213421212121212121212121212121212121342121212134213434342134342134;CP=2;SP=5;R=72;O;!;4; + { + name => 'FS20', + comment => 'remote control (decode as MS)', + id => '74.1', + knownFreqs => '868.35', + one => [1.5,-1.5], # 600 + zero => [1,-1], # 400 + sync => [-25], + clockabs => 400, + #reconstructBit => '1', + format => 'twostate', # not used now + clientmodule => 'FS20', + preamble => '810b04f70101a001', + paddingbits => '1', # disable padding + length_min => '50', + length_max => '67', + postDemodulation => \&lib::SD_Protocols::postDemo_FS20, + }, + "75" => ## Conrad RSL (Erweiterung v2) @litronics https://github.com/RFD-FHEM/SIGNALDuino/issues/69 + # ! same definition how ID 5, but other length ! + # !! protocol needed revision - start or sync failed !! https://github.com/RFD-FHEM/SIGNALDuino/issues/69#issuecomment-440349328 + # on MU;P0=-1365;P1=477;P2=1145;P3=-734;P4=-6332;D=01023202310102323102423102323102323101023232323101010232323231023102323102310102323102423102323102323101023232323101010232323231023102323102310102323102;CP=1;R=12; + { + name => 'Conrad RSL v2', + comment => 'remotes and switches', + id => '75', + knownFreqs => '', + one => [3,-1], + zero => [1,-3], + clockabs => 500, + format => 'twostate', + developId => 'y', + clientmodule => 'SD_RSL', + preamble => 'P1#', + modulematch => '^P1#[A-Fa-f0-9]{8}', + length_min => '32', + length_max => '40', + }, + "76" => ## Kabellose LED-Weihnachtskerzen XM21-0 + # ! min length not work - must CHECK ! + # https://github.com/RFD-FHEM/RFFHEM/pull/437#issuecomment-448019192 @sidey79 + # on -> P76#FFFFFFFFFFFFFFFF + # LED_XM21_0 | on MU;P0=-205;P1=113;P3=406;D=010101010101010101010101010101010101010101010101010101010101030303030101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010103030303010101010101010101010100;CP=1;R=69; + # LED_XM21_0 | on MU;P0=-198;P1=115;P4=424;D=0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010404040401010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101040404040;CP=1;R=60;O; + # LED_XM21_0 | on MU;P0=114;P1=-197;P2=419;D=0121212121010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101012121212101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010;CP=0;R=54;O; + # off -> P76#FFFFFFFFFFFFFFC + # LED_XM21_0 | off MU;P0=-189;P1=115;P4=422;D=0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101040404040101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010104040404010101010;CP=1;R=73;O; + # LED_XM21_0 | off MU;P0=-203;P1=412;P2=114;D=01010101020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020101010102020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020200;CP=2;R=74; + # LED_XM21_0 | off MU;P0=-210;P1=106;P3=413;D=0101010101010101010303030301010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101030303030100;CP=1;R=80; + { + name => 'LED XM21', + comment => 'remote with 2-buttons for LED X-MAS light string', + id => '76', + knownFreqs => '433.92', + one => [1.2,-2], # 120,-200 + #zero => [], # existiert nicht + start => [4.5,-2,4.5,-2,4.5,-2,4.5,-2], # 450,-200 Starsequenz + clockabs => 100, + format => 'twostate', # not used now + clientmodule => 'SD_UT', + preamble => 'P76#', + length_min => 58, + length_max => 64, + }, + "77" => ## NANO_DS1820_4Fach + # https://github.com/juergs/NANO_DS1820_4Fach + # Id:105 T: 22.8 MU;P0=-1483;P1=239;P2=970;P3=-21544;D=01020202010132020202010201020202020201010201020201020201010102020102010202020201010102020102020201013202020201020102020202020101020102020102020101010202010201020202020101010202010202020101;CP=1; + # Id:106 T: 0.0 MU;P0=-168;P1=420;P2=-416;P3=968;P4=-1491;P5=242;P6=-21536;D=01234343434543454343434343454543454345434543454345434343434343434343454345434343434345454363434343454345434343434345454345434543454345434543434343434343434345434543434343434545436343434345434543434343434545434543454345434543454343434343434343434543454343;CP=3;O; + # Id:106 T: 0.0 MU;P0=-1483;P1=969;P2=236;P3=-21542;D=01010102020131010101020102010101010102020102010201020102010201010101010101010102010201010101010202013101010102010201010101010202010201020102010201020101010101010101010201020101010101020201;CP=1; + # Id:107 T: 0.0 MU;P0=-32001;P1=112;P2=-8408;P3=968;P4=-1490;P5=239;P6=-21542;D=01234343434543454343434343454543454345454343454345434343434343434343454345434343434345454563434343454345434343434345454345434545434345434543434343434343434345434543434343434545456343434345434543434343434545434543454543434543454343434343434343434543454343;CP=3;O; + # Id:107 T: 0.0 MU;P0=-1483;P1=968;P2=240;P3=-21542;D=01010102020231010101020102010101010102020102010202010102010201010101010101010102010201010101010202023101010102010201010101010202010201020201010201020101010101010101010201020101010101020202;CP=1; + # Id:108 T: 0.0 MU;P0=-32001;P1=969;P2=-1483;P3=237;P4=-21542;D=01212121232123212121212123232123232121232123212321212121212121212123212321212121232123214121212123212321212121212323212323212123212321232121212121212121212321232121212123212321412121212321232121212121232321232321212321232123212121212121212121232123212121;CP=1;O; + # Id:108 T: 0.0 MU;P0=-1485;P1=967;P2=236;P3=-21536;D=010201020131010101020102010101010102020102020101020102010201010101010101010102010201010101020102013101010102010201010101010202010202010102010201020101010101010101010201020101010102010201;CP=1; + { + name => 'NANO_DS1820_4Fach', + comment => 'self build sensor', + id => '77', + knownFreqs => '', + developId => 'y', + zero => [4,-6], + one => [1,-6], + clockabs => 250, + format => 'pwm', + preamble => 'TX', + clientmodule => 'CUL_TX', + modulematch => '^TX......', + length_min => '43', + length_max => '44', + remove_zero => 1, # Removes leading zeros from output + }, + "78" => ## Remote control SEAV BeSmart S4 for BEST Cirrus Draw (07F57800) Deckenluefter + # https://github.com/RFD-FHEM/RFFHEM/issues/909 @TheChatty + # BeSmart_S4_534 light_toggle MU;P0=-19987;P1=205;P2=-530;P3=501;P4=-253;P6=-4094;D=01234123412123434123412123412123412121216123412341212343412341212341212341212121612341234121234341234121234121234121212161234123412123434123412123412123412121216123412341212343412341212341212341212121;CP=1;R=70; + # BeSmart_S4_534 5min_boost MU;P0=-23944;P1=220;P2=-529;P3=483;P4=-252;P5=-3828;D=01234123412123434123412123412121212121235123412341212343412341212341212121212123512341234121234341234121234121212121212351234123412123434123412123412121212121235123412341212343412341212341212121212123;CP=1;R=74; + # BeSmart_S4_534 level_up MU;P0=-8617;P1=204;P2=-544;P3=490;P4=-246;P6=-4106;D=01234123412123434123412123412121234121216123412341212343412341212341212123412121612341234121234341234121234121212341212161234123412123434123412123412121234121216123412341212343412341212341212123412121;CP=1;R=70; + # BeSmart_S4_534 level_down MU;P0=-14542;P1=221;P2=-522;P3=492;P4=-240;P5=-4114;D=01234123412123434123412123412121212341215123412341212343412341212341212121234121512341234121234341234121234121212123412151234123412123434123412123412121212341215123412341212343412341212341212121234121;CP=1;R=62; + { + name => 'BeSmart_Sx', + comment => 'Remote control SEAV BeSmart S4', + id => '78', + knownFreqs => '433.92', + zero => [1,-2], # 250,-500 + one => [2,-1], # 500,-250 + start => [-14], # -3500 + low time from last bit + clockabs => 250, + reconstructBit => '1', + format => 'twostate', + preamble => 'P78#', + clientmodule => 'SD_UT', + modulematch => '^P78#', + length_min => '19', # length - reconstructBit = length_min + length_max => '20', + }, + "79" => ## Heidemann | Heidemann HX | VTX-BELL + # https://github.com/RFD-FHEM/SIGNALDuino/issues/84 + # P79#A5E | ring MU;P0=656;P1=-656;P2=335;P3=-326;P4=-5024;D=0123012123012303030301 24 230123012123012303030301 24 230123012123012303030301 24 2301230121230123030303012423012301212301230303030124230123012123012303030301242301230121230123030303012423012301212301230303030124230123012123012303030301242301230121230123030303;CP=2;O; + # https://forum.fhem.de/index.php/topic,64251.0.html + # P79#4FC | ring MU;P0=540;P1=-421;P2=-703;P3=268;P4=-4948;D=4 323102323101010101010232 34 323102323101010101010232 34 323102323101010101010232 34 3231023231010101010102323432310232310101010101023234323102323101010101010232343231023231010101010102323432310232310101010101023234323102323101010101010232343231023231010101010;CP=3;O; + # https://github.com/RFD-FHEM/RFFHEM/issues/252 + # P79#A0E | ring MU;P0=-24096;P1=314;P2=-303;P3=615;P4=-603;P5=220;P6=-4672;D=0123456123412341414141412323234 16 123412341414141412323234 16 12341234141414141232323416123412341414141412323234161234123414141414123232341612341234141414141232323416123412341414141412323234161234123414141414123232341612341234141414141232323416123412341414;CP=1;R=26;O; + # P79#A0E | ring MU;P0=-10692;P1=602;P2=-608;P3=311;P4=-305;P5=-4666;D=01234123232323234141412 35 341234123232323234141412 35 341234123232323234141412 35 34123412323232323414141235341234123232323234141412353412341232323232341414123534123412323232323414141235341234123232323234141412353412341232323232341414123534123412323232323414;CP=3;R=47;O; + # P79#A0E | ring MU;P0=-7152;P1=872;P2=-593;P3=323;P4=-296;P5=622;P6=-4650;D=01234523232323234545452 36 345234523232323234545452 36 345234523232323234545452 36 34523452323232323454545236345234523232323234545452363452345232323232345454523634523452323232323454545236345234523232323234545452363452345232323232345454523634523452323232323454;CP=3;R=26;O; + # https://forum.fhem.de/index.php/topic,58397.msg879878.html#msg879878 @rcmcronny + # P79#3FC | ring MU;P0=-421;P1=344;P2=-699;P4=659;P6=-5203;P7=259;D=1612121040404040404040421216121210404040404040404212161212104040404040404042121612121040404040404040421216121210404040404040404272761212104040404040404042121612121040404040404040421216121210404040404040404212167272104040404040404042721612127040404040404;CP=4;R=0;O; + { + name => 'wireless doorbell', + comment => 'Heidemann | Heidemann HX | VTX-BELL', + id => '79', + knownFreqs => '', + zero => [-2,1], + one => [-1,2], + start => [-15,1], + clockabs => 330, + format => 'twostate', + preamble => 'P79#', + clientmodule => 'SD_BELL', + modulematch => '^P79#.*', + length_min => '12', + length_max => '12', + }, + "80" => ## EM1000WZ (Energy-Monitor) Funkprotokoll (868Mhz) @HomeAutoUser | Derwelcherichbin + # https://github.com/RFD-FHEM/RFFHEM/issues/253 + # CNT:91 CUM:14.560 5MIN:0.240 TOP:0.170 MU;P1=-417;P2=385;P3=-815;P4=-12058;D=42121212121212121212121212121212121232321212121212121232321212121212121232323212323212321232121212321212123232121212321212121232323212121212121232121212121212121232323212121212123232321232121212121232123232323212321;CP=2;R=87; + { + name => 'EM1000WZ', + comment => 'EM (Energy-Monitor)', + id => '80', + knownFreqs => '868.35', + one => [1,-2], # 800 + zero => [1,-1], # 400 + clockabs => 400, + format => 'twostate', # not used now + clientmodule => 'CUL_EM', + preamble => 'E', + length_min => '104', + length_max => '114', + postDemodulation => \&lib::SD_Protocols::postDemo_EM, + }, + "81" => ## Remote control SA-434-1 based on HT12E @elektron-bbs + # P86#115 | receive MU;P0=-485;P1=188;P2=-6784;P3=508;P5=1010;P6=-974;P7=-17172;D=0123050505630505056305630563730505056305050563056305637305050563050505630563056373050505630505056305630563730505056305050563056305637305050563050505630563056373050505630505056305630563730505056305050563056305637305050563050505630563056373050505630505056;CP=3;R=0; + # P86#115 | receive MU;P0=-1756;P1=112;P2=-11752;P3=496;P4=-495;P5=998;P6=-988;P7=-17183;D=0123454545634545456345634563734545456345454563456345637345454563454545634563456373454545634545456345634563734545456345454563456345637345454563454545634563456373454545634545456345634563734545456345454563456345637345454563454545634563456373454545634545456;CP=3;R=0; + # __ ____ + # ____| | __| | + # Bit 1 Bit 0 + # short 500 microSec / long 1000 microSec / bittime 1500 mikroSek / pilot 12 * bittime, from that 1/3 bitlength high + { + name => 'SA-434-1', + comment => 'remote control SA-434-1 mini 923301 based on HT12E', + id => '81', + knownFreqs => '433.92', + one => [-2,1], # i.O. + zero => [-1,2], # i.O. + start => [-35,1], # Message is not provided as MS, worakround is start + clockabs => 500, + format => 'twostate', + preamble => 'P81#', + modulematch => '^P81#.{3}', + clientmodule => 'SD_UT', + length_min => '12', + length_max => '12', + }, + "82" => ## Fernotron shutters and light switches + # https://github.com/RFD-FHEM/RFFHEM/issues/257 @zwiebert + # down | MU;P0=-200;P1=21748;P2=-25008;P3=410;P4=-388;P5=-3189;P6=811;P7=-785;CP=3;D=012343434343434343564646464376464646437356464646437646464376435643737373764376464373564373737376437643764356437373737373737643735643737373737373737643564376464376464646464356437646437646464373735376437646464646464643537643764646464643737353737646464646437643735373764646464643737643;e; + # stop | MU;P0=-32001;P1=441;P2=-355;P3=-3153;P4=842;P5=-757;CP=1;D=0121212121212121342424242154242424215134242424215424242154213421515151542154242151342151515154215421542134215151515151515421513421515151515151515421342154242421542424242134215424242154242151513151542424242424242421315154242424242421515131542424215424215421513154242421542421515421;e; + # the messages received are usual missing 12 bits at the end for some reason. So the checksum byte is missing. + # Fernotron protocol is unidirectional. Here we can only receive messages from controllers send to receivers. + { + name => 'Fernotron', + comment => 'shutters and light switches', + id => '82', + knownFreqs => '', + developId => 'm', + dispatchBin => '1', + paddingbits => '1', # disable padding + one => [1,-2], # on=400us, off=800us + zero => [2,-1], # on=800us, off=400us + float => [1,-8], # on=400us, off=3200us. the preamble and each 10bit word has one [1,-8] in front + pause => [1,-1], # preamble (5x) + clockabs => 400, # 400us + format => 'twostate', + preamble => 'P82#', # prepend our protocol number to converted message + clientmodule => 'Fernotron', + length_min => '100', # actual 120 bit (12 x 10bit words to decode 6 bytes data), but last 20 are for checksum + length_max => '3360', # 3360 bit (336 x 10bit words to decode 168 bytes data) for full timer message + }, + "83" => ## Remote control RH787T based on MOSDESIGN SEMICONDUCTOR CORP (CMOS ASIC encoder) M1EN compatible HT12E + # for example Westinghouse Deckenventilator Delancey, 6 speed buttons, @zwiebelxxl + # https://github.com/RFD-FHEM/RFFHEM/issues/250 + # 1_fan_minimum_speed MU;P0=388;P1=-112;P2=267;P3=-378;P5=585;P6=-693;P7=-11234;D=0123035353535356262623562626272353535353562626235626262723535353535626262356262627235353535356262623562626272353535353562626235626262723535353535626262356262627235353535356262623562626272353535353562626235626262723535353535626262356262627235353535356262;CP=2;R=43;O; + # 2_fan_low_speed MU;P0=-176;P1=262;P2=-11240;P3=112;P5=-367;P6=591;P7=-695;D=0123215656565656717171567156712156565656567171715671567121565656565671717156715671215656565656717171567156712156565656567171715671567121565656565671717156715671215656565656717171567156712156565656567171715671567121565656565671717171717171215656565656717;CP=1;R=19;O; + # 3_fan_medium_low_speed MU;P0=564;P1=-392;P2=-713;P3=245;P4=-11247;D=0101010101023231023232323431010101010232310232323234310101010102323102323232343101010101023231023232323431010101010232310232323234310101010102323102323232343101010101023231023232323431010101010232310232323234310101010102323102323232343101010101023231023;CP=3;R=40;O; + { + name => 'RH787T', + comment => 'remote control for example Westinghouse Delancey 7800140', + id => '83', + knownFreqs => '433.92', + one => [-2,1], + zero => [-1,2], + start => [-35,1], # calculated 12126,31579 µS + clockabs => 335, # calculated ca 336,8421053 µS short - 673,6842105µS long + format => 'twostate', # there is a pause puls between words + preamble => 'P83#', + clientmodule => 'SD_UT', + modulematch => '^P83#.{3}', + length_min => '12', + length_max => '12', + }, + "84" => ## Funk Wetterstation Auriol IAN 283582 Version 06/2017 (Lidl), Modell-Nr.: HG02832D, 09/2018 @roobbb + # ! some message are decode as protocol 40 ! + # https://github.com/RFD-FHEM/RFFHEM/issues/263 + # Ch:1 T: 25.3 H: 53 Bat:ok MU;P0=-28796;P1=376;P2=-875;P3=834;P4=220;P5=-632;P6=592;P7=-268;D=0123232324545454545456767454567674567456745674545454545456767676767674567674567676767456;CP=4;R=22; + # Ch:2 T: 13.1 H: 78 Bat:ok MU;P0=-28784;P1=340;P2=-903;P3=814;P4=223;P5=-632;P6=604;P7=-248;D=0123232324545454545456767456745456767674545674567454545456745454545456767454545456745676;CP=4;R=22; + # Ch:1 T: 6.9 H: 66 Bat:ok MU;P0=-21520;P1=235;P2=-855;P3=846;P4=620;P5=-236;P7=-614;D=012323232454545454545451717451717171745171717171717171717174517171745174517174517174545;CP=1;R=217; + ## Sempre 92596/65395, Hofer/Aldi, WS97210-1, WS97230-1, WS97210-2, WS97230-2 + # https://github.com/RFD-FHEM/RFFHEM/issues/223 + # Ch:3 T: 21.3 H: 77 Bat:ok MU;P0=-30004;P1=815;P2=-910;P3=599;P4=-263;P5=234;P6=-621;D=0121212345634565634345656345656343456345656345656565656343456345634563456343434565656;CP=5;R=5; + ## TECVANCE TV-4848 (Amazon) @HomeAutoUser + # Ch:1 T: 26.4 H: 49 (L39) MU;P0=-218;P1=254;P2=-605;P4=616;P5=907;P6=-799;P7=-1536;D=012121212401212124012401212121240125656565612401240404040121212404012121240121212121212124012121212401212124012401212121247;CP=1; + # Ch:1 T: 26.6 H: 49 (L41) MU;P0=239;P1=-617;P2=612;P3=-245;P4=862;P5=-842;D=01230145454545012301232323230101012323010101230123010101010123010101012301230123232301012301230145454545012301232323230101012323010101230123010101010123010101012301230123232301012301230145454545012301232323230101012323010101230123010101010123010101012301;CP=0;R=89;O; + { + name => 'IAN 283582 / TV-4848', + comment => 'Weatherstation Auriol IAN 283582 / Sempre 92596/65395 / TECVANCE', + id => '84', + knownFreqs => '433.92', + one => [3,-1], + zero => [1,-3], + start => [4,-4,4,-4,4,-4], + clockabs => 215, + format => 'twostate', + preamble => 'W84#', + postamble => '', + clientmodule => 'SD_WS', + length_min => '39', # das letzte Bit fehlt meistens + length_max => '41', + }, + "85" => ## Funk Wetterstation TFA 35.1140.01 mit Temperatur-/Feuchte- und Windsensor TFA 30.3222.02 09/2018 @Iron-R + # https://github.com/RFD-FHEM/RFFHEM/issues/266 + # Ch:1 T: 8.7 H: 85 Bat:ok MU;P0=-509;P1=474;P2=-260;P3=228;P4=718;P5=-745;D=01212303030303012301230123012301230301212121230454545453030303012123030301230303012301212123030301212303030303030303012303012303012303012301212303030303012301230123012301230301212121212454545453030303012123030301230303012301212123030301212303030303030303;CP=3;R=46;O; + # Ch:1 T: 7.6 H: 89 Bat:ok MU;P0=7944;P1=-724;P2=742;P3=241;P4=-495;P5=483;P6=-248;D=01212121343434345656343434563434345634565656343434565634343434343434345634345634345634343434343434343434345634565634345656345634343456563421212121343434345656343434563434345634565656343434565634343434343434345634345634345634343434343434343434345634565634;CP=3;R=47;O; + { + name => 'TFA 30.3222.02', + comment => 'Combisensor for Weatherstation TFA 35.1140.01', + id => '85', + knownFreqs => '', + one => [2,-1], + zero => [1,-2], + start => [3,-3,3,-3,3,-3], + clockabs => 250, + format => 'twostate', + preamble => 'W85#', + postamble => '', + clientmodule => 'SD_WS', + length_min => '64', + length_max => '68', + }, + "86" => ### for remote controls: Novy 840029, CAME TOP 432EV, BOSCH & Neff Transmitter SF01 01319004 + ### CAME TOP 432EV 433,92 MHz für z.B. Drehtor Antrieb: + # https://forum.fhem.de/index.php/topic,63370.msg849400.html#msg849400 + # https://github.com/RFD-FHEM/RFFHEM/issues/151 @andreasloe + # CAME TOP 432EV | right_button MU;P0=711;P1=-15288;P4=132;P5=-712;P6=316;P7=-313;D=4565656705656567056567056 16 565656705656567056567056 16 56565670565656705656705616565656705656567056567056165656567056565670565670561656565670565656705656705616565656705656567056567056165656567056565670565670561656565670565656705656705616565656705656567056;CP=6;R=52; + # CAME TOP 432EV | left_button MU;P0=-322;P1=136;P2=-15241;P3=288;P4=-735;P6=723;D=012343434306434343064343430623434343064343430643434306 2343434306434343064343430 623434343064343430643434306234343430643434306434343062343434306434343064343430623434343064343430643434306234343430643434306434343062343434306434343064343430;CP=3;R=27; + # CAME TOP 432EV | right_button MU;P0=-15281;P1=293;P2=-745;P3=-319;P4=703;P5=212;P6=152;P7=-428;D=0 1212121342121213421213421 01 212121342121213421213421 01 21212134212121342121342101212121342121213421213421012121213421212134212134210121243134212121342121342101252526742121213425213421012121213421212134212134210121212134212;CP=1;R=23; + # rechteTaste: 0x112 (000100010010), linkeTaste: 0x111 (000100010001), the least significant bits distinguish the keys + ### remote control Novy 840029 for Novy Pureline 6830 kitchen hood: + # https://github.com/RFD-FHEM/RFFHEM/issues/331 @Garfonso + # Novy 840029 | light on/off button MU;P0=710;P1=353;P2=-403;P4=-761;P6=-16071;D=20204161204120412041204120414141204120202041612041204120412041204141412041202020416120412041204120412041414120412020204161204120412041204120414141204120202041;CP=1;R=40; + # Novy 840029 | plus button MU;P0=22808;P1=-24232;P2=701;P3=-765;P4=357;P5=-15970;P7=-406;D=012345472347234723472347234723454723472347234723472347234547234723472347234723472345472347234723472347234723454723472347234723472347234;CP=4;R=39; + # Novy 840029 | minus button MU;P0=-8032;P1=364;P2=-398;P3=700;P4=-760;P5=-15980;D=0123412341234123412341412351234123412341234123414123512341234123412341234141235123412341234123412341412351234123412341234123414123;CP=1;R=40; + # Novy 840029 | power button MU;P0=-756;P1=718;P2=354;P3=-395;P4=-16056;D=01020202310231310202 42 310231023102310231020202310231310202 42 31023102310231023102020231023131020242310231023102310231020202310231310202;CP=2;R=41; + # Novy 840029 | novy button MU;P0=706;P1=-763;P2=370;P3=-405;P4=-15980;D=0123012301230304230123012301230123012303042;CP=2;R=42; + ### remote control Novy 840039 for Novy Cloud 230 kitchen hood: + # https://github.com/RFD-FHEM/RFFHEM/issues/792 | https://forum.fhem.de/index.php/topic,107867.0.html @Devirex + # note: !! Clockpulse is 375, value from ID 86 350 it does not work !! + # Novy 840039 | power_button MU;P0=-749;P1=378;P2=-456;P3=684;P4=-16081;D=01230101012301232301014123012301230123012301010123012323010141230123012301230123010101230123230101412;CP=1;R=66; + # Novy 840039 | cooking_light on MU;P0=-750;P1=375;P2=-418;P3=682;P4=-16059;P5=290;P6=-5060;D=0123010123010123010123412305230123012301230101230101230101234123012301230123012301012301012301012341230123012301230123010123010123010123416505230123010123010123010123412; + ### Neff Transmitter SF01 01319004 (SF01_01319004) 433,92 MHz + # https://github.com/RFD-FHEM/RFFHEM/issues/376 @fhemjcm + # SF01_01319004 | light_on_off MU;P0=-707;P1=332;P2=-376;P3=670;P5=-15243;D=01012301232323230123012301232301010123510123012323232301230123012323010101235101230123232323012301230123230101012351012301232323230123012301232301010123510123012323232301230123012323010101235101230123232323012301230123230101012351012301232323230123012301;CP=1;R=3;O; + # SF01_01319004 | plus MU;P0=-32001;P1=348;P2=-704;P3=-374;P4=664;P5=-15255;D=01213421343434342134213421343421213434512134213434343421342134213434212134345121342134343434213421342134342121343451213421343434342134213421343421213434512134213434343421342134213434212134345121342134343434213421342134342121343451213421343434342134213421;CP=1;R=15;O; + # SF01_01319004 | minus MU;P0=-32001;P1=326;P2=-721;P3=-385;P4=656;P5=-15267;D=01213421343434342134213421343421342134512134213434343421342134213434213421345121342134343434213421342134342134213451213421343434342134213421343421342134512134213434343421342134213434213421345121342134343434213421342134342134213451213421343434342134213421;CP=1;R=10;O; + # SF01_01319004 | interval MU;P0=-372;P1=330;P2=684;P3=-699;P4=-14178;D=010231020202023102310231020231310231413102310202020231023102310202313102314;CP=1;R=253; + # SF01_01319004 | delay MU;P0=-710;P1=329;P2=-388;P3=661;P4=-14766;D=01232301410123012323232301230123012323012323014;CP=1;R=1; + ### BOSCH Transmitter SF01 01319004 (SF01_01319004_Typ2) 433,92 MHz + # SF01_01319004_Typ2 | light_on_off MU;P0=706;P1=-160;P2=140;P3=-335;P4=-664;P5=385;P6=-15226;P7=248;D=01210103045303045453030304545453030454530653030453030454530303045454530304747306530304530304545303030454545303045453065303045303045453030304545453030454530653030453030454530303045454530304545306530304530304545303030454545303045453065303045303045453030304;CP=5;O; + # SF01_01319004_Typ2 | plus MU;P0=-15222;P1=379;P2=-329;P3=712;P6=-661;D=30123236123236161232323616161232361232301232361232361612323236161612323612323012323612323616123232361616123236123230123236123236161232323616161232361232301232361232361612323236161612323612323012323612323616123232361616123236123230123236123236161232323616;CP=1;O; + # SF01_01319004_Typ2 | delay MU;P0=705;P1=-140;P2=-336;P3=-667;P4=377;P5=-15230;P6=248;D=01020342020343420202034343420202020345420203420203434202020343434202020203654202034202034342020203434342020202034542020342020343420202034343420202020345420203420203434202020343434202020203454202034202034342020203434342020202034542020342020343420202034343;CP=4;O; + # SF01_01319004_Typ2 | minus MU;P0=704;P1=-338;P2=-670;P3=378;P4=-15227;P5=244;D=01023231010102323231010102310431010231010232310101023232310101025104310102310102323101010232323101010231043101023101023231010102323231010102310431010231010232310101023232310101023104310102310102323101010232323101010231043101023101023231010102323231010102;CP=3;O; + # SF01_01319004_Typ2 | interval MU;P0=-334;P1=709;P2=-152;P3=-663;P4=379;P5=-15226;P6=250;D=01210134010134340101013434340101340134540101340101343401010134343401013601365401013401013434010101343434010134013454010134010134340101013434340101340134540101340101343401010134343401013401345401013401013434010101343434010134013454010134010134340101013434;CP=4;O; + { + name => 'BOSCH | CAME | Novy | Neff | Refsta Topdraft', + comment => 'remote control CAME TOP 432EV, Novy 840029 & 840039, BOSCH / Neff or Refsta Topdraft SF01 01319004', + id => '86', + knownFreqs => '433.92', + one => [-2,1], + zero => [-1,2], + start => [-44,1], + clockabs => 350, + format => 'twostate', + preamble => 'P86#', + clientmodule => 'SD_UT', + #modulematch => '^P86#.*', + length_min => '12', + length_max => '18', + }, + "87" => ## JAROLIFT Funkwandsender TDRC 16W / TDRCT 04W + # https://github.com/RFD-FHEM/RFFHEM/issues/380 @bismosa + # P87#E8119A34200065F100 | button=up MS;P1=1524;P2=-413;P3=388;P4=-3970;P5=-815;P6=778;P7=-16024;D=34353535623562626262626235626262353562623535623562626235356235626262623562626262626262626262626262623535626235623535353535626262356262626262626267123232323232323232323232;CP=3;SP=4;R=226;O;m2; + # P87#CD287247200065F100 | button=up MS;P0=-15967;P1=1530;P2=-450;P3=368;P4=-3977;P5=-835;P6=754;D=34353562623535623562623562356262626235353562623562623562626235353562623562626262626262626262626262623535626235623535353535626262356262626262626260123232323232323232323232;CP=3;SP=4;R=229;O; + # KeeLoq is a registered trademark of Microchip Technology Inc. + { + name => 'JAROLIFT', + comment => 'remote control JAROLIFT TDRC_16W / TDRCT_04W', + id => '87', + knownFreqs => '433.92', + one => [1,-2], + zero => [2,-1], + preSync => [3.8,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1], + sync => [1,-10], # this is a end marker, but we use this as a start marker + pause => [-40], + clockabs => 400, # ca 400us + reconstructBit => '1', + format => 'twostate', + preamble => 'P87#', + clientmodule => 'SD_Keeloq', + #modulematch => '', + length_min => '72', + length_max => '85', + }, + "88" => ## Roto Dachfensterrolladen | Aurel Fernbedienung "TX-nM-HCS" (HCS301 chip) | three buttons -> up, stop, down + # https://forum.fhem.de/index.php/topic,91244.0.html @bruen985 + # P88#AC3895D790EAFEF2C | button=0100 MS;P1=361;P2=-435;P4=-4018;P5=-829;P6=759;P7=-16210;D=141562156215156262626215151562626215626215621562151515621562151515156262156262626215151562156215621515151515151562151515156262156215171212121212121212121212;CP=1;SP=4;R=66;O;m0; + # P88#9451E57890EAFEF24 | button=0100 MS;P0=-16052;P1=363;P2=-437;P3=-4001;P4=-829;P5=755;D=131452521452145252521452145252521414141452521452145214141414525252145252145252525214141452145214521414141414141452141414145252145252101212121212121212121212;CP=1;SP=3;R=51;O;m1; + ## remote control Waeco MA650_TX (HCS300 chip) | two buttons + # P88#4A823F65482822040 | button=blue MS;P0=344;P3=-429;P4=-3926;P5=719;P6=-823;P7=-15343;D=045306535306530653065353535353065353530606060606065306065353065306530653530653535353530653065353535353065353530653535353535306535353570303030303030303030303;CP=0;SP=4;R=38;O;m2;0;0; + ## remote control RADEMACHER RP-S1-HS-RF11 (HCS301 chip) fuer Garagentorantrieb RolloPort S1 with two buttons + # https://github.com/RFD-FHEM/RFFHEM/issues/612 @ D3ltorohd 20.07.2019 + # Firmware: Signalduino V 3.3.2.1-rc8 SIGNALduino cc1101 - compiled at Jan 10 2019 20:13:56 + # P88#7EFDFFDDF9C284E4C | button=0010 MS;P1=735;P2=-375;P3=377;P4=-752;P6=-3748;D=3612343434343434123434343434341234343434343434343434341234343412343434343434121234343412121212341234121212123412123434341212341212343;CP=3;SP=6;R=42;e;m1; + # P88#C2C85435F9C284E18 | button=1000 MS;P1=385;P2=-375;P3=-3756;P4=-745;P5=766;P6=-15000;D=131414525252521452141452521452525252145214521452525252141452145214141414141452521414145252525214521452525252145252141414525252521414561212121212121212121212;CP=1;SP=3;R=54;O;s=36;m0; + ## remote control SCS Sentinel - PR3-4207-002 (HCS300 chip) | four buttons + # https://github.com/RFD-FHEM/RFFHEM/issues/616 + # P88#0A8423F39D6020044 | button=one MS;P0=844;P1=-4230;P2=420;P4=-860;P6=-17704;P7=-439;D=210707070724072407240707070724070707072407070724242424242407072424240707242424072407242407070707070707240707070707070707070724070707262727272727272727272727;CP=2;SP=1;R=18;O;s=36;m0; + # P88#00C7922B9D6020024 | button=two MS;P1=417;P3=847;P4=-442;P5=-858;P7=-4258;D=1734343434343434341515343434151515153434153434153434341534153415151534341515153415341515343434343434341534343434343434343434341534341;CP=1;SP=7;R=25;e;m1; + # P88#F82542039D6020014 | button=three MS;P0=-855;P1=852;P2=-433;P3=432;P5=-17236;P6=-4250;D=363030303030121212121230121230123012301212121230121212121212123030301212303030123012303012121212121212301212121212121212121212123012353232323232323232323232;CP=3;SP=6;R=29;O;s=36;m0; + # P88#DB06531F9D6020084 | button=four MS;P0=-17496;P1=435;P2=-438;P4=-4269;P5=-845;P6=850;D=141515621515621515626262626215156262156215626215156262621515151515156262151515621562151562626262626262156262626262626262621562626262101212121212121212121212;CP=1;SP=4;R=34;O;m1; + ## remote enjoy motors HS-8, HS-1 / RIO HS-8 | three buttons + # Modulation = GFSK | Frequenz = 868.302 MHz | Bandwidth = 58.036 kHz | Deviation = 25.391 kHz | Datarate = 24.796 kHz + # https://forum.fhem.de/index.php/topic,107239.0.html | https://github.com/fhem/SD_Keeloq/issues/19 + # P88#31EB8B8A008B48058 | button=up MS;P1=399;P2=-421;P3=-4034;P4=800;P5=-815;P6=-15516;D=1342421515424242151515154215421515154242421542151515424242154215424242424242424242154242421542151542154242154242424242424242154215161212121212121212121212;CP=1;SP=3;R=86;O;m2; + # P88#54F58AA3008B48038 | button=down MS;P1=415;P2=-400;P3=-4034;P4=810;P5=-803;P6=-15468;D=1342154215421542421515151542154215154242421542154215421542424215154242424242424242154242421542151542154242154242424242424242421515161212121212121212121212;CP=1;SP=3;R=84;O;m2; + # P88#CBDA84D2008B48018 | button=stop MS;P1=417;P2=-400;P3=-4032;P4=-789;P5=811;P6=-15540;D=1314145252145214141414521414521452145252525214525214145214525214525252525252525252145252521452141452145252145252525252525252525214161212121212121212121212;CP=1;SP=3;R=86;O;m2; + ## remote Normstahl Garage DOORS - 1k AM HS 433MHz | AKHS 433-61 | one button @HomeAutoUser + # P88#A4630395D55800014 | buttone one MS;P1=314;P2=-433;P3=-3801;P4=-799;P5=680;P6=-15288;D=131452145252145252521414525252141452525252525214141452521452145214141452145214521452145214145252525252525252525252525252525252521452161212121212121212121212;CP=1;SP=3;R=56;O;m2; + # P88#8B6988E6D55800014 | buttone one MS;P0=684;P1=-436;P2=316;P3=-799;P4=-15280;P5=-3796;D=252301010123012323012323012301012323010101230101012323230101232301232301230123012301230123230101010101010101010101010101010101012301242121212121212121212121;CP=2;SP=5;R=18;O;m1; + # P88#CAADF1BFD55800010 | buttone one MS;P1=-437;P2=311;P3=-3786;P4=-806;P5=676;P6=-14940;D=232424515124512451245124512424512424242424515151242451242424242424242451245124512451245124245151515151515151515151515151515151512451562121212121212121212121;CP=2;SP=3;R=55;O;m2; + # P88#CAD0BB54D55800010 | buttone one MS;P0=686;P1=-425;P2=317;P3=-3796;P4=-802;P5=-14916;P6=240;D=232424010124012401242401240101010124012424240124240124012401240101242401240124012401240124240101010101010101010101010101010101012401052161616161616161212121;CP=2;SP=3;R=59;O;m2; + ## KeeLoq is a registered trademark of Microchip Technology Inc. + { + name => 'HCS300/HCS301', + comment => 'remote controls Aurel TX-nM-HCS, enjoy motors HS, Normstahl ,Rademacher RP-S1-HS-RF11, SCS Sentinel PR3-4207-002, Waeco MA650_TX', + id => '88', + knownFreqs => '433.92 | 868.35', + one => [1,-2], # PWM bit pulse width typ. 1.2 mS + zero => [2,-1], # PWM bit pulse width typ. 1.2 mS + preSync => [1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,], # 11 pulses preambel, 1 sync, 66 data, pause ... repeat + sync => [1,-10], # Header duration typ. 4 mS + pause => [-39], # Guard Time typ. 15.6 mS + clockabs => 400, # Basic pulse element typ. 0.4 mS (Timings from table CODE WORD TRANSMISSION TIMING REQUIREMENTS in PDF) + reconstructBit => '1', + format => 'twostate', + preamble => 'P88#', + clientmodule => 'SD_Keeloq', + length_min => '65', + length_max => '78', + }, + "89" => ## Funk Wetterstation TFA 35.1140.01 mit Temperatur-/Feuchtesensor TFA 30.3221.02 12/2018 @Iron-R + # ! some message are decode as protocol 37 and 61 ! + # https://github.com/RFD-FHEM/RFFHEM/issues/266 + # Ch:3 T: 5.5 H: 58 Bat:low MU;P0=-900;P1=390;P2=-499;P3=-288;P4=193;P7=772;D=1213424213131342134242424213134242137070707013424213134242131342134242421342424213421342131342421313134213424242421313424213707070701342421313424213134213424242134242421342134213134242131313421342424242131342421;CP=4;R=43; + # Ch:3 T: 5.4 H: 58 Bat:low MU;P0=-491;P1=382;P2=-270;P3=179;P4=112;P5=778;P6=-878;D=01212304012123012303030123030301230123012303030121212301230301230121212121256565656123030121230301212301230303012303030123012301230303012121230123030123012121212125656565612303012123030121230123030301230303012301230123030301212123012303012301212121212565;CP=3;R=43;O; + # Ch:3 T: 5 H: 60 Bat:low MU;P0=-299;P1=384;P2=169;P3=-513;P5=761;P6=-915;D=01023232310101010101023565656561023231010232310102310232323102323231023231010232323101010102323231010101010102356565656102323101023231010231023232310232323102323101023232310101010232323101010101010235656565610232310102323101023102323231023232310232310102;CP=2;R=43;O; + # Ch:2 T: 6.5 H: 62 Bat:ok MU;P0=-32001;P1=412;P2=-289;P3=173;P4=-529;P5=777;P6=-899;D=01234345656541212341234123434121212121234123412343412343456565656121212123434343434343412343412343434121234123412343412121212123412341234341234345656565612121212343434343434341234341234343412123412341234341212121212341234123434123434565656561212121234343;CP=3;R=22;O; + # Ch:2 T: 6.3 H: 62 Bat:ok MU;P0=22960;P1=-893;P2=775;P3=409;P4=-296;P5=182;P6=-513;D=01212121343434345656565656565634565634565656343456563434565634343434345656565656565656342121212134343434565656565656563456563456565634345656343456563434343434565656565656565634212121213434343456565656565656345656345656563434565634345656343434343456565656;CP=5;R=22;O; + # Ch:2 T: 6.1 H: 66 Bat:ok MU;P0=172;P1=-533;P2=401;P3=-296;P5=773;P6=-895;D=01230101230101012323010101230123010101010101230101230101012323010101230123010301230101010101012301012301010123230101012301230101010123010101010101012301565656562323232301010101010101230101230101012323010101230123010101012301010101010101230156565656232323;CP=0;R=23;O; + { + name => 'TFA 30.3221.02', + comment => 'temperature / humidity sensor for weatherstation TFA 35.1140.01', + id => '89', + knownFreqs => '433.92', + one => [2,-1], + zero => [1,-2], + start => [3,-3,3,-3,3,-3], + clockabs => 250, + format => 'twostate', + preamble => 'W89#', + postamble => '', + clientmodule => 'SD_WS', + length_min => '40', + length_max => '40', + }, + "90" => ## mumbi AFS300-s / manax MX-RCS250 (CP 258-298) + # https://forum.fhem.de/index.php/topic,94327.15.html @my-engel @peterboeckmann + # A AN MS;P0=-9964;P1=273;P4=-866;P5=792;P6=-343;D=10145614141414565656561414561456561414141456565656561456141414145614;CP=1;SP=0;R=35;O;m2; + # A AUS MS;P0=300;P1=-330;P2=-10160;P3=804;P7=-840;D=02073107070707313131310707310731310707070731313107310731070707070707;CP=0;SP=2;R=23;O;m1; + # B AN MS;P1=260;P2=-873;P3=788;P4=-351;P6=-10157;D=16123412121212343434341212341234341212121234341234341234121212341212;CP=1;SP=6;R=21;O;m2; + # B AUS MS;P1=268;P3=793;P4=-337;P6=-871;P7=-10159;D=17163416161616343434341616341634341616161634341616341634161616343416;CP=1;SP=7;R=24;O;m2; + { + name => 'mumbi | MANAX', + comment => 'remote control mumbi RC-10, MANAX MX-RCS250', + id => '90', + knownFreqs => '433.92', + one => [3,-1], + zero => [1,-3], + sync => [1,-36], + clockabs => 280, + format => 'twostate', + preamble => 'P90#', + length_min => '33', + length_max => '36', + clientmodule => 'SD_UT', + modulematch => '^P90#.*', + }, + "91" => ## Atlantic Security / Focus Security China Devices + # https://forum.fhem.de/index.php/topic,58397.msg876862.html#msg876862 @Harst @jochen_f + # normal MU;P0=800;P1=-813;P2=394;P3=-410;P4=-3992;D=0123030303030303012121230301212304230301212301230301212123012301212303012301230303030303030121212303012123042303012123012303012121230123012123030123012303030303030301212123030121230;CP=2;R=46; + # normal MU;P0=406;P1=-402;P2=802;P3=-805;P4=-3994;D=012123012301212121212121230303012123030124012123030123012123030301230123030121230123012121212121212303030121230301240121230301230121230303012301230301212301230121212121212123030301212303012;CP=0;R=52; + # warning MU;P0=14292;P1=-10684;P2=398;P3=-803;P4=-406;P5=806;P6=-4001;D=01232324532453232454532453245454532324545323232453245324562454532324532454532323245324532324545324532454545323245453232324532453245624545323245324545323232453245323245453245324545453232454532323245324532456245453232453245453232324532453232454532453245454;CP=2;R=50;O; + { + name => 'Atlantic security', + comment => 'example sensor MD-210R | MD-2018R | MD-2003R (MU decode)', + id => '91', + knownFreqs => '433.92 | 868.35', + one => [-2,1], + zero => [-1,2], + start => [-10,1], + clockabs => 400, + format => 'twostate', + preamble => 'P91#', + length_min => '35', # 36 - reconstructBit = 35 + length_max => '36', + clientmodule => 'SD_UT', + #modulematch => '^P91#.*', + reconstructBit => '1', + }, + "91.1" => ## Atlantic Security / Focus Security China Devices + # https://forum.fhem.de/index.php/topic,58397.msg878008.html#msg878008 @Harst @jochen_f + # warning MS;P0=-399;P1=407;P2=820;P3=-816;P4=-4017;D=14131020231020202313131023131313131023102023131313131310202313131020202313;CP=1;SP=4;O;m0; + # warning MS;P1=392;P2=-824;P3=-416;P4=804;P5=-4034;D=15121343421343434212121342121212121342134342121212121213434212121343434212;CP=1;SP=5;e;m2; + { + name => 'Atlantic security', + comment => 'example sensor MD-210R | MD-2018R | MD-2003R (MS decode)', + id => '91.1', + knownFreqs => '433.92 | 868.35', + one => [-2,1], + zero => [-1,2], + sync => [-10,1], + clockabs => 400, + reconstructBit => '1', + format => 'twostate', + preamble => 'P91#', + length_min => '32', + length_max => '36', + clientmodule => 'SD_UT', + #modulematch => '^P91.1#.*', + }, + "92" => ## KRINNER Lumix - LED X-MAS + # https://github.com/RFD-FHEM/RFFHEM/issues/452 | https://forum.fhem.de/index.php/topic,94873.msg876477.html?PHPSESSID=khp4ja64pcqa5gsf6gb63l1es5#msg876477 @gestein + # on MU;P0=24188;P1=-16308;P2=993;P3=-402;P4=416;P5=-967;P6=-10162;D=0123234545454523234523234545454545454545232623452345454545454523234523234545454523234523234545454545454545232623452345454545454523234523234545454523234523234545454545454545232623452345454545454523234523234545454523234523234545454545454545232;CP=4;R=25; + # off MU;P0=11076;P1=-20524;P2=281;P3=-980;P4=982;P5=-411;P6=408;P7=-10156;D=0123232345456345456363636363636363634745634563636363636345456345456363636345456345456363636363636363634745634563636363636345456345456363636345456345456363636363636363634745634563636363636345456345456363636345456345456363636363636363634;CP=6;R=38; + { + name => 'KRINNER Lumix', + comment => 'remote control LED X-MAS', + id => '92', + knownFreqs => '433.92', + zero => [1,-2], + one => [2,-1], + start => [2,-24], + clockabs => 420, + format => 'twostate', + preamble => 'P92#', + length_min => '32', + length_max => '32', + clientmodule => 'SD_UT', + #modulematch => '^P92#.*', + }, + "93" => ## ESTO Lighting GmbH | remote control KL-RF01 with 9 buttons (CP 375-395) + # https://github.com/RFD-FHEM/RFFHEM/issues/449 @daniel89fhem + # light_color_cold_white MS;P1=376;P4=-1200;P5=1170;P6=-409;P7=-12224;D=17141414561456561456565656145656141414145614141414565656145656565614;CP=1;SP=7;R=231;e;m0; + # dimup MS;P1=393;P2=-1174;P4=1180;P5=-401;P6=-12222;D=16121212451245451245454545124545124545451212121212121212454545454512;CP=1;SP=6;R=243;e;m0; + # dimdown MS;P0=397;P1=-385;P2=-1178;P3=1191;P4=-12230;D=04020202310231310231313131023131023131020202020202020231313131313102;CP=0;SP=4;R=250;e;m0; + { + name => 'ESTO Lighting GmbH', + comment => 'remote control KL-RF01', + id => '93', + knownFreqs => '433.92', + one => [3,-1], + zero => [1,-3], + sync => [1,-32], + clockabs => 385, + format => 'twostate', + preamble => 'P93#', + length_min => '32', # 2. MSG: 32 Bit, bleibt so + length_max => '36', # 1. MSG: 33 Bit, wird verlängert auf 36 Bit + clientmodule => 'SD_UT', + #modulematch => '^P93#.*', + }, + "94" => # Atech wireless weather station (vermutlicher Name: WS-308) + # https://github.com/RFD-FHEM/RFFHEM/issues/547 @Kreidler1221 2019-03-15 + # Sensor sends Bit 0 as "0", Bit 1 as "110" + # Id:0C T:-14.6 MU;P0=-32001;P1=1525;P2=-303;P3=-7612;P4=-2008;D=01212121212121213141414141212141212141414141412121414141414121214141212141414141212141212141412121412121414121214121;CP=1; + # Id:0C T:-0.4 MU;P0=-32001;P1=1533;P2=-297;P3=-7612;P4=-2005;D=0121212121212121314141414121214121214141414141212141414141414141414141412121414141212141412121414121;CP=1; + # Id:0C T:0.2 MU;P0=-32001;P1=1532;P2=-299;P3=-7608;P4=-2005;D=0121212121212121314141414121214121214141414141414141414141414141414141212141412121412121412121414121;CP=1; + # Id:0C T:10.2 MU;P0=-31292;P1=1529;P2=-300;P3=-7610;P4=-2009;D=012121212121212131414141412121412121414141414141414141412121414141414141412121414121214121214121214121214121012121212121212131414141412121412121414141414141414141412121414141414141412121414121214121214121214121214121;CP=1; + # Id:0C T:27 MU;P0=-31290;P1=1533;P2=-297;P3=-7608;P4=-2006;D=012121212121212131414141412121412121414141414141414141212141414121214121214121214141414141212141414121214121012121212121212131414141412121412121414141414141414141212141414121214121214121214141414141212141414121214121;CP=1; + { + name => 'Atech', + comment => 'Temperature sensor', + id => '94', + knownFreqs => '433.92', + one => [5.3,-1], # 1537, 290 + zero => [5.3,-6.9], # 1537, 2001 + start => [5.3,-26.1], # 1537, 7569 + clockabs => 290, + reconstructBit => '1', + format => 'twostate', + preamble => 'W94#', + clientmodule => 'SD_WS', + length_min => '24', # minimal 24*0=24 Bit, kuerzeste bekannte aus Userlog: 36 + length_max => '96', # maximal 24*110=96 Bit, laengste bekannte aus Userlog: 60 + }, + "95" => # Techmar / Garden Lights Fernbedienung, 6148011 Remote control + 12V Outdoor receiver + # https://github.com/RFD-FHEM/RFFHEM/issues/558 @BlackcatSandy + # Group_1_on MU;P0=-972;P1=526;P2=-335;P3=-666;D=01213131312131313121212121312121313131313121312131313121313131312121212121312121313131313121313121212101213131312131313121212121312121313131313121312131313121313131312121212121312121313131313121313121212101213131312131313121212121312121313131313121312131;CP=1;R=44;O; + # Group_5_on MU;P0=-651;P1=530;P2=-345;P3=-969;D=01212121312101010121010101212121210121210101010101210121010101210101010121212121012121210101010121010101212101312101010121010101212121210121210101010101210121010101210101010121212121012121210101010121010101212121312101010121010101212121210121210101010101;CP=1;R=24;O; + # Group_8_off MU;P0=538;P1=-329;P2=-653;P3=-964;D=01020301020202010202020101010102010102020202020102010202020102020202010101010101010201020202020202010202010301020202010202020101010102010102020202020102010202020102020202010101010101010201020202020202010201010301020202010202020101010102010102020202020102;CP=0;R=19;O; + { + name => 'Techmar', + comment => 'Garden Lights remote control', + id => '95', + knownFreqs => '433.92', + one => [5,-6], # 550,-660 + zero => [5,-3], # 550,-330 + start => [5,-9], # 550,-990 + clockabs => 110, + format => 'twostate', + preamble => 'P95#', + clientmodule => 'SD_UT', + length_min => '50', + length_max => '50', + }, + "96" => # Funk-Gong | Taster Grothe Mistral SE 03.1 / 01.1, Innenteil Grothe Mistral 200M(E) + # https://forum.fhem.de/index.php/topic,64251.msg940593.html?PHPSESSID=nufcvvjobdd8r7rgr0cq3qkrv0#msg940593 @coolheizer + # SD_BELL_104762 Alarm MC;LL=-430;LH=418;SL=-216;SH=226;D=23C823B1401F8;C=214;L=49;R=53; + # SD_BELL_104762 ring MC;LL=-439;LH=419;SL=-221;SH=212;D=238823B1001F8;C=215;L=49;R=69; + # SD_BELL_104762 ring low bat MC;LL=-433;LH=424;SL=-214;SH=210;D=238823B100248;C=213;L=49;R=65; + # SD_BELL_0253B3 Alarm MC;LL=-407;LH=451;SL=-195;SH=239;D=23C129D9E78;C=215;L=41;R=241; + # SD_BELL_0253B3 ring MC;LL=-412;LH=458;SL=-187;SH=240;D=238129D9A78;C=216;L=41;R=241; + # SD_BELL_024DB5 Alarm MC;LL=-415;LH=454;SL=-200;SH=226;D=23C126DAE58;C=215;L=41;R=246; + # SD_BELL_024DB5 ring MC;LL=-409;LH=448;SL=-172;SH=262;D=238126DAA58;C=215;L=41;R=238; + { + name => 'Grothe Mistral SE', + comment => 'Wireless doorbell Grothe Mistral SE 01.1 or 03.1', + id => '96', + knownFreqs => '868.35', + clockrange => [170,260], + format => 'manchester', + clientmodule => 'SD_BELL', + modulematch => '^P96#', + preamble => 'P96#', + length_min => '40', + length_max => '49', + method => \&lib::SD_Protocols::mcBit2Grothe, + }, + "97" => # Momento, remote control for wireless digital picture frame - elektron-bbs 2020-03-21 + # Short press repeatedly message 3 times, long press repeatedly until release. + # When sending, the original message is not reproduced, but the recipient also reacts to the messages generated in this way. + # Momento_0000064 play/pause MU;P0=-294;P1=237;P2=5829;P3=-3887;P4=1001;P5=-523;P6=504;P7=-995;D=01010101010101010101010234545454545454545454545454545454545454545456767454567454545456745456745456745454523454545454545454545454545454545454545454545676745456745454545674545674545674545452345454545454545454545454545454545454545454567674545674545454567454;CP=4;R=45;O; + # Momento_0000064 power MU;P0=-998;P1=-273;P2=256;P3=5830;P4=-3906;P5=991;P6=-527;P7=508;D=12121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121345656565656565656565656565656565656565656567070565670565656565670567056565670707034565656565656565656565656565656565656565656707056567;CP=2;R=40;O; + # Momento_0000064 up MU;P0=-1005;P1=-272;P2=258;P3=5856;P4=-3902;P5=1001;P6=-520;P7=508;D=0121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121213456565656565656565656565656565656565656565670705656705656567056565670565670567056345656565656565656565656565656565656565656567070565;CP=2;R=63;O; + { + name => 'Momento', + comment => 'Remote control for wireless digital picture frame', + id => '97', + knownFreqs => '433.92', + one => [2,-4], # 500, -1000 + zero => [4,-2], # 1000, -500 + start => [23,-15], # 5750, -3750 + clockabs => 250, + format => 'twostate', + preamble => 'P97#', + clientmodule => 'SD_UT', + length_min => '40', + length_max => '40', + }, + "98" => # Funk-Tuer-Gong: Modell GEA-028DB, Ningbo Rui Xiang Electrical Co.,Ltd., Vertrieb durch Walter Werkzeuge Salzburg GmbH, Art. Nr. K612021A + # https://forum.fhem.de/index.php/topic,109952.0.html 2020-04-12 + # SD_BELL_6A2C MU;P0=1488;P1=-585;P2=520;P3=-1509;P4=1949;P5=-5468;CP=2;R=38;D=01232301230123010101230123230101454501232301230123010101230123230101454501232301230123010101230123230101454501232301230123010101230123230101454501232301230123010101230123230101454501232301230123010101230123230101454501232301230123010101230123230101454501;O; + # SD_BELL_6A2C MU;P0=-296;P1=-1542;P2=1428;P3=-665;P4=483;P5=1927;P6=-5495;P7=92;CP=4;R=31;D=1234141232356562341412341234123232341234141232356562341412341234123232341234141232356562341412341234123232341234141232356562341412341234123232341234141232356562341412341234123232341234141232356562341412341234123232341234141232370;e;i; + { + name => 'GEA-028DB', + comment => 'Wireless doorbell', + knownFreqs => '433.92', + id => '98', + one => [1,-3], + zero => [3,-1], + start => [4,-11,4,-11], + clockabs => 500, + format => 'twostate', + clientmodule => 'SD_BELL', + modulematch => '^P98#', + preamble => 'P98#', + length_min => '16', + length_max => '16', + }, + "99" => # NAVARIS touch light switch Model No.: 44344.04 + # https://github.com/RFD-FHEM/RFFHEM/issues/828 + # Navaris_211073 MU;P0=-302;P1=180;P2=294;P3=-208;P4=419;P5=-423;D=01023101010101023232310102323451010231010101023101010231010101010232323101023234510102310101010231010102310101010102323231010232345101023101010102310101023101010101023232310102323451010231010101023101010231010101010232323101023234510102310101010231010102;CP=1;R=36;O; + # Navaris_13F8E3 MU;P0=406;P1=-294;P2=176;P3=286;P4=-191;P6=-415;D=01212134212134343434343434212121343434212121343406212121342121343434343434342121213434342121213434062121213421213434343434343421212134343421212134340621212134212134343434343434212121343434212121343406212121342121343434343434342121213434342121213434062121;CP=2;R=67;O; + { + name => 'Navaris 44344.04', + comment => 'Wireless touch light switch', + knownFreqs => '433.92', + id => '99', + one => [3,-2], + zero => [2,-3], + start => [4,-4], + clockabs => 100, + format => 'twostate', + clientmodule => 'SD_UT', + modulematch => '^P99#', + preamble => 'P99#', + length_min => '24', + length_max => '24', + }, + "100" => # Lacrosse, Mode 1 - IT+ + # https://forum.fhem.de/index.php/topic,106594.msg1034378.html#msg1034378 @Ralf9 + # ID=100, addr=42 temp=23.6 hum=44 bat=0 batInserted=128 MN;D=9AA6362CC8AAAA000012F8F4;R=4; + { + name => 'Lacrosse mode 1', + comment => 'example: TX25-IT,TX27-IT,TX29-IT,TX29DTH-IT,TX37,30.3143.IT,30.3144.IT', + id => '100', + knownFreqs => '868.3', + datarate => '17257.69', + sync => '2DD4', + modulation => '2-FSK', + regexMatch => qr/^9/, + register => ['0001','022E','0341','042D','05D4','0605','0780','0800','0D21','0E65','0F6A','1089','115C','1202','1322','14F8','1556','1916','1B43','1C68','2611'], + rfmode => 'Lacrosse_mode1', + clientmodule => 'LaCrosse', + length_min => '10', + method => \&lib::SD_Protocols::ConvLaCrosse, + }, + "101" => # ELV PCA 301 + # https://wiki.fhem.de/wiki/PCA301_Funkschaltsteckdose_mit_Energieverbrauchsmessung + # MN;D=0405019E8700AAAAAAAA0F13AA16ACC0540AAA49C814473A2774D208AC0B0167;N=3;R=6; + # MN;D=010503B7A101AAAAAAAA7492AA9885E53246E91113F897A4F80D30C8DE602BDF;N=3; + { + name => 'PCA 301', + comment => 'Energy socket', + id => '101', + knownFreqs => '868.950', + datarate => '6620.41', + sync => '2DD4', + modulation => '2-FSK', + register => ['0001','0246','0307','042D','05D4','06FF','0700','0802','0D21','0E6B','0FD0','1088','110B','1206','1322','14F8','1553','1700','1818','1916','1B43','1C68','1D91','23ED','2517','2611'], + rfmode => 'PCA301', + clientmodule => 'PCA301', + dispatchequals => 'true', + length_min => '24', + method => \&lib::SD_Protocols::ConvPCA301, + }, + "102" => # KoppFreeControl + # https://forum.fhem.de/index.php/topic,106594.msg1008936.html?PHPSESSID=er8d3f2ar1alq3rcijmu4efffo#msg1008936 @Ralf9 + # https://wiki.fhem.de/wiki/Kopp_Allgemein + # MN;D=07FA5E1721CC0F02FE000000000000; + { + name => 'KoppFreeControl', + comment => 'example: remotes, switches', + id => '102', + knownFreqs => '868.3', + datarate => '4785.5', + sync => 'AA54', + modulation => 'GFSK', + regexMatch => qr/^0/, # ToDo, check! fuer eine regexp Pruefung am Anfang vor dem method Aufruf + register => ['0001','012E','0246','0304','04AA','0554','060F','07E0','0800','0900','0A00','0B06','0C00','0D21','0E65','0F6A','1097','1183','1216','1363','14B9','1547','1607','170C','1829','1936','1A6C','1B07','1C40','1D91','1E87','1F6B','20F8','2156','2211','23EF','240A','253D','261F','2741'], + rfmode => 'KOPP_FC', + clientmodule => 'KOPP_FC', + method => \&lib::SD_Protocols::ConvKoppFreeControl, + }, + "103" => # Lacrosse Mode 2 - IT+ + # https://forum.fhem.de/index.php/topic,106278.msg1048506.html#msg1048506 @Ralf9 + # ID=103, addr=40 temp=19.2 hum=47 bat=0 batInserted=0 MN;D=9A05922F8180046818480800;N=2; + # https://forum.fhem.de/index.php/topic,106594.msg1034378.html#msg1034378 @Ralf9 + # ID=103, addr=52 temp=21.5 hum=47 bat=0 batInserted=0 MN;D=9D06152F5484791062004090;N=2; + { + name => 'Lacrosse mode 2', + comment => 'example: TX35-IT,TX35DTH-IT,30.3155WD,30.3156WD,EMT7110', + id => '103', + knownFreqs => '868.3', + datarate => '9579', + sync => '2DD4', + modulation => '2-FSK', + regexMatch => qr/^9/, + register => ['0001','022E','0341','042D','05D4','0605','0780','0800','0D21','0E65','0F6A','10C8','1182','1202','1322','14F8','1542','1916','1B43','1C68','2611'], + rfmode => 'Lacrosse_mode2', + clientmodule => 'LaCrosse', + length_min => '10', + method => \&lib::SD_Protocols::ConvLaCrosse, + }, + "104" => # Remote control TR60C-1 with touch screen from Satellite Electronic (Zhongshan) Ltd., Importer Westinghouse Lighting for ceiling fan Bendan + # https://forum.fhem.de/index.php?topic=53282.msg1045428#msg1045428 phoenix-anasazi 2020-04-21 + # TR60C1_0 light_off_fan_off MU;P0=18280;P1=-737;P2=419;P3=-331;P4=799;P5=-9574;P6=-7080;D=012121234343434341212121212121252121212123434343434121212121212125212121212343434343412121212121212521212121234343434341212121212121252121212123434343434121212121212126;CP=2;R=2; + # TR60C1_9 light_off_fan_4 MU;P0=14896;P1=-751;P2=394;P3=-370;P4=768;P5=-9572;P6=-21472;D=0121234123434343412121212121212523412123412343434341212121212121252341212341234343434121212121212125234121234123434343412121212121212523412123412343434341212121212121252341212341234343434121212121212126;CP=2;R=4; + # TR60C1_B light_on_fan_2 MU;P0=-96;P1=152;P2=-753;P3=389;P4=-374;P5=769;P6=-9566;P7=-19920;D=012345454523232345454545634523454523234545452323234545454563452345452323454545232323454545456345234545232345454523232345454545634523454523234545452323234545454563452345452323454545232323454545457;CP=3;R=1; + # https://github.com/RFD-FHEM/RFFHEM/issues/842 + { + name => 'TR60C-1', + comment => 'Remote control for example Westinghouse Bendan 77841B', + id => '104', + knownFreqs => '433.92', + one => [-1,2], # -380,760 + zero => [-2,1], # -760,380 + start => [-25,1], # -9500,380 + clockabs => 380, + format => 'twostate', + clientmodule => 'SD_UT', + modulematch => '^P104#', + preamble => 'P104#', + length_min => '16', + length_max => '16', + }, + "105" => # Remote control BF-301 from Shenzhen BOFU Mechanic & Electronic Co., Ltd. + # Protocol description found on https://github.com/akirjavainen/markisol/blob/master/Markisol.ino + # original remotes repeat 8 (multi) or 10 (single) times by default + # https://github.com/RFD-FHEM/RFFHEM/issues/861 stsirakidis 2020-06-27 + # BF_301_FAD0 down MU;P0=-697;P1=5629;P2=291;P3=3952;P4=-2459;P5=1644;P6=-298;P7=689;D=34567676767676207620767620762020202076202020762020207620202020207676762076202020767614567676767676207620767620762020202076202020762020207620202020207676762076202020767614567676767676207620767620762020202076202020762020207620202020207676762076202020767614;CP=2;R=41;O; + # BF_301_FAD0 stop MU;P0=5630;P1=3968;P2=-2458;P3=1642;P4=-285;P5=690;P6=282;P7=-704;D=12345454545454675467545467546767676754676767546754675467676767675454546754676767675402345454545454675467545467546767676754676767546754675467676767675454546754676767675402345454545454675467545467546767676754676767546754675467676767675454546754676767675402;CP=6;R=47;O; + # BF_301_FAD0 up MU;P0=-500;P1=5553;P2=-2462;P3=1644;P4=-299;P5=679;P6=298;P7=-687;D=01234545454545467546754546754676767675467676767675454546767676767545454675467546767671234545454545467546754546754676767675467676767675454546767676767545454675467546767671234545454545467546754546754676767675467676767675454546767676767545454675467546767671;CP=6;R=48;O; + { + name => 'BF-301', + comment => 'Remote control', + id => '105', + knownFreqs => '433.92', + one => [2,-1], # 660,-330 + zero => [1,-2], # 330,-660 + start => [17,-7,5,-1], # 5610,-2310,1650,-330 + clockabs => 330, + format => 'twostate', + clientmodule => 'SD_UT', + modulematch => '^P105#', + preamble => 'P105#', + length_min => '40', + length_max => '40', + }, + "106" => ## BBQ temperature sensor GT-TMBBQ-01s (Sender), GT-TMBBQ-01e (Empfaenger) + # https://forum.fhem.de/index.php/topic,114437.0.html KoelnSolar 2020-09-23 + # https://github.com/RFD-FHEM/RFFHEM/issues/892 Ralf9 2020-09-24 + # SD_WS_106_T T: 22.6 MS;P0=525;P1=-2051;P3=-8905;P4=-4062;D=0301010401010404010101040401010401040401040404;CP=0;SP=3;R=35;e;b=2;m0; + # SD_WS_106_T T: 88.1 MS;P1=-8514;P2=488;P3=-4075;P4=-2068;D=2123242423232423242423242324232323232423242324;CP=2;SP=1;R=31;e;b=70;s=4;m0; + # SD_WS_106_T T: 97.8 MS;P1=-9144;P2=469;P3=-4101;P4=-2099;D=2123242423232423242423242323232423242423242424;CP=2;SP=1;R=58;O;b=70;s=4;m0; + # Sensor sends every 5 seconds 1 message. + { + name => 'GT-TMBBQ-01', + comment => 'BBQ temperature sensor', + id => '106', + one => [1,-8], # 500,-4000 + zero => [1,-4], # 500,-2000 + sync => [1,-18], # 500,-9000 + clockabs => 500, + format => 'twostate', + preamble => 'W106#', + clientmodule => 'SD_WS', + modulematch => '^W106#', + length_min => '22', + length_max => '22', + }, + "107" => ## Fine Offset WH51, ECOWITT WH51, MISOL/1, Froggit DP100 Soil Moisture Sensor use with FSK 433.92 MHz + # https://forum.fhem.de/index.php/topic,109056.0.html + # SD_WS_107_H_00C6BF H: 31 MN;D=5100C6BF107F1FF8BBFFFFFFEE22;R=14; + # SD_WS_107_H_00C6BF H: 34 MN;D=5100C6BF107F22F8C3FFFFFF0443;R=14; + # SD_WS_107_H_00C6BF H: 35 MN;D=5100C6BF107F23F8C7FFFFFF5DA1;R=14; + { + name => 'WH51 433.92 MHz', + comment => 'Fine Offset WH51, ECOWITT WH51, MISOL/1, Froggit DP100 Soil moisture sensor', + id => '107', + knownFreqs => '433.92', + datarate => '17257.69', + sync => '2DD4', + modulation => '2-FSK', + regexMatch => qr/^51/, # Family code 0x51 (ECOWITT/FineOffset WH51) + preamble => 'W107#', + register => ['0001','022E','0343','042D','05D4','060E','0780','0800','0D10','0EB0','0F71','10A9','115C','1202','1322','14F8','1543','1916','1B43','1C68'], + rfmode => 'Fine_Offset_WH51_434', + clientmodule => 'SD_WS', + length_min => '28', + }, + "107.1" => # Fine Offset WH51, ECOWITT WH51, MISOL/1, Froggit DP100 Soil Moisture Sensor use with FSK 868.35 MHz + { + name => 'WH51 868.35 MHz', + comment => 'Fine Offset WH51, ECOWITT WH51, MISOL/1, Froggit DP100 Soil moisture sensor', + id => '107.1', + knownFreqs => '868.35', + datarate => '17257.69', + sync => '2DD4', + modulation => '2-FSK', + regexMatch => qr/^51/, # Family code 0x51 (ECOWITT/FineOffset WH51) + preamble => 'W107#', + register => ['0001','022E','0343','042D','05D4','060E','0780','0800','0D21','0E65','0FE8','10A9','115C','1202','1322','14F8','1543','1916','1B43','1C68'], + rfmode => 'Fine_Offset_WH51_868', + clientmodule => 'SD_WS', + length_min => '28', + }, + "108" => ## BRESSER 5-in-1 Weather Center, Bresser Professional Rain Gauge, Fody E42, Fody E43 - elektron-bbs 2021-05-02 + # https://github.com/RFD-FHEM/RFFHEM/issues/607 + # https://forum.fhem.de/index.php/topic,106594.msg1151467.html#msg1151467 + # T: 11 H: 43 W: 1.7 R: 7.6 MN;D=E6837FD73FE8EFEFFEBC89FFFF197C8028C017101001437600000001;R=230; + # elektron-bbs + # T: 20.7 H: 28 W: 0.8 R: 354.4 MN;D=E7527FF78FF7EFF8FDD7BBCAFF18AD80087008100702284435000002;R=213; + # T: -2.8 H: 78 W: 0 R: 354.4 MN;D=E8527FFF2FFFEFD7FF87BBCAF717AD8000D000102800784435080000;R=214; + # T: 8 H: 88 W: 1.3 R: 364.8 MN;D=E6527FEB0FECEF7FFF77B7C9FF19AD8014F013108000884836000003;R=211; + { + name => 'Bresser 5in1', + comment => 'BRESSER 5-in-1 weather center, rain gauge, Fody E42, Fody E43', + id => '108', + knownFreqs => '868.35', + datarate => '8.232', + sync => '2DD4', + modulation => '2-FSK', + rfmode => 'Bresser_5in1', + register => ['0001','022E','0346','042D','05D4','061A','07C0','0800','0D21','0E65','0FE8','1088','114C','1202','1322','14F8','1551','1916','1B43','1C68'], + preamble => 'W108#', + clientmodule => 'SD_WS', + length_min => '52', + method => \&lib::SD_Protocols::ConvBresser_5in1, + }, + "109" => ## Rojaflex HSR-15, HSTR-15, + # only tested remote control HSR-15 in mode bidirectional + # https://github.com/RFD-FHEM/RFFHEM/issues/955 - Hofyyy 2021-04-18 + # SD_Rojaflex_3122FD2_9 down MN;D=083122FD298A018A8E;R=0; + # SD_Rojaflex_3122FD2_9 stop MN;D=083122FD290A010A8E;R=244; + # SD_Rojaflex_3122FD2_9 up MN;D=083122FD291A011AAE;R=249; + { + name => 'Rojaflex', + comment => 'Rojaflex shutter', + id => '109', + knownFreqs => '433.92', + datarate => '9.9926', + sync => 'D391D391', + modulation => 'GFSK', + rfmode => 'Rojaflex', + regexMatch => qr/^08/, + register => ['0007','022E','0302','04D3','0591','060C','0788','0805','0D10','0EB0','0F71','10C8','1193','1213','1322','14F8','1535','170F','1916','1B43','1C40','2156','2211'], + preamble => 'P109#', + clientmodule => 'SD_Rojaflex', + length_min => '18', + length_max => '18', + }, + "110" => # ADE WS1907 Wetterstation mit Funk-Regenmesser + # https://github.com/RFD-FHEM/RFFHEM/issues/965 docolli 2021-05-14 + # T: 16.3 R: 26.6 MU;P0=970;P1=-112;P2=516;P3=-984;P4=2577;P5=-2692;P6=7350;D=01234343450503450503434343434505034343434343434343434343434343434505050503450345034343434343450345050345034505034503456503434505050343434343450503450503434343434505034343434343434343434343434343434505050503450345034343434343450345050345034505034503456503;CP=0;R=12;O; + # T: 12.6 R: 80.8 MU;P0=7344;P1=384;P2=-31380;P3=272;P4=-972;P5=2581;P6=-2689;P7=990;D=12345454545676745676745454545456745454545456767676745454545454545676767456745456767674545454545674567674545456745454545606745456767674545454545676745676745454545456745454545456767676745454545454545676767456745456767674545454545674567674545456745454545606;CP=7;R=19;O; + # T: 11.8 R: 82.1 MU;P0=-5332;P1=6864;P2=-2678;P3=994;P4=-977;P5=2693;D=01234545232323454545454523234523234545454545234545454523452345232345454545454523232345452323454545454545454523452323454545452323454521234545232323454545454523234523234545454545234545454523452345232345454545454523232345452323454545454545454523452323454545;CP=3;R=248;O; + # The sensor sends about every 45 seconds. + { + name => 'ADE_WS_1907', + comment => 'Weather station with rain gauge', + id => '110', + knownFreqs => '433.92', + one => [-3,1], # 2700,-900 + zero => [-1,3], # -900,2700 + start => [8], # 7200 + clockabs => 900, + format => 'twostate', + clientmodule => 'SD_WS', + modulematch => '^W110#', + preamble => 'W110#', + reconstructBit => '1', + length_min => '65', + length_max => '66', + }, + "111" => # Water Tank Level Monitor TS-FT002 + # https://github.com/RFD-FHEM/RFFHEM/issues/977 docolli 2021-06-05 + # T: 16.8 D: 111 MU;P0=-21110;P1=484;P2=-971;P3=-488;D=01213121212121213121312121312121213131312131313131212131313131312121212131313121313131213131313121213131312131313131313131313131212131312131312101213121212121213121312121312121213131312131313131212131313131312121212131313121313131213131313121213131312131;CP=1;R=26;O; + # T: 19 D: 47 MU;P0=-31628;P1=469;P2=-980;P3=-499;P4=-22684;D=01213121212121213121312121312121213131312131313131213131313131312121212131313121312121213131313131312131312131313131313131313131312121312131312141213121212121213121312121312121213131312131313131213131313131312121212131313121312121213131313131312131312131;CP=1;R=38;O; + # T: 20 D: 47 MU;P0=-5980;P1=464;P2=-988;P3=-511;P4=-22660;D=01213121212121213121312121312121213131312131313131213131313131312121212131313121313131213131313121312131312131313131313131313131213131312131312141213121212121213121312121312121213131312131313131213131313131312121212131313121313131213131313121312131312131;CP=1;R=38;O; + # The sensor sends normally every 180 seconds. + { + name => 'TS-FT002', + comment => 'Water tank level monitor with temperature', + id => '111', + knownFreqs => '433.92', + one => [1,-2], # 480,-960 + zero => [1,-1], # 480,-480 + start => [1,-2, 1,-1, 1,-2, 1,-2, 1,-2, 1,-2, 1,-2], # Sync 101.1111 + clockabs => 480, + format => 'twostate', + clientmodule => 'SD_WS', + modulematch => '^W111#', + preamble => 'W111#5F', # add sync 0101.1111 + length_min => '64', + length_max => '64', + }, + "112" => ## AVANTEK DB-LE + # Wireless doorbell & LED night light + # Sample: 20 Microseconds | 3 Repeats with ca. 1,57ms Pause + # A7129 -> FSK/GFSK Sub 1GHz Transceiver + # + # PPPPPSSSSDDDDDDDDDD + # | | |--------> Data + # | ||||---------> Sync + # |||||-------------> Preambel + # + # URH: aaaaa843484608a4224 + # FHEM: MN;D=08C114844FDA5CA2;R=48; + # MN;D=08C11484435D873B;R=47; + # !!! receiver hardware is required to complete in SD_BELL module !!! + { + name => 'Avantek', + comment => 'Wireless doorbell & LED night light', + id => '112', + knownFreqs => '433.3', + datarate => '50.087', + sync => '0869', + modulation => '2-FSK', + rfmode => 'Avantek', + register => ['0001','0246','0301','0408','0569','06FF','0780','0802','0D10','0EAA','0F56','108A','11F8','1202','1322','14F8','1551','1916','1B43','1C40','20FB','2156','2211'], + preamble => 'P112#', + clientmodule => 'SD_BELL', + length_min => '16', + length_max => '16', + }, + "113" => ## Wireless Grill Thermometer, Model name: GFGT 433 B1, WDJ7036, FCC ID: 2AJ9O-GFGT433B1, + # https://github.com/RFD-FHEM/RFFHEM/issues/992 @ muede-de 2021-07-13 + # The sensor sends more than 12 messages every 2 seconds. + # T: 24 T2: 29 MS;P1=-761;P2=249;P4=-3005;P5=718;P6=-270;D=24212156215656565621212121212121215621562121562156562156215656562156562156212121562121212121565621;CP=2;SP=4;R=34;O;m2; + # T: 203 T2: 300 MS;P1=-262;P2=237;P3=-760;P6=-2972;P7=721;D=26232371237171717123232323237171237171712371232323712323712371712371712371232323712371232371717123;CP=2;SP=6;R=1;O;m2; + # T: 201 T2: 257 MS;P2=-754;P3=247;P5=-2996;P6=718;P7=-272;D=35323267326767676732323232326767326767673232326767326732326732323267673267323232673232323232326732;CP=3;SP=5;R=3;O;m2; + { + name => 'GFGT_433_B1', + comment => 'Wireless Grill Thermometer', + id => '113', + knownFreqs => '433.92', + one => [3,-1], # 750,-250 + zero => [1,-3], # 250,-750 + sync => [1,-12], # 250,-3000 + clockabs => 250, + format => 'twostate', + preamble => 'W113#', + clientmodule => 'SD_WS', + modulematch => '^W113#', + reconstructBit => '1', + length_min => '47', + length_max => '48', + }, + "114" => ## TR401 (Well-Light) + # https://forum.fhem.de/index.php/topic,121103.0.html @Jake @Ralf9 + # TR401_0_2 off MU;P0=311;P1=585;P2=-779;P3=1255;P4=-1445;P5=-23617;P7=-5646;CP=1;R=230;D=12323234141414141514123414123232341414141415141234141232323414141414151412341412323234141414141514123414123232341414141415141234141232323414141414151412341412323234141414141517141232323414141414150;p; + # TR401_0_2 off MU;P0=-14293;P1=611;P2=-1424;P3=-753;P4=1277;P5=-23626;P6=-9108;P7=214;CP=1;R=240;D=1213421213434342121212121512134212134343421212121216701213421213434342121212121512134212134343421212121215121342121343434212121212151213421213434342121212121512134212134343421212121215121342121343434212121212151213421213434342121212121512134212134343421212121215121342121343434212121212151;p; + # TR401_0_2 on MU;P0=-1426;P1=599;P2=-23225;P3=-748;P4=1281;P5=372;P6=111;P7=268;CP=1;R=235;D=0121343401013434340101010101252621343401013434340101010101252705012134340101343434010101010125;p; + # TR401_0_2 on MU;P0=-14148;P1=-23738;P2=607;P3=-737;P4=1298;P5=-1419;P6=340;P7=134;CP=2;R=236;D=12343452523434345252525252161712343452523434345252525252160;p; + { + name => 'TR401', + comment => 'Remote control for example for Well-Light', + id => '114', + one => [-7,3], # -1400,600 + zero => [-4,6], # -800,1200 + start => [-118,3], # -23600,600 + clockabs => 200, + format => 'twostate', + preamble => 'P114#', + modulematch => '^P114#[13569BDE][13579BDF]F$', + clientmodule => 'SD_UT', + length_min => '12', + length_max => '12', + }, + "115" => ## BRESSER 6-in-1 Weather Center, Bresser new 5-in-1 sensors 7002550 + # https://github.com/RFD-FHEM/RFFHEM/issues/607#issuecomment-888542022 @ Alex-S1981 2021-07-28 + # The sensor alternately sends two different messages every 12 seconds. + # T: 15.2 H: 93 W: 0.8 MN;D=3BF120B00C1618FF77FF0458152293FFF06B0000;R=242; + # W: 0.6 R: 5.6 MN;D=1E6C20B00C1618FF99FF0458FFFFA9FF015B0000;R=241; + { + name => 'Bresser 6in1', + comment => 'BRESSER 6-in-1 weather center', + id => '115', + knownFreqs => '868.35', + datarate => '8.207', + sync => '2DD4', + modulation => '2-FSK', + rfmode => 'Bresser_6in1', + register => ['0001','0246','0344','042D','05D4','06FF','07C0','0802','0D21','0E65','0FE8','1088','114C','1202','1322','14F8','1551','1916','1B43','1C68'], + preamble => 'W115#', + clientmodule => 'SD_WS', + length_min => '36', + method => \&lib::SD_Protocols::ConvBresser_6in1, + }, + "116" => ## Thunder and lightning sensor Fine Offset WH57, aka Froggit DP60, aka Ambient Weather WH31L use with FSK 433.92 MHz + # https://forum.fhem.de/index.php/topic,122527.0.html + # I: lightning D: 6 MN;D=5780C65505060F6C78;R=39; + # I: lightning D: 20 MN;D=5780C655051401C4D0;R=37; + # I: disturbance D: 63 MN;D=5740C655053F0A7272;R=39; + { + name => 'WH57', + comment => 'Fine Offset WH57, Ambient Weather WH31L, Froggit DP60 Thunder and Lightning sensor', + id => '116', + knownFreqs => '433.92', + datarate => '17.257', + sync => '2DD4', + modulation => '2-FSK', + regexMatch => qr/^57/, # Family code 0x57 (FineOffset WH57) + preamble => 'W116#', + register => ['0001','022E','0343','042D','05D4','0609','0780','0800','0D10','0EB0','0F71','10A9','115C','1202','1322','14F8','1543','1916','1B43','1C68'], + rfmode => 'Fine_Offset_WH57_434', + clientmodule => 'SD_WS', + length_min => '18', + }, + "116.1" => ## Thunder and lightning sensor Fine Offset WH57, aka Froggit DP60, aka Ambient Weather WH31L use with FSK 868.35 MHz + { + name => 'WH57', + comment => 'Fine Offset WH57, Ambient Weather WH31L, Froggit DP60 Thunder and Lightning sensor', + id => '116.1', + knownFreqs => '868.35', + datarate => '17.257', + sync => '2DD4', + modulation => '2-FSK', + regexMatch => qr/^57/, # Family code 0x57 (FineOffset WH57) + preamble => 'W116#', + register => ['0001','022E','0343','042D','05D4','0609','0780','0800','0D21','0E65','0FE8','10A9','115C','1202','1322','14F8','1543','1916','1B43','1C68'], + rfmode => 'Fine_Offset_WH57_868', + clientmodule => 'SD_WS', + length_min => '18', + }, - ); - sub getProtocolList { - return \%protocols; - } + # "117" => reserved @elektron-bbs for BRESSER 7-in-1 Weather Center + + ######################################################################## + #### ### register informations from other hardware protocols #### #### + + # "993" => # HomeMatic + # # settings from CUL + # { + # name => 'HomeMatic', + # comment => '', + # id => '993', + # developId => 'm', + # knownFreqs => '868.3', + # datarate => '', + # sync => 'E9CA', + # modulation => '2-FSK', + # rfmode => 'HomeMatic', + # register => ['0007','012E','022E','030D','04E9','05CA','06FF','070C','0845','0900','0A00','0B06','0C00','0D21','0E65','0F6A','10C8','1193','1203','1322','14F8','1534','1607','1733','1818','1916','1A6C','1B43','1C40','1D91','1E87','1F6B','20F8','2156','2210','23AC','240A','253D','2611','2741'], + # }, + # "994" => # LaCrosse_mode_4 + # # https://wiki.fhem.de/wiki/JeeLink + # # https://forum.fhem.de/index.php/topic,106594.0.html?PHPSESSID=g0k1ruul2e3hmddm0uojaeurfl + # { + # name => 'LaCrosse_mode_4', + # comment => 'example: TX22 (WS 1600)', + # id => '994', + # developId => 'm', + # knownFreqs => '868.3', + # datarate => '8.842', + # sync => '2DD4', + # modulation => '2-FSK', + # rfmode => 'LaCrosse_mode_4', + # register => ['0001','012E','0246','0302','042D','05D4','06FF','0700','0802','0900','0A00','0B06','0C00','0D21','0E65','0F6A','1088','1165','1206','1322','14F8','1556','1607','1700','1818','1916','1A6C','1B43','1C68','1D91','1E87','1F6B','20F8','2156','2211','23EC','242A','2517','2611','2741'], + # }, + # "995" => # MAX + # # settings from CUL + # { + # name => 'MAX', + # comment => '', + # id => '995', + # developId => 'm', + # knownFreqs => '', + # datarate => '', + # sync => 'C626', + # modulation => '2-FSK', + # rfmode => 'MAX', + # register => ['0007','012E','0246','0307','04C6','0526','06FF','070C','0845','0900','0A00','0B06','0C00','0D21','0E65','0F6A','10C8','1193','1203','1322','14F8','1534','1607','173F','1828','1916','1A6C','1B43','1C40','1D91','1E87','1F6B','20F8','2156','2210','23AC','240A','253D','2611','2741'], + # }, + # "996" => # RIO-Funkprotokoll + # # https://forum.fhem.de/index.php/topic,107239.msg1011812.html#msg1011812 + # # send RIO in GFSK + # # https://wiki.fhem.de/wiki/Unbekannte_Funkprotokolle + # { + # name => 'RIO Protocol, send GFSK', + # comment => 'example: HS-8', + # id => '996', + # developId => 'm', + # knownFreqs => '868.3', + # datarate => '24.796', + # modulation => 'GFSK', + # rfmode => 'RIO', + # register => ['000D','012E','022D','0347','04D3','0591','063D','0704','0832','0900','0A00','0B06','0C00','0D21','0E65','0F6F','1086','1190','1218','1323','14B9','1540','1607','1700','1818','1914','1A6C','1B07','1C00','1D91','1E87','1F6B','20F8','21B6','2211','23EF','240D','253E','261F','2741'], + # }, + # "997" => # WMBus_C + # # https://wiki.fhem.de/wiki/WMBUS + # # settings from CUL + # { + # name => 'WMBus_C', + # comment => '', + # id => '997', + # developId => 'm', + # knownFreqs => '', + # datarate => '', + # modulation => '2-FSK', + # rfmode => 'WMBus_C', + # register => ['0029','012E','023F','0307','04D3','0591','06FF','0704','0845','0900','0A00','0B0F','0C00','0D1E','0EC4','0FEC','108C','1122','1202','1322','14F8','1547','1607','1730','1804','1976','1A6C','1B03','1C40','1D91','1E87','1F6B','20F8','2156','2210','23A9','240A','2520','260D','2741'], + # #regexMatch => qr/^9/, # ToDo, check! fuer eine regexp Pruefung am Anfang vor dem method Aufruf + # }, + # "998" => # WMBus_S + # # https://wiki.fhem.de/wiki/WMBUS + # # settings from CUL + # { + # name => 'WMBus_S', + # comment => '', + # id => '998', + # developId => 'm', + # knownFreqs => '', + # datarate => '', + # modulation => '2-FSK', + # rfmode => 'WMBus_S', + # register => ['0006','012E','0200','0300','0476','0596','06FF','0704','0802','0900','0A00','0B08','0C00','0D21','0E65','0F6A','106A','114A','1206','1322','14F8','1547','1607','1700','1818','192E','1A6D','1B04','1C09','1DB2','1E87','1F6B','20F8','21B6','2210','23EF','242A','2512','261F','2741'], + # #regexMatch => qr/^9/, # ToDo, check! fuer eine regexp Pruefung am Anfang vor dem method Aufruf + # }, + # "999" => # WMBus_T + # # https://wiki.fhem.de/wiki/WMBUS + # # settings from CUL + # { + # name => 'WMBus_T', + # comment => '', + # id => '999', + # developId => 'm', + # knownFreqs => '', + # datarate => '', + # modulation => '2-FSK', + # rfmode => 'WMBus_T', + # register => ['0006','012E','0200','0300','0454','053D','06FF','0704','0802','0900','0A00','0B08','0C00','0D21','0E6B','0FD0','105C','1104','1206','1322','14F8','1544','1607','1700','1818','192E','1ABF','1B43','1C09','1DB5','1E87','1F6B','20F8','21B6','2210','23EF','242A','2513','261F','2741'], + # #regexMatch => qr/^9/, # ToDo, check! fuer eine regexp Pruefung am Anfang vor dem method Aufruf + # }, + + ######################################################################## + #### ### old information from incomplete implemented protocols #### #### + + # "" => ## Livolo + # https://github.com/RFD-FHEM/RFFHEM/issues/29 + # MU;P0=-195;P1=151;P2=475;P3=-333;D=0101010101 02 01010101010101310101310101010101310101 02 01010101010101010101010101010101010101 02 01010101010101010101010101010101010101 02 010101010101013101013101;CP=1; + # + # protocol sends 24 to 47 pulses per message. + # First pulse is the header and is 595 μs long. All subsequent pulses are either 170 μs (short pulse) or 340 μs (long pulse) long. + # Two subsequent short pulses correspond to bit 0, one long pulse corresponds to bit 1. There is no footer. The message is repeated for about 1 second. + # + # Start bit: | |___| bit 0: | |___| bit 1: | |___| + # { + # name => 'Livolo', + # comment => 'remote control / dimmmer / switch ...', + # id => '', + # knownFreqs => '', + # one => [3], + # zero => [1], + # start => [5], + # clockabs => 110, #can be 90-140 + # format => 'twostate', + # preamble => 'uXX#', + # #clientmodule => '', + # #modulematch => '', + # length_min => '16', + # #length_max => '', # missing + # filterfunc => 'SIGNALduino_filterSign', + # }, + + ######################################################################## + ); } diff --git a/fhem/FHEM/lib/SD_Protocols.pm b/fhem/FHEM/lib/SD_Protocols.pm index 4e8ca3590..b8eae432c 100644 --- a/fhem/FHEM/lib/SD_Protocols.pm +++ b/fhem/FHEM/lib/SD_Protocols.pm @@ -1,201 +1,2085 @@ ################################################################################ -# The file is part of the SIGNALduino project +# $Id$ # - +# The file is part of the SIGNALduino project +# v3.5.x - https://github.com/RFD-FHEM/RFFHEM +# +# 2016-2019 S.Butzek, Ralf9 +# 2019-2021 S.Butzek, HomeAutoUser, elektron-bbs +# +################################################################################ package lib::SD_Protocols; -our $VERSION = '0.20'; use strict; use warnings; +use Carp qw(croak carp); +use Digest::CRC; +our $VERSION = '2.05'; +use Storable qw(dclone); +use Scalar::Util qw(blessed); +use Data::Dumper; -#=item new($) #This functons, will initialize the given Filename containing a valid protocolHash -#=item LoadHash($) #This functons, will load protocol hash from file into a hash -#=item exists() # This functons, will return true if the given id exists otherwise false -#=item getKeys() # This functons, will return all keys from the protocol hash -#=item checkProperty() #This functons, will return a value from the Protocolist and check if the key exists and a value is defined optional you can specify a optional default value that will be returned -#=item getProperty() #This functons, will return a value from the Protocolist without any checks -#=item setDefaults() #This functons, will add common Defaults to the Protocollist +############################# package lib::SD_Protocols +=item new() -# - - - - - - - - - - - - -#=item new($) -# This functons, will initialize the given Filename containing a valid protocolHash -# First Parameter is for filename (full or relativ path) to be loaded -# Returns string with error value or undef -# =cut -# $id +This function will initialize the given Filename containing a valid protocolHash. +First Parameter is for filename (full or relativ path) to be loaded. +Returns created object -sub new -{ - my $ret = LoadHash(@_); - return $ret->{'error'} if (exists($ret->{'error'})); - - ## Do some initialisation needed here - - return undef; +=cut + +sub new { + my $class = shift; + croak "Illegal parameter list has odd number of values" if @_ % 2; + my %args = @_; + my $self = {}; + + $self->{_protocolFilename} = $args{filename} // q[]; + $self->{_protocols} = undef; + $self->{_filetype} = $args{filetype} // 'PerlModule'; + $self->{_logCallback} = undef; + bless $self, $class; + + if ( $self->{_protocolFilename} ) { + + ( $self->{_filetype} eq 'json' ) + ? $self->LoadHashFromJson( $self->{_protocolFilename} ) + : $self->LoadHash( $self->{_protocolFilename} ); + } + return $self; } -# - - - - - - - - - - - - -#=item LoadHash($) -# This functons, will load protocol hash from file into a hash. -# First Parameter is for filename (full or relativ path) to be loaded -# Returns a reference to error or the hash -# =cut -# $id +############################# package lib::SD_Protocols +=item STORABLE_freeze() +This function is not currently explained. - -sub LoadHash -{ - if (! -e $_[0]) { - return \%{ {"error" => "File $_[0] does not exsits"}}; - } - delete($INC{$_[0]}); - if( ! eval { require "$_[0]"; 1 } ) { - return \%{ {"error" => $@}}; - } - setDefaults(); - return getProtocolList(); +Input: +Output: + +=cut + +sub STORABLE_freeze { + my $self = shift; + return join( q[:], ( $self->{_protocolFilename}, $self->{_filetype} ) ); +} + +############################# package lib::SD_Protocols +=item STORABLE_thaw() + +This function is not currently explained. + +Input: +Output: + +=cut + +sub STORABLE_thaw { + my ( $self, $cloning, $frozen ) = @_; + ( $self->{_protocolFilename}, $self->{_filetype} ) = + split( /:/xms, $frozen ); + $self->LoadHash(); + $self->LoadHashFromJson(); + return; } -# - - - - - - - - - - - - -#=item exists() -# This functons, will return true if the given ID exists otherwise false -# =cut -# $id -sub exists($) -{ - return exists($lib::SD_ProtocolData::protocols{$_[0]}); +############################# package lib::SD_Protocols +=item _checkInvocant() + +This function, checks if input param is a valid object otherwise it will croak with error message +Input: ($object); +Output: $object or croak if not an object + +=cut + +sub _checkInvocant { + my $thing = shift; + my $caller = caller; + + if( !defined $thing ) { + croak "The invocant is not defined"; + } + elsif( !ref $thing ) { + croak "The invocant is not a reference"; + } + elsif( !blessed $thing ) { + croak "The invocant is not an object"; + } + elsif( !$thing->isa($caller) ) { + croak "The invocant is not a subclass of $caller"; + } + + return $thing; } -# - - - - - - - - - - - - -#=item getProtocolList() -# This functons, will return a reference to the protocol hash -# =cut -# $id, $propertyname, -sub getProtocolList() { - return \%lib::SD_ProtocolData::protocols; } -# - - - - - - - - - - - - -#=item getKeys() -# This functons, will return all keys from the protocol hash -# -# returns "" if the var is not defined -# =cut -# $id, $propertyname, +############################# package lib::SD_Protocols +=item LoadHashFromJson() -sub getKeys() { - return keys %lib::SD_ProtocolData::protocols; } +This function, will load protocol hash from json file into a hash. +First Parameter is for filename (full or relativ path) to be loaded. +Returns error or undef on success -# - - - - - - - - - - - - -#=item checkProperty() -# This functons, will return a value from the Protocolist and check if the key exists and a value is defined optional you can specify a optional default value that will be returned -# -# returns "" if the var is not defined -# =cut -# $id, $propertyname,$default +Input: ($object,$filename); +Output: -sub checkProperty($$;$) -{ - return getProperty($_[0],$_[1]) if exists($lib::SD_ProtocolData::protocols{$_[0]}{$_[1]}) && defined($lib::SD_ProtocolData::protocols{$_[0]}{$_[1]}); - return $_[2]; # Will return undef if $default is not provided +=cut + +sub LoadHashFromJson { + my $self = shift // carp 'Not called within an object'; + my $filename = shift // $self->{_protocolFilename}; + + return if ( $self->{_filetype} ne 'json' ); + + if ( !-e $filename ) { + return qq[File $filename does not exsits]; + } + + open( my $json_fh, '<:encoding(UTF-8)', $filename ) + or croak("Can't open \$filename\": $!\n"); + my $json_text = do { local $/ = undef; <$json_fh> }; + close $json_fh or croak "Can't close '$filename' after reading"; + + use JSON; + my $json = JSON->new; + $json = $json->relaxed(1); + my $ver = $json->incr_parse($json_text); + my $prot = $json->incr_parse(); + + $self->{_protocols} = $prot // 'undef'; + $self->{_protocolsVersion} = $ver->{version} // 'undef'; + + $self->setDefaults(); + $self->{_protocolFilename} = $filename; + return; } -# - - - - - - - - - - - - -#=item getProperty() -# This functons, will return a value from the Protocolist without any checks -# -# returns "" if the var is not defined -# =cut -# $id, $propertyname +############################# package lib::SD_Protocols, test exists +=item LoadHash() -sub getProperty($$) -{ - return $lib::SD_ProtocolData::protocols{$_[0]}{$_[1]}; +This function, will load protocol hash from perlmodule file. +First Parameter is for filename (full or relativ path) to be loaded. +Returns error or undef on success + +Input: ($object,$filename); +Output: + +=cut + +sub LoadHash { + my $self = shift // carp 'Not called within an object'; + my $filename = shift // $self->{_protocolFilename}; + + return if ( $self->{_filetype} ne "PerlModule" ); + + if ( !-e $filename ) { + return qq[File $filename does not exists]; + } + + return $@ if ( !eval { require $filename; 1 } ); + $self->{_protocols} = \%lib::SD_ProtocolData::protocols; + $self->{_protocolsVersion} = $lib::SD_ProtocolData::VERSION; + + delete( $INC{$filename} ); # Unload package, because we only wanted the hash + + $self->setDefaults(); + $self->{_protocolFilename} = $filename; + return; } -# - - - - - - - - - - - - -#=item getProtocolVersion() -# This functons, will return a version value of the Protocolist -# -# =cut +############################# package lib::SD_Protocols, test exists +=item protocolexists() -sub getProtocolVersion -{ - return $lib::SD_ProtocolData::VERSION; +This function, will return true if the given ID exists otherwise false + +Input: ($object,$protocolID); +Output: + +=cut + +sub protocolExists { + my $self = shift // carp 'Not called within an object'; + my $pId= shift // carp "Illegal parameter number, protocol id was not specified"; + return exists($self->{_protocols}->{$pId}); } -# - - - - - - - - - - - - -#=item setDefaults() -# This functon will add common Defaults to the Protocollist -# -# =cut +############################# package lib::SD_Protocols, test exists +=item getProtocolList() -sub setDefaults -{ - foreach my $id (getKeys()) - { - my $format = getProperty($id,"format"); - - if (defined ($format) && $format eq "manchester") - { - # Manchester defaults : - $lib::SD_ProtocolData::protocols{$id}{method} = \&lib::SD_Protocols::MCRAW if (!defined(checkProperty($id,"method"))); - } - elsif (getProperty($id,"sync")) - { - # Messages with sync defaults : - - } - elsif (getProperty($id,"clockabs")) - { - # Messages without sync defaults : - $lib::SD_ProtocolData::protocols{$id}{length_min} = 8 if (!defined(checkProperty($id,"length_min"))); - } - - } +This function, will return a reference to the protocol hash + +=cut + +sub getProtocolList { + my $self = shift // carp 'Not called within an object'; + return $self->{_protocols}; } -# - - - - - - - - - - - - -#=item binStr2hexStr() -# This functon will convert binary string into its hex representation as string -# -# =cut +############################# package lib::SD_Protocols, test exists +=item getKeys() -sub binStr2hexStr { - my $num = shift; - my $WIDTH = 4; - my $index = length($num) - $WIDTH; - my $hex = ''; - do { - my $width = $WIDTH; - if ($index < 0) { - $width += $index; - $index = 0; +This function, will return all keys from the protocol hash + +=cut + +sub getKeys { + my $self = shift // carp 'Not called within an object'; + + my $filter = shift // undef; + if (defined $filter) + { + my (@keys) = grep { exists $self->{_protocols}->{$_}->{$filter} } keys %{$self->{_protocols}}; + return @keys; + } + + my (@ret) = keys %{ $self->{_protocols} }; + return @ret; +} + +############################# package lib::SD_Protocols, test exists +=item checkProperty() + +This function, will return a value from the Protocolist and +check if the key exists and a value is defined optional you can specify a optional default value that will be returned + +returns undef if the var is not defined + +Input: ($object,$id,$valueName); +Output: + +=cut + +sub checkProperty { + my $self = shift // carp 'Not called within an object'; + my $id = shift // return; + my $valueName = shift // return; + my $default = shift // undef; + + return $self->{_protocols}->{$id}->{$valueName} + if exists( $self->{_protocols}->{$id}->{$valueName} ) + && defined( $self->{_protocols}->{$id}->{$valueName} ); + return $default; # Will return undef if $default is not provided +} + +############################# package lib::SD_Protocols, test exists +=item getProperty() + +This function, will return a value from the Protocolist without any checks + +returns undef if the var is not defined + +Input: ($object,$protocolID,$valueName); +Output: + +=cut + +sub getProperty { + my $self = shift // carp 'Not called within an object'; + my $id = shift // return; + my $valueName = shift // return; + + return $self->{_protocols}->{$id}->{$valueName} + if ( exists $self->{_protocols}->{$id}->{$valueName} ); + return; +} + +############################# package lib::SD_Protocols, test exists +=item getProtocolVersion() + +This function, will return a version value of the Protocolist + +=cut + +sub getProtocolVersion { + my $self = shift // carp 'Not called within an object'; + return $self->{_protocolsVersion}; +} + +############################# package lib::SD_Protocols, test exists +=item setDefaults() + +This function will add common Defaults to the Protocollist + +=cut + +sub setDefaults { + my $self = shift // carp 'Not called within an object'; + + for my $id ( $self->getKeys() ) + { + my $format = $self->getProperty($id,'format'); + + if ( defined $format && ($format eq 'manchester' || $format =~ 'FSK') ) + { + # Manchester defaults : + my $cref = $self->checkProperty( $id, 'method' ); + ( !defined $cref && $format eq 'manchester' ) + ? $self->{_protocols}->{$id}->{method} = + \&lib::SD_Protocols::MCRAW + : undef; + + if ( defined $cref ) { + $cref =~ s/^\\&//xms; + ( ref $cref ne 'CODE' ) + ? $self->{_protocols}->{$id}->{method} = eval { \&$cref } + : undef; + } + } + elsif ( defined( $self->getProperty( $id, 'sync' ) ) ) { + + # Messages with sync defaults : + } + elsif ( defined( $self->getProperty( $id, 'clockabs' ) ) ) { + + # Messages without sync defaults : + ( !defined( $self->checkProperty( $id, 'length_min' ) ) ) + ? $self->{_protocols}->{$id}->{length_min} = 8 + : undef; + } + else { + + } + } + return; +} + +############################# package lib::SD_Protocols, test exists +=item binStr2hexStr() + +This function will convert binary string into its hex representation as string + +Input: binary string +Output: + hex string + +=cut + +sub binStr2hexStr { + shift if ref $_[0] eq __PACKAGE__; + + my $num = shift // return; + return if ( $num !~ /^[01]+$/xms ); + my $WIDTH = 4; + my $index = length($num) - $WIDTH; + my $hex = ''; + do { + my $width = $WIDTH; + if ( $index < 0 ) { + $width += $index; + $index = 0; + } + my $cut_string = substr( $num, $index, $width ); + $hex = sprintf( '%X', oct("0b$cut_string") ) . $hex; + $index -= $WIDTH; + } while ( $index > ( -1 * $WIDTH ) ); + return $hex; +} + +############################# package lib::SD_Protocols, test exists + +=item LengthInRange() + +This function checks if a given length is in range of the valid min and max length for the given protocolId + +Input: ($object,$protocolID,$message_length); +Output: + on success array (returnCode=1, '') + otherwise array (returncode=0,"Error message") +=cut + +sub LengthInRange { + my $self = shift // carp 'Not called within an object'; + my $id = shift // carp 'protocol ID must be provided'; + my $message_length = shift // return (0,'no message_length provided'); + + return (0,'protocol does not exists') if (!$self->protocolExists($id)); + + if ($message_length < $self->checkProperty($id,'length_min',-1)) { + return (0, 'message is to short'); + } + elsif (defined $self->getProperty($id,'length_max') && $message_length > $self->getProperty($id,'length_max')) { + return (0, 'message is to long'); + } + return (1,q{}); +} + +############################# package lib::SD_Protocols, test exists +=item MCRAW() + +This function is desired to be used as a default output helper for manchester signals. +It will check for length_max and return a hex string + +Input: $object,$name,$bitData,$id,$mcbitnum +Output: + hex string + or array (-1,"Error message") + +=cut + +sub MCRAW { + my ( $self, $name, $bitData, $id, $mcbitnum ) = @_; + $self // carp 'Not called within an object'; + + return (-1," message is to long") if ($mcbitnum > $self->checkProperty($id,"length_max",0) ); + return(1,binStr2hexStr($bitData)); +} + +############################# package lib::SD_Protocols +=item registerLogCallback() + +=cut + +sub registerLogCallback { + my $self = shift // carp 'Not called within an object'; + my $callback = shift // carp 'coderef must be provided'; + + ( ref $callback eq 'CODE' ) + ? $self->{_logCallback} = $callback + : carp 'coderef must be provided for callback'; + + return; +} + +############################# package lib::SD_Protocols +=item _logging() + +This function transfers the data to the sub which is referenced by the code ref. +example: $self->_logging('something happend','3') + +=cut + +sub _logging { + my $self = shift // carp 'Not called within an object'; + my $message = shift // carp 'message must be provided'; + my $level = shift // 3; + + if ( defined $self->{_logCallback} ) { + $self->{_logCallback}->( $message, $level ); + } + return; +} + +######################### package lib::SD_Protocols ######################### +### all functions for RAWmsg processing or module preparation ### +############################################################################# + +############################ +# ASK/OOK method functions # +############################ + +sub _ASK_OOK_methods_behind_here { + # only for functionslist - no function! +} + +############################# package lib::SD_Protocols, test exists +=item dec2binppari() + +This function calculated. It converts a decimal number with a width of 8 bits into binary format, +calculates the parity, appends the parity bit and returns this 9 bit. + +Input: $num +Output: + calculated number binary with parity + +=cut + +sub dec2binppari { # dec to bin . parity + shift if ref $_[0] eq __PACKAGE__; + my $num = shift // carp 'must be called with an number'; + my $parity = 0; + my $nbin = sprintf( "%08b", $num ); + for my $c ( split //, $nbin ) { + $parity ^= $c; + } + return qq[$nbin$parity]; # bin(num) . paritybit +} + +############################# package lib::SD_Protocols, test exists +=item mcBit2AS() + +extract the message from the bitdata if it looks like valid data + +Input: ($object,$name,$bitData,$protocolID, optional: length $bitData); +Output: + on success array (returnCode=1, hexData) + otherwise array (returncode=-1,"Error message") + +=cut + +sub mcBit2AS { + my $self = shift // carp 'Not called within an object' && return (0,'no object provided'); + my $name = shift // 'anonymous'; + my $bitData = shift // carp 'bitData must be perovided' && return (0,'no bitData provided'); + my $id = shift // carp 'protocol ID must be provided' && return (0,'no protocolId provided'); + my $mcbitnum = shift // length $bitData; + + if(index($bitData,'1100',16) >= 0) # $rawData =~ m/^A{2,3}/) + { # Valid AS detected! + my $message_start = index($bitData,'1100',16); + $self->_logging( qq[lib/mcBit2AS, AS protocol detected], 5 ); + + my $message_end=index($bitData,'1100',$message_start+16); + $message_end = length($bitData) if ($message_end == -1); + my $message_length = $message_end - $message_start; + + return (-1,' message is to short') if ($message_length < $self->checkProperty($id,'length_min',-1) ); + return (-1,' message is to long') if (defined $self->getProperty($id,'length_max' ) && $message_length > $self->getProperty($id,'length_max') ); + + my $msgbits =substr($bitData,$message_start); + my $ashex = lib::SD_Protocols::binStr2hexStr($msgbits); # output with length before + + $self->_logging( qq[$name: AS, protocol converted to hex: ($ashex) with length ($message_length) bits \n], 5 ); + + return (1,$ashex); + } + return (-1,undef); +} + +############################# package lib::SD_Protocols, test exists +=item mcBit2Grothe() + +extract the message from the bitdata if it looks like valid data + +Input: ($object,$name,$bitData,$protocolID, optional: length $bitData); +Output: + on success array (returnCode=1, hexData) + otherwise array (returncode=-1,"Error message") + +=cut + +sub mcBit2Grothe { + my $self = shift // carp 'Not called within an object' && return (0,'no object provided'); + my $name = shift // "anonymous"; + my $bitData = shift // carp 'bitData must be perovided' && return (0,'no bitData provided'); + my $id = shift // carp 'protocol ID must be provided' && return (0,'no protocolId provided');;; + my $message_length = shift // length $bitData; + + my $bitLength; + + $bitData = substr($bitData, 0, $message_length); + my $preamble = '01000111'; + my $pos = index($bitData, $preamble); + if ($pos < 0 || $pos > 5) { + $self->_logging( qq[lib/mcBit2Grothe, protocol id $id, start pattern ($preamble) not found], 3 ); + return (-1,qq[Start pattern ($preamble) not found]); + } else { + if ($pos == 1) { # eine Null am Anfang zuviel + $bitData =~ s/^0//; # eine Null am Anfang entfernen + } + $bitLength = length($bitData); + my ($rcode, $rtxt) = $self->LengthInRange($id, $bitLength); + if (!$rcode) { + $self->_logging( qq[lib/mcBit2Grothe, protocol id $id, $rtxt], 3 ); + return (-1,qq[$rtxt]); + } + } + my $hex = lib::SD_Protocols::binStr2hexStr($bitData); + $self->_logging( q[lib/mcBit2Grothe, protocol id $id detected, $bitData ($bitLength], 4 ); + return (1,$hex); ## Return the bits unchanged in hex +} + +############################# package lib::SD_Protocols, test exists +=item mcBit2Hideki() + +extract the message from the bitdata if it looks like valid data + +Input: ($object,$name,$bitData,$protocolID, optional: length $bitData); +Output: + on success array (returnCode=1, hexData) + otherwise array (returncode=-1,"Error message") + +=cut + +sub mcBit2Hideki { + my $self = shift // carp 'Not called within an object' && return (0,'no object provided'); + my $name = shift // 'anonymous'; + my $bitData = shift // carp 'bitData must be perovided' && return (0,'no bitData provided'); + my $id = shift // carp 'protocol ID must be provided' && return (0,'no protocolId provided'); + my $mcbitnum = shift // length $bitData; + + if ($mcbitnum == 89) { # optimization when the beginning was missing + my $bit0 = substr($bitData,0,1); + $bit0 = $bit0 ^ 1; + $bitData = $bit0 . $bitData; + $self->_logging( qq[lib/mcBit2Hideki, L=$mcbitnum add bit $bit0 at begin $bitData], 5 ); + } + + my $message_start = index($bitData,'10101110'); # normal rawMSG + my $invert = 0; + my $message_start_invert = index($bitData,'01010001'); # invert rawMSG + # 10101110 can occur again in raw MSG -> comparison with inverted start 01010001 + + if ( $message_start < 0 || ( $message_start_invert!= -1 && $message_start > 0 && ($message_start_invert < $message_start) ) ) { + $bitData =~ tr/01/10/; # invert message + $message_start = index($bitData,'10101110'); # 0x75 but in reverse order + $invert = 1; + } + + if ($message_start >= 0 ) # 0x75 but in reverse order + { + $self->_logging( qq[lib/mcBit2Hideki, Hideki protocol (invert=$invert) detected], 5 ); + + # Todo: Mindest Laenge fuer startpunkt vorspringen + # Todo: Wiederholung auch an das Modul weitergeben, damit es dort geprueft werden kann + my $message_end = index($bitData,'10101110',$message_start+71); # pruefen auf ein zweites 0x75, mindestens 72 bit nach 1. 0x75, da der Regensensor minimum 8 Byte besitzt je byte haben wir 9 bit + $message_end = length($bitData) if ($message_end == -1); + my $message_length = $message_end - $message_start; + + return (-1,' message is to short') if ($message_length < $self->checkProperty($id,'length_min',-1) ); + return (-1,' message is to long') if (defined $self->getProperty($id,'length_max' ) && $message_length > $self->getProperty($id,'length_max') ); + + my $hidekihex = q{}; + my $idx; + + for ($idx=$message_start; $idx<$message_end; $idx=$idx+9) + { + my $byte = q{}; + $byte= substr($bitData,$idx,8); ## Ignore every 9th bit + $self->_logging( qq[lib/mcBit2Hideki, byte in order $byte], 5 ); + $byte = scalar reverse $byte; + $self->_logging( qq[lib/mcBit2Hideki, byte reversed $byte , as hex: "].sprintf('%X', oct("0b$byte")), 5 ); + + $hidekihex=$hidekihex.sprintf('%02X', oct("0b$byte")); + } + + ($invert == 0) + ? $self->_logging( qq[lib/mcBit2Hideki, receive data is not inverted], 4 ) + : $self->_logging( qq[lib/mcBit2Hideki, receive data is inverted], 4 ); + + $self->_logging( qq[lib/mcBit2Hideki, protocol converted to hex: $hidekihex with $message_length bits, messagestart $message_start], 4 ); + + return (1,$hidekihex); ## Return only the original bits, include length + } + $self->_logging( qq[lib/mcBit2Hideki, start pattern (10101110) not found], 4 ); + return (-1,undef); +} + +############################# package lib::SD_Protocols, test exists +=item mcBit2Maverick() + +This function extract the message from the bitdata if it looks like valid data + +Input: ($object,$name,$bitData,$protocolID, optional: length $bitData); +Output: + on success array (returnCode=1, hexData) + otherwise array (returncode=-1,"Error message") + +=cut + +sub mcBit2Maverick { + my $self = shift // carp 'Not called within an object' && return (0,'no object provided'); + my $name = shift // 'anonymous'; + my $bitData = shift // carp 'bitData must be perovided' && return (0,'no bitData provided'); + my $id = shift // carp 'protocol ID must be provided' && return (0,'no protocolId provided'); + my $mcbitnum = shift // length $bitData; + + + if ($bitData =~ m/(101010101001100110010101)/xms) + { # Valid Maverick header detected + my $header_pos=$+[1]; + $self->_logging( qq[lib/mcBit2Maverick, protocol detected: header_pos = $header_pos], 4 ); + my $hex=lib::SD_Protocols::binStr2hexStr(substr($bitData,$header_pos,26*4)); + return (1,$hex); ## Return the bits unchanged in hex + } else { + return return (-1,undef); + } +} + +############################# package lib::SD_Protocols, test exists +=item mcBit2OSV1() + +extract the message from the bitdata if it looks like valid data + +Input: ($object,$name,$bitData,$protocolID, optional: length $bitData); +Output: + on success array (returnCode=1, hexData) + otherwise array (returncode=-1,"Error message") + +=cut + +sub mcBit2OSV1 { + my $self = shift // carp 'Not called within an object' && return (0,'no object provided'); + my $name = shift // 'anonymous'; + my $bitData = shift // carp 'bitData must be perovided' && return (0,'no bitData provided'); + my $id = shift // carp 'protocol ID must be provided' && return (0,'no protocolId provided');;; + my $mcbitnum = shift // length $bitData; + + return (-1,' message is to short') if ($mcbitnum < $self->checkProperty($id,'length_min',-1) ); + return (-1,' message is to long') if (defined $self->getProperty($id,'length_max') && $mcbitnum > $self->getProperty($id,'length_max') ); + + if (substr($bitData,20,1) != 0) { + $bitData =~ tr/01/10/; # invert message and check if it is possible to deocde now + } + my $calcsum = oct( '0b' . reverse substr($bitData,0,8)); + $calcsum += oct( '0b' . reverse substr($bitData,8,8)); + $calcsum += oct( '0b' . reverse substr($bitData,16,8)); + $calcsum = ($calcsum & 0xFF) + ($calcsum >> 8); + my $checksum = oct( '0b' . reverse substr($bitData,24,8)); + + if ($calcsum != $checksum) { # Checksum + return (-1,qq[OSV1 - ERROR checksum not equal: $calcsum != $checksum]); + } + + $self->_logging( qq[lib/mcBit2OSV1, input data: $bitData], 4 ); + my $newBitData = '00001010'; # Byte 0: Id1 = 0x0A + $newBitData .= '01001101'; # Byte 1: Id2 = 0x4D + my $channel = substr($bitData,6,2); # Byte 2 h: Channel + if ($channel eq '00') { # in 0 LSB first + $newBitData .= '0001'; # out 1 MSB first + } elsif ($channel eq '10') { # in 4 LSB first + $newBitData .= '0010'; # out 2 MSB first + } elsif ($channel eq '01') { # in 4 LSB first + $newBitData .= '0011'; # out 3 MSB first + } else { # in 8 LSB first + return (-1,qq[$name: OSV1 - ERROR channel not valid: $channel]); + } + $newBitData .= '0000'; # Byte 2 l: ???? + $newBitData .= '0000'; # Byte 3 h: address + $newBitData .= reverse substr($bitData,0,4); # Byte 3 l: address (Rolling Code) + $newBitData .= reverse substr($bitData,8,4); # Byte 4 h: T 0,1 + $newBitData .= '0' . substr($bitData,23,1) . '00'; # Byte 4 l: Bit 2 - Batterie 0=ok, 1=low (< 2,5 Volt) + $newBitData .= reverse substr($bitData,16,4); # Byte 5 h: T 10 + $newBitData .= reverse substr($bitData,12,4); # Byte 5 l: T 1 + $newBitData .= '0000'; # Byte 6 h: immer 0000 + $newBitData .= substr($bitData,21,1) . '000'; # Byte 6 l: Bit 3 - Temperatur 0=pos | 1=neg, Rest 0 + $newBitData .= '00000000'; # Byte 7: immer 0000 0000 + # calculate new checksum over first 16 nibbles + $checksum = 0; + for (my $i = 0; $i < 64; $i = $i + 4) { + $checksum += oct( '0b' . substr($newBitData, $i, 4)); + } + $checksum = ($checksum - 0xa) & 0xff; + $newBitData .= sprintf('%08b',$checksum); # Byte 8: new Checksum + $newBitData .= '00000000'; # Byte 9: immer 0000 0000 + my $osv1hex = '50' . lib::SD_Protocols::binStr2hexStr($newBitData); # output with length before + $self->_logging( qq[lib/mcBit2OSV1, protocol id $id translated to RFXSensor format], 4 ); + $self->_logging( qq[lib/mcBit2OSV1, converted to hex: $osv1hex], 4 ); + + return (1,$osv1hex); +} + +############################# package lib::SD_Protocols, test exists +=item mcBit2OSV2o3() + +extract the message from the bitdata if it looks like valid data + +Input: ($object,$name,$bitData,$protocolID, optional: length $bitData); +Output: + on success array (returnCode=1, hexData) + otherwise array (returncode=-1,"Error message") + +=cut + +sub mcBit2OSV2o3 { + my $self = shift // carp 'Not called within an object' && return (0,'no object provided'); + my $name = shift // "anonymous"; + my $bitData = shift // carp 'bitData must be perovided' && return (0,'no bitData provided'); + my $id = shift // carp 'protocol ID must be provided' && return (0,'no protocolId provided');;; + my $mcbitnum = shift // length $bitData; + + my $preamble_pos; + my $message_end; + my $message_length; + my $msg_start; + + #$bitData =~ tr/10/01/; + if ($bitData =~ m/^.?(01){12,17}.?10011001/xms) + { + # Valid OSV2 detected! + #$preamble_pos=index($bitData,"10011001",24); + $preamble_pos=$+[1]; + + $self->_logging( qq[lib/mcBit2OSV2, mesprotocol detected: preamble_pos = $preamble_pos], 4 ); + return return (-1," sync not found") if ($preamble_pos <24); + + $message_end=$-[1] if ($bitData =~ m/^.{44,}(01){16,17}.?10011001/); #Todo regex .{44,} 44 should be calculated from $preamble_pos+ min message lengh (44) + if (!defined($message_end) || $message_end < $preamble_pos) { + $message_end = length($bitData); + } else { + $message_end += 16; + $self->_logging( qq[lib/mcBit2OSV2, message end pattern found at pos $message_end lengthBitData=].length($bitData), 4 ); + } + $message_length = ($message_end - $preamble_pos)/2; + + return (-1," message is to short") if ($message_length < $self->checkProperty($id,'length_min',-1)); + return (-1," message is to long") if (defined $self->getProperty($id,'length_max') && $message_length > $self->getProperty($id,'length_max') ); + + my $idx=0; + my $osv2bits=""; + my $osv2hex =""; + + for ($idx=$preamble_pos;$idx<$message_end;$idx=$idx+16) + { + if ($message_end-$idx < 8 ) + { + last; + } + my $osv2byte=substr($bitData,$idx,16); + + my $rvosv2byte=q{}; + + for (my $p=0;$p_logging( qq[lib/mcBit2OSV2, protocol converted to hex: ($osv2hex) with length $osv2len bits], 4 ); + + #$found=1; + #$dmsg=$osv2hex; + return (1,$osv2hex); + } + elsif ($bitData =~ m/1{12,24}(0101)/g) { # min Preamble 12 x 1, Valid OSV3 detected! + $preamble_pos = $-[1]; + $msg_start = $preamble_pos + 4; + if ($bitData =~ m/\G.+?(1{24})0101/xms) { # preamble + sync der zweiten Nachricht + $message_end = $-[1]; + $self->_logging( qq[lib/mcBit2OSV2, protocol OSV3 with two messages detected: length of second message = ] . ($mcbitnum - $message_end - 28), 4 ); + } + else { # es wurde keine zweite Nachricht gefunden + $message_end = $mcbitnum; + } + $message_length = $message_end - $msg_start; + $self->_logging( qq[lib/mcBit2OSV2, protocol OSV3 detected: msg_start = $msg_start, message_length = $message_length], 4 ); + + return (-1," message with length ($message_length) is to short") if ($message_length < $self->checkProperty($id,'length_min',-1) ); + + my $idx=0; + my $osv3hex =q{}; + + for ($idx=$msg_start; $idx<$message_end; $idx=$idx+4) + { + if (length($bitData)-$idx < 4 ) + { + last; + } + my $osv3nibble = q{}; + #$osv3nibble=NULL; + $osv3nibble=substr($bitData,$idx,4); + + my $rvosv3nibble = q{}; + + for (my $p=0;$p_logging( qq[lib/mcBit2OSV2, protocol OSV3 = $osv3hex], 4 ); + + my $korr = 10; + # Check if nibble 1 is A + if (substr($osv3hex,1,1) ne 'A') + { + my $n1=substr($osv3hex,1,1); + $korr = hex(substr($osv3hex,3,1)); + substr($osv3hex,1,1,'A'); # nibble 1 = A + substr($osv3hex,3,1,$n1); # nibble 3 = nibble1 + } + # Korrektur nibble + my $insKorr = sprintf('%X', $korr); + # Check for ending 00 + if (substr($osv3hex,-2,2) eq '00') + { + #substr($osv3hex,1,-2); # remove 00 at end + $osv3hex = substr($osv3hex, 0, length($osv3hex)-2); + } + my $osv3len = length($osv3hex); + $osv3hex .= '0'; + my $turn0 = substr($osv3hex,5, $osv3len-4); + my $turn = ''; + for ($idx=0; $idx<$osv3len-5; $idx=$idx+2) { + $turn = $turn . substr($turn0,$idx+1,1) . substr($turn0,$idx,1); + } + $osv3hex = substr($osv3hex,0,5) . $insKorr . $turn; + $osv3hex = substr($osv3hex,0,$osv3len+1); + $osv3hex = sprintf("%02X", length($osv3hex)*4).$osv3hex; + $self->_logging( qq[lib/mcBit2OSV2, protocol OSV3 converted to hex: ($osv3hex) with length (].((length($osv3hex)-2)*4).q[) bits], 4 ); + #$found=1; + #$dmsg=$osv2hex; + return (1,$osv3hex); + } + return (-1,undef); +} + +############################# package lib::SD_Protocols, test exists +=item mcBit2OSPIR() + +This function extract the message from the bitdata if it looks like valid data + +Input: ($object,$name,$bitData,$protocolID, optional: length $bitData); +Output: + on success array (returnCode=1, hexData) + otherwise array (returncode=-1,"Error message") + +=cut + +sub mcBit2OSPIR { + my $self = shift // carp 'Not called within an object' && return (0,'no object provided'); + my $name = shift // 'anonymous'; + my $bitData = shift // carp 'bitData must be perovided' && return (0,'no bitData provided'); + my $id = shift // carp 'protocol ID must be provided' && return (0,'no protocolId provided'); + my $mcbitnum = shift // length $bitData; + + if ($bitData =~ m/(1{14}|0{14})/xms) + { # Valid Oregon PIR detected + my $header_pos=$+[1]; + $self->_logging( qq[lib/mcBit2OSPIR, protocol detected: header_pos = $header_pos], 4 ); + my $hex=lib::SD_Protocols::binStr2hexStr($bitData); + + return (1,$hex); ## Return the bits unchanged in hex + } else { + return return (-1,undef); + } +} + +############################# package lib::SD_Protocols, test exists +=item mcBit2SomfyRTS() + +This function extract the message from the bitdata if it looks like valid data + +Input: ($object,$name,$bitData,$protocolID, optional: length $bitData); +Output: + on success array (returnCode=1, hexData) + otherwise array (returncode=-1,"Error message") + +=cut + +sub mcBit2SomfyRTS { + my $self = shift // carp 'Not called within an object' && return (0,'no object provided'); + my $name = shift // 'anonymous'; + my $bitData = shift // carp 'bitData must be perovided' && return (0,'no bitData provided'); + my $id = shift // carp 'protocol ID must be provided' && return (0,'no protocolId provided'); + my $mcbitnum = shift // length $bitData; + + $self->_logging( qq[lib/mcBit2SomfyRTS, bitdata: $bitData ($mcbitnum)], 4 ); + + if ($mcbitnum == 57) { + $bitData = substr($bitData, 1, 56); + $self->_logging( qq[lib/mcBit2SomfyRTS, bitdata: $bitData, truncated to length: ]. length($bitData), 4 ); + } + my $encData = lib::SD_Protocols::binStr2hexStr($bitData); + + return (1, $encData); +} + +############################# package lib::SD_Protocols, test exists +=item mcBit2TFA() + +extract the message from the bitdata if it looks like valid data + +Input: ($object,$name,$bitData,$protocolID, optional: length $bitData); +Output: + on success array (returnCode=1, hexData) + otherwise array (returncode=-1,"Error message") + +=cut + +sub mcBit2TFA { + my $self = shift // carp 'Not called within an object' && return (0,'no object provided'); + my $name = shift // "anonymous"; + my $bitData = shift // carp 'bitData must be perovided' && return (0,'no bitData provided'); + my $id = shift // carp 'protocol ID must be provided' && return (0,'no protocolId provided');;; + my $mcbitnum = shift // length $bitData; + + my $preamble_pos; + my $message_end; + my $message_length; + + #if ($bitData =~ m/^.?(1){16,24}0101/) { + if ($bitData =~ m/(1{9}101)/xms ) + { + $preamble_pos=$+[1]; + $self->_logging( qq[lib/mcBit2TFA, 30.3208.0 preamble_pos = $preamble_pos], 4 ); + return return (-1,q[ sync not found]) if ($preamble_pos <=0); + my @messages; + + my $i=1; + my $retmsg = q{}; + do + { + $message_end = index($bitData,'1111111111101',$preamble_pos); + if ($message_end < $preamble_pos) + { + $message_end=$mcbitnum; # length($bitData); + } + $message_length = ($message_end - $preamble_pos); + + my $part_str=substr($bitData,$preamble_pos,$message_length); + $self->_logging( qq[lib/mcBit2TFA, message start($i)=$preamble_pos end=$message_end with length=$message_length], 4 ); + $self->_logging( qq[lib/mcBit2TFA, message part($i)=$part_str], 5 ); + + my ($rcode, $rtxt) = $self->LengthInRange($id, $message_length); + if ($rcode) { + my $hex=lib::SD_Protocols::binStr2hexStr($part_str); + push (@messages,$hex); + $self->_logging( qq[lib/mcBit2TFA, message part($i)=$hex], 4 ); + } + else { + $retmsg = q[, ] . $rtxt; + } + + $preamble_pos=index($bitData,'1101',$message_end)+4; + $i++; + } while ($message_end < $mcbitnum); + + my %seen; + my @dupmessages = map { 1==$seen{$_}++ ? $_ : () } @messages; + + return ($i,q[loop error, please report this data $bitData]) if ($i==10); + if (scalar(@dupmessages) > 0 ) { + $self->_logging( qq[lib/mcBit2TFA, repeated hex $dupmessages[0] found $seen{$dupmessages[0]} times"], 4 ); + return (1,$dupmessages[0]); + } else { + return (-1,qq[ no duplicate found$retmsg]); + } + } + return (-1,undef); +} + +############################# package lib::SD_Protocols, test exists +=item postDemo_EM() + +This function checks the bit sequence. On an error in the CRC or no start, it issues an output. + +Input: $id,$sum,$msg +Output: + prepares message + +=cut + +sub postDemo_EM { + my $self = shift // carp 'Not called within an object'; + my ( $name, @bit_msg ) = @_; + my $msg = join( q[], @bit_msg ); + my $msg_start = index( $msg, '0000000001' ); # find start + $msg = substr( $msg, $msg_start + 10 ); # delete preamble + 1 bit + my $new_msg = q[]; + my $crcbyte; + my $msgcrc = 0; + my $msgLength = length $msg; + + if ( $msg_start > 0 && $msgLength == 89 ) { + for my $count ( 0 .. $msgLength ) { + next if $count % 9 != 0; + $crcbyte = substr( $msg, $count, 8 ); + if ( $count < ( length($msg) - 10 ) ) { + $new_msg .= join q[], + reverse @bit_msg[ $msg_start + 10 + $count .. $msg_start + 17 + $count ]; + $msgcrc = $msgcrc ^ oct("0b$crcbyte"); + } + } + return (1,split(//xms,$new_msg)) if ($msgcrc == oct( "0b$crcbyte" )); + + $self->_logging( q[lib/postDemo_EM, protocol - CRC ERROR], 3 ); + return 0, undef; + } + + $self->_logging(qq[lib/postDemo_EM, protocol - Start not found or length msg ($msgLength) not correct], 3); + return 0, undef; +} + +############################# package lib::SD_Protocols, test exists +=item postDemo_Revolt() + +This function checks the bit sequence. On an error in the CRC, it issues an output. + +Input: $object,$name,@bit_msg +Output: + (returncode = 0 on success, prepared message or undef) + +=cut + +sub postDemo_Revolt { + my $self = shift // carp 'Not called within an object'; + my $name = shift // carp 'no $name provided'; + my @bit_msg = @_; + + my $protolength = scalar @bit_msg; + my $sum = 0; + + my $checksum = oct( '0b' . ( join "", @bit_msg[ 88 .. 95 ] ) ); + $self->_logging( qq[lib/postDemo_Revolt, length=$protolength], 5 ); + for ( my $b = 0 ; $b < 88 ; $b += 8 ) { + # build sum over first 11 bytes + $sum += oct( '0b' . ( join "", @bit_msg[ $b .. $b + 7 ] ) ); + } + $sum = $sum & 0xFF; + + if ($sum != $checksum) { + my $dmsg = lib::SD_Protocols::binStr2hexStr( join "", @bit_msg[ 0 .. 95 ] ); + $self->_logging(qq[lib/postDemo_Revolt, ERROR checksum mismatch, $sum != $checksum in msg $dmsg], 3 ); + return 0, undef; + } + my @new_bitmsg = splice @bit_msg, 0,88; + return 1, @new_bitmsg; +} + +############################# package lib::SD_Protocols, test exists +=item postDemo_FS20() + +This function checks the bit sequence. On an error in the CRC or no start, it issues an output. + +Input: $object,$name,@bit_msg +Output: + (returncode = 0 on success, prepared message or undef) + +=cut + +sub postDemo_FS20 { + my $self = shift // carp 'Not called within an object'; + my $name = shift // carp 'no $name provided'; + my @bit_msg = @_; + + my $protolength = scalar @bit_msg; + my $datastart = 0; + my $sum = 6; + my $b = 0; + my $i = 0; + for ( $datastart = 0 ; $datastart < $protolength ; $datastart++ ) { + # Start bei erstem Bit mit Wert 1 suchen + last if $bit_msg[$datastart] == 1; + } + if ( $datastart == $protolength ) { # all bits are 0 + $self->_logging(qq[lib/postDemo_FS20, ERROR message all bits are zeros], 3 ); + return 0, undef; + } + splice( @bit_msg, 0, $datastart + 1 ); # delete preamble + 1 bit + $protolength = scalar @bit_msg; + $self->_logging( qq[lib/postDemo_FS20, pos=$datastart length=$protolength], 5 ); + if ( $protolength == 46 || $protolength == 55 ) + { # If it 1 bit too long, then it will be removed (EOT-Bit) + pop(@bit_msg); + $protolength--; + } + if ( $protolength == 45 || $protolength == 54 ) { ### FS20 length 45 or 54 + + my $b=0; + for ( my $b = 0 ; $b < $protolength - 9 ; $b += 9 ) { + # build sum over first 4 or 5 bytes + $sum += oct( '0b' . ( join "", @bit_msg[ $b .. $b + 7 ] ) ); + } + my $checksum = oct( '0b' . ( join "", @bit_msg[ $protolength - 9 .. $protolength - 2 ] ) ) ; # Checksum Byte 5 or 6 + if ( ( ( $sum + 6 ) & 0xFF ) == $checksum ) + { # Message from FHT80 roothermostat + $self->_logging(qq[lib/postDemo_FS20, FS20, Detection aborted, checksum matches FHT code], 5 ); + return 0, undef; + } + if ( ( $sum & 0xFF ) == $checksum ) { ## FH20 remote control + for my $b ($b..$protolength-1) { + next if $b % 9 != 0; + my $parity = 0; # Parity even + for my $i ($b..$b+8) { # Parity over 1 byte + 1 bit + $parity += $bit_msg[$i]; } - my $cut_string = substr($num, $index, $width); - $hex = sprintf('%X', oct("0b$cut_string")) . $hex; - $index -= $WIDTH; - } while ($index > (-1 * $WIDTH)); - return $hex; + if ( $parity % 2 != 0 ) { + $self->_logging(qq[lib/postDemo_FS20, FS20, ERROR - Parity not even], 3 ); + return 0, undef; + } + } # parity ok + for ( my $b = $protolength - 1 ; $b > 0 ; $b -= 9 ) { # delete 5 or 6 parity bits + splice( @bit_msg, $b, 1 ); + } + if ( $protolength == 45 ) { ### FS20 length 45 + splice( @bit_msg, 32, 8 ); # delete checksum + splice( @bit_msg, 24, 0, ( 0, 0, 0, 0, 0, 0, 0, 0 ) ); # insert Byte 3 + } + else { ### FS20 length 54 + splice( @bit_msg, 40, 8 ); # delete checksum + } + my $dmsg = lib::SD_Protocols::binStr2hexStr( join "", @bit_msg ); + $self->_logging(qq[lib/postDemo_FS20, remote control post demodulation $dmsg length $protolength], 4 ); + return ( 1, @bit_msg ); ## FHT80TF ok + } + else { + $self->_logging(qq[lib/postDemo_FS20, ERROR - wrong checksum], 4 ); + } + } + else { + $self->_logging(qq[lib/postDemo_FS20, ERROR - wrong length=$protolength (must be 45 or 54)], 5 ); + } + return 0, undef; } +############################# package lib::SD_Protocols, test exists +=item postDemo_FHT80() -# - - - - - - - - - - - - -#=item MCRAW() -# This functon is desired to be used as a default output helper for manchester signals. It will check for length_max and return a hex string -# -# =cut -sub MCRAW -{ - my ($name,$bitData,$id,$mcbitnum) = @_; +This function checks the bit sequence. On an error in the CRC or no start, it issues an output. - return (-1," message is to long") if ($mcbitnum > checkProperty($id,"length_max",0) ); +Input: $object,$name,@bit_msg +Output: + (returncode = 0 on success, prepared message or undef) - return(1,binStr2hexStr($bitData)); +=cut + +sub postDemo_FHT80 { + my $self = shift // carp 'Not called within an object'; + my $name = shift // carp 'no $name provided'; + my @bit_msg = @_; + + my $datastart = 0; + my $protolength = scalar @bit_msg; + my $sum = 12; + my $b = 0; + my $i = 0; + for ($datastart = 0; $datastart < $protolength; $datastart++) { # Start bei erstem Bit mit Wert 1 suchen + last if $bit_msg[$datastart] == 1; + } + if ($datastart == $protolength) { # all bits are 0 + $self->_logging(qq[lib/postDemo_FHT80, ERROR message all bit are zeros], 3 ); + return 0, undef; + } + splice(@bit_msg, 0, $datastart + 1); # delete preamble + 1 bit + $protolength = scalar @bit_msg; + $self->_logging(qq[lib/postDemo_FHT80, pos=$datastart length=$protolength], 5 ); + if ($protolength == 55) { # If it 1 bit too long, then it will be removed (EOT-Bit) + pop(@bit_msg); + $protolength--; + } + if ($protolength == 54) { ### FHT80 fixed length + for($b = 0; $b < 45; $b += 9) { # build sum over first 5 bytes + $sum += oct( "0b".(join "", @bit_msg[$b .. $b + 7])); + } + my $checksum = oct( "0b".(join "", @bit_msg[45 .. 52])); # Checksum Byte 6 + if ((($sum - 6) & 0xFF) == $checksum) { ## Message from FS20 remote contro + $self->_logging(qq[lib/postDemo_FHT80, Detection aborted, checksum matches FS20 code], 5 ); + return 0, undef; + } + if (($sum & 0xFF) == $checksum) { ## FHT80 Raumthermostat + for($b = 0; $b < 54; $b += 9) { # check parity over 6 byte + my $parity = 0; # Parity even + for($i = $b; $i < $b + 9; $i++) { # Parity over 1 byte + 1 bit + $parity += $bit_msg[$i]; + } + if ($parity % 2 != 0) { + $self->_logging(qq[lib/postDemo_FHT80, ERROR - Parity not even], 3 ); + return 0, undef; + } + } # parity ok + for($b = 53; $b > 0; $b -= 9) { # delete 6 parity bits + splice(@bit_msg, $b, 1); + } + if ($bit_msg[26] != 1) { # Bit 5 Byte 3 must 1 + $self->_logging(qq[lib/postDemo_FHT80, ERROR - byte 3 bit 5 not 1], 3 ); + return 0, undef; + } + splice(@bit_msg, 40, 8); # delete checksum + splice(@bit_msg, 24, 0, (0,0,0,0,0,0,0,0)); # insert Byte 3 + my $dmsg = lib::SD_Protocols::binStr2hexStr(join "", @bit_msg); + $self->_logging(qq[lib/postDemo_FHT80, roomthermostat post demodulation $dmsg], 4 ); + return (1, @bit_msg); ## FHT80 ok + } + else { + $self->_logging(qq[lib/postDemo_FHT80, ERROR - wrong checksum], 4 ); + } + } + else { + $self->_logging(qq[lib/postDemo_FHT80, ERROR - wrong length=$protolength (must be 54)], 5 ); + } + return 0, undef; +} + +############################# package lib::SD_Protocols, test exists +=item postDemo_FHT80TF() + +This function checks the bit sequence. On an error in the CRC or no start, it issues an output. + +Input: $object,$name,@bit_msg +Output: + (returncode = 0 on success, prepared message or undef) + +=cut + +sub postDemo_FHT80TF { + my $self = shift // carp 'Not called within an object'; + my $name = shift // carp 'no $name provided'; + my @bit_msg = @_; + + my $protolength = scalar @bit_msg; + my $datastart = 0; + my $sum = 12; + my $b = 0; + if ($protolength < 46) { # min 5 bytes + 6 bits + $self->_logging(qq[lib/postDemo_FHT80TF, ERROR lenght of message < 46], 4 ); + return 0, undef; + } + for ($datastart = 0; $datastart < $protolength; $datastart++) { # Start bei erstem Bit mit Wert 1 suchen + last if $bit_msg[$datastart] == 1; + } + if ($datastart == $protolength) { # all bits are 0 + $self->_logging(qq[lib/postDemo_FHT80TF, ERROR message all bit are zeros], 3 ); + return 0, undef; + } + splice(@bit_msg, 0, $datastart + 1); # delete preamble + 1 bit + $protolength = scalar @bit_msg; + if ($protolength == 45) { ### FHT80TF fixed length + for(my $b = 0; $b < 36; $b += 9) { # build sum over first 4 bytes + $sum += oct( "0b".(join "", @bit_msg[$b .. $b + 7])); + } + my $checksum = oct( "0b".(join "", @bit_msg[36 .. 43])); # Checksum Byte 5 + if (($sum & 0xFF) == $checksum) { ## FHT80TF Tuer-/Fensterkontakt + for(my $b = 0; $b < 45; $b += 9) { # check parity over 5 byte + my $parity = 0; # Parity even + for(my $i = $b; $i < $b + 9; $i++) { # Parity over 1 byte + 1 bit + $parity += $bit_msg[$i]; + } + if ($parity % 2 != 0) { + $self->_logging(qq[lib/postDemo_FHT80TF, ERROR Parity not even], 4 ); + return 0, undef; + } + } # parity ok + for(my $b = 44; $b > 0; $b -= 9) { # delete 5 parity bits + splice(@bit_msg, $b, 1); + } + if ($bit_msg[26] != 0) { # Bit 5 Byte 3 must 0 + $self->_logging(qq[lib/postDemo_FHT80TF, ERROR - byte 3 bit 5 not 0], 3 ); + return 0, undef; + } + splice(@bit_msg, 32, 8); # delete checksum + my $dmsg = lib::SD_Protocols::binStr2hexStr(join "", @bit_msg); + $self->_logging(qq[lib/postDemo_FHT80TF, door/window switch post demodulation $dmsg], 4 ); + return (1, @bit_msg); ## FHT80TF ok + } + } + return 0, undef; +} + +############################# package lib::SD_Protocols, test exists +=item postDemo_WS2000() + +This function checks the bit sequence. On an error in the CRC or no start, it issues an output. + +Input: $object,$name,@bit_msg +Output: + (returncode = 0 on failure, prepared message or undef) + +=cut + +sub postDemo_WS2000 { + my $self = shift // carp 'Not called within an object'; + my $name = shift // carp 'no $name provided'; + my @bit_msg = @_; + + my $protolength = scalar @bit_msg; + my @new_bit_msg = q{}; + my @datalenghtws = (35,50,35,50,70,40,40,85); + my $datastart = 0; + my $datalength = 0; + my $datalength1 = 0; + my $index = 0; + my $data = 0; + my $dataindex = 0; + my $check = 0; + my $sum = 5; + my $typ = 0; + my $adr = 0; + my @sensors = ( + 'Thermo', + 'Thermo/Hygro', + 'Rain', + 'Wind', + 'Thermo/Hygro/Baro', + 'Brightness', + 'Pyrano', + 'Kombi' + ); + + for ($datastart = 0; $datastart < $protolength; $datastart++) { # Start bei erstem Bit mit Wert 1 suchen + last if $bit_msg[$datastart] == 1; + } + if ($datastart == $protolength) { # all bits are 0 + $self->_logging(qq[lib/postDemo_WS2000, ERROR message all bit are zeros],4); + return 0, undef; + } + $datalength = $protolength - $datastart; + $datalength1 = $datalength - ($datalength % 5); # modulo 5 + $self->_logging(qq[lib/postDemo_WS2000, protolength: $protolength, datastart: $datastart, datalength $datalength],5); + $typ = oct( '0b'.(join "", reverse @bit_msg[$datastart + 1.. $datastart + 4])); # Sensortyp + if ($typ > 7) { + $self->_logging(qq[lib/postDemo_WS2000, Sensortyp $typ - ERROR typ to big (0-7)],5); + return 0, undef; + } + if ($typ == 1 && ($datalength == 45 || $datalength == 46)) {$datalength1 += 5;} # Typ 1 ohne Summe + if ($datalenghtws[$typ] != $datalength1) { # check lenght of message + $self->_logging(qq[lib/postDemo_WS2000, Sensortyp $typ - ERROR lenght of message $datalength1 ($datalenghtws[$typ])],4); + return 0, undef; + } elsif ($datastart > 10) { # max 10 Bit preamble + $self->_logging(qq[lib/postDemo_WS2000, ERROR preamble > 10 ($datastart)],4); + return 0, undef; + } else { + do { + if ($bit_msg[$index + $datastart] != 1) { # jedes 5. Bit muss 1 sein + $self->_logging(qq[lib/postDemo_WS2000, Sensortyp $typ - ERROR checking bit $index],4); + return (0, undef); + } + $dataindex = $index + $datastart + 1; + $data = oct( '0b'.(join '', reverse @bit_msg[$dataindex .. $dataindex + 3])); + if ($index == 5) {$adr = ($data & 0x07)} # Sensoradresse + if ($datalength == 45 || $datalength == 46) { # Typ 1 ohne Summe + if ($index <= $datalength - 5) { + $check = $check ^ $data; # Check - Typ XOR Adresse XOR bis XOR Check muss 0 ergeben + } + } else { + if ($index <= $datalength - 10) { + $check = $check ^ $data; # Check - Typ XOR Adresse XOR bis XOR Check muss 0 ergeben + $sum += $data; + } + } + $index += 5; + } until ($index >= $datalength -1 ); + } + if ($check != 0) { + $self->_logging(qq[lib/postDemo_WS2000, Sensortyp $typ Adr $adr - ERROR check XOR],4); + return (0, undef); + } else { + if ($datalength < 45 || $datalength > 46) { # Summe pruefen, au�er Typ 1 ohne Summe + $data = oct( "0b".(join '', reverse @bit_msg[$dataindex .. $dataindex + 3])); + if ($data != ($sum & 0x0F)) { + $self->_logging(qq[lib/postDemo_WS2000, Sensortyp $typ Adr $adr - ERROR sum],4); + return (0, undef); + } + } + $self->_logging(qq[lib/postDemo_WS2000, Sensortyp $typ Adr $adr - $sensors[$typ]],4); + $datastart += 1; # [x] - 14_CUL_WS + @new_bit_msg[4 .. 7] = reverse @bit_msg[$datastart .. $datastart+3]; # [2] Sensortyp + @new_bit_msg[0 .. 3] = reverse @bit_msg[$datastart+5 .. $datastart+8]; # [1] Sensoradresse + @new_bit_msg[12 .. 15] = reverse @bit_msg[$datastart+10 .. $datastart+13]; # [4] T 0.1, R LSN, Wi 0.1, B 1, Py 1 + @new_bit_msg[8 .. 11] = reverse @bit_msg[$datastart+15 .. $datastart+18]; # [3] T 1, R MID, Wi 1, B 10, Py 10 + if ($typ == 0 || $typ == 2) { # Thermo (AS3), Rain (S2000R, WS7000-16) + @new_bit_msg[16 .. 19] = reverse @bit_msg[$datastart+20 .. $datastart+23]; # [5] T 10, R MSN + } else { + @new_bit_msg[20 .. 23] = reverse @bit_msg[$datastart+20 .. $datastart+23]; # [6] T 10, Wi 10, B 100, Py 100 + @new_bit_msg[16 .. 19] = reverse @bit_msg[$datastart+25 .. $datastart+28]; # [5] H 0.1, Wr 1, B Fak, Py Fak + if ($typ == 1 || $typ == 3 || $typ == 4 || $typ == 7) { # Thermo/Hygro, Wind, Thermo/Hygro/Baro, Kombi + @new_bit_msg[28 .. 31] = reverse @bit_msg[$datastart+30 .. $datastart+33]; # [8] H 1, Wr 10 + @new_bit_msg[24 .. 27] = reverse @bit_msg[$datastart+35 .. $datastart+38]; # [7] H 10, Wr 100 + if ($typ == 4) { # Thermo/Hygro/Baro (S2001I, S2001ID) + @new_bit_msg[36 .. 39] = reverse @bit_msg[$datastart+40 .. $datastart+43]; # [10] P 1 + @new_bit_msg[32 .. 35] = reverse @bit_msg[$datastart+45 .. $datastart+48]; # [9] P 10 + @new_bit_msg[44 .. 47] = reverse @bit_msg[$datastart+50 .. $datastart+53]; # [12] P 100 + @new_bit_msg[40 .. 43] = reverse @bit_msg[$datastart+55 .. $datastart+58]; # [11] P Null + } + } + } + return (1, @new_bit_msg); + } +} + +############################# package lib::SD_Protocols, test exists +=item postDemo_WS7035() + +This function checks the bit sequence. On an error in the CRC or no start, it issues an output. + +Input: $object,$name,@bit_msg +Output: + (returncode = 1 on success, prepared message or undef) + +=cut + +sub postDemo_WS7035 { + my $self = shift // carp 'Not called within an object'; + my $name = shift // carp 'no $name provided'; + my @bit_msg = @_; + + my $msg = join('',@bit_msg); + my $parity = 0; # Parity even + my $sum = 0; # checksum + $self->_logging(qq[lib/postDemo_WS7035, $msg], 4 ); + if (substr($msg,0,8) ne '10100000') { # check ident + $self->_logging(qq[lib/postDemo_WS7035, ERROR - Ident not 1010 0000],3 ); + return 0, undef; + } else { + for(my $i = 15; $i < 28; $i++) { # Parity over bit 15 and 12 bit temperature + $parity += substr($msg, $i, 1); + } + if ($parity % 2 != 0) { + $self->_logging(qq[lib/postDemo_WS7035, ERROR - Parity not even],3 ); + return 0, undef; + } else { + for(my $i = 0; $i < 39; $i += 4) { # Sum over nibble 0 - 9 + $sum += oct('0b'.substr($msg,$i,4)); + } + if (($sum &= 0x0F) != oct('0b'.substr($msg,40,4))) { + $self->_logging(qq[lib/postDemo_WS7035, ERROR - wrong checksum],3 ); + return 0, undef; + } else { + ### ToDo: Regex anstelle der viele substr einfuegen ## + $self->_logging(qq[lib/postDemo_WS7035, ]. substr($msg,0,4) ." ". substr($msg,4,4) ." ". substr($msg,8,4) ." ". substr($msg,12,4) ." ". substr($msg,16,4) ." ". substr($msg,20,4) ." ". substr($msg,24,4) ." ". substr($msg,28,4) ." ". substr($msg,32,4) ." ". substr($msg,36,4) ." ". substr($msg,40),4 ); + substr($msg, 27, 4, ''); # delete nibble 8 + return (1,split(//,$msg)); + } + } + } +} + +############################# package lib::SD_Protocols, test exists +=item postDemo_WS7053() + +This function checks the bit sequence. On an error in the CRC or no start, it issues an output. + +Input: $object,$name,@bit_msg +Output: + (returncode = 0 on failure, prepared message or undef) + +=cut + +sub postDemo_WS7053 { + my $self = shift // carp 'Not called within an object'; + my $name = shift // carp 'no $name provided'; + my @bit_msg = @_; + + my $msg = join("",@bit_msg); + my $parity = 0; # Parity even + $self->_logging(qq[lib/postDemo_WS7053, MSG = $msg],4); + my $msg_start = index($msg, '10100000'); + if ($msg_start > 0) { # start not correct + $msg = substr($msg, $msg_start); + $msg .= '0'; + $self->_logging(qq[lib/postDemo_WS7053, cut $msg_start char(s) at begin],5); + } + if ($msg_start < 0) { # start not found + $self->_logging(qq[lib/postDemo_WS7053, ERROR - Ident 10100000 not found],3); + return 0, undef; + } else { + if (length($msg) < 32) { # msg too short + $self->_logging(qq[lib/postDemo_WS7053, ERROR - msg too short, length ] . length($msg),3); + return 0, undef; + } else { + for(my $i = 15; $i < 28; $i++) { # Parity over bit 15 and 12 bit temperature + $parity += substr($msg, $i, 1); + } + if ($parity % 2 != 0) { + $self->_logging(qq[lib/postDemo_WS7053, ERROR - Parity not even] . length($msg),3); + return 0, undef; + } else { + # Todo substr durch regex ersetzen + $self->_logging(qq[lib/postDemo_WS7053, before: ] . substr($msg,0,4) ." ". substr($msg,4,4) ." ". substr($msg,8,4) ." ". substr($msg,12,4) ." ". substr($msg,16,4) ." ". substr($msg,20,4) ." ". substr($msg,24,4) ." ". substr($msg,28,4),5); + # Format from 7053: Bit 0-7 Ident, Bit 8-15 Rolling Code/Parity, Bit 16-27 Temperature (12.3), Bit 28-31 Zero + my $new_msg = substr($msg,0,28) . substr($msg,16,8) . substr($msg,28,4); + # Format for CUL_TX: Bit 0-7 Ident, Bit 8-15 Rolling Code/Parity, Bit 16-27 Temperature (12.3), Bit 28 - 35 Temperature (12), Bit 36-39 Zero + $self->_logging(qq[lib/postDemo_WS7053, after: ] . substr($new_msg,0,4) ." ". substr($new_msg,4,4) ." ". substr($new_msg,8,4) ." ". substr($new_msg,12,4) ." ". substr($new_msg,16,4) ." ". substr($new_msg,20,4) ." ". substr($new_msg,24,4) ." ". substr($new_msg,28,4) ." ". substr($new_msg,32,4) ." ". substr($new_msg,36,4),5); + return (1,split("",$new_msg)); + } + } + } +} + +############################# package lib::SD_Protocols, test exists +=item postDemo_lengtnPrefix() + +calculates the hex (in bits) and adds it at the beginning of the message + +Input: $object,$name,@bit_msg +Output: + (returncode = 0 on failure, prepared message or undef) + +=cut + +sub postDemo_lengtnPrefix { + my $self = shift // carp 'Not called within an object'; + my $name = shift // carp 'no $name provided'; + my @bit_msg = @_; + + my $msg = join('',@bit_msg); + $msg=sprintf('%08b', length($msg)).$msg; + + return (1,split('',$msg)); +} + +############################# package lib::SD_Protocols, test exists +=item Convbit2Arctec() + +This function convert 0 -> 01, 1 -> 10 to be compatible with IT Module. + +Input: @bit_msg +Output: + converted message + +=cut + +sub Convbit2Arctec { + my ( $self, undef, @bitmsg ) = @_; + $self // carp 'Not called within an object'; + @bitmsg // carp 'no bitmsg provided'; + my $convmsg = join( "", @bitmsg ); + my @replace = qw(01 10); + + # Convert 0 -> 01 1 -> 10 to be compatible with IT Module + $convmsg =~ s/(0|1)/$replace[$1]/gx; + return ( 1, split( //, $convmsg ) ); +} + +############################# package lib::SD_Protocols, test exists +=item Convbit2itv1() + +This function convert 0F -> 01 (F) to be compatible with CUL. + +Input: $msg +Output: + converted message + +=cut + +sub Convbit2itv1 { + shift if ref $_[0] eq __PACKAGE__; + my ( undef, @bitmsg ) = @_; + @bitmsg // carp 'no bitmsg provided'; + my $msg = join( "", @bitmsg ); + + $msg =~ s/0F/01/gsm; # Convert 0F -> 01 (F) to be compatible with CUL + return ( 1, split( //, $msg ) ) if ( index( $msg, 'F' ) == -1 ); + return ( 0, 0 ); +} + +############################# package lib::SD_Protocols, test exists +=item ConvHE800() + +This function checks the length of the bits. +If the length is less than 40, it adds a 0. + +Input: $name, @bit_msg +Output: + scalar converted message on success + +=cut + +sub ConvHE800 { + my ( $self, $name, @bit_msg ) = @_; + $self // carp 'Not called within an object'; + + my $protolength = scalar @bit_msg; + + if ( $protolength < 40 ) { + for ( my $i = 0 ; $i < ( 40 - $protolength ) ; $i++ ) { + push( @bit_msg, 0 ); + } + } + return ( 1, @bit_msg ); +} + +############################# package lib::SD_Protocols, test exists +=item ConvHE_EU() + +This function checks the length of the bits. +If the length is less than 72, it adds a 0. + +Input: $name, @bit_msg +Output: + scalar converted message on success + +=cut + +sub ConvHE_EU { + my ( $self, $name, @bit_msg ) = @_; + my $protolength = scalar @bit_msg; + + if ( $protolength < 72 ) { + for ( my $i = 0 ; $i < ( 72 - $protolength ) ; $i++ ) { + push( @bit_msg, 0 ); + } + } + return ( 1, @bit_msg ); +} + +############################# package lib::SD_Protocols, test exists +=item ConvITV1_tristateToBit() + +This function Convert 0 -> 00, 1 -> 11, F => 01 to be compatible with IT Module. + +Input: $msg +Output: + converted message + +=cut + +sub ConvITV1_tristateToBit { + shift if ref $_[0] eq __PACKAGE__; + my ($msg) = @_; + + $msg =~ s/0/00/gsm; + $msg =~ s/1/11/gsm; + $msg =~ s/F/01/gsm; + $msg =~ s/D/10/gsm; + + return ( 1, $msg ); +} + +############################# package lib::SD_Protocols, test exists +=item PreparingSend_FS20_FHT() + +This function prepares the send message. + +Input: $id,$sum,$msg +Output: + prepares message + +=cut + +sub PreparingSend_FS20_FHT { + my $self = shift // carp 'Not called within an object'; + my $id = shift // carp 'no idprovided'; + my $sum = shift // carp 'no sum provided'; + my $msg = shift // carp 'no msg provided'; + + return if ( $id > 74 || $id < 73 ); + + my $temp = 0; + my $newmsg = q[P] . $id . q[#0000000000001]; # 12 Bit Praeambel, 1 bit + my $msgLength = length $msg; + + for my $i ( 0 .. $msgLength - 1 ) { + next if $i % 2 != 0; + $temp = hex( substr( $msg, $i, 2 ) ); + $sum += $temp; + $newmsg .= dec2binppari($temp); + } + + $newmsg .= dec2binppari( $sum & 0xFF ); # Checksum + my $repeats = $id - 71; # FS20(74)=3, FHT(73)=2 + return $newmsg . q[0P#R] . $repeats; # EOT, Pause, 3 Repeats +} + +######################### +# xFSK method functions # +######################### + +sub _xFSK_methods_behind_here { + # only for functionslist - no function! +} + +=item ConvBresser_5in1() + +This function checks number/count of set bits within bytes 14-25 and inverted data of 13 byte further. +Delete inverted data (nibble 1-27)and reduce message length (nibble 53). + +Input: $hexData +Output: $hexData + scalar converted message on success + or array (1,"Error message") + +=cut + +sub ConvBresser_5in1 { + my $self = shift // carp 'Not called within an object'; + my $hexData = shift // croak 'Error: called without $hexdata as input'; + my $d2; + my $bit; + my $bitsumRef; + my $bitadd = 0; + my $hexLength = length ($hexData); + + return ( 1, 'ConvBresser_5in1, hexData is to short' ) + if ( $hexLength < 52 ); # check double, in def length_min set + + for (my $i = 0; $i < 13; $i++) { + $d2 = hex(substr($hexData,($i+13)*2,2)); + return ( 1, qq[ConvBresser_5in1, inverted data at pos $i] ) if ((hex(substr($hexData,$i*2,2)) ^ $d2) != 255); + if ($i == 0) { + $bitsumRef = $d2; + } else { + + while ($d2) { + $bitadd += $d2 & 1; + $d2 >>= 1; + } + } + } + return (1, qq[ConvBresser_5in1, checksumCalc:$bitadd != checksum:$bitsumRef ] ) if ($bitadd != $bitsumRef); + return substr($hexData, 28, 24); +} + +=item ConvBresser_6in1() + +This function checks CRC16 over bytes 2 - 17 and sum over bytes 2 - 17 (must be 255). + +Input: $hexData +Output: $hexData + scalar converted message on success + or array (1,"Error message") + +=cut + +sub ConvBresser_6in1 { + my $self = shift // carp 'Not called within an object'; + my $hexData = shift // croak 'Error: called without $hexdata as input'; + my $hexLength = length ($hexData); + + return ( 1, 'ConvBresser_6in1, hexData is to short' ) if ( $hexLength < 36 ); # check double, in def length_min set + my $crc = substr( $hexData, 0, 4 ); + my $ctx = Digest::CRC->new(width => 16, poly => 0x1021); + my $calcCrc = sprintf( "%04X", $ctx->add( pack 'H*', substr( $hexData, 4, 30 ) )->digest ); + $self->_logging(qq[ConvBresser_6in1, calcCRC16 = 0x$calcCrc, CRC16 = 0x$crc],5); + return ( 1, qq[ConvBresser_6in1, checksumCalc:0x$calcCrc != checksum:0x$crc] ) if ($calcCrc ne $crc); + + my $sum = 0; + for (my $i = 2; $i < 18; $i++) { + $sum += hex(substr($hexData,($i) * 2, 2)); + } + $sum &= 0xFF; + $self->_logging(qq[ConvBresser_6in1, sum = $sum],5); + return ( 1, qq[ConvBresser_6in1, sum $sum != 255] ) if ($sum != 255); + + return $hexData; } +############################# package lib::SD_Protocols, test exists +=item ConvPCA301() -1; \ No newline at end of file +This function checks crc and converts data to a format which the PCA301 module can handle +croaks if called with less than one parameters + +Input: $hexData +Output: + scalar converted message on success + or array (1,"Error message") + +=cut + +sub ConvPCA301 { + my $self = shift // carp 'Not called within an object'; + my $hexData = shift // croak 'Error: called without $hexdata as input'; + + return ( 1, +'ConvPCA301, Usage: Input #1, $hexData needs to be at least 24 chars long' + ) if ( length($hexData) < 24 ); # check double, in def length_min set + + my $checksum = substr( $hexData, 20, 4 ); + my $ctx = Digest::CRC->new( + width => 16, + poly => 0x8005, + init => 0x0000, + refin => 0, + refout => 0, + xorout => 0x0000 + ); + my $calcCrc = sprintf( "%04X", + $ctx->add( pack 'H*', substr( $hexData, 0, 20 ) )->digest ); + + return ( 1, qq[ConvPCA301, checksumCalc:$calcCrc != checksum:$checksum] ) + if ( $calcCrc ne $checksum ); + + my $channel = hex( substr( $hexData, 0, 2 ) ); + my $command = hex( substr( $hexData, 2, 2 ) ); + my $addr1 = hex( substr( $hexData, 4, 2 ) ); + my $addr2 = hex( substr( $hexData, 6, 2 ) ); + my $addr3 = hex( substr( $hexData, 8, 2 ) ); + my $plugstate = substr( $hexData, 11, 1 ); + my $power1 = hex( substr( $hexData, 12, 2 ) ); + my $power2 = hex( substr( $hexData, 14, 2 ) ); + my $consumption1 = hex( substr( $hexData, 16, 2 ) ); + my $consumption2 = hex( substr( $hexData, 18, 2 ) ); + + return ("OK 24 $channel $command $addr1 $addr2 $addr3 $plugstate $power1 $power2 $consumption1 $consumption2 $checksum" ); +} + +############################# package lib::SD_Protocols, test exists +=item ConvKoppFreeControl() + +This function checks crc and converts data to a format which the KoppFreeControl module can handle +croaks if called with less than one parameters + +Input: $hexData +Output: + scalar converted message on success + or array (1,"Error message") + +=cut + +sub ConvKoppFreeControl { + my $self = shift // carp 'Not called within an object'; + my $hexData = shift // croak 'Error: called without $hexdata as input'; + + # kr07C2AD1A30CC0F0328 + # || |||| || ++-------- Transmitter Code 2 + # || |||| ++-------------- Keycode + # || ++++------------------ Transmitter Code 1 + # ++------------------------ kr wird von der culfw bei Empfang einer Kopp Botschaft als Kennung gesendet + # + # right rawMSG MN;D=07FA5E1721CC0F02FE000000000000; + # wrong rawMSG MN;D=0A018200CA043A90; + + return ( 1, +'ConvKoppFreeControl, Usage: Input #1, $hexData needs to be at least 4 chars long' + ) if ( length($hexData) < 4 ); # check double, in def length_min set + + my $anz = hex( substr( $hexData, 0, 2 ) ) + 1; + + return ( 1, 'ConvKoppFreeControl, hexData is to short' ) + if ( length($hexData) < $anz * 2 ); # check double, in def length_min set + + my $blkck = 0xAA; + + for my $i ( 0 .. $anz - 1 ) { + my $d = hex( substr( $hexData, $i * 2, 2 ) ); + $blkck ^= $d; + } + + my $checksum = hex( substr( $hexData, $anz * 2, 2 ) ); + + return ( 1, + qq[ConvKoppFreeControl, checksumCalc:$blkck != checksum:$checksum] ) + if ( $blkck != $checksum ); + return ( "kr" . substr( $hexData, 0, $anz * 2 ) ); +} + +############################# package lib::SD_Protocols, test exists +=item ConvLaCrosse() + +This function checks crc and converts data to a format which the LaCrosse module can handle +croaks if called with less than one parameter + +Input: $hexData +Output: + scalar converted message on success + or array (1,"Error message") + +Message Format: + + .- [0] -. .- [1] -. .- [2] -. .- [3] -. .- [4] -. + | | | | | | | | | | + SSSS.DDDD DDN_.TTTT TTTT.TTTT WHHH.HHHH CCCC.CCCC + | | | || | | | | | | || | | | + | | | || | | | | | | || | `--------- CRC + | | | || | | | | | | |`-------- Humidity + | | | || | | | | | | | + | | | || | | | | | | `---- weak battery + | | | || | | | | | | + | | | || | | | | `----- Temperature T * 0.1 + | | | || | | | | + | | | || | | `---------- Temperature T * 1 + | | | || | | + | | | || `--------------- Temperature T * 10 + | | | | `--- new battery + | | `---------- ID + `---- START + +=cut + +sub ConvLaCrosse { + my $self = shift // carp 'Not called within an object'; + my $hexData = shift // croak 'Error: called without $hexdata as input'; + + croak qq[ConvLaCrosse, Usage: Input #1, $hexData is not valid HEX] + if (not $hexData =~ /^[0-9a-fA-F]+$/xms) ; # check valid hexData + + return ( 1,'ConvLaCrosse, Usage: Input #1, $hexData needs to be at least 8 chars long' ) + if ( length($hexData) < 8 ) ; # check number of length for this sub to not throw an error + + my $ctx = Digest::CRC->new( width => 8, poly => 0x31 ); + my $calcCrc = $ctx->add( pack 'H*', substr( $hexData, 0, 8 ) )->digest; + my $checksum = sprintf( "%d", hex( substr( $hexData, 8, 2 ) ) ); + return ( 1, qq[ConvLaCrosse, checksumCalc:$calcCrc != checksum:$checksum] ) + if ( $calcCrc != $checksum ); + + my $addr = + ( ( hex( substr( $hexData, 0, 2 ) ) & 0x0F ) << 2 ) | + ( ( hex( substr( $hexData, 2, 2 ) ) & 0xC0 ) >> 6 ); + my $temperature = ( + ( + ( ( hex( substr( $hexData, 2, 2 ) ) & 0x0F ) * 100 ) + + ( ( ( hex( substr( $hexData, 4, 2 ) ) & 0xF0 ) >> 4 ) * 10 ) + + ( hex( substr( $hexData, 4, 2 ) ) & 0x0F ) + ) / 10 + ) - 40; + return ( 1, qq[ConvLaCrosse, temp:$temperature (out of Range)] ) + if ( $temperature >= 60 || $temperature <= -40 ) + ; # Shoud be checked in logical module + + my $humidity = hex( substr( $hexData, 6, 2 ) ); + my $batInserted = ( hex( substr( $hexData, 2, 2 ) ) & 0x20 ) << 2; + my $SensorType = 1; + + my $humObat = $humidity & 0x7F; + + if ( $humObat == 125 ) { # Channel 2 ??? doubtful + $SensorType = 2; + } + ### humidity check is in Lacrosse module and some sensors without hum, send a value over 100 ### + # elsif ( $humObat > 99 ) { # Shoud be checked in logical module + # return ( -1, qq[ConvLaCrosse: hum:$humObat (out of Range)] ); + # } + + # build string for 36_LaCrosse.pm + $temperature = ( ( $temperature * 10 + 1000 ) & 0xFFFF ); + my $t1 = ( $temperature >> 8 ) & 0xFF; + my $t2 = $temperature & 0xFF; + my $sensTypeBat = $SensorType | $batInserted; + return (qq[OK 9 $addr $sensTypeBat $t1 $t2 $humidity]); +} + +############################# package lib::SD_Protocols, test not exists +=item PreparingSend_KOPP_FC() + +This function calculated crc and prepares the send message. + +Input: $blkctrInternal,$Keycode,$TransCode1,$TransCode2 +Output: + prepares message + +Message Format: + + https://wiki.fhem.de/wiki/Kopp_Allgemein | https://github.com/heliflieger/a-culfw/blob/master/culfw/clib/kopp-fc.c + kr07C2AD1A30CC0F0328 + || |||| || ++-------- Transmitter Code 2 + || |||| ++-------------- Keycode + || ++++------------------ Transmitter Code 1 + ++------------------------ kr wird von der culfw bei Empfang einer Kopp Botschaft als Kennung gesendet + + # $message = "s" + # . $keycodehex + # . $hash->{TRANSMITTERCODE1} + # . $hash->{TRANSMITTERCODE2} + # . $hash->{TIMEOUT} + # . "N"; # N for do not print messages (FHEM will write error messages to log files if CCD/CUL sends status info + +=cut + +sub PreparingSend_KOPP_FC { + my $self = shift // carp 'Not called within an object'; + my $blkctrInternal = shift // carp 'Error: called without Internal blkctr as input'; + my $Keycode = shift // carp 'Error: called without $Keycode as input'; + my $TransCode1 = shift // carp 'Error: called without $TransCode1 as input'; + my $TransCode2 = shift // carp 'Error: called without $TransCode2 as input'; + my $blkck = 0xAA; + my $d; + + # check from Keycode, TransCode1 and TransCode2 direct in modul 10_KOPP_FC.pm + $self->_logging(qq[lib/PreparingSend_KOPP_FC, called with all parameters],5); + + my $dmsg = '07' . $TransCode1 . $blkctrInternal . $Keycode . 'CC0F' . $TransCode2; + + ## checksum to calculate + for my $i (0..7) { + $d = hex(substr($dmsg,$i*2,2)); + $blkck ^= $d; + } + + $dmsg.= sprintf("%02x",$blkck) . '000000000000;'; + + ## additional length check | ToDo: must be checked, CUL data without preamble kr == 18 + # if (length($dmsg) != 31) { # working dmsg with comma == 31 (30 + 1) + # $self->_logging(qq[lib/PreparingSend_KOPP_FC, ERROR! dmsg wrong length - STOPPING send],2); + # return; + # } + + my $msg = 'SN;R=13;N=4;D=' . $dmsg; # N=4 | to compatible @Ralf + + return $msg; +} + +1;