2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-03 16:56:54 +00:00

HMCCUDEV: device and channel addressing reworked, prepared for upcoming RPC version

git-svn-id: https://svn.fhem.de/fhem/trunk@9790 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
fhemzap 2015-11-05 18:19:02 +00:00
parent 40fc47a70d
commit dab49cd678

View File

@ -4,7 +4,7 @@
# #
# $Id:$ # $Id:$
# #
# Version 1.1 # Version 1.9
# #
# (c) 2015 zap (zap01 <at> t-online <dot> de) # (c) 2015 zap (zap01 <at> t-online <dot> de)
# #
@ -22,7 +22,7 @@
# #
# attr <name> ccureadings { 0 | 1 } # attr <name> ccureadings { 0 | 1 }
# attr <name> statechannel <channel> # attr <name> statechannel <channel>
# attr <name> stateval <text1>:<subtext1>[,...] # attr <name> statevals <text1>:<subtext1>[,...]
# attr <name> substitute <regexp1>:<subtext1>[,...] # attr <name> substitute <regexp1>:<subtext1>[,...]
# #
################################################################ ################################################################
@ -54,7 +54,7 @@ sub HMCCUDEV_Initialize ($)
$hash->{GetFn} = "HMCCUDEV_Get"; $hash->{GetFn} = "HMCCUDEV_Get";
$hash->{AttrFn} = "HMCCUDEV_Attr"; $hash->{AttrFn} = "HMCCUDEV_Attr";
$hash->{AttrList} = "IODev ccureadings:0,1 stateval substitute statechannel:0,1,2,3 loglevel:0,1,2,3,4,5,6 ". $readingFnAttributes; $hash->{AttrList} = "IODev ccureadingformat:name,address,datapoint ccureadings:0,1 statevals substitute statechannel loglevel:0,1,2,3,4,5,6 ". $readingFnAttributes;
} }
##################################### #####################################
@ -67,20 +67,45 @@ sub HMCCUDEV_Define ($$)
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my @a = split("[ \t][ \t]*", $def); my @a = split("[ \t][ \t]*", $def);
return "Specifiy the CCU device name as parameters" if(@a < 3); return "Specifiy the CCU device name or address as parameters" if (@a < 3);
return "Channel or datapoint not allowed in CCU device name" if ($a[2] =~ /^(.*):/);
$attr{$name}{ccureadings} = 1; my $devname = shift @a;
my $devtype = shift @a;
my $devspec = shift @a;
# Keep name of CCU device if ($devspec =~ /^[A-Z]{3,3}[0-9]{7,7}$/) {
$hash->{ccudev} = $a[2]; # CCU Device address
$hash->{ccuaddr} = $devspec;
# Set commands / values $hash->{ccuname} = HMCCU_GetDeviceName ($devspec, '');
if (defined ($a[3]) && $a[3] eq 'readonly') { }
$hash->{statevals} = $a[3]; elsif ($devspec =~ /^(.*):/ || $devspec =~ /\..+$/) {
# Channel and/or datapoint specified
return "Channel or datapoint not allowed in CCU device name";
} }
else { else {
# CCU Device name
$hash->{ccuname} = $devspec;
$hash->{ccuaddr} = HMCCU_GetAddress ($devspec, '', 1);
}
return "CCU device address not found" if ($hash->{ccuaddr} eq '');
return "CCU device name not found" if ($hash->{ccuname} eq '');
$hash->{ccutype} = HMCCU_GetDeviceType ($hash->{ccuaddr}, '');
$hash->{ccuif} = HMCCU_GetDeviceInterface ($hash->{ccuaddr}, '');
$hash->{statevals} = 'devstate'; $hash->{statevals} = 'devstate';
$hash->{statechannel} = '';
my $arg = shift @a;
while (defined ($arg)) {
if ($arg eq 'readonly') {
$hash->{statevals} = $arg;
}
else {
return "State channel must be numeric" if ($arg !~ /^[0-9]+$/);
$hash->{statechannel} = $arg;
}
$arg = shift @a;
} }
# Inform HMCCU device about client device # Inform HMCCU device about client device
@ -103,7 +128,7 @@ sub HMCCUDEV_Attr ($@)
if ($attrname eq "IODev") { if ($attrname eq "IODev") {
$defs{$name}{IODev} = $defs{$attrval}; $defs{$name}{IODev} = $defs{$attrval};
} }
elsif ($attrname eq "stateval") { elsif ($attrname eq "statevals") {
$defs{$name}{statevals} = "devstate"; $defs{$name}{statevals} = "devstate";
my @states = split /,/,$attrval; my @states = split /,/,$attrval;
foreach my $st (@states) { foreach my $st (@states) {
@ -112,6 +137,9 @@ sub HMCCUDEV_Attr ($@)
$defs{$name}{statevals} .= '|'.$statesubs[0]; $defs{$name}{statevals} .= '|'.$statesubs[0];
} }
} }
elsif ($attrname eq "statechannel") {
$defs{$name}{statechannel} = $attrval;
}
} }
return undef; return undef;
@ -134,51 +162,48 @@ sub HMCCUDEV_Set ($@)
return undef; return undef;
} }
my $statechannel = AttrVal ($name, "statechannel", ''); # my $statechannel = AttrVal ($name, "statechannel", '');
my $stateval = AttrVal ($name, "stateval", ''); my $statechannel = $hash->{statechannel};
my $statevals = AttrVal ($name, "statevals", '');
my $substitute = AttrVal ($name, "substitute", ''); my $substitute = AttrVal ($name, "substitute", '');
my $hmccu_hash = $hash->{IODev}; my $hmccu_hash = $hash->{IODev};
my $hmccu_name = $hash->{IODev}->{NAME}; my $hmccu_name = $hash->{IODev}->{NAME};
my $ccudev = $hash->{ccudev};
# process set <name> command par1 ... # process set <name> command par1 ...
if ($opt eq 'datapoint') { if ($opt eq 'datapoint') {
my $objname = shift @a; my $objname = shift @a;
my $objvalue = join ('%20', @a); my $objvalue = join ('%20', @a);
if (!defined ($objname) || $objname !~ /^[0-9]+\..*$/ || !defined ($objvalue)) { if (!defined ($objname) || $objname !~ /^[0-9]+\..+$/ || !defined ($objvalue)) {
return HMCCUDEV_SetError ($hash, "Usage: set <device> datapoint <channel>.<datapoint> <value>"); return HMCCUDEV_SetError ($hash, "Usage: set <device> datapoint <channel>.<datapoint> <value> [...]");
} }
$objname = $ccudev.':'.$objname;
my ($dev, $chn, $dpt, $flags) = HMCCU_ParseCCUDev ($objname);
if ($flags != 7) {
return HMCCUDEV_SetError ($hash, "Format for objname is channel.datapoint");
}
$objvalue = HMCCU_Substitute ($objvalue, $substitute); $objvalue = HMCCU_Substitute ($objvalue, $substitute);
# Build datapoint address
$objname = $hash->{ccuif}.'.'.$hash->{ccuaddr}.':'.$objname;
HMCCU_Set ($hmccu_hash, $hmccu_name, 'datapoint', $objname, $objvalue); HMCCU_Set ($hmccu_hash, $hmccu_name, 'datapoint', $objname, $objvalue);
usleep (100000); usleep (100000);
HMCCU_Get ($hmccu_hash, $hmccu_name, 'datapoint', $objname); HMCCU_Get ($hmccu_hash, $hmccu_name, 'datapoint', $objname);
return undef; return undef;
} }
elsif ($opt =~ /($hash->{statevals})/) { elsif ($opt =~ /^($hash->{statevals})$/) {
my $cmd = $1; my $cmd = $1;
my $objvalue = ($cmd ne 'devstate') ? $cmd : join ('%20', @a); my $objvalue = ($cmd ne 'devstate') ? $cmd : join ('%20', @a);
if ($statechannel eq '') { if ($statechannel eq '') {
return undef; return HMCCUDEV_SetError ($hash, "No STATE channel specified");
# return HMCCUDEV_SetError ($hash, "No STATE channel specified");
} }
if (!defined ($objvalue)) { if (!defined ($objvalue)) {
return HMCCUDEV_SetError ($hash, "Usage: set <device> devstate <value>"); return HMCCUDEV_SetError ($hash, "Usage: set <device> devstate <value>");
} }
$objvalue = HMCCU_Substitute ($objvalue, $statevals);
# Build datapoint address
my $objname = $hash->{ccuif}.'.'.$hash->{ccuaddr}.':'.$statechannel.'.STATE';
my $objname = $ccudev.':'.$statechannel.'.STATE';
$objvalue = HMCCU_Substitute ($objvalue, $stateval);
HMCCU_Set ($hmccu_hash, $hmccu_name, 'datapoint', $objname, $objvalue); HMCCU_Set ($hmccu_hash, $hmccu_name, 'datapoint', $objname, $objvalue);
usleep (100000); usleep (100000);
HMCCU_Get ($hmccu_hash, $hmccu_name, 'datapoint', $objname); HMCCU_Get ($hmccu_hash, $hmccu_name, 'datapoint', $objname);
@ -189,7 +214,7 @@ sub HMCCUDEV_Set ($@)
my $retmsg = "HMCCUDEV: Unknown argument $opt, choose one of datapoint devstate"; my $retmsg = "HMCCUDEV: Unknown argument $opt, choose one of datapoint devstate";
return undef if ($hash->{statevals} eq 'readonly'); return undef if ($hash->{statevals} eq 'readonly');
if ($stateval ne '') { if ($statevals ne '') {
my @cmdlist = split /\|/,$hash->{statevals}; my @cmdlist = split /\|/,$hash->{statevals};
shift @cmdlist; shift @cmdlist;
$retmsg .= ':'.join(',',@cmdlist); $retmsg .= ':'.join(',',@cmdlist);
@ -218,16 +243,18 @@ sub HMCCUDEV_Get ($@)
my $hmccu_hash = $hash->{IODev}; my $hmccu_hash = $hash->{IODev};
my $hmccu_name = $hash->{IODev}->{NAME}; my $hmccu_name = $hash->{IODev}->{NAME};
my $ccudev = $hash->{ccudev};
if ($opt eq 'devstate') { if ($opt eq 'devstate') {
my $statechannel = AttrVal ($name, 'statechannel', ''); # my $statechannel = AttrVal ($name, 'statechannel', '');
if ($statechannel ne '') { my $statechannel = $hash->{statechannel};
my $objname = $ccudev.':'.$statechannel; if ($statechannel eq '') {
return HMCCUDEV_SetError ($hash, "No STATE channel specified");
HMCCU_Get ($hmccu_hash, $hmccu_name, 'devstate', $objname);
} }
# Build datapoint address
my $objname = $hash->{ccuif}.'.'.$hash->{ccuaddr}.':'.$statechannel;
HMCCU_Get ($hmccu_hash, $hmccu_name, 'devstate', $objname);
return undef; return undef;
} }
elsif ($opt eq 'datapoint') { elsif ($opt eq 'datapoint') {
@ -236,11 +263,8 @@ sub HMCCUDEV_Get ($@)
return HMCCUDEV_SetError ($hash, "Usage: get <device> datapoint <channel>.<datapoint>"); return HMCCUDEV_SetError ($hash, "Usage: get <device> datapoint <channel>.<datapoint>");
} }
$objname = $ccudev.':'.$objname; # Build datapoint address
my ($dev, $chn, $dpt, $flags) = HMCCU_ParseCCUDev ($objname); $objname = $hash->{ccuif}.'.'.$hash->{ccuaddr}.':'.$objname;
if ($flags != 7) {
return HMCCUDEV_SetError ($hash, "Format for objname is channel.datapoint");
}
HMCCU_Get ($hmccu_hash, $hmccu_name, 'datapoint', $objname); HMCCU_Get ($hmccu_hash, $hmccu_name, 'datapoint', $objname);
@ -248,7 +272,7 @@ sub HMCCUDEV_Get ($@)
} }
elsif ($opt eq 'update') { elsif ($opt eq 'update') {
foreach my $r (keys %{$hash->{READINGS}}) { foreach my $r (keys %{$hash->{READINGS}}) {
if ($r =~ /^$ccudev:[0-9]\..+/) { if ($r =~ /^.+:[0-9]+\..+/) {
HMCCU_Get ($hmccu_hash, $hmccu_name, 'datapoint', $r); HMCCU_Get ($hmccu_hash, $hmccu_name, 'datapoint', $r);
} }
} }
@ -318,12 +342,12 @@ sub HMCCUDEV_SetError ($$)
<br/> <br/>
State of a CCU device channel is set to <i>StateValue</i>. Channel must State of a CCU device channel is set to <i>StateValue</i>. Channel must
be defined as attribute statechannel. State values can be replaced be defined as attribute statechannel. State values can be replaced
by setting attribute stateval. by setting attribute statevals.
<br/><br/> <br/><br/>
Example:<br/> Example:<br/>
<code> <code>
attr myswitch statechannel 1<br/> attr myswitch statechannel 1<br/>
attr myswitch stateval on:true,off:false<br/> attr myswitch statevals on:true,off:false<br/>
set myswitch on set myswitch on
</code> </code>
</li><br/> </li><br/>
@ -364,15 +388,18 @@ sub HMCCUDEV_SetError ($$)
<br/> <br/>
If set to 1 values read from CCU will be stored as readings. If set to 1 values read from CCU will be stored as readings.
</li><br/> </li><br/>
<li>statechannel &lt;<i>Channel</i>&gt; <li>statechannel &lt;channel-number&gt;
<br/> <br/>
Channel for setting device state by devstate command. Channel for setting device state by devstate command.
</li><br/> </li><br/>
<li>stateval &lt;<i>text</i>:<i>text</i>[,...]&gt; <li>statevals &lt;text&gt;:&lt;text&gt;[,...]
<br/> <br/>
Define substitution for set commands values. Define substitution for set commands values. The parameters &lt;text&gt;
are available as set commands. Example:<br/>
<code>attr my_switch statevals on:true,off:false</code><br/>
<code>set my_switch on</code>
</li><br/> </li><br/>
<li>substitude &lt;<i>expression</i>:<i>string</i>[,...]&gt; <li>substitude &lt;expression&gt;:&lt;subststr&gt;[,...]
<br/> <br/>
Define substitions for reading values. Substitutions for parfile values must Define substitions for reading values. Substitutions for parfile values must
be specified in parfiles. be specified in parfiles.