mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 06:39:11 +00:00
devspec added
delattr reenamed to deleteattr git-svn-id: https://svn.fhem.de/fhem/trunk@135 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
88003d6b52
commit
5b6dbf91d7
@ -369,6 +369,8 @@
|
||||
- feature: Generate warning if too many commands were sent in the last hour
|
||||
- doc: linux.html: Introduction (Peter S.)
|
||||
- feature: contrib/82_M232Voltage.pm (by Boris, 24.12)
|
||||
- feature: delattr renamed to deleteattr (Rudi, 29.12)
|
||||
- feature: device spec (list/range/regexp) for most commands implemented
|
||||
|
||||
- TODO
|
||||
emem -2.5kW / getDevData for emwz -1
|
||||
|
@ -71,7 +71,7 @@ sr($$$$)
|
||||
$sst += ($seconds/3600);
|
||||
|
||||
my $diff = 0;
|
||||
if($nh > $sst) {
|
||||
if($nh >= $sst) {
|
||||
$nt += 86400; # Tommorow
|
||||
$diff = 24;
|
||||
@lt = localtime($nt);
|
||||
|
22
fhem/HISTORY
22
fhem/HISTORY
@ -2,7 +2,7 @@
|
||||
Created the file HISTORY and the file README.DEV
|
||||
|
||||
- Pest, Thu Feb 1 20:45 MET 2007
|
||||
Added description for attribute "model" in commandref.html
|
||||
Added description for attribute ,
|
||||
|
||||
- Rudi, Sun Feb 11 18:56:05 MET 2007
|
||||
- showtime added for pgm2 (useful for FS20 piri display)
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
- Rudi, Sun Mar 4 11:18:10 MET 2007
|
||||
Reorganization. Goal: making attribute adding/deleting more uniform
|
||||
("at/notify" and other device differences), and making web-configuration
|
||||
(,
|
||||
possible (i.e. saving the configfile, list of possible devices etc).
|
||||
|
||||
Internal changes:
|
||||
@ -34,24 +34,24 @@
|
||||
-> User written scripts can more easily analyze device states
|
||||
|
||||
User visible changes:
|
||||
- at/notify "renamed" to "define <name> at/notify", both moved to external
|
||||
- at/notify ,
|
||||
modules. Now it is possible
|
||||
- to have a further "at" or "notify" modules
|
||||
- to have a further ,
|
||||
(notify & filelog use the same interface)
|
||||
- to have more than one notify for the same event
|
||||
- to delete at commands without strange escapes.
|
||||
The delete syntax changed (no more def/at/ntfy needed)
|
||||
- at/notify can have attributes
|
||||
Drawback: each at and notify must have a name, which is strange first.
|
||||
- logfile/modpath/pidfile/port/verbose "renamed" to "attr global xxx"
|
||||
- logfile/modpath/pidfile/port/verbose ,
|
||||
Dumping and extending these attributes is easier, no special handling
|
||||
required in the web-frontend.
|
||||
- savefile renamed to "attr global statefile"
|
||||
- savefile renamed to ,
|
||||
- configfile global attribute added.
|
||||
- save command added, it writes the statefile and then the configfile.
|
||||
- delattr added to delete single attributes
|
||||
- list/xmllist format changed, they contain more information.
|
||||
- "define/set/get/attr name ?" returns a list of possible arguments
|
||||
- ,
|
||||
in the same format. This data is contained in the xmllist.
|
||||
- disable attribute for at/notify/filelog
|
||||
- rename added
|
||||
@ -92,7 +92,7 @@
|
||||
- feature: modify command added. It helps change e.g. only the time component
|
||||
for an at command, without deleting and creating it again and then
|
||||
reapplying all the attributes.
|
||||
- feature: the "-" character is disallowed in defined names. Use dot (.) or _
|
||||
- feature: the ,
|
||||
instead. The - is used to separate ranges in the set command.
|
||||
|
||||
- Rudi, Sun May 27 12:51:52 MEST 2007
|
||||
@ -164,3 +164,9 @@
|
||||
- Peter Sun Dec 23 19:59:00 MEST 2007
|
||||
- linux.html: Introduction refinement.
|
||||
|
||||
- Rudi Sat Dec 29 16:27:14 MET 2007
|
||||
- delattr renamed to deleteattr
|
||||
- devicespec introduced:
|
||||
it may contain a list of devices, a range of devices, or multiple devices
|
||||
identified by regexp. Following commands take a devicespec as argument:
|
||||
attr, deleteattr, delete, get, list, set, setstate, trigger
|
||||
|
@ -15,7 +15,7 @@
|
||||
<a href="#attr">attr</a><br>
|
||||
<a href="#defattr">defattr</a><br>
|
||||
<a href="#define">define</a><br>
|
||||
<a href="#delattr">delattr</a><br>
|
||||
<a href="#deleteattr">deleteattr</a><br>
|
||||
<a href="#delete">delete</a><br>
|
||||
<a href="#get">get</a><br>
|
||||
<a href="#include">include</a><br>
|
||||
@ -32,6 +32,7 @@
|
||||
<a href="#trigger">trigger</a><br>
|
||||
<a href="#sleep">sleep</a><br>
|
||||
<a href="#xmllist">xmllist</a><br>
|
||||
<a href="#devspec">Device specification</a><br>
|
||||
<a href="#perl">Perl specials</a><br>
|
||||
|
||||
<a name="intro"></a>
|
||||
@ -115,7 +116,7 @@ split in multiple lines<br><br>
|
||||
<a name="attr"></a>
|
||||
<h3>attr</h3>
|
||||
<ul>
|
||||
<code>attr <name> <attrname> [<value>] </code><br>
|
||||
<code>attr <devspec> <attrname> [<value>] </code><br>
|
||||
or <br>
|
||||
<code>attr at <at-spec-regexp> <attribute> </code><br>
|
||||
|
||||
@ -126,6 +127,8 @@ split in multiple lines<br><br>
|
||||
below.<br>
|
||||
|
||||
Use "attr <name> ?" to get a list of possible attributes.
|
||||
See the <a href="#devspec">Device specification</a> section for details on
|
||||
<devspec>.
|
||||
<br><br>
|
||||
|
||||
Following are attributes of the global device:<br>
|
||||
@ -470,7 +473,7 @@ split in multiple lines<br><br>
|
||||
|
||||
Notes:<br>
|
||||
<ul>
|
||||
<li>See <a href="#delattr">delattr</a> to delete attributes.</li>
|
||||
<li>See <a href="#deleteattr">deleteattr</a> to delete attributes.</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
@ -1093,18 +1096,20 @@ split in multiple lines<br><br>
|
||||
</ul>
|
||||
|
||||
|
||||
<a name="delattr"></a>
|
||||
<h3>delattr</h3>
|
||||
<a name="deleteattr"></a>
|
||||
<h3>deleteattr</h3>
|
||||
<ul>
|
||||
<code>delattr <name> [<attrname>]</code> <br>
|
||||
<code>deleteattr <devspec> [<attrname>]</code> <br>
|
||||
<br>
|
||||
Delete either a single attribute (see the <a href="#attr">attr</a> command)
|
||||
or all attributes for a device (if no <attrname> is defined).<br>
|
||||
or all attributes for a device (if no <attrname> is defined).
|
||||
See the <a href="#devspec">Device specification</a> section for details on
|
||||
<devspec>.<br>
|
||||
|
||||
Examples:
|
||||
<ul>
|
||||
<code>delattr lamp follow-on-for-timer</code><br>
|
||||
<code>delattr lamp</code><br>
|
||||
<code>deleteattr lamp follow-on-for-timer</code><br>
|
||||
<code>deleteattr lamp</code><br>
|
||||
</ul>
|
||||
<br>
|
||||
</ul>
|
||||
@ -1112,10 +1117,11 @@ split in multiple lines<br><br>
|
||||
<a name="delete"></a>
|
||||
<h3>delete</h3>
|
||||
<ul>
|
||||
<code>delete <name></code> <br>
|
||||
<code>delete <devspec></code> <br>
|
||||
<br>
|
||||
Delete something created with the <a href="#define">define</a> command.
|
||||
<br>
|
||||
See the <a href="#devspec">Device specification</a> section for details on
|
||||
<devspec>.<br>
|
||||
Examples:
|
||||
<ul>
|
||||
<code>delete lamp</code><br>
|
||||
@ -1126,12 +1132,13 @@ split in multiple lines<br><br>
|
||||
<a name="get"></a>
|
||||
<h3>get</h3>
|
||||
<ul>
|
||||
<code>get <name> <type-specific></code>
|
||||
<code>get <devspec> <type-specific></code>
|
||||
<br><br>
|
||||
Ask a value directly from the device, and wait for an answer. In general, you
|
||||
can get a list of possible commands by<br><code>get <device> ?</code>
|
||||
<br>
|
||||
Right now only the FHZ module supports this function.
|
||||
See the <a href="#devspec">Device specification</a> section for details on
|
||||
<devspec>.<br>
|
||||
|
||||
<h4>Type FHZ:</h4>
|
||||
<ul>
|
||||
@ -1231,11 +1238,13 @@ split in multiple lines<br><br>
|
||||
<a name="list"></a>
|
||||
<h3>list</h3>
|
||||
<ul>
|
||||
<code>list [name]</code>
|
||||
<code>list [devspec]</code>
|
||||
<br><br>
|
||||
Output a list of all definitions, all notify settings and all at
|
||||
entries. This is one of the few commands which return a string in a
|
||||
normal case.
|
||||
See the <a href="#devspec">Device specification</a> section for details on
|
||||
<devspec>.
|
||||
<br><br>
|
||||
Example:
|
||||
<pre><code> FHZ> list
|
||||
@ -1404,13 +1413,13 @@ Send buffer:<br /> 2007-10-19 00:31:24 desired-temp 22.5
|
||||
<a name="set"></a>
|
||||
<h3>set</h3>
|
||||
<ul>
|
||||
<code>set <name> <type-specific></code>
|
||||
<code>set <devspec> <type-specific></code>
|
||||
<br><br>
|
||||
Set parameters of a device / send signals to a device. You can
|
||||
get a list of possible commands by<br><code>set <name> ?</code>
|
||||
<br>
|
||||
Instead of <name> you can also use an enumeration (separated by comma)
|
||||
or ranges (separated by -), see the FS20 examples.
|
||||
See the <a href="#devspec">Device specification</a> section for details on
|
||||
<devspec>.<br>
|
||||
|
||||
<a name="FHZset"></a>
|
||||
<h4>Type FHZ:</h4>
|
||||
@ -1687,12 +1696,14 @@ must between 5.5 and 30.5 Celsius. Value 5.5 set the actuator to OFF, value 30.
|
||||
<a name="setstate"></a>
|
||||
<h3>setstate</h3>
|
||||
<ul>
|
||||
<code>setstate <name> <value></code>
|
||||
<code>setstate <devspec> <value></code>
|
||||
<br><br>
|
||||
Set the "STATE" for <code><name></code> as shown in paranthesis in the
|
||||
<a href="#list">list</a> command
|
||||
to <code><value></code> without sending any signals to the device
|
||||
itself. This command is also used in the <a href="#statefile">statefile</a>.
|
||||
See the <a href="#devspec">Device specification</a> section for details on
|
||||
<devspec>.
|
||||
<br><br>
|
||||
Examples:
|
||||
<ul>
|
||||
@ -1726,9 +1737,12 @@ must between 5.5 and 30.5 Celsius. Value 5.5 set the actuator to OFF, value 30.
|
||||
<a name="trigger"></a>
|
||||
<h3>trigger</h3>
|
||||
<ul>
|
||||
<code>trigger <dev> <state></code>
|
||||
<code>trigger <devspec> <state></code>
|
||||
<br><br>
|
||||
Trigger a <a href="#notify">notify</a> definition.
|
||||
See the <a href="#devspec">Device specification</a> section for details on
|
||||
<devspec>.
|
||||
|
||||
<br><br>
|
||||
Example:
|
||||
<ul>
|
||||
@ -1777,6 +1791,45 @@ must between 5.5 and 30.5 Celsius. Value 5.5 set the actuator to OFF, value 30.
|
||||
</ul>
|
||||
|
||||
|
||||
<a name="devspec"></a>
|
||||
<h3>Device specification</h3>
|
||||
<ul>
|
||||
The commands
|
||||
<a href="#attr">attr</a>,
|
||||
<a href="#deleteattr">deleteattr</a>,
|
||||
<a href="#delete">delete</a>,
|
||||
<a href="#get">get</a>,
|
||||
<a href="#list">list</a>,
|
||||
<a href="#set">set</a>,
|
||||
<a href="#setstate">setstate</a>,
|
||||
<a href="#trigger">trigger</a>
|
||||
can take a more complex device specification as argument,
|
||||
which will be expanded to a list of devices. A devspec can be:
|
||||
<ul>
|
||||
<li>a list of devices, separated by comma (,)</li>
|
||||
<li>a range of devices, separated by dash (-)</li>
|
||||
<li>a regular expression, if the the spec contains on e of the following
|
||||
characters: ^*[]$</li>
|
||||
</ul>
|
||||
Example:
|
||||
<ul>
|
||||
<code>set lamp1,lamp2,lamp3 on</code><br>
|
||||
<code>set lamp[1-3] on</code><br>
|
||||
<code>set lamp.* on</code><br>
|
||||
<code>set lamp1-lamp3 on</code><br>
|
||||
<code>set lamp1-lamp3,lamp3 on</code><br>
|
||||
</ul>
|
||||
Notes:
|
||||
<ul>
|
||||
<li>first the spec is separated by komma, then the range or the regular
|
||||
expression operations are executed.</li>
|
||||
<li>if there is a device which xactly corresponds to the spec, then
|
||||
no special processing is done.</li>
|
||||
<li>the returned list can contain the same device more than once, so
|
||||
int tha last example the list will contain lamp3 twice.</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<a name="perl"></a>
|
||||
<h3>Perl specials</h3>
|
||||
<ul>
|
||||
|
@ -93,7 +93,7 @@ define roll_eg_wz1 FS20 fb02 0c fg f2 lm 8f
|
||||
define roll_wz1_off1 at *20:00:00 { if( $value{roll_eg_wz1} ne "off" ) { \
|
||||
if( $attr{roll_eg_wz1}{freigabe} ) { \
|
||||
fhem("set roll_eg_wz1 off");; \
|
||||
fhem("delattr roll_eg_wz1 freigabe") \
|
||||
fhem("deleteattr roll_eg_wz1 freigabe") \
|
||||
} else { \
|
||||
fhem("attr roll_eg_wz1 freigabe") \
|
||||
} \
|
||||
@ -102,11 +102,11 @@ define roll_wz1_off1 at *20:00:00 { if( $value{roll_eg_wz1} ne "of
|
||||
define roll_wz1_off2 at +*{sunset_rel(+3600)} { if( $value{roll_eg_wz1} ne "off" ) { \
|
||||
if( $attr{roll_eg_wz1}{freigabe} ) { \
|
||||
fhem("set roll_eg_wz1 off");; \
|
||||
fhem("delattr roll_eg_wz1 freigabe") \
|
||||
fhem("deleteattr roll_eg_wz1 freigabe") \
|
||||
} else { \
|
||||
fhem("attr roll_eg_wz1 freigabe") \
|
||||
} \
|
||||
} }
|
||||
|
||||
define roll_wz1_off3 at *22:00:00 { fhem("set roll_eg_wz1 off") if($value{roll_eg_wz1} ne "off");; \
|
||||
fhem("delattr roll_eg_wz1 freigabe") }
|
||||
fhem("deleteattr roll_eg_wz1 freigabe") }
|
||||
|
371
fhem/fhem.pl
371
fhem/fhem.pl
@ -64,11 +64,12 @@ sub fhem($);
|
||||
sub fhz($);
|
||||
sub doGlobalDef($);
|
||||
sub PrintHash($$);
|
||||
sub devspec2array($);
|
||||
|
||||
sub CommandAttr($$);
|
||||
sub CommandDefAttr($$);
|
||||
sub CommandDefine($$);
|
||||
sub CommandDelAttr($$);
|
||||
sub CommandDeleteAttr($$);
|
||||
sub CommandDelete($$);
|
||||
sub CommandGet($$);
|
||||
sub CommandHelp($$);
|
||||
@ -137,7 +138,7 @@ my %intAt; # Internal at timer hash.
|
||||
my $intAtCnt=0;
|
||||
my $reread_active = 0;
|
||||
my $AttrList = "room comment";
|
||||
my $cvsid = '$Id: fhem.pl,v 1.32 2007-12-13 15:26:27 rudolfkoenig Exp $';
|
||||
my $cvsid = '$Id: fhem.pl,v 1.33 2007-12-29 15:57:42 rudolfkoenig Exp $';
|
||||
|
||||
$init_done = 0;
|
||||
|
||||
@ -152,17 +153,17 @@ my %cmds = (
|
||||
"?" => { Fn=>"CommandHelp",
|
||||
Hlp=>",get this help" },
|
||||
"attr" => { Fn=>"CommandAttr",
|
||||
Hlp=>"<name> <attrname> [<attrvalue>],set attributes for <name>" },
|
||||
Hlp=>"<devspec> <attrname> [<attrval>],set attribute for <devspec>" },
|
||||
"defattr" => { Fn=>"CommandDefAttr",
|
||||
Hlp=>"<attrname> <attrvalue>,set attr for following definitions" },
|
||||
"define" => { Fn=>"CommandDefine",
|
||||
Hlp=>"<name> <type> <options>,define a device/at/notify entity" },
|
||||
"delattr" => { Fn=>"CommandDelAttr",
|
||||
Hlp=>"<name> [<attrname>],delete attribute <attrname> for <name>" },
|
||||
"deleteattr" => { Fn=>"CommandDeleteAttr",
|
||||
Hlp=>"<devspec> [<attrname>],delete attribute for <devspec>" },
|
||||
"delete" => { Fn=>"CommandDelete",
|
||||
Hlp=>"name,delete the corresponding definition"},
|
||||
Hlp=>"<devspec>,delete the corresponding definition(s)"},
|
||||
"get" => { Fn=>"CommandGet",
|
||||
Hlp=>"<name> <type dependent>,request data from <name>" },
|
||||
Hlp=>"<devspec> <type dependent>,request data from <devspec>" },
|
||||
"help" => { Fn=>"CommandHelp",
|
||||
Hlp=>",get this help" },
|
||||
"include" => { Fn=>"CommandInclude",
|
||||
@ -170,7 +171,7 @@ my %cmds = (
|
||||
"inform" => { Fn=>"CommandInform",
|
||||
Hlp=>"{on|off},echo all commands and events to this client" },
|
||||
"list" => { Fn=>"CommandList",
|
||||
Hlp=>"[device],list definitions and status info" },
|
||||
Hlp=>"[devspec],list definitions and status info" },
|
||||
"modify" => { Fn=>"CommandModify",
|
||||
Hlp=>"device <options>,modify the definition (e.g. at, notify)" },
|
||||
"quit" => { Fn=>"CommandQuit",
|
||||
@ -184,15 +185,15 @@ my %cmds = (
|
||||
"save" => { Fn=>"CommandSave",
|
||||
Hlp=>"[configfile],write the configfile and the statefile" },
|
||||
"set" => { Fn=>"CommandSet",
|
||||
Hlp=>"<name> <type dependent>,transmit code for <name>" },
|
||||
Hlp=>"<devspec> <type dependent>,transmit code for <devspec>" },
|
||||
"setstate"=> { Fn=>"CommandSetstate",
|
||||
Hlp=>"<name> <state>,set the state shown in the command list" },
|
||||
Hlp=>"<devspec> <state>,set the state shown in the command list" },
|
||||
"shutdown"=> { Fn=>"CommandShutdown",
|
||||
Hlp=>",terminate the server" },
|
||||
"sleep" => { Fn=>"CommandSleep",
|
||||
Hlp=>"<sec>,sleep for sec, 3 decimal places are interpreted" },
|
||||
"trigger" => { Fn=>"CommandTrigger",
|
||||
Hlp=>"<dev> <state>,trigger notify command" },
|
||||
Hlp=>"<devspec> <state>,trigger notify command" },
|
||||
"xmllist" => { Fn=>"CommandXmlList",
|
||||
Hlp=>",list definitions and status info as xml" },
|
||||
);
|
||||
@ -533,6 +534,38 @@ AnalyzeCommand($$)
|
||||
}
|
||||
}
|
||||
|
||||
#####################################
|
||||
my $namedef =
|
||||
"where <name> is either:\n" .
|
||||
"- a single device name\n" .
|
||||
"- a list seperated by komma (,)\n" .
|
||||
"- a regexp, if contains one of the following characters: *[]^\$\n" .
|
||||
"- a range seperated by dash (-)\n";
|
||||
|
||||
sub
|
||||
devspec2array($)
|
||||
{
|
||||
my ($name) = @_;
|
||||
return $name if(defined($defs{$name}));
|
||||
my @ret;
|
||||
|
||||
foreach my $l (split(",", $name)) { # List
|
||||
if($l =~ m/[*\[\]^\$]/) { # Regexp
|
||||
push @ret, grep($_ =~ m/$l/, sort keys %defs);
|
||||
next;
|
||||
}
|
||||
if($l =~ m/-/) { # Range
|
||||
my ($lower, $upper) = split("-", $l, 2);
|
||||
push @ret, grep($_ ge $lower && $_ le $upper, sort keys %defs);
|
||||
next;
|
||||
}
|
||||
push @ret, $l;
|
||||
}
|
||||
|
||||
return $name if(!@ret); # No match, return the input
|
||||
return @ret;
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
CommandHelp($$)
|
||||
@ -782,7 +815,6 @@ CommandShutdown($$)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
#####################################
|
||||
sub
|
||||
DoSet(@)
|
||||
@ -798,6 +830,7 @@ DoSet(@)
|
||||
return DoTrigger($dev, join(" ", @a));
|
||||
}
|
||||
|
||||
|
||||
#####################################
|
||||
sub
|
||||
CommandSet($$)
|
||||
@ -805,32 +838,10 @@ CommandSet($$)
|
||||
my ($cl, $param) = @_;
|
||||
my @a = split("[ \t][ \t]*", $param);
|
||||
return "Usage: set <name> <type-dependent-options>\n" .
|
||||
" <name> can be an enumeration (separated by comma)\n" .
|
||||
" or a range (separated by -)" if(int(@a)<1);
|
||||
"$namedef" if(int(@a)<1);
|
||||
|
||||
my $dev = $a[0];
|
||||
my @rets;
|
||||
|
||||
foreach my $sdev (split(",", $dev)) {
|
||||
|
||||
if($sdev =~ m/-/) { # Range (separated by -)
|
||||
|
||||
if(defined($defs{$sdev})) {
|
||||
$a[0] = $sdev;
|
||||
my $ret = DoSet(@a);
|
||||
push @rets, $ret if($ret);
|
||||
next;
|
||||
}
|
||||
|
||||
my @lim = split("-", $sdev);
|
||||
foreach my $sd (sort keys %defs) {
|
||||
next if($sd lt $lim[0] || $sd gt $lim[1]);
|
||||
$a[0] = $sd;
|
||||
my $ret = DoSet(@a);
|
||||
push @rets, $ret if($ret);
|
||||
}
|
||||
next;
|
||||
}
|
||||
foreach my $sdev (devspec2array($a[0])) {
|
||||
|
||||
if(!defined($defs{$sdev})) {
|
||||
push @rets, "Please define $sdev first";
|
||||
@ -853,12 +864,26 @@ CommandGet($$)
|
||||
my ($cl, $param) = @_;
|
||||
|
||||
my @a = split("[ \t][ \t]*", $param);
|
||||
return "Usage: get <name> <type-dependent-options>" if(int(@a) < 1);
|
||||
my $dev = $a[0];
|
||||
return "Please define $dev first ($param)" if(!defined($defs{$dev}));
|
||||
return "No get implemented for $dev" if(!$modules{$defs{$dev}{TYPE}}{GetFn});
|
||||
return "Usage: get <name> <type-dependent-options>\n" .
|
||||
"$namedef" if(int(@a) < 1);
|
||||
|
||||
return CallFn($a[0], "GetFn", $defs{$dev}, @a);
|
||||
|
||||
my @rets;
|
||||
foreach my $sdev (devspec2array($a[0])) {
|
||||
if(!defined($defs{$sdev})) {
|
||||
push @rets, "Please define $sdev first";
|
||||
next;
|
||||
}
|
||||
if(!$modules{$defs{$sdev}{TYPE}}{GetFn}) {
|
||||
push @rets, "No get implemented for $sdev";
|
||||
next;
|
||||
}
|
||||
|
||||
$a[0] = $sdev;
|
||||
my $ret = CallFn($sdev, "GetFn", $defs{$sdev}, @a);
|
||||
push @rets, $ret if($ret);
|
||||
}
|
||||
return join("\n", @rets);
|
||||
}
|
||||
|
||||
#####################################
|
||||
@ -985,38 +1010,65 @@ CommandDelete($$)
|
||||
{
|
||||
my ($cl, $def) = @_;
|
||||
|
||||
return "Please define $def first" if(!defined($defs{$def}));
|
||||
my $ret = CallFn($def, "UndefFn", $defs{$def}, $def);
|
||||
return $ret if($ret);
|
||||
return "Usage: delete <name>\n" .
|
||||
"$namedef" if(!$def);
|
||||
|
||||
delete($attr{$def});
|
||||
delete($defs{$def});
|
||||
my @rets;
|
||||
foreach my $sdev (devspec2array($def)) {
|
||||
if(!defined($defs{$sdev})) {
|
||||
push @rets, "Please define $sdev first";
|
||||
next;
|
||||
}
|
||||
|
||||
return undef;
|
||||
my $ret = CallFn($sdev, "UndefFn", $defs{$sdev}, $sdev);
|
||||
if($ret) {
|
||||
push @rets, $ret;
|
||||
next;
|
||||
}
|
||||
delete($attr{$sdev});
|
||||
delete($defs{$sdev});
|
||||
}
|
||||
return join("\n", @rets);
|
||||
}
|
||||
|
||||
#############
|
||||
sub
|
||||
CommandDelAttr($$)
|
||||
CommandDeleteAttr($$)
|
||||
{
|
||||
my ($cl, $def) = @_;
|
||||
|
||||
my @a = split(" ", $def, 2);
|
||||
return "Usage: delattr <name> [<attrname>]" if(@a < 1);
|
||||
return "Cannot delete global parameters" if($a[0] eq "global");
|
||||
return "No definition found for $a[0]\n" if(!$defs{$a[0]});
|
||||
return "Usage: deleteattr <name> [<attrname>]\n" .
|
||||
"$namedef" if(@a < 1);
|
||||
|
||||
$ret = CallFn($a[0], "AttrFn", "del", @a);
|
||||
return $ret if($ret);
|
||||
my @rets;
|
||||
foreach my $sdev (devspec2array($a[0])) {
|
||||
|
||||
if($sdev eq "global") {
|
||||
push @rets, "Cannot delete global parameters";
|
||||
next;
|
||||
}
|
||||
if(!defined($defs{$sdev})) {
|
||||
push @rets, "Please define $sdev first";
|
||||
next;
|
||||
}
|
||||
|
||||
$a[0] = $sdev;
|
||||
$ret = CallFn($sdev, "AttrFn", "del", @a);
|
||||
if($ret) {
|
||||
push @rets, $ret;
|
||||
next;
|
||||
}
|
||||
|
||||
if(@a == 1) {
|
||||
delete($attr{$sdev});
|
||||
} else {
|
||||
delete($attr{$sdev}{$a[1]}) if(defined($attr{$sdev}));
|
||||
}
|
||||
|
||||
if(@a == 1) {
|
||||
delete($attr{$a[0]});
|
||||
return undef;
|
||||
}
|
||||
return "Attribute not defined"
|
||||
if(!defined($attr{$a[0]}) || !defined($attr{$a[0]}{$a[1]}));
|
||||
delete($attr{$a[0]}{$a[1]});
|
||||
return undef;
|
||||
|
||||
return join("\n", @rets);
|
||||
}
|
||||
|
||||
sub
|
||||
@ -1071,11 +1123,15 @@ CommandList($$)
|
||||
|
||||
} else {
|
||||
|
||||
return "No device named $param found" if(!defined($defs{$param}));
|
||||
my $d = $defs{$param};
|
||||
foreach my $sdev (devspec2array($param)) {
|
||||
if(!defined($defs{$sdev})) {
|
||||
$str .= "No device named $param found";
|
||||
next;
|
||||
}
|
||||
$str .= "Internals:\n";
|
||||
$str .= PrintHash($defs{$sdev}, 2);
|
||||
}
|
||||
|
||||
$str .= "Internals:\n";
|
||||
$str .= PrintHash($d, 2);
|
||||
}
|
||||
|
||||
return $str;
|
||||
@ -1224,40 +1280,15 @@ getAllAttr($)
|
||||
return $list;
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
CommandAttr($$)
|
||||
GlobalAttr($$)
|
||||
{
|
||||
my ($cl, $param) = @_;
|
||||
my $ret = undef;
|
||||
|
||||
my @a = split(" ", $param, 3);
|
||||
return "Usage: attr <name> <attrname> [<attrvalue>]" if(@a < 2);
|
||||
|
||||
return "Please define $a[0] first: no definition found"
|
||||
if(!defined($defs{$a[0]}));
|
||||
|
||||
my $list = getAllAttr($a[0]);
|
||||
return "Unknown argument $a[1], choose one of $list" if($a[1] eq "?");
|
||||
return "Unknown attribute $a[1], use attr global userattr ($list)"
|
||||
if(" $list " !~ m/ ${a[1]}[ :;]/);
|
||||
|
||||
|
||||
$ret = CallFn($a[0], "AttrFn", "set", @a);
|
||||
return $ret if($ret);
|
||||
|
||||
if(defined($a[2])) {
|
||||
$attr{$a[0]}{$a[1]} = $a[2];
|
||||
} else {
|
||||
$attr{$a[0]}{$a[1]} = "1";
|
||||
}
|
||||
|
||||
return if($a[0] ne "global"); # Global specials ahead
|
||||
my ($name, $val) = @_;
|
||||
|
||||
################
|
||||
if($a[1] eq "logfile") {
|
||||
if($name eq "logfile") {
|
||||
my @t = localtime;
|
||||
my $ret = OpenLogfile(ResolveDateWildcards($a[2], @t));
|
||||
my $ret = OpenLogfile(ResolveDateWildcards($val, @t));
|
||||
if($ret) {
|
||||
return $ret if($init_done);
|
||||
die($ret);
|
||||
@ -1265,10 +1296,10 @@ CommandAttr($$)
|
||||
}
|
||||
|
||||
################
|
||||
elsif($a[1] eq "port") {
|
||||
elsif($name eq "port") {
|
||||
|
||||
return undef if($reread_active);
|
||||
my ($port, $global) = split(" ", $a[2]);
|
||||
my ($port, $global) = split(" ", $val);
|
||||
if($global && $global ne "global") {
|
||||
return "Bad syntax, usage: attr global port <portnumber> [global]";
|
||||
}
|
||||
@ -1289,8 +1320,8 @@ CommandAttr($$)
|
||||
}
|
||||
|
||||
################
|
||||
elsif($a[1] eq "verbose") {
|
||||
if($a[2] =~ m/^[0-5]$/) {
|
||||
elsif($name eq "verbose") {
|
||||
if($val =~ m/^[0-5]$/) {
|
||||
return undef;
|
||||
} else {
|
||||
$attr{global}{verbose} = 3;
|
||||
@ -1298,10 +1329,10 @@ CommandAttr($$)
|
||||
}
|
||||
}
|
||||
|
||||
elsif($a[1] eq "modpath") {
|
||||
elsif($name eq "modpath") {
|
||||
return "modpath must point to a directory where the FHEM subdir is"
|
||||
if(! -d "$a[2]/FHEM");
|
||||
my $modpath = "$a[2]/FHEM";
|
||||
if(! -d "$val/FHEM");
|
||||
my $modpath = "$val/FHEM";
|
||||
|
||||
opendir(DH, $modpath) || return "Can't read $modpath: $!";
|
||||
my $counter = 0;
|
||||
@ -1327,12 +1358,67 @@ CommandAttr($$)
|
||||
"point modpath to a directory where the FHEM subdir is";
|
||||
}
|
||||
|
||||
$modpath_set = $a[2];
|
||||
$modpath_set = $val;
|
||||
}
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
#####################################
|
||||
sub
|
||||
CommandAttr($$)
|
||||
{
|
||||
my ($cl, $param) = @_;
|
||||
my $ret = undef;
|
||||
|
||||
my @a = split(" ", $param, 3);
|
||||
return "Usage: attr <name> <attrname> [<attrvalue>]\n" .
|
||||
"$namedef" if(@a < 2);
|
||||
|
||||
|
||||
my @rets;
|
||||
foreach my $sdev (devspec2array($a[0])) {
|
||||
|
||||
if(!defined($defs{$sdev})) {
|
||||
push @rets, "Please define $sdev first";
|
||||
next;
|
||||
}
|
||||
|
||||
my $list = getAllAttr($sdev);
|
||||
if($a[1] eq "?") {
|
||||
push @rets, "Unknown argument $a[1], choose one of $list";
|
||||
next;
|
||||
}
|
||||
if(" $list " !~ m/ ${a[1]}[ :;]/) {
|
||||
push @rets, "Unknown attribute $a[1], use attr global userattr ($list)";
|
||||
next;
|
||||
}
|
||||
|
||||
$a[0] = $sdev;
|
||||
$ret = CallFn($sdev, "AttrFn", "set", @a);
|
||||
if($ret) {
|
||||
push @rets, $ret;
|
||||
next;
|
||||
}
|
||||
|
||||
if(defined($a[2])) {
|
||||
$attr{$sdev}{$a[1]} = $a[2];
|
||||
} else {
|
||||
$attr{$sdev}{$a[1]} = "1";
|
||||
}
|
||||
|
||||
if($sdev eq "global") {
|
||||
$ret = GlobalAttr($a[1], $a[2]);
|
||||
if($ret) {
|
||||
push @rets, $ret;
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return join("\n", @rets);
|
||||
}
|
||||
|
||||
|
||||
#####################################
|
||||
# Default Attr
|
||||
@ -1357,42 +1443,52 @@ sub
|
||||
CommandSetstate($$)
|
||||
{
|
||||
my ($cl, $param) = @_;
|
||||
my $ret = undef;
|
||||
|
||||
my @a = split(" ", $param, 2);
|
||||
return "Usage: setstate <name> <state>" if(@a != 2);
|
||||
return "Please define $a[0] first" if(!defined($defs{$a[0]}));
|
||||
return "Usage: setstate <name> <state>\n" .
|
||||
"$namedef" if(@a != 2);
|
||||
|
||||
my $d = $defs{$a[0]};
|
||||
|
||||
# Detailed state with timestamp
|
||||
if($a[1] =~ m/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} /) {
|
||||
my @b = split(" ", $a[1], 4);
|
||||
|
||||
if($defs{$a[0]}{TYPE} eq "FS20" && $b[2] ne "state") { # Compatibility mode
|
||||
$b[3] = $b[2] . ($b[3] ? " $b[3]" : "");
|
||||
$b[2] = "state";
|
||||
my @rets;
|
||||
foreach my $sdev (devspec2array($a[0])) {
|
||||
if(!defined($defs{$sdev})) {
|
||||
push @rets, "Please define $sdev first";
|
||||
next;
|
||||
}
|
||||
|
||||
my $tim = "$b[0] $b[1]";
|
||||
$ret = CallFn($a[0], "StateFn", $d, $tim, $b[2], $b[3]);
|
||||
return $ret if($ret);
|
||||
my $d = $defs{$sdev};
|
||||
|
||||
if(!$d->{READINGS}{$b[2]} || $d->{READINGS}{$b[2]}{TIME} lt $tim) {
|
||||
$d->{READINGS}{$b[2]}{VAL} = $b[3];
|
||||
$d->{READINGS}{$b[2]}{TIME} = $tim;
|
||||
# Detailed state with timestamp
|
||||
if($a[1] =~ m/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} /) {
|
||||
my @b = split(" ", $a[1], 4);
|
||||
|
||||
if($defs{$sdev}{TYPE} eq "FS20" && $b[2] ne "state") { # Compatibility
|
||||
$b[3] = $b[2] . ($b[3] ? " $b[3]" : "");
|
||||
$b[2] = "state";
|
||||
}
|
||||
|
||||
my $tim = "$b[0] $b[1]";
|
||||
my $ret = CallFn($sdev, "StateFn", $d, $tim, $b[2], $b[3]);
|
||||
if($ret) {
|
||||
push @rets, $ret;
|
||||
next;
|
||||
}
|
||||
|
||||
if(!$d->{READINGS}{$b[2]} || $d->{READINGS}{$b[2]}{TIME} lt $tim) {
|
||||
$d->{READINGS}{$b[2]}{VAL} = $b[3];
|
||||
$d->{READINGS}{$b[2]}{TIME} = $tim;
|
||||
}
|
||||
|
||||
} else {
|
||||
$d->{STATE} = $a[1];
|
||||
|
||||
$oldvalue{$sdev}{VAL} = $a[1];
|
||||
# This time is not the correct one, but we do not store a timestamp for
|
||||
# this reading.
|
||||
$oldvalue{$sdev}{TIME} = TimeNow();
|
||||
}
|
||||
|
||||
} else {
|
||||
$d->{STATE} = $a[1];
|
||||
|
||||
$oldvalue{$a[0]}{VAL} = $a[1];
|
||||
# This time is not the correct one, but we do not store a timestamp for
|
||||
# this reading.
|
||||
$oldvalue{$a[0]}{TIME} = TimeNow();
|
||||
}
|
||||
|
||||
return $ret;
|
||||
return join("\n", @rets);
|
||||
}
|
||||
|
||||
#####################################
|
||||
@ -1402,9 +1498,22 @@ CommandTrigger($$)
|
||||
my ($cl, $param) = @_;
|
||||
|
||||
my ($dev, $state) = split(" ", $param, 2);
|
||||
return "Usage: trigger <device> <state>" if(!$state);
|
||||
return "Please define $dev first" if(!defined($defs{$dev}));
|
||||
return DoTrigger($dev, $state);
|
||||
return "Usage: trigger <name> <state>\n" .
|
||||
"$namedef" if(!$state);
|
||||
|
||||
my @rets;
|
||||
foreach my $sdev (devspec2array($dev)) {
|
||||
if(!defined($defs{$sdev})) {
|
||||
push @rets, "Please define $sdev first";
|
||||
next;
|
||||
}
|
||||
my $ret = DoTrigger($sdev, $state);
|
||||
if($ret) {
|
||||
push @rets, $ret;
|
||||
next;
|
||||
}
|
||||
}
|
||||
return join("\n", @rets);
|
||||
}
|
||||
|
||||
#####################################
|
||||
|
Loading…
Reference in New Issue
Block a user