mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-04 05:16:45 +00:00
36_ShellyMonitor: Fix fuer "Panic"-Meldungen, besserer Support Shelly-WT
git-svn-id: https://svn.fhem.de/fhem/trunk@23552 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
87c5d86762
commit
63224a3fbb
@ -29,7 +29,7 @@ my $SHELLY_DEF_SEN = {
|
||||
"132" => { "type"=>"S", "desc"=>"output_2"},
|
||||
"142" => { "type"=>"S", "desc"=>"output_3"},
|
||||
"113" => { "type"=>"T", "desc"=>"deviceTemp", "unit"=>"C"},
|
||||
"114" => { "type"=>"T", "desc"=>"deviceTemp", "unit"=>"F"},
|
||||
"114" => { "type"=>"T", "desc"=>"deviceTempF", "unit"=>"F"},
|
||||
"214" => { "type"=>"E", "desc"=>"energy_0", "unit"=>"Wmin"},
|
||||
# Version 2, since FW >= 1.6
|
||||
"1101" => { "type"=>"S", "desc"=>"output_0"},
|
||||
@ -60,10 +60,10 @@ my $SHELLY_DEF_SEN = {
|
||||
# Used by Shelly i3 SHIX3-1:
|
||||
"2303" => { "type"=>"EVC", "desc"=>"inputEventCnt_2"},
|
||||
"3101" => { "type"=>"T", "desc"=>"extTemp_0", "unit"=>"C"},
|
||||
"3102" => { "type"=>"T", "desc"=>"extTemp_0", "unit"=>"F"},
|
||||
"3102" => { "type"=>"T", "desc"=>"extTemp_0f", "unit"=>"F"},
|
||||
"3103" => { "type"=>"H", "desc"=>"humidity"},
|
||||
"3104" => { "type"=>"T", "desc"=>"deviceTemp", "unit"=>"C"},
|
||||
"3105" => { "type"=>"T", "desc"=>"deviceTemp", "unit"=>"F"},
|
||||
"3105" => { "type"=>"T", "desc"=>"deviceTempF", "unit"=>"F"},
|
||||
# Used by Shelly Sense SHSEN-1, Shelly Door Window SHDW-1, Shelly Door Window 2 SHDW-2:
|
||||
"3106" => { "type"=>"L", "desc"=>"luminosity", "unit"=>"lux"},
|
||||
# Used by Shelly Gas SHGS-1:
|
||||
@ -86,9 +86,9 @@ my $SHELLY_DEF_SEN = {
|
||||
"3116" => { "type"=>"S", "desc"=>"dayLight"},
|
||||
"3117" => { "type"=>"S", "desc"=>"extInput"},
|
||||
"3201" => { "type"=>"T", "desc"=>"extTemp_1", "unit"=>"C"},
|
||||
"3202" => { "type"=>"T", "desc"=>"extTemp_1", "unit"=>"F"},
|
||||
"3202" => { "type"=>"T", "desc"=>"extTemp_1f", "unit"=>"F"},
|
||||
"3301" => { "type"=>"T", "desc"=>"extTemp_2", "unit"=>"C"},
|
||||
"3302" => { "type"=>"T", "desc"=>"extTemp_2", "unit"=>"F"},
|
||||
"3302" => { "type"=>"T", "desc"=>"extTemp_2f", "unit"=>"F"},
|
||||
"4101" => { "type"=>"P", "desc"=>"power_0", "unit"=>"W"},
|
||||
# Used by Shelly 2 SHSW-21 roller-mode, Shelly 2.5 SHSW-25 roller-mode:
|
||||
"4102" => { "type"=>"P", "desc"=>"rollerPower", "unit"=>"W"},
|
||||
@ -400,11 +400,11 @@ sub ShellyMonitor_DoRead
|
||||
$hash->{".ReceivedByIp"}->{$sending_ip}++;
|
||||
|
||||
my $ip2devicesDirty = 0;
|
||||
my @devices = getDevicesForIp($hash, $sending_ip);
|
||||
if (! @devices ) {
|
||||
my @devrefs = getDevicesForIp($hash, $sending_ip);
|
||||
if (! @devrefs ) {
|
||||
Log3 ($name, 4, "$sending_ip not found in cache");
|
||||
# Search for defined devices by IP:
|
||||
@devices = ();
|
||||
@devrefs = ();
|
||||
my @devNames = devspec2array("TYPE=Shelly:FILTER=DEF=$sending_ip");
|
||||
foreach ( @devNames ) {
|
||||
my $model = AttrVal($_, "model", "generic");
|
||||
@ -414,14 +414,13 @@ sub ShellyMonitor_DoRead
|
||||
model => $model,
|
||||
mode => AttrVal($_, "mode", undef)
|
||||
);
|
||||
push @devices, \%d;
|
||||
push @devrefs, \%d;
|
||||
Log3 $name, 2, "Defined real device $_ for $sending_ip as model $model";
|
||||
}
|
||||
my $ip2devices = \@devices;
|
||||
$hash->{".ip2device"}->{$sending_ip} = $ip2devices;
|
||||
$hash->{".ip2device"}->{$sending_ip} = [ @devrefs ];
|
||||
$ip2devicesDirty = 1;
|
||||
} else {
|
||||
Log3 $name, 4, "$sending_ip: in cache, devices=" . join (' ', map { scalar $_->{name} } @devices) . " (size=" . scalar @devices . ")";
|
||||
Log3 $name, 4, "$sending_ip: in cache, devices=" . join (' ', map { scalar $_->{name} } @devrefs) . " (size=" . scalar @devrefs . ")";
|
||||
}
|
||||
my $autoCreate = (defined $hash->{".autoCreate"}) ? 1 : 0;
|
||||
|
||||
@ -486,7 +485,7 @@ sub ShellyMonitor_DoRead
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( @devices ) {
|
||||
foreach ( @devrefs ) {
|
||||
$_->{expires} = time()+$validity;
|
||||
}
|
||||
|
||||
@ -496,9 +495,9 @@ sub ShellyMonitor_DoRead
|
||||
# Handle ignoring of devices
|
||||
my $ignoreRegexp = $hash->{".ignoreDevices"};
|
||||
if ($ignoreRegexp) {
|
||||
@devices = grep { $_->{name} !~ qr/$ignoreRegexp/ } @devices;
|
||||
@devrefs = grep { $_->{name} !~ qr/$ignoreRegexp/ } @devrefs;
|
||||
Log3 ($name, 4, "Applied RegExp $ignoreRegexp");
|
||||
if (! @devices || scalar @devices == 0) {
|
||||
if (! @devrefs || scalar @devrefs == 0) {
|
||||
Log3 ($name, 4, "Shelly-devices found by IP match ignoreRule");
|
||||
$hash->{".Ignored"}++;
|
||||
return;
|
||||
@ -517,7 +516,7 @@ sub ShellyMonitor_DoRead
|
||||
$shellyId = $2;
|
||||
}
|
||||
# Iterate over Shellys found by IP and x-check ID
|
||||
foreach ( @devices ) {
|
||||
foreach ( @devrefs ) {
|
||||
$_->{expires} = time()+$validity;
|
||||
next unless $_->{isDefined};
|
||||
my $device = $defs{$_->{name}};
|
||||
@ -526,7 +525,8 @@ sub ShellyMonitor_DoRead
|
||||
if ($device->{SHELLYID} !~ qr/.*$shellyId$/) {
|
||||
Log3 $name, 1, "Device $_ has ID " . $device->{SHELLYID} . " which does not match $shellyId";
|
||||
my $dName = $_;
|
||||
@devices = grep { $_->{name} ne $dName } @devices;
|
||||
@devrefs = grep { $_->{name} ne $dName } @devrefs;
|
||||
$hash->{".ip2device"}->{$sending_ip} = [ @devrefs ];
|
||||
}
|
||||
} else {
|
||||
$device->{SHELLYID} = $shellyId;
|
||||
@ -537,7 +537,7 @@ sub ShellyMonitor_DoRead
|
||||
my $haveAutoCreated = 0;
|
||||
|
||||
# Hopefully, all Shellys have an ID with 6-12 Chars...
|
||||
if (scalar @devices==0 && $global_devid=~ /(SH[^#]+)#([A-F0-9]{6,12})#/) {
|
||||
if (scalar @devrefs==0 && $global_devid=~ /(SH[^#]+)#([A-F0-9]{6,12})#/) {
|
||||
my $shellyCoIoTModel = $1;
|
||||
my $shellyId = $2;
|
||||
my @devsByShellyId = devspec2array("TYPE=Shelly:FILTER=SHELLYID=.*".$shellyId);
|
||||
@ -559,7 +559,8 @@ sub ShellyMonitor_DoRead
|
||||
model => $model,
|
||||
mode => AttrVal($oname, "mode", undef)
|
||||
);
|
||||
push @devices, \%d;
|
||||
push @devrefs, \%d;
|
||||
$hash->{".ip2device"}->{$sending_ip} = [ @devrefs ];
|
||||
$ip2devicesDirty = 1;
|
||||
Log3 $name, 2, "Changed IP for device '" . $oname . "' to $sending_ip";
|
||||
|
||||
@ -581,8 +582,8 @@ sub ShellyMonitor_DoRead
|
||||
# Search if a shadow device is already existing with a different IP
|
||||
my @ips = ( keys %{$hash->{".ip2device"}} );
|
||||
foreach my $ip ( @ips ) {
|
||||
my @devices = getDevicesForIp($hash, $ip);
|
||||
foreach my $dev ( @devices ) {
|
||||
my @devrefs2 = getDevicesForIp($hash, $ip);
|
||||
foreach my $dev ( @devrefs2 ) {
|
||||
if ($dev->{name} eq $dname && $dev->{isDefined}==0) {
|
||||
Log3 $name, 2, "shadow device $dname found on old ip $ip, removing";
|
||||
delete $hash->{".ip2device"}->{$ip};
|
||||
@ -598,12 +599,13 @@ sub ShellyMonitor_DoRead
|
||||
expires => time()+$validity,
|
||||
attrs => $DEVID_ATTRS{$shellyCoIoTModel}
|
||||
);
|
||||
push @devices, \%d;
|
||||
push @devrefs, \%d;
|
||||
$hash->{".ip2device"}->{$sending_ip} = [ @devrefs ];
|
||||
$ip2devicesDirty = 1;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( @devices ) {
|
||||
foreach ( @devrefs ) {
|
||||
my $device = $defs{$_->{name}};
|
||||
next unless ($device);
|
||||
if ($_->{isDefined}) {
|
||||
@ -634,7 +636,7 @@ sub ShellyMonitor_DoRead
|
||||
my $rtype = $1;
|
||||
my $rno = $2;
|
||||
|
||||
foreach ( @devices ) {
|
||||
foreach ( @devrefs ) {
|
||||
# We want to set the mode also for shadow devices
|
||||
my $model = $_->{model};
|
||||
if ($rtype eq "mode") {
|
||||
@ -688,10 +690,11 @@ sub ShellyMonitor_DoRead
|
||||
}
|
||||
} else {
|
||||
# Generic Shelly Device gets any reading in native form
|
||||
foreach ( @devices ) {
|
||||
foreach ( @devrefs ) {
|
||||
# We want to set the mode also for shadow devices
|
||||
my $model = $_->{model};
|
||||
my $device = $defs{$_->{name}};
|
||||
$svalue = join (' ', @$svalue) if (ref $svalue eq "ARRAY");
|
||||
readingsBulkUpdateIfChanged($device, $rname, $svalue)
|
||||
if (defined $device && (( ! defined $model ) || ($model eq "generic")));
|
||||
}
|
||||
@ -702,7 +705,7 @@ sub ShellyMonitor_DoRead
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ( @devices ) {
|
||||
foreach ( @devrefs ) {
|
||||
if ($_->{isDefined}) {
|
||||
my $device = $defs{$_->{name}};
|
||||
if ($rgbdevices{$_->{name}} &&
|
||||
@ -735,15 +738,15 @@ sub ShellyMonitor_detailFn {
|
||||
my $now = time();
|
||||
my $formNo = 1;
|
||||
foreach my $ip ( @ips ) {
|
||||
my @devices = getDevicesForIp($hash, $ip);
|
||||
foreach my $dev ( @devices ) {
|
||||
my @devrefs = getDevicesForIp($hash, $ip);
|
||||
foreach my $dev ( @devrefs ) {
|
||||
if ($dev->{expires} < $now) {
|
||||
Log3 $hash->{NAME}, 1, "Device " . $dev->{name} . " has expired, no messages seen";
|
||||
if (scalar @devices == 1) {
|
||||
if (scalar @devrefs == 1) {
|
||||
delete $hash->{".ip2device"}->{$ip};
|
||||
} else {
|
||||
@devices = grep { $_->{expires} > $now } @devices;
|
||||
$hash->{".ip2device"}->{$ip} = \ @devices;
|
||||
@devrefs = grep { $_->{expires} > $now } @devrefs;
|
||||
$hash->{".ip2device"}->{$ip} = \ @devrefs;
|
||||
}
|
||||
next;
|
||||
}
|
||||
@ -815,8 +818,8 @@ sub ShellyMonitor_Notify
|
||||
my @ips = ( keys %{$hash->{".ip2device"}} );
|
||||
$ip2devicesDirty = 0;
|
||||
foreach my $ip ( @ips ) {
|
||||
my @devices = getDevicesForIp($hash, $ip);
|
||||
foreach my $dev ( @devices ) {
|
||||
my @devrefs = getDevicesForIp($hash, $ip);
|
||||
foreach my $dev ( @devrefs ) {
|
||||
next unless ($dev->{name} eq $evDev1);
|
||||
$ip2devicesDirty = 1;
|
||||
delete $hash->{".ip2device"}->{$ip} if ($evType eq "DELETED");
|
||||
@ -874,11 +877,11 @@ sub ShellyMonitor_Set
|
||||
my @ips = grep { $_ =~ qr/^$sValue$/ } ( keys %{$hash->{".ip2device"}} );
|
||||
return "Provided IP $sValue did not match any IPs" unless (scalar @ips>=1);
|
||||
foreach my $ip ( @ips ) {
|
||||
my @devices = getDevicesForIp($hash, $ip);
|
||||
next unless (@devices);
|
||||
my $device = $devices[0];
|
||||
my @devrefs = getDevicesForIp($hash, $ip);
|
||||
next unless (@devrefs);
|
||||
my $device = $devrefs[0];
|
||||
next if ($device->{isDefined});
|
||||
Log3 $name, 1, "AutoCreate called for IP $ip, #devices=" . scalar @devices;
|
||||
Log3 $name, 1, "AutoCreate called for IP $ip, #devices=" . scalar @devrefs;
|
||||
my $dname = defined $devName ? $devName : $device->{name};
|
||||
$device->{name} = $dname;
|
||||
my $model = $device->{model};
|
||||
@ -945,15 +948,24 @@ sub getDevicesForIp {
|
||||
my ($hash, $ip) = @_;
|
||||
my $ip2devices = $hash->{".ip2device"}->{$ip};
|
||||
return unless ($ip2devices);
|
||||
my @devices = @{$ip2devices};
|
||||
foreach ( @devices ) {
|
||||
my @devrefs = @{$ip2devices};
|
||||
foreach ( @devrefs ) {
|
||||
if (ref $_ ne "HASH") {
|
||||
@devices = ();
|
||||
delete $hash->{".ip2device"}->{$ip};
|
||||
Log3 $hash->{NAME}, 1, "Panic, it happened: Cache for $ip did contain a none-hash";
|
||||
@devrefs = ();
|
||||
Log3 $hash->{NAME}, 1, "Panic, it happened: Cache for $ip did contain a none-hash, $_ instead";
|
||||
}
|
||||
}
|
||||
return @devices;
|
||||
return @devrefs;
|
||||
}
|
||||
|
||||
sub completecheck {
|
||||
my ($hash) = @_;
|
||||
my @is = ( keys %{$hash->{".ip2device"}} );
|
||||
foreach my $ip ( @is ) {
|
||||
my @devrefs = getDevicesForIp($hash, $ip);
|
||||
Log3 $hash->{NAME}, 4, "IP: $ip " . scalar @devrefs . " entries";
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user