fix temperature bug if temp negativ
rewrite parts of code
This commit is contained in:
parent
2468631700
commit
3dce1c8328
@ -1,8 +1,8 @@
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
#
|
#
|
||||||
# Developed with Kate
|
# Developed with VSCodium and richterger perl plugin.
|
||||||
#
|
#
|
||||||
# (c) 2017-2020 Copyright: Marko Oldenburg (leongaultier at gmail dot com)
|
# (c) 2017-2022 Copyright: Marko Oldenburg (fhemdevelopment at cooltux dot net)
|
||||||
# All rights reserved
|
# All rights reserved
|
||||||
#
|
#
|
||||||
# Special thanks goes to:
|
# Special thanks goes to:
|
||||||
@ -37,30 +37,28 @@
|
|||||||
|
|
||||||
package FHEM::XiaomiBTLESens;
|
package FHEM::XiaomiBTLESens;
|
||||||
|
|
||||||
my $missingModul = q{};
|
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
use experimental qw /switch/;
|
||||||
|
|
||||||
use POSIX;
|
use POSIX;
|
||||||
use FHEM::Meta;
|
use FHEM::Meta;
|
||||||
|
|
||||||
use GPUtils qw(GP_Import GP_Export);
|
use GPUtils qw(GP_Import GP_Export);
|
||||||
|
|
||||||
|
my $missingModul = q{};
|
||||||
|
|
||||||
# try to use JSON::MaybeXS wrapper
|
# try to use JSON::MaybeXS wrapper
|
||||||
# for chance of better performance + open code
|
# for chance of better performance + open code
|
||||||
eval {
|
eval {
|
||||||
require JSON::MaybeXS;
|
require JSON::MaybeXS;
|
||||||
import JSON::MaybeXS qw( decode_json encode_json );
|
import JSON::MaybeXS qw( decode_json encode_json );
|
||||||
1;
|
1;
|
||||||
};
|
} or do {
|
||||||
|
|
||||||
if ($@) {
|
|
||||||
$@ = undef;
|
|
||||||
|
|
||||||
# try to use JSON wrapper
|
# try to use JSON wrapper
|
||||||
# for chance of better performance
|
# for chance of better performance
|
||||||
eval {
|
eval {
|
||||||
|
|
||||||
# JSON preference order
|
# JSON preference order
|
||||||
local $ENV{PERL_JSON_BACKEND} =
|
local $ENV{PERL_JSON_BACKEND} =
|
||||||
'Cpanel::JSON::XS,JSON::XS,JSON::PP,JSON::backportPP'
|
'Cpanel::JSON::XS,JSON::XS,JSON::PP,JSON::backportPP'
|
||||||
@ -69,10 +67,7 @@ if ($@) {
|
|||||||
require JSON;
|
require JSON;
|
||||||
import JSON qw( decode_json encode_json );
|
import JSON qw( decode_json encode_json );
|
||||||
1;
|
1;
|
||||||
};
|
} or do {
|
||||||
|
|
||||||
if ($@) {
|
|
||||||
$@ = undef;
|
|
||||||
|
|
||||||
# In rare cases, Cpanel::JSON::XS may
|
# In rare cases, Cpanel::JSON::XS may
|
||||||
# be installed but JSON|JSON::MaybeXS not ...
|
# be installed but JSON|JSON::MaybeXS not ...
|
||||||
@ -80,10 +75,7 @@ if ($@) {
|
|||||||
require Cpanel::JSON::XS;
|
require Cpanel::JSON::XS;
|
||||||
import Cpanel::JSON::XS qw(decode_json encode_json);
|
import Cpanel::JSON::XS qw(decode_json encode_json);
|
||||||
1;
|
1;
|
||||||
};
|
} or do {
|
||||||
|
|
||||||
if ($@) {
|
|
||||||
$@ = undef;
|
|
||||||
|
|
||||||
# In rare cases, JSON::XS may
|
# In rare cases, JSON::XS may
|
||||||
# be installed but JSON not ...
|
# be installed but JSON not ...
|
||||||
@ -91,10 +83,7 @@ if ($@) {
|
|||||||
require JSON::XS;
|
require JSON::XS;
|
||||||
import JSON::XS qw(decode_json encode_json);
|
import JSON::XS qw(decode_json encode_json);
|
||||||
1;
|
1;
|
||||||
};
|
} or do {
|
||||||
|
|
||||||
if ($@) {
|
|
||||||
$@ = undef;
|
|
||||||
|
|
||||||
# Fallback to built-in JSON which SHOULD
|
# Fallback to built-in JSON which SHOULD
|
||||||
# be available since 5.014 ...
|
# be available since 5.014 ...
|
||||||
@ -102,22 +91,19 @@ if ($@) {
|
|||||||
require JSON::PP;
|
require JSON::PP;
|
||||||
import JSON::PP qw(decode_json encode_json);
|
import JSON::PP qw(decode_json encode_json);
|
||||||
1;
|
1;
|
||||||
};
|
} or do {
|
||||||
|
|
||||||
if ($@) {
|
|
||||||
$@ = undef;
|
|
||||||
|
|
||||||
# Fallback to JSON::backportPP in really rare cases
|
# Fallback to JSON::backportPP in really rare cases
|
||||||
require JSON::backportPP;
|
require JSON::backportPP;
|
||||||
import JSON::backportPP qw(decode_json encode_json);
|
import JSON::backportPP qw(decode_json encode_json);
|
||||||
1;
|
1;
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
eval "use Blocking;1" or $missingModul .= "Blocking ";
|
eval { require Blocking; 1 } or $missingModul .= "Blocking ";
|
||||||
|
|
||||||
#use Data::Dumper; only for Debugging
|
#use Data::Dumper; only for Debugging
|
||||||
|
|
||||||
@ -153,14 +139,6 @@ BEGIN {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#-- Export to main context with different name
|
|
||||||
GP_Export(
|
|
||||||
qw(
|
|
||||||
Initialize
|
|
||||||
stateRequestTimer
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
my %XiaomiModels = (
|
my %XiaomiModels = (
|
||||||
flowerSens => {
|
flowerSens => {
|
||||||
'rdata' => '0x35',
|
'rdata' => '0x35',
|
||||||
@ -206,6 +184,8 @@ my %CallBatteryAge = (
|
|||||||
'48h' => 172800
|
'48h' => 172800
|
||||||
);
|
);
|
||||||
|
|
||||||
|
sub ::XiaomiBTLESens_Initialize { goto &Initialize }
|
||||||
|
|
||||||
sub Initialize {
|
sub Initialize {
|
||||||
my $hash = shift;
|
my $hash = shift;
|
||||||
|
|
||||||
@ -242,9 +222,12 @@ sub Initialize {
|
|||||||
sub Define {
|
sub Define {
|
||||||
my $hash = shift;
|
my $hash = shift;
|
||||||
my $arg_ref = shift;
|
my $arg_ref = shift;
|
||||||
|
my $version;
|
||||||
|
|
||||||
return $@ if ( !FHEM::Meta::SetInternals($hash) );
|
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;
|
||||||
|
|
||||||
return 'too few parameters: define <name> XiaomiBTLESens <BTMAC>'
|
return 'too few parameters: define <name> XiaomiBTLESens <BTMAC>'
|
||||||
if ( scalar( @{$arg_ref} ) != 3 );
|
if ( scalar( @{$arg_ref} ) != 3 );
|
||||||
@ -296,72 +279,76 @@ sub Attr {
|
|||||||
my ( $cmd, $name, $attrName, $attrVal ) = @_;
|
my ( $cmd, $name, $attrName, $attrVal ) = @_;
|
||||||
my $hash = $defs{$name};
|
my $hash = $defs{$name};
|
||||||
|
|
||||||
if ( $attrName eq 'disable' ) {
|
given ($attrName) {
|
||||||
if ( $cmd eq 'set' && $attrVal == 1 ) {
|
when ('disable') {
|
||||||
|
if ( $cmd eq 'set' && $attrVal == 1 ) {
|
||||||
|
RemoveInternalTimer($hash);
|
||||||
|
|
||||||
|
readingsSingleUpdate( $hash, 'state', 'disabled', 1 );
|
||||||
|
Log3( $name, 3, "XiaomiBTLESens ($name) - disabled" );
|
||||||
|
}
|
||||||
|
|
||||||
|
elsif ( $cmd eq 'del' ) {
|
||||||
|
Log3( $name, 3, "XiaomiBTLESens ($name) - enabled" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
when ('disabledForIntervals') {
|
||||||
|
if ( $cmd eq 'set' ) {
|
||||||
|
## no critic (Only use a capturing group if you plan to use the captured value)
|
||||||
|
return
|
||||||
|
'check disabledForIntervals Syntax HH:MM-HH:MM or HH:MM-HH:MM HH:MM-HH:MM ...'
|
||||||
|
if ( $attrVal !~ /^((\d{2}:\d{2})-(\d{2}:\d{2})\s?)+$/x );
|
||||||
|
## use critic
|
||||||
|
Log3( $name, 3,
|
||||||
|
"XiaomiBTLESens ($name) - disabledForIntervals" );
|
||||||
|
stateRequest($hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
elsif ( $cmd eq 'del' ) {
|
||||||
|
Log3( $name, 3, "XiaomiBTLESens ($name) - enabled" );
|
||||||
|
readingsSingleUpdate( $hash, 'state', 'active', 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
when ('interval') {
|
||||||
RemoveInternalTimer($hash);
|
RemoveInternalTimer($hash);
|
||||||
|
|
||||||
readingsSingleUpdate( $hash, 'state', 'disabled', 1 );
|
if ( $cmd eq 'set' ) {
|
||||||
Log3( $name, 3, "XiaomiBTLESens ($name) - disabled" );
|
if ( $attrVal < 120 ) {
|
||||||
}
|
Log3( $name, 3,
|
||||||
|
|
||||||
elsif ( $cmd eq 'del' ) {
|
|
||||||
Log3( $name, 3, "XiaomiBTLESens ($name) - enabled" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
elsif ( $attrName eq 'disabledForIntervals' ) {
|
|
||||||
if ( $cmd eq 'set' ) {
|
|
||||||
return
|
|
||||||
'check disabledForIntervals Syntax HH:MM-HH:MM or HH:MM-HH:MM HH:MM-HH:MM ...'
|
|
||||||
if ( $attrVal !~ /^((\d{2}:\d{2})-(\d{2}:\d{2})\s?)+$/ );
|
|
||||||
Log3( $name, 3, "XiaomiBTLESens ($name) - disabledForIntervals" );
|
|
||||||
stateRequest($hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
elsif ( $cmd eq 'del' ) {
|
|
||||||
Log3( $name, 3, "XiaomiBTLESens ($name) - enabled" );
|
|
||||||
readingsSingleUpdate( $hash, 'state', 'active', 1 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
elsif ( $attrName eq 'interval' ) {
|
|
||||||
RemoveInternalTimer($hash);
|
|
||||||
|
|
||||||
if ( $cmd eq 'set' ) {
|
|
||||||
if ( $attrVal < 120 ) {
|
|
||||||
Log3( $name, 3,
|
|
||||||
"XiaomiBTLESens ($name) - interval too small, please use something >= 120 (sec), default is 300 (sec)"
|
"XiaomiBTLESens ($name) - interval too small, please use something >= 120 (sec), default is 300 (sec)"
|
||||||
);
|
);
|
||||||
return
|
return
|
||||||
'interval too small, please use something >= 120 (sec), default is 300 (sec)';
|
'interval too small, please use something >= 120 (sec), default is 300 (sec)';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$hash->{INTERVAL} = $attrVal;
|
||||||
|
Log3( $name, 3,
|
||||||
|
"XiaomiBTLESens ($name) - set interval to $attrVal" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
$hash->{INTERVAL} = $attrVal;
|
elsif ( $cmd eq 'del' ) {
|
||||||
|
$hash->{INTERVAL} = 300;
|
||||||
Log3( $name, 3,
|
Log3( $name, 3,
|
||||||
"XiaomiBTLESens ($name) - set interval to $attrVal" );
|
"XiaomiBTLESens ($name) - set interval to default" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
elsif ( $cmd eq 'del' ) {
|
when ('blockingCallLoglevel') {
|
||||||
$hash->{INTERVAL} = 300;
|
if ( $cmd eq 'set' ) {
|
||||||
Log3( $name, 3,
|
$hash->{loglevel} = $attrVal;
|
||||||
"XiaomiBTLESens ($name) - set interval to default" );
|
Log3( $name, 3,
|
||||||
}
|
"XiaomiBTLESens ($name) - set blockingCallLoglevel to $attrVal"
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
|
||||||
elsif ( $attrName eq 'blockingCallLoglevel' ) {
|
elsif ( $cmd eq 'del' ) {
|
||||||
if ( $cmd eq 'set' ) {
|
$hash->{loglevel} = 4;
|
||||||
$hash->{loglevel} = $attrVal;
|
Log3( $name, 3,
|
||||||
Log3( $name, 3,
|
"XiaomiBTLESens ($name) - set blockingCallLoglevel to default"
|
||||||
"XiaomiBTLESens ($name) - set blockingCallLoglevel to $attrVal"
|
);
|
||||||
);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
elsif ( $cmd eq 'del' ) {
|
|
||||||
$hash->{loglevel} = 4;
|
|
||||||
Log3( $name, 3,
|
|
||||||
"XiaomiBTLESens ($name) - set blockingCallLoglevel to default"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,35 +372,24 @@ sub Notify {
|
|||||||
(
|
(
|
||||||
(
|
(
|
||||||
(
|
(
|
||||||
grep /^DEFINED.$name$/,
|
grep { /^DEFINED.$name$/x } @{$events}
|
||||||
@{$events}
|
or grep { /^DELETEATTR.$name.disable$/x } @{$events}
|
||||||
or grep /^DELETEATTR.$name.disable$/,
|
or grep { /^ATTR.$name.disable.0$/x } @{$events}
|
||||||
@{$events}
|
or grep { /^DELETEATTR.$name.interval$/x } @{$events}
|
||||||
or grep /^ATTR.$name.disable.0$/,
|
or grep { /^DELETEATTR.$name.model$/x } @{$events}
|
||||||
@{$events}
|
or grep { /^ATTR.$name.model.+/x } @{$events}
|
||||||
or grep /^DELETEATTR.$name.interval$/,
|
or grep { /^ATTR.$name.interval.[0-9]+/x } @{$events}
|
||||||
@{$events}
|
|
||||||
or grep /^DELETEATTR.$name.model$/,
|
|
||||||
@{$events}
|
|
||||||
or grep /^ATTR.$name.model.+/,
|
|
||||||
@{$events}
|
|
||||||
or grep /^ATTR.$name.interval.[0-9]+/,
|
|
||||||
@{$events}
|
|
||||||
)
|
)
|
||||||
&& $devname eq 'global'
|
&& $devname eq 'global'
|
||||||
)
|
)
|
||||||
or grep /^resetBatteryTimestamp$/,
|
or grep { /^resetBatteryTimestamp$/x } @{$events}
|
||||||
@{$events}
|
|
||||||
)
|
)
|
||||||
&& $init_done
|
&& $init_done
|
||||||
|| (
|
|| (
|
||||||
(
|
(
|
||||||
grep /^INITIALIZED$/,
|
grep { /^INITIALIZED$/x } @{$events}
|
||||||
@{$events}
|
or grep { /^REREADCFG$/x } @{$events}
|
||||||
or grep /^REREADCFG$/,
|
or grep { /^MODIFIED.$name$/x } @{$events}
|
||||||
@{$events}
|
|
||||||
or grep /^MODIFIED.$name$/,
|
|
||||||
@{$events}
|
|
||||||
)
|
)
|
||||||
&& $devname eq 'global'
|
&& $devname eq 'global'
|
||||||
)
|
)
|
||||||
@ -427,8 +403,7 @@ sub Notify {
|
|||||||
|| AttrVal( $name, 'model', 'mijiaLYWSD03MMC' ) eq 'mijiaLYWSD03MMC'
|
|| AttrVal( $name, 'model', 'mijiaLYWSD03MMC' ) eq 'mijiaLYWSD03MMC'
|
||||||
)
|
)
|
||||||
&& $devname eq $name
|
&& $devname eq $name
|
||||||
&& grep /^$name.firmware.+/,
|
&& grep { /^$name.firmware.+/x } @{$events}
|
||||||
@{$events}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -509,7 +484,7 @@ sub stateRequestTimer {
|
|||||||
stateRequest($hash);
|
stateRequest($hash);
|
||||||
|
|
||||||
InternalTimer( gettimeofday() + $hash->{INTERVAL} + int( rand(300) ),
|
InternalTimer( gettimeofday() + $hash->{INTERVAL} + int( rand(300) ),
|
||||||
'XiaomiBTLESens_stateRequestTimer', $hash );
|
\&FHEM::XiaomiBTLESens::stateRequestTimer, $hash );
|
||||||
|
|
||||||
Log3( $name, 4,
|
Log3( $name, 4,
|
||||||
"XiaomiBTLESens ($name) - stateRequestTimer: Call Request Timer" );
|
"XiaomiBTLESens ($name) - stateRequestTimer: Call Request Timer" );
|
||||||
@ -517,7 +492,7 @@ sub stateRequestTimer {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub Set($$@) {
|
sub Set {
|
||||||
my $hash = shift;
|
my $hash = shift;
|
||||||
my $arg_ref = shift;
|
my $arg_ref = shift;
|
||||||
my $name = shift @$arg_ref;
|
my $name = shift @$arg_ref;
|
||||||
@ -585,14 +560,14 @@ sub Get {
|
|||||||
elsif ( $cmd eq 'firmware' ) {
|
elsif ( $cmd eq 'firmware' ) {
|
||||||
return 'usage: firmware' if ( scalar( @{$arg_ref} ) != 0 );
|
return 'usage: firmware' if ( scalar( @{$arg_ref} ) != 0 );
|
||||||
|
|
||||||
$mod = 'read';
|
$mod = 'read';
|
||||||
$handle = $XiaomiModels{ AttrVal( $name, 'model', '' ) }{firmware};
|
$handle = $XiaomiModels{ AttrVal( $name, 'model', '' ) }{firmware};
|
||||||
|
|
||||||
}
|
}
|
||||||
elsif ( $cmd eq 'devicename' ) {
|
elsif ( $cmd eq 'devicename' ) {
|
||||||
return "usage: devicename" if ( scalar( @{$arg_ref} ) != 0 );
|
return "usage: devicename" if ( scalar( @{$arg_ref} ) != 0 );
|
||||||
|
|
||||||
$mod = 'read';
|
$mod = 'read';
|
||||||
$handle = $XiaomiModels{ AttrVal( $name, 'model', '' ) }{devicename};
|
$handle = $XiaomiModels{ AttrVal( $name, 'model', '' ) }{devicename};
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -670,7 +645,9 @@ sub CreateParamGatttool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub Gatttool_executeCommand {
|
sub Gatttool_executeCommand {
|
||||||
my $command = join q{ }, @_;
|
my @command = @_;
|
||||||
|
## no critic (Backtick operator used . Use IPC::Open3 instead)
|
||||||
|
my $command = join q{ }, @command;
|
||||||
return ( $_ = qx{$command 2>&1}, $? >> 8 );
|
return ( $_ = qx{$command 2>&1}, $? >> 8 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -683,8 +660,11 @@ sub ExecGatttool_Run {
|
|||||||
my $gatttool;
|
my $gatttool;
|
||||||
my $json_notification;
|
my $json_notification;
|
||||||
|
|
||||||
$gatttool = qx(which gatttool) if ( $sshHost eq 'none' );
|
## no critic (Backtick operator used . Use IPC::Open3 instead)
|
||||||
|
$gatttool = qx(which gatttool) if ( $sshHost eq 'none' );
|
||||||
$gatttool = qx(ssh $sshHost 'which gatttool') if ( $sshHost ne 'none' );
|
$gatttool = qx(ssh $sshHost 'which gatttool') if ( $sshHost ne 'none' );
|
||||||
|
## use critic
|
||||||
|
|
||||||
chomp $gatttool;
|
chomp $gatttool;
|
||||||
|
|
||||||
if ( defined($gatttool) && ($gatttool) ) {
|
if ( defined($gatttool) && ($gatttool) ) {
|
||||||
@ -692,12 +672,11 @@ sub ExecGatttool_Run {
|
|||||||
my $cmd;
|
my $cmd;
|
||||||
my $loop;
|
my $loop;
|
||||||
my @gtResult;
|
my @gtResult;
|
||||||
my $wait = 1;
|
my $wait = 1;
|
||||||
my $sshHost = AttrVal( $name, 'sshHost', 'none' );
|
my $hci = AttrVal( $name, 'hciDevice', 'hci0' );
|
||||||
my $hci = AttrVal( $name, 'hciDevice', 'hci0' );
|
|
||||||
|
|
||||||
$cmd .= "ssh $sshHost '" if ( $sshHost ne 'none' );
|
$cmd .= "ssh $sshHost '" if ( $sshHost ne 'none' );
|
||||||
$cmd .= "timeout 10 " if ($listen);
|
$cmd .= "timeout 10 " if ($listen);
|
||||||
$cmd .= "gatttool -i $hci -b $mac ";
|
$cmd .= "gatttool -i $hci -b $mac ";
|
||||||
$cmd .= "--char-read -a $handle" if ( $gattCmd eq 'read' );
|
$cmd .= "--char-read -a $handle" if ( $gattCmd eq 'read' );
|
||||||
$cmd .= "--char-write-req -a $handle -n $value"
|
$cmd .= "--char-write-req -a $handle -n $value"
|
||||||
@ -724,17 +703,17 @@ sub ExecGatttool_Run {
|
|||||||
"XiaomiBTLESens ($name) - ExecGatttool_Run: Execute Command $psCommand | grep -E $gatttoolCmdlineStaticEscaped"
|
"XiaomiBTLESens ($name) - ExecGatttool_Run: Execute Command $psCommand | grep -E $gatttoolCmdlineStaticEscaped"
|
||||||
);
|
);
|
||||||
|
|
||||||
# $grepGatttool = qx(ps ax| grep -E \'$gatttoolCmdlineStaticEscaped\')
|
## no critic (Backtick operator used . Use IPC::Open3 instead)
|
||||||
$grepGatttool =
|
$grepGatttool =
|
||||||
qx($psCommand | grep -E \'$gatttoolCmdlineStaticEscaped\')
|
qx($psCommand | grep -E \'$gatttoolCmdlineStaticEscaped\')
|
||||||
if ( $sshHost eq 'none' );
|
if ( $sshHost eq 'none' );
|
||||||
|
|
||||||
# $grepGatttool = qx(ssh $sshHost 'ps ax| grep -E "$gatttoolCmdlineStaticEscaped"')
|
|
||||||
$grepGatttool =
|
$grepGatttool =
|
||||||
qx(ssh $sshHost '$psCommand | grep -E "$gatttoolCmdlineStaticEscaped"')
|
qx(ssh $sshHost '$psCommand | grep -E "$gatttoolCmdlineStaticEscaped"')
|
||||||
if ( $sshHost ne 'none' );
|
if ( $sshHost ne 'none' );
|
||||||
|
## use critic
|
||||||
|
|
||||||
if ( not $grepGatttool =~ /^\s*$/ ) {
|
if ( not $grepGatttool =~ /^\s*$/x ) {
|
||||||
Log3( $name, 3,
|
Log3( $name, 3,
|
||||||
"XiaomiBTLESens ($name) - ExecGatttool_Run: another gatttool process is running. waiting..."
|
"XiaomiBTLESens ($name) - ExecGatttool_Run: another gatttool process is running. waiting..."
|
||||||
);
|
);
|
||||||
@ -755,11 +734,15 @@ qx(ssh $sshHost '$psCommand | grep -E "$gatttoolCmdlineStaticEscaped"')
|
|||||||
);
|
);
|
||||||
|
|
||||||
( $returnString, $returnCode ) = Gatttool_executeCommand($cmd);
|
( $returnString, $returnCode ) = Gatttool_executeCommand($cmd);
|
||||||
@gtResult = split /:\s/, $returnString;
|
@gtResult = split /:\s/x, $returnString;
|
||||||
|
|
||||||
Log3( $name, 5,
|
Log3(
|
||||||
|
$name,
|
||||||
|
5,
|
||||||
"XiaomiBTLESens ($name) - ExecGatttool_Run: gatttool loop result "
|
"XiaomiBTLESens ($name) - ExecGatttool_Run: gatttool loop result "
|
||||||
. join q{,}, @gtResult );
|
. join q{,},
|
||||||
|
@gtResult
|
||||||
|
);
|
||||||
|
|
||||||
$returnCode = 2
|
$returnCode = 2
|
||||||
if ( !defined( $gtResult[0] ) );
|
if ( !defined( $gtResult[0] ) );
|
||||||
@ -770,9 +753,13 @@ qx(ssh $sshHost '$psCommand | grep -E "$gatttoolCmdlineStaticEscaped"')
|
|||||||
"XiaomiBTLESens ($name) - ExecGatttool_Run: errorcode: \"$returnCode\", ErrorString: \"$returnString\""
|
"XiaomiBTLESens ($name) - ExecGatttool_Run: errorcode: \"$returnCode\", ErrorString: \"$returnString\""
|
||||||
) if ( $returnCode != 0 && $returnCode != 124 );
|
) if ( $returnCode != 0 && $returnCode != 124 );
|
||||||
|
|
||||||
Log3( $name, 4,
|
Log3(
|
||||||
|
$name,
|
||||||
|
4,
|
||||||
"XiaomiBTLESens ($name) - ExecGatttool_Run: gatttool result "
|
"XiaomiBTLESens ($name) - ExecGatttool_Run: gatttool result "
|
||||||
. join q{,}, @gtResult );
|
. join q{,},
|
||||||
|
@gtResult
|
||||||
|
);
|
||||||
|
|
||||||
$handle = '0x35'
|
$handle = '0x35'
|
||||||
if ( $sshHost ne 'none'
|
if ( $sshHost ne 'none'
|
||||||
@ -788,12 +775,12 @@ qx(ssh $sshHost '$psCommand | grep -E "$gatttoolCmdlineStaticEscaped"')
|
|||||||
|
|
||||||
if ( $gtResult[1] ne 'no data response' && $listen ) {
|
if ( $gtResult[1] ne 'no data response' && $listen ) {
|
||||||
( $gtResult[1] ) = split '\n', $gtResult[1];
|
( $gtResult[1] ) = split '\n', $gtResult[1];
|
||||||
$gtResult[1] =~ s/\\n//g;
|
$gtResult[1] =~ s/\\n//xg;
|
||||||
}
|
}
|
||||||
|
|
||||||
$json_notification = encodeJSON( $gtResult[1] );
|
$json_notification = encodeJSON( $gtResult[1] );
|
||||||
|
|
||||||
if ( $gtResult[1] =~ /^([0-9a-f]{2}(\s?))*$/ ) {
|
if ( $gtResult[1] =~ /^([0-9a-f]{2}(\s?))*$/x ) {
|
||||||
return "$name|$mac|ok|$gattCmd|$handle|$json_notification";
|
return "$name|$mac|ok|$gattCmd|$handle|$json_notification";
|
||||||
}
|
}
|
||||||
elsif ( $returnCode == 0 && $gattCmd eq 'write' ) {
|
elsif ( $returnCode == 0 && $gattCmd eq 'write' ) {
|
||||||
@ -822,7 +809,7 @@ sub ExecGatttool_Done {
|
|||||||
my $string = shift;
|
my $string = shift;
|
||||||
|
|
||||||
my ( $name, $mac, $respstate, $gattCmd, $handle, $json_notification ) =
|
my ( $name, $mac, $respstate, $gattCmd, $handle, $json_notification ) =
|
||||||
split /\|/, $string;
|
split( /\|/x, $string );
|
||||||
|
|
||||||
my $hash = $defs{$name};
|
my $hash = $defs{$name};
|
||||||
|
|
||||||
@ -844,7 +831,8 @@ sub ExecGatttool_Done {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $respstate eq 'ok'
|
if ( $respstate
|
||||||
|
&& $respstate eq 'ok'
|
||||||
&& $gattCmd eq 'write'
|
&& $gattCmd eq 'write'
|
||||||
&& AttrVal( $name, 'model', 'none' ) eq 'flowerSens' )
|
&& AttrVal( $name, 'model', 'none' ) eq 'flowerSens' )
|
||||||
{
|
{
|
||||||
@ -852,7 +840,9 @@ sub ExecGatttool_Done {
|
|||||||
$XiaomiModels{ AttrVal( $name, 'model', '' ) }{rdata} );
|
$XiaomiModels{ AttrVal( $name, 'model', '' ) }{rdata} );
|
||||||
|
|
||||||
}
|
}
|
||||||
elsif ( $respstate eq 'ok' ) {
|
elsif ($respstate
|
||||||
|
&& $respstate eq 'ok' )
|
||||||
|
{
|
||||||
ProcessingNotification( $hash, $gattCmd, $handle,
|
ProcessingNotification( $hash, $gattCmd, $handle,
|
||||||
$decode_json->{gtResult} );
|
$decode_json->{gtResult} );
|
||||||
|
|
||||||
@ -913,111 +903,120 @@ sub ProcessingNotification {
|
|||||||
|
|
||||||
}
|
}
|
||||||
elsif ( AttrVal( $name, 'model', 'none' ) eq 'thermoHygroSens' ) {
|
elsif ( AttrVal( $name, 'model', 'none' ) eq 'thermoHygroSens' ) {
|
||||||
if ( $handle eq '0x18' ) {
|
given ($handle) {
|
||||||
### Thermo/Hygro Sens - Read Battery Data
|
when ('0x18') {
|
||||||
Log3( $name, 4,
|
### Thermo/Hygro Sens - Read Battery Data
|
||||||
"XiaomiBTLESens ($name) - ProcessingNotification: handle 0x18"
|
Log3( $name, 4,
|
||||||
);
|
"XiaomiBTLESens ($name) - ProcessingNotification: handle 0x18"
|
||||||
|
);
|
||||||
|
|
||||||
$readings = ThermoHygroSensHandle0x18( $hash, $notification );
|
$readings = ThermoHygroSensHandle0x18( $hash, $notification );
|
||||||
}
|
}
|
||||||
elsif ( $handle eq '0x10' ) {
|
when ('0x10') {
|
||||||
### Thermo/Hygro Sens - Read Sensor Data
|
### Thermo/Hygro Sens - Read Sensor Data
|
||||||
Log3( $name, 4,
|
Log3( $name, 4,
|
||||||
"XiaomiBTLESens ($name) - ProcessingNotification: handle 0x10"
|
"XiaomiBTLESens ($name) - ProcessingNotification: handle 0x10"
|
||||||
);
|
);
|
||||||
|
|
||||||
$readings = ThermoHygroSensHandle0x10( $hash, $notification );
|
$readings = ThermoHygroSensHandle0x10( $hash, $notification );
|
||||||
}
|
}
|
||||||
elsif ( $handle eq '0x24' ) {
|
when ('0x24') {
|
||||||
### Thermo/Hygro Sens - Read Firmware Data
|
### Thermo/Hygro Sens - Read Firmware Data
|
||||||
Log3( $name, 4,
|
Log3( $name, 4,
|
||||||
"XiaomiBTLESens ($name) - ProcessingNotification: handle 0x24"
|
"XiaomiBTLESens ($name) - ProcessingNotification: handle 0x24"
|
||||||
);
|
);
|
||||||
|
|
||||||
$readings = ThermoHygroSensHandle0x24( $hash, $notification );
|
$readings = ThermoHygroSensHandle0x24( $hash, $notification );
|
||||||
}
|
}
|
||||||
elsif ( $handle eq '0x3' ) {
|
when ('0x3') {
|
||||||
### Thermo/Hygro Sens - Read and Write Devicename
|
### Thermo/Hygro Sens - Read and Write Devicename
|
||||||
Log3( $name, 4,
|
Log3( $name, 4,
|
||||||
"XiaomiBTLESens ($name) - ProcessingNotification: handle 0x3" );
|
"XiaomiBTLESens ($name) - ProcessingNotification: handle 0x3"
|
||||||
|
);
|
||||||
|
|
||||||
return CreateParamGatttool( $hash, 'read',
|
return CreateParamGatttool( $hash, 'read',
|
||||||
$XiaomiModels{ AttrVal( $name, 'model', '' ) }{devicename} )
|
$XiaomiModels{ AttrVal( $name, 'model', '' ) }{devicename} )
|
||||||
if ( $gattCmd ne 'read' );
|
if ( $gattCmd ne 'read' );
|
||||||
$readings = ThermoHygroSensHandle0x3( $hash, $notification );
|
$readings = ThermoHygroSensHandle0x3( $hash, $notification );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elsif ( AttrVal( $name, 'model', 'none' ) eq 'mijiaLYWSD03MMC' ) {
|
elsif ( AttrVal( $name, 'model', 'none' ) eq 'mijiaLYWSD03MMC' ) {
|
||||||
if ( $handle eq '0x1b' ) {
|
given ($handle) {
|
||||||
### mijiaLYWSD03MMC - Read Battery Data
|
when ('0x1b') {
|
||||||
Log3( $name, 4,
|
### mijiaLYWSD03MMC - Read Battery Data
|
||||||
"XiaomiBTLESens ($name) - ProcessingNotification: handle 0x1b"
|
Log3( $name, 4,
|
||||||
);
|
"XiaomiBTLESens ($name) - ProcessingNotification: handle 0x1b"
|
||||||
|
);
|
||||||
|
|
||||||
$readings = mijiaLYWSD03MMC_Handle0x1b( $hash, $notification );
|
$readings = mijiaLYWSD03MMC_Handle0x1b( $hash, $notification );
|
||||||
}
|
}
|
||||||
elsif ( $handle eq '0x38' ) {
|
when ('0x38') {
|
||||||
### mijiaLYWSD03MMC - Read Sensor Data
|
### mijiaLYWSD03MMC - Read Sensor Data
|
||||||
Log3( $name, 4,
|
Log3( $name, 4,
|
||||||
"XiaomiBTLESens ($name) - ProcessingNotification: handle 0x38"
|
"XiaomiBTLESens ($name) - ProcessingNotification: handle 0x38"
|
||||||
);
|
);
|
||||||
|
|
||||||
$readings = mijiaLYWSD03MMC_Handle0x38( $hash, $notification );
|
$readings = mijiaLYWSD03MMC_Handle0x38( $hash, $notification );
|
||||||
}
|
}
|
||||||
elsif ( $handle eq '0x12' ) {
|
when ('0x12') {
|
||||||
### mijiaLYWSD03MMC - Read Firmware Data
|
### mijiaLYWSD03MMC - Read Firmware Data
|
||||||
Log3( $name, 4,
|
Log3( $name, 4,
|
||||||
"XiaomiBTLESens ($name) - ProcessingNotification: handle 0x12"
|
"XiaomiBTLESens ($name) - ProcessingNotification: handle 0x12"
|
||||||
);
|
);
|
||||||
|
|
||||||
$readings = mijiaLYWSD03MMC_Handle0x12( $hash, $notification );
|
$readings = mijiaLYWSD03MMC_Handle0x12( $hash, $notification );
|
||||||
}
|
}
|
||||||
elsif ( $handle eq '0x3' ) {
|
when ('0x3') {
|
||||||
### mijiaLYWSD03MMC - Read and Write Devicename
|
### mijiaLYWSD03MMC - Read and Write Devicename
|
||||||
Log3( $name, 4,
|
Log3( $name, 4,
|
||||||
"XiaomiBTLESens ($name) - ProcessingNotification: handle 0x3" );
|
"XiaomiBTLESens ($name) - ProcessingNotification: handle 0x3"
|
||||||
|
);
|
||||||
|
|
||||||
return CreateParamGatttool( $hash, 'read',
|
return CreateParamGatttool( $hash, 'read',
|
||||||
$XiaomiModels{ AttrVal( $name, 'model', '' ) }{devicename} )
|
$XiaomiModels{ AttrVal( $name, 'model', '' ) }{devicename} )
|
||||||
unless ( $gattCmd eq 'read' );
|
unless ( $gattCmd eq 'read' );
|
||||||
$readings = mijiaLYWSD03MMC_Handle0x3( $hash, $notification );
|
$readings = mijiaLYWSD03MMC_Handle0x3( $hash, $notification );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elsif ( AttrVal( $name, 'model', 'none' ) eq 'clearGrassSens' ) {
|
elsif ( AttrVal( $name, 'model', 'none' ) eq 'clearGrassSens' ) {
|
||||||
if ( $handle eq '0x3b' ) {
|
given ($handle) {
|
||||||
### Clear Grass Sens - Read Battery Data
|
when ('0x3b') {
|
||||||
Log3( $name, 4,
|
### Clear Grass Sens - Read Battery Data
|
||||||
"XiaomiBTLESens ($name) - ProcessingNotification: handle 0x3b"
|
Log3( $name, 4,
|
||||||
);
|
"XiaomiBTLESens ($name) - ProcessingNotification: handle 0x3b"
|
||||||
|
);
|
||||||
|
|
||||||
$readings = ClearGrassSensHandle0x3b( $hash, $notification );
|
$readings = ClearGrassSensHandle0x3b( $hash, $notification );
|
||||||
}
|
}
|
||||||
elsif ( $handle eq '0x1e' ) {
|
when ('0x1e') {
|
||||||
### Clear Grass Sens - Read Sensor Data
|
### Clear Grass Sens - Read Sensor Data
|
||||||
Log3( $name, 4,
|
Log3( $name, 4,
|
||||||
"XiaomiBTLESens ($name) - ProcessingNotification: handle 0x1e"
|
"XiaomiBTLESens ($name) - ProcessingNotification: handle 0x1e"
|
||||||
);
|
);
|
||||||
|
|
||||||
$readings = ClearGrassSensHandle0x1e( $hash, $notification );
|
$readings = ClearGrassSensHandle0x1e( $hash, $notification );
|
||||||
}
|
}
|
||||||
elsif ( $handle eq '0x2a' ) {
|
when ('0x2a') {
|
||||||
### Clear Grass Sens - Read Firmware Data
|
### Clear Grass Sens - Read Firmware Data
|
||||||
Log3( $name, 4,
|
Log3( $name, 4,
|
||||||
"XiaomiBTLESens ($name) - ProcessingNotification: handle 0x2a"
|
"XiaomiBTLESens ($name) - ProcessingNotification: handle 0x2a"
|
||||||
);
|
);
|
||||||
|
|
||||||
$readings = ClearGrassSensHandle0x2a( $hash, $notification );
|
$readings = ClearGrassSensHandle0x2a( $hash, $notification );
|
||||||
}
|
}
|
||||||
elsif ( $handle eq '0x3' ) {
|
when ('0x3') {
|
||||||
### Clear Grass Sens - Read and Write Devicename
|
### Clear Grass Sens - Read and Write Devicename
|
||||||
Log3( $name, 4,
|
Log3( $name, 4,
|
||||||
"XiaomiBTLESens ($name) - ProcessingNotification: handle 0x3" );
|
"XiaomiBTLESens ($name) - ProcessingNotification: handle 0x3"
|
||||||
|
);
|
||||||
|
|
||||||
return CreateParamGatttool( $hash, 'read',
|
return CreateParamGatttool( $hash, 'read',
|
||||||
$XiaomiModels{ AttrVal( $name, 'model', '' ) }{devicename} )
|
$XiaomiModels{ AttrVal( $name, 'model', '' ) }{devicename} )
|
||||||
if ( $gattCmd ne 'read' );
|
if ( $gattCmd ne 'read' );
|
||||||
$readings = ClearGrassSensHandle0x3( $hash, $notification );
|
$readings = ClearGrassSensHandle0x3( $hash, $notification );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1034,7 +1033,7 @@ sub FlowerSensHandle0x38 {
|
|||||||
|
|
||||||
Log3( $name, 4, "XiaomiBTLESens ($name) - FlowerSens Handle0x38" );
|
Log3( $name, 4, "XiaomiBTLESens ($name) - FlowerSens Handle0x38" );
|
||||||
|
|
||||||
my @dataBatFw = split /\s/, $notification;
|
my @dataBatFw = split /\s/x, $notification;
|
||||||
|
|
||||||
### neue Vereinheitlichung für Batteriereadings Forum #800017
|
### neue Vereinheitlichung für Batteriereadings Forum #800017
|
||||||
$readings{'batteryPercent'} = hex( "0x" . $dataBatFw[0] );
|
$readings{'batteryPercent'} = hex( "0x" . $dataBatFw[0] );
|
||||||
@ -1062,7 +1061,7 @@ sub FlowerSensHandle0x35 {
|
|||||||
|
|
||||||
Log3( $name, 4, "XiaomiBTLESens ($name) - FlowerSens Handle0x35" );
|
Log3( $name, 4, "XiaomiBTLESens ($name) - FlowerSens Handle0x35" );
|
||||||
|
|
||||||
my @dataSensor = split /\s/, $notification;
|
my @dataSensor = split /\s/x, $notification;
|
||||||
|
|
||||||
return stateRequest($hash)
|
return stateRequest($hash)
|
||||||
if ( $dataSensor[0] eq "aa"
|
if ( $dataSensor[0] eq "aa"
|
||||||
@ -1110,7 +1109,7 @@ sub ThermoHygroSensHandle0x18 {
|
|||||||
Log3( $name, 4, "XiaomiBTLESens ($name) - Thermo/Hygro Sens Handle0x18" );
|
Log3( $name, 4, "XiaomiBTLESens ($name) - Thermo/Hygro Sens Handle0x18" );
|
||||||
|
|
||||||
chomp($notification);
|
chomp($notification);
|
||||||
$notification =~ s/\s+//g;
|
$notification =~ s/\s+//xg;
|
||||||
|
|
||||||
### neue Vereinheitlichung für Batteriereadings Forum #800017
|
### neue Vereinheitlichung für Batteriereadings Forum #800017
|
||||||
$readings{'batteryPercent'} = hex( "0x" . $notification );
|
$readings{'batteryPercent'} = hex( "0x" . $notification );
|
||||||
@ -1134,14 +1133,14 @@ sub ThermoHygroSensHandle0x10 {
|
|||||||
Log3( $name, 4, "XiaomiBTLESens ($name) - Thermo/Hygro Sens Handle0x10" );
|
Log3( $name, 4, "XiaomiBTLESens ($name) - Thermo/Hygro Sens Handle0x10" );
|
||||||
|
|
||||||
return stateRequest($hash)
|
return stateRequest($hash)
|
||||||
if ( $notification !~ /^([0-9a-f]{2}(\s?))*$/ );
|
if ( $notification !~ /^([0-9a-f]{2}(\s?))*$/x );
|
||||||
|
|
||||||
my @numberOfHex = split /\s/, $notification;
|
my @numberOfHex = split /\s/x, $notification;
|
||||||
|
|
||||||
$notification =~ s/\s+//g;
|
$notification =~ s/\s+//xg;
|
||||||
|
|
||||||
$readings{'temperature'} = pack( 'H*', substr( $notification, 4, 8 ) );
|
$readings{'temperature'} = pack( 'H*', substr( $notification, 4, 8 ) );
|
||||||
$readings{'humidity'} = pack(
|
$readings{'humidity'} = pack(
|
||||||
'H*',
|
'H*',
|
||||||
substr(
|
substr(
|
||||||
$notification,
|
$notification,
|
||||||
@ -1170,7 +1169,7 @@ sub ThermoHygroSensHandle0x24 {
|
|||||||
|
|
||||||
Log3( $name, 4, "XiaomiBTLESens ($name) - Thermo/Hygro Sens Handle0x24" );
|
Log3( $name, 4, "XiaomiBTLESens ($name) - Thermo/Hygro Sens Handle0x24" );
|
||||||
|
|
||||||
$notification =~ s/\s+//g;
|
$notification =~ s/\s+//xg;
|
||||||
|
|
||||||
$readings{'firmware'} = pack( 'H*', $notification );
|
$readings{'firmware'} = pack( 'H*', $notification );
|
||||||
|
|
||||||
@ -1189,7 +1188,7 @@ sub ThermoHygroSensHandle0x3 {
|
|||||||
|
|
||||||
Log3( $name, 4, "XiaomiBTLESens ($name) - Thermo/Hygro Sens Handle0x3" );
|
Log3( $name, 4, "XiaomiBTLESens ($name) - Thermo/Hygro Sens Handle0x3" );
|
||||||
|
|
||||||
$notification =~ s/\s+//g;
|
$notification =~ s/\s+//xg;
|
||||||
|
|
||||||
$readings{'devicename'} = pack( 'H*', $notification );
|
$readings{'devicename'} = pack( 'H*', $notification );
|
||||||
|
|
||||||
@ -1198,7 +1197,7 @@ sub ThermoHygroSensHandle0x3 {
|
|||||||
return \%readings;
|
return \%readings;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub mijiaLYWSD03MMC_Handle0x1b($$) {
|
sub mijiaLYWSD03MMC_Handle0x1b {
|
||||||
### mijiaLYWSD03MMC - Battery Data
|
### mijiaLYWSD03MMC - Battery Data
|
||||||
my ( $hash, $notification ) = @_;
|
my ( $hash, $notification ) = @_;
|
||||||
|
|
||||||
@ -1208,7 +1207,7 @@ sub mijiaLYWSD03MMC_Handle0x1b($$) {
|
|||||||
Log3( $name, 4, "XiaomiBTLESens ($name) - mijiaLYWSD03MMC Handle0x1b" );
|
Log3( $name, 4, "XiaomiBTLESens ($name) - mijiaLYWSD03MMC Handle0x1b" );
|
||||||
|
|
||||||
chomp($notification);
|
chomp($notification);
|
||||||
$notification =~ s/\s+//g;
|
$notification =~ s/\s+//xg;
|
||||||
|
|
||||||
### neue Vereinheitlichung für Batteriereadings Forum #800017
|
### neue Vereinheitlichung für Batteriereadings Forum #800017
|
||||||
$readings{'batteryPercent'} = $notification; ###hex( "0x" . $notification );
|
$readings{'batteryPercent'} = $notification; ###hex( "0x" . $notification );
|
||||||
@ -1220,7 +1219,7 @@ sub mijiaLYWSD03MMC_Handle0x1b($$) {
|
|||||||
return \%readings;
|
return \%readings;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub mijiaLYWSD03MMC_Handle0x38($$) {
|
sub mijiaLYWSD03MMC_Handle0x38 {
|
||||||
### mijiaLYWSD03MMC - Read Sensor Data
|
### mijiaLYWSD03MMC - Read Sensor Data
|
||||||
my ( $hash, $notification ) = @_;
|
my ( $hash, $notification ) = @_;
|
||||||
|
|
||||||
@ -1230,20 +1229,25 @@ sub mijiaLYWSD03MMC_Handle0x38($$) {
|
|||||||
Log3( $name, 4, "XiaomiBTLESens ($name) - mijiaLYWSD03MMC Handle0x38" );
|
Log3( $name, 4, "XiaomiBTLESens ($name) - mijiaLYWSD03MMC Handle0x38" );
|
||||||
|
|
||||||
return stateRequest($hash)
|
return stateRequest($hash)
|
||||||
unless ( $notification =~ /^([0-9a-f]{2}(\s?))*$/ );
|
unless ( $notification =~ /^([0-9a-f]{2}(\s?))*$/x );
|
||||||
|
|
||||||
my @splitVal = split /\s/, $notification;
|
my @splitVal = split /\s/x, $notification;
|
||||||
|
|
||||||
$notification =~ s/\s+//g;
|
$notification =~ s/\s+//xg;
|
||||||
|
|
||||||
$readings{'temperature'} = hex( "0x" . $splitVal[1] . $splitVal[0] ) / 100;
|
$readings{'temperature'} =
|
||||||
$readings{'humidity'} = hex( "0x" . $splitVal[2] );
|
hex( "0x" . $splitVal[1] . $splitVal[0] ) > 20000
|
||||||
|
? ( -65536 + hex( "0x" . $splitVal[1] . $splitVal[0] ) ) / 100
|
||||||
|
: hex( "0x" . $splitVal[1] . $splitVal[0] ) / 100;
|
||||||
|
|
||||||
|
$readings{'humidity'} = hex( "0x" . $splitVal[2] );
|
||||||
|
|
||||||
$hash->{helper}{CallBattery} = 0;
|
$hash->{helper}{CallBattery} = 0;
|
||||||
|
|
||||||
return \%readings;
|
return \%readings;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub mijiaLYWSD03MMC_Handle0x12($$) {
|
sub mijiaLYWSD03MMC_Handle0x12 {
|
||||||
### mijiaLYWSD03MMC - Read Firmware Data
|
### mijiaLYWSD03MMC - Read Firmware Data
|
||||||
my ( $hash, $notification ) = @_;
|
my ( $hash, $notification ) = @_;
|
||||||
|
|
||||||
@ -1252,15 +1256,16 @@ sub mijiaLYWSD03MMC_Handle0x12($$) {
|
|||||||
|
|
||||||
Log3( $name, 4, "XiaomiBTLESens ($name) - mijiaLYWSD03MMC Handle0x12" );
|
Log3( $name, 4, "XiaomiBTLESens ($name) - mijiaLYWSD03MMC Handle0x12" );
|
||||||
|
|
||||||
$notification =~ s/\s+//g;
|
$notification =~ s/\s+//xg;
|
||||||
|
|
||||||
$readings{'firmware'} = pack( 'H*', $notification );
|
$readings{'firmware'} = pack( 'H*', $notification );
|
||||||
|
|
||||||
$hash->{helper}{CallBattery} = 0;
|
$hash->{helper}{CallBattery} = 0;
|
||||||
|
|
||||||
return \%readings;
|
return \%readings;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub mijiaLYWSD03MMC_Handle0x3($$) {
|
sub mijiaLYWSD03MMC_Handle0x3 {
|
||||||
### mijiaLYWSD03MMC - Read and Write Devicename
|
### mijiaLYWSD03MMC - Read and Write Devicename
|
||||||
my ( $hash, $notification ) = @_;
|
my ( $hash, $notification ) = @_;
|
||||||
|
|
||||||
@ -1269,11 +1274,12 @@ sub mijiaLYWSD03MMC_Handle0x3($$) {
|
|||||||
|
|
||||||
Log3( $name, 4, "XiaomiBTLESens ($name) - mijiaLYWSD03MMC Handle0x3" );
|
Log3( $name, 4, "XiaomiBTLESens ($name) - mijiaLYWSD03MMC Handle0x3" );
|
||||||
|
|
||||||
$notification =~ s/\s+//g;
|
$notification =~ s/\s+//xg;
|
||||||
|
|
||||||
$readings{'devicename'} = pack( 'H*', $notification );
|
$readings{'devicename'} = pack( 'H*', $notification );
|
||||||
|
|
||||||
$hash->{helper}{CallBattery} = 0;
|
$hash->{helper}{CallBattery} = 0;
|
||||||
|
|
||||||
return \%readings;
|
return \%readings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1288,7 +1294,7 @@ sub ClearGrassSensHandle0x3b {
|
|||||||
Log3( $name, 4, "XiaomiBTLESens ($name) - Clear Grass Sens Handle0x3b" );
|
Log3( $name, 4, "XiaomiBTLESens ($name) - Clear Grass Sens Handle0x3b" );
|
||||||
|
|
||||||
chomp($notification);
|
chomp($notification);
|
||||||
$notification =~ s/\s+//g;
|
$notification =~ s/\s+//xg;
|
||||||
|
|
||||||
### neue Vereinheitlichung für Batteriereadings Forum #800017
|
### neue Vereinheitlichung für Batteriereadings Forum #800017
|
||||||
$readings{'batteryPercent'} = hex( substr( $notification, 14, 2 ) );
|
$readings{'batteryPercent'} = hex( substr( $notification, 14, 2 ) );
|
||||||
@ -1312,11 +1318,11 @@ sub ClearGrassSensHandle0x1e {
|
|||||||
Log3( $name, 4, "XiaomiBTLESens ($name) - Clear Grass Sens Handle0x1e" );
|
Log3( $name, 4, "XiaomiBTLESens ($name) - Clear Grass Sens Handle0x1e" );
|
||||||
|
|
||||||
return stateRequest($hash)
|
return stateRequest($hash)
|
||||||
if ( $notification !~ /^([0-9a-f]{2}(\s?))*$/ );
|
if ( $notification !~ /^([0-9a-f]{2}(\s?))*$/x );
|
||||||
|
|
||||||
my @numberOfHex = split /\s/, $notification;
|
my @numberOfHex = split /\s/x, $notification;
|
||||||
|
|
||||||
$notification =~ s/\s+//g;
|
$notification =~ s/\s+//xg;
|
||||||
|
|
||||||
$readings{'temperature'} = hex( substr( $notification, 4, 2 ) ) / 10;
|
$readings{'temperature'} = hex( substr( $notification, 4, 2 ) ) / 10;
|
||||||
$readings{'humidity'} =
|
$readings{'humidity'} =
|
||||||
@ -1338,7 +1344,7 @@ sub ClearGrassSensHandle0x2a {
|
|||||||
|
|
||||||
Log3( $name, 4, "XiaomiBTLESens ($name) - Clear Grass Sens Handle0x2a" );
|
Log3( $name, 4, "XiaomiBTLESens ($name) - Clear Grass Sens Handle0x2a" );
|
||||||
|
|
||||||
$notification =~ s/\s+//g;
|
$notification =~ s/\s+//xg;
|
||||||
|
|
||||||
$readings{'firmware'} = pack( 'H*', $notification );
|
$readings{'firmware'} = pack( 'H*', $notification );
|
||||||
|
|
||||||
@ -1357,7 +1363,7 @@ sub ClearGrassSensHandle0x3 {
|
|||||||
|
|
||||||
Log3( $name, 4, "XiaomiBTLESens ($name) - Clear Grass Sens Handle0x3" );
|
Log3( $name, 4, "XiaomiBTLESens ($name) - Clear Grass Sens Handle0x3" );
|
||||||
|
|
||||||
$notification =~ s/\s+//g;
|
$notification =~ s/\s+//xg;
|
||||||
|
|
||||||
$readings{'devicename'} = pack( 'H*', $notification );
|
$readings{'devicename'} = pack( 'H*', $notification );
|
||||||
|
|
||||||
@ -1519,6 +1525,8 @@ sub CallBattery_Timestamp {
|
|||||||
$hash->{helper}{updateTimeCallBattery} =
|
$hash->{helper}{updateTimeCallBattery} =
|
||||||
gettimeofday(); # in seconds since the epoch
|
gettimeofday(); # in seconds since the epoch
|
||||||
$hash->{helper}{updateTimestampCallBattery} = FmtDateTime( gettimeofday() );
|
$hash->{helper}{updateTimestampCallBattery} = FmtDateTime( gettimeofday() );
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub CallBattery_UpdateTimeAge {
|
sub CallBattery_UpdateTimeAge {
|
||||||
@ -1553,7 +1561,7 @@ sub BTLE_CmdlinePreventGrepFalsePositive {
|
|||||||
# avoid an *additional* grep process plus pipe...
|
# avoid an *additional* grep process plus pipe...
|
||||||
my $cmdline = shift;
|
my $cmdline = shift;
|
||||||
|
|
||||||
$cmdline =~ s/(.)(.*)/[$1]$2/;
|
$cmdline =~ s/(.)(.*)/[$1]$2/x;
|
||||||
|
|
||||||
return $cmdline;
|
return $cmdline;
|
||||||
}
|
}
|
||||||
@ -1747,7 +1755,7 @@ sub BTLE_CmdlinePreventGrepFalsePositive {
|
|||||||
],
|
],
|
||||||
"release_status": "stable",
|
"release_status": "stable",
|
||||||
"license": "GPL_2",
|
"license": "GPL_2",
|
||||||
"version": "v3.0.0",
|
"version": "v3.0.1",
|
||||||
"author": [
|
"author": [
|
||||||
"Marko Oldenburg <leongaultier@gmail.com>"
|
"Marko Oldenburg <leongaultier@gmail.com>"
|
||||||
],
|
],
|
||||||
|
Loading…
Reference in New Issue
Block a user