mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 06:39:11 +00:00
new module 33_readingsProxy to make (a subset of) a reading from one device
available as a new device. can be used to separate channels from 1-wire, EnOcean or SWAP multichannel devices git-svn-id: https://svn.fhem.de/fhem/trunk@4289 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
cae893bd58
commit
9e50d48bcf
@ -1,6 +1,10 @@
|
||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
||||
# Do not insert empty lines here, update check depends on it.
|
||||
- SVN
|
||||
- feature: new module 33_readingsProxy to make (a subset of) a reading
|
||||
from one device available as a new device. can be used to
|
||||
separate channels from 1-wire, EnOcean or SWAP multichannel
|
||||
devices (by justme1968)
|
||||
- change: improvements for OWDevice and OWServer (justme1968)
|
||||
- feature: new attribute resolution for 1-wire temperature readings
|
||||
(justme1968 & Boris)
|
||||
|
341
fhem/FHEM/33_readingsProxy.pm
Normal file
341
fhem/FHEM/33_readingsProxy.pm
Normal file
@ -0,0 +1,341 @@
|
||||
# $Id$
|
||||
##############################################################################
|
||||
#
|
||||
# This file is part of fhem.
|
||||
#
|
||||
# Fhem is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Fhem is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with fhem. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
package main;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use SetExtensions;
|
||||
|
||||
sub readingsProxy_Initialize($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
|
||||
$hash->{DefFn} = "readingsProxy_Define";
|
||||
$hash->{NotifyFn} = "readingsProxy_Notify";
|
||||
$hash->{UndefFn} = "readingsProxy_Undefine";
|
||||
$hash->{SetFn} = "readingsProxy_Set";
|
||||
$hash->{GetFn} = "readingsProxy_Get";
|
||||
$hash->{AttrList} = "disable:1 "
|
||||
."getList "
|
||||
."setList "
|
||||
."getFn setFn valueFn "
|
||||
.$readingFnAttributes;
|
||||
}
|
||||
|
||||
sub
|
||||
readingsProxy_updateDevices($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
|
||||
my %list;
|
||||
|
||||
my @params = split(" ", $hash->{DEF});
|
||||
while (@params) {
|
||||
my $param = shift(@params);
|
||||
|
||||
my @device = split(":", $param);
|
||||
|
||||
if( defined($defs{$device[0]})
|
||||
&& defined($defs{$device[0]}) ) {
|
||||
$list{$device[0]} = 1;
|
||||
$hash->{DEVICE} = $device[0];
|
||||
$hash->{READING} = $device[1];
|
||||
}
|
||||
}
|
||||
|
||||
$hash->{CONTENT} = \%list;
|
||||
}
|
||||
|
||||
sub readingsProxy_Define($$)
|
||||
{
|
||||
my ($hash, $def) = @_;
|
||||
|
||||
my @args = split("[ \t]+", $def);
|
||||
|
||||
return "Usage: define <name> readingsProxy <device>+" if(@args < 3);
|
||||
|
||||
my $name = shift(@args);
|
||||
my $type = shift(@args);
|
||||
|
||||
readingsProxy_updateDevices($hash);
|
||||
|
||||
$hash->{STATE} = 'Initialized';
|
||||
|
||||
readingsProxy_update($hash, undef) if( $init_done );
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub readingsProxy_Undefine($$)
|
||||
{
|
||||
my ($hash,$arg) = @_;
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub
|
||||
readingsProxy_update($$)
|
||||
{
|
||||
my ($hash,$value) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
my $DEVICE = $hash->{DEVICE};
|
||||
my $READING = $hash->{READING};
|
||||
|
||||
$value = ReadingsVal($DEVICE,$READING,undef) if( !defined($value) );
|
||||
|
||||
my $value_fn = AttrVal( $name, "valueFn", "" );
|
||||
if( $value_fn =~ m/^{.*}$/ ) {
|
||||
my $VALUE = $value;
|
||||
|
||||
my $value_fn = eval $value_fn;
|
||||
Log3 $name, 3, $name .": valueFn: ". $@ if($@);
|
||||
return undef if( !defined($value_fn) );
|
||||
$value = $value_fn if( $value_fn );
|
||||
}
|
||||
|
||||
readingsSingleUpdate($hash, "state", $value, 1)
|
||||
}
|
||||
|
||||
sub
|
||||
readingsProxy_Notify($$)
|
||||
{
|
||||
my ($hash,$dev) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
if( grep(m/^INITIALIZED$/, @{$dev->{CHANGED}}) ) {
|
||||
readingsProxy_updateDevices($hash);
|
||||
return undef;
|
||||
}
|
||||
elsif( grep(m/^REREADCFG$/, @{$dev->{CHANGED}}) ) {
|
||||
readingsProxy_updateDevices($hash);
|
||||
return undef;
|
||||
}
|
||||
|
||||
return if( AttrVal($name,"disable", 0) > 0 );
|
||||
|
||||
return if($dev->{NAME} eq $name);
|
||||
|
||||
my $max = int(@{$dev->{CHANGED}});
|
||||
for (my $i = 0; $i < $max; $i++) {
|
||||
my $s = $dev->{CHANGED}[$i];
|
||||
$s = "" if(!defined($s));
|
||||
|
||||
if( $dev->{NAME} eq "global" && $s =~ m/^RENAMED ([^ ]*) ([^ ]*)$/) {
|
||||
my ($old, $new) = ($1, $2);
|
||||
if( defined($hash->{CONTENT}{$old}) ) {
|
||||
|
||||
$hash->{DEF} =~ s/(\s*)$old((:\S+)?\s*)/$1$new$2/g;
|
||||
}
|
||||
readingsProxy_updateDevices($hash);
|
||||
} elsif( $dev->{NAME} eq "global" && $s =~ m/^DELETED ([^ ]*)$/) {
|
||||
my ($name) = ($1);
|
||||
|
||||
if( defined($hash->{CONTENT}{$name}) ) {
|
||||
|
||||
$hash->{DEF} =~ s/(\s*)$name((:\S+)?\s*)/ /g;
|
||||
$hash->{DEF} =~ s/^ //;
|
||||
$hash->{DEF} =~ s/ $//;
|
||||
}
|
||||
readingsProxy_updateDevices($hash);
|
||||
} elsif( $dev->{NAME} eq "global" && $s =~ m/^DEFINED ([^ ]*)$/) {
|
||||
readingsProxy_updateDevices($hash);
|
||||
} else {
|
||||
next if( $dev->{NAME} ne $hash->{DEVICE} );
|
||||
|
||||
my @parts = split(/: /,$s);
|
||||
my $reading = shift @parts;
|
||||
my $value = join(": ", @parts);
|
||||
|
||||
$reading = "" if( !defined($reading) );
|
||||
$value = "" if( !defined($value) );
|
||||
if( $value eq "" ) {
|
||||
$reading = "state";
|
||||
$value = $s;
|
||||
}
|
||||
next if( $reading ne $hash->{READING} );
|
||||
|
||||
readingsProxy_update($hash, $value);
|
||||
}
|
||||
}
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub
|
||||
readingsProxy_Set($@)
|
||||
{
|
||||
my ($hash, $name, @a) = @_;
|
||||
|
||||
return "no set value specified" if(int(@a) < 1);
|
||||
my $setList = AttrVal($name, "setList", "");
|
||||
$setList = getAllSets($hash->{DEVICE}) if( $setList eq "%PARENT%" );
|
||||
return SetExtensions($hash,$setList,$name,@a) if(!$setList || $a[0] eq "?");
|
||||
|
||||
my $found = 0;
|
||||
foreach my $set (split(" ", $setList)) {
|
||||
if( "$set " =~ m/^${a[0]}[ :]/ ) {
|
||||
$found = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
return SetExtensions($hash,$setList,$name,@a) if( !$found );
|
||||
|
||||
my $v = join(" ", @a);
|
||||
my $set_fn = AttrVal( $hash->{NAME}, "setFn", "" );
|
||||
if( $set_fn =~ m/^{.*}$/ ) {
|
||||
my $DEVICE = $hash->{DEVICE};
|
||||
my $READING = $hash->{READING};
|
||||
my $CMD = $a[0];
|
||||
my $ARGS = join(" ", @a[1..$#a]);
|
||||
|
||||
my $set_fn = eval $set_fn;
|
||||
Log3 $name, 3, $name .": setFn: ". $@ if($@);
|
||||
return undef if( !defined($set_fn) );
|
||||
$v = $set_fn if( $set_fn );
|
||||
}
|
||||
|
||||
Log3 $name, 4, "$name: set hash->{DEVICE} $v";
|
||||
return CommandSet(undef,"$hash->{DEVICE} ".$v);
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
sub
|
||||
readingsProxy_Get($@)
|
||||
{
|
||||
my ($hash, $name, @a) = @_;
|
||||
|
||||
return "no get value specified" if(int(@a) < 1);
|
||||
my $getList = AttrVal($name, "getList", "");
|
||||
$getList = getAllGets($hash->{DEVICE}) if( $getList eq "%PARENT%" );
|
||||
return "Unknown argument ?, choose one of $getList" if(!$getList || $a[0] eq "?");
|
||||
|
||||
my $found = 0;
|
||||
foreach my $get (split(" ", $getList)) {
|
||||
if( "$get " =~ m/^${a[0]}[ :]/ ) {
|
||||
$found = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
return "Unknown argument $a[0], choose one of $getList" if(!$found);
|
||||
|
||||
my $v = join(" ", @a);
|
||||
my $get_fn = AttrVal( $hash->{NAME}, "getFn", "" );
|
||||
if( $get_fn =~ m/^{.*}$/ ) {
|
||||
my $DEVICE = $hash->{DEVICE};
|
||||
my $READING = $hash->{READING};
|
||||
my $CMD = $a[0];
|
||||
my $ARGS = join(" ", @a[1..$#a]);
|
||||
|
||||
my $get_fn = eval $get_fn;
|
||||
Log3 $name, 3, $name .": getFn: ". $@ if($@);
|
||||
return undef if( !defined($get_fn) );
|
||||
$v = $get_fn if( $get_fn );
|
||||
}
|
||||
|
||||
Log3 $name, 4, "$name: get hash->{DEVICE} $v";
|
||||
return CommandGet(undef,"$hash->{DEVICE} ".$v);
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=pod
|
||||
=begin html
|
||||
|
||||
<a name="readingsProxy"></a>
|
||||
<h3>readingsProxy</h3>
|
||||
<ul>
|
||||
Makes (a subset of) a reading from one device available as a new device.<br>
|
||||
This can be used to map channels from 1-Wire, EnOcean or SWAP devices to independend devices that
|
||||
can have state,icons and webCmd different from the parent device and can be used in a floorplan.
|
||||
<br><br>
|
||||
<a name="readingsProxy_Define"></a>
|
||||
<b>Define</b>
|
||||
<ul>
|
||||
<code>define <name> readingsProxy <device>:<reading></code><br>
|
||||
<br>
|
||||
|
||||
Examples:
|
||||
<ul>
|
||||
<code>define myProxy readingsProxy myDS2406:latch.A</code><br>
|
||||
</ul>
|
||||
</ul><br>
|
||||
|
||||
<a name="readingsProxy_Set"></a>
|
||||
<b>Set</b>
|
||||
<ul>
|
||||
</ul><br>
|
||||
|
||||
<a name="readingsProxy_Get"></a>
|
||||
<b>Get</b>
|
||||
<ul>
|
||||
</ul><br>
|
||||
|
||||
<a name="readingsProxy_Attr"></a>
|
||||
<b>Attributes</b>
|
||||
<ul>
|
||||
<li>disable<br>
|
||||
1 -> disable notify processing. Notice: this also disables rename and delete handling.</li>
|
||||
<li>getList<br>
|
||||
Space separated list of commands, which will be returned upon "get name ?",
|
||||
so the FHEMWEB frontend can construct a dropdown.
|
||||
%PARENT% will result in the complete list of commands from the parent device.
|
||||
get commands not in this list will be rejected.</li>
|
||||
<li>setList<br>
|
||||
Space separated list of commands, which will be returned upon "set name ?",
|
||||
so the FHEMWEB frontend can construct a dropdown and offer on/off switches.
|
||||
%PARENT% will result in the complete list of commands from the parent device.
|
||||
set commands not in this list will be rejected.
|
||||
Example: attr proxyName setList on off</li>
|
||||
<li><a href="#readingFnAttributes">readingFnAttributes</a></li>
|
||||
<li>getFn<br>
|
||||
perl expresion that will return the get command forwarded to the parent device.
|
||||
has access to $DEVICE, $READING, $CMD and $ARGS.<br>
|
||||
undef -> do nothing<br>
|
||||
"" -> pass-through<br>
|
||||
everything else -> use this instead</li>
|
||||
<li>setFn<br>
|
||||
perl expresion that will return the set command forwarded to the parent device.
|
||||
has access to $DEVICE, $READING, $CMD and $ARGS.<br>
|
||||
undef -> do nothing<br>
|
||||
"" -> pass-through<br>
|
||||
everything else -> use this instead<br>
|
||||
Examples:<br>
|
||||
<code>attr myProxy setFn {($CMD eq "on")?"off":"on"}</code>
|
||||
</li>
|
||||
<li>valueFn<br>
|
||||
perl expresion that will return the value that sould be used as state.
|
||||
has access to $DEVICE, $READING, $CMD and $VALUE.<br>
|
||||
undef -> do nothing<br>
|
||||
"" -> pass-through<br>
|
||||
everything else -> use this instead<br>
|
||||
Examples:<br>
|
||||
<code>attr myProxy valueFn {($VALUE == 0)?"off":"on"}</code>
|
||||
</li>
|
||||
</ul><br>
|
||||
</ul>
|
||||
|
||||
=end html
|
||||
=cut
|
@ -87,6 +87,7 @@ FHEM/31_LightScene.pm justme1968 http://forum.fhem.de Automatis
|
||||
FHEM/32_SYSSTAT.pm justme1968 http://forum.fhem.de Unterstuetzende Dienste
|
||||
FHEM/32_mailcheck.pm justme1968 http://forum.fhem.de Automatisierung
|
||||
FHEM/33_readingsGroup.pm justme1968 http://forum.fhem.de Frontends
|
||||
FHEM/33_readingsproxy.pm justme1968 http://forum.fhem.de Automatisierung
|
||||
FHEM/32_speedtest.pm justme1968 http://forum.fhem.de Sonstiges
|
||||
FHEM/34_panStamp.pm justme1968 http://forum.fhem.de Sonstiges Systeme
|
||||
FHEM/34_SWAP.pm justme1968 http://forum.fhem.de Sonstiges Systeme
|
||||
|
@ -110,6 +110,7 @@
|
||||
<a href="#RandomTimer">RandomTimer</a>
|
||||
<a href="#rain">rain</a>
|
||||
<a href="#readingsGroup">readingsGroup</a>
|
||||
<a href="#readingsProxy">readingsProxy</a>
|
||||
<a href="#remotecontrol">remotecontrol</a>
|
||||
<a href="#SUNRISE_EL">SUNRISE_EL</a>
|
||||
<a href="#SYSSTAT">SYSSTAT</a>
|
||||
|
@ -108,6 +108,7 @@
|
||||
<a href="#RandomTimer">RandomTimer</a>
|
||||
<a href="#rain">rain</a>
|
||||
<a href="#readingsGroup">readingsGroup</a>
|
||||
<a href="#readingsProxy">readingsProxy</a>
|
||||
<a href="#remotecontrol">remotecontrol</a>
|
||||
<a href="#SUNRISE_EL">SUNRISE_EL</a>
|
||||
<a href="#SYSSTAT">SYSSTAT</a>
|
||||
|
Loading…
Reference in New Issue
Block a user