diff --git a/fhem/contrib/HMCCU/88_HMCCUDEV.pm b/fhem/contrib/HMCCU/88_HMCCUDEV.pm deleted file mode 100644 index 760be8cbc..000000000 --- a/fhem/contrib/HMCCU/88_HMCCUDEV.pm +++ /dev/null @@ -1,595 +0,0 @@ -################################################################ -# -# 88_HMCCUDEV.pm -# -# $Id:$ -# -# Version 2.6 -# -# (c) 2016 zap (zap01 t-online de) -# -################################################################ -# -# define HMCCUDEV [readonly] -# -# set control -# set datapoint . -# set devstate -# set -# set config [] = [...] -# -# get devstate -# get datapoint . -# get channel [.] -# get config [] -# get configdesc [] -# get update -# -# attr ccureadings { 0 | 1 } -# attr ccureadingformat { address | name } -# attr ccureadingfilter -# attr controldatapoint . -# attr statechannel -# attr statedatapoint -# attr statevals :[,...] -# attr substitute :[,...] -# -################################################################ -# Requires module 88_HMCCU -################################################################ - -package main; - -use strict; -use warnings; -use SetExtensions; -# use Data::Dumper; - -use Time::HiRes qw( gettimeofday usleep ); - -sub HMCCUDEV_Define ($@); -sub HMCCUDEV_Set ($@); -sub HMCCUDEV_Get ($@); -sub HMCCUDEV_Attr ($@); -sub HMCCUDEV_SetError ($$); - -##################################### -# Initialize module -##################################### - -sub HMCCUDEV_Initialize ($) -{ - my ($hash) = @_; - - $hash->{DefFn} = "HMCCUDEV_Define"; - $hash->{SetFn} = "HMCCUDEV_Set"; - $hash->{GetFn} = "HMCCUDEV_Get"; - $hash->{AttrFn} = "HMCCUDEV_Attr"; - - $hash->{AttrList} = "IODev ccureadingfilter ccureadingformat:name,address ccureadings:0,1 ccustate ccuget:State,Value statevals substitute statechannel statedatapoint controldatapoint stripnumber:0,1,2 loglevel:0,1,2,3,4,5,6 ". $readingFnAttributes; -} - -##################################### -# Define device -##################################### - -sub HMCCUDEV_Define ($@) -{ - my ($hash, $def) = @_; - my $name = $hash->{NAME}; - my @a = split("[ \t][ \t]*", $def); - - my $usage = "Usage: define HMCCUDEV {|} [] [readonly]"; - return $usage if (@a < 3); - - my $devname = shift @a; - my $devtype = shift @a; - my $devspec = shift @a; - - return "Invalid or unknown CCU device name or address" if (! HMCCU_IsValidDevice ($devspec)); - - if ($devspec =~ /^(.+)\.([A-Z]{3,3}[0-9]{7,7})$/) { - # CCU Device address with interface - $hash->{ccuif} = $1; - $hash->{ccuaddr} = $2; - $hash->{ccuname} = HMCCU_GetDeviceName ($hash->{ccuaddr}, ''); - } - elsif ($devspec =~ /^[A-Z]{3,3}[0-9]{7,7}$/) { - # CCU Device address without interface - $hash->{ccuaddr} = $devspec; - $hash->{ccuname} = HMCCU_GetDeviceName ($devspec, ''); - $hash->{ccuif} = HMCCU_GetDeviceInterface ($hash->{ccuaddr}, 'BidCos-RF'); - } - else { - # CCU Device name - $hash->{ccuname} = $devspec; - my ($add, $chn) = HMCCU_GetAddress ($devspec, '', ''); - return "Name is a channel name" if ($chn ne ''); - $hash->{ccuaddr} = $add; - $hash->{ccuif} = HMCCU_GetDeviceInterface ($hash->{ccuaddr}, 'BidCos-RF'); - } - - return "CCU device address not found for $devspec" if ($hash->{ccuaddr} eq ''); - return "CCU device name not found for $devspec" if ($hash->{ccuname} eq ''); - - $hash->{ccutype} = HMCCU_GetDeviceType ($hash->{ccuaddr}, ''); - $hash->{channels} = HMCCU_GetDeviceChannels ($hash->{ccuaddr}); - $hash->{statevals} = 'devstate'; - - my $n = 0; - my $arg = shift @a; - while (defined ($arg)) { - return $usage if ($n == 2); - if ($arg eq 'readonly') { - $hash->{statevals} = $arg; - $n++; - } - elsif ($arg =~ /^[0-9]+$/) { - $attr{$name}{statechannel} = $arg; - $n++; - } - else { - return $usage; - } - $arg = shift @a; - } - - # Inform HMCCU device about client device - AssignIoPort ($hash); - - readingsSingleUpdate ($hash, "state", "Initialized", 1); - $hash->{ccudevstate} = 'Active'; - - return undef; -} - -##################################### -# Set attribute -##################################### - -sub HMCCUDEV_Attr ($@) -{ - my ($cmd, $name, $attrname, $attrval) = @_; - my $hash = $defs{$name}; - - if ($cmd eq "set") { - return "Missing attribute value" if (!defined ($attrval)); - if ($attrname eq 'IODev') { - $hash->{IODev} = $defs{$attrval}; - } - elsif ($attrname eq "statevals") { - return "Device is read only" if ($hash->{statevals} eq 'readonly'); - $hash->{statevals} = 'devstate'; - my @states = split /,/,$attrval; - foreach my $st (@states) { - my @statesubs = split /:/,$st; - return "value := text:substext[,...]" if (@statesubs != 2); - $hash->{statevals} .= '|'.$statesubs[0]; - } - } - } - elsif ($cmd eq "del") { - if ($attrname eq "statevals") { - $hash->{statevals} = "devstate"; - } - } - - return undef; -} - -##################################### -# Set commands -##################################### - -sub HMCCUDEV_Set ($@) -{ - my ($hash, @a) = @_; - my $name = shift @a; - my $opt = shift @a; - - if (!exists ($hash->{IODev})) { - return HMCCUDEV_SetError ($hash, "No IO device defined"); - } - if ($hash->{statevals} eq 'readonly') { - return undef; - } - - my $statechannel = AttrVal ($name, "statechannel", ''); - my $statedatapoint = AttrVal ($name, "statedatapoint", 'STATE'); - my $statevals = AttrVal ($name, "statevals", ''); - my $controldatapoint = AttrVal ($name, "controldatapoint", ''); - - my $hmccu_hash = $hash->{IODev}; - my $hmccu_name = $hash->{IODev}->{NAME}; - - my $result = ''; - my $rc; - - if ($opt eq 'datapoint') { - my $objname = shift @a; - my $objvalue = join ('%20', @a); - - if (!defined ($objname) || $objname !~ /^[0-9]+\..+$/ || !defined ($objvalue)) { - return HMCCUDEV_SetError ($hash, "Usage: set datapoint . [...]"); - } - $objvalue = HMCCU_Substitute ($objvalue, $statevals, 1, ''); - - # Build datapoint address - $objname = $hash->{ccuif}.'.'.$hash->{ccuaddr}.':'.$objname; - - $rc = HMCCU_SetDatapoint ($hash, $objname, $objvalue); - return HMCCUDEV_SetError ($hash, $rc) if ($rc < 0); - - usleep (100000); - ($rc, $result) = HMCCU_GetDatapoint ($hash, $objname); - return HMCCUDEV_SetError ($hash, $rc) if ($rc < 0); - - HMCCU_SetState ($hash, "OK"); - return undef; - } - elsif ($opt eq 'control') { - return HMCCUDEV_SetError ($hash, "Attribute control datapoint not set") if ($controldatapoint eq ''); - my $objvalue = shift @a; - my $objname = $hash->{ccuif}.'.'.$hash->{ccuaddr}.':'.$controldatapoint; - $rc = HMCCU_SetDatapoint ($hash, $objname, $objvalue); - return HMCCUDEV_SetError ($hash, $rc) if ($rc < 0); - - HMCCU_SetState ($hash, "OK"); - return undef; - } - elsif ($opt =~ /^($hash->{statevals})$/) { - my $cmd = $1; - my $objvalue = ($cmd ne 'devstate') ? $cmd : join ('%20', @a); - - return HMCCUDEV_SetError ($hash, "No state channel specified") if ($statechannel eq ''); - return HMCCUDEV_SetError ($hash, "Usage: set devstate [...]") if (!defined ($objvalue)); - - $objvalue = HMCCU_Substitute ($objvalue, $statevals, 1, ''); - - # Build datapoint address - my $objname = $hash->{ccuif}.'.'.$hash->{ccuaddr}.':'.$statechannel.'.'.$statedatapoint; - - $rc = HMCCU_SetDatapoint ($hash, $objname, $objvalue); - return HMCCUDEV_SetError ($hash, $rc) if ($rc < 0); - - usleep (100000); - ($rc, $result) = HMCCU_GetDatapoint ($hash, $objname); - return HMCCUDEV_SetError ($hash, $rc) if ($rc < 0); - - HMCCU_SetState ($hash, "OK"); - return undef; - } - elsif ($opt eq 'config') { - return HMCCUDEV_SetError ($hash, "Usage: set $name config [{channel-number}] {parameter}={value} [...]") if (@a < 1);; - my $objname = $hash->{ccuaddr}; - $objname .= ':'.shift @a if ($a[0] =~ /^[0-9]+$/); - - my $rc = HMCCU_RPCSetConfig ($hash, $objname, \@a); - return HMCCUDEV_SetError ($hash, $rc) if ($rc < 0); - - HMCCU_SetState ($hash, "OK"); - return undef; - } - else { - my $retmsg = "HMCCUDEV: Unknown argument $opt, choose one of config control datapoint"; - return undef if ($hash->{statevals} eq 'readonly'); - - if ($statechannel ne '') { - $retmsg .= " devstate"; - if ($hash->{statevals} ne '') { - my @cmdlist = split /\|/,$hash->{statevals}; - shift @cmdlist; - $retmsg .= ':'.join(',',@cmdlist); - foreach my $sv (@cmdlist) { - $retmsg .= ' '.$sv.':noArg'; - } - } - } - - return $retmsg; - } -} - -##################################### -# Get commands -##################################### - -sub HMCCUDEV_Get ($@) -{ - my ($hash, @a) = @_; - my $name = shift @a; - my $opt = shift @a; - - if (!defined ($hash->{IODev})) { - return HMCCUDEV_SetError ($hash, "No IO device defined"); - } - - my $statechannel = AttrVal ($name, 'statechannel', ''); - my $statedatapoint = AttrVal ($name, 'statedatapoint', 'STATE'); - my $ccureadings = AttrVal ($name, 'ccureadings', 1); - - my $result = ''; - my $rc; - - if ($opt eq 'devstate') { - if ($statechannel eq '') { - return HMCCUDEV_SetError ($hash, "No state channel specified"); - } - - my $objname = $hash->{ccuif}.'.'.$hash->{ccuaddr}.':'.$statechannel.'.'.$statedatapoint; - ($rc, $result) = HMCCU_GetDatapoint ($hash, $objname); - - return HMCCUDEV_SetError ($hash, $rc) if ($rc < 0); - return $ccureadings ? undef : $result; - } - elsif ($opt eq 'datapoint') { - my $objname = shift @a; - if (!defined ($objname) || $objname !~ /^[0-9]+\..*$/) { - return HMCCUDEV_SetError ($hash, "Usage: get datapoint ."); - } - - $objname = $hash->{ccuif}.'.'.$hash->{ccuaddr}.':'.$objname; - ($rc, $result) = HMCCU_GetDatapoint ($hash, $objname); - - return HMCCUDEV_SetError ($hash, $rc) if ($rc < 0); - - HMCCU_SetState ($hash, "OK") if (exists ($hash->{STATE}) && $hash->{STATE} eq "Error"); - return $ccureadings ? undef : $result; - } - elsif ($opt eq 'channel') { - my @chnlist; - foreach my $objname (@a) { - last if (!defined ($objname)); - if ($objname =~ /^([0-9]+)/ && exists ($hash->{channels})) { - return HMCCUDEV_SetError ($hash, "Invalid channel number: $objname") if ($1 >= $hash->{channels}); - } - else { - return HMCCUDEV_SetError ($hash, "Invalid channel number: $objname"); - } - if ($objname =~ /^[0-9]{1,2}.*=/) { - $objname =~ s/=/ /; - } - push (@chnlist, $hash->{ccuif}.'.'.$hash->{ccuaddr}.':'.$objname); - } - if (@chnlist == 0) { - return HMCCUDEV_SetError ($hash, "Usage: get $name channel {channel-number}[.{datapoint-expr}] [...]"); - } - - ($rc, $result) = HMCCU_GetChannel ($hash, \@chnlist); - return HMCCUDEV_SetError ($hash, $rc) if ($rc < 0); - - HMCCU_SetState ($hash, "OK") if (exists ($hash->{STATE}) && $hash->{STATE} eq "Error"); - return $ccureadings ? undef : $result; - } - elsif ($opt eq 'update') { - my $ccuget = shift @a; - $ccuget = 'Attr' if (!defined ($ccuget)); - if ($ccuget !~ /^(Attr|State|Value)$/) { - return HMCCUDEV_SetError ($hash, "Usage: get $name update [{'State'|'Value'}]"); - } - $rc = HMCCU_GetUpdate ($hash, $hash->{ccuaddr}, $ccuget); - return HMCCUDEV_SetError ($hash, $rc) if ($rc < 0); - - return undef; - } - elsif ($opt eq 'deviceinfo') { - my $ccuget = shift @a; - $ccuget = 'Attr' if (!defined ($ccuget)); - if ($ccuget !~ /^(Attr|State|Value)$/) { - return HMCCUDEV_SetError ($hash, "Usage: get $name deviceinfo [{'State'|'Value'}]"); - } - $result = HMCCU_GetDeviceInfo ($hash, $hash->{ccuaddr}, $ccuget); - return HMCCUDEV_SetError ($hash, -2) if ($result eq ''); - return $result; - } - elsif ($opt eq 'config') { - my $channel = shift @a; - my $ccuobj = $hash->{ccuaddr}; - $ccuobj .= ':'.$channel if (defined ($channel)); - - my ($rc, $res) = HMCCU_RPCGetConfig ($hash, $ccuobj, "getParamset"); - return HMCCUDEV_SetError ($hash, $rc) if ($rc < 0); - HMCCU_SetState ($hash, "OK") if (exists ($hash->{STATE}) && $hash->{STATE} eq "Error"); - return $ccureadings ? undef : $result; - } - elsif ($opt eq 'configdesc') { - my $channel = shift @a; - my $ccuobj = $hash->{ccuaddr}; - $ccuobj .= ':'.$channel if (defined ($channel)); - - my ($rc, $res) = HMCCU_RPCGetConfig ($hash, $ccuobj, "getParamsetDescription"); - return HMCCUDEV_SetError ($hash, $rc) if ($rc < 0); - HMCCU_SetState ($hash, "OK") if (exists ($hash->{STATE}) && $hash->{STATE} eq "Error"); - return $res; - } - else { - my $retmsg = "HMCCUDEV: Unknown argument $opt, choose one of datapoint channel update:noArg config configdesc deviceinfo:noArg"; - if ($statechannel ne '') { - $retmsg .= ' devstate:noArg'; - } - return $retmsg; - } -} - -##################################### -# Set error status -##################################### - -sub HMCCUDEV_SetError ($$) -{ - my ($hash, $text) = @_; - my $name = $hash->{NAME}; - my $msg; - my %errlist = ( - -1 => 'Channel name or address invalid', - -2 => 'Execution of CCU script failed', - -3 => 'Cannot detect IO device', - -4 => 'Device deleted in CCU' - ); - - if (exists ($errlist{$text})) { - $msg = $errlist{$text}; - } - else { - $msg = $text; - } - - $msg = "HMCCUDEV: ".$name." ". $msg; - readingsSingleUpdate ($hash, "state", "Error", 1); - Log 1, $msg; - return $msg; -} - -1; - -=pod -=begin html - - -

HMCCUDEV

-
-
    - The module implements client devices for HMCCU. A HMCCU device must exist - before a client device can be defined. -

    - - Define -
      -
      - define <name> HMCCUDEV {<device-name>|<device-address>} [<statechannel>] [readonly] -

      - If readonly parameter is specified no set command will be available. -

      - Examples:
      - define window_living HMCCUDEV WIN-LIV-1 readonly
      - define temp_control HMCCUDEV BidCos-RF.LEQ1234567 1 -
      -
    -
    - - - Set
    -
      -
      -
    • set <name> devstate <value> [...] -
      - Set state of a CCU device channel. Channel must be defined as attribute - 'statechannel'. Default datapoint can be modfied by setting attribute - 'statedatapoint'. -

      - Example:
      - set light_entrance devstate on -

    • -
    • set <name> <statevalue> -
      - State of a CCU device channel is set to statevalue. Channel must - be defined as attribute 'statechannel'. Default datapoint STATE can be - modified by setting attribute 'statedatapoint'. Values for statevalue - are defined by setting attribute 'statevals'. -

      - Example:
      - - attr myswitch statechannel 1
      - attr myswitch statevals on:true,off:false
      - set myswitch on -
      -

    • -
    • set <name> datapoint <channel-number>.<datapoint> <value> [...] -
      - Set value of a datapoint of a CCU device channel. -

      - Example:
      - set temp_control datapoint 1.SET_TEMPERATURE 21 -

    • -
    • set <name> config [<channel-number>] <parameter>=<value> [...] -
      - Set configuration parameter of CCU device or channel. -
    • -
    -
    - - - Get
    -
      -
      -
    • get <name> devstate -
      - Get state of CCU device. Attribute 'statechannel' must be set. -

    • -
    • get <name> datapoint <channel-number>.<datapoint> -
      - Get value of a CCU device datapoint. -

    • -
    • get <name> config -
      - Get configuration parameters of CCU device. -

    • -
    • get <name> configdesc -
      - Get description of configuration parameters for CCU device. -

    • -
    • get <name> update [{'State'|'Value'}]
      - Update datapoints / readings of device. -

    • -
    • get <name> deviceinfo [{'State'|'Value'}]
      - Display all channels and datapoints of device. -
    • -
    -
    - - - Attributes
    -
    -
      -
    • ccuget <State | Value>
      - Set read access method for CCU channel datapoints. Method 'State' is slower than 'Value' because - each request is sent to the device. With method 'Value' only CCU is queried. Default is 'Value'. -

    • -
    • ccureadings <0 | 1>
      - If set to 1 values read from CCU will be stored as readings. Default is 1. -

    • -
    • ccureadingfilter <datapoint-expr> -
      - Only datapoints matching specified expression are stored as - readings. -

    • -
    • ccureadingformat <address | name>
      - Set format of readings. Default is 'name'. -

    • -
    • controldatapoint <channel-number.datapoint>
      - Set datapoint for device control. Can be use to realize user defined control elements for - setting control datapoint. For example if datapoint of thermostat control is - 2.SET_TEMPERATURE one can define a slider for setting the destination temperature with - following attributes:

      - attr mydev controldatapoint 2.SET_TEMPERATURE - attr mydev webCmd control - attr mydev widgetOverride control:slider,10,1,25 -

    • -
    • statechannel <channel-number> -
      - Channel for setting device state by devstate command. -

    • -
    • statedatapoint <datapoint> -
      - Datapoint for setting device state by devstate command. -

    • -
    • statevals <text>:<text>[,...] -
      - Define substitution for set commands values. The parameters <text> - are available as set commands. Example:
      - attr my_switch statevals on:true,off:false
      - set my_switch on -

    • -
    • substitude <subst-rule>[;...] -
      - Define substitions for reading values. Substitutions for parfile values must - be specified in parfiles. Syntax of subst-rule is

      - [datapoint!]<regexp1>:<text1>[,...] -

    • -
    -
-
- -=end html -=cut -