2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-02-07 16:59:18 +00:00

HMCCU: Several updates and fixes

git-svn-id: https://svn.fhem.de/fhem/trunk@11496 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
fhemzap 2016-05-22 16:48:17 +00:00
parent bdf8d639e0
commit afc574626a
6 changed files with 1365 additions and 459 deletions

File diff suppressed because it is too large Load Diff

View File

@ -29,9 +29,10 @@
# attr <name> ccureadings { 0 | 1 }
# attr <name> ccureadingfilter <datapoint-expr>
# attr <name> ccureadingformat { name | address | datapoint }
# attr <name> ccuverify { 0 | 1 }
# attr <name> ccuverify { 0 | 1 | 2 }
# attr <name> controldatapoint <datapoint>
# attr <name> disable { 0 | 1 }
# attr <name> statedatapoint <datapoint>
# attr <name> statevals <text1>:<subtext1>[,...]
# attr <name> substitute <subst-rule>[;...]
#
@ -66,7 +67,7 @@ sub HMCCUCHN_Initialize ($)
$hash->{GetFn} = "HMCCUCHN_Get";
$hash->{AttrFn} = "HMCCUCHN_Attr";
$hash->{AttrList} = "IODev ccureadingfilter ccureadingformat:name,address,datapoint ccureadings:0,1 ccuverify:0,1 ccuget:State,Value controldatapoint disable:0,1 statedatapoint statevals substitute stripnumber:0,1,2 ". $readingFnAttributes;
$hash->{AttrList} = "IODev ccureadingfilter ccureadingformat:name,address,datapoint ccureadings:0,1 ccuverify:0,1,2 ccuget:State,Value controldatapoint disable:0,1 statedatapoint statevals substitute stripnumber:0,1,2 ". $readingFnAttributes;
}
#####################################
@ -185,9 +186,10 @@ sub HMCCUCHN_Set ($@)
}
my $statevals = AttrVal ($name, "statevals", '');
my $statedatapoint = AttrVal ($name, "statedatapoint", 'STATE');
my $controldatapoint = AttrVal ($name, "controldatapoint", '');
my $ccuverify = AttrVal ($name, "ccuverify", 0);
# my $statedatapoint = AttrVal ($name, "statedatapoint", 'STATE');
# my $controldatapoint = AttrVal ($name, "controldatapoint", '');
my ($sc, $statedatapoint, $cc, $controldatapoint) = HMCCU_GetSpecialDatapoints (
$hash, '', 'STATE', '', '');
my $result = '';
my $rc;
@ -209,18 +211,13 @@ sub HMCCUCHN_Set ($@)
$rc = HMCCU_SetDatapoint ($hash, $objname, $objvalue);
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
if ($ccuverify) {
usleep (100000);
($rc, $result) = HMCCU_GetDatapoint ($hash, $objname);
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
}
HMCCU_SetState ($hash, "OK");
return undef;
}
elsif ($opt eq 'control') {
return HMCCU_SetError ($hash, "Attribute controldatapoint not set") if ($controldatapoint eq '');
my $objvalue = shift @a;
my $objname = $hash->{ccuif}.'.'.$hash->{ccuaddr}.':'.$controldatapoint;
my $objname = $hash->{ccuif}.'.'.$hash->{ccuaddr}.'.'.$controldatapoint;
$rc = HMCCU_SetDatapoint ($hash, $objname, $objvalue);
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
HMCCU_SetState ($hash, "OK");
@ -240,11 +237,6 @@ sub HMCCUCHN_Set ($@)
$rc = HMCCU_SetDatapoint ($hash, $objname, $objvalue);
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
if ($ccuverify) {
usleep (100000);
($rc, $result) = HMCCU_GetDatapoint ($hash, $objname);
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
}
HMCCU_SetState ($hash, "OK");
return undef;
}
@ -297,7 +289,7 @@ sub HMCCUCHN_Set ($@)
if ($hash->{statevals} ne '') {
my @cmdlist = split /\|/,$hash->{statevals};
shift @cmdlist;
$retmsg .= ':'.join(',',@cmdlist);
$retmsg .= ':'.join(',',@cmdlist) if (@cmdlist > 0);
foreach my $sv (@cmdlist) {
$retmsg .= ' '.$sv.':noArg';
}
@ -329,7 +321,8 @@ sub HMCCUCHN_Get ($@)
return "HMCCUCHN: CCU busy";
}
my $statedatapoint = AttrVal ($name, "statedatapoint", 'STATE');
# my $statedatapoint = AttrVal ($name, "statedatapoint", 'STATE');
my ($sc, $statedatapoint, $cc, $cd) = HMCCU_GetSpecialDatapoints ($hash, '', 'STATE', '', '');
my $ccureadings = AttrVal ($name, "ccureadings", 1);
my $result = '';
@ -533,8 +526,10 @@ sub HMCCUCHN_SetError ($$)
Syntax for filter rule is: [channel-no:]RegExp<br/>
If channel-no is specified the following rule applies only to this channel.
</li><br/>
<li>ccuverify &lt;0 | 1&gt;<br/>
If set to 1 a datapoint is read for verification after set operation.
<li>ccuverify &lt;0 | 1 | 2&gt;<br/>
If set to 1 a datapoint is read for verification after set operation. If set to 2 the
corresponding reading will be set to the new value directly after setting a datapoint
in CCU.
</li><br/>
<li>controldatapoint &lt;datapoint&gt;<br/>
Set datapoint for device control. Can be use to realize user defined control elements for

View File

@ -4,7 +4,7 @@
#
# $Id:$
#
# Version 3.1
# Version 3.2
#
# (c) 2016 zap (zap01 <at> t-online <dot> de)
#
@ -16,6 +16,7 @@
# set <name> config [<channel>] <parameter>=<value> [...]
# set <name> control <value>
# set <name> datapoint <channel>.<datapoint> <value>
# set <name> defaults
# set <name> devstate <value>
# set <name> on-for-timer <seconds>
# set <name> <stateval_cmds>
@ -23,6 +24,7 @@
#
# get <name> devstate
# get <name> datapoint <channel>.<datapoint>
# get <name> defaults
# get <name> channel <channel>[.<datapoint-expr>]
# get <name> config [<channel>]
# get <name> configdesc [<channel>]
@ -32,12 +34,12 @@
# attr <name> ccureadings { 0 | 1 }
# attr <name> ccureadingformat { address | name }
# attr <name> ccureadingfilter <filter-rule>[,...]
# attr <name> ccuverify { 0 | 1 }
# attr <name> controldatapoint <channel>.<datapoint>
# attr <name> ccuverify { 0 | 1 | 2}
# attr <name> controldatapoint <channel-number>.<datapoint>
# attr <name> disable { 0 | 1 }
# attr <name> mapdatapoints <channel>.<datapoint>=<channel>.<datapoint>[,...]
# attr <name> statechannel <channel>
# attr <name> statedatapoint <datapoint>
# attr <name> statedatapoint [<channel-number>.]<datapoint>
# attr <name> statevals <text1>:<subtext1>[,...]
# attr <name> substitute <regexp1>:<subtext1>[,...]
#
@ -73,7 +75,7 @@ sub HMCCUDEV_Initialize ($)
$hash->{GetFn} = "HMCCUDEV_Get";
$hash->{AttrFn} = "HMCCUDEV_Attr";
$hash->{AttrList} = "IODev ccureadingfilter:textField-long ccureadingformat:name,address ccureadings:0,1 ccuget:State,Value ccuverify:0,1 disable:0,1 mapdatapoints:textField-long statevals substitute statechannel statedatapoint controldatapoint stripnumber:0,1,2 ". $readingFnAttributes;
$hash->{AttrList} = "IODev ccureadingfilter:textField-long ccureadingformat:name,address ccureadings:0,1 ccuget:State,Value ccuverify:0,1,2 disable:0,1 mapdatapoints:textField-long statevals substitute statechannel statedatapoint controldatapoint stripnumber:0,1,2 ". $readingFnAttributes;
}
#####################################
@ -278,11 +280,12 @@ sub HMCCUDEV_Set ($@)
return "HMCCUDEV: CCU busy";
}
my $statechannel = AttrVal ($name, "statechannel", '');
my $statedatapoint = AttrVal ($name, "statedatapoint", 'STATE');
# my $statechannel = AttrVal ($name, "statechannel", '');
# my $statedatapoint = AttrVal ($name, "statedatapoint", 'STATE');
my $statevals = AttrVal ($name, "statevals", '');
my $controldatapoint = AttrVal ($name, "controldatapoint", '');
my $ccuverify = AttrVal ($name, "ccuverify", 0);
# my $controldatapoint = AttrVal ($name, "controldatapoint", '');
my ($statechannel, $statedatapoint, $controlchannel, $controldatapoint) =
HMCCU_GetSpecialDatapoints ($hash, '', 'STATE', '', '');
my $result = '';
my $rc;
@ -305,20 +308,13 @@ sub HMCCUDEV_Set ($@)
$rc = HMCCU_SetDatapoint ($hash, $objname, $objvalue);
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
if ($ccuverify && HMCCU_IsValidDatapoint ($hash, $hash->{ccutype}, $hash->{ccuaddr},
$objname, 1)) {
usleep (100000);
($rc, $result) = HMCCU_GetDatapoint ($hash, $objname);
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
}
HMCCU_SetState ($hash, "OK");
return undef;
}
elsif ($opt eq 'control') {
return HMCCU_SetError ($hash, "Attribute controldatapoint not set") if ($controldatapoint eq '');
my $objvalue = shift @a;
my $objname = $hash->{ccuif}.'.'.$hash->{ccuaddr}.':'.$controldatapoint;
my $objname = $hash->{ccuif}.'.'.$hash->{ccuaddr}.':'.$controlchannel.'.'.$controldatapoint;
$rc = HMCCU_SetDatapoint ($hash, $objname, $objvalue);
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
@ -340,12 +336,6 @@ sub HMCCUDEV_Set ($@)
$rc = HMCCU_SetDatapoint ($hash, $objname, $objvalue);
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
if ($ccuverify) {
usleep (100000);
($rc, $result) = HMCCU_GetDatapoint ($hash, $objname);
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
}
HMCCU_SetState ($hash, "OK");
return undef;
}
@ -423,8 +413,13 @@ sub HMCCUDEV_Set ($@)
HMCCU_SetState ($hash, "OK");
return undef;
}
elsif ($opt eq 'defaults') {
HMCCU_SetDefaults ($hash);
HMCCU_SetState ($hash, "OK");
return undef;
}
else {
my $retmsg = "HMCCUDEV: Unknown argument $opt, choose one of config control datapoint";
my $retmsg = "HMCCUDEV: Unknown argument $opt, choose one of config control datapoint defaults:noArg";
return undef if ($hash->{statevals} eq 'readonly');
if ($statechannel ne '') {
@ -432,7 +427,7 @@ sub HMCCUDEV_Set ($@)
if ($hash->{statevals} ne '') {
my @cmdlist = split /\|/,$hash->{statevals};
shift @cmdlist;
$retmsg .= ':'.join(',',@cmdlist);
$retmsg .= ':'.join(',',@cmdlist) if (@cmdlist > 0);
foreach my $sv (@cmdlist) {
$retmsg .= ' '.$sv.':noArg';
}
@ -467,9 +462,11 @@ sub HMCCUDEV_Get ($@)
return "HMCCUDEV: CCU busy";
}
my $statechannel = AttrVal ($name, 'statechannel', '');
my $statedatapoint = AttrVal ($name, 'statedatapoint', 'STATE');
# my $statechannel = AttrVal ($name, 'statechannel', '');
# my $statedatapoint = AttrVal ($name, 'statedatapoint', 'STATE');
my $ccureadings = AttrVal ($name, 'ccureadings', 1);
my ($statechannel, $statedatapoint, $cc, $cd) = HMCCU_GetSpecialDatapoints (
$hash, '', 'STATE', '', '');
my $result = '';
my $rc;
@ -591,6 +588,10 @@ sub HMCCUDEV_Get ($@)
HMCCU_SetState ($hash, "OK") if (exists ($hash->{STATE}) && $hash->{STATE} eq "Error");
return $res;
}
elsif ($opt eq 'defaults') {
$result = HMCCU_GetDefaults ($hash);
return $result;
}
else {
my $retmsg = "HMCCUDEV: Unknown argument $opt, choose one of datapoint";
@ -598,7 +599,7 @@ sub HMCCUDEV_Get ($@)
my $valuecount = HMCCU_GetValidDatapoints ($hash, $hash->{ccutype}, -1, 1, \@valuelist);
$retmsg .= ":".join(",", @valuelist) if ($valuecount > 0);
$retmsg .= " channel update:noArg config configdesc deviceinfo:noArg";
$retmsg .= " defaults:noArg channel update:noArg config configdesc deviceinfo:noArg";
if ($statechannel ne '') {
$retmsg .= ' devstate:noArg';
@ -676,6 +677,9 @@ sub HMCCUDEV_SetError ($$)
Example:<br/>
<code>set light_entrance devstate on</code>
</li><br/>
<li>set &lt;name&gt; defaults<br/>
Set default attributes for CCU device type.
</li><br/>
<li>set &lt;name&gt; on-for-timer &lt;seconds&gt;<br/>
Switch device on for specified time. Requires that 'statechannel' is set and
contains datapoint ON_TIME. In addition 'statevals' must contain value 'on'.
@ -725,6 +729,9 @@ sub HMCCUDEV_SetError ($$)
<li>get &lt;name&gt; configdesc [&lt;channel-number&gt;] [&lt;rpcport&gt;]<br/>
Get description of configuration parameters for CCU device.
</li><br/>
<li>get &lt;name&gt; defaults<br/>
Display default attributes for CCU device type.
</li><br/>
<li>get &lt;name&gt; update [{'State'|'Value'}]<br/>
Update datapoints / readings of device.
</li><br/>
@ -753,8 +760,10 @@ sub HMCCUDEV_SetError ($$)
<li>ccureadingformat &lt;address | name&gt; <br/>
Set format of readings. Default is 'name'.
</li><br/>
<li>ccuverify &lt;0 | 1&gt;<br/>
If set to 1 a datapoint is read for verification after set operation.
<li>ccuverify &lt;0 | 1 | 2&gt;<br/>
If set to 1 a datapoint is read for verification after set operation. If set to 2 the
corresponding reading will be set to the new value directly after setting a datapoint
in CCU.
</li><br/>
<li>controldatapoint &lt;channel-number.datapoint&gt;<br/>
Set datapoint for device control. Can be use to realize user defined control elements for

View File

@ -0,0 +1,122 @@
#########################################################################
#
# HMCCUConf.pm
#
# $Id:$
#
# Version 3.2
#
# Configuration parameters for Homematic devices.
#
# (c) 2016 zap (zap01 <at> t-online <dot> de)
#
#########################################################################
package HMCCUConf;
use strict;
use warnings;
use vars qw(%HMCCU_DEV_DEFAULTS);
# Default attributes for Homematic devices of type HMCCUDEV
%HMCCU_DEV_DEFAULTS = (
"HM-Sec-SCo" => { # Tuer/Fensterkontakt optisch
ccureadingfilter => "(ERROR|UNREACH|LOWBAT|STATE)",
statechannel => 1,
substitute => "STATE!(0|false):closed,(1|true):open;LOWBAT!(0|false):no,(1|true):yes"
},
"HM-Sec-SC" => { # Tuer/Fensterkontakt magnetisch
ccureadingfilter => "(ERROR|UNREACH|LOWBAT|STATE)",
statechannel => 1,
substitute => "STATE!(0|false):closed,(1|true):open;LOWBAT!(0|false):no,(1|true):yes"
},
"HM-LC-Sw1-Pl-2" => { # Steckdose
ccureadingfilter => "(STATE|UNREACH)",
controldatapoint => "1.STATE",
statechannel => 1,
statevals => "on:true,off:false",
substitute => "STATE!(1|true):on,(0|false):off",
webCmd => "control",
widgetOverride => "control:uzsuToggle,off,on"
},
"HMIP-PS" => { # Steckdose (IP)
ccureadingfilter => "(STATE|UNREACH)",
statechannel => 3,
statevals => "on:1,off:0",
substitute => "STATE!(1|true):on,(0|false):off"
},
"HM-ES-PMSw1-Pl" => { # Steckdose mit Energiemessung
ccureadingfilter => "(STATE|UNREACH|CURRENT|ENERGY_COUNTER|POWER)",
statechannel => 1,
statevals => "on:1,off:0",
stripnumber => 1,
substitute => "STATE!(1|true):on,(0|false):off"
},
"HMIP-PSM" => { # Steckdose mit Energiemessung (IP)
ccureadingfilter => "(STATE|UNREACH|CURRENT|ENERGY_COUNTER|POWER)",
statechannel => 3,
statevals => "on:true,off:false",
stripnumber => 1,
substitute => "STATE!(1|true):on,(0|false):off"
},
"HM-LC-Bl1PBU-FM" => { # Rolladenaktor
cmdIcon => "up:fts_shutter_up stop:fts_shutter_manual down:fts_shutter_down",
controldatapoint => "1.LEVEL",
eventMap => "/datapoint 1.STOP 1:stop/datapoint 1.LEVEL 1:down/datapoint 1.LEVEL 0:up/",
statechannel => 1,
statevals => "up:0.0,down:1.0",
stripnumber => 1,
webCmd => "control:up:stop:down",
widgetOverride => "control:slider,0,0.05,1,1"
},
"HM-TC-IT-WM-W-EU" => { # Wandthermostat
ccureadingfilter => "(UNREACH|^HUMIDITY|^TEMPERATURE|^SET_TEMPERATURE|^LOWBAT$|^WINDOW_OPEN)",
cmdIcon => "Auto:sani_heating_automatic Manu:sani_heating_manual Boost:sani_heating_boost on:general_an off:general_aus",
controldatapoint => "2.SET_TEMPERATURE",
eventMap => "/datapoint 2.MANU_MODE 20.0:Manu/datapoint 2.AUTO_MODE 1:Auto/datapoint 2.BOOST_MODE 1:Boost/datapoint 2.MANU_MODE 4.5:off/datapoint 2.MANU_MODE 30.5:on/",
statechannel => 2,
statedatapoint => "SET_TEMPERATURE",
stripnumber => 1,
substitute => "LOWBAT!(0|false):no,(1|true):yes;CONTROL_MODE!0:AUTO,1:MANU,2:PARTY,3:BOOST;WINDOW_OPEN_REPORTING!(true|1):open,(false|0):closed",
webCmd => "control:Auto:Manu:Boost:on:off",
widgetOverride => "control:slider,10,1,25"
},
"HM-CC-RT-DN" => { # Heizkörperthermostat
ccureadingfilter => "(UNREACH|LOWBAT|TEMPERATURE|VALVE_STATE|CONTROL)",
cmdIcon => "Auto:sani_heating_automatic Manu:sani_heating_manual Boost:sani_heating_boost on:general_an off:general_aus",
controldatapoint => "4.SET_TEMPERATURE",
eventMap => "/datapoint 4.MANU_MODE 20.0:Manu/datapoint 4.AUTO_MODE 1:Auto/datapoint 4.BOOST_MODE 1:Boost/datapoint 4.MANU_MODE 4.5:off/datapoint 4.MANU_MODE 30.5:on/",
statechannel => 4,
statedatapoint => "SET_TEMPERATURE",
stripnumber => 1,
substitute => "LOWBAT!(0|false):no,(1|true):yes;CONTROL_MODE!0:AUTO,1:MANU,2:PARTY,3:BOOST",
webCmd => "control:Auto:Manu:Boost:on:off",
widgetOverride => "control:slider,10,1,25"
},
"HM-WDS40-TH-I" => { # Temperatur/Luftfeuchte Sensor
ccureadingfilter => "(UNREACH|^HUMIDITY|^TEMPERATURE|^LOWBAT$)",
statechannel => 1,
statedatapoint => "TEMPERATURE",
stripnumber => 1,
substitute => "LOWBAT!(0|false):no,(1|true):yes"
},
"HM-ES-TX-WM" => { # Stromzähler Sensor
ccureadingfilter => "(UNREACH|LOWBAT|^ENERGY_COUNTER|^POWER)",
substitute => "LOWBAT!(true|1):yes,(false|0):no"
},
"HM-CC-VG-1" => { # Heizungsgruppe
ccureadingfilter => "(^SET_TEMPERATURE|^TEMPERATURE|^HUMIDITY|LOWBAT$|^VALVE|^CONTROL|^WINDOW_OPEN)",
cmdIcon => "Auto:sani_heating_automatic Manu:sani_heating_manual Boost:sani_heating_boost on:general_an off:general_aus",
controldatapoint => "1.SET_TEMPERATURE",
eventMap => "/datapoint 1.MANU_MODE 20.0:Manu/datapoint 1.AUTO_MODE 1:Auto/datapoint 1.BOOST_MODE 1:Boost/datapoint 1.MANU_MODE 4.5:off/datapoint 1.MANU_MODE 30.5:on/",
statechannel => 1,
statedatapoint => "SET_TEMPERATURE",
stripnumber => 1,
substitute => "LOWBAT!(0|false):no,(1|true):yes;CONTROL_MODE!0:AUTO,1:MANU,2:PARTY,3:BOOST;WINDOW_OPEN_REPORTING!(true|1):open,(false|0):closed",
webCmd => "control:Auto:Manu:Boost:on:off",
widgetOverride => "control:slider,10,1,25"
}
);
1;

View File

@ -1,6 +1,5 @@
package RPCQueue;
use strict;
use IO::File;
use Fcntl 'SEEK_END', 'SEEK_SET', 'O_CREAT', 'O_RDWR';

View File

@ -50,7 +50,7 @@ my $shutdown = 0;
my $eventcount = 0;
my $totalcount = 0;
my $loglevel = 0;
my %ev = ('total', 0, 'EV', 0, 'ND', 0, 'DD', 0, 'UD', 0, 'RD', 0, 'RA', 0, 'IN', 0, 'EX', 0);
my %ev = ('total', 0, 'EV', 0, 'ND', 0, 'DD', 0, 'UD', 0, 'RD', 0, 'RA', 0, 'SL', 0, 'IN', 0, 'EX', 0);
# Functions
sub CheckProcess ($$);
@ -244,11 +244,11 @@ sub CCURPC_NewDevicesCB ($$$)
{
my ($server, $cb, $a) = @_;
$ev{total}++;
$ev{ND}++;
Log "NewDevice: received ".scalar(@$a)." device specifications";
for my $dev (@$a) {
$ev{total}++;
$ev{ND}++;
WriteQueue ("ND|".$dev->{ADDRESS}."|".$dev->{TYPE});
}
@ -264,11 +264,11 @@ sub CCURPC_DeleteDevicesCB ($$$)
{
my ($server, $cb, $a) = @_;
$ev{total}++;
$ev{DD}++;
Log "DeleteDevice: received ".scalar(@$a)." device addresses";
for my $dev (@$a) {
$ev{total}++;
$ev{DD}++;
WriteQueue ("DD|".$dev);
}
@ -313,11 +313,11 @@ sub CCURPC_ReaddDevicesCB ($$$)
{
my ($server, $cb, $a) = @_;
$ev{total}++;
$ev{RA}++;
Log "ReaddDevice: received ".scalar(@$a)." device addresses";
for my $dev (@$a) {
$ev{total}++;
$ev{RA}++;
WriteQueue ("RA|".$dev);
}
@ -339,6 +339,12 @@ sub CCURPC_EventCB ($$$$$)
$eventcount++;
if (($eventcount % 500) == 0 && $loglevel == 2) {
Log "Received $eventcount events from CCU since last check";
my @stkeys = ('total', 'EV', 'ND', 'DD', 'RD', 'RA', 'UD', 'IN', 'SL', 'EX');
my $msg = "ST";
foreach my $stkey (@stkeys) {
$msg .= "|".$ev{$stkey};
}
WriteQueue ($msg);
}
# Never remove this statement!
@ -434,3 +440,4 @@ if ($loglevel == 2) {
Log "Events $cnt = ".$ev{$cnt};
}
}