mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-05-04 20:17:45 +00:00
state definition and split attribute added to 66_ECMD, 67_ECMDDevice
git-svn-id: https://svn.fhem.de/fhem/trunk@6456 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
7d0deb744d
commit
88252a74a5
@ -1,5 +1,7 @@
|
||||
# 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.
|
||||
- feature: state definition and split attribute added to 66_ECMD,
|
||||
67_ECMDDevice
|
||||
- FHEMWEB: JavaScripts and CssFiles attributes added
|
||||
- change: avoid updating weather information on get (59_Weather.pm)
|
||||
- change: removed noshutdown=0 for HTTP connections made in 57_Calendar.pm
|
||||
|
@ -64,7 +64,7 @@ ECMD_Initialize($)
|
||||
$hash->{GetFn} = "ECMD_Get";
|
||||
$hash->{SetFn} = "ECMD_Set";
|
||||
$hash->{AttrFn} = "ECMD_Attr";
|
||||
$hash->{AttrList}= "classdefs logTraffic:0,1,2,3,4,5 timeout";
|
||||
$hash->{AttrList}= "classdefs split logTraffic:0,1,2,3,4,5 timeout";
|
||||
}
|
||||
|
||||
#####################################
|
||||
@ -316,6 +316,12 @@ ECMD_EvalClassDef($$$)
|
||||
Log3 $hash, 5, "$name: parameters are $def";
|
||||
$hash->{fhem}{classDefs}{$classname}{params}= $def;
|
||||
#
|
||||
# state
|
||||
#
|
||||
} elsif($cmd eq "state") {
|
||||
Log3 $hash, 5, "$name: state is determined as $def";
|
||||
$hash->{fhem}{classDefs}{$classname}{state}= $def;
|
||||
#
|
||||
# reading
|
||||
#
|
||||
} elsif($cmd eq "reading") {
|
||||
@ -487,6 +493,7 @@ sub ECMD_Read($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
my $buf = ECMD_SimpleRead($hash);
|
||||
return unless(defined($buf));
|
||||
return if($buf eq "");
|
||||
|
||||
ECMD_Log $hash, 5, "Spontaneously received " . dq($buf);
|
||||
@ -631,6 +638,13 @@ ECMD_Write($$$)
|
||||
<li>classdefs<br>A colon-separated list of <classname>=<filename>.
|
||||
The list is automatically updated if a class definition is added. You can
|
||||
directly set the attribute.</li>
|
||||
<li>split<br>
|
||||
Some devices send several readings in one transmission. The split attribute defines the
|
||||
separator to split such transmissions into separate messages. The regular expression for
|
||||
matching a reading is then applied to each message in turn. After splitting, the separator
|
||||
is <b>not</b> part of the single messages.
|
||||
Example: <code>attr myECMD \n</code> splits <code>foo 12\nbar off</code> into
|
||||
<code>foo 12</code> and <code>bar off</code>.</li>
|
||||
<li>logTraffic <loglevel><br>Enables logging of sent and received datagrams with the given loglevel. Control characters in the logged datagrams are escaped, i.e. a double backslash is shown for a single backslash, \n is shown for a line feed character, etc.</li>
|
||||
<li>timeout <seconds><br>Time in seconds to wait for a reply from the physical ECMD device before FHEM assumes that something has gone wrong. The default is 3 seconds if this attribute is not set.</li>
|
||||
<!--
|
||||
@ -681,6 +695,12 @@ ECMD_Write($$$)
|
||||
<br><br>
|
||||
</li>
|
||||
|
||||
<li><code>state <reading></code><br><br>
|
||||
Normally, the state reading is set to the latest command or reading name followed
|
||||
by the value, if any. This command sets the state reading to the value of the
|
||||
named reading if and only if the reading is updated.<br><br>
|
||||
</li>
|
||||
|
||||
<li><code>set <commandname> cmd { <a href="#perl"><perl special></a> }</code><br>
|
||||
<code>get <commandname> cmd { <a href="#perl"><perl special></a> }</code>
|
||||
<br><br>
|
||||
|
@ -108,18 +108,30 @@ sub
|
||||
ECMDDevice_Changed($$$)
|
||||
{
|
||||
my ($hash, $cmd, $value)= @_;
|
||||
#Debug "Device changed: $cmd $value";
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
my $state= $cmd;
|
||||
|
||||
if(defined($value) && $value ne "") {
|
||||
readingsBulkUpdate($hash, $cmd, $value);
|
||||
$state.= " $value";
|
||||
}
|
||||
readingsBulkUpdate($hash, "state", $state);
|
||||
readingsBulkUpdate($hash, $cmd, $value) if(defined($value) && $value ne "");
|
||||
|
||||
my $state;
|
||||
my $classname= $hash->{fhem}{classname};
|
||||
my $IOhash= $hash->{IODev};
|
||||
if(defined($IOhash->{fhem}{classDefs}{$classname}{state})) {
|
||||
if($cmd eq $IOhash->{fhem}{classDefs}{$classname}{state}) {
|
||||
$state= defined($value) ? $value : "?";
|
||||
#Debug "cmd= $cmd, setting state to $state (OVERRIDE)";
|
||||
}
|
||||
} else {
|
||||
$state= $cmd;
|
||||
$state.= " $value" if(defined($value) && $value ne "");
|
||||
#Debug "cmd= $cmd, setting state to $state (DEFAULT)";
|
||||
}
|
||||
readingsBulkUpdate($hash, "state", $state) if(defined($state));
|
||||
|
||||
readingsEndUpdate($hash, 1);
|
||||
my $name= $hash->{NAME};
|
||||
Log3 $hash, 4 , "ECMDDevice $name $state";
|
||||
#Log3 $hash, 4 , "ECMDDevice $name $state" if(defined($state));
|
||||
return $state;
|
||||
}
|
||||
|
||||
@ -247,41 +259,52 @@ ECMDDevice_Parse($$)
|
||||
|
||||
# NOTE: we will update all matching readings for all devices, not just the first!
|
||||
|
||||
my ($IOhash, $msg) = @_; # IOhash points to the ECMD, not to the ECMDDevice
|
||||
my ($IOhash, $message) = @_; # IOhash points to the ECMD, not to the ECMDDevice
|
||||
|
||||
my @matches;
|
||||
my $name= $IOhash->{NAME};
|
||||
|
||||
#Debug "Trying to find a match for \"" . escapeLogLine($msg) ."\"";
|
||||
# walk over all clients
|
||||
foreach my $d (keys %defs) {
|
||||
my $hash= $defs{$d};
|
||||
if($hash->{TYPE} eq "ECMDDevice" && $hash->{IODev} eq $IOhash) {
|
||||
my $classname= $hash->{fhem}{classname};
|
||||
my $classDef= $IOhash->{fhem}{classDefs}{$classname};
|
||||
#Debug " Checking device $d with class $classname...";
|
||||
next unless(defined($classDef->{readings}));
|
||||
#Debug " Trying to find a match in class $classname...";
|
||||
my %specials= ECMDDevice_DeviceParams2Specials($hash);
|
||||
# we run over all readings in that classdef
|
||||
foreach my $r (keys %{$classDef->{readings}}) {
|
||||
my $regex= ECMDDevice_ReplaceSpecials($classDef->{readings}{$r}{match}, %specials);
|
||||
#Debug " Trying to match reading $r with regular expressing \"$regex\".";
|
||||
if($msg =~ m/$regex/) {
|
||||
# we found a match
|
||||
Log3 $IOhash, 5, "$name: match regex $regex for reading $r of device $d with class $classname";
|
||||
push @matches, $d;
|
||||
my $postproc= $classDef->{readings}{$r}{postproc};
|
||||
my $value= ECMDDevice_PostProc($hash, $postproc, $msg);
|
||||
Log3 $hash, 5, "postprocessed value is $value";
|
||||
ECMDDevice_Changed($hash, $r, $value);
|
||||
}
|
||||
my @msgs;
|
||||
if(defined(AttrVal($name, "split", undef))) {
|
||||
@msgs= split(AttrVal($name, "split", undef), $message);
|
||||
} else {
|
||||
push @msgs, $message;
|
||||
}
|
||||
|
||||
foreach my $msg (@msgs) {
|
||||
#Debug "Trying to find a match for \"" . escapeLogLine($msg) ."\"";
|
||||
# walk over all clients
|
||||
foreach my $d (keys %defs) {
|
||||
my $hash= $defs{$d};
|
||||
if($hash->{TYPE} eq "ECMDDevice" && $hash->{IODev} eq $IOhash) {
|
||||
my $classname= $hash->{fhem}{classname};
|
||||
my $classDef= $IOhash->{fhem}{classDefs}{$classname};
|
||||
#Debug " Checking device $d with class $classname...";
|
||||
next unless(defined($classDef->{readings}));
|
||||
#Debug " Trying to find a match in class $classname...";
|
||||
my %specials= ECMDDevice_DeviceParams2Specials($hash);
|
||||
# we run over all readings in that classdef
|
||||
foreach my $r (keys %{$classDef->{readings}}) {
|
||||
my $regex= ECMDDevice_ReplaceSpecials($classDef->{readings}{$r}{match}, %specials);
|
||||
#Debug " Trying to match reading $r with regular expressing \"$regex\".";
|
||||
if($msg =~ m/$regex/) {
|
||||
# we found a match
|
||||
Log3 $IOhash, 5, "$name: match regex $regex for reading $r of device $d with class $classname";
|
||||
push @matches, $d;
|
||||
my $postproc= $classDef->{readings}{$r}{postproc};
|
||||
my $value= ECMDDevice_PostProc($hash, $postproc, $msg);
|
||||
Log3 $hash, 5, "postprocessed value is $value";
|
||||
ECMDDevice_Changed($hash, $r, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return @matches if(@matches);
|
||||
return "UNDEFINED ECMDDevice message $msg";
|
||||
# NOTE: In a split message, undefined messages are not reported if there was at least one match.
|
||||
return "UNDEFINED ECMDDevice message $message";
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user