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.
|
# 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.
|
# 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
|
- FHEMWEB: JavaScripts and CssFiles attributes added
|
||||||
- change: avoid updating weather information on get (59_Weather.pm)
|
- change: avoid updating weather information on get (59_Weather.pm)
|
||||||
- change: removed noshutdown=0 for HTTP connections made in 57_Calendar.pm
|
- change: removed noshutdown=0 for HTTP connections made in 57_Calendar.pm
|
||||||
|
@ -64,7 +64,7 @@ ECMD_Initialize($)
|
|||||||
$hash->{GetFn} = "ECMD_Get";
|
$hash->{GetFn} = "ECMD_Get";
|
||||||
$hash->{SetFn} = "ECMD_Set";
|
$hash->{SetFn} = "ECMD_Set";
|
||||||
$hash->{AttrFn} = "ECMD_Attr";
|
$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";
|
Log3 $hash, 5, "$name: parameters are $def";
|
||||||
$hash->{fhem}{classDefs}{$classname}{params}= $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
|
# reading
|
||||||
#
|
#
|
||||||
} elsif($cmd eq "reading") {
|
} elsif($cmd eq "reading") {
|
||||||
@ -487,6 +493,7 @@ sub ECMD_Read($)
|
|||||||
{
|
{
|
||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
my $buf = ECMD_SimpleRead($hash);
|
my $buf = ECMD_SimpleRead($hash);
|
||||||
|
return unless(defined($buf));
|
||||||
return if($buf eq "");
|
return if($buf eq "");
|
||||||
|
|
||||||
ECMD_Log $hash, 5, "Spontaneously received " . dq($buf);
|
ECMD_Log $hash, 5, "Spontaneously received " . dq($buf);
|
||||||
@ -631,6 +638,13 @@ ECMD_Write($$$)
|
|||||||
<li>classdefs<br>A colon-separated list of <classname>=<filename>.
|
<li>classdefs<br>A colon-separated list of <classname>=<filename>.
|
||||||
The list is automatically updated if a class definition is added. You can
|
The list is automatically updated if a class definition is added. You can
|
||||||
directly set the attribute.</li>
|
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>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>
|
<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>
|
<br><br>
|
||||||
</li>
|
</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>
|
<li><code>set <commandname> cmd { <a href="#perl"><perl special></a> }</code><br>
|
||||||
<code>get <commandname> cmd { <a href="#perl"><perl special></a> }</code>
|
<code>get <commandname> cmd { <a href="#perl"><perl special></a> }</code>
|
||||||
<br><br>
|
<br><br>
|
||||||
|
@ -108,18 +108,30 @@ sub
|
|||||||
ECMDDevice_Changed($$$)
|
ECMDDevice_Changed($$$)
|
||||||
{
|
{
|
||||||
my ($hash, $cmd, $value)= @_;
|
my ($hash, $cmd, $value)= @_;
|
||||||
|
#Debug "Device changed: $cmd $value";
|
||||||
|
|
||||||
readingsBeginUpdate($hash);
|
readingsBeginUpdate($hash);
|
||||||
my $state= $cmd;
|
|
||||||
|
|
||||||
if(defined($value) && $value ne "") {
|
readingsBulkUpdate($hash, $cmd, $value) if(defined($value) && $value ne "");
|
||||||
readingsBulkUpdate($hash, $cmd, $value);
|
|
||||||
$state.= " $value";
|
my $state;
|
||||||
}
|
my $classname= $hash->{fhem}{classname};
|
||||||
readingsBulkUpdate($hash, "state", $state);
|
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);
|
readingsEndUpdate($hash, 1);
|
||||||
my $name= $hash->{NAME};
|
my $name= $hash->{NAME};
|
||||||
Log3 $hash, 4 , "ECMDDevice $name $state";
|
#Log3 $hash, 4 , "ECMDDevice $name $state" if(defined($state));
|
||||||
return $state;
|
return $state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,41 +259,52 @@ ECMDDevice_Parse($$)
|
|||||||
|
|
||||||
# NOTE: we will update all matching readings for all devices, not just the first!
|
# 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 @matches;
|
||||||
my $name= $IOhash->{NAME};
|
my $name= $IOhash->{NAME};
|
||||||
|
|
||||||
#Debug "Trying to find a match for \"" . escapeLogLine($msg) ."\"";
|
my @msgs;
|
||||||
# walk over all clients
|
if(defined(AttrVal($name, "split", undef))) {
|
||||||
foreach my $d (keys %defs) {
|
@msgs= split(AttrVal($name, "split", undef), $message);
|
||||||
my $hash= $defs{$d};
|
} else {
|
||||||
if($hash->{TYPE} eq "ECMDDevice" && $hash->{IODev} eq $IOhash) {
|
push @msgs, $message;
|
||||||
my $classname= $hash->{fhem}{classname};
|
}
|
||||||
my $classDef= $IOhash->{fhem}{classDefs}{$classname};
|
|
||||||
#Debug " Checking device $d with class $classname...";
|
foreach my $msg (@msgs) {
|
||||||
next unless(defined($classDef->{readings}));
|
#Debug "Trying to find a match for \"" . escapeLogLine($msg) ."\"";
|
||||||
#Debug " Trying to find a match in class $classname...";
|
# walk over all clients
|
||||||
my %specials= ECMDDevice_DeviceParams2Specials($hash);
|
foreach my $d (keys %defs) {
|
||||||
# we run over all readings in that classdef
|
my $hash= $defs{$d};
|
||||||
foreach my $r (keys %{$classDef->{readings}}) {
|
if($hash->{TYPE} eq "ECMDDevice" && $hash->{IODev} eq $IOhash) {
|
||||||
my $regex= ECMDDevice_ReplaceSpecials($classDef->{readings}{$r}{match}, %specials);
|
my $classname= $hash->{fhem}{classname};
|
||||||
#Debug " Trying to match reading $r with regular expressing \"$regex\".";
|
my $classDef= $IOhash->{fhem}{classDefs}{$classname};
|
||||||
if($msg =~ m/$regex/) {
|
#Debug " Checking device $d with class $classname...";
|
||||||
# we found a match
|
next unless(defined($classDef->{readings}));
|
||||||
Log3 $IOhash, 5, "$name: match regex $regex for reading $r of device $d with class $classname";
|
#Debug " Trying to find a match in class $classname...";
|
||||||
push @matches, $d;
|
my %specials= ECMDDevice_DeviceParams2Specials($hash);
|
||||||
my $postproc= $classDef->{readings}{$r}{postproc};
|
# we run over all readings in that classdef
|
||||||
my $value= ECMDDevice_PostProc($hash, $postproc, $msg);
|
foreach my $r (keys %{$classDef->{readings}}) {
|
||||||
Log3 $hash, 5, "postprocessed value is $value";
|
my $regex= ECMDDevice_ReplaceSpecials($classDef->{readings}{$r}{match}, %specials);
|
||||||
ECMDDevice_Changed($hash, $r, $value);
|
#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 @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