diff --git a/.github/workflows/perlCritic.yml b/.github/workflows/perlCritic.yml index 7e4d443c0..54c0c9590 100644 --- a/.github/workflows/perlCritic.yml +++ b/.github/workflows/perlCritic.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 - - uses: shogo82148/actions-setup-perl@v1.29.0 + - uses: shogo82148/actions-setup-perl@v1.31.3 with: perl-version: 5.32 install-modules-with: cpanm diff --git a/.github/workflows/prove.yml b/.github/workflows/prove.yml index babf66251..31f0393c9 100644 --- a/.github/workflows/prove.yml +++ b/.github/workflows/prove.yml @@ -16,7 +16,7 @@ jobs: name: Perl ${{ matrix.perl }} on ${{ matrix.os }} steps: - uses: actions/checkout@v4 - - uses: shogo82148/actions-setup-perl@v1.29.0 + - uses: shogo82148/actions-setup-perl@v1.31.3 with: perl-version: ${{ matrix.perl }} install-modules-with: cpanm @@ -45,7 +45,7 @@ jobs: - name: Create clover report for perl Modules run: cover -report clover - - uses: codecov/codecov-action@v4.3.0 + - uses: codecov/codecov-action@v4.6.0 with: token: ${{ secrets.CODECOV_TOKEN }} file: clover.xml @@ -57,7 +57,7 @@ jobs: working-directory: /opt/fhem/ run: cover -report clover - - uses: codecov/codecov-action@v4.3.0 + - uses: codecov/codecov-action@v4.6.0 with: token: ${{ secrets.CODECOV_TOKEN }} file: clover.xml diff --git a/.github/workflows/version.yml b/.github/workflows/version.yml index ed68acea7..7420eacec 100644 --- a/.github/workflows/version.yml +++ b/.github/workflows/version.yml @@ -64,7 +64,7 @@ jobs: runs-on: ubuntu-latest steps: - id: file_changes - uses: tj-actions/changed-files@v42 + uses: tj-actions/changed-files@v45 with: json: true quotepath: false @@ -110,13 +110,13 @@ jobs: separator: ' ' - name: Update SDUINO_VERSION date if: endsWith(matrix.file, '00_SIGNALduino.pm') - uses: jacobtomlinson/gha-find-replace@3.0.2 + uses: jacobtomlinson/gha-find-replace@3.0.4 with: find: \w+\s+=>\s\'\d.\d.\d\+\d+\' replace: "SDUINO_VERSION => '${{ steps.versions.outputs._1 }}+${{ needs.metadata.outputs.date }}'" include: "${{ matrix.files }}" - name: Update Date in ID line - uses: jacobtomlinson/gha-find-replace@3.0.2 + uses: jacobtomlinson/gha-find-replace@3.0.4 with: find: \d\d\d\d-\d\d-\d\d\s\d\d:\d\d:\d\dZ\s[\w|-]+\s replace: "${{ needs.metadata.outputs.datetime }}Z ${{ github.event.pull_request.user.login }} " diff --git a/CHANGED b/CHANGED index a995910fc..891c2ad2f 100644 --- a/CHANGED +++ b/CHANGED @@ -1,3 +1,43 @@ +2024-09-10 - Merge pull request #1266 from RFD-FHEM/sidey79/issue1264 + +Attribute Clients is used if it is set +2024-09-08 - SD_WS_48 TFA JOKER Temperature transmitter 30.3212 (#1271) + +* SD_WS_48 TFA JOKER +Decoding realized. +* Update testData.json +add testdata for temperature transmitter TFA 30.3212 +2024-09-08 - Bugfix remote control CREATE 6601L (new identity) (#1269) + +* Bugfix CREATE_6601L +Ident does not consist of 4 nibbles, but 5. +* Update 14_SD_UT.pm + +2024-08-04 - new remote control CREATE 6601L (#1263) + +* new remote control CREATE 6601L +* Update 14_SD_UT.pm +* Update 00_SIGNALduino.pm +* Update README.md +* Update testData.json +add data for Remote control CREATE 6601L +* add test data for set command Remote control CREATE 6601L +* Update 03_set.t +* Update fhem.cfg + +2024-07-25 - new remote control RCnoName20_09 (#1261) + +* new RC RCnoName20_09 +remote control RCnoName20_09 with 9 buttons for ceiling fan, see https://forum.fhem.de/index.php?topic=138538.0 +* Update SD_ProtocolData.pm +* Update testData.json +add data for RCnoName20_09 +* Update 14_SD_UT.pm + +2024-06-20 - Bugfix Bresser lightning count (#1260) + +* Bugfix Bresser lightning count +Lightning counter overflowed at 999, now at 1599. 2024-04-25 - WMBUS extension to dispatch messages (#1252) * WMBUS proposal - extension to dispatch messages diff --git a/FHEM/00_SIGNALduino.pm b/FHEM/00_SIGNALduino.pm index f50bc8178..c6689d9b1 100644 --- a/FHEM/00_SIGNALduino.pm +++ b/FHEM/00_SIGNALduino.pm @@ -1,4 +1,4 @@ -# $Id: 00_SIGNALduino.pm 3.5.6 2024-04-24 06:21:19Z HomeAutoUser $ +# $Id: 00_SIGNALduino.pm 3.5.6 2024-08-28 14:15:02Z sidey79 $ # v3.5.6 - 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 @@ -255,7 +255,7 @@ my %matchListSIGNALduino = ( '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|118|121|127|128|130|132)#.*', # universal - more devices with different protocols + '17:SD_UT' => '^P(?:14|20|20.1|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|118|121|127|128|130|132)#.*', # 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}', @@ -3116,7 +3116,10 @@ sub SIGNALduino_Attr { ## Change Clients if( $aName eq 'Clients' ) { $hash->{Clients} = $aVal; - $hash->{Clients} = $clientsSIGNALduino if( !$hash->{Clients}) ; ## Set defaults + return if ($hash->{Clients}); + + ## Set defaults + $hash->{Clients} = $clientsSIGNALduino; return 'Setting defaults'; } ## Change MatchList @@ -3407,7 +3410,8 @@ sub SIGNALduino_IdList { #my $w = join ', ' => map "$_" => keys %BlacklistIDs; #SIGNALduino_Log3 $name, 3, "$name IdList, Attr blacklist $w"; } - $hash->{Clients} = $clientsSIGNALduino; # Set Default in clientlist if whitelist is not active + + $hash->{Clients} = AttrVal($name,'Clients', $clientsSIGNALduino); # use Attribute Clients or default if whitelist is not active } else { $hash->{Clients} = q[] # clear Clients if whitelist is active } diff --git a/FHEM/14_SD_UT.pm b/FHEM/14_SD_UT.pm index dcc2e4f95..8ecff6117 100644 --- a/FHEM/14_SD_UT.pm +++ b/FHEM/14_SD_UT.pm @@ -1,5 +1,5 @@ ######################################################################################### -# $Id: 14_SD_UT.pm 0 2023-12-19 18:00:00Z HomeAuto_User $ +# $Id: 14_SD_UT.pm 0 2024-09-08 08:41:41Z elektron-bbs $ # # The file is part of the SIGNALduino project. # The purpose of this module is universal support for devices. @@ -296,24 +296,29 @@ #} ############################################################################################################################################################################### # - Remote control with 4 buttons for diesel heating [Protocol 20] -#{ https://forum.fhem.de/index.php/topic,58397.msg999475.html#msg999475 @ fhem_user0815 2019-12-04 +# 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; -#} +# - Remote control with 9 buttons for ceiling fan with lighting (Controller MP 2.5+3UF) [Protocol 20] +# https://forum.fhem.de/index.php?topic=138538.0 @ Butsch 2024-06-17 +# RCnoName20_09_024F fan_stop MS;P0=249;P1=-744;P3=770;P4=-228;P5=-8026;D=050101010101013401013401013434343401010101010134010101010101010134;CP=0;SP=5;R=35;O;m2; +# RCnoName20_09_024F fan_low MS;P0=-7940;P1=246;P2=-757;P3=736;P4=-247;D=101212121212123412123412123434343412121212123434121212343412343412;CP=1;SP=0;R=47;O;m2; # - Remote control with 10 buttons for Leroy Deckenventilator [Protocol 20] -#{ https://forum.fhem.de/index.php/topic,53282.msg1233431.html#msg1233431 @ steffen83 2022-09-01 +# https://forum.fhem.de/index.php/topic,53282.msg1233431.html#msg1233431 @ steffen83 2022-09-01 # RCnoName20_10_3E00 light_on MU;P0=-8774;P1=282;P2=-775;P3=815;P4=-253;P5=-32001;D=10121234343434341212121212121212121212123434343412121234343412343415;CP=1; # RCnoName20_10_3E00 light_off MU;P0=-238;P1=831;P3=300;P4=-762;P5=-363;P6=192;P7=-8668;D=01010101010343434343434343434343434103415156464156464641564646734341010101010343434343434343434343434103410103434103434341034343734341010101010343434343434343434343434103410103434103434341034343734341010101010343434343434343434343434103410103434103434341;CP=3;O; # RCnoName20_10_3E00 fan_stop MU;P0=184;P1=-380;P2=128;P3=-9090;P4=-768;P5=828;P6=-238;P7=298;D=45656565656747474747474747474747474567474560404515124040451040374745656565656747474747474747474747474567474567474565674747456747374745656565656747474747474747474747474567474567474565674747456747374745656565656747474747474747474747474567474567474565674747;CP=7;O; -#} +# - Remote control CREATE 6601L with 14 buttons for CREATE Deckenventilator [Protocol 20] +# https://forum.fhem.de/index.php?topic=53282.msg1316246#msg1316246 @ Kent 2024-07-04 +# CREATE_6601L_1B900 fan_2 MS;P0=-7944;P1=-740;P4=253;P6=732;P7=-256;D=404141416767416767674141674141414141414141674141414141674141416767;CP=4;SP=0;R=67;O;m2; +# CREATE_6601L_1B900 fan_5 MS;P0=-264;P2=-743;P3=254;P4=733;P5=-7942;D=353232324040324040403232403232323232323232324032324032323232403240;CP=3;SP=5;R=40;O;m2; # - Remote control DC-1961-TG with 12 buttons for ceiling fan with lighting [Protocol 20] -#{ https://forum.fhem.de/index.php/topic,53282.msg1240911.html#msg1240911 @ Skusi 2022-10-23 +# https://forum.fhem.de/index.php/topic,53282.msg1240911.html#msg1240911 @ Skusi 2022-10-23 # DC_1961_TG_1846 light_on_off MS;P1=291;P2=-753;P3=762;P4=-249;P5=-8312;D=151212123434121212123412121234341234123412341212121234341212341234;CP=1;SP=5;R=224;O;m2; # DC_1961_TG_1846 fan_off MS;P1=-760;P2=747;P3=-282;P4=253;P5=-8335;D=454141412323414141412341414123234123412341412323234123232323412323;CP=4;SP=5;R=27;O;m2; # DC_1961_TG_1846 fan_direction MS;P0=-8384;P1=255;P2=-766;P3=754;P4=-263;D=101212123434121212123412121234341234123412341212341234341212341212;CP=1;SP=0;R=27;O;m2; -#} ############################################################################################################################################################################### # - Remote control Momento for wireless digital picture frame [Protocol 97] #{ elektron-bbs 2020-03-21 @@ -447,8 +452,6 @@ use warnings; use FHEM::Meta; no warnings 'portable'; # Support for 64-bit ints required -our $VERSION_SD_UT = '2023-12-19'; - sub SD_UT_bin2tristate; sub SD_UT_tristate2bin; @@ -811,6 +814,19 @@ my %models = ( Protocol => 'P20', Typ => 'remote' }, + 'RCnoName20_09' => { '00001000' => 'light_on_off', + '00000010' => 'fan_low', + '00000011' => 'fan_med', + '00001001' => 'fan_high', + '00000110' => 'fan_stop', + '00000001' => 'time_1h', + '00000111' => 'time_2h', + '00000101' => 'time_4h', + '00001010' => 'time_8h', + hex_length => [8], + Protocol => 'P20', + Typ => 'remote' + }, 'RCnoName20_10' => { '00011110' => 'light_on', '00010110' => 'light_off', '00010101' => 'fan_low', @@ -875,6 +891,22 @@ my %models = ( Protocol => 'P130', Typ => 'remote' }, + 'CREATE_6601L' => { '0101' => 'fan_on_off', # count 0-7 + '0010' => 'fan_1', # count 0-7 + '1000' => 'fan_2,fan_direction', # same bits, but count 0-7 (fan_2) or 8-15 + '0110' => 'fan_3', # count 0-7 + '0011' => 'fan_4', # count 0-7 + '0100' => 'fan_5,beeper_on_off', # same bits, but count 0-7 or 8-15 (fan_5) + '1010' => 'fan_6', # count 8-15 + '1001' => 'light_on_off', # count 0-7 + '1110' => 'light_color', # count 0-7 + '1011' => 'time_1h', # count 0-7 + '0111' => 'time_2h', # count 8-15 + '0001' => 'time_4h', # count 0-7 + hex_length => [8], + Protocol => 'P20', + Typ => 'remote' + }, 'DC_1961_TG' => { '10100111' => 'fan_off', '10100001' => 'fan_1', '10100010' => 'fan_2', @@ -1047,7 +1079,7 @@ my %models = ( ############################# sub SD_UT_Initialize { my ($hash) = @_; - $hash->{Match} = '^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|118|121|127|128|130|132)#.*'; + $hash->{Match} = '^P(?:14|20|20.1|22|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|118|121|127|128|130|132)#.*'; $hash->{DefFn} = \&SD_UT_Define; $hash->{UndefFn} = \&SD_UT_Undef; $hash->{ParseFn} = \&SD_UT_Parse; @@ -1065,9 +1097,7 @@ sub SD_UT_Initialize { 'MD_210R.*' => {ATTR => 'model:MD_210R', FILTER => '%NAME', autocreateThreshold => '3:180', GPLOT => q{}}, 'Momento.*' => {ATTR => 'model:Momento', FILTER => '%NAME', autocreateThreshold => '3:180', GPLOT => q{}}, 'OR28V.*' => {ATTR => 'model:OR28V', FILTER => '%NAME', autocreateThreshold => '3:180', GPLOT => q{}}, - 'RCnoName20.*' => {ATTR => 'model:RCnoName20', FILTER => '%NAME', autocreateThreshold => '3:180', GPLOT => q{}}, - 'DC_1961_TG.*' => {ATTR => 'model:DC_1961_TG', FILTER => '%NAME', autocreateThreshold => '3:180', GPLOT => q{}}, - 'TC6861.*' => {ATTR => 'model:TR401', FILTER => '%NAME', autocreateThreshold => '3:180', GPLOT => q{}}, + 'TC6861.*' => {ATTR => 'model:TC6861', FILTER => '%NAME', autocreateThreshold => '3:180', GPLOT => q{}}, 'TR401.*' => {ATTR => 'model:TR401', FILTER => '%NAME', autocreateThreshold => '3:180', GPLOT => q{}}, 'Techmar.*' => {ATTR => 'model:Techmar', FILTER => '%NAME', autocreateThreshold => '3:180', GPLOT => q{}}, 'Visivo.*' => {ATTR => 'model:Visivo', FILTER => '%NAME', autocreateThreshold => '3:180', GPLOT => q{}}, @@ -1114,46 +1144,48 @@ sub SD_UT_Define { } ### [2] checks CAME_TOP_432EV & Novy_840029 & Novy_840039 & Unitec_47031 ### - # uncoverable branch true + # uncoverable branch true return "wrong HEX-Value! ($a[3]) $a[2] HEX-Value to short | long or not HEX (0-9 | a-f | A-F){2}" if (($a[2] eq 'CAME_TOP_432EV' || $a[2] eq 'Novy_840029' || $a[2] eq 'Novy_840039' || $a[2] eq 'Unitec_47031') && not $a[3] =~ /^[0-9a-fA-F]{2}/xms); ### [3] checks SA_434_1_mini | QUIGG_DMV | TR_502MSV | BeSmart_S4 ### - # uncoverable branch true + # uncoverable branch true return "wrong HEX-Value! ($a[3]) $a[2] HEX-Value to short or long (must be 3 chars) or not HEX (0-9 | a-f | A-F){3}" if (($a[2] eq 'SA_434_1_mini' || $a[2] eq 'QUIGG_DMV' || $a[2] eq 'TR_502MSV' || $a[2] eq 'BeSmart_S4') && not $a[3] =~ /^[0-9a-fA-F]{3}/xms); - ### [4 nibble] checks Neff SF01_01319004 & BOSCH SF01_01319004_Typ2 & Chilitec_22640 & ESTO KL_RF01 & RCnoName20 & RCnoName20_10 & RCnoName128 & DC-1961-TG & xavax & BF_301 & Meikee_xx & CREATE_6601TL### - # uncoverable branch true - return "Wrong HEX-Value! ($a[3]) $a[2] Hex-value to short or long (must be 4 chars) or not hex (0-9 | a-f | A-F) {4}" if (($a[2] eq 'SF01_01319004' || $a[2] eq 'SF01_01319004_Typ2' || $a[2] eq 'Chilitec_22640' || $a[2] eq 'KL_RF01' || $a[2] eq 'RCnoName20' || $a[2] eq 'RCnoName20_10' || $a[2] eq 'RCnoName128' || $a[2] eq 'DC_1961_TG' || $a[2] eq 'xavax' || $a[2] eq 'BF_301' || $a[2] eq 'Meikee_21' || $a[2] eq 'Meikee_24' || $a[2] eq 'CREATE_6601TL' || $a[2] eq 'HA_HX2') && not $a[3] =~ /^[0-9a-fA-F]{4}/xms); - ### [5 nibble] checks RCnoName127 + ### [4 nibble] checks Neff SF01_01319004 & BOSCH SF01_01319004_Typ2 & Chilitec_22640 & ESTO KL_RF01 & RCnoName20 & RCnoName20_09 & RCnoName20_10 & RCnoName128 & DC-1961-TG & xavax & BF_301 & Meikee_xx & CREATE_6601TL ### + # uncoverable branch true + return "Wrong HEX-Value! ($a[3]) $a[2] Hex-value to short or long (must be 4 chars) or not hex (0-9 | a-f | A-F) {4}" + if (($a[2] eq 'SF01_01319004' || $a[2] eq 'SF01_01319004_Typ2' || $a[2] eq 'Chilitec_22640' || $a[2] eq 'KL_RF01' || $a[2] eq 'RCnoName20' || $a[2] eq 'RCnoName20_09' + || $a[2] eq 'RCnoName20_10' || $a[2] eq 'RCnoName128' || $a[2] eq 'DC_1961_TG' || $a[2] eq 'xavax' || $a[2] eq 'BF_301' || $a[2] eq 'Meikee_21' || $a[2] eq 'Meikee_24' + || $a[2] eq 'CREATE_6601TL' || $a[2] eq 'HA_HX2') && not $a[3] =~ /^[0-9a-fA-F]{4}/xms); + ### [5 nibble] checks CREATE_6601L & RCnoName127 # uncoverable branch true - return "Wrong HEX-Value! ($a[3]) $a[2] Hex-value to short or long (must be 5 chars) or not hex (0-9 | a-f | A-F) {5}" if ($a[2] eq 'RCnoName127' && not $a[3] =~ /^[0-9a-fA-F]{5}/xms); + return "Wrong HEX-Value! ($a[3]) $a[2] Hex-value to short or long (must be 5 chars) or not hex (0-9 | a-f | A-F) {5}" if (($a[2] eq 'CREATE_6601L' || $a[2] eq 'RCnoName127') && not $a[3] =~ /^[0-9a-fA-F]{5}/xms); ### [6] checks Manax | mumbi ### - # uncoverable branch true + # uncoverable branch true return "wrong HEX-Value! ($a[3]) $a[2] HEX-Value to short | long or not HEX (0-9 | a-f | A-F){4}_[ABCD]|[all]" if ($a[2] eq 'RC_10' && not $a[3] =~ /^[0-9a-fA-F]{4}_([ABCD]|all)$/xms) ; ### [6] checks MD_2003R | MD_210R | MD_2018R | Navaris | AC114_01B | Visivo ### - # uncoverable branch true + # uncoverable branch true return "wrong HEX-Value! ($a[3]) $a[2] Hex-value to short or long (must be 6 chars) or not hex (0-9 | a-f | A-F){6}" if (($a[2] eq 'MD_2003R' || $a[2] eq 'MD_210R' || $a[2] eq 'MD_2018R' || $a[2] eq 'Navaris' || $a[2] eq 'AC114_01B' || $a[2] eq 'Visivo') && not $a[3] =~ /^[0-9a-fA-F]{6}/xms); ### [7] checks Hoermann HSM4 | Krinner_LUMIX | Momento ### - # uncoverable branch true + # uncoverable branch true return "wrong HEX-Value! ($a[3]) $a[2] Hex-value to short or long (must be 7 chars) or not hex (0-9 | a-f | A-F){7}" if (($a[2] eq 'HSM4' || $a[2] eq 'Krinner_LUMIX' || $a[2] eq 'Momento') && not $a[3] =~ /^[0-9a-fA-F]{7}/xms); ### [7] checks Tedsen_SKX1xx, Tedsen_SKX2xx, Tedsen_SKX4xx, Tedsen_SKX6xx (tristate code)### - # uncoverable branch true + # uncoverable branch true return "wrong tristate code! ($a[3]) $a[2] code to short or long (must be 7 chars) or values not 0, 1 or F" if (($a[2] eq 'Tedsen_SKX1xx' || $a[2] eq 'Tedsen_SKX2xx' || $a[2] eq 'Tedsen_SKX4xx' || $a[2] eq 'Tedsen_SKX6xx') && not $a[3] =~ /^[01fF]{7}$/xms); ### [8 nibble] checks Techmar ### - # uncoverable branch true + # uncoverable branch true return "wrong HEX-Value! ($a[3]) $a[2] Hex-value to short or long (must be 8 chars) or not hex (0-9 | a-f | A-F)" if (($a[2] eq 'Techmar') && not $a[3] =~ /^[0-9a-fA-F]{8}$/xms); ### [9] checks Hoermann HS1-868-BS ### - # uncoverable branch true + # uncoverable branch true return "wrong HEX-Value! ($a[3]) $a[2] HEX-Value to short | long or not HEX (0-9 | a-f | A-F){9}" if ($a[2] eq 'HS1_868_BS' && not $a[3] =~ /^[0-9a-fA-F]{9}/xms); ### [14] checks LED_XM21_0 ### - # uncoverable branch true + # uncoverable branch true return "wrong HEX-Value! ($a[3]) $a[2] HEX-Value to short | long or not HEX (0-9 | a-f | A-F){14}" if ($a[2] eq 'LED_XM21_0' && not $a[3] =~ /^[0-9a-fA-F]{14}/xms); ### [3] checks TR401 (Well-Light) ### - # uncoverable branch true + # uncoverable branch true return "wrong devicecode! ($a[3]) $a[2] must be [0-9]_[1-4]" if ($a[2] eq 'TR401' && not $a[3] =~ /^[0-9]_[1-4]/xms); ### [3] checks TC6861 (Busch-Transcontrol HF) [P121] ### - # uncoverable branch true + # uncoverable branch true return "SD_UT model $a[2] wrong devicecode: ($a[3]) - must be 3 digit house code (hex 0-9 A-F) _ 1 digit channel (dec 1-3) - e.g. 3DC_1" if ($a[2] eq 'TC6861' && not $a[3] =~ /^[0-9A-F]{3}_[1-3]$/xms); - $hash->{versionModule} = $VERSION_SD_UT; $hash->{lastMSG} = 'no data'; $hash->{bitMSG} = 'no data'; $iodevice = $a[4] if($a[4]); @@ -1375,13 +1407,14 @@ sub SD_UT_Set { } elsif ($model eq 'TC6861') { $msg = $models{$model}{Protocol} . q{#P}; $msgEnd = '#R' . $repeats; - ############ Meikee_21 | Meikee_24 | RCnoName128 | RCnoName20 | RCnoName20_10 | DC-1961-TG | CREATE_6601TL | HA_HX2 ############ - } elsif ($model eq 'Meikee_21' || $model eq 'Meikee_24' || $model eq 'RCnoName128' || $model eq 'RCnoName20' || $model eq 'RCnoName20_10' || $model eq 'DC_1961_TG' || $model eq 'CREATE_6601TL' || $model eq 'HA_HX2') { + ############ Meikee_21 | Meikee_24 | RCnoName128 | RCnoName20 | RCnoName20_09 | RCnoName20_10 | DC-1961-TG | CREATE_6601TL | HA_HX2 ############ + } elsif ($model eq 'Meikee_21' || $model eq 'Meikee_24' || $model eq 'RCnoName128' || $model eq 'RCnoName20' || $model eq 'RCnoName20_09' || $model eq 'RCnoName20_10' + || $model eq 'DC_1961_TG' || $model eq 'CREATE_6601TL' || $model eq 'HA_HX2') { my $adr = sprintf '%016b' , hex $definition[1]; # argument 1 - adress to binary with 16 bits $msg = $models{$model}{Protocol} . q{#} . $adr; $msgEnd = '#R' . $repeats; - ############ RCnoName127 ############ - } elsif ($model eq 'RCnoName127') { + ############ CREATE_6601L | RCnoName127 ############ + } elsif ($model eq 'CREATE_6601L' || $model eq 'RCnoName127') { my $adr = sprintf '%020b' , hex $definition[1]; # argument 1 - adress to binary with 20 bits $msg = $models{$model}{Protocol} . q{#} . $adr; $msgEnd = '#R' . $repeats; @@ -1394,16 +1427,32 @@ sub SD_UT_Set { ### create setlist ### foreach my $keys (keys %{ $models{$model}}) { if ( $keys =~ /^[0-1]{1,}/xms ) { - $ret.= $models{$model}{$keys}.':noArg '; + if ($model eq 'CREATE_6601L' && index($models{$model}{$keys},',') > 0) { + my @values = split(',', $models{$model}{$keys}); + foreach ( @values ) { + $ret .= $_ . ':noArg '; + } + } else { + $ret .= $models{$model}{$keys} . ':noArg '; + } } } } else { if (defined $msgEnd) { ### if cmd, set bits ### - foreach my $keys (keys %{ $models{$model}}) { + foreach my $keys (keys %{$models{$model}}) { if ( $keys =~ /^[0-1]{1,}/xms ) { + if ($model eq 'CREATE_6601L' && index($models{$model}{$keys},',') > 0) { + my @values = split(',', $models{$model}{$keys}); + foreach ( @values ) { + $value = $_; + Log3 $name, 5, "$ioname: SD_UT_Set model=$model value=$value"; + last if ($value eq $cmd); + } + } else { + $value = $models{$model}{$keys}; + } $save = $keys; - $value = $models{$model}{$keys}; last if ($value eq $cmd); } } @@ -1491,14 +1540,17 @@ sub SD_UT_Set { $msg .= $save; # on/off $msg .= sprintf('%012b', hex $housecode); $msg .= $models{$model}{ch}{$ch} . $msgEnd; - # $msg .= $models{$model}{ch}{$ch} . 'P' . $msgEnd; - ############ RCnoName20_10 or DC-1961-TG [P20] ############ - } elsif ($model eq 'RCnoName20_10' || $model eq 'DC_1961_TG') { + ############ RCnoName20_09 or RCnoName20_10 or DC-1961-TG or CREATE_6601L [P20] ############ + } elsif ($model eq 'RCnoName20_09' || $model eq 'RCnoName20_10' || $model eq 'DC_1961_TG' || $model eq 'CREATE_6601L') { $msg .= $save; # button my $rollingCode = ReadingsVal($name, 'rollingCode', 0); $rollingCode += 1; - if ($rollingCode > 7) { - $rollingCode = 0; + if ($model eq 'CREATE_6601L' && ($cmd eq 'fan_5' || $cmd eq 'fan_direction' || $cmd eq 'time_2h')) { # rolling code 8-15 + $rollingCode += 8 if ($rollingCode < 8); + $rollingCode = 8 if ($rollingCode > 15); + } else { # rolling code 0-7 + $rollingCode -= 8 if ($rollingCode > 7); + $rollingCode = 0 if ($rollingCode > 7); } readingsSingleUpdate($hash, 'rollingCode' , $rollingCode, 0); $msg .= sprintf('%04b', $rollingCode); # rolling code @@ -1508,6 +1560,7 @@ sub SD_UT_Set { } $msg .= sprintf('%04b', $xor); # check $msg .= $msgEnd; + Log3 $name, 5, "$ioname: SD_UT_Set model=$model, cmd=$cmd, msg=$msg, save=$save, rollingCode=$rollingCode"; ############ RCnoName127 [P127] ############ } elsif ($model eq 'RCnoName127') { $msg .= $save; # button @@ -1581,20 +1634,24 @@ sub SD_UT_Parse { my $state = 'unknown'; my $tristateCode; my $unknown_bits; # unknown bits to a reading - + my $rollingCode; my $deletecache = $modules{SD_UT}{defptr}{deletecache}; Log3 $iohash, 5, "$ioname: SD_UT device in delete cache = $deletecache" if($deletecache && $deletecache ne '-'); + # uncoverable branch true if ($deletecache && $deletecache ne '-') { CommandDelete( undef, "$deletecache" ); # delete device CommandDelete( undef, "FileLog_$deletecache" ); # delete filelog_device + # uncoverable branch true Log3 $iohash, 3, "SD_UT_Parse device $deletecache deleted" if($deletecache); $modules{SD_UT}{defptr}{deletecache} = '-'; return ''; } + # uncoverable branch true if ($hlen == 3) { ### Westinghouse Buttons_five [P29] ### + # uncoverable branch true if (!$def && ($protocol == 29 || $protocol == 30)) { $deviceCode = substr($rawData,2,1); $devicedef = 'Buttons_five ' . $deviceCode; @@ -1602,23 +1659,27 @@ sub SD_UT_Parse { } ### Westinghouse Buttons_six [P29] ### if (!$def && ($protocol == 29 || $protocol == 30)) { + # uncoverable branch true $deviceCode = substr($rawData,2,1); $devicedef = 'Buttons_six ' . $deviceCode; $def = $modules{SD_UT}{defptr}{$devicedef}; } ### Unitec_47031 [P30] ### + # uncoverable branch true if (!$def && ($protocol == 30 || $protocol == 83)) { $deviceCode = substr($rawData,0,2); $devicedef = 'Unitec_47031 ' . $deviceCode; $def = $modules{SD_UT}{defptr}{$devicedef}; } ### Remote control SA_434_1_mini 923301 [P81] ### + # uncoverable branch true if (!$def && ($protocol == 81 || $protocol == 83 || $protocol == 86)) { $deviceCode = $rawData; $devicedef = 'SA_434_1_mini ' . $deviceCode; $def = $modules{SD_UT}{defptr}{$devicedef}; } ### Westinghouse_Delancey RH787T [P83] ### no define + # uncoverable branch true if (!$def && ($protocol == 83 || $protocol == 30)) { $deviceCode = substr($bitData,1,4); $deviceCode = sprintf("%X", oct( "0b$deviceCode" ) ); @@ -1626,16 +1687,19 @@ sub SD_UT_Parse { $def = $modules{SD_UT}{defptr}{$devicedef}; } ### CAME_TOP_432EV [P86] ### no define + # uncoverable branch true if (!$def && ($protocol == 86 || $protocol == 81)) { $deviceCode = substr($rawData,0,2); $devicedef = 'CAME_TOP_432EV ' . $deviceCode; $def = $modules{SD_UT}{defptr}{$devicedef}; } ### TR401 (Well-Light) [P114] ### + # uncoverable branch true if (!$def && $protocol == 114 && substr($bitData,-5) eq '11111') { $model = 'TR401'; my $housecode = substr($rawData,1,1) >> 1; my $ch = substr($bitData,1,3); + # uncoverable branch true if ( exists $models{$model}{ch}{$ch} ) { $ch = $models{$model}{ch}{$ch}; $deviceCode = $housecode .'_'. $ch; @@ -1794,22 +1858,46 @@ sub SD_UT_Parse { if (!$def && $protocol == 20) { ### Remote control RCnoName20 [P20] ### $deviceCode = substr($rawData,0,4); - $devicedef = 'RCnoName20 ' . $deviceCode; - $def = $modules{SD_UT}{defptr}{$devicedef}; - $model = 'RCnoName20'; - $name = 'RCnoName20_' . $deviceCode; - ### Remote control RCnoName20_10 or DC-1961-TG [P20] ### + my $button = substr($bitData,16,15); + if (exists $models{'RCnoName20'}{$button}) { + $model = 'RCnoName20'; + $devicedef = $model . ' ' . $deviceCode; + $def = $modules{SD_UT}{defptr}{$devicedef}; + $name = $model . '_' . $deviceCode; + } + ### Remote control RCnoName20_09 or RCnoName20_10 or DC-1961-TG or CREATE_6601L [P20] ### my $xor = 0; for (my $n = 0; $n < 8; $n++) { $xor ^= hex(substr($rawData,$n,1)); } if ($xor == 10) { - my $button = substr($bitData,16,8); - $model = 'RCnoName20_10' if exists $models{'RCnoName20_10'}{$button}; - $model = 'DC_1961_TG' if exists $models{'DC_1961_TG'}{$button}; - $devicedef = $model . ' ' . $deviceCode if (!$def); - $def = $modules{SD_UT}{defptr}{$devicedef} if (!$def); - $name = $model . '_' . $deviceCode; + $button = substr($bitData,16,8); + if (exists $models{'RCnoName20_09'}{$button} && !$def) { + $model = 'RCnoName20_09'; + $devicedef = $model . ' ' . $deviceCode; + $def = $modules{SD_UT}{defptr}{$devicedef}; + $name = $model . '_' . $deviceCode; + } + if (exists $models{'RCnoName20_10'}{$button} && !$def) { + $model = 'RCnoName20_10'; + $devicedef = $model . ' ' . $deviceCode; + $def = $modules{SD_UT}{defptr}{$devicedef}; + $name = $model . '_' . $deviceCode; + } + if (exists $models{'DC_1961_TG'}{$button} && !$def) { + $model = 'DC_1961_TG'; + $devicedef = $model . ' ' . $deviceCode; + $def = $modules{SD_UT}{defptr}{$devicedef}; + $name = $model . '_' . $deviceCode; + } + $button = substr($bitData,20,4) if (!$def); + if (exists $models{'CREATE_6601L'}{$button} && !$def) { + $deviceCode = substr($rawData,0,5); + $model = 'CREATE_6601L'; + $devicedef = $model . ' ' . $deviceCode; + $def = $modules{SD_UT}{defptr}{$devicedef}; + $name = $model . '_' . $deviceCode; + } } } if (!$def && $protocol == 92) { @@ -2245,11 +2333,17 @@ sub SD_UT_Parse { } elsif ($model eq 'RCnoName20' && $protocol == 20) { $state = substr($bitData,16,15); # last bit is filled $deviceCode = substr($rawData,0,4); - ### Remote control RCnoName20_10 or DC-1961-TG[P20] ### - } elsif (($model eq 'RCnoName20_10' || $model eq 'DC_1961_TG') && $protocol == 20) { + ### Remote control RCnoName20_09 or RCnoName20_10 or DC-1961-TG [P20] ### + } elsif (($model eq 'RCnoName20_09' || $model eq 'RCnoName20_10' || $model eq 'DC_1961_TG') && $protocol == 20) { $state = substr($bitData,16,8); $deviceCode = substr($rawData,0,4); - my $rollingCode = hex(substr($rawData,6,1)); + $rollingCode = hex(substr($rawData,6,1)); + readingsBulkUpdate($hash, 'rollingCode', $rollingCode, 0); + ### Remote control CREATE_6601L [P20] ### + } elsif ($model eq 'CREATE_6601L' && $protocol == 20) { + $state = substr($bitData,20,4); + $deviceCode = substr($rawData,0,5); + $rollingCode = hex(substr($rawData,6,1)); readingsBulkUpdate($hash, 'rollingCode', $rollingCode, 0); ### Remote control xavax [P26] ### } elsif ($model eq 'xavax' && $protocol == 26) { @@ -2327,6 +2421,23 @@ sub SD_UT_Parse { if ($model eq 'Novy_840029' || $model eq 'Novy_840039') { $state = $state =~ /^[01]+$/x ? "Please check your model. The code $deviceCode is not supported." : $state; } + if ($model eq 'CREATE_6601L') { + Log3 $name, 5, "$ioname: SD_UT_Parse $devicedef state=$state, rollingCode=$rollingCode"; + if ($state eq 'fan_5,beeper_on_off') { + if ($rollingCode < 8) { # rollingcode 0-7 + $state = 'beeper_on_off'; + } else { # rollingcode 8-15 + $state = 'fan_5'; + } + } + if ($state eq 'fan_2,fan_direction') { + if ($rollingCode < 8) { # rollingcode 0-7 + $state = 'fan_2'; + } else { # rollingcode 8-15 + $state = 'fan_direction'; + } + } + } } readingsBulkUpdate($hash, 'deviceCode', $deviceCode, 0) if (defined($deviceCode) && $models{$model}{Typ} eq 'remote'); @@ -2513,14 +2624,14 @@ sub SD_UT_Attr { $deviceCode = substr $bitData,8,24; $deviceCode = sprintf("%06X", oct( "0b$bitData" ) ); $devicename = $devicemodel.'_'.$deviceCode; - ############ Meikee_xx or RCnoName20 or RCnoName20_10 or RCnoName128 or DC_1961_TG or CREATE_6601TL or HA_HX2 ############ - } elsif ($attrValue eq 'Meikee_21' || $attrValue eq 'Meikee_24' || $attrValue eq 'RCnoName20' || $attrValue eq 'RCnoName20_10' || - $attrValue eq 'RCnoName128' || $attrValue eq 'DC_1961_TG' || $attrValue eq 'CREATE_6601TL' || $attrValue eq 'HA_HX2') { + ############ Meikee_xx or RCnoName20 or RCnoName20_09 or RCnoName20_10 or RCnoName128 or DC_1961_TG or CREATE_6601TL or HA_HX2 ############ + } elsif ($attrValue eq 'Meikee_21' || $attrValue eq 'Meikee_24' || $attrValue eq 'RCnoName20' || $attrValue eq 'RCnoName20_09' || $attrValue eq 'RCnoName20_10' || + $attrValue eq 'RCnoName128' || $attrValue eq 'DC_1961_TG' || $attrValue eq 'CREATE_6601TL' || $attrValue eq 'HA_HX2') { $deviceCode = substr($bitData,0,16); $deviceCode = sprintf("%04X", oct( "0b$deviceCode" ) ); $devicename = $devicemodel.'_'.$deviceCode; - ############ RCnoName127 ############ - } elsif ($attrValue eq 'RCnoName127') { + ############ CREATE_6601L or RCnoName127 ############ + } elsif ($attrValue eq 'CREATE_6601L' || $attrValue eq 'RCnoName127') { $deviceCode = substr $bitData,0,20; $deviceCode = sprintf("%05X", oct( "0b$deviceCode" ) ); $devicename = $devicemodel.'_'.$deviceCode; @@ -2625,13 +2736,10 @@ sub SD_UT_tristate2bin {
  • Busch-Transcontrol HF - remote control 6861   (module model: TC6861, protocol 121)
  • CAME swing gate drive   (module model: CAME_TOP_432EV, protocol 86)
  • ChiliTec LED X-Mas light   (module model: Chilitec_22640, protocol 14)
  • +
  • CREATE 6601L Remote control for ceiling fan with light   (module model: CREATE_6601L, protocol 20)
  • CREATE 6601TL Remote control for ceiling fan with light   (module model: CREATE_6601TL, protocol 130)
  • DC-1961-TG - remote control with 12 buttons for ceiling fan with lighting   (module model: DC_1961_TG, protocol 20)
  • ESTO ceiling lamp   (module model: KL_RF01, protocol 93)
  • -
  • Remote control with 4 buttons for diesel heating   (module model: RCnoName20, protocol 20)
  • -
  • Remote control with 10 buttons for Leroy ceiling fan   (module model: RCnoName20_10, protocol 20)
  • -
  • Remote control with 12 buttons for ceiling fan   (module model: RCnoName128, protocol 128)
  • -
  • Remote control with 14 buttons for ceiling fan   (module model: RCnoName127, protocol 127)
  • Halemeier HA-HX2   (module model: HA-HX2, protocol 132)
  • Hoermann HS1-868-BS   (module model: HS1_868_BS, protocol 69)
  • Hoermann HSM4   (module model: HSM4, protocol 69)
  • @@ -2653,6 +2761,11 @@ sub SD_UT_tristate2bin {
  • Novy Cloud 230 kitchen hood   (module model: Novy_840039, protocol 86)
  • Novy Pureline 6830 kitchen hood   (module model: Novy_840029, protocol 86)
  • QUIGG DMV-7000   (module model: QUIGG_DMV, protocol 34)
  • +
  • Remote control with 4 buttons for diesel heating   (module model: RCnoName20, protocol 20)
  • +
  • Remote control with 9 buttons for ceiling fan   (module model: RCnoName20_09, protocol 20)
  • +
  • Remote control with 10 buttons for Leroy ceiling fan   (module model: RCnoName20_10, protocol 20)
  • +
  • Remote control with 12 buttons for ceiling fan   (module model: RCnoName128, protocol 128)
  • +
  • Remote control with 14 buttons for ceiling fan   (module model: RCnoName127, protocol 127)
  • SA-434-1 mini 923301   (module model: SA_434_1_mini, protocol 81)
  • Techmar Garden Lights    (module model: Techmar, protocol 95)
  • Tedsen Teletaster (protocol 46): @@ -2788,7 +2901,7 @@ sub SD_UT_tristate2bin {
  • ignore
  • IODev
  • model
    - The attribute indicates the model type of your device (AC114_01B, BeSmart_S4, Buttons_five, Buttons_six, CAME_TOP_432EV, Chilitec_22640, CREATE_6601TL, DC_1961_TG, HA_HX2, HS1-868-BS, HSM4, KL_RF01, LED_XM21_0, Meikee_21, Meikee_24, Momento, Navaris, Novy_840029, Novy_840039, OR28V, QUIGG_DMV, RC_10, RH787T, SA_434_1_mini, SF01_01319004, TC6861, TR60C1, Tedsen_SKX1xx, Tedsen_SKX2xx, Tedsen_SKX4xx, Tedsen_SKX6xx, TR_502MSV, Unitec_47031, unknown).
    + The attribute indicates the model type of your device (AC114_01B, BeSmart_S4, Buttons_five, Buttons_six, CAME_TOP_432EV, Chilitec_22640, CREATE_6601L, CREATE_6601TL, DC_1961_TG, HA_HX2, HS1-868-BS, HSM4, KL_RF01, LED_XM21_0, Meikee_21, Meikee_24, Momento, Navaris, Novy_840029, Novy_840039, OR28V, QUIGG_DMV, RC_10, RH787T, SA_434_1_mini, SF01_01319004, TC6861, TR60C1, Tedsen_SKX1xx, Tedsen_SKX2xx, Tedsen_SKX4xx, Tedsen_SKX6xx, TR_502MSV, Unitec_47031, unknown).
    If the attribute is changed, a new device is created using autocreate. Autocreate must be activated for this.
  • repeats
    @@ -2862,10 +2975,12 @@ sub SD_UT_tristate2bin {
  • Busch-Transcontrol HF - Handsender 6861   (Modulmodel: TC6861, Protokoll 121)
  • CAME Drehtor Antrieb   (Modulmodel: CAME_TOP_432EV, Protokoll 86)
  • ChiliTec LED Christbaumkerzen   (Modulmodel: Chilitec_22640, Protokoll 14)
  • +
  • CREATE 6601L Fernbedienung für Ventilator mit Licht   (Modulmodel: CREATE_6601L, Protokoll 20)
  • CREATE 6601TL Fernbedienung für Ventilator mit Licht   (Modulmodel: CREATE_6601TL, Protokoll 130)
  • DC-1961-TG - Fernbedienung mit 12 Tasten für Deckenventilator mit Beleuchtung   (Modulmodel: DC_1961_TG, Protokoll 20)
  • ESTO Deckenlampe   (Modulmodel: KL_RF01, Protokoll 93)
  • Fernbedienung mit 4 Tasten für Diesel-Heizung    (Modulmodel: RCnoName20, Protokoll 20)
  • +
  • Fernbedienung mit 9 Tasten für Deckenventilator   (Modulmodel: RCnoName20_09, Protokoll 20)
  • Fernbedienung mit 10 Tasten für Leroy Deckenventilator   (Modulmodel: RCnoName20_10, Protokoll 20)
  • Fernbedienung mit 12 Tasten für Deckenventilator   (Modulmodel: RCnoName128, Protokoll 128)
  • Fernbedienung mit 14 Tasten für Deckenventilator   (Modulmodel: RCnoName127, Protokoll 127)
  • @@ -3025,7 +3140,7 @@ sub SD_UT_tristate2bin {
  • ignore
  • IODev
  • model
    - Diese Attribut bezeichnet den Modelltyp Ihres Gerätes (AC114_01B, BeSmart_S4, Buttons_five, Buttons_six, CAME_TOP_432EV, Chilitec_22640, CREATE_6601TL, DC_1961_TG, HA_HX2, HS1-868-BS, HSM4, KL_RF01, LED_XM21_0, Meikee_21, Meikee_24, Momento, Navaris, Novy_840029, Novy_840039, OR28V, QUIGG_DMV, RC_10, RH787T, SA_434_1_mini, SF01_01319004, TC6861, TR60C1, Tedsen_SKX1xx, Tedsen_SKX2xx, Tedsen_SKX4xx, Tedsen_SKX6xx, TR_502MSV, Unitec_47031, unknown).
    + Dieses Attribut bezeichnet den Modelltyp Ihres Gerätes (AC114_01B, BeSmart_S4, Buttons_five, Buttons_six, CAME_TOP_432EV, Chilitec_22640, CREATE_6601L, CREATE_6601TL, DC_1961_TG, HA_HX2, HS1-868-BS, HSM4, KL_RF01, LED_XM21_0, Meikee_21, Meikee_24, Momento, Navaris, Novy_840029, Novy_840039, OR28V, QUIGG_DMV, RC_10, RH787T, SA_434_1_mini, SF01_01319004, TC6861, TR60C1, Tedsen_SKX1xx, Tedsen_SKX2xx, Tedsen_SKX4xx, Tedsen_SKX6xx, TR_502MSV, Unitec_47031, unknown).
    Bei Änderung des Attributes wird ein neues Gerät mittels autocreate erzeugt. Autocreate muss dazu aktiviert sein.
  • repeats
    @@ -3075,6 +3190,7 @@ sub SD_UT_tristate2bin { =end html_DE + =for :application/json;q=META.json 14_SD_UT.pm { "author": [ @@ -3115,7 +3231,7 @@ sub SD_UT_tristate2bin { } } }, - "version": "v1.0.2", + "version": "v1.0.5", "release_status": "stable", "resources": { "bugtracker": { diff --git a/FHEM/14_SD_WS.pm b/FHEM/14_SD_WS.pm index c2a215c6f..7222fb755 100644 --- a/FHEM/14_SD_WS.pm +++ b/FHEM/14_SD_WS.pm @@ -1,4 +1,4 @@ -# $Id: 14_SD_WS.pm 26982 2024-03-11 20:44:20Z sidey79 $ +# $Id: 14_SD_WS.pm 26982 2024-09-08 15:09:34Z elektron-bbs $ # # The purpose of this module is to support serval # weather sensors which use various protocol @@ -8,7 +8,7 @@ # elektron-bbs 2018 - # sidey 2017 - # -# 17.04.2017 WH2 (TFA 30.3157 nur Temp, Hum = 255),es wird das Perlmodul Digest::CRC benoetigt fuer CRC-Pruefung benoetigt +# 17.04.2017 WH2 (TFA 30.3157 nur Temp, Hum = 255),es wird das Perlmodul Digest::CRC fuer CRC-Pruefung benoetigt # 29.05.2017 Test ob Digest::CRC installiert # 22.07.2017 WH2 angepasst # 21.08.2017 WH2 Abbruch wenn kein "FF" am Anfang @@ -54,6 +54,7 @@ # 21.08.2023 neues Protokoll 129: Sainlogic weather station FT-0835 # 25.11.2023 Protokoll 117: neuer Sensor BRESSER Air Quality Sensor Art.No.: 7009970, Hersteller CCL Electronics LTD Model C3123A # 06.01.2024 neues Protokoll 131: BRESSER Blitzsensor Art.No.: 7009976, Hersteller CCL Electronics LTD Model C3129A +# 03.09.2024 neues Protokoll 48: Funk-Thermometer JOKER TFA 30.3055, Temperatursender 30.3212 package main; @@ -97,6 +98,7 @@ sub SD_WS_Initialize { "SD_WS_33_TH_.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.* model:other", FILTER => "%NAME", GPLOT => "temp4hum4:Temp/Hum,", autocreateThreshold => "2:180"}, "SD_WS_33_T_.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.* model:other", FILTER => "%NAME", GPLOT => "temp4:Temp,", autocreateThreshold => "2:180"}, "SD_WS_38_T_.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", FILTER => "%NAME", GPLOT => "temp4:Temp,", autocreateThreshold => "3:180"}, + "SD_WS_48_T.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", FILTER => "%NAME", GPLOT => "temp4:Temp,", autocreateThreshold => "3:180"}, "SD_WS_51_TH.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", FILTER => "%NAME", GPLOT => "temp4hum4:Temp/Hum,", autocreateThreshold => "3:180"}, "SD_WS_53_TH.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", FILTER => "%NAME", GPLOT => "temp4hum4:Temp/Hum,", autocreateThreshold => "3:180"}, "SD_WS_54_R.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", FILTER => "%NAME", GPLOT => "rain4:Rain,", autocreateThreshold => "3:180"}, @@ -118,7 +120,7 @@ sub SD_WS_Initialize { 'SD_WS_122_T.*' => { ATTR => 'event-min-interval:.*:60 event-on-change-reading:.*', FILTER => '%NAME', GPLOT => 'temp4:Temp,', autocreateThreshold => '10:180'}, 'SD_WS_123_T.*' => { ATTR => 'event-min-interval:.*:300 event-on-change-reading:.*', FILTER => '%NAME', GPLOT => 'temp4:Temp,', autocreateThreshold => '2:180'}, 'SD_WS_125_.*' => { ATTR => 'event-min-interval:.*:300 event-on-change-reading:.*', FILTER => '%NAME', GPLOT => 'temp4hum4:Temp/Hum,', autocreateThreshold => '2:300'}, - 'SD_WS_126_R.*' => { ATTR => 'event-min-interval:.*:300 event-on-change-reading:.*', FILTER => '%NAME', GPLOT => 'rain4:Rain,', autocreateThreshold => "2:180"}, + 'SD_WS_126_R.*' => { ATTR => 'event-min-interval:.*:300 event-on-change-reading:.*', FILTER => '%NAME', GPLOT => 'rain4:Rain,', autocreateThreshold => "2:180"}, 'SD_WS_129.*' => { ATTR => 'event-min-interval:.*:300 event-on-change-reading:.*', FILTER => '%NAME', GPLOT => 'temp4hum4:Temp/Hum,', autocreateThreshold => '3:180'}, 'SD_WS_131.*' => { ATTR => 'event-min-interval:.*:300 event-on-change-reading:.*', FILTER => '%NAME', GPLOT => q{}, autocreateThreshold => '2:180'}, }; @@ -256,46 +258,6 @@ sub SD_WS_Parse { my $pm10; # particulate matter <= 10 µm my %decodingSubs = ( - 50 => # Protocol 50 - # FF550545FF9E - # FF550541FF9A - # AABCDDEEFFGG - # A = Preamble, always FF - # B = TX type, always 5 - # C = Address (5/6/7) > low 2 bits = 1/2/3 - # D = Soil moisture 05% - # E = temperature - # F = security code, always F - # G = Checksum 55+05+45+FF=19E CRC value = 9E - { # subs to decode this - sensortype => 'XT300', - model => 'SD_WS_50_SM', - prematch => sub {my $msg = shift; return 1 if ($msg =~ /^FF5[0-9A-F]{5}FF[0-9A-F]{2}/); }, # prematch - crcok => sub {my $msg = shift; return 1 if ((hex(substr($msg,2,2))+hex(substr($msg,4,2))+hex(substr($msg,6,2))+hex(substr($msg,8,2))&0xFF) == (hex(substr($msg,10,2))) ); }, # crc - id => sub {my $msg = shift; return (hex(substr($msg,2,2)) &0x03 ); }, # id - temp => sub {my $msg = shift; return ((hex(substr($msg,6,2)))-40) }, # temp - hum => sub {my $msg = shift; return hex(substr($msg,4,2)); }, # hum - channel => sub {my (undef,$bitData) = @_; return ( SD_WS_binaryToNumber($bitData,12,15)&0x03 ); }, # channel - }, - 71 => - # 5C2A909F792F - # 589A829FDFF4 - # PiiTTTK?CCCC - # P = Preamble (immer 5 ?) - # i = ID - # T = Temperatur - # K = Kanal (B/A/9) - # ? = immer F ? - # C = Checksum ? - { - sensortype => 'PV-8644', - model => 'SD_WS71_T', - prematch => sub {my $msg = shift; return 1 if ($msg =~ /^5[A-F0-9]{6}F[A-F0-9]{2}/); }, # prematch - crcok => sub {return 1; }, # crc is unknown - id => sub {my (undef,$bitData) = @_; return SD_WS_binaryToNumber($bitData,4,11); }, # id - temp => sub {my (undef,$bitData) = @_; return ((SD_WS_binaryToNumber($bitData,12,23) - 2448) / 10); }, # temp - channel => sub {my (undef,$bitData) = @_; return SD_WS_binaryToNumber($bitData,26,27); }, # channel - }, 27 => { # Protokollbeschreibung: Temperatur-/Feuchtigkeitssensor EuroChron EFTH-800, EFS-3110A @@ -445,6 +407,71 @@ sub SD_WS_Parse { } }, } , + 48 => ## Funk-Thermometer JOKER TFA 30.3055, Temperatursender 30.3212 + # FF489034FF10 + # PPFIITTTPPCC + # P = 8 bit preamble, always 0xFF + # F = 4 bit flags, always 0b0100 + # I = 8 bit ident + # T = 12 bit temperature, if first bit=1 then negative + # P = 8 bit postamble, always 0xFF + # C = 8 bit CRC-8/NRSC-5, see https://crccalc.com/?crc=FF489034FF10&method=CRC-8/NRSC-5&datatype=1&outtype=0 + # width=8 poly=0x31 init=0xff refin=false refout=false xorout=0x00 check=0xf7 residue=0x00 name="CRC-8/NRSC-5" + { + sensortype => 'Temperature transmitter', + model => 'SD_WS_48_T', + modelStat => sub { my (undef,undef) = @_; return 'TFA 30.3212'; }, + prematch => sub { my ($rawData,undef) = @_; return 1 if ($rawData =~ /^FF4[0-9A-F]{5}FF[0-9A-F]{2}/); }, + id => sub { my ($rawData,undef) = @_; return substr($rawData,3,2); }, + temp => sub { my (undef,$bitData) = @_; + my $temp = SD_WS_binaryToNumber($bitData,21,31) / 10; + $temp *= -1 if (substr($bitData,20,1)); + return $temp; + }, + crcok => sub { my $rawData = shift; + my $rc = eval { + require Digest::CRC; + Digest::CRC->import(); + 1; + }; + if ($rc) { + my $datacheck1 = pack( 'H*', substr($rawData,0,12) ); + my $crcmein1 = Digest::CRC->new(width => 8, init => 0xFF, poly => 0x31); + my $rr3 = $crcmein1->add($datacheck1)->hexdigest; + Log3 $name, 4, "$name: SD_WS_48 Parse msg $rawData, CRC $rr3"; + if (hex($rr3) == 0) { + return 1; + } else { + Log3 $name, 3, "$name: SD_WS_48 Parse msg $rawData - ERROR CRC8 (0x$rr3 must be 0x00)"; + return 0; + } + } else { + Log3 $name, 1, "$name: SD_WS_48 Parse msg $rawData - ERROR CRC not checked, please install module Digest::CRC"; + return 0; + } + } + }, + 50 => # Protocol 50 + # FF550545FF9E + # FF550541FF9A + # AABCDDEEFFGG + # A = Preamble, always FF + # B = TX type, always 5 + # C = Address (5/6/7) > low 2 bits = 1/2/3 + # D = Soil moisture 05% + # E = temperature + # F = security code, always F + # G = Checksum 55+05+45+FF=19E CRC value = 9E + { # subs to decode this + sensortype => 'XT300', + model => 'SD_WS_50_SM', + prematch => sub {my $msg = shift; return 1 if ($msg =~ /^FF5[0-9A-F]{5}FF[0-9A-F]{2}/); }, # prematch + crcok => sub {my $msg = shift; return 1 if ((hex(substr($msg,2,2))+hex(substr($msg,4,2))+hex(substr($msg,6,2))+hex(substr($msg,8,2))&0xFF) == (hex(substr($msg,10,2))) ); }, # crc + id => sub {my $msg = shift; return (hex(substr($msg,2,2)) &0x03 ); }, # id + temp => sub {my $msg = shift; return ((hex(substr($msg,6,2)))-40) }, # temp + hum => sub {my $msg = shift; return hex(substr($msg,4,2)); }, # hum + channel => sub {my (undef,$bitData) = @_; return ( SD_WS_binaryToNumber($bitData,12,15)&0x03 ); }, # channel + }, 51 => { # Auriol Message Format (rflink/Plugin_044.c): @@ -634,6 +661,25 @@ sub SD_WS_Parse { temp => sub {my (undef,$bitData) = @_; return FHEM::Core::Utils::Math::round((SD_WS_binaryToNumber($bitData,20,31)-720)*0.0556,1); }, # temp hum => sub {my ($rawData,$bitData) = @_; return substr($rawData,1,1) eq "5" ? (SD_WS_binaryToNumber($bitData,32,39)) : 0;}, # hum } , + 71 => + # 5C2A909F792F + # 589A829FDFF4 + # PiiTTTK?CCCC + # P = Preamble (immer 5 ?) + # i = ID + # T = Temperatur + # K = Kanal (B/A/9) + # ? = immer F ? + # C = Checksum ? + { + sensortype => 'PV-8644', + model => 'SD_WS71_T', + prematch => sub {my $msg = shift; return 1 if ($msg =~ /^5[A-F0-9]{6}F[A-F0-9]{2}/); }, # prematch + crcok => sub {return 1; }, # crc is unknown + id => sub {my (undef,$bitData) = @_; return SD_WS_binaryToNumber($bitData,4,11); }, # id + temp => sub {my (undef,$bitData) = @_; return ((SD_WS_binaryToNumber($bitData,12,23) - 2448) / 10); }, # temp + channel => sub {my (undef,$bitData) = @_; return SD_WS_binaryToNumber($bitData,26,27); }, # channel + }, 84 => { # Protokollbeschreibung: Funk Wetterstation Auriol IAN 283582 (Lidl) @@ -909,7 +955,7 @@ sub SD_WS_Parse { # r?ss cccc # r: 1 bit device reset, 0 after inserting battery or pressing reset, 1 after 1 hour (checked with Fody E42) # s: 2 bit sensor type, 00 = Bresser_5in1, 01 = Fody_E42, 11 = Bresser_rain_gauge - # c: 4 bit channel, 0000 = Bresser_5in1, 0001/0010/0011 = Fody_E42 (changes after reset), 1001 = Bresser_rain_gauge + # c: 4 bit channel, 0000 = Bresser_5in1, 0001/0010/0011 = Fody_E42 (changes after reset), 1001, 1010 or 1011 = Bresser_rain_gauge # G = wind gust in 1/10 m/s, normal binary coded, GGxG = 0x76D1 => 0x0176 = 256 + 118 = 374 => 37.4 m/s. MSB is out of sequence. # D = wind direction 0..F = N..NNE..E..S..W..NNW # W = wind speed in 1/10 m/s, BCD coded, WWxW = 0x7512 => 0x0275 = 275 => 27.5 m/s. MSB is out of sequence. @@ -933,7 +979,7 @@ sub SD_WS_Parse { modelStat => sub {my (undef,$bitData) = @_; my $typ = substr($bitData,10,2); if ($typ eq '00') { - $typ = 'Bresser 5in1, Fody E43 outdoor sensor'; + $typ = 'Bresser 5-in-1, Fody E43 outdoor sensor'; } elsif ($typ eq '01') { $typ = 'Fody E42 thermo-/hygro sensor'; } elsif ($typ eq '11') { @@ -1438,7 +1484,7 @@ sub SD_WS_Parse { temp => sub {my (undef,$bitData) = @_; return if (substr($bitData,19,1) eq '1'); return SD_WS_binaryToNumber($bitData,21,30) * 0.1 - 40; - }, + }, hum => sub {my (undef,$bitData) = @_; return if (substr($bitData,19,1) eq '1'); return SD_WS_binaryToNumber($bitData,31,38); @@ -1487,7 +1533,7 @@ sub SD_WS_Parse { return 0; } return 1; - } + } }, 122 => { # TM40, Wireless Grill-, Meat-, Roasting-Thermometer with 4 Temperature Sensors @@ -1527,7 +1573,7 @@ sub SD_WS_Parse { }, bat => sub { my (undef,$bitData) = @_; return substr($bitData,88,1) eq "0" ? "ok" : "low"; }, transmitter => sub { my (undef,$bitData) = @_; return substr($bitData,92,1) eq "0" ? "on" : "off"; }, - crcok => sub {return 1;}, # Check could not be determined yet. + crcok => sub {return 1;}, # Check could not be determined yet. }, 123 => { # Inkbird IBS-P01R Pool Thermometer, Inkbird ITH-20R (not tested) @@ -1598,14 +1644,14 @@ sub SD_WS_Parse { model => 'SD_WS_125_TH', prematch => sub {my ($rawData,undef) = @_; return 1 if ($rawData =~ /^(30|37)/); }, id => sub {my ($rawData,undef) = @_; return (substr($rawData,2,2));}, - channel => sub {my (undef,$bitData) = @_; return (SD_WS_binaryToNumber($bitData,17,19) + 1);}, - bat => sub {my (undef,$bitData) = @_; return substr($bitData,20,1) eq '0' ? 'ok' : 'low';}, + channel => sub {my (undef,$bitData) = @_; return (SD_WS_binaryToNumber($bitData,17,19) + 1);}, + bat => sub {my (undef,$bitData) = @_; return substr($bitData,20,1) eq '0' ? 'ok' : 'low';}, temp => sub {my (undef,$bitData) = @_; - my $temp = SD_WS_binaryToNumber($bitData,22,31); + my $temp = SD_WS_binaryToNumber($bitData,22,31); return FHEM::Core::Utils::Math::round(($temp - 400) / 10, 1); - }, - hum => sub { my ($rawData,undef) = @_; return hex(substr($rawData,8,2)); }, - crcok => sub { my ($rawData,undef) = @_; + }, + hum => sub {my ($rawData,undef) = @_; return hex(substr($rawData,8,2)); }, + crcok => sub {my ($rawData,undef) = @_; if (HAS_DigestCRC) { my $calc_crc8 = Digest::CRC->new(width => 8, poly=>0x31); my $crc_digest = $calc_crc8->add( pack 'H*', substr( $rawData, 0, 12 ) )->digest; @@ -1658,7 +1704,7 @@ sub SD_WS_Parse { batVoltage => sub { my (undef,$bitData) = @_; my $v = oct(q[0b].substr($bitData,35,5)); return $v ne '0' ? $v / 10 : undef; }, - crcok => sub { my ($rawData,undef) = @_; + crcok => sub { my ($rawData,undef) = @_; if (HAS_DigestCRC) { my $calc_crc8 = Digest::CRC->new(width => 8, poly=>0x31); my $crc_digest = $calc_crc8->add( pack 'H*', substr( $rawData, 0, 16 ) )->digest; @@ -1752,7 +1798,7 @@ sub SD_WS_Parse { # CCCCIIIIcccB?FDD???? # C = LFSR-16 digest, generator 0x8810, key 0xABF9, final xor 0x899E # I = station ID - # c = 3 nibbles lightning count, BCD + # c = 3 nibbles lightning count, 1 digit hex, 2 digit BCD # B = flags, 4 bit # Bit: 0123 # 1000 @@ -1779,9 +1825,9 @@ sub SD_WS_Parse { } return $typ; }, - prematch => sub {my $rawData = shift; return 1 if ($rawData =~ /^[0-9A-F]{8}[0-9]{3}[0-9A-F]{3}[0-9]{2}/); }, + prematch => sub {my $rawData = shift; return 1 if ($rawData =~ /^[0-9A-F]{9}[0-9]{2}[0-9A-F]{3}[0-9]{2}/); }, id => sub {my ($rawData,undef) = @_; return substr($rawData,4,4); }, - count => sub { my ($rawData,undef) = @_; return substr($rawData,8,3) * 1; }, + count => sub { my ($rawData,$bitData) = @_; return SD_WS_binaryToNumber($bitData,32,35) * 100 + substr($rawData,9,2) * 1; }, bat => sub {my (undef,$bitData) = @_; return substr($bitData,44,1) eq '0' ? 'low' : 'ok';}, batChange => sub {my (undef,$bitData) = @_; return substr($bitData,52,1) eq '0' ? '1' : '0';}, distance => sub { my ($rawData,undef) = @_; return substr($rawData,14,2) * 1; }, @@ -2507,7 +2553,7 @@ sub SD_WS_WH2SHIFT {
  • WH2, WH2A (TFA Dostmann/Wertheim 30.3157 (sold in Germany), Agimex Rosenborg 66796 (sold in Denmark),ClimeMET CM9088 (Sold in UK)
  • Weatherstation Auriol IAN 283582 Version 06/2017 (Lidl), Modell-Nr.: HG02832D
  • Weatherstation Auriol AHFL 433 B2, IAN 314695 (Lidl)
  • -
  • Weatherstations and sensors TFA 30.3151, 30.3152, 30.3153, 30.3157, 30.3200, 30.3208.02, 30.3221.02, 30.3222.02, 30.3228.02, 30.3229.02, 30.3233.01, 30.3251.10, 35.1077.54.S2, 35.1140.01
  • +
  • Weatherstations and sensors TFA 30.3151, 30.3152, 30.3153, 30.3157, 30.3200, 30.3208.02, 30.3212, 30.3221.02, 30.3222.02, 30.3228.02, 30.3229.02, 30.3233.01, 30.3251.10, 35.1077.54.S2, 35.1140.01
  • Wireless Grill Thermometer, Model name: GFGT 433 B1


  • @@ -2655,7 +2701,7 @@ sub SD_WS_WH2SHIFT {
  • WH2, WH2A (TFA Dostmann/Wertheim 30.3157 (Deutschland), Agimex Rosenborg 66796 (Denmark), ClimeMET CM9088 (UK)
  • Wetterstation Auriol IAN 283582 Version 06/2017 (Lidl), Modell-Nr.: HG02832D
  • Wetterstation Auriol AHFL 433 B2, IAN 314695 (Lidl)
  • -
  • Wetterstationen und Sensoren TFA 30.3151, 30.3152, 30.3153, 30.3157, 30.3200, 30.3208.02, 30.3221.02, 30.3222.02, 30.3228.02, 30.3229.02, 30.3233.01, 30.3251.10, 35.1077.54.S2, 35.1140.01
  • +
  • Wetterstationen und Sensoren TFA 30.3151, 30.3152, 30.3153, 30.3157, 30.3200, 30.3208.02, 30.3212, 30.3221.02, 30.3222.02, 30.3228.02, 30.3229.02, 30.3233.01, 30.3251.10, 35.1077.54.S2, 35.1140.01


  • @@ -2783,7 +2829,7 @@ sub SD_WS_WH2SHIFT { "x_fhem_maintainer_github": [ "Sidey79" ], - "version": "v1.1.2", + "version": "v1.1.4", "description": "The SD_WS module processes the messages from various environmental sensors received from an IO device (CUL, CUN, SIGNALDuino, SignalESP etc.)", "dynamic_config": 1, "keywords": [ diff --git a/FHEM/lib/SD_ProtocolData.pm b/FHEM/lib/SD_ProtocolData.pm index 11f9a4e62..d6327103d 100644 --- a/FHEM/lib/SD_ProtocolData.pm +++ b/FHEM/lib/SD_ProtocolData.pm @@ -1,4 +1,4 @@ -# $Id: SD_ProtocolData.pm 26975 2024-04-24 06:21:19Z HomeAutoUser $ +# $Id: SD_ProtocolData.pm 26975 2024-09-08 15:09:34Z elektron-bbs $ # The file is part of the SIGNALduino project. # All protocol definitions are contained in this file. # @@ -85,7 +85,7 @@ package lib::SD_ProtocolData; use strict; use warnings; - our $VERSION = '1.56'; + our $VERSION = '1.57'; 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; @@ -725,9 +725,17 @@ package lib::SD_ProtocolData; # DC_1961_TG_1846 light_on_off MS;P1=291;P2=-753;P3=762;P4=-249;P5=-8312;D=151212123434121212123412121234341234123412341212121234341212341234;CP=1;SP=5;R=224;O;m2; # DC_1961_TG_1846 fan_off MS;P1=-760;P2=747;P3=-282;P4=253;P5=-8335;D=454141412323414141412341414123234123412341412323234123232323412323;CP=4;SP=5;R=27;O;m2; # DC_1961_TG_1846 fan_direction MS;P0=-8384;P1=255;P2=-766;P3=754;P4=-263;D=101212123434121212123412121234341234123412341212341234341212341212;CP=1;SP=0;R=27;O;m2; + ## Remote control with 9 buttons for ceiling fan with lighting (Controller MP 2.5+3UF) + # https://forum.fhem.de/index.php?topic=138538.0 @ Butsch 2024-06-17 + # RCnoName20_09_024F fan_low MS;P0=249;P1=-744;P3=770;P4=-228;P5=-8026;D=050101010101013401013401013434343401010101010134010101010101010134;CP=0;SP=5;R=35;O;m2; + # RCnoName20_09_024F fan_stop MS;P0=-7940;P1=246;P2=-757;P3=736;P4=-247;D=101212121212123412123412123434343412121212123434121212343412343412;CP=1;SP=0;R=47;O;m2; + ## Remote control CREATE 6601L with 14 buttons for ceiling fan with lighting + # https://forum.fhem.de/index.php?topic=53282.msg1316246#msg1316246 @ Kent 2024-07-04 + # CREATE_6601L_1B90 fan_2 MS;P0=-7944;P1=-740;P4=253;P6=732;P7=-256;D=404141416767416767674141674141414141414141674141414141674141416767;CP=4;SP=0;R=67;O;m2; + # CREATE_6601L_1B90 fan_5 MS;P0=-264;P2=-743;P3=254;P4=733;P5=-7942;D=353232324040324040403232403232323232323232324032324032323232403240;CP=3;SP=5;R=40;O;m2; { name => 'RCnoName20', - comment => 'Remote control with 4, 10 or 12 buttons', + comment => 'Remote control with 4, 9, 10, 12 or 14 buttons', id => '20', knownFreqs => '433.92', one => [3,-1], # 720,-240 @@ -748,7 +756,7 @@ package lib::SD_ProtocolData; # RCnoName20_10_3E00 fan_stop MU;P0=184;P1=-380;P2=128;P3=-9090;P4=-768;P5=828;P6=-238;P7=298;D=45656565656747474747474747474747474567474560404515124040451040374745656565656747474747474747474747474567474567474565674747456747374745656565656747474747474747474747474567474567474565674747456747374745656565656747474747474747474747474567474567474565674747;CP=7;O; { name => 'RCnoName20', - comment => 'Remote control with 4, 10 or 12 buttons', + comment => 'Remote control with 4, 9, 10, 12 or 14 buttons', id => '20.1', knownFreqs => '433.92', one => [3,-1], # 720,-240 @@ -1300,7 +1308,7 @@ package lib::SD_ProtocolData; { name => 'Somfy RTS', id => '43', - knownFreqs => '', + knownFreqs => '433.42', clockrange => [610,680], # min , max format => 'manchester', preamble => 'Ys', @@ -1412,25 +1420,25 @@ package lib::SD_ProtocolData; 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 ! + "48" => ## TFA Temperature transmitter 30.3212 for Wireless thermometer JOKER 30.3055 # 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; + # SD_WS_48_T T: 24.3 W48#FF49C0F3FFD9 MU;P0=591;P1=-1488;P2=-3736;P3=1338;P4=-372;P6=-988;D=23406060606063606363606363606060636363636363606060606363606060606060606060606060636060636360106060606060606063606363606363606060636363636363606060606363606060606060606060606060636060636360106060606060606063606363606363606060636363636363606060606363606060;CP=0;O; + # SD_WS_48_T T: 16.3 W48#FF4D40A3FFE5 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', + name => 'TFA JOKER', + comment => 'Temperature transmitter TFA 30.3212', 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], + clockabs => 250, + one => [2,-4], # 500,-1000 + zero => [6,-4], # 1500,-1000 + start => [-6], # -1500 + reconstructBit => '1', format => 'twostate', - preamble => 'U48#', - #clientmodule => '', - modulematch => '^U48#.*', - length_min => '47', + preamble => 'W48#', + clientmodule => 'SD_WS', + modulematch => '^W48#.*', + length_min => '47', # lenght without reconstructBit length_max => '48', }, "49" => ## QUIGG GT-9000, EASY HOME RCT DS1 CR-A, uniTEC 48110 and other @@ -3320,7 +3328,7 @@ package lib::SD_ProtocolData; datarate => '17.257', sync => '2DD4', modulation => '2-FSK', - regexMatch => qr/^(30|37)/, + regexMatch => qr/^(30|37)/, preamble => 'W125#', register => ['0001','022E','0343','042D','05D4','060b','0780','0800','0D21','0E65','0FE8','10A9','115C','1202','1322','14F8','1543','1916','1B43','1C68'], rfmode => 'Fine_Offset_WH31_868', @@ -3357,8 +3365,8 @@ package lib::SD_ProtocolData; comment => 'Remote control with 14 buttons for ceiling fan', id => '127', knownFreqs => '433.92', - one => [1,-3], # 370,-1110 - zero => [3,-1], # 1110, -370 + one => [1,-3], # 370,-1110 + zero => [3,-1], # 1110, -370 start => [-15], # -5550 (MU) reconstructBit => '1', clockabs => '370', diff --git a/README.md b/README.md index 3151bda86..7f967682a 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ Supported Devices / Protocols |CAME TOP 432EV | Remote control | |CTW600, WH1080, WH2315 | Weather station | |Clarus | remote power socket| +|CREATE 6601L, 6601TL | Remote control for ceiling fan with lighting | |Conrad RSL | shutters | |DC-1961-TG | Remote control with 12 buttons for ceiling fan with lighting | |Dooya | Shutters and blinds from various vendors like Rohrmotor24 | @@ -103,7 +104,7 @@ Supported Devices / Protocols |Technoline TX3 | Weather sensor | |Tedsen SKX1xx, SKX2xx, SKX4xx, SKX6xx | Remote control | |Temola TM40 | Wireless grill, meat, roast thermometer with 4 temperature sensors | -|TFA 30.3151, 30.3152, 30.3153, 30.3157, 30.3200, 30.3208.02, 30.3209.02, 30.3221.02, 30.3222.02, 30.3228.02, 30.3229.02, 30.3233.01, 30.3251.10, 35.1077.54.S2, 35.1140.01 | Weather sensors and stations | +|TFA 30.3151, 30.3152, 30.3153, 30.3157, 30.3200, 30.3208.02, 30.3209.02, 30.3212, 30.3221.02, 30.3222.02, 30.3228.02, 30.3229.02, 30.3233.01, 30.3251.10, 35.1077.54.S2, 35.1140.01 | Weather sensors and stations | |TR401 | Remote control | |TR60C-1 | Remote control with touch screen | |TS-FT002 | Water tank level monitor with temperature | diff --git a/controls_signalduino.txt b/controls_signalduino.txt index f12c5d5d2..eabbdd33b 100644 --- a/controls_signalduino.txt +++ b/controls_signalduino.txt @@ -1,4 +1,4 @@ -UPD 2024-04-25_06:24:54 241827 FHEM/00_SIGNALduino.pm +UPD 2024-09-08_18:52:14 241877 FHEM/00_SIGNALduino.pm UPD 2023-01-06_12:08:43 20082 FHEM/10_FS10.pm UPD 2024-01-03_23:05:39 27250 FHEM/10_SD_GT.pm UPD 2023-01-01_18:10:40 25403 FHEM/10_SD_Rojaflex.pm @@ -7,12 +7,12 @@ UPD 2023-01-01_18:10:40 16260 FHEM/14_FLAMINGO.pm UPD 2023-10-14_22:18:35 24045 FHEM/14_Hideki.pm UPD 2024-03-11_20:44:57 13353 FHEM/14_SD_AS.pm UPD 2023-01-01_18:10:40 29419 FHEM/14_SD_BELL.pm -UPD 2024-01-02_23:01:30 198578 FHEM/14_SD_UT.pm -UPD 2024-03-11_20:44:57 166468 FHEM/14_SD_WS.pm +UPD 2024-09-08_14:07:18 204993 FHEM/14_SD_UT.pm +UPD 2024-09-08_18:21:59 169490 FHEM/14_SD_WS.pm UPD 2023-01-09_19:54:48 21030 FHEM/14_SD_WS07.pm UPD 2023-01-23_21:06:26 38569 FHEM/14_SD_WS09.pm UPD 2023-01-09_19:54:48 16458 FHEM/14_SD_WS_Maverick.pm UPD 2023-01-28_20:08:00 40378 FHEM/41_OREGON.pm UPD 2020-12-17_23:16:30 15582 FHEM/90_SIGNALduino_un.pm -UPD 2024-04-25_06:24:54 253287 FHEM/lib/SD_ProtocolData.pm +UPD 2024-09-08_18:21:59 254416 FHEM/lib/SD_ProtocolData.pm UPD 2024-01-06_20:21:35 81862 FHEM/lib/SD_Protocols.pm diff --git a/t/FHEM/00_SIGNALduino/01_SIGNALduino_Attr.t b/t/FHEM/00_SIGNALduino/01_SIGNALduino_Attr.t index b36529210..7ffa5d695 100644 --- a/t/FHEM/00_SIGNALduino/01_SIGNALduino_Attr.t +++ b/t/FHEM/00_SIGNALduino/01_SIGNALduino_Attr.t @@ -30,6 +30,38 @@ my @mockData = ( }, rValue => match qr/only available for a receiver with CC1101/, }, + { + cmd => q[set], + deviceName => q[dummyDuino], + plan => 2, + testname => q[set default client attribute], + input => q[Clients], + attrCheck => hash { + field Clients => U(); + etc(); + }, + hashCheck => hash { + field Clients => match qr/:CUL_EM:/; + etc(); + }, + rValue => match qr/Setting defaults/, + }, + { + cmd => q[set], + deviceName => q[dummyDuino], + plan => 3, + testname => q[set custom client attribute], + input => q[Clients SD_WS:SD_UT], + attrCheck => hash { + field Clients => 'SD_WS:SD_UT'; + etc(); + }, + hashCheck => hash { + field Clients => 'SD_WS:SD_UT'; + etc(); + }, + rValue => U(), + }, { # todoReason => "reason", cmd => q[set], diff --git a/t/FHEM/00_SIGNALduino/02_SIGNALduino_IdList.t b/t/FHEM/00_SIGNALduino/02_SIGNALduino_IdList.t index 8a092f18b..4b78c425e 100644 --- a/t/FHEM/00_SIGNALduino/02_SIGNALduino_IdList.t +++ b/t/FHEM/00_SIGNALduino/02_SIGNALduino_IdList.t @@ -13,7 +13,7 @@ sub runTest { my $target = shift; my $targetHash = $defs{$target}; - plan(11); + plan(13); subtest 'check if sub SIGNALduino_IdList causes crash if name does not exists' => sub { is( @@ -112,6 +112,24 @@ sub runTest { #print 'last char is '.substr($targetHash->{Clients}, -1); }; + subtest 'check with attribute Clients and without attr whitelist_IDs' => sub { + plan(1); + CommandDeleteAttr(undef, qq[$target whitelist_IDs]); + CommandAttr(undef, qq[$target Clients CUL_EM:MY_MODULE:SIGNALduino_un:]); + SIGNALduino_IdList("sduino_IdList:$target"); + is($targetHash->{Clients},'CUL_EM:MY_MODULE:SIGNALduino_un','Clients from Attribute are used'); + }; + + subtest 'check with attribute Clients and with attr whitelist_IDs' => sub { + plan(4); + CommandAttr(undef, qq[$target whitelist_IDs 54,47]); + CommandAttr(undef, qq[$target Clients CUL_EM:MY_MODULE:SIGNALduino_un:]); + SIGNALduino_IdList("sduino_IdList:$target"); + unlike($targetHash->{Clients},qr/CUL_EM/,'Clients from Attribute are not used'); + unlike($targetHash->{Clients},qr/MY_MODULE/,'Clients from Attribute are not used'); + unlike($targetHash->{Clients},qr/SIGNALduino_un/,'Clients from Attribute are not used'); + like($targetHash->{Clients},qr/SD_WS_Maverick:SD_WS|SD_WS:SD_WS_Maverick/,'Clients from whitelist are used'); + }; } diff --git a/t/FHEM/14_SD_UT/03_set.t b/t/FHEM/14_SD_UT/03_set.t index 1ae84f134..797e1055b 100644 --- a/t/FHEM/14_SD_UT/03_set.t +++ b/t/FHEM/14_SD_UT/03_set.t @@ -81,6 +81,43 @@ my $module = basename (dirname(__FILE__)); returnCheck => q[SD_UT_Test_RCnoName20_10 Unkown set command!], subCheck => hash { end(); } , }, + { + targetName => q[SD_UT_Test_CREATE_6601L_1B900], + testname => q[set ? ], + cmd => q[set ?], + + returnCheck => check_set( !match qr/hex_length/, match qr/fan_4:noArg/, match qr/time_4h:noArg/, match qr/light_color:noArg/, match qr/fan_1:noArg/, match qr/time_1h:noArg/, match qr/light_on_off:noArg/, match qr/time_2h:noArg/, match qr/fan_on_off:noArg/, match qr/fan_6:noArg/, match qr/fan_2:noArg/, match qr/fan_direction:noArg/, match qr/fan_3:noArg/, match qr/fan_5:noArg/, match qr/beeper_on_off:noArg/ ), + subCheck => hash { end(); } , + prep_commands => [ # Any FHEM custom command can be placed in here, which will be called before the test is run + 'attr $targetName model CREATE_6601L', + ], + }, + { + targetName => q[SD_UT_Test_CREATE_6601L_1B900], + testname => q[set command beeper_on_off rollingCode 0-7], + cmd => q[set beeper_on_off], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P20#00011011100100000000010001001001#R5' }; etc() } } } , + prep_commands => [ # Any FHEM custom command can be placed in here, which will be called before the test is run + 'setreading $targetName rollingCode 3', + 'attr $targetName model CREATE_6601L', + ], + hashCheck => hash { field READINGS => hash {field rollingCode => hash { field VAL => 4; etc(); }; etc(); }; etc(); }, + }, + { + targetName => q[SD_UT_Test_CREATE_6601L_1B900], + testname => q[set command fan_5 rollingCode 8-15], + cmd => q[set fan_5], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P20#00011011100100000000010011010000#R5' }; etc() } } } , + prep_commands => [ # Any FHEM custom command can be placed in here, which will be called before the test is run + 'setreading $targetName rollingCode 4', + 'attr $targetName model CREATE_6601L', + ], + hashCheck => hash { field READINGS => hash {field rollingCode => hash { field VAL => 13; etc(); }; etc(); }; etc(); }, + }, { targetName => q[SD_UT_Test_OR28V_1], testname => q[set command volume_minus], diff --git a/t/FHEM/14_SD_UT/fhem.cfg b/t/FHEM/14_SD_UT/fhem.cfg index b4b36359e..cb2bbfc92 100644 --- a/t/FHEM/14_SD_UT/fhem.cfg +++ b/t/FHEM/14_SD_UT/fhem.cfg @@ -8,6 +8,7 @@ define SD_UT_Test_Buttons_five_E SD_UT Buttons_five E define SD_UT_Test_Buttons_six SD_UT Buttons_six E define SD_UT_Test_CAME_TOP_432EV_EE SD_UT CAME_TOP_432EV EE define SD_UT_Test_Chilitec_22640_AA80 SD_UT Chilitec_22640 AA80 +define SD_UT_Test_CREATE_6601L_1B900 SD_UT CREATE_6601L 1B900 define SD_UT_Test_DC_1961_TG_1846 SD_UT DC_1961_TG 1846 define SD_UT_Test_HA_HX2_85EF SD_UT HA_HX2 85EF define SD_UT_Test_HS1_868_BS_F62A9C01C SD_UT HS1_868_BS F62A9C01C diff --git a/t/FHEM/14_SD_UT/testData.json b/t/FHEM/14_SD_UT/testData.json index a99a4d7df..b1b43df77 100644 --- a/t/FHEM/14_SD_UT/testData.json +++ b/t/FHEM/14_SD_UT/testData.json @@ -2607,5 +2607,157 @@ "id" : 132, "module" : "SD_UT", "name" : "HA_HX2_01EF" + }, + { + "data" : [ + { + "comment" : "Remote control with 9 buttons for ceiling fan with lighting (Controller MP 2.5+3UF)", + "dmsg" : "P20#024F0201", + "internals" : { + "DEF" : "RCnoName20_09 024F", + "NAME" : "RCnoName20_09_024F" + }, + "readings" : { + "LastAction" : "receive", + "deviceCode" : "024F", + "rollingCode" : "0", + "state" : "fan_low" + }, + "rmsg" : "MS;P0=249;P1=-744;P3=770;P4=-228;P5=-8026;D=050101010101013401013401013434343401010101010134010101010101010134;CP=0;SP=5;R=35;O;m2;", + "tests" : [ + { + "attributes" : { + "model" : "RCnoName20_09" + }, + "comment" : "#0" + } + ] + }, + { + "comment" : "Remote control with 9 buttons for ceiling fan with lighting (Controller MP 2.5+3UF)", + "dmsg" : "P20#024F0636", + "internals" : { + "DEF" : "RCnoName20_09 024F", + "NAME" : "RCnoName20_09_024F" + }, + "readings" : { + "LastAction" : "receive", + "deviceCode" : "024F", + "rollingCode" : "3", + "state" : "fan_stop" + }, + "rmsg" : "MS;P0=-7940;P1=246;P2=-757;P3=736;P4=-247;D=101212121212123412123412123434343412121212123434121212343412343412;CP=1;SP=0;R=47;O;m2;", + "tests" : [ + { + "attributes" : { + "model" : "RCnoName20_09" + }, + "comment" : "#1" + } + ] + } + ], + "id" : "20", + "module" : "SD_UT", + "name" : "RCnoName20_09_024F" + }, + { + "data" : [ + { + "comment" : "Remote control CREATE 6601L with 14 buttons for ceiling fan with lighting", + "dmsg" : "P20#1B900823", + "internals" : { + "DEF" : "CREATE_6601L 1B900", + "NAME" : "CREATE_6601L_1B900" + }, + "readings" : { + "LastAction" : "receive", + "deviceCode" : "1B900", + "rollingCode" : "2", + "state" : "fan_2" + }, + "rmsg" : "MS;P0=-7944;P1=-740;P4=253;P6=732;P7=-256;D=404141416767416767674141674141414141414141674141414141674141416767;CP=4;SP=0;R=67;O;m2;", + "tests" : [ + { + "attributes" : { + "model" : "CREATE_6601L" + }, + "comment" : "#0" + } + ] + }, + { + "comment" : "Remote control CREATE 6601L with 14 buttons for ceiling fan with lighting", + "dmsg" : "P20#1B900485", + "internals" : { + "DEF" : "CREATE_6601L 1B900", + "NAME" : "CREATE_6601L_1B900" + }, + "readings" : { + "LastAction" : "receive", + "deviceCode" : "1B900", + "rollingCode" : "8", + "state" : "fan_5" + }, + "rmsg" : "MS;P0=-264;P2=-743;P3=254;P4=733;P5=-7942;D=353232324040324040403232403232323232323232324032324032323232403240;CP=3;SP=5;R=40;O;m2;", + "tests" : [ + { + "attributes" : { + "model" : "CREATE_6601L" + }, + "comment" : "#1" + } + ] + }, + { + "comment" : "Remote control CREATE 6601L with 14 buttons for ceiling fan with lighting", + "dmsg" : "P20#1B9008BA", + "internals" : { + "DEF" : "CREATE_6601L 1B900", + "NAME" : "CREATE_6601L_1B900" + }, + "readings" : { + "LastAction" : "receive", + "deviceCode" : "1B900", + "rollingCode" : "11", + "state" : "fan_direction" + }, + "rmsg" : "MS;P1=247;P2=-732;P4=745;P5=-256;P7=-7933;D=171212124545124545451212451212121212121212451212124512454545124512;CP=1;SP=7;R=48;O;m2;", + "tests" : [ + { + "attributes" : { + "model" : "CREATE_6601L" + }, + "comment" : "#2" + } + ] + }, + { + "comment" : "Remote control CREATE 6601L with 14 buttons for ceiling fan with lighting", + "dmsg" : "P20#1B90047A", + "internals" : { + "DEF" : "CREATE_6601L 1B900", + "NAME" : "CREATE_6601L_1B900" + }, + "readings" : { + "LastAction" : "receive", + "deviceCode" : "1B900", + "rollingCode" : "7", + "state" : "beeper_on_off" + }, + "rmsg" : "MS;P2=247;P3=-744;P4=731;P5=-273;P6=-7911;D=262323234545234545452323452323232323232323234523232345454545234523;CP=2;SP=6;R=43;O;m2;", + "tests" : [ + { + "attributes" : { + "model" : "CREATE_6601L" + }, + "comment" : "#3" + } + ] + } + ], + "id" : "20", + "module" : "SD_UT", + "name" : "CREATE_6601L_1B900" } ] diff --git a/t/FHEM/14_SD_WS/testData.json b/t/FHEM/14_SD_WS/testData.json index 8aedb5da9..d238c7204 100644 --- a/t/FHEM/14_SD_WS/testData.json +++ b/t/FHEM/14_SD_WS/testData.json @@ -2599,5 +2599,50 @@ "id" : 131, "module" : "SD_WS", "name" : "Bresser lightning" + }, + { + "data" : [ + { + "comment" : "Temperature transmitter TFA 30.3212", + "dmsg" : "W48#FF49C0F3FFD9", + "internals" : { + "DEF" : "SD_WS_48_T", + "NAME" : "SD_WS_48_T" + }, + "readings" : { + "state" : "T: 24.3", + "temperature" : "24.3", + "type" : "Temperature transmitter" + }, + "rmsg" : "MU;P0=591;P1=-1488;P2=-3736;P3=1338;P4=-372;P6=-988;D=23406060606063606363606363606060636363636363606060606363606060606060606060606060636060636360106060606060606063606363606363606060636363636363606060606363606060606060606060606060636060636360106060606060606063606363606363606060636363636363606060606363606060;CP=0;O;", + "tests" : [ + { + "comment" : "#0" + } + ] + }, + { + "comment" : "Temperature transmitter TFA 30.3212", + "dmsg" : "W48#FF4D40A3FFE5", + "internals" : { + "DEF" : "SD_WS_48_T", + "NAME" : "SD_WS_48_T" + }, + "readings" : { + "state" : "T: 16.3", + "temperature" : "16.3", + "type" : "Temperature transmitter" + }, + "rmsg" : "MU;P0=96;P1=-244;P2=510;P3=-1000;P4=1520;P5=-1506;D=01232323232343234343232343234323434343434343234323434343232323232323232323232323234343234325232323232323232343234343232343234323434343434343234323434343232323232323232323232323234343234325232323232323232343234343232343234323434343434343234323434343232323;CP=2;O;", + "tests" : [ + { + "comment" : "#1" + } + ] + } + ], + "id" : "48", + "module" : "SD_WS", + "name" : "Temperature transmitter TFA 30.3212" } ]