dev #25
@@ -1,6 +1,6 @@
 | 
			
		||||
###############################################################################
 | 
			
		||||
#
 | 
			
		||||
# Developed with Kate
 | 
			
		||||
# Developed with VSCodium
 | 
			
		||||
#
 | 
			
		||||
#  (c) 2016-2021 Copyright: Marko Oldenburg (fhemdevelopment at cooltux dot net)
 | 
			
		||||
#  All rights reserved
 | 
			
		||||
@@ -43,6 +43,14 @@ use warnings;
 | 
			
		||||
use FHEM::Meta;
 | 
			
		||||
require FHEM::Devices::Nuki::Bridge;
 | 
			
		||||
 | 
			
		||||
use GPUtils qw(GP_Import);
 | 
			
		||||
 | 
			
		||||
BEGIN {
 | 
			
		||||
 | 
			
		||||
    # Import from main context
 | 
			
		||||
    GP_Import(qw( readingFnAttributes ));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sub ::NUKIBridge_Initialize { goto &Initialize }
 | 
			
		||||
 | 
			
		||||
sub Initialize {
 | 
			
		||||
@@ -68,7 +76,7 @@ sub Initialize {
 | 
			
		||||
      . 'webhookFWinstance:'
 | 
			
		||||
      . $webhookFWinstance . ' '
 | 
			
		||||
      . 'webhookHttpHostname '
 | 
			
		||||
      . $::readingFnAttributes;
 | 
			
		||||
      . $readingFnAttributes;
 | 
			
		||||
 | 
			
		||||
    return FHEM::Meta::InitMod( __FILE__, $hash );
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
###############################################################################
 | 
			
		||||
#
 | 
			
		||||
# Developed with Kate
 | 
			
		||||
# Developed with VSCodium
 | 
			
		||||
#
 | 
			
		||||
#  (c) 2016-2021 Copyright: Marko Oldenburg (fhemdevelopment at cooltux dot net)
 | 
			
		||||
#  All rights reserved
 | 
			
		||||
@@ -32,11 +32,19 @@ use warnings;
 | 
			
		||||
use FHEM::Meta;
 | 
			
		||||
require FHEM::Devices::Nuki::Device;
 | 
			
		||||
 | 
			
		||||
use GPUtils qw(GP_Import);
 | 
			
		||||
 | 
			
		||||
BEGIN {
 | 
			
		||||
 | 
			
		||||
    # Import from main context
 | 
			
		||||
    GP_Import(qw( readingFnAttributes ));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
main::LoadModule('NUKIBridge');
 | 
			
		||||
 | 
			
		||||
sub ::NUKIDevice_Initialize { goto &Initialize }
 | 
			
		||||
 | 
			
		||||
sub Initialize($) {
 | 
			
		||||
sub Initialize {
 | 
			
		||||
    my ($hash) = @_;
 | 
			
		||||
 | 
			
		||||
    $hash->{Match} = '^{.*}$';
 | 
			
		||||
@@ -52,7 +60,7 @@ sub Initialize($) {
 | 
			
		||||
        'IODev '
 | 
			
		||||
      . 'model:smartlock,opener,smartdoor,smartlock3 '
 | 
			
		||||
      . 'disable:1 '
 | 
			
		||||
      . $::readingFnAttributes;
 | 
			
		||||
      . $readingFnAttributes;
 | 
			
		||||
 | 
			
		||||
    return FHEM::Meta::InitMod( __FILE__, $hash );
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
UPD 2021-12-05_12:27:18 9217 FHEM/73_NUKIBridge.pm
 | 
			
		||||
UPD 2021-12-05_12:27:18 7569 FHEM/74_NUKIDevice.pm
 | 
			
		||||
UPD 2021-12-10_13:24:18 42533 lib/FHEM/Devices/Nuki/Bridge.pm
 | 
			
		||||
UPD 2021-12-10_13:25:37 15802 lib/FHEM/Devices/Nuki/Device.pm
 | 
			
		||||
UPD 2021-12-10_20:21:10 9332 FHEM/73_NUKIBridge.pm
 | 
			
		||||
UPD 2021-12-10_20:22:28 7681 FHEM/74_NUKIDevice.pm
 | 
			
		||||
UPD 2021-12-10_19:44:48 42801 lib/FHEM/Devices/Nuki/Bridge.pm
 | 
			
		||||
UPD 2021-12-10_20:17:22 16247 lib/FHEM/Devices/Nuki/Device.pm
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
###############################################################################
 | 
			
		||||
#
 | 
			
		||||
# Developed with Kate
 | 
			
		||||
# Developed with VSCodium
 | 
			
		||||
#
 | 
			
		||||
#  (c) 2016-2021 Copyright: Marko Oldenburg (fhemdevelopment at cooltux dot net)
 | 
			
		||||
#  All rights reserved
 | 
			
		||||
@@ -719,6 +719,8 @@ sub DistributionErrHandle2 {
 | 
			
		||||
    my $json  = shift;
 | 
			
		||||
    my $name  = $hash->{NAME};
 | 
			
		||||
 | 
			
		||||
# 2021.12.10 13:55:43 1: PERL WARNING: Use of uninitialized value $json in string eq at lib/FHEM/Devices/Nuki/Bridge.pm line 722.
 | 
			
		||||
# Can't use string ("{"success": false}") as a HASH ref while "strict refs" in use at lib/FHEM/Devices/Nuki/Bridge.pm line 722.
 | 
			
		||||
    if (   ( $json eq '' || $json =~ /Unavailable/i )
 | 
			
		||||
        && exists( $param->{code} )
 | 
			
		||||
        && $param->{code} != 200 )
 | 
			
		||||
@@ -835,7 +837,7 @@ sub Distribution {
 | 
			
		||||
    return $errHandle1
 | 
			
		||||
      if ($errHandle1);
 | 
			
		||||
 | 
			
		||||
    $errHandle2 = DistributionErrHandle2( $hash, $param, $json );
 | 
			
		||||
    $errHandle2 = DistributionErrHandle2( $hash, $err, $param, $json );
 | 
			
		||||
    return $errHandle2
 | 
			
		||||
      if ($errHandle2);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
###############################################################################
 | 
			
		||||
#
 | 
			
		||||
# Developed with Kate
 | 
			
		||||
# Developed with VSCodium
 | 
			
		||||
#
 | 
			
		||||
#  (c) 2016-2021 Copyright: Marko Oldenburg (fhemdevelopment at cooltux dot net)
 | 
			
		||||
#  All rights reserved
 | 
			
		||||
@@ -28,24 +28,34 @@ package FHEM::Devices::Nuki::Device;
 | 
			
		||||
 | 
			
		||||
use strict;
 | 
			
		||||
use warnings;
 | 
			
		||||
use experimental qw( switch );
 | 
			
		||||
 | 
			
		||||
use FHEM::Meta;
 | 
			
		||||
 | 
			
		||||
use GPUtils qw(GP_Import);
 | 
			
		||||
 | 
			
		||||
BEGIN {
 | 
			
		||||
 | 
			
		||||
    # Import from main context
 | 
			
		||||
    GP_Import(
 | 
			
		||||
        qw( init_done
 | 
			
		||||
          defs
 | 
			
		||||
          modules
 | 
			
		||||
          )
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# try to use JSON::MaybeXS wrapper
 | 
			
		||||
#   for chance of better performance + open code
 | 
			
		||||
eval {
 | 
			
		||||
    require JSON::MaybeXS;
 | 
			
		||||
    import JSON::MaybeXS qw( decode_json encode_json );
 | 
			
		||||
    1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
if ($@) {
 | 
			
		||||
    $@ = undef;
 | 
			
		||||
} or do {
 | 
			
		||||
 | 
			
		||||
    # try to use JSON wrapper
 | 
			
		||||
    #   for chance of better performance
 | 
			
		||||
    eval {
 | 
			
		||||
 | 
			
		||||
        # JSON preference order
 | 
			
		||||
        local $ENV{PERL_JSON_BACKEND} =
 | 
			
		||||
          'Cpanel::JSON::XS,JSON::XS,JSON::PP,JSON::backportPP'
 | 
			
		||||
@@ -54,10 +64,7 @@ if ($@) {
 | 
			
		||||
        require JSON;
 | 
			
		||||
        import JSON qw( decode_json encode_json );
 | 
			
		||||
        1;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    if ($@) {
 | 
			
		||||
        $@ = undef;
 | 
			
		||||
    } or do {
 | 
			
		||||
 | 
			
		||||
        # In rare cases, Cpanel::JSON::XS may
 | 
			
		||||
        #   be installed but JSON|JSON::MaybeXS not ...
 | 
			
		||||
@@ -65,10 +72,7 @@ if ($@) {
 | 
			
		||||
            require Cpanel::JSON::XS;
 | 
			
		||||
            import Cpanel::JSON::XS qw(decode_json encode_json);
 | 
			
		||||
            1;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        if ($@) {
 | 
			
		||||
            $@ = undef;
 | 
			
		||||
        } or do {
 | 
			
		||||
 | 
			
		||||
            # In rare cases, JSON::XS may
 | 
			
		||||
            #   be installed but JSON not ...
 | 
			
		||||
@@ -76,10 +80,7 @@ if ($@) {
 | 
			
		||||
                require JSON::XS;
 | 
			
		||||
                import JSON::XS qw(decode_json encode_json);
 | 
			
		||||
                1;
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            if ($@) {
 | 
			
		||||
                $@ = undef;
 | 
			
		||||
            } or do {
 | 
			
		||||
 | 
			
		||||
                # Fallback to built-in JSON which SHOULD
 | 
			
		||||
                #   be available since 5.014 ...
 | 
			
		||||
@@ -87,20 +88,17 @@ if ($@) {
 | 
			
		||||
                    require JSON::PP;
 | 
			
		||||
                    import JSON::PP qw(decode_json encode_json);
 | 
			
		||||
                    1;
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                if ($@) {
 | 
			
		||||
                    $@ = undef;
 | 
			
		||||
                } or do {
 | 
			
		||||
 | 
			
		||||
                    # Fallback to JSON::backportPP in really rare cases
 | 
			
		||||
                    require JSON::backportPP;
 | 
			
		||||
                    import JSON::backportPP qw(decode_json encode_json);
 | 
			
		||||
                    1;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
                };
 | 
			
		||||
            };
 | 
			
		||||
        };
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
######## Begin Device
 | 
			
		||||
 | 
			
		||||
@@ -195,7 +193,9 @@ sub Define {
 | 
			
		||||
    my $def  = shift // return;
 | 
			
		||||
 | 
			
		||||
    return $@ unless ( FHEM::Meta::SetInternals($hash) );
 | 
			
		||||
    use version 0.60; our $VERSION = FHEM::Meta::Get( $hash, 'version' );
 | 
			
		||||
 | 
			
		||||
    $version = FHEM::Meta::Get( $hash, 'version' );
 | 
			
		||||
    our $VERSION = $version;
 | 
			
		||||
 | 
			
		||||
    my ( $name, undef, $nukiId, $deviceType ) = split( m{\s+}xms, $def );
 | 
			
		||||
    return 'too few parameters: define <name> NUKIDevice <nukiId> <deviceType>'
 | 
			
		||||
@@ -227,11 +227,11 @@ sub Define {
 | 
			
		||||
 | 
			
		||||
    $iodev = $hash->{IODev}->{NAME};
 | 
			
		||||
 | 
			
		||||
    $hash->{BRIDGEAPI} = $::defs{$iodev}->{BRIDGEAPI}
 | 
			
		||||
    $hash->{BRIDGEAPI} = $defs{$iodev}->{BRIDGEAPI}
 | 
			
		||||
      if ( defined($iodev)
 | 
			
		||||
        && $iodev );
 | 
			
		||||
 | 
			
		||||
    my $d = $::modules{NUKIDevice}{defptr}{$nukiId};
 | 
			
		||||
    my $d = $modules{NUKIDevice}{defptr}{$nukiId};
 | 
			
		||||
 | 
			
		||||
    return
 | 
			
		||||
        'NUKIDevice device '
 | 
			
		||||
@@ -250,11 +250,11 @@ sub Define {
 | 
			
		||||
    ::CommandAttr( undef, $name . ' model ' . $deviceTypes{$deviceType} )
 | 
			
		||||
      if ( ::AttrVal( $name, 'model', 'none' ) eq 'none' );
 | 
			
		||||
 | 
			
		||||
    $::modules{NUKIDevice}{defptr}{$nukiId} = $hash;
 | 
			
		||||
    $modules{NUKIDevice}{defptr}{$nukiId} = $hash;
 | 
			
		||||
 | 
			
		||||
    GetUpdate($hash)
 | 
			
		||||
      if ( ::ReadingsVal( $name, 'success', 'none' ) eq 'none'
 | 
			
		||||
        && $::init_done );
 | 
			
		||||
        && $init_done );
 | 
			
		||||
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
@@ -266,7 +266,7 @@ sub Undef {
 | 
			
		||||
    my $name   = $hash->{NAME};
 | 
			
		||||
 | 
			
		||||
    ::Log3( $name, 3, "NUKIDevice ($name) - undefined with NukiId: $nukiId" );
 | 
			
		||||
    delete( $::modules{NUKIDevice}{defptr}{$nukiId} );
 | 
			
		||||
    delete( $modules{NUKIDevice}{defptr}{$nukiId} );
 | 
			
		||||
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
@@ -277,7 +277,7 @@ sub Attr {
 | 
			
		||||
    my $attrName = shift;
 | 
			
		||||
    my $attrVal  = shift;
 | 
			
		||||
 | 
			
		||||
    my $hash  = $::defs{$name};
 | 
			
		||||
    my $hash  = $defs{$name};
 | 
			
		||||
    my $token = $hash->{IODev}->{TOKEN};
 | 
			
		||||
 | 
			
		||||
    if ( $attrName eq 'disable' ) {
 | 
			
		||||
@@ -330,17 +330,13 @@ sub Notify {
 | 
			
		||||
    GetUpdate($hash)
 | 
			
		||||
      if (
 | 
			
		||||
        (
 | 
			
		||||
            grep /^INITIALIZED$/,
 | 
			
		||||
            @{$events}
 | 
			
		||||
            or grep /^REREADCFG$/,
 | 
			
		||||
            @{$events}
 | 
			
		||||
            or grep /^MODIFIED.$name$/,
 | 
			
		||||
            @{$events}
 | 
			
		||||
            or grep /^DEFINED.$name$/,
 | 
			
		||||
            @{$events}
 | 
			
		||||
               grep { /^INITIALIZED$/x } @{$events}
 | 
			
		||||
            or grep { /^REREADCFG$/x } @{$events}
 | 
			
		||||
            or grep { /^MODIFIED.$name$/x } @{$events}
 | 
			
		||||
            or grep { /^DEFINED.$name$/x } @{$events}
 | 
			
		||||
        )
 | 
			
		||||
        && $devname eq 'global'
 | 
			
		||||
        && $::init_done
 | 
			
		||||
        && $init_done
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
    return;
 | 
			
		||||
@@ -427,7 +423,7 @@ sub Parse {
 | 
			
		||||
    #########################################
 | 
			
		||||
    ####### Errorhandling #############
 | 
			
		||||
 | 
			
		||||
    if ( $json !~ m/^[\[{].*[}\]]$/ ) {
 | 
			
		||||
    if ( $json !~ m{\A[\[{].*[}\]]\z}xms ) {
 | 
			
		||||
        ::Log3( $name, 3, "NUKIDevice ($name) - invalid json detected: $json" );
 | 
			
		||||
        return "NUKIDevice ($name) - invalid json detected: $json";
 | 
			
		||||
    }
 | 
			
		||||
@@ -449,18 +445,18 @@ sub Parse {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    my $nukiId = $decode_json->{nukiId};
 | 
			
		||||
    if ( my $hash = $::modules{NUKIDevice}{defptr}{$nukiId} ) {
 | 
			
		||||
        my $name = $hash->{NAME};
 | 
			
		||||
    if ( my $dhash = $modules{NUKIDevice}{defptr}{$nukiId} ) {
 | 
			
		||||
        my $dname = $dhash->{NAME};
 | 
			
		||||
 | 
			
		||||
        WriteReadings( $hash, $decode_json );
 | 
			
		||||
        ::Log3( $name, 4,
 | 
			
		||||
            "NUKIDevice ($name) - find logical device: $hash->{NAME}" );
 | 
			
		||||
        WriteReadings( $dhash, $decode_json );
 | 
			
		||||
        ::Log3( $dname, 4,
 | 
			
		||||
            "NUKIDevice ($dname) - find logical device: $dhash->{NAME}" );
 | 
			
		||||
 | 
			
		||||
        return $hash->{NAME};
 | 
			
		||||
        return $dhash->{NAME};
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        ::Log3( $name, 4,
 | 
			
		||||
                "NUKIDevice ($name) - autocreate new device "
 | 
			
		||||
        ::Log3( $dname, 4,
 | 
			
		||||
                "NUKIDevice ($dname) - autocreate new device "
 | 
			
		||||
              . ::makeDeviceName( $decode_json->{name} )
 | 
			
		||||
              . " with nukiId $decode_json->{nukiId}, model $decode_json->{deviceType}"
 | 
			
		||||
        );
 | 
			
		||||
@@ -472,16 +468,14 @@ sub Parse {
 | 
			
		||||
 | 
			
		||||
    ::Log3( $name, 5, "NUKIDevice ($name) - parse status message for $name" );
 | 
			
		||||
 | 
			
		||||
    WriteReadings( $hash, $decode_json );
 | 
			
		||||
    return WriteReadings( $hash, $decode_json );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sub WriteReadings {
 | 
			
		||||
    my $hash        = shift;
 | 
			
		||||
    my $decode_json = shift;
 | 
			
		||||
    my $name        = $hash->{NAME};
 | 
			
		||||
 | 
			
		||||
sub SmartlockState {
 | 
			
		||||
    ############################
 | 
			
		||||
    #### Status des Smartlock
 | 
			
		||||
    my $hash        = shift;
 | 
			
		||||
    my $decode_json = shift;
 | 
			
		||||
 | 
			
		||||
    if ( defined( $hash->{helper}{lockAction} ) ) {
 | 
			
		||||
        my $state;
 | 
			
		||||
@@ -527,6 +521,16 @@ sub WriteReadings {
 | 
			
		||||
        delete $hash->{helper}{lockAction};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sub WriteReadings {
 | 
			
		||||
    my $hash        = shift;
 | 
			
		||||
    my $decode_json = shift;
 | 
			
		||||
    my $name        = $hash->{NAME};
 | 
			
		||||
 | 
			
		||||
    SmartlockState();
 | 
			
		||||
 | 
			
		||||
    ::readingsBeginUpdate($hash);
 | 
			
		||||
 | 
			
		||||
    my $t;
 | 
			
		||||
@@ -555,36 +559,43 @@ sub WriteReadings {
 | 
			
		||||
            && $t ne 'doorsensorState'
 | 
			
		||||
            && $t ne 'doorsensorStateName' );
 | 
			
		||||
 | 
			
		||||
        ::readingsBulkUpdate(
 | 
			
		||||
            $hash, $t,
 | 
			
		||||
            (
 | 
			
		||||
                  $v =~ m/^[0-9]$/
 | 
			
		||||
                ? $lockStates{$v}{ $hash->{DEVICETYPEID} }
 | 
			
		||||
                : $v
 | 
			
		||||
            )
 | 
			
		||||
        ) if ( $t eq 'state' );
 | 
			
		||||
 | 
			
		||||
        ::readingsBulkUpdate( $hash, $t, $modes{$v}{ $hash->{DEVICETYPEID} } )
 | 
			
		||||
          if ( $t eq 'mode' );
 | 
			
		||||
 | 
			
		||||
        ::readingsBulkUpdate( $hash, $t, $deviceTypes{$v} )
 | 
			
		||||
          if ( $t eq 'deviceType' );
 | 
			
		||||
 | 
			
		||||
        ::readingsBulkUpdate( $hash, $t, $doorsensorStates{$v} )
 | 
			
		||||
          if ( $t eq 'doorsensorState' );
 | 
			
		||||
 | 
			
		||||
        ::readingsBulkUpdate( $hash, $t, ( $v == 1 ? 'true' : 'false' ) )
 | 
			
		||||
          if ( $t eq 'paired' );
 | 
			
		||||
 | 
			
		||||
        ::readingsBulkUpdate( $hash, $t, ( $v == 1 ? 'true' : 'false' ) )
 | 
			
		||||
          if ( $t eq 'batteryCharging' );
 | 
			
		||||
 | 
			
		||||
        ::readingsBulkUpdate( $hash, 'batteryState',
 | 
			
		||||
            ( $v == 1 ? 'low' : 'ok' ) )
 | 
			
		||||
          if ( $t eq 'batteryCritical' );
 | 
			
		||||
 | 
			
		||||
        ::readingsBulkUpdate( $hash, 'batteryPercent', $v )
 | 
			
		||||
          if ( $t eq 'batteryChargeState' );
 | 
			
		||||
        given ($t) {
 | 
			
		||||
            when ('state') {
 | 
			
		||||
                ::readingsBulkUpdate(
 | 
			
		||||
                    $hash, $t,
 | 
			
		||||
                    (
 | 
			
		||||
                          $v =~ m{\A[0-9]\z}xms
 | 
			
		||||
                        ? $lockStates{$v}->{ $hash->{DEVICETYPEID} }
 | 
			
		||||
                        : $v
 | 
			
		||||
                    )
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
            when ('mode') {
 | 
			
		||||
                ::readingsBulkUpdate( $hash, $t,
 | 
			
		||||
                    $modes{$v}{ $hash->{DEVICETYPEID} } );
 | 
			
		||||
            }
 | 
			
		||||
            when ('deviceType') {
 | 
			
		||||
                ::readingsBulkUpdate( $hash, $t, $deviceTypes{$v} );
 | 
			
		||||
            }
 | 
			
		||||
            when ('doorsensorState') {
 | 
			
		||||
                ::readingsBulkUpdate( $hash, $t, $doorsensorStates{$v} );
 | 
			
		||||
            }
 | 
			
		||||
            when ('paired') {
 | 
			
		||||
                ::readingsBulkUpdate( $hash, $t,
 | 
			
		||||
                    ( $v == 1 ? 'true' : 'false' ) );
 | 
			
		||||
            }
 | 
			
		||||
            when ('batteryCharging') {
 | 
			
		||||
                ::readingsBulkUpdate( $hash, $t,
 | 
			
		||||
                    ( $v == 1 ? 'true' : 'false' ) );
 | 
			
		||||
            }
 | 
			
		||||
            when ('batteryCritical') {
 | 
			
		||||
                ::readingsBulkUpdate( $hash, 'batteryState',
 | 
			
		||||
                    ( $v == 1 ? 'low' : 'ok' ) );
 | 
			
		||||
            }
 | 
			
		||||
            when ('batteryChargeState') {
 | 
			
		||||
                ::readingsBulkUpdate( $hash, 'batteryPercent', $v )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ::readingsEndUpdate( $hash, 1 );
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user