From 267833e010804420bbec1058cf0ec975b38b9587 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Jun 2023 22:07:51 +0200 Subject: [PATCH 01/55] Bump shogo82148/actions-setup-perl from 1.21.2 to 1.21.3 (#1179) --- updated-dependencies: - dependency-name: shogo82148/actions-setup-perl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/perlCritic.yml | 2 +- .github/workflows/prove.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/perlCritic.yml b/.github/workflows/perlCritic.yml index aee7a6d04..c0a018d59 100644 --- a/.github/workflows/perlCritic.yml +++ b/.github/workflows/perlCritic.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - - uses: shogo82148/actions-setup-perl@v1.21.2 + - uses: shogo82148/actions-setup-perl@v1.21.3 with: perl-version: 5.32 install-modules-with: cpanm diff --git a/.github/workflows/prove.yml b/.github/workflows/prove.yml index 2c76028e6..1211f9e57 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@v3 - - uses: shogo82148/actions-setup-perl@v1.21.2 + - uses: shogo82148/actions-setup-perl@v1.21.3 with: perl-version: ${{ matrix.perl }} install-modules-with: cpanm From a5889eec7e3284ee3da21d6c0930e0f45e7f81d6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 5 Jul 2023 07:26:44 +0200 Subject: [PATCH 02/55] Bump shogo82148/actions-setup-perl from 1.21.3 to 1.22.0 (#1180) Bumps [shogo82148/actions-setup-perl](https://github.com/shogo82148/actions-setup-perl) from 1.21.3 to 1.22.0. - [Release notes](https://github.com/shogo82148/actions-setup-perl/releases) - [Commits](https://github.com/shogo82148/actions-setup-perl/compare/v1.21.3...v1.22.0) --- updated-dependencies: - dependency-name: shogo82148/actions-setup-perl dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/perlCritic.yml | 2 +- .github/workflows/prove.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/perlCritic.yml b/.github/workflows/perlCritic.yml index c0a018d59..ef7bd1aea 100644 --- a/.github/workflows/perlCritic.yml +++ b/.github/workflows/perlCritic.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - - uses: shogo82148/actions-setup-perl@v1.21.3 + - uses: shogo82148/actions-setup-perl@v1.22.0 with: perl-version: 5.32 install-modules-with: cpanm diff --git a/.github/workflows/prove.yml b/.github/workflows/prove.yml index 1211f9e57..dab18ab1a 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@v3 - - uses: shogo82148/actions-setup-perl@v1.21.3 + - uses: shogo82148/actions-setup-perl@v1.22.0 with: perl-version: ${{ matrix.perl }} install-modules-with: cpanm From a5c4362b7b749a56ea93049c4ec590c4a8b50af5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jul 2023 06:40:08 +0200 Subject: [PATCH 03/55] Bump shogo82148/actions-setup-perl from 1.22.0 to 1.23.0 (#1181) Bumps [shogo82148/actions-setup-perl](https://github.com/shogo82148/actions-setup-perl) from 1.22.0 to 1.23.0. - [Release notes](https://github.com/shogo82148/actions-setup-perl/releases) - [Commits](https://github.com/shogo82148/actions-setup-perl/compare/v1.22.0...v1.23.0) --- updated-dependencies: - dependency-name: shogo82148/actions-setup-perl dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/perlCritic.yml | 2 +- .github/workflows/prove.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/perlCritic.yml b/.github/workflows/perlCritic.yml index ef7bd1aea..7b826eb27 100644 --- a/.github/workflows/perlCritic.yml +++ b/.github/workflows/perlCritic.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - - uses: shogo82148/actions-setup-perl@v1.22.0 + - uses: shogo82148/actions-setup-perl@v1.23.0 with: perl-version: 5.32 install-modules-with: cpanm diff --git a/.github/workflows/prove.yml b/.github/workflows/prove.yml index dab18ab1a..f0e265c29 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@v3 - - uses: shogo82148/actions-setup-perl@v1.22.0 + - uses: shogo82148/actions-setup-perl@v1.23.0 with: perl-version: ${{ matrix.perl }} install-modules-with: cpanm From 2f4ce9ec687dea8f7628ea5f876b2135c0df9d0f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Aug 2023 07:29:13 +0200 Subject: [PATCH 04/55] Bump shogo82148/actions-setup-perl from 1.23.0 to 1.23.1 (#1182) Bumps [shogo82148/actions-setup-perl](https://github.com/shogo82148/actions-setup-perl) from 1.23.0 to 1.23.1. - [Release notes](https://github.com/shogo82148/actions-setup-perl/releases) - [Commits](https://github.com/shogo82148/actions-setup-perl/compare/v1.23.0...v1.23.1) --- updated-dependencies: - dependency-name: shogo82148/actions-setup-perl dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/perlCritic.yml | 2 +- .github/workflows/prove.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/perlCritic.yml b/.github/workflows/perlCritic.yml index 7b826eb27..ed23d2a43 100644 --- a/.github/workflows/perlCritic.yml +++ b/.github/workflows/perlCritic.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - - uses: shogo82148/actions-setup-perl@v1.23.0 + - uses: shogo82148/actions-setup-perl@v1.23.1 with: perl-version: 5.32 install-modules-with: cpanm diff --git a/.github/workflows/prove.yml b/.github/workflows/prove.yml index f0e265c29..c1456d7e4 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@v3 - - uses: shogo82148/actions-setup-perl@v1.23.0 + - uses: shogo82148/actions-setup-perl@v1.23.1 with: perl-version: ${{ matrix.perl }} install-modules-with: cpanm From 6ef467c4b13c11c633aef1b4a5a22467f6a0ffbe Mon Sep 17 00:00:00 2001 From: sidey79 <7968127+sidey79@users.noreply.github.com> Date: Tue, 15 Aug 2023 22:02:28 +0200 Subject: [PATCH 05/55] Support and for FREQEST register value (#1168) feat[cc1101]:Added support and for FREQEST value - feature needs firmware >=4.0.0 - commandref for AFC on/off extended - added tests --------- Co-authored-by: Udo Co-authored-by: GitHub Action --- FHEM/00_SIGNALduino.pm | 31 ++++++++++++++----- controls_signalduino.txt | 2 +- .../00_SIGNALduino/01_SIGNALduino_Parse_MN.t | 16 ++++++++++ .../02_SIGNALduino_Split_Message.t | 20 ++++++++++-- 4 files changed, 59 insertions(+), 10 deletions(-) diff --git a/FHEM/00_SIGNALduino.pm b/FHEM/00_SIGNALduino.pm index 88fe4c518..fd1898bf4 100644 --- a/FHEM/00_SIGNALduino.pm +++ b/FHEM/00_SIGNALduino.pm @@ -1,4 +1,4 @@ -# $Id: 00_SIGNALduino.pm 3.5.5 2023-05-16 16:34:07Z sidey79 $ +# $Id: 00_SIGNALduino.pm 3.5.6 2023-08-15 16:47:42Z sidey79 $ # v3.5.5 - 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 @@ -42,7 +42,7 @@ use List::Util qw(first); use constant { - SDUINO_VERSION => '3.5.5+20230516', # Datum wird automatisch bei jedem pull request aktualisiert + SDUINO_VERSION => '3.5.5+20230815', # 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, @@ -2144,7 +2144,7 @@ sub SIGNALduino_Split_Message { my $clockabs; my $mcbitnum; my $rssi; - + my $freqafc; ## for AFC cc1101 0x32 (0xF2): FREQEST – Frequency Offset Estimate from Demodulator my @msg_parts = SIGNALduino_splitMsg($rmsg,';'); ## Split message parts by ';' my %ret; my $debug = AttrVal($name,'debug',0); @@ -2204,6 +2204,10 @@ sub SIGNALduino_Split_Message { $rssi = $_ ; Debug "$name: extracted RSSI $rssi \n" if ($debug); $ret{rssi} = $rssi; + } elsif ($_ =~ m/A=(-?[0-9]{0,3})/ ){ + # uncoverable branch true + Debug qq[$name: extracted FREQEST $1 \n] if ($debug); + $ret{freqest} = $1; } else { Debug "$name: unknown Message part $_" if ($debug);; } @@ -2216,7 +2220,7 @@ sub SIGNALduino_Split_Message { ############################# package main, test exists # Function which dispatches a message if needed. sub SIGNALduno_Dispatch { - my ($hash, $rmsg, $dmsg, $rssi, $id) = @_; + my ($hash, $rmsg, $dmsg, $rssi, $id, $freqafc) = @_; my $name = $hash->{NAME}; if (!defined($dmsg)) @@ -2274,6 +2278,10 @@ sub SIGNALduno_Dispatch { else { $rssi = ''; } + if(defined($freqafc)) { # AFC cc1101 0x32 (0xF2): FREQEST – Frequency Offset Estimate from Demodulator + $addvals{FREQAFC} = $freqafc; + } + $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 @@ -2894,7 +2902,7 @@ sub SIGNALduino_Parse_MN { 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]+;)?$/){ + if ($rmsg !~ /^MN;D=[0-9A-F]+;(?:R=[0-9]+;)?(?:A=-?[0-9]{1,3};)?$/) { # AFC cc1101 0x32 (0xF2): FREQEST – Frequency Offset Estimate from Demodulator $hash->{logMethod}->($hash->{NAME}, 3, qq[$hash->{NAME}: Parse_MN, faulty msg: $rmsg]); return ; # Abort here if not successfull } @@ -2906,10 +2914,15 @@ sub SIGNALduino_Parse_MN { 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} ){ + my $freqafc; + if ( exists $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); }; + if ( exists $msg_parts{freqest} ){ #AFC cc1101 0x32 (0xF2): FREQEST – Frequency Offset Estimate from Demodulator + $freqafc = $msg_parts{freqest}; + $freqafc = FHEM::Core::Utils::Math::round((26000000 / 16384 * $freqafc / 1000),0); + } my $messagetype=$msg_parts{messagetype}; my $name = $hash->{NAME}; @@ -2953,7 +2966,7 @@ sub SIGNALduino_Parse_MN { } $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); + SIGNALduno_Dispatch($hash,$rmsg,$dmsg,$rssi,$id,$freqafc); $message_dispatched++; } @@ -4526,6 +4539,8 @@ USB-connected devices (SIGNALduino):

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!

    +
  • CEA -> Switching on the automatic frequency control for FSK modulation and firmware version >= V 4.0.0 (config: AFC=1)
  • +
  • CDA -> Switching off the automatic frequency control for FSK modulation and firmware version >= V 4.0.0 (config: AFC=0)
  • CER -> turn on data compression (config: Mred=1)
  • CDR -> disable data compression (config: Mred=0)

  • @@ -5122,6 +5137,8 @@ USB-connected devices (SIGNALduino):

    + LED_XM21_0 light string +
      +
    • on: button I on the remote
    • +
    • off: button O on the remote
    • +

    + Techmar Garden Lights (Remote control with 10 button)
    • Group_1 ... Group_9: Group 1 to 9, on / off
    • @@ -2755,7 +2789,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, 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_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
      @@ -2773,7 +2807,7 @@ sub SD_UT_tristate2bin { Generated readings of the models
        - AC114-01, Buttons_five, Buttons_six, CAME_TOP_432EV, Chilitec_22640, HSM4, KL_RF01, LED_XM21_0, Meikee_xx, Momento, Novy_840029, Novy_840039, OR28V, QUIGG_DMV, RC_10, RH787T, SF01_01319004, SF01_01319004_Typ2, TR401, TR_502MSV, Visivo + AC114-01, Buttons_five, Buttons_six, CAME_TOP_432EV, Chilitec_22640, HA_HX2, HSM4, KL_RF01, LED_XM21_0, Meikee_xx, Momento, Novy_840029, Novy_840039, OR28V, QUIGG_DMV, RC_10, RH787T, SF01_01319004, SF01_01319004_Typ2, TR401, TR_502MSV, Visivo
        • deviceCode: Device code of the system
        • LastAction: Last executed action of the device (receive for command received | send for command send).
        • @@ -2836,6 +2870,7 @@ sub SD_UT_tristate2bin {
        • 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)
        • +
        • Halemeier HA-HX2   (Modulmodel: HA-HX2, Protokoll 132)
        • Hoermann HS1-868-BS   (Modulmodel: HS1_868_BS, Protokoll 69)
        • Hoermann HSM4   (Modulmodel: HSM4, Protokoll 69)
        • Krinner LUMIX Christbaumkerzen   (Modulmodel: Krinner_LUMIX, Protokol 92)
        • @@ -2924,15 +2959,15 @@ sub SD_UT_tristate2bin {
        • night_mode: Taste MOND auf der Fernbedienung

        - LED_XM21_0 Christbaumkerzen + Fernbedienungen SA-434-1 mini 923301, Hoermann HS1-868-BS, Tedsen_SKX1xx
          -
        • on: Taste I auf der Fernbedienung
        • -
        • off: Taste O auf der Fernbedienung
        • +
        • send: Tastendruck (Sendet immer den gleichen Befehl, auch wenn der Benutzer einen anderen Set-Befehl via Konsole sendet.)

        - Fernbedienungen SA-434-1 mini 923301, Hoermann HS1-868-BS, Tedsen_SKX1xx + Halemeier HA_HX2
          -
        • send: Tastendruck (Sendet immer den gleichen Befehl, auch wenn der Benutzer einen anderen Set-Befehl via Konsole sendet.)
        • +
        • on: Taste ON auf der Fernbedienung
        • +
        • off: Taste OFF auf der Fernbedienung

        Hoermann HSM4 (Fernbedienung mit 4 Tasten) @@ -2943,6 +2978,12 @@ sub SD_UT_tristate2bin {
      • button_4: Taste 4 auf der Fernbedienung

      + LED_XM21_0 Christbaumkerzen +
        +
      • on: Taste I auf der Fernbedienung
      • +
      • off: Taste O auf der Fernbedienung
      • +

      + Techmar Garden Lights (Fernbedienung mit 10 Tasten)
      • Group_1 ... Group_9: Gruppe 1 bis 9, jeweils ein und aus
      • @@ -2985,7 +3026,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, 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).
        + 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).
        Bei Änderung des Attributes wird ein neues Gerät mittels autocreate erzeugt. Autocreate muss dazu aktiviert sein.
      • repeats
        @@ -3003,7 +3044,7 @@ sub SD_UT_tristate2bin { Generierte Readings der Modelle
          - AC114-01, BeSmart_S4, Buttons_five, Buttons_six, CAME_TOP_432EV, Chilitec_22640, HSM4, KL_RF01, LED_XM21_0, Meikee_xx, Momento, Novy_840029, Novy_840039, OR28V, QUIGG_DMV, RC_10, RH787T, SF01_01319004, SF01_01319004_Typ2, TR401, TR_502MSV, Visivo + AC114-01, BeSmart_S4, Buttons_five, Buttons_six, CAME_TOP_432EV, Chilitec_22640, HA_HX2, HSM4, KL_RF01, LED_XM21_0, Meikee_xx, Momento, Novy_840029, Novy_840039, OR28V, QUIGG_DMV, RC_10, RH787T, SF01_01319004, SF01_01319004_Typ2, TR401, TR_502MSV, Visivo
          • deviceCode: GeräteCode des Systemes
          • LastAction: Zuletzt ausgeführte Aktion des Gerätes (receive für Kommando empfangen, send für Kommando gesendet).
          • @@ -3075,6 +3116,7 @@ sub SD_UT_tristate2bin { } } }, + "version": "v1.0.2", "release_status": "stable", "resources": { "bugtracker": { diff --git a/FHEM/lib/SD_ProtocolData.pm b/FHEM/lib/SD_ProtocolData.pm index b206d2cc0..535e0e05d 100644 --- a/FHEM/lib/SD_ProtocolData.pm +++ b/FHEM/lib/SD_ProtocolData.pm @@ -85,7 +85,7 @@ package lib::SD_ProtocolData; use strict; use warnings; - our $VERSION = '1.54'; + our $VERSION = '1.55'; 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; @@ -3469,7 +3469,38 @@ package lib::SD_ProtocolData; length_min => '24', length_max => '24', }, - + #"131" => ## reserved for elektron-bbs + "132" => ## Remote control Halemeier HA-HX2 for Actor HA-RX-M2-1 + # https://github.com/RFD-FHEM/RFFHEM/issues/1207 @ HomeAuto_User 2023-12-11 + # https://forum.fhem.de/index.php?topic=38452.0 (probably identical) + # remote 1 - off | P132#85EFAC + # MU;P0=304;P1=-351;P2=633;P3=-692;P4=-12757;D=01230303030301230123030121240301212121230123030303012303030303012124030121212123012303030301230303030301230123030121240301212121230123030303012303030303012301230301212403012121212301230303030123030303030123012303012124030121212123012303030301230303030301;CP=0;R=241;O; + # MU;P0=-12609;P1=305;P2=-696;P3=-344;P4=653;D=01213434343421342121212134212121212134213421213434012134343434213421212121342121212121342134212134340121343434342134212121213421212121213421342121343401213434343421342121212134212121212134213421213434012134343434213421212121342121212121342134212134340121;CP=1;R=239;O; + # remote 1 - on | P132#85EFAA + # MU;P0=-696;P1=312;P2=-371;P3=637;P4=-12847;D=01012301230123012341012323232301230101010123010101010123012301230123410123232323012301010101230101010101230123012301234101232323230123010101012301010101012301230123012341012323232301230101010123010101010123012301230123410123232323012301010101230101010101;CP=1;R=236;O; + # MU;P0=-701;P1=304;P2=-366;P3=642;P4=-12781;D=01012301230123012341012323232301230101010123010101010123012301230123410123232323012301010101230101010101230123012301234101232323230123010101012301010101012301230123012341012323232301230101010123010101010123012301230123410123232323012301010101230101010101;CP=1;R=238;O; + # remote 2 - on | P132#01EFAA + # MU;P0=-340;P1=639;P2=-686;P3=304;P4=-12480;D=01230123014301010101010101232323232301230123012301430101010101010123232323012323232323012301230123014301010101010101232323230123232323230123012301230143010101010101012323232301232323232301230123012301430101010101010123232323012323232323012301230123014301;CP=3;R=226;O; + # MU;P0=-120;P1=642;P2=-343;P3=-684;P4=319;P5=-12492;D=01212121343434342134343434342134213421342154212121212121213434343421343434343421342134213421542121212121212134343434213434343434213421342134215421212121212121343434342134343434342134213421342154212121212121213434343421343434343421342134213421542121212121;CP=4;R=227;O; + # remote 2 - off | P132#01EFAC + # MU;P0=622;P1=-367;P2=-690;P3=323;P4=-12531;D=01010101010101023232323102323232323102310232310101010102323232310232323232310231023231010431010101010101023232323102323232323102310232310104310101010101010232323231023232323231023102323101043101010101010102323232310232323232310231023231010431010101010101;CP=3;R=235;O; + # MU;P0=307;P1=-685;P2=-350;P3=658;P4=-12510;D=01010102310101010102310231010232340232323232323231010101023101010101023102323232323232323101010102310101010102310231010232340232323232323231010101023101010101023102310102323402323232323232310101010231010101010231023101023234023232323232323101010102310101;CP=0;R=232;O; + { + name => 'HA-HX2', + comment => 'Remote control for Halemeier LED actor HA-RX-M2-1', + id => '132', + knownFreqs => '433.92', + one => [-2,1], + zero => [-1,2], + start => [-39,1], + clockabs => 330, + format => 'twostate', + preamble => 'P132#', + clientmodule => 'SD_UT', + modulematch => '^P132#.*', + length_min => '24', + length_max => '24', + }, ######################################################################## #### ### register informations from other hardware protocols #### #### diff --git a/README.md b/README.md index fc151939b..27919e8f2 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ Supported Devices / Protocols |Grothe Mistral SE 03.1| wireless gong | |GT-9000| Remote control based on protocol GT-9000 with encoding (EASY HOME RCT DS1, Tec Star)| |GT-TMBBQ-01| BBQ temperature sensor| +|Halemeier| Remote controls for LED controller | |Hama TS33C, Hama TS34A, Hama TS36E, Bresser Thermo/Hygro Sensor | Weather sensor | |Heidemann, Heidemann HX, VTX-BELL | wireless bell | |Hoermann HSM2, HSM4, HS1-868-BS | Remote control | diff --git a/controls_signalduino.txt b/controls_signalduino.txt index ceaf007e0..2526a9831 100644 --- a/controls_signalduino.txt +++ b/controls_signalduino.txt @@ -1,4 +1,4 @@ -UPD 2023-12-15_21:44:52 239453 FHEM/00_SIGNALduino.pm +UPD 2023-12-19_18:55:25 239457 FHEM/00_SIGNALduino.pm UPD 2023-01-06_12:08:43 20082 FHEM/10_FS10.pm UPD 2023-01-09_20:47:40 25008 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 2023-01-23_21:06:26 13260 FHEM/14_SD_AS.pm UPD 2023-01-01_18:10:40 29419 FHEM/14_SD_BELL.pm -UPD 2023-11-04_11:01:03 195492 FHEM/14_SD_UT.pm +UPD 2023-12-19_18:52:35 198590 FHEM/14_SD_UT.pm UPD 2023-09-18_21:06:46 156089 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 2023-11-04_11:01:03 247344 FHEM/lib/SD_ProtocolData.pm +UPD 2023-12-18_19:22:15 251034 FHEM/lib/SD_ProtocolData.pm UPD 2023-08-25_16:10:10 80775 FHEM/lib/SD_Protocols.pm diff --git a/t/FHEM/14_SD_UT/03_set.t b/t/FHEM/14_SD_UT/03_set.t index 1e885c09b..32ff32c9f 100644 --- a/t/FHEM/14_SD_UT/03_set.t +++ b/t/FHEM/14_SD_UT/03_set.t @@ -113,8 +113,16 @@ my $module = basename (dirname(__FILE__)); returnCheck => F(), subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P128#100010100111111111111110#R5' }; etc() } } } , }, + { + targetName => q[SD_UT_Test_HA_HX2_85EF], + testname => q[set command on], + cmd => q[set on], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P132#100001011110111110101010#R5' }; etc() } } } , + }, ); - + sub runTest { Test2::SIGNALduino::FHEM_Command::commandCheck($module); diff --git a/t/FHEM/14_SD_UT/fhem.cfg b/t/FHEM/14_SD_UT/fhem.cfg index bded6e98b..576e818dd 100644 --- a/t/FHEM/14_SD_UT/fhem.cfg +++ b/t/FHEM/14_SD_UT/fhem.cfg @@ -16,3 +16,6 @@ attr SD_UT_Test_RCnoName127_3603A model RCnoName127 define SD_UT_Test_RCnoName128_8A7F SD_UT RCnoName128 8A7F attr SD_UT_Test_RCnoName128_8A7F model RCnoName128 + +define SD_UT_Test_HA_HX2_85EF SD_UT HA_HX2 85EF +attr SD_UT_Test_HA_HX2_85EF model HA_HX2 diff --git a/t/FHEM/14_SD_UT/testData.json b/t/FHEM/14_SD_UT/testData.json index 18f3282ee..12d090de6 100644 --- a/t/FHEM/14_SD_UT/testData.json +++ b/t/FHEM/14_SD_UT/testData.json @@ -2417,5 +2417,54 @@ "id" : 130, "module" : "SD_UT", "name" : "CREATE_6601TL" + }, + { + "data" : [ + { + "comment" : "Remote control with two buttons for Halemeier LED controllers (typ HA-HX2 for actor HA-RX-M2-1)", + "dmsg" : "P132#01EFAC", + "internals" : { + "DEF" : "HA_HX2 01EF", + "NAME" : "HA_HX2_01EF" + }, + "readings" : { + "deviceCode" : "01EF", + "state" : "off" + }, + "rmsg" : "MU;P0=307;P1=-685;P2=-350;P3=658;P4=-12510;D=01010102310101010102310231010232340232323232323231010101023101010101023102323232323232323101010102310101010102310231010232340232323232323231010101023101010101023102310102323402323232323232310101010231010101010231023101023234023232323232323101010102310101;CP=0;R=232;O;", + "tests" : [ + { + "attributes" : { + "model" : "HA_HX2" + }, + "comment" : "#0 state off" + } + ] + }, + { + "comment" : "Remote control with two buttons for Halemeier LED controllers (typ HA-HX2 for actor HA-RX-M2-1)", + "dmsg" : "P132#85EFAA", + "internals" : { + "DEF" : "HA_HX2 85EF", + "NAME" : "HA_HX2_85EF" + }, + "readings" : { + "deviceCode" : "85EF", + "state" : "on" + }, + "rmsg" : "MU;P0=-696;P1=312;P2=-371;P3=637;P4=-12847;D=01012301230123012341012323232301230101010123010101010123012301230123410123232323012301010101230101010101230123012301234101232323230123010101012301010101012301230123012341012323232301230101010123010101010123012301230123410123232323012301010101230101010101;CP=1;R=236;O;", + "tests" : [ + { + "attributes" : { + "model" : "HA_HX2" + }, + "comment" : "#1 state on with other DEF" + } + ] + } + ], + "id" : 132, + "module" : "SD_UT", + "name" : "HA_HX2_01EF" } ] From 26c4bab720313a843ecaa928acfd35080c9baa73 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Wed, 20 Dec 2023 08:17:55 +0000 Subject: [PATCH 30/55] Automatic updated controls and CHANGED --- CHANGED | 14 ++++++++++++++ controls_signalduino.txt | 6 +++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/CHANGED b/CHANGED index 94ae85d37..94a3c09c5 100644 --- a/CHANGED +++ b/CHANGED @@ -1,3 +1,17 @@ +2023-12-20 - new def | remote ha-hx2 (#1212) + +* Update SD_ProtocolData.pm + +* Update 14_SD_UT.pm +- new device HA-HX2 + +* Update testData.json + +* Update 03_set.t + +* Update fhem.cfg + +* Update README.md 2023-12-15 - create client list based on whitelistIDs attribute (#1205) * perf [clientlist]: Keep order and skip sorting diff --git a/controls_signalduino.txt b/controls_signalduino.txt index 2526a9831..c8baebc1e 100644 --- a/controls_signalduino.txt +++ b/controls_signalduino.txt @@ -1,4 +1,4 @@ -UPD 2023-12-19_18:55:25 239457 FHEM/00_SIGNALduino.pm +UPD 2023-12-20_09:17:17 239457 FHEM/00_SIGNALduino.pm UPD 2023-01-06_12:08:43 20082 FHEM/10_FS10.pm UPD 2023-01-09_20:47:40 25008 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 2023-01-23_21:06:26 13260 FHEM/14_SD_AS.pm UPD 2023-01-01_18:10:40 29419 FHEM/14_SD_BELL.pm -UPD 2023-12-19_18:52:35 198590 FHEM/14_SD_UT.pm +UPD 2023-12-20_09:17:17 198590 FHEM/14_SD_UT.pm UPD 2023-09-18_21:06:46 156089 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 2023-12-18_19:22:15 251034 FHEM/lib/SD_ProtocolData.pm +UPD 2023-12-20_09:17:17 251034 FHEM/lib/SD_ProtocolData.pm UPD 2023-08-25_16:10:10 80775 FHEM/lib/SD_Protocols.pm From 2a5ebf56f1914e9ba733ee8495ffcc8deb324ef2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Dec 2023 23:14:14 +0100 Subject: [PATCH 31/55] Bump actions/github-script from 6 to 7 (#1202) Bumps [actions/github-script](https://github.com/actions/github-script) from 6 to 7. - [Release notes](https://github.com/actions/github-script/releases) - [Commits](https://github.com/actions/github-script/compare/v6...v7) --- updated-dependencies: - dependency-name: actions/github-script dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: sidey79 <7968127+sidey79@users.noreply.github.com> --- .github/workflows/update.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update.yml b/.github/workflows/update.yml index 22b914051..a64e78b41 100644 --- a/.github/workflows/update.yml +++ b/.github/workflows/update.yml @@ -19,7 +19,7 @@ jobs: - name: Check if Branch is in PR if: github.event_name == 'push' id: checkbranch - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: script: | console.log(process.env.BRANCH_NAME) From 70c9596a47964f99f6cfe388ebc15c1a00199903 Mon Sep 17 00:00:00 2001 From: HomeAutoUser Date: Fri, 22 Dec 2023 11:03:17 +0100 Subject: [PATCH 32/55] Update tests | for the functional reliability of the module SD_UT (#1214) * added data for Tedsen_SKX1xx * added sendtest AC114_01B * added sendtest BF_301 * added sendtest BeSmart_S4 * added sendtest Buttons_five * added sendtest CAME_TOP_432EV * added sendtest Chilitec_22640 * added sendtest DC_1961_TG * added sendtest HS1_868_BS * added sendtest HSM4 * added sendtest KL_RF01 * added sendtest Krinner_LUMIX * added sendtest LED_XM21_0 * added sendtest Meikee_24 * added sendtest Momento * added sendtest Navaris * added sendtest Novy_840029 + Novy_840039 * added sendtest QUIGG_DMV * added sendtest RC_10 * added sendtest RC_10 variant two * added sendtest RH787T * added sendtest SA_434_1_mini * added sendtest SF01_01319004 + SF01_01319004_Typ2 * added sendtest TR401 * added sendtest TR60C1 * added sendtest TR60C1 variant length cmd < 10 * added sendtest TR_502MSV * added sendtest Techmar * added sendtest Tedsen_SKX1xx,Tedsen_SKX2xx,Tedsen_SKX6xx * added sendtest Visivo * added sendtest with attr UTfrequency * added sendtest xavax * added some checksum tests * added some define tests --- t/FHEM/14_SD_UT/01_define.t | 72 +++++++ t/FHEM/14_SD_UT/03_set.t | 379 ++++++++++++++++++++++++++++++---- t/FHEM/14_SD_UT/fhem.cfg | 105 ++++++++++ t/FHEM/14_SD_UT/testData.json | 124 ++++++++++- 4 files changed, 634 insertions(+), 46 deletions(-) create mode 100644 t/FHEM/14_SD_UT/01_define.t diff --git a/t/FHEM/14_SD_UT/01_define.t b/t/FHEM/14_SD_UT/01_define.t new file mode 100644 index 000000000..8a364aeeb --- /dev/null +++ b/t/FHEM/14_SD_UT/01_define.t @@ -0,0 +1,72 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use Test2::V0; +use Test2::Tools::Compare qw{is}; + +our %defs; + +InternalTimer(time()+1, sub { + my $ioName = shift; + my $ioHash = $defs{$ioName}; + + + subtest 'SD_UT - define unknown_please_select_model SD_UT unknown' => sub { + plan(1); + + my $sensorname=q[unknown_please_select_model]; + my $model=q[unknown]; + CommandDefine(undef,qq[$sensorname SD_UT $model]); + is(IsDevice($sensorname), 1, "check device created with define"); + }; + + subtest 'SD_UT - delete unknown_please_select_model' => sub { + plan(1); + + my $sensorname=q[unknown_please_select_model]; + CommandDelete(undef,qq[$sensorname]); + is(IsDevice($sensorname), 0, "check device deleted"); + }; + + subtest 'SD_UT - wrong define unknown_please_select_model SD_UT unknown A1' => sub { + plan(1); + + my $sensorname=q[unknown_please_select_model]; + my $model=q[unknown]; + CommandDefine(undef,qq[$sensorname SD_UT $model A1]); + is(IsDevice($sensorname), 0, "check sensor not created with define"); + }; + + subtest 'SD_UT - model RH787T wrong HEX-Value one HEX-Value define RH787T_11 SD_UT RH787T 11' => sub { + plan(1); + + my $sensorname=q[RH787T_11]; + my $model=q[RH787T]; + CommandDefine(undef,qq[$sensorname SD_UT $model 11]); + is(IsDevice($sensorname), 0, "check device not created with define"); + }; + + subtest 'SD_UT - model RH787T wrong HEX-Value define RH787T_1 SD_UT RH787T G' => sub { + plan(1); + + my $sensorname=q[RH787T_1]; + my $model=q[RH787T]; + CommandDefine(undef,qq[$sensorname SD_UT $model G]); + is(IsDevice($sensorname), 0, "check device not created with define"); + }; + + subtest 'SD_UT - model OR28V wrong address define OR28V_1 SD_UT OR28V 17' => sub { + plan(1); + + my $sensorname=q[OR28V_1]; + my $model=q[OR28V]; + CommandDefine(undef,qq[$sensorname SD_UT $model 17]); + is(IsDevice($sensorname), 0, "check device not created with define"); + }; + + done_testing(); + exit(0); + +}, 'dummyDuino'); + +1; \ No newline at end of file diff --git a/t/FHEM/14_SD_UT/03_set.t b/t/FHEM/14_SD_UT/03_set.t index 32ff32c9f..3fd649a2b 100644 --- a/t/FHEM/14_SD_UT/03_set.t +++ b/t/FHEM/14_SD_UT/03_set.t @@ -24,49 +24,49 @@ my $module = basename (dirname(__FILE__)); mocking => sub { $mock->override ( IOWrite => sub { return @_ } ); } }, }, - { - targetName => q[SD_UT_Test_Buttons_six], # Name of the definition which is tested - testname => q[set command fan_off], # Name of our setcommand - cmd => q[set fan_off], # Command to execute for test + { + targetName => q[SD_UT_Test_Buttons_six], # Name of the definition which is tested + testname => q[set command fan_off], # Name of our setcommand + cmd => q[set fan_off], # Command to execute for test # Check for arguments given to mocked sub subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P29#111110111110#R5' }; etc() } } } , returnCheck => F(), # Check for false return from command #todo => 1, # Enable Todo block }, - { - targetName => q[SD_UT_Test_Buttons_six], - testname => q[set command 1_fan_low_speed], - cmd => q[set 1_fan_low_speed], + { + targetName => q[SD_UT_Test_Buttons_six], + testname => q[set command 1_fan_low_speed], + cmd => q[set 1_fan_low_speed], prep_commands => [ # Any FHEM custom command can be placed in here, which will be called before the test is run - 'attr $targetName repeats 4', + 'attr $targetName repeats 4', ], - - returnCheck => F(), + + returnCheck => F(), subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P29#011111111110#R4' }; etc() } } } , }, { - targetName => q[SD_UT_Test_RCnoName20_10], + targetName => q[SD_UT_Test_RCnoName20_10], testname => q[set ? ], - cmd => q[set ?], + cmd => q[set ?], returnCheck => check_set( !match qr/hex_length/, match qr/time_1h:noArg/, match qr/time_2h:noArg/, match qr/time_4h:noArg/, match qr/light_on:noArg/, match qr/light_off:noArg/, match qr/fan_low:noArg/, match qr/fan_mid:noArg/, match qr/fan_high:noArg/, match qr/fan_stop:noArg/, match qr/fan_natural:noArg/ ), subCheck => hash { end(); } , - }, - { - targetName => q[SD_UT_Test_RCnoName20_10], - testname => q[set command light_on], - cmd => q[set light_on], - - returnCheck => F(), + }, + { + targetName => q[SD_UT_Test_RCnoName20_10], + testname => q[set command light_on], + cmd => q[set light_on], + + returnCheck => F(), subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P20#00111110000000000001111000011001#R5' }; etc() } } } , }, { - targetName => q[SD_UT_Test_RCnoName20_10], + targetName => q[SD_UT_Test_RCnoName20_10], testname => q[set command fan_high with rollingcode overflow], - cmd => q[set fan_high], + cmd => q[set fan_high], - returnCheck => F(), + returnCheck => F(), subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P20#00111110000000000001010000000010#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 15', @@ -74,27 +74,320 @@ my $module = basename (dirname(__FILE__)); hashCheck => hash { field READINGS => hash {field rollingCode => hash { field VAL => 0; etc(); }; etc(); }; etc(); }, }, { - targetName => q[SD_UT_Test_RCnoName20_10], + targetName => q[SD_UT_Test_RCnoName20_10], testname => q[set unsupported command: Protocol ], - cmd => q[set Protocol], + cmd => q[set Protocol], returnCheck => q[SD_UT_Test_RCnoName20_10 Unkown set command!], subCheck => hash { end(); } , - }, + }, { - targetName => q[SD_UT_Test_OR28V_1], + targetName => q[SD_UT_Test_OR28V_1], testname => q[set command volume_minus], - cmd => q[set volume_minus], + cmd => q[set volume_minus], - returnCheck => F(), + returnCheck => F(), subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P68#01011101100010000000#R5' }; etc() } } } , - }, + }, + { + targetName => q[SD_UT_Test_Chilitec_22640_AA80], + testname => q[set command power_on], + cmd => q[set power_on], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P14#10101010100000001000#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_DC_1961_TG_1846], + testname => q[set command light_on_off], + cmd => q[set light_on_off], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P20#00011000010001101010100000010010#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_Visivo_7DF825], + testname => q[set command up], + cmd => q[set up], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P24#10011111011111011111100000100101000000101001110000010000#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_xavax_DAAB], + testname => q[set command Ch1_on], + cmd => q[set Ch1_on], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P26#11011010101010110010010101010100100001110P#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_Buttons_five_E], + testname => q[set command fan_off], + cmd => q[set fan_off], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P29#111110111110#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_QUIGG_DMV_891], + testname => q[set command Ch1_on], + cmd => q[set Ch1_on], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P34#10001001000111101110P#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_TR_502MSV_FFF], + testname => q[set command Ch1_on], + cmd => q[set Ch1_on], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P34#11111111111111101110P#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_Tedsen_SKX1xx_F1FF11F], + testname => q[set command Button_1], + cmd => q[set Button_1], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P46#101110101111101100#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_Tedsen_SKX2xx_1F10110], + testname => q[set command Button_1], + cmd => q[set Button_1], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P46#111011001111001000#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_Tedsen_SKX6xx_1F10FF0], + testname => q[set command Button_6], + cmd => q[set Button_6], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P46#111011001010001011#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_AC114_01B_00587B], + testname => q[set command down], + cmd => q[set down], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P56#10100011000000000101100001111011000000010000000001000011000101111P#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_HS1_868_BS_F62A9C01C], + testname => q[set command send], + cmd => q[set send], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P69#00000000111101100010101010011100000000011100#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_HSM4_E6BE910], + testname => q[set command button_1], + cmd => q[set button_1], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P69#00000000111001101011111010010001000001111100#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_LED_XM21_0_FFFFFFFFFFFFFF], + testname => q[set command on], + cmd => q[set on], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P76#1111111111111111111111111111111111111111111111111111111111111111#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_BeSmart_S4_534], + testname => q[set command light_toggle], + cmd => q[set light_toggle], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P78#01010011010010010000#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_SA_434_1_mini_604], + testname => q[set command send], + cmd => q[set send], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P81#011000000100#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_RH787T_0], + testname => q[set command 1_fan_minimum_speed], + cmd => q[set 1_fan_minimum_speed], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P83#000001110111#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_CAME_TOP_432EV_EE], + testname => q[set command right_button], + cmd => q[set right_button], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P86#111011101101#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_Novy_840029_55], + testname => q[set command speed_plus], + cmd => q[set speed_plus], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P86#010101010101#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_Novy_840039_55], + testname => q[set command ambient_light_on], + cmd => q[set ambient_light_on], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P86#010101010110111110#R5#C375' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_SF01_01319004_A150], + testname => q[set command plus], + cmd => q[set plus], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P86#101000010101001100#R5' }; etc() } } } , + }, { - targetName => q[SD_UT_Test_TC6861_3DC_1], + targetName => q[SD_UT_Test_SF01_01319004_Typ2_2638], + testname => q[set command delay], + cmd => q[set delay], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P86#001001100011100001#R5' }; etc() } } } , + }, + ### RC_10 | Special feature, Reading x_n5-8_on and x_n5-8_off must be present before sending can occur ### + { + targetName => q[SD_UT_Test_RC_10_7869_A], + testname => q[set command on with all readings], + cmd => q[set on], + + prep_commands => [ # Any FHEM custom command can be placed in here, which will be called before the test is run + 'setreading $targetName x_n4 0000', + 'setreading $targetName x_n5-8_on 1111001001010', + 'setreading $targetName x_n5-8_off 1110001001000', + ], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P90#0111100001101001000011110010010101#R5' }; etc() } } } , + }, + ### RC_10 | Special feature, Reading x_n5-8_on and x_n5-8_off must be present before sending can occur ### + { + targetName => q[SD_UT_Test_RC_10_7869_all], + testname => q[set command on without reading x_n5-8_off], + cmd => q[set on], + + returnCheck => q[ERROR! SD_UT_Test_RC_10_7869_all: To send, please push button on and off again on remote.], + subCheck => hash { end(); } , + }, + { + targetName => q[SD_UT_Test_Krinner_LUMIX_A06C360], testname => q[set command on], - cmd => q[set on], + cmd => q[set on], - returnCheck => F(), + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P92#10100000011011000011011000000001#R5' }; etc() } } } , + }, + ### UTfrequency example ### + { + targetName => q[SD_UT_Test_Krinner_LUMIX_A06C360_UTfrequency], + testname => q[set command on with attr UTfrequency], + cmd => q[set on], + + prep_commands => [ # Any FHEM custom command can be placed in here, which will be called before the test is run + 'attr $targetName UTfrequency 868', + ], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P92#10100000011011000011011000000001#R5#F216276' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_KL_RF01_16F6], + testname => q[set command light_color_cold_white], + cmd => q[set light_color_cold_white], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P93#000101101111011000010000111011110#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_Techmar_7709F5DE], + testname => q[set command Group_5_on], + cmd => q[set Group_5_on], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P95#01110111000010011111010111011110000100011110111000#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_Momento_0000064], + testname => q[set command play/pause], + cmd => q[set play/pause], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P97#0000000000000000000001100100001001001000#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_Navaris_211073], + testname => q[set command send], + cmd => q[set send], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P99#001000010001000001110011#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_TR60C1_0], + testname => q[set command light_off_fan_off], + cmd => q[set light_off_fan_off], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P104#0000111110000000#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_TR60C1_0_2], + testname => q[set command length < 10], + cmd => q[set fan_4], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P104#0000011110000000#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_BF_301_FAD0], + testname => q[set command down], + cmd => q[set down], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P105#1111101011010000100010001000001110100011#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_TR401_0_2], + testname => q[set command off], + cmd => q[set off], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P114#101100011111#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_Meikee_24_20D3], + testname => q[set command on], + cmd => q[set on], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P118#001000001101001100000010#R5' }; etc() } } } , + }, + { + targetName => q[SD_UT_Test_TC6861_3DC_1], + testname => q[set command on], + cmd => q[set on], + + returnCheck => F(), subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P121#P001100111101110001111110#R5' }; etc() } } } , }, { @@ -102,7 +395,7 @@ my $module = basename (dirname(__FILE__)); testname => q[set command fan_1], cmd => q[set fan_1], - returnCheck => F(), + returnCheck => F(), subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P127#001101100000001110100000101111#R5' }; etc() } } } , }, { @@ -110,7 +403,7 @@ my $module = basename (dirname(__FILE__)); testname => q[set button_left], cmd => q[set button_left], - returnCheck => F(), + returnCheck => F(), subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P128#100010100111111111111110#R5' }; etc() } } } , }, { @@ -120,24 +413,24 @@ my $module = basename (dirname(__FILE__)); returnCheck => F(), subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P132#100001011110111110101010#R5' }; etc() } } } , - }, + } ); sub runTest { Test2::SIGNALduino::FHEM_Command::commandCheck($module); done_testing(); - exit(0); + exit(0); } sub waitDone { - if ($init_done) - { - runTest(@_); - } else { - InternalTimer(time()+0.2, &waitDone,@_); - } + if ($init_done) + { + runTest(@_); + } else { + InternalTimer(time()+0.2, &waitDone,@_); + } } diff --git a/t/FHEM/14_SD_UT/fhem.cfg b/t/FHEM/14_SD_UT/fhem.cfg index 576e818dd..3f4f6192e 100644 --- a/t/FHEM/14_SD_UT/fhem.cfg +++ b/t/FHEM/14_SD_UT/fhem.cfg @@ -9,6 +9,111 @@ define SD_UT_Test_RCnoName20_10 SD_UT RCnoName20_10 3E00 define SD_UT_Test_OR28V_1 SD_UT OR28V 1 attr SD_UT_Test_OR28V_1 model OR28V +define SD_UT_Test_Chilitec_22640_AA80 SD_UT Chilitec_22640 AA80 +attr SD_UT_Test_Chilitec_22640_AA80 model Chilitec_22640 + +define SD_UT_Test_DC_1961_TG_1846 SD_UT DC_1961_TG 1846 +attr SD_UT_Test_DC_1961_TG_1846 model DC_1961_TG + +define SD_UT_Test_Visivo_7DF825 SD_UT Visivo 7DF825 +attr SD_UT_Test_Visivo_7DF825 model Visivo + +define SD_UT_Test_xavax_DAAB SD_UT xavax DAAB +attr SD_UT_Test_xavax_DAAB model xavax + +define SD_UT_Test_Buttons_five_E SD_UT Buttons_five E +attr SD_UT_Test_Buttons_five_E model Buttons_five + +define SD_UT_Test_QUIGG_DMV_891 SD_UT QUIGG_DMV 891 +attr SD_UT_Test_QUIGG_DMV_891 model QUIGG_DMV + +define SD_UT_Test_TR_502MSV_FFF SD_UT TR_502MSV FFF +attr SD_UT_Test_TR_502MSV_FFF model TR_502MSV + +define SD_UT_Test_Tedsen_SKX1xx_F1FF11F SD_UT Tedsen_SKX1xx F1FF11F +attr SD_UT_Test_Tedsen_SKX1xx_F1FF11F model Tedsen_SKX1xx + +define SD_UT_Test_Tedsen_SKX2xx_1F10110 SD_UT Tedsen_SKX2xx 1F10110 +attr SD_UT_Test_Tedsen_SKX2xx_1F10110 model Tedsen_SKX2xx + +define SD_UT_Test_Tedsen_SKX6xx_1F10FF0 SD_UT Tedsen_SKX6xx 1F10FF0 +attr SD_UT_Test_Tedsen_SKX6xx_1F10FF0 model Tedsen_SKX6xx + +define SD_UT_Test_AC114_01B_00587B SD_UT AC114_01B 00587B +attr SD_UT_Test_AC114_01B_00587B model AC114_01B + +define SD_UT_Test_HS1_868_BS_F62A9C01C SD_UT HS1_868_BS F62A9C01C +attr SD_UT_Test_HS1_868_BS_F62A9C01C model HS1_868_BS + +define SD_UT_Test_HSM4_E6BE910 SD_UT HSM4 E6BE910 +attr SD_UT_Test_HSM4_E6BE910 model HSM4 + +define SD_UT_Test_LED_XM21_0_FFFFFFFFFFFFFF SD_UT LED_XM21_0 FFFFFFFFFFFFFF +attr SD_UT_Test_LED_XM21_0_FFFFFFFFFFFFFF model LED_XM21_0 + +define SD_UT_Test_BeSmart_S4_534 SD_UT BeSmart_S4 534 +attr SD_UT_Test_BeSmart_S4_534 model BeSmart_S4 + +define SD_UT_Test_SA_434_1_mini_604 SD_UT SA_434_1_mini 604 +attr SD_UT_Test_SA_434_1_mini_604 model SA_434_1_mini + +define SD_UT_Test_RH787T_0 SD_UT RH787T 0 +attr SD_UT_Test_RH787T_0 model RH787T + +define SD_UT_Test_CAME_TOP_432EV_EE SD_UT CAME_TOP_432EV EE +attr SD_UT_Test_CAME_TOP_432EV_EE model CAME_TOP_432EV + +define SD_UT_Test_Novy_840029_55 SD_UT Novy_840029 55 +attr SD_UT_Test_Novy_840029_55 model Novy_840029 + +define SD_UT_Test_Novy_840039_55 SD_UT Novy_840039 55 +attr SD_UT_Test_Novy_840039_55 model Novy_840039 + +define SD_UT_Test_SF01_01319004_A150 SD_UT SF01_01319004 A150 +attr SD_UT_Test_SF01_01319004_A150 model SF01_01319004 + +define SD_UT_Test_SF01_01319004_Typ2_2638 SD_UT SF01_01319004_Typ2 2638 +attr SD_UT_Test_SF01_01319004_Typ2_2638 model SF01_01319004_Typ2 + +define SD_UT_Test_RC_10_7869_A SD_UT RC_10 7869_A +attr SD_UT_Test_RC_10_7869_A model RC_10 + +define SD_UT_Test_RC_10_7869_all SD_UT RC_10 7869_all +attr SD_UT_Test_RC_10_7869_all model RC_10 + +define SD_UT_Test_Krinner_LUMIX_A06C360 SD_UT Krinner_LUMIX A06C360 +attr SD_UT_Test_Krinner_LUMIX_A06C360 model Krinner_LUMIX + +define SD_UT_Test_Krinner_LUMIX_A06C360_UTfrequency SD_UT Krinner_LUMIX A06C360 +attr SD_UT_Test_Krinner_LUMIX_A06C360_UTfrequency model Krinner_LUMIX + +define SD_UT_Test_KL_RF01_16F6 SD_UT KL_RF01 16F6 +attr SD_UT_Test_KL_RF01_16F6 model KL_RF01 + +define SD_UT_Test_Techmar_7709F5DE SD_UT Techmar 7709F5DE +attr SD_UT_Test_Techmar_7709F5DE model Techmar + +define SD_UT_Test_Momento_0000064 SD_UT Momento 0000064 +attr SD_UT_Test_Momento_0000064 model Momento + +define SD_UT_Test_Navaris_211073 SD_UT Navaris 211073 +attr SD_UT_Test_Navaris_211073 model Navaris + +define SD_UT_Test_TR60C1_0 SD_UT TR60C1 0 +attr SD_UT_Test_TR60C1_0 model TR60C1 + +define SD_UT_Test_TR60C1_0_2 SD_UT TR60C1 0 +attr SD_UT_Test_TR60C1_0_2 model TR60C1 + +define SD_UT_Test_BF_301_FAD0 SD_UT BF_301 FAD0 +attr SD_UT_Test_BF_301_FAD0 model BF_301 + +define SD_UT_Test_TR401_0_2 SD_UT TR401 0_2 +attr SD_UT_Test_TR401_0_2 model TR401 + +define SD_UT_Test_Meikee_24_20D3 SD_UT Meikee_24 20D3 +attr SD_UT_Test_Meikee_24_20D3 model Meikee_24 + define SD_UT_Test_TC6861_3DC_1 SD_UT TC6861 3DC_1 define SD_UT_Test_RCnoName127_3603A SD_UT RCnoName127 3603A diff --git a/t/FHEM/14_SD_UT/testData.json b/t/FHEM/14_SD_UT/testData.json index 12d090de6..ead55ce08 100644 --- a/t/FHEM/14_SD_UT/testData.json +++ b/t/FHEM/14_SD_UT/testData.json @@ -237,6 +237,18 @@ "comment" : "#1" } ] + }, + { + "comment" : "Remote control for motorized screen, wrong checksum", + "dmsg" : "P24#9F7DF82508C210", + "tests" : [ + { + "returns" : { + "ParseFn" : "" + }, + "comment" : "#2" + } + ] } ], "id" : "24", @@ -289,7 +301,31 @@ "comment" : "#1" } ] - } + }, + { + "comment" : "model 00111939 - check nibble 0-3 and nibble 5-8", + "dmsg" : "P26#DABB255478", + "tests" : [ + { + "returns" : { + "ParseFn" : "" + }, + "comment" : "#2" + } + ] + }, + { + "comment" : "model 00111939 - check nibble 8 and nibble 9", + "dmsg" : "P26#DAAB255468", + "tests" : [ + { + "returns" : { + "ParseFn" : "" + }, + "comment" : "#3" + } + ] + } ], "id" : "26", "module" : "SD_UT", @@ -497,6 +533,28 @@ }, { "data" : [ + { + "comment" : "Tedsen remote with one button, model SKX1MD", + "dmsg" : "P46#BAFB0", + "internals" : { + "DEF" : "Tedsen_SKX1xx F1FF11F", + "NAME" : "Tedsen_SKX1xx_F1FF11F" + }, + "readings" : { + "LastAction" : "receive", + "state" : "Button_1", + "tristateCode" : "F1FF11F10" + }, + "rmsg" : "MU;P0=-15829;P1=-3580;P2=1962;P3=-330;P4=245;P5=-2051;D=1234523232345234523232323234523234540023452323234523452323232323452323454023452323234523452323232323452323454023452323234523452323232323452323454023452323234523452323232323452323454023452323234523452323;CP=2;", + "tests" : [ + { + "attributes" : { + "model" : "Tedsen_SKX1xx" + }, + "comment" : "#0" + } + ] + }, { "comment" : "Geiger Rolladen", "dispatch_repeats" : "1", @@ -571,6 +629,18 @@ "comment" : "#0" } ] + }, + { + "comment" : "Celexon Motorleinwand with wrong checksum", + "dmsg" : "P56#A300587B810043178", + "tests" : [ + { + "returns" : { + "ParseFn" : "" + }, + "comment" : "#1" + } + ] } ], "id" : "56", @@ -695,7 +765,19 @@ "comment" : "#2" } ] - } + }, + { + "comment" : "Vista Remote Control wrong checksum", + "dmsg" : "P68#57823", + "tests" : [ + { + "returns" : { + "ParseFn" : "" + }, + "comment" : "#3" + } + ] + } ], "id" : "68", "module" : "SD_UT", @@ -1760,6 +1842,18 @@ "comment" : "#2" } ] + }, + { + "comment" : "Garden Lights remote control with wrong checksum", + "dmsg" : "P95#7709F5DE09160", + "tests" : [ + { + "returns" : { + "ParseFn" : "" + }, + "comment" : "#3" + } + ] } ], "id" : "95", @@ -1834,7 +1928,19 @@ "comment" : "#2" } ] - } + }, + { + "comment" : "remote control for wireless digital picture frame with wrong checksum", + "dmsg" : "P97#000006443A", + "tests" : [ + { + "returns" : { + "ParseFn" : "" + }, + "comment" : "#3" + } + ] + } ], "id" : "97", "module" : "SD_UT", @@ -2015,6 +2121,18 @@ "comment" : "#2" } ] + }, + { + "comment" : "Remote control wrong checksum", + "dmsg" : "P105#FAD08384A8", + "tests" : [ + { + "returns" : { + "ParseFn" : "" + }, + "comment" : "#3" + } + ] } ], "id" : "105", From bbf9b7cb1718c428c9be572772abdedb2372f019 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:37:15 +0100 Subject: [PATCH 33/55] Bump lewagon/wait-on-check-action from 1.3.1 to 1.3.3 (#1216) Bumps [lewagon/wait-on-check-action](https://github.com/lewagon/wait-on-check-action) from 1.3.1 to 1.3.3. - [Release notes](https://github.com/lewagon/wait-on-check-action/releases) - [Commits](https://github.com/lewagon/wait-on-check-action/compare/v1.3.1...v1.3.3) --- updated-dependencies: - dependency-name: lewagon/wait-on-check-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/version.yml b/.github/workflows/version.yml index 3ae4104aa..57a381bdf 100644 --- a/.github/workflows/version.yml +++ b/.github/workflows/version.yml @@ -169,7 +169,7 @@ jobs: - name: Wait for tests to succeed if: ${{ steps.commit.outputs.status }} - uses: lewagon/wait-on-check-action@v1.3.1 + uses: lewagon/wait-on-check-action@v1.3.3 with: running-workflow-name: 'Commit and Push back' ref: ${{ github.head_ref }} From 1762fb28d352e7de9c282ef4f52fd9c0803ee19c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Dec 2023 18:37:38 +0100 Subject: [PATCH 34/55] Bump shogo82148/actions-setup-perl from 1.25.0 to 1.26.0 (#1215) --- updated-dependencies: - dependency-name: shogo82148/actions-setup-perl dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/perlCritic.yml | 2 +- .github/workflows/prove.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/perlCritic.yml b/.github/workflows/perlCritic.yml index 719784b21..3222e9208 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.25.0 + - uses: shogo82148/actions-setup-perl@v1.26.0 with: perl-version: 5.32 install-modules-with: cpanm diff --git a/.github/workflows/prove.yml b/.github/workflows/prove.yml index 79dda6749..7c88ae81c 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.25.0 + - uses: shogo82148/actions-setup-perl@v1.26.0 with: perl-version: ${{ matrix.perl }} install-modules-with: cpanm From 4c9b8be796741ec0d268944a28b9f546812bfc90 Mon Sep 17 00:00:00 2001 From: Udo Date: Sun, 31 Dec 2023 15:15:49 +0100 Subject: [PATCH 35/55] new sensor BRESSER PM2.5/10 air quality meter (#1219) * Bresser PM2.5/10 air quality meter new sensor BRESSER PM2.5/10 air quality meter, protocol 117 * Update SD_Protocols.pm * Update SD_Protocols.pm * Update testData.json * Update README.md * Update SD_ProtocolData.pm --- FHEM/00_SIGNALduino.pm | 11 ++- FHEM/14_SD_WS.pm | 149 +++++++++++++++++++++++++++------- FHEM/lib/SD_ProtocolData.pm | 15 ++-- FHEM/lib/SD_Protocols.pm | 6 +- README.md | 3 +- controls_signalduino.txt | 8 +- t/FHEM/14_SD_WS/testData.json | 55 +++++++++++++ 7 files changed, 199 insertions(+), 48 deletions(-) diff --git a/FHEM/00_SIGNALduino.pm b/FHEM/00_SIGNALduino.pm index 963a77322..b2655c1b4 100644 --- a/FHEM/00_SIGNALduino.pm +++ b/FHEM/00_SIGNALduino.pm @@ -4823,10 +4823,12 @@ USB-connected devices (SIGNALduino):
              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.3 MHz + Modulation 2-FSK, Datarate=8.23 kbps, Sync Word=2DD4, Packet Length=18 Byte, frequency 868.3 MHz
          • Bresser_7in1
            - modulation 2-FSK, Datarate=8.23 kbps, Sync Word=2DD4, Packet Length=22 Byte, frequency 868.3 MHz + Modulation 2-FSK, Datarate=8.23 kbps, Sync Word=2DD4, Packet Length=23 Byte, frequency 868.3 MHz +
              Example: BRESSER 7-in-1 outdoor sensor, BRESSER PM2.5/10 air quality meter
            +
          • Fine_Offset_WH51_434
            Modulation 2-FSK, Datarate=17.26 kbps, Sync Word=2DD4, Packet Length=14 Byte, Frequency 433.92 MHz @@ -5417,10 +5419,11 @@ USB-connected devices (SIGNALduino):
              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.3 MHz + Modulation 2-FSK, Datenrate=8.23 kbps, Sync Word=2DD4, Packet Length=18 Byte, Frequenz 868.3 MHz
          • Bresser_7in1
            - Modulation 2-FSK, Datenrate=8.23 kbps, Sync Word=2DD4, Packet Length=22 Byte, Frequenz 868.3 MHz + Modulation 2-FSK, Datenrate=8.23 kbps, Sync Word=2DD4, Packet Length=23 Byte, Frequenz 868.3 MHz +
              Beispiel: BRESSER 7-in-1 Außensensor, BRESSER PM2.5/10 Luftqualitätssensor
          • Fine_Offset_WH51_434
            Modulation 2-FSK, Datenrate=17.26 kbps, Sync Word=2DD4, Packet Length=14 Byte, Frequenz 433.92 MHz diff --git a/FHEM/14_SD_WS.pm b/FHEM/14_SD_WS.pm index 13e119174..d38169e87 100644 --- a/FHEM/14_SD_WS.pm +++ b/FHEM/14_SD_WS.pm @@ -1,4 +1,4 @@ -# $Id: 14_SD_WS.pm 26982 2023-09-11 16:54:55Z elektron-bbs $ +# $Id: 14_SD_WS.pm 26982 2023-12-29 20:00:00Z elektron-bbs $ # # The purpose of this module is to support serval # weather sensors which use various protocol @@ -52,6 +52,7 @@ # 01.04.2023 Added protocol 125: ecowitt WH31 support # 06.05.2023 Added protocol 126: ecowitt WH40 support # 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 package main; @@ -128,6 +129,9 @@ sub SD_WS_Define { carp "SD_WS_Define, too few arguments ($hash, $def)" if @_ < 2; my @a = split("[ \t][ \t]*", $def); + # Anzeigen der Modulversion (Internal FVERSION) über FHEM::Meta, Variable in META.json Abschnitt erforderlich: "version": "v1.0.0", siehe https://wiki.fhem.de/wiki/Meta + return $@ unless ( FHEM::Meta::SetInternals($hash) ); + return "wrong syntax: define SD_WS ".int(@a) if(int(@a) < 3 ); $hash->{CODE} = $a[2]; @@ -209,6 +213,7 @@ sub SD_WS_Parse { my $bitData = unpack("B$blen", pack("H$hlen", $rawData)); my $bitData2; my $model; # wenn im elsif Abschnitt definiert, dann wird der Sensor per AutoCreate angelegt + my $modelStat; # for FHEM statistics https://fhem.de/stats/statistics.html my $SensorTyp; my $id; my $bat; @@ -245,6 +250,8 @@ sub SD_WS_Parse { my $identified; my $transmitter; my $dcf; + my $pm2_5; # particulate matter <= 2.5 µm + my $pm10; # particulate matter <= 10 µm my %decodingSubs = ( 50 => # Protocol 50 @@ -1248,60 +1255,122 @@ sub SD_WS_Parse { return 1; } } , - 117 => { # https://github.com/merbanan/rtl_433/blob/master/src/devices/bresser_7in1.c # The compact 7-in-1 multifunction outdoor sensor transmits the data on 868.3 MHz. # The device uses FSK-PCM encoding, the device sends a transmission every 12 seconds. # A transmission starts with a preamble of 0xAA. # Preamble: aa aa aa aa aa 2d d4 - # # 1 2 3 4 # 01234567890123456789012345678901234567890123456789 # -------------------------------------------------- - # 0CF0A6F5B98A10AAAAAAAAAAAAAABABC3EAABBFCAAAAAAAAAA000000 original message - # A65A0C5F1320BA000000000000001016940011560000000000AAAAAA message after all nibbles xor 0xA - # CCCCIIIIDDD??FGGGWWWRRRRRR??TTTBHHbbbbbbVVVttttttt - # C = LFSR-16 digest, generator 0x8810 key 0xba95 with a final xor 0x6df1, which likely means we got that wrong. + # EF0AE6AB8FEA18A89A8BABAACAAAB2CCCFAF3C33AF2AAAAAAA original message + # 45A04C012540B2023021010060001866650596990580000000 message after all nibbles xor 0xA + # CCCCIIIIDDD?SFGGGWWWRRRRRR??TTTBHHbbbbbbVVVttttttt + # C = LFSR-16 digest, generator 0x8810 key 0xba95 with a final xor 0x6df1 # I = station ID - # D = wind direction in degree, BCD coded, DDD = 158 => 158 ° + # D = wind direction in degree, BCD coded, DDD = 254 => 254 ° + # S = sensor type, xor 0xA, 1 = 7-in-1 outdoor sensor, 8 = Air quality sensor # F = flags, 4 bit # Bit: 0123 - # 1010 - # r??? + # 1010 xor 0xA = 0000 + # rccc # r: 1 bit device reset, 1 after inserting battery - # ???: always 010 - # G = wind gust in 1/10 m/s, BCD coded, GGG = 123 => 12.3 m/s. - # W = wind speed in 1/10 m/s, BCD coded, WWW = 123 => 12.3 m/s. - # R = rain counter, in 0.1 mm, BCD coded RRRRRR = 000084 => 8.4 mm - # T = temperature in 1/10 °C, BCD coded, TTT = 312 => 31.2 °C + # c: 3 bit channel always 0 by outdoor sensor, 1-4 by air quality sensor + # G = wind gust in 1/10 m/s, BCD coded, GGG = 023 => 2.3 m/s. + # W = wind speed in 1/10 m/s, BCD coded, WWW = 021 => 2.1 m/s. + # R = rain counter, in 0.1 mm, BCD coded RRRRRR = 010060 => 1006.0 mm + # T = temperature in 1/10 °C, BCD coded, TTT = 186 => 18.6 °C # B = battery. 0=Ok, 6=Low - # H = humidity in percent, BCD coded, HH = 23 => 23 % - # b = brightness, BCD coded, BBBBBB = 005584 => 5.584 klx - # V = uv, BCD coded, VVV = 012 => 1.2 + # H = humidity in percent, BCD coded, HH = 65 => 65 % + # b = brightness, BCD coded, BBBBBB = 059699 => 59.699 klx + # V = uv, BCD coded, VVV = 058 => 5.8 # ? = unknown # t = trailer + # + # BRESSER Air Quality Sensor Art.No.: 7009970, Manufacturer CCL Electronics LTD Model C3123A + # The sensor transmits approximately every 60 seconds. + # 1 2 3 4 + # 01234567890123456789012345678901234567890123456789 + # -------------------------------------------------- + # EF596068B83A89B9AA9BDA9EBA9EDA33333333333392DAAAAA original message + # 45F3CAC2129023130031703410347099999999999938700000 message after all nibbles xor 0xA, PM2.5: 341 PM10: 347 + # CCCCIIII????SF????????222?111?????????????BBBttttt + # 2 = PM2.5 particlae matter in µg/m³, BCD coded, 341 => 341 µg/m³ + # 1 = PM10 particlae matter in µg/m³, BCD coded, 347 => 347 µg/m³ + # B = battery voltage in 1/100 Volt, BCD coded, 387 => 3,87 Volt + # All others as in 7-in-1 multifunction outdoor sensor sensortype => 'Bresser_7in1', model => 'SD_WS_117', - prematch => sub {my $rawData = shift; return 1 if ($rawData =~ /^[0-9A-F]{8}[0-9]{3}[0-9A-F]{3}[0-9]{12}[0-9A-F]{2}[0-9]{15}/); }, + prematch => sub {my $rawData = shift; return 1 if ($rawData =~ /^[0-9A-F]{8}[0-9]{3}[0-9A-F]{3}[0-9]{12}[0-9A-F]{2}[0-9]{16}/); }, id => sub {my ($rawData,undef) = @_; return substr($rawData,4,4); }, winddir => sub {my ($rawData,undef) = @_; + return if (substr($rawData,12,1) ne 'B'); # only weather station $winddir = substr($rawData,8,3); return ($winddir * 1, $winddirtxtar[FHEM::Core::Utils::Math::round(($winddir / 22.5),0)]); }, + modelStat => sub {my ($rawData,undef) = @_; + my $typ = hex(substr($rawData,12,1)) ^ 0xA; # sensor type + if ($typ eq '1') { + $typ = 'Bresser 7-in-1 outdoor sensor'; + } elsif ($typ eq '8') { + $typ = 'Bresser PM2.5/10 air quality meter'; + } else { + $typ = 'SD_WS_117'; + } + return $typ; + }, batChange => sub {my (undef,$bitData) = @_; return substr($bitData,52,1) eq '0' ? '1' : '0';}, - windgust => sub {my ($rawData,undef) = @_; return substr($rawData,14,3) * 0.1;}, - windspeed => sub {my ($rawData,undef) = @_; return substr($rawData,17,3) * 0.1;}, - rain => sub {my ($rawData,undef) = @_; return substr($rawData,20,6) * 0.1;}, + channel => sub {my ($rawData,undef) = @_; + return if (substr($rawData,12,1) eq 'B'); # not by weather station + return ((hex(substr($rawData,13,1)) ^ 0xA) & 0x07); # channel + }, + windgust => sub {my ($rawData,undef) = @_; + return if (substr($rawData,12,1) ne 'B'); # only Bresser_7in1 outdoor sensor + return substr($rawData,14,3) * 0.1; + }, + windspeed => sub {my ($rawData,undef) = @_; + return if (substr($rawData,12,1) ne 'B'); # only Bresser_7in1 outdoor sensor + return substr($rawData,17,3) * 0.1; + }, + rain => sub {my ($rawData,undef) = @_; + return if (substr($rawData,12,1) ne 'B'); # only Bresser_7in1 outdoor sensor + return substr($rawData,20,6) * 0.1; + }, + pm_2_5 => sub {my ($rawData,undef) = @_; # particulate matter <= 2.5 µm + return if (substr($rawData,12,1) eq 'B'); # not by Bresser_7in1 outdoor sensor + return substr($rawData,22,3) * 1; + }, + pm_10 => sub {my ($rawData,undef) = @_; # particulate matter <= 10 µm + return if (substr($rawData,12,1) eq 'B'); # not by Bresser_7in1 outdoor sensor + return substr($rawData,26,3) * 1; + }, temp => sub {my ($rawData,undef) = @_; + return if (substr($rawData,12,1) ne 'B'); # only Bresser_7in1 outdoor sensor $rawTemp = substr($rawData,28,3) * 0.1; if ($rawTemp > 60) {$rawTemp -= 100}; - return $rawTemp; + return FHEM::Core::Utils::Math::round($rawTemp,1); + }, + bat => sub {my ($rawData,undef) = @_; + return if (substr($rawData,12,1) ne 'B'); # only Bresser_7in1 outdoor sensor + return substr($rawData,31,1) eq '0' ? 'ok' : 'low'; + }, + hum => sub {my ($rawData,undef) = @_; + return if (substr($rawData,12,1) ne 'B'); # only Bresser_7in1 outdoor sensor + return substr($rawData,32,2) * 1; + }, + brightness => sub {my ($rawData,undef) = @_; + return if (substr($rawData,12,1) ne 'B'); # only Bresser_7in1 outdoor sensor + return substr($rawData,34,6) * 0.001; + }, + uv => sub {my ($rawData,undef) = @_; + return if (substr($rawData,12,1) ne 'B'); # only Bresser_7in1 outdoor sensor + return substr($rawData,40,3) * 0.1; + }, + batVoltage => sub { my ($rawData,undef) = @_; + return if (substr($rawData,12,1) eq 'B'); # not by Bresser_7in1 outdoor sensor + return substr($rawData,42,3) * 0.01; }, - bat => sub {my ($rawData,undef) = @_; return substr($rawData,31,1) eq '0' ? 'ok' : 'low';}, - hum => sub {my ($rawData,undef) = @_; return substr($rawData,32,2) * 1;}, - brightness => sub {my ($rawData,undef) = @_; return substr($rawData,34,6) * 0.001;}, - uv => sub {my ($rawData,undef) = @_; return substr($rawData,40,3) * 0.1;}, crcok => sub {return 1;}, # checks are in SD_Protocols.pm sub ConvBresser_7in1 }, 120 => { @@ -1963,6 +2032,7 @@ sub SD_WS_Parse { $windgust = $decodingSubs{$protocol}{windgust}->( $rawData,$bitData ) if (exists($decodingSubs{$protocol}{windgust})); $channel = $decodingSubs{$protocol}{channel}->( $rawData,$bitData ) if (exists($decodingSubs{$protocol}{channel})); $model = $decodingSubs{$protocol}{model}; + $modelStat = $decodingSubs{$protocol}{modelStat}->( $rawData,$bitData ) if (exists($decodingSubs{$protocol}{modelStat})); $bat = $decodingSubs{$protocol}{bat}->( $rawData,$bitData ) if (exists($decodingSubs{$protocol}{bat})); $batVoltage = $decodingSubs{$protocol}{batVoltage}->( $rawData,$bitData ) if (exists($decodingSubs{$protocol}{batVoltage})); $batChange = $decodingSubs{$protocol}{batChange}->( $rawData,$bitData ) if (exists($decodingSubs{$protocol}{batChange})); @@ -1985,6 +2055,8 @@ sub SD_WS_Parse { $brightness = $decodingSubs{$protocol}{brightness}->( $rawData,$bitData ) if (exists($decodingSubs{$protocol}{brightness})); $transmitter = $decodingSubs{$protocol}{transmitter}->( $rawData,$bitData ) if (exists($decodingSubs{$protocol}{transmitter})); $dcf = $decodingSubs{$protocol}{dcf}->( $rawData,$bitData ) if (exists($decodingSubs{$protocol}{dcf})); + $pm2_5 = $decodingSubs{$protocol}{pm_2_5}->( $rawData,$bitData ) if (exists($decodingSubs{$protocol}{pm_2_5})); + $pm10 = $decodingSubs{$protocol}{pm_10}->( $rawData,$bitData ) if (exists($decodingSubs{$protocol}{pm_10})); Log3 $iohash, 4, "$name: SD_WS_Parse decoded protocol-id $protocol ($SensorTyp), sensor-id $id"; } else { @@ -2143,7 +2215,14 @@ sub SD_WS_Parse { $state .= ' ' if (length($state) > 0); $state .= "B: $brightness"; } - + if (defined($pm2_5)) { + $state .= ' ' if (length($state) > 0); + $state .= "PM2.5: $pm2_5"; + } + if (defined($pm10)) { + $state .= ' ' if (length($state) > 0); + $state .= "PM10: $pm10"; + } ### protocol 33 has different bits per sensor type if ($protocol eq "33") { if (AttrVal($name,'model',0) eq "S522") { # Conrad S522 @@ -2168,6 +2247,11 @@ sub SD_WS_Parse { } } + if (AttrVal($name,'model','0') eq '0' && !defined($modelStat)) { + $modelStat = $model; + Log3 $name, 4, "$ioname: SD_WS_Parse $name, model=$model, modelStat=$modelStat, SensorTyp=$SensorTyp"; + } + readingsBeginUpdate($hash); readingsBulkUpdate($hash, "state", $state); readingsBulkUpdate($hash, "temperature", $temp) if (defined($temp) && (($temp > -60 && $temp < 70 ) || $protocol eq '106' || $protocol eq '113' || $protocol eq '122')); @@ -2189,6 +2273,7 @@ sub SD_WS_Parse { readingsBulkUpdate($hash, "humidityTrend", $trendHum) if (defined($trendHum) && length($trendHum) > 0); readingsBulkUpdate($hash, "sendmode", $sendmode) if (defined($sendmode) && length($sendmode) > 0); readingsBulkUpdateIfChanged($hash, "type", $SensorTyp, 0) if (defined($SensorTyp)); + readingsBulkUpdate($hash, 'model', $modelStat, 0) if (defined($modelStat)); readingsBulkUpdate($hash, "beep", $beep) if (defined($beep)); readingsBulkUpdate($hash, "adc", $adc) if (defined($adc)); readingsBulkUpdate($hash, 'rain', $rain) if (defined($rain)); @@ -2202,6 +2287,8 @@ sub SD_WS_Parse { readingsBulkUpdate($hash, 'brightness', $brightness) if (defined($brightness)); readingsBulkUpdateIfChanged($hash, 'transmitter', $transmitter) if (defined($transmitter)); readingsBulkUpdate($hash, 'dcf', $dcf) if (defined($dcf)); + readingsBulkUpdate($hash, 'pm_2_5', $pm2_5) if (defined($pm2_5)); + readingsBulkUpdate($hash, 'pm_10', $pm10) if (defined($pm10)); readingsEndUpdate($hash, 1); # Notify is done by Dispatch return $name; @@ -2319,7 +2406,7 @@ sub SD_WS_WH2SHIFT {
          • ADE WS1907 Weather station with rain gauge
          • Atech wireless weather station
          • BBQ temperature sensor GT-TMBBQ-01s (transmitter), GT-TMBBQ-01e (receiver)
          • -
          • Bresser 5-in-1, 6-in-1 and 7-in-1 Comfort Weather Center, 7009994, Professional rain gauge, Temeo
          • +
          • Bresser 5-in-1, 6-in-1 and 7-in-1 Comfort Weather Center, 7009994, PM2.5/10 air quality meter, Professional rain gauge, Temeo
          • Conrad S522
          • EuroChron EFTH-800, EFS-3110A (temperature and humidity sensor)
          • Fine Offset WH51, aka ECOWITT WH51, aka Froggit DP100, aka MISOL/1 (soil moisture sensor)
          • @@ -2463,7 +2550,7 @@ sub SD_WS_WH2SHIFT {
          • ADE WS1907 Wetterstation mit Regenmesser
          • Atech Wetterstation
          • BBQ Temperatur Sensor GT-TMBBQ-01s (Sender), GT-TMBBQ-01e (Empfaenger)
          • -
          • Bresser 5-in-1, 6-in-1 und 7-in-1 Comfort Wetter Center, 7009994, Profi Regenmesser, Temeo
          • +
          • Bresser 5-in-1, 6-in-1 und 7-in-1 Comfort Wetter Center, 7009994, PM2.5/10 Luftqualitätsmesser, Profi Regenmesser, Temeo
          • Conrad S522
          • EuroChron EFTH-800, EFS-3110A (Temperatur- und Feuchtigkeitssensor)
          • Fine Offset WH51, aka ECOWITT WH51, aka Froggit DP100, aka MISOL/1 (Bodenfeuchtesensor)
          • @@ -2598,6 +2685,7 @@ sub SD_WS_WH2SHIFT {
          =end html_DE + =for :application/json;q=META.json 14_SD_WS.pm { "abstract": "Supports various weather stations", @@ -2611,6 +2699,7 @@ sub SD_WS_WH2SHIFT { "x_fhem_maintainer_github": [ "Sidey79" ], + "version": "v1.0.0", "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 535e0e05d..b182efa81 100644 --- a/FHEM/lib/SD_ProtocolData.pm +++ b/FHEM/lib/SD_ProtocolData.pm @@ -1,4 +1,4 @@ -# $Id: SD_ProtocolData.pm 26975 2023-08-27 19:36:33Z elektron-bbs $ +# $Id: SD_ProtocolData.pm 26975 2023-12-29 20:00:00Z elektron-bbs $ # The file is part of the SIGNALduino project. # All protocol definitions are contained in this file. # @@ -70,7 +70,7 @@ ##### 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: 130 - +# ID´s are currently unused: 133 - # 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/MN protocol and a URL of issue in GitHub or discussion in FHEM Forum @@ -85,7 +85,7 @@ package lib::SD_ProtocolData; use strict; use warnings; - our $VERSION = '1.55'; + our $VERSION = '1.56'; 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; @@ -3142,11 +3142,14 @@ package lib::SD_ProtocolData; clientmodule => 'SD_WS', length_min => '18', }, - "117" => ## BRESSER 7-in-1 Weather Center + "117" => ## BRESSER 7-in-1 Weather Center (outdoor sensor) # https://forum.fhem.de/index.php/topic,78809.msg1196941.html#msg1196941 @ JensS 2021-12-30 # T: 12.7 H: 87 W: 0 R: 8.4 B: 6.676 MN;D=FC28A6F58DCA18AAAAAAAAAA2EAAB8DA2DAACCDCAAAAAAAAAA000000;R=29; # T: 13.1 H: 88 W: 0 R: 0 B: 0.36 MN;D=4DC4A6F5B38A10AAAAAAAAAAAAAAB9BA22AAA9CAAAAAAAAAAA000000;R=15; # T: 10.1 H: 94 W: 0 R: 0 B: 1.156 MN;D=0CF0A6F5B98A10AAAAAAAAAAAAAABABC3EAABBFCAAAAAAAAAA000000;R=28; + ## BRESSER PM2.5/10 air quality meter @ elektron-bbs 2023-11-30 + # PM2.5: 629 PM10: 636 MN;D=ACF66068BDCA89BD2AF22AC83AC9CA33333333333393CAAAAA00;R=9; + # PM2.5: 8 PM10: 9 MN;D=E3626068BDCA89BD2AAADAAA2AAA3AAEEAAF9AAFEA93CAAAAA00;R=10; { name => 'Bresser 7in1', comment => 'BRESSER 7-in-1 weather center', @@ -3156,10 +3159,10 @@ package lib::SD_ProtocolData; sync => '2DD4', modulation => '2-FSK', rfmode => 'Bresser_7in1', - register => ['0001','022E','0345','042D','05D4','0616','07C0','0800','0D21','0E65','0F6A','1088','114C','1202','1322','14F8','1551','1916','1B43','1C68'], + register => ['0001','022E','0345','042D','05D4','0617','07C0','0800','0D21','0E65','0F6A','1088','114C','1202','1322','14F8','1551','1916','1B43','1C68'], preamble => 'W117#', clientmodule => 'SD_WS', - length_min => '44', + length_min => '46', method => \&lib::SD_Protocols::ConvBresser_7in1, }, "118" => ## Remote controls for Meikee LED lights e.g. RGB LED Wallwasher Light and Solar Flood Light diff --git a/FHEM/lib/SD_Protocols.pm b/FHEM/lib/SD_Protocols.pm index 0e0607b38..67c902ad3 100644 --- a/FHEM/lib/SD_Protocols.pm +++ b/FHEM/lib/SD_Protocols.pm @@ -16,7 +16,7 @@ use Carp qw(croak carp); use constant HAS_DigestCRC => defined eval { require Digest::CRC; }; use constant HAS_JSON => defined eval { require JSON; }; -our $VERSION = '2.07'; +our $VERSION = '2.08'; use Storable qw(dclone); use Scalar::Util qw(blessed); @@ -2021,7 +2021,7 @@ sub ConvBresser_7in1 { my $hexData = shift // croak 'Error: called without $hexdata as input'; my $hexLength = length($hexData); - return (1, 'ConvBresser_7in1, hexData is to short') if ($hexLength < 44); # check double, in def length_min set + return (1, 'ConvBresser_7in1, hexData is to short') if ($hexLength < 46); # check double, in def length_min set return (1, 'ConvBresser_7in1, byte 21 is 0x00') if (substr($hexData,42,2) eq '00'); # check byte 21 my $hexDataXorA =''; @@ -2032,7 +2032,7 @@ sub ConvBresser_7in1 { $self->_logging(qq[ConvBresser_7in1, msg=$hexData],5); $self->_logging(qq[ConvBresser_7in1, xor=$hexDataXorA],5); - my $checksum = lib::SD_Protocols::LFSR_digest16(20, 0x8810, 0xba95, substr($hexDataXorA,4,40)); + my $checksum = lib::SD_Protocols::LFSR_digest16(21, 0x8810, 0xBA95, substr($hexDataXorA,4,42)); my $checksumcalc = sprintf('%04X',$checksum ^ hex(substr($hexDataXorA,0,4))); $self->_logging(qq[ConvBresser_7in1, checksumCalc:0x$checksumcalc, must be 0x6DF1],5); return ( 1, qq[ConvBresser_7in1, checksumCalc:0x$checksumcalc != checksum:0x6DF1] ) if ($checksumcalc ne '6DF1'); diff --git a/README.md b/README.md index 27919e8f2..54af2a2c5 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Supported Devices / Protocols |BF-301 | Remote control| |benon (Semexo OHG) | Remote control (BH-P)| |BOSCH / Neff / Refsta Topdraft | Remote control (SF01 01319004, SF01 01319004 v2)| -|BRESSER 5-in-1, 6-in-1, 7-in-1, Professional Rain Gauge, TemeoTrend, SM60020 Soil moisture sensor | Weather Station, Rain Gauge, Thermo-/Hygro Sensor | +|BRESSER 5-in-1, 6-in-1, 7-in-1, Professional Rain Gauge, TemeoTrend, SM60020 Soil moisture sensor, PM2.5/10 Air quality sensor | Weather Station, Rain Gauge, Thermo-/Hygro Sensor, Particulate meter | |Busch-Transcontrol HF | Remote control (6861)| |CAME TOP 432EV | Remote control | |CTW600, WH1080, WH2315 | Weather station | @@ -43,6 +43,7 @@ Supported Devices / Protocols |Fine Offset WH51, aka ECOWITT WH51, aka Froggit DP100, aka MISOL/1 | Soil moisture sensor | |Fine Offset WH57, aka Ambient Weather WH31L, aka Froggit DP60 | Thunder and lightning sensor | |Fine Offset WH31, aka Ambient Weather WH31E, aka ecowitt WH31 | Temperature and humidity sensor | +|Fine Offset WH40, aka Ambient Weather WH40E, aka ecowitt WH40 | Rain gauge | |FLAMINGO | Flamingo smoke detector | |Fody E42 | Temperature/humidity sensor (protocol BRESSER 5-in-1) | |FreeTec PE-6946 | wireless bell | diff --git a/controls_signalduino.txt b/controls_signalduino.txt index c8baebc1e..813c673ea 100644 --- a/controls_signalduino.txt +++ b/controls_signalduino.txt @@ -1,4 +1,4 @@ -UPD 2023-12-20_09:17:17 239457 FHEM/00_SIGNALduino.pm +UPD 2023-12-29_21:43:52 239695 FHEM/00_SIGNALduino.pm UPD 2023-01-06_12:08:43 20082 FHEM/10_FS10.pm UPD 2023-01-09_20:47:40 25008 FHEM/10_SD_GT.pm UPD 2023-01-01_18:10:40 25403 FHEM/10_SD_Rojaflex.pm @@ -8,11 +8,11 @@ UPD 2023-10-14_22:18:35 24045 FHEM/14_Hideki.pm UPD 2023-01-23_21:06:26 13260 FHEM/14_SD_AS.pm UPD 2023-01-01_18:10:40 29419 FHEM/14_SD_BELL.pm UPD 2023-12-20_09:17:17 198590 FHEM/14_SD_UT.pm -UPD 2023-09-18_21:06:46 156089 FHEM/14_SD_WS.pm +UPD 2023-12-29_21:43:52 161715 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 2023-12-20_09:17:17 251034 FHEM/lib/SD_ProtocolData.pm -UPD 2023-08-25_16:10:10 80775 FHEM/lib/SD_Protocols.pm +UPD 2023-12-30_16:18:23 251336 FHEM/lib/SD_ProtocolData.pm +UPD 2023-12-29_22:11:03 80775 FHEM/lib/SD_Protocols.pm diff --git a/t/FHEM/14_SD_WS/testData.json b/t/FHEM/14_SD_WS/testData.json index f85bbddf4..c07837c8a 100644 --- a/t/FHEM/14_SD_WS/testData.json +++ b/t/FHEM/14_SD_WS/testData.json @@ -2044,6 +2044,61 @@ "module" : "SD_WS", "name" : "BRESSER 7-in-1" }, + { + "data" : [ + { + "comment" : "BRESSER PM2.5/10 air quality meter", + "dmsg" : "W117#49C8CAC2176023178000700080009004400530054039600000AA", + "internals" : { + "DEF" : "SD_WS_117_1", + "NAME" : "SD_WS_117_1" + }, + "readings" : { + "batteryChanged" : "1", + "batteryVoltage" : 3.96, + "channel" : 1, + "pm_10" : 9, + "pm_2_5" : 8, + "state" : "PM2.5: 8 PM10: 9", + "type" : "Bresser_7in1" + }, + "rmsg" : "MN;D=E3626068BDCA89BD2AAADAAA2AAA3AAEEAAF9AAFEA93CAAAAA00;R=10;", + "tests" : [ + { + "attributes" : {}, + "comment" : "#0" + } + ] + }, + { + "comment" : "BRESSER PM2.5/10 air quality meter", + "dmsg" : "W117#065CCAC2176023178058806290636099999999999939600000AA", + "internals" : { + "DEF" : "SD_WS_117_1", + "NAME" : "SD_WS_117_1" + }, + "readings" : { + "batteryChanged" : "1", + "batteryVoltage" : 3.96, + "channel" : 1, + "pm_10" : 636, + "pm_2_5" : 629, + "state" : "PM2.5: 629 PM10: 636", + "type" : "Bresser_7in1" + }, + "rmsg" : "MN;D=ACF66068BDCA89BD2AF22AC83AC9CA33333333333393CAAAAA00;R=9;", + "tests" : [ + { + "attributes" : {}, + "comment" : "#1" + } + ] + } + ], + "id" : 117, + "module" : "SD_WS", + "name" : "BRESSER PM2.5/10" + }, { "data" : [ { From d784bb80a2f619836a7aa6da9748dba5eb26209f Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Sun, 31 Dec 2023 14:16:28 +0000 Subject: [PATCH 36/55] Automatic updated controls and CHANGED --- CHANGED | 9 +++++++++ controls_signalduino.txt | 8 ++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/CHANGED b/CHANGED index 94a3c09c5..ef6318d4c 100644 --- a/CHANGED +++ b/CHANGED @@ -1,3 +1,12 @@ +2023-12-31 - new sensor BRESSER PM2.5/10 air quality meter (#1219) + +* Bresser PM2.5/10 air quality meter + new sensor BRESSER PM2.5/10 air quality meter, protocol 117 +* Update SD_Protocols.pm +* Update SD_Protocols.pm +* Update testData.json +* Update README.md +* Update SD_ProtocolData.pm 2023-12-20 - new def | remote ha-hx2 (#1212) * Update SD_ProtocolData.pm diff --git a/controls_signalduino.txt b/controls_signalduino.txt index 813c673ea..344a45f3f 100644 --- a/controls_signalduino.txt +++ b/controls_signalduino.txt @@ -1,4 +1,4 @@ -UPD 2023-12-29_21:43:52 239695 FHEM/00_SIGNALduino.pm +UPD 2023-12-31_15:15:49 239695 FHEM/00_SIGNALduino.pm UPD 2023-01-06_12:08:43 20082 FHEM/10_FS10.pm UPD 2023-01-09_20:47:40 25008 FHEM/10_SD_GT.pm UPD 2023-01-01_18:10:40 25403 FHEM/10_SD_Rojaflex.pm @@ -8,11 +8,11 @@ UPD 2023-10-14_22:18:35 24045 FHEM/14_Hideki.pm UPD 2023-01-23_21:06:26 13260 FHEM/14_SD_AS.pm UPD 2023-01-01_18:10:40 29419 FHEM/14_SD_BELL.pm UPD 2023-12-20_09:17:17 198590 FHEM/14_SD_UT.pm -UPD 2023-12-29_21:43:52 161715 FHEM/14_SD_WS.pm +UPD 2023-12-31_15:15:49 161715 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 2023-12-30_16:18:23 251336 FHEM/lib/SD_ProtocolData.pm -UPD 2023-12-29_22:11:03 80775 FHEM/lib/SD_Protocols.pm +UPD 2023-12-31_15:15:49 251336 FHEM/lib/SD_ProtocolData.pm +UPD 2023-12-31_15:15:49 80775 FHEM/lib/SD_Protocols.pm From 7f600a4512ef494ad5eeea873fed889318b918b5 Mon Sep 17 00:00:00 2001 From: sidey79 <7968127+sidey79@users.noreply.github.com> Date: Sun, 31 Dec 2023 16:00:43 +0100 Subject: [PATCH 37/55] Bump actions/artifact-download and -upload from v3 to v4 (#1210) * Bump actions/upload-artifact from 3 to 4 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3 to 4. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Bump actions/download-artifact from 3 to 4 (#1208) * Bump actions/download-artifact from 3 to 4 Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 3 to 4. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --------- Signed-off-by: dependabot[bot] Co-authored-by: sidey79 <7968127+sidey79@users.noreply.github.com> Co-authored-by: GitHub Action Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix[pipeline]: Fix matrix filename variable * Update Versiondate * Update Versiondate --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: GitHub Action --- .github/workflows/version.yml | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/.github/workflows/version.yml b/.github/workflows/version.yml index 57a381bdf..79cbbb581 100644 --- a/.github/workflows/version.yml +++ b/.github/workflows/version.yml @@ -121,13 +121,20 @@ jobs: 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 }} " include: "${{ matrix.files }}" + - name: Artifactname + env: + ARTIFACT_NAME: "${{ matrix.files }}" + run: | + ARTIFACT_NAME=${{ env.ARTIFACT_NAME }} + ARTIFACT_NAME=$(basename $ARTIFACT_NAME) # get only the filename and use this as artifact name + echo ARTIFACT_NAME=${ARTIFACT_NAME} >> $GITHUB_ENV # update GitHub ENV vars - name: Save updated Files in artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: updated-files + name: ${{ env.ARTIFACT_NAME }} retention-days: 1 path: | - ${{ matrix.file }} + ${{ matrix.files }} commit: permissions: contents: write @@ -141,12 +148,13 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Download all modified artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: - path: ${{ github.workspace }} + path: ${{ github.workspace }}/artifacts + - name: replace files from artifacts run: | - for FPATH in ./updated-files/*.pm; do + for FPATH in ./artifacts/*/*.pm; do FILE=$(basename $FPATH) find ./FHEM -name "$FILE" -exec cp $FPATH "{}" \; done From 9d675ed561d4f54d9b287f4ae5d299a49701e1a0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 11:03:38 +0100 Subject: [PATCH 38/55] Bump shogo82148/actions-setup-perl from 1.26.0 to 1.27.0 (#1220) --- updated-dependencies: - dependency-name: shogo82148/actions-setup-perl dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/perlCritic.yml | 2 +- .github/workflows/prove.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/perlCritic.yml b/.github/workflows/perlCritic.yml index 3222e9208..8d645bceb 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.26.0 + - uses: shogo82148/actions-setup-perl@v1.27.0 with: perl-version: 5.32 install-modules-with: cpanm diff --git a/.github/workflows/prove.yml b/.github/workflows/prove.yml index 7c88ae81c..3c5eb5cba 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.26.0 + - uses: shogo82148/actions-setup-perl@v1.27.0 with: perl-version: ${{ matrix.perl }} install-modules-with: cpanm From fbde07431ef0336e25c2b51667ca72de20480f98 Mon Sep 17 00:00:00 2001 From: HomeAutoUser Date: Tue, 2 Jan 2024 23:01:30 +0100 Subject: [PATCH 39/55] Update tests part two | for the functional reliability of the module SD_UT (#1218) * added some tests for define and attr --- FHEM/14_SD_UT.pm | 3 +- controls_signalduino.txt | 2 +- t/FHEM/14_SD_UT/01_attr.t | 258 ++++++++++++++++++++++++++++++---- t/FHEM/14_SD_UT/01_define.t | 11 +- t/FHEM/14_SD_UT/03_set.t | 10 ++ t/FHEM/14_SD_UT/fhem.cfg | 151 ++++++-------------- t/FHEM/14_SD_UT/testData.json | 23 +++ 7 files changed, 315 insertions(+), 143 deletions(-) diff --git a/FHEM/14_SD_UT.pm b/FHEM/14_SD_UT.pm index d24dcf63e..dcc2e4f95 100644 --- a/FHEM/14_SD_UT.pm +++ b/FHEM/14_SD_UT.pm @@ -1881,8 +1881,7 @@ sub SD_UT_Parse { } elsif ($state eq '1000') { $state = 'off'; } else { - $state = 'unknown'; - $def = undef; + $state = substr($bitData,20,4); } ### if received data from device _all, set channels A | B | C | D to state and trigger event ### diff --git a/controls_signalduino.txt b/controls_signalduino.txt index 344a45f3f..cd705534f 100644 --- a/controls_signalduino.txt +++ b/controls_signalduino.txt @@ -7,7 +7,7 @@ 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 2023-01-23_21:06:26 13260 FHEM/14_SD_AS.pm UPD 2023-01-01_18:10:40 29419 FHEM/14_SD_BELL.pm -UPD 2023-12-20_09:17:17 198590 FHEM/14_SD_UT.pm +UPD 2023-12-27_11:07:48 198578 FHEM/14_SD_UT.pm UPD 2023-12-31_15:15:49 161715 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 diff --git a/t/FHEM/14_SD_UT/01_attr.t b/t/FHEM/14_SD_UT/01_attr.t index 00402a92e..b0e981a31 100644 --- a/t/FHEM/14_SD_UT/01_attr.t +++ b/t/FHEM/14_SD_UT/01_attr.t @@ -10,8 +10,6 @@ our %attr; InternalTimer(time()+0.4, sub { my $sensorname=shift; - - my $attr = q[repeats]; subtest qq[set $sensorname $attr 1..99] => sub { plan(99); @@ -49,55 +47,255 @@ InternalTimer(time()+0.4, sub { }; $attr = q[model]; - my $v = q[Buttons_five]; - subtest qq[Change module attribute to buttons_five] => sub { - plan(2); - $defs{$sensorname}{lastMSG} = q[010]; - CommandAttr(undef,qq[$sensorname $attr $v]); - isnt($attr{$sensorname}{$attr}, $v, qq[check attribute $attr isnt $v]); - - $defs{$sensorname}{bitMSG} = q[010]; - CommandAttr(undef,qq[$sensorname $attr $v]); + $defs{$sensorname}{lastMSG} = q[010]; + + subtest qq[Change module with hexlength 3 with attribute] => sub { + plan(18); + for my $v (qw(Buttons_five Buttons_six RH787T SA_434_1_mini Unitec_47031 CAME_TOP_432EV TR401 Novy_840029 Novy_840039)) { + $defs{$sensorname}{bitMSG} = undef; + CommandAttr(undef,qq[$sensorname $attr $v]); + isnt($attr{$sensorname}{$attr}, $v, qq[check attribute $attr is not $v]); + + $defs{$sensorname}{bitMSG} = q[111110111110]; + CommandAttr(undef,qq[$sensorname $attr $v]); is($attr{$sensorname}{$attr}, $v, qq[check attribute $attr is $v]); + } }; - $attr = q[model]; - my $v = q[Buttons_six]; - subtest qq[Change module attribute to buttons_six] => sub { - plan(2); +}, 'SD_UT_Test_Buttons_six'); + +InternalTimer(time()+0.41, sub { + my $sensorname=shift; + + my $attr = q[model]; + $defs{$sensorname}{lastMSG} = q[1846A865]; + + subtest qq[Change module with hexlength 8 with attribute] => sub { + plan(8); + for my $v (qw(DC_1961_TG Krinner_LUMIX RCnoName127 RCnoName20)) { $defs{$sensorname}{bitMSG} = undef; CommandAttr(undef,qq[$sensorname $attr $v]); isnt($attr{$sensorname}{$attr}, $v, qq[check attribute $attr is not $v]); - - $defs{$sensorname}{bitMSG} = q[010]; + + $defs{$sensorname}{bitMSG} = q[00011000010001101010100001100101]; CommandAttr(undef,qq[$sensorname $attr $v]); is($attr{$sensorname}{$attr}, $v, qq[check attribute $attr is $v]); + } }; +}, 'SD_UT_Test_hlen8'); + +InternalTimer(time()+0.42, sub { + my $sensorname=shift; + my $attr = q[model]; + $defs{$sensorname}{lastMSG} = q[1846]; -}, 'SD_UT_Test_Buttons_six'); + subtest qq[Change module with hexlength 4 with attribute] => sub { + plan(2); + for my $v (qw(TR60C1)) { + $defs{$sensorname}{bitMSG} = undef; + CommandAttr(undef,qq[$sensorname $attr $v]); + isnt($attr{$sensorname}{$attr}, $v, qq[check attribute $attr is not $v]); -InternalTimer(time()+0.41, sub { + $defs{$sensorname}{bitMSG} = q[0000111110000000]; + CommandAttr(undef,qq[$sensorname $attr $v]); + is($attr{$sensorname}{$attr}, $v, qq[check attribute $attr is $v]); + } + }; + +}, 'SD_UT_Test_hlen4'); + +InternalTimer(time()+0.43, sub { my $sensorname=shift; my $attr = q[model]; - my $v = q[DC_1961_TG]; - subtest qq[Change module attribute to DC_1961_TG] => sub { - plan(2); - $defs{$sensorname}{lastMSG} = q[1846A865]; - CommandAttr(undef,qq[$sensorname $attr $v]); - isnt($attr{$sensorname}{$attr}, $v, qq[check attribute $attr isnt $v]); - - $defs{$sensorname}{bitMSG} = q[010]; - CommandAttr(undef,qq[$sensorname $attr $v]); + $defs{$sensorname}{lastMSG} = q[18469]; + + subtest qq[Change module with hexlength 5 with attribute] => sub { + plan(22); + for my $v (qw(Chilitec_22640 OR28V QUIGG_DMV SF01_01319004 SF01_01319004_Typ2 Tedsen_SKX1xx Tedsen_SKX2xx Tedsen_SKX4xx Tedsen_SKX6xx TR_502MSV BeSmart_S4)) { + $defs{$sensorname}{bitMSG} = undef; + CommandAttr(undef,qq[$sensorname $attr $v]); + isnt($attr{$sensorname}{$attr}, $v, qq[check attribute $attr is not $v]); + + $defs{$sensorname}{bitMSG} = q[10101010100000001000]; + CommandAttr(undef,qq[$sensorname $attr $v]); is($attr{$sensorname}{$attr}, $v, qq[check attribute $attr is $v]); + } + }; + +}, 'SD_UT_Test_hlen5'); + +InternalTimer(time()+0.44, sub { + my $sensorname=shift; + + my $attr = q[model]; + $defs{$sensorname}{lastMSG} = q[16F610]; + + subtest qq[Change module with hexlength 6 with attribute] => sub { + plan(10); + for my $v (qw(CREATE_6601TL HA_HX2 Navaris RCnoName128 TC6861)) { + $defs{$sensorname}{bitMSG} = undef; + CommandAttr(undef,qq[$sensorname $attr $v]); + isnt($attr{$sensorname}{$attr}, $v, qq[check attribute $attr is not $v]); + + $defs{$sensorname}{bitMSG} = q[100001011110111110101010]; + CommandAttr(undef,qq[$sensorname $attr $v]); + is($attr{$sensorname}{$attr}, $v, qq[check attribute $attr is $v]); + } + }; + +}, 'SD_UT_Test_hlen6'); + +InternalTimer(time()+0.44, sub { + my $sensorname=shift; + + my $attr = q[model]; + $defs{$sensorname}{lastMSG} = q[16F610EF0]; + + subtest qq[Change module with hexlength 9 with attribute] => sub { + plan(10); + for my $v (qw(KL_RF01 MD_2003R MD_210R MD_2018R RC_10)) { + $defs{$sensorname}{bitMSG} = undef; + CommandAttr(undef,qq[$sensorname $attr $v]); + isnt($attr{$sensorname}{$attr}, $v, qq[check attribute $attr is not $v]); + + $defs{$sensorname}{bitMSG} = q[000101101111011000010000111011110000]; + CommandAttr(undef,qq[$sensorname $attr $v]); + is($attr{$sensorname}{$attr}, $v, qq[check attribute $attr is $v]); + } + }; + +}, 'SD_UT_Test_hlen9'); + +InternalTimer(time()+0.45, sub { + my $sensorname=shift; + + my $attr = q[model]; + $defs{$sensorname}{lastMSG} = q[DAAB255487]; + + subtest qq[Change module with hexlength 10 with attribute] => sub { + plan(4); + for my $v (qw(BF_301 xavax)) { + $defs{$sensorname}{bitMSG} = undef; + CommandAttr(undef,qq[$sensorname $attr $v]); + isnt($attr{$sensorname}{$attr}, $v, qq[check attribute $attr is not $v]); + + $defs{$sensorname}{bitMSG} = q[1111101011010000100010001000001110100011]; + CommandAttr(undef,qq[$sensorname $attr $v]); + is($attr{$sensorname}{$attr}, $v, qq[check attribute $attr is $v]); + } + }; + +}, 'SD_UT_Test_hlen10'); + +InternalTimer(time()+0.46, sub { + my $sensorname=shift; + + my $attr = q[model]; + $defs{$sensorname}{lastMSG} = q[1846ABCDEF0]; + + subtest qq[Change module with hexlength 11 with attribute] => sub { + plan(4); + for my $v (qw(HSM4 HS1_868_BS)) { + $defs{$sensorname}{bitMSG} = undef; + CommandAttr(undef,qq[$sensorname $attr $v]); + isnt($attr{$sensorname}{$attr}, $v, qq[check attribute $attr is not $v]); + + $defs{$sensorname}{bitMSG} = q[00000000111001101011111010010001000001111100]; + CommandAttr(undef,qq[$sensorname $attr $v]); + is($attr{$sensorname}{$attr}, $v, qq[check attribute $attr is $v]); + } + }; + +}, 'SD_UT_Test_hlen11'); + +InternalTimer(time()+0.47, sub { + my $sensorname=shift; + + my $attr = q[model]; + $defs{$sensorname}{lastMSG} = q[1846ABCDEF0AD]; + + subtest qq[Change module with hexlength 13 with attribute] => sub { + plan(2); + for my $v (qw(Techmar)) { + $defs{$sensorname}{bitMSG} = undef; + CommandAttr(undef,qq[$sensorname $attr $v]); + isnt($attr{$sensorname}{$attr}, $v, qq[check attribute $attr is not $v]); + + $defs{$sensorname}{bitMSG} = q[0111011100001001111101011101111000001001111101100000]; + CommandAttr(undef,qq[$sensorname $attr $v]); + is($attr{$sensorname}{$attr}, $v, qq[check attribute $attr is $v]); + } + }; + +}, 'SD_UT_Test_hlen13'); + +InternalTimer(time()+0.48, sub { + my $sensorname=shift; + + my $attr = q[model]; + $defs{$sensorname}{lastMSG} = q[1846ABCDEF0AD0]; + + subtest qq[Change module with hexlength 14 with attribute] => sub { + plan(2); + for my $v (qw(Visivo)) { + $defs{$sensorname}{bitMSG} = undef; + CommandAttr(undef,qq[$sensorname $attr $v]); + isnt($attr{$sensorname}{$attr}, $v, qq[check attribute $attr is not $v]); + + $defs{$sensorname}{bitMSG} = q[10011111011111011111100000100101000000101001110000010000]; + CommandAttr(undef,qq[$sensorname $attr $v]); + is($attr{$sensorname}{$attr}, $v, qq[check attribute $attr is $v]); + } + }; + +}, 'SD_UT_Test_hlen14'); + +InternalTimer(time()+0.49, sub { + my $sensorname=shift; + + my $attr = q[model]; + $defs{$sensorname}{lastMSG} = q[FFFFFFFFFFFFFFFF]; + + subtest qq[Change module with hexlength 15 with attribute] => sub { + plan(2); + for my $v (qw(LED_XM21_0)) { + $defs{$sensorname}{bitMSG} = undef; + CommandAttr(undef,qq[$sensorname $attr $v]); + isnt($attr{$sensorname}{$attr}, $v, qq[check attribute $attr is not $v]); + + $defs{$sensorname}{bitMSG} = q[1111111111111111111111111111111111111111111111111111111111111111]; + CommandAttr(undef,qq[$sensorname $attr $v]); + is($attr{$sensorname}{$attr}, $v, qq[check attribute $attr is $v]); + } + }; + +}, 'SD_UT_Test_hlen15'); + +InternalTimer(time()+0.50, sub { + my $sensorname=shift; + + my $attr = q[model]; + $defs{$sensorname}{lastMSG} = q[FFFFFFFFFFFFFFFFF]; + + subtest qq[Change module with hexlength 17 with attribute] => sub { + plan(2); + for my $v (qw(AC114_01B)) { + $defs{$sensorname}{bitMSG} = undef; + CommandAttr(undef,qq[$sensorname $attr $v]); + isnt($attr{$sensorname}{$attr}, $v, qq[check attribute $attr is not $v]); + + $defs{$sensorname}{bitMSG} = q[10100011000000000101100001111011000000010000000001000011000101111000]; + CommandAttr(undef,qq[$sensorname $attr $v]); + is($attr{$sensorname}{$attr}, $v, qq[check attribute $attr is $v]); + } }; done_testing(); exit(0); -}, 'SD_UT_Test_TC6861_3DC_1'); - +}, 'SD_UT_Test_hlen17'); 1; \ No newline at end of file diff --git a/t/FHEM/14_SD_UT/01_define.t b/t/FHEM/14_SD_UT/01_define.t index 8a364aeeb..51a8c9353 100644 --- a/t/FHEM/14_SD_UT/01_define.t +++ b/t/FHEM/14_SD_UT/01_define.t @@ -55,6 +55,15 @@ InternalTimer(time()+1, sub { is(IsDevice($sensorname), 0, "check device not created with define"); }; + subtest 'SD_UT - model OR28V wrong address define OR28V_2 SD_UT OR28V 199' => sub { + plan(1); + + my $sensorname=q[OR28V_2]; + my $model=q[OR28V]; + CommandDefine(undef,qq[$sensorname SD_UT $model 199]); + is(IsDevice($sensorname), 0, "check device not created with define"); + }; + subtest 'SD_UT - model OR28V wrong address define OR28V_1 SD_UT OR28V 17' => sub { plan(1); @@ -63,7 +72,7 @@ InternalTimer(time()+1, sub { CommandDefine(undef,qq[$sensorname SD_UT $model 17]); is(IsDevice($sensorname), 0, "check device not created with define"); }; - + done_testing(); exit(0); diff --git a/t/FHEM/14_SD_UT/03_set.t b/t/FHEM/14_SD_UT/03_set.t index 3fd649a2b..1ae84f134 100644 --- a/t/FHEM/14_SD_UT/03_set.t +++ b/t/FHEM/14_SD_UT/03_set.t @@ -89,6 +89,16 @@ my $module = basename (dirname(__FILE__)); returnCheck => F(), subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P68#01011101100010000000#R5' }; etc() } } } , }, + { + targetName => q[SD_UT_Test_OR28V_2], + testname => q[set command volume_minus], + cmd => q[set volume_minus], + prep_commands => [ # Any FHEM custom command can be placed in here, which will be called before the test is run + 'setreading $targetName state volume_minus', + ], + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P68#01101101100010000001#R5' }; etc() } } } , + }, { targetName => q[SD_UT_Test_Chilitec_22640_AA80], testname => q[set command power_on], diff --git a/t/FHEM/14_SD_UT/fhem.cfg b/t/FHEM/14_SD_UT/fhem.cfg index 3f4f6192e..b4b36359e 100644 --- a/t/FHEM/14_SD_UT/fhem.cfg +++ b/t/FHEM/14_SD_UT/fhem.cfg @@ -1,126 +1,59 @@ define dummyDuino SIGNALduino none attr dummyDuino dummy 1 +define SD_UT_Test_AC114_01B_00587B SD_UT AC114_01B 00587B +define SD_UT_Test_BF_301_FAD0 SD_UT BF_301 FAD0 +define SD_UT_Test_BeSmart_S4_534 SD_UT BeSmart_S4 534 +define SD_UT_Test_Buttons_five_E SD_UT Buttons_five E define SD_UT_Test_Buttons_six SD_UT Buttons_six E -attr SD_UT_Test_Buttons_six model Buttons_six - -define SD_UT_Test_RCnoName20_10 SD_UT RCnoName20_10 3E00 - -define SD_UT_Test_OR28V_1 SD_UT OR28V 1 -attr SD_UT_Test_OR28V_1 model OR28V - +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 -attr SD_UT_Test_Chilitec_22640_AA80 model Chilitec_22640 - define SD_UT_Test_DC_1961_TG_1846 SD_UT DC_1961_TG 1846 -attr SD_UT_Test_DC_1961_TG_1846 model DC_1961_TG - -define SD_UT_Test_Visivo_7DF825 SD_UT Visivo 7DF825 -attr SD_UT_Test_Visivo_7DF825 model Visivo - -define SD_UT_Test_xavax_DAAB SD_UT xavax DAAB -attr SD_UT_Test_xavax_DAAB model xavax - -define SD_UT_Test_Buttons_five_E SD_UT Buttons_five E -attr SD_UT_Test_Buttons_five_E model Buttons_five - -define SD_UT_Test_QUIGG_DMV_891 SD_UT QUIGG_DMV 891 -attr SD_UT_Test_QUIGG_DMV_891 model QUIGG_DMV - -define SD_UT_Test_TR_502MSV_FFF SD_UT TR_502MSV FFF -attr SD_UT_Test_TR_502MSV_FFF model TR_502MSV - -define SD_UT_Test_Tedsen_SKX1xx_F1FF11F SD_UT Tedsen_SKX1xx F1FF11F -attr SD_UT_Test_Tedsen_SKX1xx_F1FF11F model Tedsen_SKX1xx - -define SD_UT_Test_Tedsen_SKX2xx_1F10110 SD_UT Tedsen_SKX2xx 1F10110 -attr SD_UT_Test_Tedsen_SKX2xx_1F10110 model Tedsen_SKX2xx - -define SD_UT_Test_Tedsen_SKX6xx_1F10FF0 SD_UT Tedsen_SKX6xx 1F10FF0 -attr SD_UT_Test_Tedsen_SKX6xx_1F10FF0 model Tedsen_SKX6xx - -define SD_UT_Test_AC114_01B_00587B SD_UT AC114_01B 00587B -attr SD_UT_Test_AC114_01B_00587B model AC114_01B - +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 -attr SD_UT_Test_HS1_868_BS_F62A9C01C model HS1_868_BS - define SD_UT_Test_HSM4_E6BE910 SD_UT HSM4 E6BE910 -attr SD_UT_Test_HSM4_E6BE910 model HSM4 - +define SD_UT_Test_KL_RF01_16F6 SD_UT KL_RF01 16F6 +define SD_UT_Test_Krinner_LUMIX_A06C360 SD_UT Krinner_LUMIX A06C360 +define SD_UT_Test_Krinner_LUMIX_A06C360_UTfrequency SD_UT Krinner_LUMIX A06C360 define SD_UT_Test_LED_XM21_0_FFFFFFFFFFFFFF SD_UT LED_XM21_0 FFFFFFFFFFFFFF -attr SD_UT_Test_LED_XM21_0_FFFFFFFFFFFFFF model LED_XM21_0 - -define SD_UT_Test_BeSmart_S4_534 SD_UT BeSmart_S4 534 -attr SD_UT_Test_BeSmart_S4_534 model BeSmart_S4 - -define SD_UT_Test_SA_434_1_mini_604 SD_UT SA_434_1_mini 604 -attr SD_UT_Test_SA_434_1_mini_604 model SA_434_1_mini - -define SD_UT_Test_RH787T_0 SD_UT RH787T 0 -attr SD_UT_Test_RH787T_0 model RH787T - -define SD_UT_Test_CAME_TOP_432EV_EE SD_UT CAME_TOP_432EV EE -attr SD_UT_Test_CAME_TOP_432EV_EE model CAME_TOP_432EV - +define SD_UT_Test_Meikee_24_20D3 SD_UT Meikee_24 20D3 +define SD_UT_Test_Momento_0000064 SD_UT Momento 0000064 +define SD_UT_Test_Navaris_211073 SD_UT Navaris 211073 define SD_UT_Test_Novy_840029_55 SD_UT Novy_840029 55 -attr SD_UT_Test_Novy_840029_55 model Novy_840029 - define SD_UT_Test_Novy_840039_55 SD_UT Novy_840039 55 -attr SD_UT_Test_Novy_840039_55 model Novy_840039 - -define SD_UT_Test_SF01_01319004_A150 SD_UT SF01_01319004 A150 -attr SD_UT_Test_SF01_01319004_A150 model SF01_01319004 - -define SD_UT_Test_SF01_01319004_Typ2_2638 SD_UT SF01_01319004_Typ2 2638 -attr SD_UT_Test_SF01_01319004_Typ2_2638 model SF01_01319004_Typ2 - +define SD_UT_Test_OR28V_1 SD_UT OR28V 1 +define SD_UT_Test_OR28V_2 SD_UT OR28V 2 +define SD_UT_Test_QUIGG_DMV_891 SD_UT QUIGG_DMV 891 define SD_UT_Test_RC_10_7869_A SD_UT RC_10 7869_A -attr SD_UT_Test_RC_10_7869_A model RC_10 - define SD_UT_Test_RC_10_7869_all SD_UT RC_10 7869_all -attr SD_UT_Test_RC_10_7869_all model RC_10 - -define SD_UT_Test_Krinner_LUMIX_A06C360 SD_UT Krinner_LUMIX A06C360 -attr SD_UT_Test_Krinner_LUMIX_A06C360 model Krinner_LUMIX - -define SD_UT_Test_Krinner_LUMIX_A06C360_UTfrequency SD_UT Krinner_LUMIX A06C360 -attr SD_UT_Test_Krinner_LUMIX_A06C360_UTfrequency model Krinner_LUMIX - -define SD_UT_Test_KL_RF01_16F6 SD_UT KL_RF01 16F6 -attr SD_UT_Test_KL_RF01_16F6 model KL_RF01 - -define SD_UT_Test_Techmar_7709F5DE SD_UT Techmar 7709F5DE -attr SD_UT_Test_Techmar_7709F5DE model Techmar - -define SD_UT_Test_Momento_0000064 SD_UT Momento 0000064 -attr SD_UT_Test_Momento_0000064 model Momento - -define SD_UT_Test_Navaris_211073 SD_UT Navaris 211073 -attr SD_UT_Test_Navaris_211073 model Navaris - +define SD_UT_Test_RCnoName127_3603A SD_UT RCnoName127 3603A +define SD_UT_Test_RCnoName128_8A7F SD_UT RCnoName128 8A7F +define SD_UT_Test_RCnoName20_10 SD_UT RCnoName20_10 3E00 +define SD_UT_Test_RH787T_0 SD_UT RH787T 0 +define SD_UT_Test_SA_434_1_mini_604 SD_UT SA_434_1_mini 604 +define SD_UT_Test_SF01_01319004_A150 SD_UT SF01_01319004 A150 +define SD_UT_Test_SF01_01319004_Typ2_2638 SD_UT SF01_01319004_Typ2 2638 +define SD_UT_Test_TC6861_3DC_1 SD_UT TC6861 3DC_1 +define SD_UT_Test_TR401_0_2 SD_UT TR401 0_2 define SD_UT_Test_TR60C1_0 SD_UT TR60C1 0 -attr SD_UT_Test_TR60C1_0 model TR60C1 - define SD_UT_Test_TR60C1_0_2 SD_UT TR60C1 0 -attr SD_UT_Test_TR60C1_0_2 model TR60C1 - -define SD_UT_Test_BF_301_FAD0 SD_UT BF_301 FAD0 -attr SD_UT_Test_BF_301_FAD0 model BF_301 - -define SD_UT_Test_TR401_0_2 SD_UT TR401 0_2 -attr SD_UT_Test_TR401_0_2 model TR401 - -define SD_UT_Test_Meikee_24_20D3 SD_UT Meikee_24 20D3 -attr SD_UT_Test_Meikee_24_20D3 model Meikee_24 - -define SD_UT_Test_TC6861_3DC_1 SD_UT TC6861 3DC_1 - -define SD_UT_Test_RCnoName127_3603A SD_UT RCnoName127 3603A -attr SD_UT_Test_RCnoName127_3603A model RCnoName127 +define SD_UT_Test_TR_502MSV_FFF SD_UT TR_502MSV FFF +define SD_UT_Test_Techmar_7709F5DE SD_UT Techmar 7709F5DE +define SD_UT_Test_Tedsen_SKX1xx_F1FF11F SD_UT Tedsen_SKX1xx F1FF11F +define SD_UT_Test_Tedsen_SKX2xx_1F10110 SD_UT Tedsen_SKX2xx 1F10110 +define SD_UT_Test_Tedsen_SKX6xx_1F10FF0 SD_UT Tedsen_SKX6xx 1F10FF0 +define SD_UT_Test_Visivo_7DF825 SD_UT Visivo 7DF825 +define SD_UT_Test_xavax_DAAB SD_UT xavax DAAB -define SD_UT_Test_RCnoName128_8A7F SD_UT RCnoName128 8A7F -attr SD_UT_Test_RCnoName128_8A7F model RCnoName128 -define SD_UT_Test_HA_HX2_85EF SD_UT HA_HX2 85EF -attr SD_UT_Test_HA_HX2_85EF model HA_HX2 +define SD_UT_Test_hlen4 SD_UT unknown +define SD_UT_Test_hlen5 SD_UT unknown +define SD_UT_Test_hlen6 SD_UT unknown +define SD_UT_Test_hlen8 SD_UT unknown +define SD_UT_Test_hlen9 SD_UT unknown +define SD_UT_Test_hlen10 SD_UT unknown +define SD_UT_Test_hlen11 SD_UT unknown +define SD_UT_Test_hlen13 SD_UT unknown +define SD_UT_Test_hlen14 SD_UT unknown +define SD_UT_Test_hlen15 SD_UT unknown +define SD_UT_Test_hlen17 SD_UT unknown diff --git a/t/FHEM/14_SD_UT/testData.json b/t/FHEM/14_SD_UT/testData.json index ead55ce08..a99a4d7df 100644 --- a/t/FHEM/14_SD_UT/testData.json +++ b/t/FHEM/14_SD_UT/testData.json @@ -1527,6 +1527,29 @@ "comment" : "#3" } ] + }, + { + "comment" : "button all / state unknown", + "dmsg" : "P90#786909230", + "internals" : { + "DEF" : "RC_10 7869_all", + "NAME" : "RC_10_7869_all" + }, + "readings" : { + "LastAction" : "receive", + "deviceCode" : "0111100001101001", + "state" : "1001", + "x_n4" : "0000" + }, + "rmsg" : "MS;P1=-363;P2=789;P3=267;P4=-887;P5=-10332;D=35342121212134343434212134213434213434343421343421343421343434212134;CP=3;SP=5;O;m2;4;", + "tests" : [ + { + "attributes" : { + "model" : "RC_10" + }, + "comment" : "#4" + } + ] } ], "id" : "90", From 0f23255f9785278bf2cc784091e27fdb480dd786 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Tue, 2 Jan 2024 22:02:04 +0000 Subject: [PATCH 40/55] Automatic updated controls and CHANGED --- CHANGED | 3 +++ controls_signalduino.txt | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGED b/CHANGED index ef6318d4c..7ab1214f4 100644 --- a/CHANGED +++ b/CHANGED @@ -1,3 +1,6 @@ +2024-01-02 - Update tests part two | for the functional reliability of the module SD_UT (#1218) + +* added some tests for define and attr 2023-12-31 - new sensor BRESSER PM2.5/10 air quality meter (#1219) * Bresser PM2.5/10 air quality meter diff --git a/controls_signalduino.txt b/controls_signalduino.txt index cd705534f..3e21b081a 100644 --- a/controls_signalduino.txt +++ b/controls_signalduino.txt @@ -7,7 +7,7 @@ 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 2023-01-23_21:06:26 13260 FHEM/14_SD_AS.pm UPD 2023-01-01_18:10:40 29419 FHEM/14_SD_BELL.pm -UPD 2023-12-27_11:07:48 198578 FHEM/14_SD_UT.pm +UPD 2024-01-02_23:01:30 198578 FHEM/14_SD_UT.pm UPD 2023-12-31_15:15:49 161715 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 From bbaabf8f0c2b28952494f1500b5df079fcfb96f4 Mon Sep 17 00:00:00 2001 From: sidey79 <7968127+sidey79@users.noreply.github.com> Date: Wed, 3 Jan 2024 09:06:30 +0100 Subject: [PATCH 41/55] Call debug via a coderef if enabled, otherwise return (#1169) * 00_SIGNALduino.pm added coderef for debug output$hash->{debugMethod} --- FHEM/00_SIGNALduino.pm | 113 +++++++++--------- controls_signalduino.txt | 2 +- t/FHEM/00_SIGNALduino/01_SIGNALduino_Attr.t | 63 ++++++++++ .../01_SIGNALduino_PatternExists.t | 10 +- 4 files changed, 127 insertions(+), 61 deletions(-) diff --git a/FHEM/00_SIGNALduino.pm b/FHEM/00_SIGNALduino.pm index b2655c1b4..522a873d6 100644 --- a/FHEM/00_SIGNALduino.pm +++ b/FHEM/00_SIGNALduino.pm @@ -1,4 +1,4 @@ -# $Id: 00_SIGNALduino.pm 3.5.6 2023-12-14 17:16:35Z sidey79 $ +# $Id: 00_SIGNALduino.pm 3.5.6 2024-01-02 22:22:14Z 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 @@ -392,9 +392,9 @@ sub SIGNALduino_Define { my $dev = $a[2]; - #Debug "dev: $dev" if ($debug); + #$hash->{debugMethod}->(qq[dev: $dev]); #my $hardware=AttrVal($name,'hardware','nano'); - #Debug "hardware: $hardware" if ($debug); + #$hash->{debugMethod}->(qq[hardware: $hardware]); if($dev eq 'none') { Log3 $name, 1, "$name: Define, device is none, commands will be echoed only"; @@ -419,7 +419,8 @@ sub SIGNALduino_Define { $hash->{MatchList} = \%matchListSIGNALduino; $hash->{DeviceName} = $dev; $hash->{logMethod} = \&main::Log3; - + $hash->{debugMethod} = sub { return; }; + my $ret=undef; $hash->{protocolObject} = dclone($Protocols); $hash->{protocolObject}->registerLogCallback(SIGNALduino_createLogCallback($hash)); @@ -2025,14 +2026,14 @@ sub SIGNALduino_PatternExists { #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); + $hash->{debugMethod}->(qq[tol: looking for ($searchpattern +- $tol)]); 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); + $hash->{debugMethod}->(qq[index => gap in tol (+- $tol) of pulse ($searchpattern) : ].Dumper(\%pattern_gap)); # Extract fist pattern, which is nearst to our searched value my @closestidx = (sort {$pattern_gap{$a} <=> $pattern_gap{$b}} keys %pattern_gap); @@ -2056,9 +2057,9 @@ sub SIGNALduino_PatternExists { } [[]], @_ } 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); + $hash->{debugMethod}->(q[sumlists is: ].Dumper @sumlist); + $hash->{debugMethod}->(qq[res is: ].Dumper $res[0]); + $hash->{debugMethod}->(qq[indexer is: ].Dumper \@indexer); OUTERLOOP: for my $i (0..$#{$res[0]}) @@ -2077,7 +2078,7 @@ sub SIGNALduino_PatternExists { { $plist{$indexer[$x]} = $res[0][$i][$x]; } - Debug qq[plist is for this check ].Dumper(\%plist) if($debug); + $hash->{debugMethod}->(q[plist is for this check ].Dumper(\%plist)); # Create our searchstring with our mapping table my @patternVariant= @{$search}; @@ -2087,7 +2088,7 @@ sub SIGNALduino_PatternExists { $v = $plist{$v}; #Debug qq[after: $v ] if($debug); } - Debug qq[patternVariant is ].Dumper(\@patternVariant) if($debug); + $hash->{debugMethod}->(q[patternVariant is ].Dumper(\@patternVariant)); my $search_pattern = join '', @patternVariant; (index ($$data, $search_pattern) > -1) ? return $search_pattern : next; @@ -2110,14 +2111,14 @@ sub SIGNALduino_MatchSignalPattern { 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); + #$hash->{debugMethod}->(qq[ $idx check: ".$patternList->{$data_array->[$idx]}.]); + $hash->{debugMethod}->(qq[$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); + $hash->{debugMethod}->(qq[$name: Error index ($idx) does not exist!!]); return -1; } @@ -2148,11 +2149,12 @@ sub SIGNALduino_Split_Message { my $freqafc; ## for AFC cc1101 0x32 (0xF2): FREQEST – Frequency Offset Estimate from Demodulator my @msg_parts = SIGNALduino_splitMsg($rmsg,';'); ## Split message parts by ';' my %ret; - my $debug = AttrVal($name,'debug',0); + my $hash = $defs{$name}; + my $debug = AttrVal($hash->{NAME},'debug',0); foreach (@msg_parts) { - #Debug "$name: checking msg part:( $_ )" if ($debug); + #$hash->{debugMethod}->(qq[$name: checking msg part:( $_ )]); #if ($_ =~ m/^MS/ or $_ =~ m/^MC/ or $_ =~ m/^Mc/ or $_ =~ m/^MU/) #### Synced Message start if ($_ =~ m/^M./) @@ -2166,51 +2168,51 @@ sub SIGNALduino_Split_Message { my @pattern = split(/=/,$_); $patternList{$pattern[0]} = $pattern[1]; - Debug "$name: extracted pattern @pattern \n" if ($debug); + $hash->{debugMethod}->(qq[$name: extracted pattern @pattern \n]); } elsif($_ =~ m/D=\d+/ or $_ =~ m/^D=[A-F0-9]+/) #### Message from array { $_ =~ s/D=//; $rawData = $_ ; - Debug "$name: extracted data $rawData\n" if ($debug); + $hash->{debugMethod}->(qq[$name: extracted data $rawData\n]); $ret{rawData} = $rawData; } elsif($_ =~ m/^SP=([0-9])$/) #### Sync Pulse Index { - Debug "$name: extracted syncidx $1\n" if ($debug); + $hash->{debugMethod}->(qq[$name: extracted syncidx $1\n]); #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);; + $hash->{debugMethod}->(qq[$name: extracted clockidx $1\n]); $ret{clockidx} = $1; } elsif($_ =~ m/^L=\d/) #### MC bit length { (undef, $mcbitnum) = split(/=/,$_); - Debug "$name: extracted number of $mcbitnum bits\n" if ($debug);; + $hash->{debugMethod}->(qq[$name: extracted number of $mcbitnum bits\n]); $ret{mcbitnum} = $mcbitnum; } elsif($_ =~ m/^C=\d+/) #### Message from array { $_ =~ s/C=//; $clockabs = $_ ; - Debug "$name: extracted absolute clock $clockabs \n" if ($debug); + $hash->{debugMethod}->(qq[$name: extracted absolute clock $clockabs \n]); $ret{clockabs} = $clockabs; } elsif($_ =~ m/^R=\d+/) #### RSSI { $_ =~ s/R=//; $rssi = $_ ; - Debug "$name: extracted RSSI $rssi \n" if ($debug); + $hash->{debugMethod}->(qq[$name: extracted RSSI $rssi \n]); $ret{rssi} = $rssi; } elsif ($_ =~ m/A=(-?[0-9]{0,3})/ ){ # uncoverable branch true Debug qq[$name: extracted FREQEST $1 \n] if ($debug); $ret{freqest} = $1; } else { - Debug "$name: unknown Message part $_" if ($debug);; + $hash->{debugMethod}->(qq[$name: unknown Message part $_]); } #print "$_\n"; } @@ -2310,7 +2312,7 @@ sub SIGNALduino_moduleMatch { my $modMatchRegex=$hash->{protocolObject}->checkProperty($id,'modulematch',undef); if (!defined($modMatchRegex) || $dmsg =~ m/$modMatchRegex/) { - Debug "$name: modmatch passed for: $dmsg" if ($debug); + $hash->{debugMethod}->(qq[$name: modmatch passed for: $dmsg]); 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 @@ -2401,19 +2403,19 @@ sub SIGNALduino_Parse_MS { IDLOOP: foreach my $id (@{$hash->{msIdList}}) { - Debug qq[Testing against protocol id $id -> ].$hash->{protocolObject}->getProperty($id,'name') if ($debug); + $hash->{debugMethod}->(qq[Testing against protocol id $id -> ].$hash->{protocolObject}->getProperty($id,'name')); # 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); + $hash->{debugMethod}->(q[protocClock=].$hash->{protocolObject}->getProperty($id,'clockabs').qq[, msgClock=$clockabs is not in tol=].$clockabs*0.30); next; } elsif ($debug) { - Debug qq[protocClock=].$hash->{protocolObject}->getProperty($id,'clockabs').qq[, msgClock=$clockabs is in tol="] . $clockabs*0.30; + $hash->{debugMethod}->(q[protocClock=].$hash->{protocolObject}->getProperty($id,'clockabs').qq[, msgClock=$clockabs is in tol="] . $clockabs*0.30); } } - Debug 'Searching in patternList: '.Dumper(\%patternList) if($debug); + $hash->{debugMethod}->(q[Searching in patternList: ].Dumper(\%patternList)); my %patternLookupHash=(); my %endPatternLookupHash=(); @@ -2425,7 +2427,7 @@ sub SIGNALduino_Parse_MS { 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); + $hash->{debugMethod}->(sprintf("%s pattern not found",$key)); next IDLOOP if ($key ne 'float') ; } @@ -2434,13 +2436,13 @@ sub SIGNALduino_Parse_MS { $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); + $hash->{debugMethod}->(qq[bit_length=$bit_length to short]); next IDLOOP; } - Debug "expecting $bit_length bits in signal" if ($debug); + $hash->{debugMethod}->(qq[expecting $bit_length bits in signal]); %endPatternLookupHash=(); } - Debug sprintf("Found matched %s with indexes: (%s)",$key,$return_text) if ($debug); + $hash->{debugMethod}->(sprintf("Found matched %s with indexes: (%s)",$key,$return_text)); } next if (scalar keys %patternLookupHash == 0); # Keine Eingträge im patternLookupHash @@ -2472,13 +2474,13 @@ sub SIGNALduino_Parse_MS { } } - Debug "$name: decoded message raw (@bit_msg), ".@bit_msg." bits\n" if ($debug); + $hash->{debugMethod}->(qq[$name: decoded message raw (@bit_msg), ".@bit_msg." bits\n]); #Check converted message against lengths my ($rcode, $rtxt) = $hash->{protocolObject}->LengthInRange($id,scalar @bit_msg); if (!$rcode) { - Debug "$name: decoded $rtxt" if ($debug); + $hash->{debugMethod}->(qq[$name: decoded $rtxt]); next; } my $padwith = $hash->{protocolObject}->checkProperty($id,'paddingbits',4); @@ -2489,7 +2491,7 @@ sub SIGNALduino_Parse_MS { push(@bit_msg,'0'); $i++; } - Debug "$name padded $i bits to bit_msg array" if ($debug); + $hash->{debugMethod}->(qq[$name padded $i bits to bit_msg array]); if ($i == 0) { $hash->{logMethod}->($name, 5, "$name: Parse_MS, dispatching bits: @bit_msg"); @@ -2581,7 +2583,7 @@ sub SIGNALduino_Parse_MU { my $message_dispatched=0; my $debug = AttrVal($hash->{NAME},'debug',0); - Debug "$name: processing unsynced message\n" if ($debug); + $hash->{debugMethod}->(qq[$name: processing unsynced message\n]); my $clockabs = 1; #Clock will be fetched from protocol if possible $patternListRaw{$_} = $msg_parts{pattern}{$_} for keys %{$msg_parts{pattern}}; @@ -2618,8 +2620,8 @@ sub SIGNALduino_Parse_MU { %patternList = map { $_ => FHEM::Core::Utils::Math::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); + $hash->{debugMethod}->(qq[Testing against protocol id $id -> ]. $hash->{protocolObject}->getProperty($id,'name')); + $hash->{debugMethod}->(qq[Searching in patternList: ].Dumper(\%patternList)); my $startStr=''; # Default match if there is no start pattern available my $message_start=0 ; @@ -2627,24 +2629,24 @@ sub SIGNALduino_Parse_MU { 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); + $hash->{debugMethod}->('msgStartLst: '.Dumper(\@{$hash->{protocolObject}->getProperty($id,'start')})); 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); + $hash->{debugMethod}->(qq[startStr is: $startStr]); $message_start = index($rawData, $startStr); if ( $message_start == -1) { - Debug "startStr $startStr not found." if ($debug); + $hash->{debugMethod}->(qq[startStr $startStr not found.]); 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); + $hash->{debugMethod}->(qq[rawData = $rawData]); + $hash->{debugMethod}->(qq[startStr $startStr found. Message starts at $message_start]); #SIGNALduino_Log3 $name, 5, "$name: Parse_MU, substr: $rawData"; # todo: entfernen } } @@ -2662,10 +2664,10 @@ sub SIGNALduino_Parse_MU { 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); + $hash->{debugMethod}->(sprintf("%s pattern not found",$key)); next IDLOOP if ($key ne "float"); } - Debug sprintf("Found matched %s with indexes: (%s)",$key,$return_text) if ($debug); + $hash->{debugMethod}->(sprintf("Found matched %s with indexes: (%s)",$key,$return_text)); if ($key eq "one") { $signalRegex .= $return_text; @@ -2687,7 +2689,7 @@ sub SIGNALduino_Parse_MU { if (defined($hash->{protocolObject}->getProperty($id,'reconstructBit'))) { $signalRegex .= '(?:' . join('|',keys %endPatternLookupHash) . ')?'; } - Debug "signalRegex is $signalRegex " if ($debug); + $hash->{debugMethod}->(qq[signalRegex is $signalRegex ]); my $nrRestart=0; my $nrDispatch=0; @@ -2725,7 +2727,7 @@ sub SIGNALduino_Parse_MU { } } - Debug "$name: demodulated message raw (@bit_msg), ".@bit_msg." bits\n" if ($debug); + $hash->{debugMethod}->(qq[$name: demodulated message raw (@bit_msg), ".@bit_msg." bits\n]); 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); @@ -2741,7 +2743,7 @@ sub SIGNALduino_Parse_MU { 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); + $hash->{debugMethod}->(qq[$name: padding 0 bit to bit_msg array]); } my $dmsg = join ('', @bit_msg); my $bit_length=scalar @bit_msg; @@ -2815,7 +2817,7 @@ sub SIGNALduino_Parse_MC { my $debug = AttrVal($hash->{NAME},'debug',0); - Debug "$name: processing manchester messag len:".length($rawData) if ($debug); + $hash->{debugMethod}->("$name: processing manchester messag len:".length($rawData)); my $hlen = length($rawData); my $blen; @@ -2835,13 +2837,13 @@ sub SIGNALduino_Parse_MC { 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); + $hash->{debugMethod}->(qq[clock and min length matched]); (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')); my $polarityInvert = ( $hash->{protocolObject}->checkProperty($id,'polarity','') eq 'invert' ) ? 1 : 0; - Debug "$name: polarityInvert=$polarityInvert" if ($debug); + $hash->{debugMethod}->(qq[$name: polarityInvert=$polarityInvert]); if ( $messagetype eq 'Mc' || ( defined $hash->{version} && substr $hash->{version},0,6 eq 'V 3.2.') ) { @@ -2852,7 +2854,7 @@ sub SIGNALduino_Parse_MC { ? unpack("B$blen", pack("H$hlen", $rawDataInverted)) : unpack("B$blen", pack("H$hlen", $rawData)); - Debug "$name: extracted data $bitData (bin)\n" if ($debug); ## Convert Message from hex to bits + $hash->{debugMethod}->(qq[$name: extracted data $bitData (bin)\n]); ## Convert Message from hex to bits $hash->{logMethod}->($name, 5, "$name: Parse_MC, extracted data $bitData (bin)"); my $method = $hash->{protocolObject}->getProperty($id,'method'); @@ -2993,7 +2995,7 @@ sub SIGNALduino_Parse { my $debug = AttrVal($iohash->{NAME},'debug',0); - Debug "$name: incoming message: ($rmsg)\n" if ($debug); + $hash->{debugMethod}->(qq[$name: incoming message: ($rmsg)\n]); if (AttrVal($name, 'rawmsgEvent', 0)) { DoTrigger($name, 'RAWMSG ' . $rmsg); @@ -3024,7 +3026,7 @@ sub SIGNALduino_Parse { $dispatched= SIGNALduino_Parse_MN($hash, $rmsg); } else { - Debug "$name: unknown Messageformat, aborting\n" if ($debug); + $hash->{debugMethod}->(qq[$name: unknown Messageformat, aborting\n]); return ; } @@ -3140,6 +3142,7 @@ sub SIGNALduino_Attr { elsif ($aName eq 'debug') { $debug = $aVal; + $hash->{debugMethod} = ($cmd eq 'set' && $aVal == 1) ? \&main::Debug : sub { return; }; $hash->{logMethod}->($name, 3, "$name: Attr, setting debug to: " . $debug); } ## Change whitelist_IDs diff --git a/controls_signalduino.txt b/controls_signalduino.txt index 3e21b081a..4eae8f51a 100644 --- a/controls_signalduino.txt +++ b/controls_signalduino.txt @@ -1,4 +1,4 @@ -UPD 2023-12-31_15:15:49 239695 FHEM/00_SIGNALduino.pm +UPD 2024-01-02_23:21:53 240267 FHEM/00_SIGNALduino.pm UPD 2023-01-06_12:08:43 20082 FHEM/10_FS10.pm UPD 2023-01-09_20:47:40 25008 FHEM/10_SD_GT.pm UPD 2023-01-01_18:10:40 25403 FHEM/10_SD_Rojaflex.pm diff --git a/t/FHEM/00_SIGNALduino/01_SIGNALduino_Attr.t b/t/FHEM/00_SIGNALduino/01_SIGNALduino_Attr.t index 65c571262..b36529210 100644 --- a/t/FHEM/00_SIGNALduino/01_SIGNALduino_Attr.t +++ b/t/FHEM/00_SIGNALduino/01_SIGNALduino_Attr.t @@ -4,6 +4,7 @@ use warnings; use Test2::V0; use Test2::Tools::Compare qw{is field U D match hash bag }; +use Test2::Tools::Ref; use Mock::Sub; use Test2::Todo; @@ -201,6 +202,68 @@ my @mockData = ( }, rValue => U(), }, + { + cmd => q[set], + deviceName => q[cc1101dummyDuino], + plan => 3, + testname => q[set debug 1], + input => qq[debug 1], + attrCheck => hash { + field debug => T(); + etc(); + }, + hashCheck => hash { + field debugMethod => \&main::Debug; + etc(); + }, + rValue => U(), + }, + { + cmd => q[set], + deviceName => q[cc1101dummyDuino], + plan => 4, + testname => q[set debug 0], + input => qq[debug 0], + attrCheck => hash { + field debug => F(); + etc(); + }, + hashCheck => hash { + field debugMethod => validator(sub { + my %params = @_; + my $got = $params{got}; + return 1 if ( $params{exists} && ref_is_not($got,\&main::Debug) ); + return 1; + } + ); + etc(); + }, + rValue => U(), + }, + { + cmd => q[del], + deviceName => q[cc1101dummyDuino], + plan => 4, + testname => q[del debug ], + input => qq[debug], + pre_code => sub { + CommandAttr(undef, qq[cc1101dummyDuino debug 1]); + }, + attrCheck => hash { + etc(); + }, + hashCheck => hash { + field debugMethod => validator(sub { + my %params = @_; + my $got = $params{got}; + return 1 if ( $params{exists} && ref_is_not($got,\&main::Debug) ); + return 0; + } + ); + etc(); + }, + rValue => U(), + }, ); plan (scalar @mockData + 2); diff --git a/t/FHEM/00_SIGNALduino/01_SIGNALduino_PatternExists.t b/t/FHEM/00_SIGNALduino/01_SIGNALduino_PatternExists.t index 853622687..8dcb0da1a 100644 --- a/t/FHEM/00_SIGNALduino/01_SIGNALduino_PatternExists.t +++ b/t/FHEM/00_SIGNALduino/01_SIGNALduino_PatternExists.t @@ -20,7 +20,7 @@ InternalTimer(time(), sub { plan(1); my $rmsg="MU;P0=7944;P1=-724;P2=742;P3=241;P4=-495;P5=483;P6=-248;D=01212121343434345656343434563434345634565656343434565634343434343434345634345634345634343434343434343434345634565634345656345634343456563421212121343434345656343434563434345634565656343434565634343434343434345634345634345634343434343434343434345634565634;CP=3;R=47;"; - my %msg_parts = SIGNALduino_Split_Message($rmsg, $targetHash); + my %msg_parts = SIGNALduino_Split_Message($rmsg, $target); my $clockabs= 480; $patternListRaw{$_} = $msg_parts{pattern}{$_} for keys %{$msg_parts{pattern}}; @@ -31,7 +31,7 @@ InternalTimer(time(), sub { plan(1); my $rmsg="MU;P0=740;P1=-2076;P2=381;P3=-4022;P4=-604;P5=152;P6=-1280;P7=-8692;D=012123232321245621212121232123232427212323212123232326;CP=2;R=228;"; - my %msg_parts = SIGNALduino_Split_Message($rmsg, $targetHash); + my %msg_parts = SIGNALduino_Split_Message($rmsg, $target); my $clockabs= 480; $patternListRaw{$_} = $msg_parts{pattern}{$_} for keys %{$msg_parts{pattern}}; @@ -42,7 +42,7 @@ InternalTimer(time(), sub { plan(1); my $rmsg="MU;P0=-2076;P1=479;P2=-963;P3=-492;P4=-22652;D=01213121213121212131313121313131312121313131313121212121313131212131313131313131313121313121313131313131313131312131212121313121412131212121212131213121213121212131313121313131312121313131313121212121313131212131313131313131313121313121313131313131313131;CP=1;R=26;O;"; - my %msg_parts = SIGNALduino_Split_Message($rmsg, $targetHash); + my %msg_parts = SIGNALduino_Split_Message($rmsg, $target); my $clockabs= 480; $patternListRaw{$_} = $msg_parts{pattern}{$_} for keys %{$msg_parts{pattern}}; @@ -54,7 +54,7 @@ InternalTimer(time(), sub { plan(3); my $rmsg="MU;P0=7944;P1=-724;P2=742;P3=241;P4=-495;P5=483;P6=-248;D=01212121343434345656343434563434345634565656343434565634343434343434345634345634345634343434343434343434345634565634345656345634343456563421212121343434345656343434563434345634565656343434565634343434343434345634345634345634343434343434343434345634565634;CP=3;R=47;"; - my %msg_parts = SIGNALduino_Split_Message($rmsg, $targetHash); + my %msg_parts = SIGNALduino_Split_Message($rmsg, $target); my $clockabs= 250; $patternListRaw{$_} = $msg_parts{pattern}{$_} for keys %{$msg_parts{pattern}}; @@ -69,7 +69,7 @@ InternalTimer(time(), sub { plan(3); my $rmsg="MU;P0=-9524;P1=364;P2=-414;P3=669;P4=-755;P5=-16076;CP=1;R=83;D=0123412341234123412341412341414141412351234123412341234123414123414141414123;e;w=0;"; - my %msg_parts = SIGNALduino_Split_Message($rmsg, $targetHash); + my %msg_parts = SIGNALduino_Split_Message($rmsg, $target); my $clockabs= 350; $patternListRaw{$_} = $msg_parts{pattern}{$_} for keys %{$msg_parts{pattern}}; From 2aa9529a58e25e0000d4fdd8b61ef01834d00ebc Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Wed, 3 Jan 2024 08:07:03 +0000 Subject: [PATCH 42/55] Automatic updated controls and CHANGED --- CHANGED | 5 +++++ controls_signalduino.txt | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGED b/CHANGED index 7ab1214f4..63556fe82 100644 --- a/CHANGED +++ b/CHANGED @@ -1,3 +1,8 @@ +2024-01-03 - Call debug via a coderef if enabled, otherwise return (#1169) + +* 00_SIGNALduino.pm + +added coderef for debug output$hash->{debugMethod} 2024-01-02 - Update tests part two | for the functional reliability of the module SD_UT (#1218) * added some tests for define and attr diff --git a/controls_signalduino.txt b/controls_signalduino.txt index 4eae8f51a..33e688709 100644 --- a/controls_signalduino.txt +++ b/controls_signalduino.txt @@ -1,4 +1,4 @@ -UPD 2024-01-02_23:21:53 240267 FHEM/00_SIGNALduino.pm +UPD 2024-01-03_09:06:30 240267 FHEM/00_SIGNALduino.pm UPD 2023-01-06_12:08:43 20082 FHEM/10_FS10.pm UPD 2023-01-09_20:47:40 25008 FHEM/10_SD_GT.pm UPD 2023-01-01_18:10:40 25403 FHEM/10_SD_Rojaflex.pm From 1be59b7d2944df9ecf2412e942c37eaa62986662 Mon Sep 17 00:00:00 2001 From: HomeAutoUser Date: Wed, 3 Jan 2024 23:05:39 +0100 Subject: [PATCH 43/55] little fix 10_SD_GT and added tests (#1223) * Update 10_SD_GT.pm - replace tabs with spaces (no module restrictions) - fix META versionssupport - fix PERL WARNING - added tests - revised SVN numbre - remove old Internals VERSION_SD_GT - added Meta version --- FHEM/10_SD_GT.pm | 1080 ++++++++++++++++++----------------- controls_signalduino.txt | 2 +- t/FHEM/10_SD_GT/01_define.t | 36 ++ t/FHEM/10_SD_GT/03_set.t | 65 +++ t/FHEM/10_SD_GT/fhem.cfg | 4 +- 5 files changed, 647 insertions(+), 540 deletions(-) create mode 100644 t/FHEM/10_SD_GT/01_define.t create mode 100644 t/FHEM/10_SD_GT/03_set.t diff --git a/FHEM/10_SD_GT.pm b/FHEM/10_SD_GT.pm index 36f6c5a6a..6e51bf16f 100644 --- a/FHEM/10_SD_GT.pm +++ b/FHEM/10_SD_GT.pm @@ -1,11 +1,11 @@ ################################################################# -# $Id: 10_SD_GT.pm 26985 2023-01-06 12:07:45Z sidey79 $ +# $Id: 10_SD_GT.pm 27957 2024-01-03 12:07:45Z sidey79 $ # # The file is part of the SIGNALduino project. +# The purpose of this module is to support remote controls with QUIGG Gt-9000 protocol (based on code quigg_gt9000.c from pilight) +# +# 2019- - HomeAuto_User & elektron-bbs & sidey79 # -# 2019 - HomeAuto_User & elektron-bbs -# for remote controls using protocol QUIGG Gt-9000 -# based on code quigg_gt9000.c from pilight ################################################################# package SD_GT; @@ -15,44 +15,42 @@ use warnings; use GPUtils qw(GP_Import GP_Export); use FHEM::Meta; -our $VERSION = '1.1'; - # Export to main context with different name GP_Export(qw( - Initialize - ) + Initialize + ) ); ## Import der FHEM Funktionen BEGIN { - GP_Import(qw( - AssignIoPort - AttrVal - attr - defs - DoTrigger - IOWrite - IsIgnored - Log3 - modules - ReadingsVal - readingsBeginUpdate - readingsBulkUpdate - readingsEndUpdate - readingsSingleUpdate - )) + GP_Import(qw( + AssignIoPort + AttrVal + attr + defs + DoTrigger + IOWrite + IsIgnored + Log3 + modules + ReadingsVal + readingsBeginUpdate + readingsBulkUpdate + readingsEndUpdate + readingsSingleUpdate + )) }; sub Initialize { - my ($hash) = @_; - $hash->{DefFn} = \&Define; - $hash->{UndefFn} = \&Undef; - $hash->{SetFn} = \&Set; - $hash->{ParseFn} = \&Parse; - $hash->{Match} = '^P49#[A-Fa-f0-9]+'; - $hash->{AttrList} = "IODev repeats:1,2,3,4,5,6,7,8,9,12,15 showtime:0,1 disableSetAllFunction:0,1 do_not_notify:0,1 ignore:0,1 showtime:0,1 $main::readingFnAttributes"; - $hash->{AutoCreate} = {'SD_GT_LEARN' => {FILTER => '%NAME', autocreateThreshold => '5:180', GPLOT => q{}}}; - return FHEM::Meta::InitMod( __FILE__, $hash ); + my ($hash) = @_; + $hash->{DefFn} = \&Define; + $hash->{UndefFn} = \&Undef; + $hash->{SetFn} = \&Set; + $hash->{ParseFn} = \&Parse; + $hash->{Match} = '^P49#[A-Fa-f0-9]+'; + $hash->{AttrList} = "IODev repeats:1,2,3,4,5,6,7,8,9,12,15 showtime:0,1 disableSetAllFunction:0,1 do_not_notify:0,1 ignore:0,1 showtime:0,1 $main::readingFnAttributes"; + $hash->{AutoCreate} = {'SD_GT_LEARN' => {FILTER => '%NAME', autocreateThreshold => '5:180', GPLOT => q{}}}; + return FHEM::Meta::InitMod( __FILE__, $hash ); } sub parseSystemcodeHex; @@ -61,407 +59,412 @@ sub checkVersion; sub getSystemCodes; my %buttons = ( - '1' => { # Version 1 - 'hash' => [0x0, 0x9, 0xF, 0x4, 0xA, 0xD, 0x5, 0xB, 0x3, 0x2, 0x1, 0x7, 0xE, 0x6, 0xC, 0x8], - 'C' => { # unit C - 'unit' => 'A', - '1' => 'on', - '5' => 'on', - '6' => 'on', - 'A' => 'on', - '2' => 'off', - '7' => 'off', - '8' => 'off', - 'B' => 'off', + '1' => { # Version 1 + 'hash' => [0x0, 0x9, 0xF, 0x4, 0xA, 0xD, 0x5, 0xB, 0x3, 0x2, 0x1, 0x7, 0xE, 0x6, 0xC, 0x8], + 'C' => { # unit C + 'unit' => 'A', + '1' => 'on', + '5' => 'on', + '6' => 'on', + 'A' => 'on', + '2' => 'off', + '7' => 'off', + '8' => 'off', + 'B' => 'off', }, - '5' => { # unit 5 - 'unit' => 'B', - '0' => 'on', - '3' => 'on', - 'E' => 'on', - 'F' => 'on', - '4' => 'off', - '9' => 'off', - 'C' => 'off', - 'D' => 'off', + '5' => { # unit 5 + 'unit' => 'B', + '0' => 'on', + '3' => 'on', + 'E' => 'on', + 'F' => 'on', + '4' => 'off', + '9' => 'off', + 'C' => 'off', + 'D' => 'off', }, - 'E' => { # unit 5 - 'unit' => 'C', - '2' => 'on', - '7' => 'on', - '8' => 'on', - 'B' => 'on', - '1' => 'off', - '5' => 'off', - '6' => 'off', - 'A' => 'off', + 'E' => { # unit 5 + 'unit' => 'C', + '2' => 'on', + '7' => 'on', + '8' => 'on', + 'B' => 'on', + '1' => 'off', + '5' => 'off', + '6' => 'off', + 'A' => 'off', }, - '7' => { # unit 7 - 'unit' => 'D', - '4' => 'on', - '9' => 'on', - 'C' => 'on', - 'D' => 'on', - '0' => 'off', - '3' => 'off', - 'E' => 'off', - 'F' => 'off', + '7' => { # unit 7 + 'unit' => 'D', + '4' => 'on', + '9' => 'on', + 'C' => 'on', + 'D' => 'on', + '0' => 'off', + '3' => 'off', + 'E' => 'off', + 'F' => 'off', }, - '2' => { # unit 2 - 'unit' => 'all', - '2' => 'on', - '7' => 'on', - '8' => 'on', - 'B' => 'on', - '1' => 'off', - '5' => 'off', - '6' => 'off', - 'A' => 'off', + '2' => { # unit 2 + 'unit' => 'all', + '2' => 'on', + '7' => 'on', + '8' => 'on', + 'B' => 'on', + '1' => 'off', + '5' => 'off', + '6' => 'off', + 'A' => 'off', }, - }, - '2' => { # Version 2 - 'hash' => [0x0, 0x9, 0x5, 0xF, 0x3, 0x6, 0xC, 0x7, 0xE, 0xD, 0x1, 0xB, 0x2, 0xA, 0x4, 0x8], - '0' => { # unit 0 - 'unit' => 'A', - '3' => 'on', - '4' => 'on', - '7' => 'on', - 'B' => 'on', - '1' => 'off', - '2' => 'off', - '9' => 'off', - 'A' => 'off', + }, + '2' => { # Version 2 + 'hash' => [0x0, 0x9, 0x5, 0xF, 0x3, 0x6, 0xC, 0x7, 0xE, 0xD, 0x1, 0xB, 0x2, 0xA, 0x4, 0x8], + '0' => { # unit 0 + 'unit' => 'A', + '3' => 'on', + '4' => 'on', + '7' => 'on', + 'B' => 'on', + '1' => 'off', + '2' => 'off', + '9' => 'off', + 'A' => 'off', }, - '4' => { # unit 4 - 'unit' => 'B', - '3' => 'on', - '4' => 'on', - '7' => 'on', - 'B' => 'on', - '1' => 'off', - '2' => 'off', - '9' => 'off', - 'A' => 'off', + '4' => { # unit 4 + 'unit' => 'B', + '3' => 'on', + '4' => 'on', + '7' => 'on', + 'B' => 'on', + '1' => 'off', + '2' => 'off', + '9' => 'off', + 'A' => 'off', }, - 'C' => { # unit C - 'unit' => 'C', - '3' => 'on', - '4' => 'on', - '7' => 'on', - 'B' => 'on', - '1' => 'off', - '2' => 'off', - '9' => 'off', - 'A' => 'off', + 'C' => { # unit C + 'unit' => 'C', + '3' => 'on', + '4' => 'on', + '7' => 'on', + 'B' => 'on', + '1' => 'off', + '2' => 'off', + '9' => 'off', + 'A' => 'off', }, - '2' => { # unit 2 - 'unit' => 'D', - '1' => 'on', - '2' => 'on', - '9' => 'on', - 'A' => 'on', - '3' => 'off', - '4' => 'off', - '7' => 'off', - 'B' => 'off', + '2' => { # unit 2 + 'unit' => 'D', + '1' => 'on', + '2' => 'on', + '9' => 'on', + 'A' => 'on', + '3' => 'off', + '4' => 'off', + '7' => 'off', + 'B' => 'off', }, - 'A' => { # unit A - 'unit' => 'all', - '1' => 'on', - '2' => 'on', - '9' => 'on', - 'A' => 'on', - '3' => 'off', - '4' => 'off', - '7' => 'off', - 'B' => 'off', + 'A' => { # unit A + 'unit' => 'all', + '1' => 'on', + '2' => 'on', + '9' => 'on', + 'A' => 'on', + '3' => 'off', + '4' => 'off', + '7' => 'off', + 'B' => 'off', }, - } + } ); sub Define { - my ($hash, $def) = @_; - my @a = split m{\s+}xms , $def; - my $name = $hash->{NAME}; - my $iodevice; - my $ioname; - - if( @a < 3 ) { return 'SD_GT: wrong syntax for define, must be: define SD_GT ' }; - - $hash->{DEF} = $a[2]; - if ($a[3]) { $iodevice = $a[3] } - if ($a[4]) { readingsSingleUpdate($hash,'SystemCode',$a[4],1) } - if ($a[5]) { readingsSingleUpdate($hash,'Version',$a[5],1) } - $hash->{VersionModule} = $VERSION; - - $modules{SD_GT}{defptr}{$hash->{DEF}} = $hash; - if (exists $modules{SD_GT}{defptr}{ioname} && !$iodevice) { $ioname = $modules{SD_GT}{defptr}{ioname} }; - if (not $iodevice) { $iodevice = $ioname } - - AssignIoPort($hash, $iodevice); - return; + my ($hash, $def) = @_; + my @a = split m{\s+}xms , $def; + my $name = $hash->{NAME}; + my $iodevice; + my $ioname; + + # Anzeigen der Modulversion (Internal FVERSION) über FHEM::Meta, Variable in META.json Abschnitt erforderlich: "version": "v1.0.0", siehe https://wiki.fhem.de/wiki/Meta + return $@ unless ( FHEM::Meta::SetInternals($hash) ); + + if( @a < 3 ) { return 'SD_GT: wrong syntax for define, must be: define SD_GT ' }; + + $hash->{DEF} = $a[2]; + if ($a[3]) { $iodevice = $a[3] } + if ($a[4]) { readingsSingleUpdate($hash,'SystemCode',$a[4],1) } + if ($a[5]) { readingsSingleUpdate($hash,'Version',$a[5],1) } + + $modules{SD_GT}{defptr}{$hash->{DEF}} = $hash; + if (exists $modules{SD_GT}{defptr}{ioname} && !$iodevice) { $ioname = $modules{SD_GT}{defptr}{ioname} }; + if (not $iodevice) { $iodevice = $ioname } + + AssignIoPort($hash, $iodevice); + return; } sub Set { - my ($hash, $name, $cmd, @a) = @_; - my $ioname = $hash->{IODev}{NAME}; - my $repeats = AttrVal($name,'repeats', '5'); - my $ret = undef; - my $EMPTY = q{}; - - if (not defined $cmd) { return "The command \"set $name\" requires at least one of the arguments: \"on\" or \"off\"" }; - - if ($cmd eq q{?}) { - if ($hash->{DEF} ne 'LEARN') { - if (ReadingsVal($name, 'CodesOff', $EMPTY) ne $EMPTY) { $ret .= 'off:noArg ' }; - if (ReadingsVal($name, 'CodesOn', $EMPTY) ne $EMPTY) { $ret .= 'on:noArg ' }; - } - return $ret; - } - - my $sendCodesStr; - my @sendCodesAr; - my $sendCodesCnt; - my $sendCode = ReadingsVal($name, 'SendCode', $EMPTY); # load last sendCode - if ($cmd eq 'on') { $sendCodesStr = ReadingsVal($name, 'CodesOn', $EMPTY) }; - if ($cmd eq 'off') { $sendCodesStr = ReadingsVal($name, 'CodesOff', $EMPTY) }; - @sendCodesAr = split /[,]/xms , $sendCodesStr; - $sendCodesCnt = scalar @sendCodesAr; - if ($sendCodesCnt < 1) { return "$name: No codes available for sending, please press buttons on your remote for learning." }; - my ($index) = grep { $sendCodesAr[$_] eq $sendCode } (0 .. $sendCodesCnt - 1); - if (not defined $index) { $index = -1 }; - $index++; - if ($index >= $sendCodesCnt) { $index = 0 }; - $sendCode = $sendCodesAr[$index]; # new sendCode - - Log3 $name, 3, "$ioname: SD_GT set $name $cmd"; - Log3 $name, 4, "$ioname: SD_GT_Set $name $cmd ($sendCodesCnt codes $sendCodesStr - send $sendCode)"; - - if ($hash->{DEF} =~ /_all$/xms && AttrVal($name,'disableSetAllFunction', 0) == 0) { # send button all - my $systemCode = ReadingsVal($name, 'SystemCode', $EMPTY); - foreach my $d (keys %defs) { # sucht angelegte SD_GT mit gleichem Sytemcode - if(defined($defs{$d}) && $defs{$d}{TYPE} eq 'SD_GT' && $defs{$d}{DEF} =~ /$systemCode/xms && $defs{$d}{DEF} =~ /[ABCD]$/xms && ReadingsVal($d, 'state', $EMPTY) ne $cmd) { - readingsSingleUpdate($defs{$d}, 'state' , $cmd , 1); - Log3 $name, 3, "$ioname: SD_GT set $d $cmd"; - } - } - } - - my $msg = 'P49#0x' . $sendCode . '#R' . $repeats; - Log3 $name, 5, "$ioname: $name SD_GT_Set first set sendMsg $msg"; - IOWrite($hash, 'sendMsg', $msg); - $msg = 'P49.1#0x' . $sendCode . '#R' . $repeats; - Log3 $name, 5, "$ioname: $name SD_GT_Set second set sendMsg $msg"; - IOWrite($hash, 'sendMsg', $msg); - - readingsBeginUpdate($hash); - readingsBulkUpdate($hash, 'state', $cmd); - readingsBulkUpdate($hash, 'SendCode', $sendCode, 0); - readingsEndUpdate($hash, 1); - return $ret; + my ($hash, $name, $cmd, @a) = @_; + my $ioname = $hash->{IODev}{NAME}; + my $repeats = AttrVal($name,'repeats', '5'); + my $ret = undef; + my $EMPTY = q{}; + + if (not defined $cmd) { return "The command \"set $name\" requires at least one of the arguments: \"on\" or \"off\"" }; + + if ($cmd eq q{?}) { + if ($hash->{DEF} ne 'LEARN') { + if (ReadingsVal($name, 'CodesOff', $EMPTY) ne $EMPTY) { $ret .= 'off:noArg ' }; + if (ReadingsVal($name, 'CodesOn', $EMPTY) ne $EMPTY) { $ret .= 'on:noArg ' }; + } + return $ret; + } + + my $sendCodesStr; + my @sendCodesAr; + my $sendCodesCnt; + my $sendCode = ReadingsVal($name, 'SendCode', $EMPTY); # load last sendCode + if ($cmd eq 'on') { $sendCodesStr = ReadingsVal($name, 'CodesOn', $EMPTY) }; + if ($cmd eq 'off') { $sendCodesStr = ReadingsVal($name, 'CodesOff', $EMPTY) }; + @sendCodesAr = split /[,]/xms , $sendCodesStr; + $sendCodesCnt = scalar @sendCodesAr; + if ($sendCodesCnt < 1) { return "$name: No codes available for sending, please press buttons on your remote for learning." }; + my ($index) = grep { $sendCodesAr[$_] eq $sendCode } (0 .. $sendCodesCnt - 1); + if (not defined $index) { $index = -1 }; + $index++; + if ($index >= $sendCodesCnt) { $index = 0 }; + $sendCode = $sendCodesAr[$index]; # new sendCode + + Log3 $name, 3, "$ioname: SD_GT set $name $cmd"; + Log3 $name, 4, "$ioname: SD_GT_Set $name $cmd ($sendCodesCnt codes $sendCodesStr - send $sendCode)"; + + if ($hash->{DEF} =~ /_all$/xms && AttrVal($name,'disableSetAllFunction', 0) == 0) { # send button all + my $systemCode = ReadingsVal($name, 'SystemCode', $EMPTY); + foreach my $d (keys %defs) { # sucht angelegte SD_GT mit gleichem Sytemcode + if(defined($defs{$d}) && $defs{$d}{TYPE} eq 'SD_GT' && $defs{$d}{DEF} =~ /$systemCode/xms && $defs{$d}{DEF} =~ /[ABCD]$/xms && ReadingsVal($d, 'state', $EMPTY) ne $cmd) { + readingsSingleUpdate($defs{$d}, 'state' , $cmd , 1); + Log3 $name, 3, "$ioname: SD_GT set $d $cmd"; + } + } + } + + my $msg = 'P49#0x' . $sendCode . '#R' . $repeats; + Log3 $name, 5, "$ioname: $name SD_GT_Set first set sendMsg $msg"; + IOWrite($hash, 'sendMsg', $msg); + $msg = 'P49.1#0x' . $sendCode . '#R' . $repeats; + Log3 $name, 5, "$ioname: $name SD_GT_Set second set sendMsg $msg"; + IOWrite($hash, 'sendMsg', $msg); + + readingsBeginUpdate($hash); + readingsBulkUpdate($hash, 'state', $cmd); + readingsBulkUpdate($hash, 'SendCode', $sendCode, 0); + readingsEndUpdate($hash, 1); + return $ret; } sub Undef { - my ($hash, $name) = @_; - if(defined($hash->{DEF}) && defined($modules{SD_GT}{defptr}{$hash->{DEF}})) {delete($modules{SD_GT}{defptr}{$hash->{DEF}}) }; - return; + my ($hash, $name) = @_; + if(defined($hash->{DEF}) && defined($modules{SD_GT}{defptr}{$hash->{DEF}})) {delete($modules{SD_GT}{defptr}{$hash->{DEF}}) }; + return; } sub Parse { - my ($iohash, $msg) = @_; - my $ioname = $iohash->{NAME}; - my ($protocol,$rawData) = split /[#]/xms , $msg; - my $devicedef; - my $version = 0; - my $systemCode = 0; - my $level; # A, B, C, D or all - my $state; - my $EMPTY = q{}; - - my ($systemCode1, $systemCode2) = getSystemCodes($rawData); - Log3 $ioname, 4, "$ioname: SD_GT_Parse $rawData, possible codes version 1 $systemCode1 or version 2 $systemCode2"; - - # sucht Version und SytemCode in bereits angelegten SD_GT - foreach my $d (keys %defs) { - if($defs{$d}{TYPE} eq 'SD_GT' && defined $defs{$d}) { - $version = ReadingsVal($d, 'Version', 0) ; - $systemCode = ReadingsVal($d, 'SystemCode', 0); - Log3 $iohash, 4, "$ioname: SD_GT_Parse found $d, version $version, systemCode $systemCode"; - last if ($systemCode1 eq $systemCode && $version == 1); - last if ($systemCode2 eq $systemCode && $version == 2); - } - $version = 0; # reset version - $systemCode = 0; # reset systemCode - } - Log3 $ioname, 4, "$ioname: SD_GT_Parse $rawData, found version $version with systemCode $systemCode"; - - if ($version == 0 && $systemCode eq '0') { # Version und systemCode nicht gefunden - $devicedef = 'LEARN'; - } else { # Version und systemCode gefunden - my $statecode = substr $rawData,4,1; - my $unit = substr $rawData,5,1; - $state = $buttons{$version}->{$unit}->{$statecode}; - $level = $buttons{$version}->{$unit}->{'unit'}; - $devicedef = $systemCode . '_' . $level; - Log3 $ioname, 4, "$ioname: SD_GT_Parse code $rawData, device $devicedef"; - } - - my $def = $modules{SD_GT}{defptr}{$devicedef}; - $modules{SD_GT}{defptr}{ioname} = $ioname; - if(!$def) { - Log3 $ioname, 1, "$ioname: SD_GT_Parse UNDEFINED SD_GT_$devicedef device detected"; - return "UNDEFINED SD_GT_$devicedef SD_GT $devicedef"; - } - my $hash = $def; - my $name = $hash->{NAME}; - if (IsIgnored($name)) { return $EMPTY }; - - my $learnCodesStr; - my @learnCodesAr; - my $learnCodesCnt; - - if ($devicedef eq 'LEARN') { - $learnCodesStr = ReadingsVal($name, 'LearnCodes', $EMPTY ); - @learnCodesAr = split /[,]/xms , $learnCodesStr; - $learnCodesCnt = scalar @learnCodesAr; - Log3 $name, 3, "$ioname: $name $rawData, $learnCodesCnt learned codes $learnCodesStr"; - if ($learnCodesCnt == 0) { # erster Code empfangen - push @learnCodesAr, $rawData ; - $learnCodesCnt++; - Log3 $name, 3, "$ioname: $name code $rawData is first plausible code"; - } elsif (grep {/$rawData/xms} @learnCodesAr) { # Code schon vorhanden - $state = 'code already registered, please press another button'; - Log3 $name, 3, "$ioname: $name code $rawData already registered ($learnCodesStr)"; - } else { # Code pruefen und evtl. uebernehmen - push @learnCodesAr, $rawData; - ($version, $systemCode) = checkVersion(@learnCodesAr); - if ($version == 0) { # Fehler Version oder Systemcode - if ($learnCodesCnt == 1) { - @learnCodesAr = (); - $systemCode = 0; - } else { - pop @learnCodesAr; # Wir entfernen das letzte Element des Arrays - } - $state = 'version not unique, please press another button'; - Log3 $name, 3, "$ioname: $name ERROR - version not unique"; - } else { # Version und Code OK - $learnCodesCnt++; - Log3 $name, 3, "$ioname: $name code $learnCodesCnt $rawData, version $version, systemCode $systemCode"; - } - } - if (not defined $state) { $state = "learned code $learnCodesCnt, please press another button" }; - } - - if ($state eq 'on') { - $learnCodesStr = ReadingsVal($name, 'CodesOn', $EMPTY); - @learnCodesAr = split /[,]/xms , $learnCodesStr; - if (not grep {/$rawData/xms} @learnCodesAr) { push @learnCodesAr, $rawData }; - } - if ($state eq 'off') { - $learnCodesStr = ReadingsVal($name, 'CodesOff', $EMPTY); - @learnCodesAr = split /[,]/xms , $learnCodesStr; - if (not grep {/$rawData/xms} @learnCodesAr) { push @learnCodesAr, $rawData }; - } - - if (defined $level) { Log3 $name, 4, "$ioname: SD_GT_Parse code $rawData, $name, button $level $state" }; - - if (defined $level && $level eq 'all' && AttrVal($name,'disableSetAllFunction', 0) == 0) { # received button all - foreach my $d (keys %defs) { # sucht angelegte SD_GT mit gleichem Sytemcode - if(defined($defs{$d}) && $defs{$d}{TYPE} eq 'SD_GT' && $defs{$d}{DEF} =~ /$systemCode/xms && $defs{$d}{DEF} =~ /[ABCD]$/xms && ReadingsVal($d, 'state', $EMPTY) ne $state) { - readingsSingleUpdate($defs{$d}, 'state' , $state , 1); - DoTrigger($d, undef, 0); - Log3 $name, 4, "$ioname: SD_GT_Parse received button $level, set $d $state"; - } - } - } - - $learnCodesStr = join q{,} , @learnCodesAr; - my $systemCodeDec = hex $systemCode; - - readingsBeginUpdate($hash); - readingsBulkUpdate($hash, 'state', $state); - if ($devicedef eq 'LEARN') { readingsBulkUpdate($hash, 'LearnCodes', $learnCodesStr) }; - if ($state eq 'on') { readingsBulkUpdate($hash, 'CodesOn', $learnCodesStr, 0) }; - if ($state eq 'off') { readingsBulkUpdate($hash, 'CodesOff', $learnCodesStr, 0) }; - if ($devicedef ne 'LEARN' || $learnCodesCnt > 5) { - if ($version != 0) { readingsBulkUpdate($hash, 'Version', $version, 0) }; - if ($systemCode ne '0') { readingsBulkUpdate($hash, 'SystemCode', $systemCode, 0) }; - if ($systemCodeDec != 0) { readingsBulkUpdate($hash, 'SystemCodeDec', $systemCodeDec, 0) }; - } - readingsEndUpdate($hash, 1); - return $name; + my ($iohash, $msg) = @_; + my $ioname = $iohash->{NAME}; + my ($protocol,$rawData) = split /[#]/xms , $msg; + my $devicedef; + my $version = 0; + my $systemCode = 0; + my $level; # A, B, C, D or all + my $state; + my $EMPTY = q{}; + + my ($systemCode1, $systemCode2) = getSystemCodes($rawData); + Log3 $ioname, 4, "$ioname: SD_GT_Parse $rawData, possible codes version 1 $systemCode1 or version 2 $systemCode2"; + + # sucht Version und SytemCode in bereits angelegten SD_GT + foreach my $d (keys %defs) { + if($defs{$d}{TYPE} eq 'SD_GT' && defined $defs{$d}) { + $version = ReadingsVal($d, 'Version', 0) ; + $systemCode = ReadingsVal($d, 'SystemCode', 0); + Log3 $iohash, 4, "$ioname: SD_GT_Parse found $d, version $version, systemCode $systemCode"; + last if ($systemCode1 eq $systemCode && $version == 1); + last if ($systemCode2 eq $systemCode && $version == 2); + } + $version = 0; # reset version + $systemCode = 0; # reset systemCode + } + Log3 $ioname, 4, "$ioname: SD_GT_Parse $rawData, found version $version with systemCode $systemCode"; + + if ($version == 0 && $systemCode eq '0') { # Version und systemCode nicht gefunden + $devicedef = 'LEARN'; + } else { # Version und systemCode gefunden + my $statecode = substr $rawData,4,1; + my $unit = substr $rawData,5,1; + $state = $buttons{$version}->{$unit}->{$statecode}; + $level = $buttons{$version}->{$unit}->{'unit'}; + $devicedef = $systemCode . '_' . $level; + Log3 $ioname, 4, "$ioname: SD_GT_Parse code $rawData, device $devicedef"; + } + + my $def = $modules{SD_GT}{defptr}{$devicedef}; + $modules{SD_GT}{defptr}{ioname} = $ioname; + if(!$def) { + Log3 $ioname, 1, "$ioname: SD_GT_Parse UNDEFINED SD_GT_$devicedef device detected"; + return "UNDEFINED SD_GT_$devicedef SD_GT $devicedef"; + } + my $hash = $def; + my $name = $hash->{NAME}; + if (IsIgnored($name)) { return $EMPTY }; + + my $learnCodesStr; + my @learnCodesAr; + my $learnCodesCnt; + + if ($devicedef eq 'LEARN') { + $learnCodesStr = ReadingsVal($name, 'LearnCodes', $EMPTY ); + @learnCodesAr = split /[,]/xms , $learnCodesStr; + $learnCodesCnt = scalar @learnCodesAr; + Log3 $name, 3, "$ioname: $name $rawData, $learnCodesCnt learned codes $learnCodesStr"; + if ($learnCodesCnt == 0) { # erster Code empfangen + push @learnCodesAr, $rawData ; + $learnCodesCnt++; + Log3 $name, 3, "$ioname: $name code $rawData is first plausible code"; + } elsif (grep {/$rawData/xms} @learnCodesAr) { # Code schon vorhanden + $state = 'code already registered, please press another button'; + Log3 $name, 3, "$ioname: $name code $rawData already registered ($learnCodesStr)"; + } else { # Code pruefen und evtl. uebernehmen + push @learnCodesAr, $rawData; + ($version, $systemCode) = checkVersion(@learnCodesAr); + if ($version == 0) { # Fehler Version oder Systemcode + if ($learnCodesCnt == 1) { + @learnCodesAr = (); + $systemCode = 0; + } else { + pop @learnCodesAr; # Wir entfernen das letzte Element des Arrays + } + $state = 'version not unique, please press another button'; + Log3 $name, 3, "$ioname: $name ERROR - version not unique"; + } else { # Version und Code OK + $learnCodesCnt++; + Log3 $name, 3, "$ioname: $name code $learnCodesCnt $rawData, version $version, systemCode $systemCode"; + } + } + if (not defined $state) { $state = "learned code $learnCodesCnt, please press another button" }; + } + + ### additional test from state, as sometimes the state is unknown when receiving --> PEARL WARNING: Interception + if (not defined $state) { $state = "status unknown, please press another button" }; + + if ($state eq 'on') { + $learnCodesStr = ReadingsVal($name, 'CodesOn', $EMPTY); + @learnCodesAr = split /[,]/xms , $learnCodesStr; + if (not grep {/$rawData/xms} @learnCodesAr) { push @learnCodesAr, $rawData }; + } + if ($state eq 'off') { + $learnCodesStr = ReadingsVal($name, 'CodesOff', $EMPTY); + @learnCodesAr = split /[,]/xms , $learnCodesStr; + if (not grep {/$rawData/xms} @learnCodesAr) { push @learnCodesAr, $rawData }; + } + + if (defined $level) { Log3 $name, 4, "$ioname: SD_GT_Parse code $rawData, $name, button $level $state" }; + + if (defined $level && $level eq 'all' && AttrVal($name,'disableSetAllFunction', 0) == 0) { # received button all + foreach my $d (keys %defs) { # sucht angelegte SD_GT mit gleichem Sytemcode + if(defined($defs{$d}) && $defs{$d}{TYPE} eq 'SD_GT' && $defs{$d}{DEF} =~ /$systemCode/xms && $defs{$d}{DEF} =~ /[ABCD]$/xms && ReadingsVal($d, 'state', $EMPTY) ne $state) { + readingsSingleUpdate($defs{$d}, 'state' , $state , 1); + DoTrigger($d, undef, 0); + Log3 $name, 4, "$ioname: SD_GT_Parse received button $level, set $d $state"; + } + } + } + + $learnCodesStr = join q{,} , @learnCodesAr; + my $systemCodeDec = hex $systemCode; + + readingsBeginUpdate($hash); + readingsBulkUpdate($hash, 'state', $state); + if ($devicedef eq 'LEARN') { readingsBulkUpdate($hash, 'LearnCodes', $learnCodesStr) }; + if ($state eq 'on') { readingsBulkUpdate($hash, 'CodesOn', $learnCodesStr, 0) }; + if ($state eq 'off') { readingsBulkUpdate($hash, 'CodesOff', $learnCodesStr, 0) }; + if ($devicedef ne 'LEARN' || $learnCodesCnt > 5) { + if ($version != 0) { readingsBulkUpdate($hash, 'Version', $version, 0) }; + if ($systemCode ne '0') { readingsBulkUpdate($hash, 'SystemCode', $systemCode, 0) }; + if ($systemCodeDec != 0) { readingsBulkUpdate($hash, 'SystemCodeDec', $systemCodeDec, 0) }; + } + readingsEndUpdate($hash, 1); + return $name; } sub parseSystemcodeHex { - my $rawData = shift; - my $version = shift; - my $systemCode1dec = hex substr $rawData,0,1; - my $systemCode2enc = hex substr $rawData,1,1; - my $systemCode2dec = 0; # calculate all codes with base syscode2 = 0 - my $systemCode3enc = hex substr $rawData,2,1; - my $systemCode3dec = decodePayload($systemCode3enc, $systemCode2enc, $systemCode1dec, $version); - my $systemCode4enc = hex substr $rawData,3,1; - my $systemCode4dec = decodePayload($systemCode4enc, $systemCode3enc, $systemCode1dec, $version); - my $systemCode5enc = hex substr $rawData,4,1; - my $systemCode5dec = decodePayload($systemCode5enc, $systemCode4enc, $systemCode1dec, $version); - my $systemCode = ($systemCode1dec<<16) + ($systemCode2dec<<12) + ($systemCode3dec<<8) + ($systemCode4dec<<4) + $systemCode5dec; - my $systemCodeHex = sprintf '%X', $systemCode; - return $systemCodeHex; + my $rawData = shift; + my $version = shift; + my $systemCode1dec = hex substr $rawData,0,1; + my $systemCode2enc = hex substr $rawData,1,1; + my $systemCode2dec = 0; # calculate all codes with base syscode2 = 0 + my $systemCode3enc = hex substr $rawData,2,1; + my $systemCode3dec = decodePayload($systemCode3enc, $systemCode2enc, $systemCode1dec, $version); + my $systemCode4enc = hex substr $rawData,3,1; + my $systemCode4dec = decodePayload($systemCode4enc, $systemCode3enc, $systemCode1dec, $version); + my $systemCode5enc = hex substr $rawData,4,1; + my $systemCode5dec = decodePayload($systemCode5enc, $systemCode4enc, $systemCode1dec, $version); + my $systemCode = ($systemCode1dec<<16) + ($systemCode2dec<<12) + ($systemCode3dec<<8) + ($systemCode4dec<<4) + $systemCode5dec; + my $systemCodeHex = sprintf '%X', $systemCode; + return $systemCodeHex; } sub checkVersion { - my (@rawData) = @_; - my $anzahl = scalar @rawData; - my $x = 0; - my @codes; - my $systemCode = q{}; - my $version = 1; - while ($x < $anzahl) { - $systemCode = parseSystemcodeHex($rawData[$x], $version); - if ( not grep {/$systemCode/xms} @codes) { - push @codes, $systemCode; - } - $x++; - } - $anzahl = scalar @codes; - $x = 0; - if ($anzahl > 1) { - $version = 2; - @codes =(); - while ($x < $anzahl) { - $systemCode = parseSystemcodeHex($rawData[$x], $version); - if ( not grep {/$systemCode/xms} @codes) { - push @codes, $systemCode; - } - $x++; - } - $anzahl = scalar @codes; - } - if ($anzahl > 1) { # keine eindeutige Version erkannt - $version = 0; - $systemCode = 0; - } - return ($version, $systemCode); + my (@rawData) = @_; + my $anzahl = scalar @rawData; + my $x = 0; + my @codes; + my $systemCode = q{}; + my $version = 1; + while ($x < $anzahl) { + $systemCode = parseSystemcodeHex($rawData[$x], $version); + if ( not grep {/$systemCode/xms} @codes) { + push @codes, $systemCode; + } + $x++; + } + $anzahl = scalar @codes; + $x = 0; + if ($anzahl > 1) { + $version = 2; + @codes =(); + while ($x < $anzahl) { + $systemCode = parseSystemcodeHex($rawData[$x], $version); + if ( not grep {/$systemCode/xms} @codes) { + push @codes, $systemCode; + } + $x++; + } + $anzahl = scalar @codes; + } + if ($anzahl > 1) { # keine eindeutige Version erkannt + $version = 0; + $systemCode = 0; + } + return ($version, $systemCode); } sub decodePayload { - my $payload = shift; - my $index = shift; - my $syscodetype = shift; - my $version = shift; - my $ret = -1; - if ($version >= 1) { - my @gt9000_hash = @{ $buttons{$version}->{'hash'} }; - $ret = int($payload) ^ int($gt9000_hash[$index]); - } - return $ret; + my $payload = shift; + my $index = shift; + my $syscodetype = shift; + my $version = shift; + my $ret = -1; + if ($version >= 1) { + my @gt9000_hash = @{ $buttons{$version}->{'hash'} }; + $ret = int($payload) ^ int($gt9000_hash[$index]); + } + return $ret; } sub getSystemCodes { - my ($rawData) = shift; - my $systemCode1 = parseSystemcodeHex($rawData, 1); - my $systemCode2 = parseSystemcodeHex($rawData, 2); - return ($systemCode1, $systemCode2); + my ($rawData) = shift; + my $systemCode1 = parseSystemcodeHex($rawData, 1); + my $systemCode2 = parseSystemcodeHex($rawData, 2); + return ($systemCode1, $systemCode2); } 1; @@ -476,75 +479,75 @@ sub getSystemCodes {

          SD_GT

            - The SD_GT module decodes and sends messages using the GT-9000 protocol. - This protocol is used by a variety of remote controls, which are traded under different names. - The messages are received and sent by a SIGNALduino. -

            - The following models are currently known that use this protocol: -

            -
              -
            • EASY HOME RCT DS1 CR-A 3725
            • -
            • Globaltronics GT-3000, GT-9000
            • -
            • OBI Emil Lux / CMI Art.Nr.: 315606
            • -
            • SilverCrest FSS B 20-A (3726) / 66538
            • -
            • Tec Star Modell 2335191R
            • -
            • uniTEC 48110 Funkfernschalterset (Receiver 55006x10, Transmitter: 50074)
            • -
            -
            - New devices are usually automatically created in FHEM via autocreate. - Since the protocol uses encryption, manual setup is virtually impossible. -

            - The remote control is set up in a learning process. - After receiving at least 5 messages within 3 minutes, a new device "SD_GT_LEARN" will be created. - Setting up the individual buttons of the remote control starts after receiving another 6 different messages. - This learning process is signaled with the status "learned code 4, please press another button", whereby the counter displays the number of currently registered codes. -
            - All buttons of the remote control must now be pressed several times. - Upon successful decoding of the radio signals, the individual keys are created. -

            - The programming of the remote control is finished, if all key levels (A, B, C, D and possibly all) are created and the commands "on" and "off" are displayed. - For each device, the Readings "CodesOn" and "CodesOff" must be set up with at least one code each. - Without these learned codes no sending is possible. -
            - The device "SD_GT_LEARN" is no longer needed and can be deleted. -

            - If several remote controls are to be taught in, this process must be carried out separately for each remote control. - The "SD_GT_LEARN" device must be deleted before starting to learn a new remote control. -

            - - -

            Attribute:

            - -

            - -

            Readings:

            -
              -
            • CodesOff: one to four hexadecimal codes for "off" that have been taught and used for sending
            • -
            • CodesOn: one to four hexadecimal codes for "on" that have been learned and used for sending
            • -
            • SendCode: the last sent code
            • -
            • SystemCode: System code hexadecimal, the same for all buttons on a remote control
            • -
            • SystemCodeDec: System code in decimal representation
            • -
            • Version: Version of the encryption used
            • -
            • state: State, "on" or "off"
            • -
            + The SD_GT module decodes and sends messages using the GT-9000 protocol. + This protocol is used by a variety of remote controls, which are traded under different names. + The messages are received and sent by a SIGNALduino. +

            + The following models are currently known that use this protocol: +

            +
              +
            • EASY HOME RCT DS1 CR-A 3725
            • +
            • Globaltronics GT-3000, GT-9000
            • +
            • OBI Emil Lux / CMI Art.Nr.: 315606
            • +
            • SilverCrest FSS B 20-A (3726) / 66538
            • +
            • Tec Star Modell 2335191R
            • +
            • uniTEC 48110 Funkfernschalterset (Receiver 55006x10, Transmitter: 50074)
            • +
            +
            + New devices are usually automatically created in FHEM via autocreate. + Since the protocol uses encryption, manual setup is virtually impossible. +

            + The remote control is set up in a learning process. + After receiving at least 5 messages within 3 minutes, a new device "SD_GT_LEARN" will be created. + Setting up the individual buttons of the remote control starts after receiving another 6 different messages. + This learning process is signaled with the status "learned code 4, please press another button", whereby the counter displays the number of currently registered codes. +
            + All buttons of the remote control must now be pressed several times. + Upon successful decoding of the radio signals, the individual keys are created. +

            + The programming of the remote control is finished, if all key levels (A, B, C, D and possibly all) are created and the commands "on" and "off" are displayed. + For each device, the Readings "CodesOn" and "CodesOff" must be set up with at least one code each. + Without these learned codes no sending is possible. +
            + The device "SD_GT_LEARN" is no longer needed and can be deleted. +

            + If several remote controls are to be taught in, this process must be carried out separately for each remote control. + The "SD_GT_LEARN" device must be deleted before starting to learn a new remote control. +

            + + +

            Attribute:

            + +

            + +

            Readings:

            +
              +
            • CodesOff: one to four hexadecimal codes for "off" that have been taught and used for sending
            • +
            • CodesOn: one to four hexadecimal codes for "on" that have been learned and used for sending
            • +
            • SendCode: the last sent code
            • +
            • SystemCode: System code hexadecimal, the same for all buttons on a remote control
            • +
            • SystemCodeDec: System code in decimal representation
            • +
            • Version: Version of the encryption used
            • +
            • state: State, "on" or "off"
            • +
          =end html @@ -554,75 +557,75 @@ sub getSystemCodes {

          SD_GT

            - Das SD_GT-Modul dekodiert und sendet Nachrichten unter Verwendung des Protokolls vom Typ GT-9000. - Dieses Protokoll wird von einer Vielzahl Fernbedienungen verwendet, die unter verschiedene Namen gehandelt werden. - Die Nachrichten werden von einem SIGNALduino empfangen und gesendet. -

            - Folgende Modelle sind zur Zeit bekannt, die dieses Protokoll verwenden: -

            -
              -
            • EASY HOME RCT DS1 CR-A 3725
            • -
            • Globaltronics GT-3000, GT-9000
            • -
            • OBI Emil Lux / CMI Art.Nr.: 315606
            • -
            • SilverCrest FSS B 20-A (3726) / 66538
            • -
            • Tec Star Modell 2335191R
            • -
            • uniTEC 48110 Funkfernschalterset (Receiver 55006x10, Transmitter: 50074)
            • -
            -
            - Neue Geräte werden in FHEM normalerweise per autocreate automatisch angelegt. - Da das Protokoll eine Verschlüsselung nutzt, ist ein manuelles Einrichten praktisch nicht möglich. -

            - Das Einrichten der Fernbedienung erfolgt in einem Lernprozess. - Nach dem Empfang von mindestens 5 Nachrichten innerhalb von 3 Minuten wird ein neues Gerät "SD_GT_LEARN" angelegt. - Das Einrichten der einzelnen Tasten der Fernbedienung beginnt nach dem Empfang weiterer 6 verschiedener Nachrichten. - Dieser Lernprozess wird mit dem Status "learned code 4, please press another button" signalisiert, wobei der Zähler die Anzahl der aktuell registrierten Codes anzeigt. -
            - Es müssen jetzt sämtliche Tasten der Fernbedienung mehrmals betätigt werden. - Bei erfolgreicher Dekodierung der Funksignale werden dabei die einzelnen Tasten angelegt. -

            - Das Anlernen der Fernbedienung ist beendet, wenn alle Tastenebenen (A, B, C, D und evtl. all) angelegt sind und jeweils die Befehle "on" und "off" angezeigt werden. - Bei jedem Gerät müssen die Readings "CodesOn" und "CodesOff" mit jeweils mindestens einem Code eingerichtet sein. - Ohne diese gelernten Codes ist kein Senden möglich. -
            - Das Gerät "SD_GT_LEARN" wird jetzt nicht mehr benötigt und kann gelöscht werden. -

            - Sollen mehrere Fernbedienungen angelernt werden, muss dieser Prozess für jede Fernbedienung getrennt durchgeführt werden. - Das Gerät "SD_GT_LEARN" muss jeweils vor Beginn des Anlernens einer neuen Fernbedienung gelöscht werden. -

            - - -

            Attribute:

            - -

            - -

            Readings:

            -
              -
            • CodesOff: ein bis vier hexadezimale Codes für "off", die angelernt wurden und zum Senden verwendet werden
            • -
            • CodesOn: ein bis vier hexadezimale Codes für "on", die angelernt wurden und zum Senden verwendet werden
            • -
            • SendCode: der zuletzt gesendete Code
            • -
            • SystemCode: Systemcode hexadezimal, bei allen Tasten einer Fernbedienung gleich
            • -
            • SystemCodeDec: Systemcode in dezimaler Darstellng
            • -
            • Version: Version der verwendeten Verschlüsselung
            • -
            • state: Zustand, "on" oder "off"
            • -
            + Das SD_GT-Modul dekodiert und sendet Nachrichten unter Verwendung des Protokolls vom Typ GT-9000. + Dieses Protokoll wird von einer Vielzahl Fernbedienungen verwendet, die unter verschiedene Namen gehandelt werden. + Die Nachrichten werden von einem SIGNALduino empfangen und gesendet. +

            + Folgende Modelle sind zur Zeit bekannt, die dieses Protokoll verwenden: +

            +
              +
            • EASY HOME RCT DS1 CR-A 3725
            • +
            • Globaltronics GT-3000, GT-9000
            • +
            • OBI Emil Lux / CMI Art.Nr.: 315606
            • +
            • SilverCrest FSS B 20-A (3726) / 66538
            • +
            • Tec Star Modell 2335191R
            • +
            • uniTEC 48110 Funkfernschalterset (Receiver 55006x10, Transmitter: 50074)
            • +
            +
            + Neue Geräte werden in FHEM normalerweise per autocreate automatisch angelegt. + Da das Protokoll eine Verschlüsselung nutzt, ist ein manuelles Einrichten praktisch nicht möglich. +

            + Das Einrichten der Fernbedienung erfolgt in einem Lernprozess. + Nach dem Empfang von mindestens 5 Nachrichten innerhalb von 3 Minuten wird ein neues Gerät "SD_GT_LEARN" angelegt. + Das Einrichten der einzelnen Tasten der Fernbedienung beginnt nach dem Empfang weiterer 6 verschiedener Nachrichten. + Dieser Lernprozess wird mit dem Status "learned code 4, please press another button" signalisiert, wobei der Zähler die Anzahl der aktuell registrierten Codes anzeigt. +
            + Es müssen jetzt sämtliche Tasten der Fernbedienung mehrmals betätigt werden. + Bei erfolgreicher Dekodierung der Funksignale werden dabei die einzelnen Tasten angelegt. +

            + Das Anlernen der Fernbedienung ist beendet, wenn alle Tastenebenen (A, B, C, D und evtl. all) angelegt sind und jeweils die Befehle "on" und "off" angezeigt werden. + Bei jedem Gerät müssen die Readings "CodesOn" und "CodesOff" mit jeweils mindestens einem Code eingerichtet sein. + Ohne diese gelernten Codes ist kein Senden möglich. +
            + Das Gerät "SD_GT_LEARN" wird jetzt nicht mehr benötigt und kann gelöscht werden. +

            + Sollen mehrere Fernbedienungen angelernt werden, muss dieser Prozess für jede Fernbedienung getrennt durchgeführt werden. + Das Gerät "SD_GT_LEARN" muss jeweils vor Beginn des Anlernens einer neuen Fernbedienung gelöscht werden. +

            + + +

            Attribute:

            + +

            + +

            Readings:

            +
              +
            • CodesOff: ein bis vier hexadezimale Codes für "off", die angelernt wurden und zum Senden verwendet werden
            • +
            • CodesOn: ein bis vier hexadezimale Codes für "on", die angelernt wurden und zum Senden verwendet werden
            • +
            • SendCode: der zuletzt gesendete Code
            • +
            • SystemCode: Systemcode hexadezimal, bei allen Tasten einer Fernbedienung gleich
            • +
            • SystemCodeDec: Systemcode in dezimaler Darstellng
            • +
            • Version: Version der verwendeten Verschlüsselung
            • +
            • state: Zustand, "on" oder "off"
            • +
          =end html_DE @@ -671,6 +674,7 @@ sub getSystemCodes { } } }, + "version": "v1.2.0", "release_status": "stable", "resources": { "bugtracker": { diff --git a/controls_signalduino.txt b/controls_signalduino.txt index 33e688709..171e882bf 100644 --- a/controls_signalduino.txt +++ b/controls_signalduino.txt @@ -1,6 +1,6 @@ UPD 2024-01-03_09:06:30 240267 FHEM/00_SIGNALduino.pm UPD 2023-01-06_12:08:43 20082 FHEM/10_FS10.pm -UPD 2023-01-09_20:47:40 25008 FHEM/10_SD_GT.pm +UPD 2024-01-03_19:11:00 27250 FHEM/10_SD_GT.pm UPD 2023-01-01_18:10:40 25403 FHEM/10_SD_Rojaflex.pm UPD 2023-01-01_18:10:40 10096 FHEM/14_BresserTemeo.pm UPD 2023-01-01_18:10:40 16260 FHEM/14_FLAMINGO.pm diff --git a/t/FHEM/10_SD_GT/01_define.t b/t/FHEM/10_SD_GT/01_define.t new file mode 100644 index 000000000..5620626eb --- /dev/null +++ b/t/FHEM/10_SD_GT/01_define.t @@ -0,0 +1,36 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use Test2::V0; +use Test2::Tools::Compare qw{is}; + +our %defs; + +InternalTimer(time()+1, sub { + my $ioName = shift; + my $ioHash = $defs{$ioName}; + + + subtest 'SD_GT - define SD_GT_Test_D SD_GT C07E2_D' => sub { + plan(1); + + my $device=q[SD_GT_Test_D]; + my $def=q[C07E2_D]; + CommandDefine(undef,qq[$device SD_GT $def]); + is(IsDevice($device), 1, "check device created with define"); + }; + + subtest 'SD_GT - delete device' => sub { + plan(1); + + my $device=q[SD_GT_Test_D]; + CommandDelete(undef,qq[$device]); + is(IsDevice($device), 0, "check device deleted"); + }; + + done_testing(); + exit(0); + +}, 'dummyDuino'); + +1; \ No newline at end of file diff --git a/t/FHEM/10_SD_GT/03_set.t b/t/FHEM/10_SD_GT/03_set.t new file mode 100644 index 000000000..604839d56 --- /dev/null +++ b/t/FHEM/10_SD_GT/03_set.t @@ -0,0 +1,65 @@ +#!/usr/bin/env perl +use strict; +use warnings; + +use Test2::V0; +use File::Basename; + +# Testtool which supports DMSG Tests from SIGNALDuino_tool +use Test2::SIGNALduino::FHEM_Command; +use Test2::Tools::Compare qw{is U validator array hash}; +use Test2::Mock; + +our %defs; +our $init_done; +our $mock; + +my $module = basename (dirname(__FILE__)); + +# This is the testdata, which will speify what to test and what to check +@mockData = ( + { + # Default mocking for every testrun in our loop + defaults => { + mocking => sub { $mock->override ( IOWrite => sub { return @_ } ); } + }, + }, + { + targetName => q[SD_GT_Set], + testname => q[set command on with all readings], + cmd => q[set on], + + prep_commands => [ # Any FHEM custom command can be placed in here, which will be called before the test is run + 'setreading $targetName CodesOff C6B542', + 'setreading $targetName CodesOn C22B92', + 'setreading $targetName SystemCode C07E2', + 'setreading $targetName SystemCodeDec 788450', + 'setreading $targetName Version 2', + ], + + returnCheck => F(), + subCheck => hash { field 'IOWrite' => array { item 0 => hash { field 'args' => array { item hash { etc(); } ; item 'sendMsg'; item 'P49#0xC22B92#R5' }; etc() } } } , + } +); + +sub runTest { + Test2::SIGNALduino::FHEM_Command::commandCheck($module); + + done_testing(); + exit(0); +} + +sub waitDone { + + if ($init_done) + { + runTest(@_); + } else { + InternalTimer(time()+0.2, &waitDone,@_); + } + +} + +waitDone(); + +1; \ No newline at end of file diff --git a/t/FHEM/10_SD_GT/fhem.cfg b/t/FHEM/10_SD_GT/fhem.cfg index bd31945ab..d5c7fb42d 100644 --- a/t/FHEM/10_SD_GT/fhem.cfg +++ b/t/FHEM/10_SD_GT/fhem.cfg @@ -1,2 +1,4 @@ define dummyDuino SIGNALduino none -attr dummyDuino dummy 1 \ No newline at end of file +attr dummyDuino dummy 1 + +define SD_GT_Set SD_GT C77E2_D \ No newline at end of file From 243a8c646a2cd2872a85c809bb8b18bc2658c21e Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Wed, 3 Jan 2024 22:06:13 +0000 Subject: [PATCH 44/55] Automatic updated controls and CHANGED --- CHANGED | 10 ++++++++++ controls_signalduino.txt | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGED b/CHANGED index 63556fe82..695f68227 100644 --- a/CHANGED +++ b/CHANGED @@ -1,3 +1,13 @@ +2024-01-03 - little fix 10_SD_GT and added tests (#1223) + +* Update 10_SD_GT.pm +- replace tabs with spaces (no module restrictions) +- fix META versionssupport +- fix PERL WARNING +- added tests +- revised SVN numbre +- remove old Internals VERSION_SD_GT +- added Meta version 2024-01-03 - Call debug via a coderef if enabled, otherwise return (#1169) * 00_SIGNALduino.pm diff --git a/controls_signalduino.txt b/controls_signalduino.txt index 171e882bf..9db8c4796 100644 --- a/controls_signalduino.txt +++ b/controls_signalduino.txt @@ -1,6 +1,6 @@ UPD 2024-01-03_09:06:30 240267 FHEM/00_SIGNALduino.pm UPD 2023-01-06_12:08:43 20082 FHEM/10_FS10.pm -UPD 2024-01-03_19:11:00 27250 FHEM/10_SD_GT.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 UPD 2023-01-01_18:10:40 10096 FHEM/14_BresserTemeo.pm UPD 2023-01-01_18:10:40 16260 FHEM/14_FLAMINGO.pm From c7f21a4ca2ad7b7664ca9136b5a215b863d26b51 Mon Sep 17 00:00:00 2001 From: Udo Date: Sat, 6 Jan 2024 20:21:35 +0100 Subject: [PATCH 45/55] new protocol 131 for BRESSER Lightning detector (#1224) * Bresser lightning detector new protocol 131 for Bresser lightning detector * Update testData.json * Update README.md * Update Versiondate --- FHEM/00_SIGNALduino.pm | 9 ++++- FHEM/14_SD_WS.pm | 68 +++++++++++++++++++++++++++++++---- FHEM/lib/SD_ProtocolData.pm | 22 ++++++++++-- FHEM/lib/SD_Protocols.pm | 28 +++++++++++++-- README.md | 2 +- controls_signalduino.txt | 8 ++--- t/FHEM/14_SD_WS/testData.json | 53 +++++++++++++++++++++++++++ 7 files changed, 174 insertions(+), 16 deletions(-) diff --git a/FHEM/00_SIGNALduino.pm b/FHEM/00_SIGNALduino.pm index 522a873d6..92adcfc49 100644 --- a/FHEM/00_SIGNALduino.pm +++ b/FHEM/00_SIGNALduino.pm @@ -1,4 +1,4 @@ -# $Id: 00_SIGNALduino.pm 3.5.6 2024-01-02 22:22:14Z sidey79 $ +# $Id: 00_SIGNALduino.pm 3.5.6 2024-01-06 16:07:53Z elektron-bbs $ # 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 @@ -4832,6 +4832,9 @@ USB-connected devices (SIGNALduino):
          Modulation 2-FSK, Datarate=8.23 kbps, Sync Word=2DD4, Packet Length=23 Byte, frequency 868.3 MHz
            Example: BRESSER 7-in-1 outdoor sensor, BRESSER PM2.5/10 air quality meter
          +
        • Bresser_lightning
          + Modulation 2-FSK, Datarate=8.23 kbps, Sync Word=2DD4, Packet Length=10 Byte, frequency 868.3 MHz +
            Beispiel: BRESSER lightning sensor
        • Fine_Offset_WH51_434
          Modulation 2-FSK, Datarate=17.26 kbps, Sync Word=2DD4, Packet Length=14 Byte, Frequency 433.92 MHz @@ -5428,6 +5431,10 @@ USB-connected devices (SIGNALduino):
          Modulation 2-FSK, Datenrate=8.23 kbps, Sync Word=2DD4, Packet Length=23 Byte, Frequenz 868.3 MHz
            Beispiel: BRESSER 7-in-1 Außensensor, BRESSER PM2.5/10 Luftqualitätssensor
        • +
        • Bresser_lightning
          + Modulation 2-FSK, Datenrate=8.23 kbps, Sync Word=2DD4, Packet Length=10 Byte, Frequenz 868.3 MHz +
            Beispiel: BRESSER Blitzsensor
          +
        • 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
          diff --git a/FHEM/14_SD_WS.pm b/FHEM/14_SD_WS.pm index d38169e87..39fa4ea5f 100644 --- a/FHEM/14_SD_WS.pm +++ b/FHEM/14_SD_WS.pm @@ -1,4 +1,4 @@ -# $Id: 14_SD_WS.pm 26982 2023-12-29 20:00:00Z elektron-bbs $ +# $Id: 14_SD_WS.pm 26982 2024-01-06 16:07:53Z elektron-bbs $ # # The purpose of this module is to support serval # weather sensors which use various protocol @@ -53,6 +53,7 @@ # 06.05.2023 Added protocol 126: ecowitt WH40 support # 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 package main; @@ -119,6 +120,7 @@ sub SD_WS_Initialize { '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_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'}, }; return FHEM::Meta::InitMod( __FILE__, $hash ); } @@ -1710,6 +1712,53 @@ sub SD_WS_Parse { return 1; }, }, + 131 => { + # BRESSER Blitzsensor Art.No.: 7009976, Hersteller CCL Electronics LTD Model C3129A + # --------------------------------------------------------------------------------- + # The sensor transmits immediately when a flash is detected, otherwise approximately every 60 seconds. + # 0 1 + # 01234567890123456789 + # -------------------- + # 73FB2866AAA298AAAAAA original message + # 8BF082CC138832120000 message after all nibbles xor 0xA + # CCCCIIIIcccB?FDD???? + # C = LFSR-16 digest, generator 0x8810, key 0xABF9, final xor 0x899E + # I = station ID + # c = 3 nibbles lightning count, BCD + # B = flags, 4 bit + # Bit: 0123 + # 1000 + # b??? + # b: 1 bit batteryState, 1 = ok, 0 = low + # ?: 3 bit unknown always 000 + # ? = 1 nibble, unknown, always 0x3 (type?) + # F = flags, 4 bit + # Bit: 0123 + # 1010 xor 0xA = 0000 + # r??? + # r: 1 bit device reset, 1 after device reset + # ?: 3 bit unknown always 000 + # D = 2 nibbles last distance, 0 after reset, BCD + # ? = 4 nibbles, unknown, always 0x0 + sensortype => 'Bresser_lightning', + model => 'SD_WS_131', + modelStat => sub {my ($rawData,undef) = @_; + my $typ = hex(substr($rawData,12,1)); # sensor type + if ($typ eq '3') { + $typ = 'Bresser lightning detector'; + } else { + $typ = 'SD_WS_131'; + } + 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}/); }, + id => sub {my ($rawData,undef) = @_; return substr($rawData,4,4); }, + count => sub { my ($rawData,undef) = @_; return substr($rawData,8,3) * 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; }, + crcok => sub {return 1;}, # checks are in SD_Protocols.pm sub ConvBresser_lightning + }, ); Log3 $name, 4, "$name: SD_WS_Parse protocol $protocol, rawData $rawData"; @@ -2223,6 +2272,7 @@ sub SD_WS_Parse { $state .= ' ' if (length($state) > 0); $state .= "PM10: $pm10"; } + ### protocol 33 has different bits per sensor type if ($protocol eq "33") { if (AttrVal($name,'model',0) eq "S522") { # Conrad S522 @@ -2273,7 +2323,7 @@ sub SD_WS_Parse { readingsBulkUpdate($hash, "humidityTrend", $trendHum) if (defined($trendHum) && length($trendHum) > 0); readingsBulkUpdate($hash, "sendmode", $sendmode) if (defined($sendmode) && length($sendmode) > 0); readingsBulkUpdateIfChanged($hash, "type", $SensorTyp, 0) if (defined($SensorTyp)); - readingsBulkUpdate($hash, 'model', $modelStat, 0) if (defined($modelStat)); + readingsBulkUpdateIfChanged($hash, 'model', $modelStat, 0) if (defined($modelStat)); readingsBulkUpdate($hash, "beep", $beep) if (defined($beep)); readingsBulkUpdate($hash, "adc", $adc) if (defined($adc)); readingsBulkUpdate($hash, 'rain', $rain) if (defined($rain)); @@ -2406,7 +2456,7 @@ sub SD_WS_WH2SHIFT {
        • ADE WS1907 Weather station with rain gauge
        • Atech wireless weather station
        • BBQ temperature sensor GT-TMBBQ-01s (transmitter), GT-TMBBQ-01e (receiver)
        • -
        • Bresser 5-in-1, 6-in-1 and 7-in-1 Comfort Weather Center, 7009994, PM2.5/10 air quality meter, Professional rain gauge, Temeo
        • +
        • Bresser 5-in-1, 6-in-1 and 7-in-1 Comfort Weather Center, 7009994, Lightning detector, PM2.5/10 air quality meter, Professional rain gauge, Temeo
        • Conrad S522
        • EuroChron EFTH-800, EFS-3110A (temperature and humidity sensor)
        • Fine Offset WH51, aka ECOWITT WH51, aka Froggit DP100, aka MISOL/1 (soil moisture sensor)
        • @@ -2462,12 +2512,15 @@ sub SD_WS_WH2SHIFT {
        • batteryPercent (battery level in %)
        • brightness (kLux)
        • channel (number of channel
        • +
        • count (number of lightnings
        • distance (distance in cm (protocol 111) or km (protocol 116)
        • humidity (humidity (1-100 % only if available)
        • humidityTrend (consistent, rising, falling)
        • -
        • sendmode (automatic or manual)
        • +
        • pm_2_5 (particulate matter <= 2.5 µm)
        • +
        • pm_10 (particulate matter <= 10 µm)
        • rain (l/m²))
        • rain_total (l/m²))
        • +
        • sendmode (automatic or manual)
        • state (T: H: W: R:)
        • temperature (°C)
        • temperatureTrend (consistent, rising, falling)
        • @@ -2550,7 +2603,7 @@ sub SD_WS_WH2SHIFT {
        • ADE WS1907 Wetterstation mit Regenmesser
        • Atech Wetterstation
        • BBQ Temperatur Sensor GT-TMBBQ-01s (Sender), GT-TMBBQ-01e (Empfaenger)
        • -
        • Bresser 5-in-1, 6-in-1 und 7-in-1 Comfort Wetter Center, 7009994, PM2.5/10 Luftqualitätsmesser, Profi Regenmesser, Temeo
        • +
        • Bresser 5-in-1, 6-in-1 und 7-in-1 Comfort Wetter Center, 7009994, Blitzsensor, PM2.5/10 Luftqualitätsmesser, Profi Regenmesser, Temeo
        • Conrad S522
        • EuroChron EFTH-800, EFS-3110A (Temperatur- und Feuchtigkeitssensor)
        • Fine Offset WH51, aka ECOWITT WH51, aka Froggit DP100, aka MISOL/1 (Bodenfeuchtesensor)
        • @@ -2607,9 +2660,12 @@ sub SD_WS_WH2SHIFT {
        • batteryPercent (Batteriestand in %)
        • brightness (Helligkeit in kLux)
        • channel (Sensor-Kanal)
        • +
        • count (Anzahl)
        • distance (Entfernung in cm (Protokoll 111) oder km (Protokoll 116)
        • humidity (Luft-/Bodenfeuchte, 1-100 %)
        • humidityTrend (Trend Luftfeuchte, gleichbleibend, steigend, fallend)
        • +
        • pm_2_5 (Feinstaub <= 2.5 µm)
        • +
        • pm_10 (Feinstaub <= 10 µm)
        • rain (Regenmenge l/m²))
        • rain_total (Regenmenge l/m²))
        • sendmode (Sendemodus, automatic oder manuell mittels Taster am Sender)
        • @@ -2699,7 +2755,7 @@ sub SD_WS_WH2SHIFT { "x_fhem_maintainer_github": [ "Sidey79" ], - "version": "v1.0.0", + "version": "v1.1.0", "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 b182efa81..75971f68e 100644 --- a/FHEM/lib/SD_ProtocolData.pm +++ b/FHEM/lib/SD_ProtocolData.pm @@ -1,4 +1,4 @@ -# $Id: SD_ProtocolData.pm 26975 2023-12-29 20:00:00Z elektron-bbs $ +# $Id: SD_ProtocolData.pm 26975 2024-01-06 16:07:53Z elektron-bbs $ # The file is part of the SIGNALduino project. # All protocol definitions are contained in this file. # @@ -3472,7 +3472,25 @@ package lib::SD_ProtocolData; length_min => '24', length_max => '24', }, - #"131" => ## reserved for elektron-bbs + "131" => ## BRESSER lightning detector @ elektron-bbs 2023-12-26 + # SD_WS_131 count: 0, distance: 0, batteryState: ok, batteryChanged: 0 MN;D=DA5A2866AAA290AAAAAA;R=23;A=-2; + # SD_WS_131 count: 1, distance: 17, batteryState: ok, batteryChanged: 0 MN;D=5B192866AAB290BDAAAA;R=32;A=-3; + # SD_WS_131 count: 148, distance: 8, batteryState: ok, batteryChanged: 1 MN;D=AA362866BE2298A2AAAA;R=24;A=-2; + { + name => 'Bresser lightning', + comment => 'Bresser lightning detector', + id => '131', + knownFreqs => '868.300', + datarate => '8.232', + sync => '2DD4', + modulation => '2-FSK', + rfmode => 'Bresser_lightning', + register => ['0001','022E','0342','042D','05D4','060A','07C0','0800','0D21','0E65','0F6A','1088','114C','1202','1322','14F8','1551','1916','1B43','1C68'], + preamble => 'W131#', + clientmodule => 'SD_WS', + length_min => '20', + method => \&lib::SD_Protocols::ConvBresser_lightning, + }, "132" => ## Remote control Halemeier HA-HX2 for Actor HA-RX-M2-1 # https://github.com/RFD-FHEM/RFFHEM/issues/1207 @ HomeAuto_User 2023-12-11 # https://forum.fhem.de/index.php?topic=38452.0 (probably identical) diff --git a/FHEM/lib/SD_Protocols.pm b/FHEM/lib/SD_Protocols.pm index 67c902ad3..4c332b8e9 100644 --- a/FHEM/lib/SD_Protocols.pm +++ b/FHEM/lib/SD_Protocols.pm @@ -1,5 +1,5 @@ ################################################################################ -# $Id: SD_Protocols.pm 26975 2023-08-21 19:02:34Z elektron-bbs $ +# $Id: SD_Protocols.pm 26975 2024-01-06 16:07:53Z elektron-bbs $ # # The file is part of the SIGNALduino project # v3.5.x - https://github.com/RFD-FHEM/RFFHEM @@ -16,7 +16,7 @@ use Carp qw(croak carp); use constant HAS_DigestCRC => defined eval { require Digest::CRC; }; use constant HAS_JSON => defined eval { require JSON; }; -our $VERSION = '2.08'; +our $VERSION = '2.09'; use Storable qw(dclone); use Scalar::Util qw(blessed); @@ -2040,6 +2040,30 @@ sub ConvBresser_7in1 { return $hexDataXorA; } +sub ConvBresser_lightning { + 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_lightning, hexData is to short') if ($hexLength < 20); # check double, in def length_min set + + my $hexDataXorA =''; + for (my $i = 0; $i < $hexLength; $i++) { + my $xor = hex(substr($hexData,$i,1)) ^ 0xA; + $hexDataXorA .= sprintf('%X',$xor); + } + $self->_logging(qq[ConvBresser_lightning, msg=$hexData],5); + $self->_logging(qq[ConvBresser_lightning, xor=$hexDataXorA],5); + + # LFSR-16 gen 8810 key abf9 final xor 899e + my $checksum = lib::SD_Protocols::LFSR_digest16(8, 0x8810, 0xABF9, substr($hexDataXorA,4,16)); + my $checksumcalc = sprintf('%04X',$checksum ^ hex(substr($hexDataXorA,0,4))); + $self->_logging(qq[ConvBresser_lightning, checksumCalc:0x$checksumcalc, must be 0x899E],5); + return ( 1, qq[ConvBresser_lightning, checksumCalc:0x$checksumcalc != checksum:0x899E] ) if ($checksumcalc ne '899E'); + + return substr($hexDataXorA, 0, 20); +} + =item LFSR_digest16() This function checks 16 bit LFSR diff --git a/README.md b/README.md index 54af2a2c5..3151bda86 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Supported Devices / Protocols |BF-301 | Remote control| |benon (Semexo OHG) | Remote control (BH-P)| |BOSCH / Neff / Refsta Topdraft | Remote control (SF01 01319004, SF01 01319004 v2)| -|BRESSER 5-in-1, 6-in-1, 7-in-1, Professional Rain Gauge, TemeoTrend, SM60020 Soil moisture sensor, PM2.5/10 Air quality sensor | Weather Station, Rain Gauge, Thermo-/Hygro Sensor, Particulate meter | +|BRESSER 5-in-1, 6-in-1, 7-in-1, Professional Rain Gauge, TemeoTrend, SM60020 Soil moisture sensor, PM2.5/10 Air quality sensor, Lightning sensor | Weather Station, Rain Gauge, Thermo-/Hygro Sensor, Particulate meter, Lightning detector | |Busch-Transcontrol HF | Remote control (6861)| |CAME TOP 432EV | Remote control | |CTW600, WH1080, WH2315 | Weather station | diff --git a/controls_signalduino.txt b/controls_signalduino.txt index 9db8c4796..08774c92d 100644 --- a/controls_signalduino.txt +++ b/controls_signalduino.txt @@ -1,4 +1,4 @@ -UPD 2024-01-03_09:06:30 240267 FHEM/00_SIGNALduino.pm +UPD 2024-01-06_15:07:27 240687 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 @@ -8,11 +8,11 @@ UPD 2023-10-14_22:18:35 24045 FHEM/14_Hideki.pm UPD 2023-01-23_21:06:26 13260 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 2023-12-31_15:15:49 161715 FHEM/14_SD_WS.pm +UPD 2024-01-06_15:07:27 164816 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 2023-12-31_15:15:49 251336 FHEM/lib/SD_ProtocolData.pm -UPD 2023-12-31_15:15:49 80775 FHEM/lib/SD_Protocols.pm +UPD 2024-01-06_15:07:27 252437 FHEM/lib/SD_ProtocolData.pm +UPD 2024-01-06_15:07:27 81862 FHEM/lib/SD_Protocols.pm diff --git a/t/FHEM/14_SD_WS/testData.json b/t/FHEM/14_SD_WS/testData.json index c07837c8a..8aedb5da9 100644 --- a/t/FHEM/14_SD_WS/testData.json +++ b/t/FHEM/14_SD_WS/testData.json @@ -2546,5 +2546,58 @@ "id" : 129, "module" : "SD_WS", "name" : "FT-0835" + }, + { + "data" : [ + { + "comment" : "BRESSER lightning detector", + "dmsg" : "W131#70F082CC00083A000000", + "internals" : { + "DEF" : "SD_WS_131", + "NAME" : "SD_WS_131" + }, + "readings" : { + "batteryChanged" : "0", + "batteryState" : "ok", + "count" : 0, + "distance" : 0, + "state" : "D: 0", + "type" : "Bresser_lightning" + }, + "rmsg" : "MN;D=DA5A2866AAA290AAAAAA;R=23;A=-2;", + "tests" : [ + { + "attributes" : {}, + "comment" : "#0" + } + ] + }, + { + "comment" : "BRESSER lightning detector", + "dmsg" : "W131#009C82CC148832080000", + "internals" : { + "DEF" : "SD_WS_131", + "NAME" : "SD_WS_131" + }, + "readings" : { + "batteryChanged" : "1", + "batteryState" : "ok", + "count" : 148, + "distance" : 8, + "state" : "D: 8", + "type" : "Bresser_lightning" + }, + "rmsg" : "MN;D=AA362866BE2298A2AAAA;R=24;A=-2;", + "tests" : [ + { + "attributes" : {}, + "comment" : "#1" + } + ] + } + ], + "id" : 131, + "module" : "SD_WS", + "name" : "Bresser lightning" } ] From 58b2afaa8621f3a5f0616f2a59c1e4fa24f8653c Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Sat, 6 Jan 2024 19:22:08 +0000 Subject: [PATCH 46/55] Automatic updated controls and CHANGED --- CHANGED | 7 +++++++ controls_signalduino.txt | 8 ++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGED b/CHANGED index 695f68227..40a6619d4 100644 --- a/CHANGED +++ b/CHANGED @@ -1,3 +1,10 @@ +2024-01-06 - new protocol 131 for BRESSER Lightning detector (#1224) + +* Bresser lightning detector +new protocol 131 for Bresser lightning detector +* Update testData.json +* Update README.md +* Update Versiondate 2024-01-03 - little fix 10_SD_GT and added tests (#1223) * Update 10_SD_GT.pm diff --git a/controls_signalduino.txt b/controls_signalduino.txt index 08774c92d..b7c0b5615 100644 --- a/controls_signalduino.txt +++ b/controls_signalduino.txt @@ -1,4 +1,4 @@ -UPD 2024-01-06_15:07:27 240687 FHEM/00_SIGNALduino.pm +UPD 2024-01-06_20:21:35 240687 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 @@ -8,11 +8,11 @@ UPD 2023-10-14_22:18:35 24045 FHEM/14_Hideki.pm UPD 2023-01-23_21:06:26 13260 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-01-06_15:07:27 164816 FHEM/14_SD_WS.pm +UPD 2024-01-06_20:21:35 164816 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-01-06_15:07:27 252437 FHEM/lib/SD_ProtocolData.pm -UPD 2024-01-06_15:07:27 81862 FHEM/lib/SD_Protocols.pm +UPD 2024-01-06_20:21:35 252437 FHEM/lib/SD_ProtocolData.pm +UPD 2024-01-06_20:21:35 81862 FHEM/lib/SD_Protocols.pm From a8cdf0f2cfefb5f52d72422a573403bf01d79669 Mon Sep 17 00:00:00 2001 From: Udo Date: Sun, 7 Jan 2024 18:08:13 +0100 Subject: [PATCH 47/55] SD_WS add reading model for statistics (#1225) * add models for FHEM statistics see FHEM statistics https://fhem.de/stats/statistics.html --- FHEM/14_SD_WS.pm | 32 ++++++++++++++++++++++++++++++-- controls_signalduino.txt | 2 +- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/FHEM/14_SD_WS.pm b/FHEM/14_SD_WS.pm index 39fa4ea5f..f0af0aff6 100644 --- a/FHEM/14_SD_WS.pm +++ b/FHEM/14_SD_WS.pm @@ -1,4 +1,4 @@ -# $Id: 14_SD_WS.pm 26982 2024-01-06 16:07:53Z elektron-bbs $ +# $Id: 14_SD_WS.pm 26982 2024-01-07 15:31:22Z elektron-bbs $ # # The purpose of this module is to support serval # weather sensors which use various protocol @@ -930,6 +930,19 @@ sub SD_WS_Parse { model => 'SD_WS_108', prematch => sub {my $rawData = shift; return 1 if ($rawData =~ /^[0-9A-F]{8}[0-9]{2}[0-9A-F]{1}[0-9]{3}[0-9A-F]{1}[0-9]{5}[0-9A-F]{1}[0-9]{1}/); }, id => sub {my ($rawData,undef) = @_; return substr($rawData,0,2); }, + modelStat => sub {my (undef,$bitData) = @_; + my $typ = substr($bitData,10,2); + if ($typ eq '00') { + $typ = 'Bresser 5in1, Fody E43 outdoor sensor'; + } elsif ($typ eq '01') { + $typ = 'Fody E42 thermo-/hygro sensor'; + } elsif ($typ eq '11') { + $typ = 'Bresser rain gauge'; + } else { + $typ = 'SD_WS_108'; + } + return $typ; + }, winddir => sub {my ($rawData,$bitData) = @_; return if (substr($bitData,10,2) eq '01' || substr($bitData,10,2) eq '11'); # Bresser rain gauge, Fody E42 my $winddirraw = hex(substr($rawData,6,1)); @@ -1119,6 +1132,21 @@ sub SD_WS_Parse { model => 'SD_WS_115', prematch => sub { return 1; }, # no precheck known id => sub {my ($rawData,undef) = @_; return substr($rawData,4,8); }, + modelStat => sub {my ($rawData,undef) = @_; + my $typ = substr($rawData,12,1); + if ($typ eq '1') { + $typ = 'Bresser 6-in-1, new 5-in-1, 3-in-1 outdoor sensor'; + } elsif ($typ eq '2') { + $typ = 'Bresser Thermo-/hygro sensor'; + } elsif ($typ eq '3') { + $typ = 'Bresser Pool thermometer'; + } elsif ($typ eq '4') { + $typ = 'Bresser SM60020 Soil moisture/temperature sensor'; + } else { + $typ = 'SD_WS_115'; + } + return $typ; + }, bat => sub {my ($rawData,$bitData) = @_; return if (substr($rawData,12,1) eq '1' && substr($rawData,33,1) eq '1'); # not by weather station & rain return substr($bitData,110,1) eq '1' ? 'ok' : 'low'; @@ -2755,7 +2783,7 @@ sub SD_WS_WH2SHIFT { "x_fhem_maintainer_github": [ "Sidey79" ], - "version": "v1.1.0", + "version": "v1.1.1", "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/controls_signalduino.txt b/controls_signalduino.txt index b7c0b5615..c9ff1d2cb 100644 --- a/controls_signalduino.txt +++ b/controls_signalduino.txt @@ -8,7 +8,7 @@ UPD 2023-10-14_22:18:35 24045 FHEM/14_Hideki.pm UPD 2023-01-23_21:06:26 13260 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-01-06_20:21:35 164816 FHEM/14_SD_WS.pm +UPD 2024-01-07_14:39:58 166295 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 From f5a9a2a51118e014db275a021a63397e3f253d19 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Sun, 7 Jan 2024 17:08:50 +0000 Subject: [PATCH 48/55] Automatic updated controls and CHANGED --- CHANGED | 4 ++++ controls_signalduino.txt | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGED b/CHANGED index 40a6619d4..1d4e4507a 100644 --- a/CHANGED +++ b/CHANGED @@ -1,3 +1,7 @@ +2024-01-07 - SD_WS add reading model for statistics (#1225) + +* add models for FHEM statistics +see FHEM statistics https://fhem.de/stats/statistics.html 2024-01-06 - new protocol 131 for BRESSER Lightning detector (#1224) * Bresser lightning detector diff --git a/controls_signalduino.txt b/controls_signalduino.txt index c9ff1d2cb..551c8127d 100644 --- a/controls_signalduino.txt +++ b/controls_signalduino.txt @@ -8,7 +8,7 @@ UPD 2023-10-14_22:18:35 24045 FHEM/14_Hideki.pm UPD 2023-01-23_21:06:26 13260 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-01-07_14:39:58 166295 FHEM/14_SD_WS.pm +UPD 2024-01-07_18:08:13 166295 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 From 7e49a6ef01fadfea81642c2c582fba9a4a494e3f Mon Sep 17 00:00:00 2001 From: Udo Date: Tue, 9 Jan 2024 21:34:16 +0100 Subject: [PATCH 49/55] 14_SD_WS.pm small corrections (#1226) * 14_SD_WS.pm small corrections Small corrections without changing the function of the module. --- FHEM/14_SD_WS.pm | 40 ++++++++++++++++++++-------------------- controls_signalduino.txt | 2 +- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/FHEM/14_SD_WS.pm b/FHEM/14_SD_WS.pm index f0af0aff6..8748df7e0 100644 --- a/FHEM/14_SD_WS.pm +++ b/FHEM/14_SD_WS.pm @@ -1,4 +1,4 @@ -# $Id: 14_SD_WS.pm 26982 2024-01-07 15:31:22Z elektron-bbs $ +# $Id: 14_SD_WS.pm 26982 2024-01-07 20:20:20Z elektron-bbs $ # # The purpose of this module is to support serval # weather sensors which use various protocol @@ -318,7 +318,7 @@ sub SD_WS_Parse { # prematch => sub {my $rawData = shift; return 1 if ($rawData =~ /^[0-9A-F]{7}0[0-9]{2}[0-9A-F]{2}$/); }, # prematch 113C49A 0 47 AE (EFTH-800) prematch => sub {my $rawData = shift; return 1 if ($rawData =~ /^[0-9A-F]{7}0|8[0-9]{2}[0-9A-F]{2}$/); }, # prematch 3F94519 8 55 C7 (EFS-3110A) channel => sub {my (undef,$bitData) = @_; return (SD_WS_binaryToNumber($bitData,1,3) + 1 ); }, - id => sub {my (undef,$bitData) = @_; return substr($rawData,1,3); }, + id => sub {my ($rawData,undef) = @_; return substr($rawData,1,3); }, bat => sub {my (undef,$bitData) = @_; return substr($bitData,16,1) eq "0" ? "ok" : "low";}, temp => sub {my (undef,$bitData) = @_; return substr($bitData,17,1) eq "0" ? ((SD_WS_binaryToNumber($bitData,18,27) - 1024) / 10.0) : (SD_WS_binaryToNumber($bitData,18,27) / 10.0);}, hum => sub {my (undef,$bitData) = @_; return (SD_WS_binaryToNumber($bitData,32,35) * 10) + (SD_WS_binaryToNumber($bitData,36,39));}, @@ -428,7 +428,7 @@ sub SD_WS_Parse { sensortype => 'NC-3911', model => 'SD_WS_38_T', prematch => sub {my $msg = shift; return 1 if ($msg =~ /^[0-9A-F]{9}$/); }, - id => sub {my (undef,$bitData) = @_; return substr($rawData,0,2); }, + id => sub {my ($rawData,undef) = @_; return substr($rawData,0,2); }, bat => sub {my (undef,$bitData) = @_; return substr($bitData,8,1) eq "1" ? "ok" : "low";}, beep => sub {my (undef,$bitData) = @_; return substr($bitData,9,1) eq "1" ? "on" : "off"; }, channel => sub {my (undef,$bitData) = @_; return SD_WS_binaryToNumber($bitData,10,11); }, @@ -467,7 +467,7 @@ sub SD_WS_Parse { prematch => sub {my $msg = shift; return 1 if ($msg =~ /^[0-9A-F]{9}[1-3]$/);}, # 10 nibbles, 9 hex chars, only channel 1-3 # prematch => sub {my $msg = shift; return 1 if ($msg =~ /^[0-9A-F]{10}$/);}, # 10 nibbles, all hex chars crcok => sub {return 1; }, # crc is unknown - id => sub {my (undef,$bitData) = @_; return substr($rawData,0,2);}, # long-id in hex + id => sub {my ($rawData,undef) = @_; return substr($rawData,0,2);}, # long-id in hex sendmode => sub {my (undef,$bitData) = @_; return substr($bitData,12,1) eq "1" ? "manual" : "auto";}, bat => sub {my (undef,$bitData) = @_; return substr($bitData,13,1) eq "1" ? "low" : "ok";}, trend => sub {my (undef,$bitData) = @_; return ('consistent', 'rising', 'falling', 'unknown')[SD_WS_binaryToNumber($bitData,14,15)];}, @@ -506,14 +506,14 @@ sub SD_WS_Parse { return 0; } }, - id => sub {my (undef,$bitData) = @_; return substr($rawData,0,2);}, # long-id in hex + id => sub {my ($rawData,undef) = @_; return substr($rawData,0,2);}, # long-id in hex bat => sub {my (undef,$bitData) = @_; return substr($bitData,8,1) eq "1" ? "low" : "ok";}, channel => sub {my (undef,$bitData) = @_; return (SD_WS_binaryToNumber($bitData,10,11) + 1);}, temp => sub {my (undef,$bitData) = @_; return substr($bitData,12,1) eq "1" ? ((SD_WS_binaryToNumber($bitData,12,23) - 4096) / 10.0) : (SD_WS_binaryToNumber($bitData,12,23) / 10.0);}, hum => sub {my (undef,$bitData) = @_; return (SD_WS_binaryToNumber($bitData,24,30) );}, }, 54 => { - # TFA Drop Rainmeter 30.3233.01 + # TFA Drop Rainmeter 30.3233.01 (Funk-Regenmesser DROP 47.3005, Sender 30.3233.01) # ---------------------------------------------------------------------------------- # 0 8 16 24 32 40 48 56 64 - 01234567890123456 # 00111101 10011100 01000011 00001010 00011011 10101010 00000001 10001001 1000 - 3D9C430A1BAA01898 @@ -640,14 +640,14 @@ sub SD_WS_Parse { # ------------------------------------------------------------------------ # 0 4 | 8 12 | 16 20 | 24 28 | 32 36 # 1111 1100 | 0001 0110 | 0001 0000 | 0011 0111 | 0100 1001 - # iiii iiii | hhhh hhhh | bscc tttt | tttt tttt | ???? ???? + # iiii iiii | hhhh hhhh | bscc tttt | tttt tttt | xxxx xxxx # i: 8 bit id (?) - no change after battery change, i have seen two IDs: 0x03 and 0xfe # h: 8 bit relative humidity percentage # b: 1 bit battery indicator (0=>OK, 1=>LOW) # s: 1 bit sendmode 1=manual (button pressed) 0=auto # c: 2 bit channel valid channels are 0-2 (1-3) # t: 12 bit signed temperature scaled by 10 - # ?: unknown + # x: 8 bit check (not for all sensor types) # Sensor sends approximately every 30 seconds sensortype => 'Auriol IAN 283582, TV-4848', @@ -664,7 +664,7 @@ sub SD_WS_Parse { $tempraw /= 10.0; return $tempraw; }, - crcok => sub {return 1;}, # crc test method is so far unknown + crcok => sub {return 1;}, # crc check only takes place when the device is known. The test method is not yet known for all sensor types. } , 85 => { @@ -761,7 +761,7 @@ sub SD_WS_Parse { sensortype => 'TFA 30.3221.02', model => 'SD_WS_89_TH', prematch => sub {my $msg = shift; return 1 if ($msg =~ /^[0-9A-F]{2}[01245689ACDE]{1}[0-9A-F]{7}$/); }, # valid channel only 0-2 - id => sub {my (undef,$bitData) = @_; return substr($rawData,0,2); }, + id => sub {my ($rawData,undef) = @_; return substr($rawData,0,2); }, bat => sub {my (undef,$bitData) = @_; return substr($bitData,8,1) eq "0" ? "ok" : "low";}, sendmode => sub {my (undef,$bitData) = @_; return substr($bitData,9,1) eq "1" ? "manual" : "auto"; }, channel => sub {my (undef,$bitData) = @_; return (SD_WS_binaryToNumber($bitData,10,11) + 1); }, @@ -796,7 +796,7 @@ sub SD_WS_Parse { Log3 $iohash, 3, "$name: SD_WS_Parse $model ERROR - BCD of temperature ($rawtemp100 $rawtemp10 $rawtemp1)"; return; }; - my $temp = ($rawtemp100 * 10 + $rawtemp10 + $rawtemp1 / 10) * ( substr($_[1],10,1) == 1 ? -1.0 : 1.0); + return ($rawtemp100 * 10 + $rawtemp10 + $rawtemp1 / 10) * ( substr($_[1],10,1) == 1 ? -1.0 : 1.0); }, crcok => sub {return 1;}, # crc test method is so far unknown }, @@ -993,7 +993,7 @@ sub SD_WS_Parse { sensortype => 'ADE WS1907', model => 'SD_WS_110_TR', prematch => sub {return 1;}, # no precheck known - id => sub {my (undef,$bitData) = @_; return substr($rawData,0,4);}, # long-id in hex + id => sub {my ($rawData,undef) = @_; return substr($rawData,0,4);}, # long-id in hex bat => sub {my (undef,$bitData) = @_; return substr($bitData,16,1) eq "0" ? "ok" : "low";}, batChange => sub {my (undef,$bitData) = @_; return substr($bitData,17,1);}, sendCounter => sub {my (undef,$bitData) = @_; return (SD_WS_binaryToNumber($bitData,20,22));}, @@ -1116,7 +1116,7 @@ sub SD_WS_Parse { # CCCCIIIIIIIIFFGGGWWWDDD?RRRRRR???XSS Msg 2, 36 Nibble, wind, rain # C = CRC16 # I = station ID - # F = flags, 8 bit (nibble 12 1: weather station, 2: indoor, 4: soil probe, nibble 13 1 bit battery change, 3 bit channel) + # F = flags, 8 bit (nibble 12 1: weather station, 2: indoor, 3: pool thermometer, 4: soil probe, nibble 13 1 bit battery change, 3 bit channel) # G = wind gust in 1/10 m/s, inverted, BCD coded, GGG = FE6 =~ 019 => 1.9 m/s. # W = wind speed in 1/10 m/s, inverted, BCD coded, LSB first nibble, MSB last two nibble, WWW = EFE =~ 101 => 1.1 m/s. # D = wind direction in grad, BCD coded, DDD = 158 => 158 ° @@ -1920,7 +1920,7 @@ sub SD_WS_Parse { { if ($sign) { - $temp = 0 - $temp + $temp = 0 - $temp; } } @@ -2249,7 +2249,7 @@ sub SD_WS_Parse { } #my $state = (($temp > -60 && $temp < 70) ? "T: $temp":"T: xx") . (($hum > 0 && $hum < 100) ? " H: $hum":""); - my $state = ""; + my $state = ''; if (defined($temp)) { $state .= "T: $temp"; } @@ -2266,19 +2266,19 @@ sub SD_WS_Parse { $state .= "T4: $temp4"; } if (defined($hum) && ($hum > 0 && $hum < 100)) { - $state .= " H: $hum" + $state .= " H: $hum"; } if (defined($windspeed)) { $state .= ' ' if (length($state) > 0); - $state .= "W: $windspeed" + $state .= "W: $windspeed"; } if (defined($rain_total)) { $state .= ' ' if (length($state) > 0); - $state .= "R: $rain_total" + $state .= "R: $rain_total"; } if (defined($rain)) { $state .= ' ' if (length($state) > 0); - $state .= "R: $rain" + $state .= "R: $rain"; } if (defined($identified)) { $state .= ' ' if (length($state) > 0); @@ -2783,7 +2783,7 @@ sub SD_WS_WH2SHIFT { "x_fhem_maintainer_github": [ "Sidey79" ], - "version": "v1.1.1", + "version": "v1.1.2", "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/controls_signalduino.txt b/controls_signalduino.txt index 551c8127d..f71a3f25d 100644 --- a/controls_signalduino.txt +++ b/controls_signalduino.txt @@ -8,7 +8,7 @@ UPD 2023-10-14_22:18:35 24045 FHEM/14_Hideki.pm UPD 2023-01-23_21:06:26 13260 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-01-07_18:08:13 166295 FHEM/14_SD_WS.pm +UPD 2024-01-07_21:06:55 166470 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 From c7053f56f9b7a110893ca24f2f84e823863ffb09 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Tue, 9 Jan 2024 20:34:53 +0000 Subject: [PATCH 50/55] Automatic updated controls and CHANGED --- CHANGED | 4 ++++ controls_signalduino.txt | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGED b/CHANGED index 1d4e4507a..7dcdabb33 100644 --- a/CHANGED +++ b/CHANGED @@ -1,3 +1,7 @@ +2024-01-09 - 14_SD_WS.pm small corrections (#1226) + +* 14_SD_WS.pm small corrections +Small corrections without changing the function of the module. 2024-01-07 - SD_WS add reading model for statistics (#1225) * add models for FHEM statistics diff --git a/controls_signalduino.txt b/controls_signalduino.txt index f71a3f25d..837e4cd82 100644 --- a/controls_signalduino.txt +++ b/controls_signalduino.txt @@ -8,7 +8,7 @@ UPD 2023-10-14_22:18:35 24045 FHEM/14_Hideki.pm UPD 2023-01-23_21:06:26 13260 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-01-07_21:06:55 166470 FHEM/14_SD_WS.pm +UPD 2024-01-09_21:34:16 166470 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 From c604c6ece8a06b8601a653f4dba1cec75d0d7d53 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 07:10:31 +0000 Subject: [PATCH 51/55] Bump tj-actions/changed-files from 39 to 42 Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 39 to 42. - [Release notes](https://github.com/tj-actions/changed-files/releases) - [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md) - [Commits](https://github.com/tj-actions/changed-files/compare/v39...v42) --- updated-dependencies: - dependency-name: tj-actions/changed-files dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/version.yml b/.github/workflows/version.yml index 79cbbb581..d5f0bc2f5 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@v39 + uses: tj-actions/changed-files@v42 with: json: true quotepath: false From 1402fd7ecbcd05e00eeac90fa4d4e4c5dab68825 Mon Sep 17 00:00:00 2001 From: sidey79 <7968127+sidey79@users.noreply.github.com> Date: Sat, 20 Jan 2024 18:20:03 +0100 Subject: [PATCH 52/55] cicd[action]: Update globstar pattern as needed by updated action --- .github/workflows/version.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/version.yml b/.github/workflows/version.yml index d5f0bc2f5..5ec673d6c 100644 --- a/.github/workflows/version.yml +++ b/.github/workflows/version.yml @@ -69,9 +69,9 @@ jobs: json: true quotepath: false files: | - FHEM/*.pm - FHEM/lib/*.pm - lib/FHEM/*.pm + FHEM/**.pm + FHEM/lib/**.pm + lib/FHEM/**.pm - name: Get current date id: date From 601a49b623c5c819e6546bd1d53ca8fda7246ff5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Jan 2024 03:54:17 +0000 Subject: [PATCH 53/55] Bump codecov/codecov-action from 3.1.4 to 3.1.5 Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3.1.4 to 3.1.5. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v3.1.4...v3.1.5) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/prove.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/prove.yml b/.github/workflows/prove.yml index 3c5eb5cba..a4ef67570 100644 --- a/.github/workflows/prove.yml +++ b/.github/workflows/prove.yml @@ -43,7 +43,7 @@ jobs: FHEM_DIR: /opt/fhem - name: Create clover report for perl Modules run: cover -report clover - - uses: codecov/codecov-action@v3.1.4 + - uses: codecov/codecov-action@v3.1.5 with: token: ${{ secrets.CODECOV_TOKEN }} file: ./cover_db/clover.xml @@ -53,7 +53,7 @@ jobs: - name: Create clover report for fhem tests working-directory: /opt/fhem/ run: cover -report clover - - uses: codecov/codecov-action@v3.1.4 + - uses: codecov/codecov-action@v3.1.5 with: token: ${{ secrets.CODECOV_TOKEN }} file: /opt/fhem/cover_db/clover.xml From 71c1772c89987ee2bed4361cb457563f57a86578 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 03:18:51 +0000 Subject: [PATCH 54/55] Bump shogo82148/actions-setup-perl from 1.27.0 to 1.28.0 --- updated-dependencies: - dependency-name: shogo82148/actions-setup-perl dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/perlCritic.yml | 2 +- .github/workflows/prove.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/perlCritic.yml b/.github/workflows/perlCritic.yml index 8d645bceb..f6bfd6c0c 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.27.0 + - uses: shogo82148/actions-setup-perl@v1.28.0 with: perl-version: 5.32 install-modules-with: cpanm diff --git a/.github/workflows/prove.yml b/.github/workflows/prove.yml index a4ef67570..eb5cf0615 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.27.0 + - uses: shogo82148/actions-setup-perl@v1.28.0 with: perl-version: ${{ matrix.perl }} install-modules-with: cpanm From bbbfa584aecacaf9f78ffdaebfa622d6a7c3e35c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 Feb 2024 22:47:52 +0000 Subject: [PATCH 55/55] Bump codecov/codecov-action from 3.1.5 to 4.0.1 Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3.1.5 to 4.0.1. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v3.1.5...v4.0.1) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/prove.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/prove.yml b/.github/workflows/prove.yml index eb5cf0615..57cb50231 100644 --- a/.github/workflows/prove.yml +++ b/.github/workflows/prove.yml @@ -43,7 +43,7 @@ jobs: FHEM_DIR: /opt/fhem - name: Create clover report for perl Modules run: cover -report clover - - uses: codecov/codecov-action@v3.1.5 + - uses: codecov/codecov-action@v4.0.1 with: token: ${{ secrets.CODECOV_TOKEN }} file: ./cover_db/clover.xml @@ -53,7 +53,7 @@ jobs: - name: Create clover report for fhem tests working-directory: /opt/fhem/ run: cover -report clover - - uses: codecov/codecov-action@v3.1.5 + - uses: codecov/codecov-action@v4.0.1 with: token: ${{ secrets.CODECOV_TOKEN }} file: /opt/fhem/cover_db/clover.xml