diff --git a/fhem/CHANGED b/fhem/CHANGED index fbd7f98be..b2f9e024d 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,6 @@ # 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. + - bugfix: 88_HMCCU: fixed CUxD bug and minor bugs - feature: 93_DbRep: V7.10.0, new "changeValue" command, minor fixes - bugfix: 88_xs1Bridge: fix Filelog check - new: 39_Talk2Fhem: new module for language control diff --git a/fhem/FHEM/88_HMCCU.pm b/fhem/FHEM/88_HMCCU.pm index 3c67b3f5d..5172372aa 100755 --- a/fhem/FHEM/88_HMCCU.pm +++ b/fhem/FHEM/88_HMCCU.pm @@ -4,7 +4,7 @@ # # $Id$ # -# Version 4.2.001 +# Version 4.2.002 # # Module for communication between FHEM and Homematic CCU2. # @@ -104,7 +104,7 @@ my %HMCCU_CUST_CHN_DEFAULTS; my %HMCCU_CUST_DEV_DEFAULTS; # HMCCU version -my $HMCCU_VERSION = '4.2.001'; +my $HMCCU_VERSION = '4.2.002'; # Default RPC port (BidCos-RF) my $HMCCU_RPC_PORT_DEFAULT = 2001; @@ -1271,6 +1271,7 @@ sub HMCCU_Set ($@) } elsif ($opt eq 'rpcserver') { my $action = shift @$a; + $action = shift @$a if ($action eq $opt); $usage = "Usage: set $name $opt {'on'|'off'|'restart'}"; return HMCCU_SetError ($hash, $usage) @@ -2201,8 +2202,10 @@ sub HMCCU_SetState ($@) } ###################################################################### -# Set state of RPC server. -# Parameters iface and msg are optional. +# Set state of RPC server. Update all client devices if overall state +# is 'running'. +# Parameters iface and msg are optional. If iface is set function +# was called by HMCCURPCPROC device. ###################################################################### sub HMCCU_SetRPCState ($@) @@ -2212,11 +2215,21 @@ sub HMCCU_SetRPCState ($@) my $ccuflags = AttrVal ($name, 'ccuflags', 'null'); my $filter; - my $f = 0; # Overall process states: 0=starting/stopping, 1=running/error, 2=stopped/error + my $rpcstate = $state; - if ($ccuflags =~ /(intrpc|extrpc)/) { - $f = 1 if ($state eq 'running'); - $f = 2 if ($state eq 'inactive'); + if ($ccuflags =~ /(intrpc|extrpc)/ || $ccuflags !~ /(intrpc|extrpc|procrpc)/) { + if ($state ne $hash->{RPCState}) { + $hash->{RPCState} = $state; + readingsSingleUpdate ($hash, "rpcstate", $state, 1); + HMCCU_Log ($hash, 4, "Set rpcstate to $state", undef); + HMCCU_Log ($hash, 1, $msg, undef) if (defined ($msg)); + HMCCU_Log ($hash, 1, "All RPC servers $state", undef); + DoTrigger ($name, "RPC server $state"); + if ($state eq 'running') { + my ($c_ok, $c_err) = HMCCU_UpdateClients ($hash, '.*', 'Attr', 0, $filter); + HMCCU_Log ($hash, 2, "Updated devices. Success=$c_ok Failed=$c_err", undef); + } + } } elsif (defined ($iface) && $ccuflags =~ /procrpc/) { # Set interface state @@ -2224,47 +2237,50 @@ sub HMCCU_SetRPCState ($@) $hash->{hmccu}{interfaces}{$ifname}{state} = $state if (defined ($ifname)); # Count number of processes in state running, error or inactive - my %statecount = ("running" => 0, "error" => 0, "inactive" => 0); + # Prepare filter for updating client devices + my %stc = ("running" => 0, "error" => 0, "inactive" => 0); my @iflist = HMCCU_GetRPCInterfaceList ($hash); foreach my $i (@iflist) { my $st = $hash->{hmccu}{interfaces}{$i}{state}; - $statecount{$st}++ if (exists ($statecount{$st})); + $stc{$st}++ if (exists ($stc{$st})); if ($hash->{hmccu}{interfaces}{$i}{manager} eq 'HMCCU') { $filter = defined ($filter) ? "$filter|$i" : $i; } } # Determine overall process state - $f = 1 if ($statecount{"running"}+$statecount{"error"} == scalar (@iflist)); - $f = 2 if ($statecount{"inactive"}+$statecount{"error"} == scalar (@iflist)); - } + my $rpcstate = 'null'; + $rpcstate = "running" if ($stc{"running"} == scalar (@iflist)); + $rpcstate = "inactive" if ($stc{"inactive"} == scalar (@iflist)); + $rpcstate = "error" if ($stc{"error"} == scalar (@iflist)); - if ($state ne $hash->{RPCState}) { - # Update RPC state - $hash->{RPCState} = $state; - readingsSingleUpdate ($hash, "rpcstate", $state, 1); - - if ($f > 0) { - # Running or inactive - HMCCU_SetState ($hash, 'OK'); - HMCCU_Log ($hash, 1, "All RPC servers $state", undef); - DoTrigger ($name, "RPC server $state"); - - if ($f == 1) { - # If RPC process(es) running update all devices where interface is managed by HMCCU - my ($c_ok, $c_err) = HMCCU_UpdateClients ($hash, '.*', 'Attr', 0, $filter); - Log3 $name, 2, "HMCCU: Updated devices. Success=$c_ok Failed=$c_err"; + if ($rpcstate =~ /^(running|inactive|error)$/) { + if ($rpcstate ne $hash->{RPCState}) { + $hash->{RPCState} = $rpcstate; + readingsSingleUpdate ($hash, "rpcstate", $rpcstate, 1); + HMCCU_Log ($hash, 4, "Set rpcstate to $rpcstate", undef); + HMCCU_Log ($hash, 1, $msg, undef) if (defined ($msg)); + HMCCU_Log ($hash, 1, "All RPC servers $rpcstate", undef); + DoTrigger ($name, "RPC server $rpcstate"); + if ($rpcstate eq 'running') { + my ($c_ok, $c_err) = HMCCU_UpdateClients ($hash, '.*', 'Attr', 0, $filter); + HMCCU_Log ($hash, 2, "Updated devices. Success=$c_ok Failed=$c_err", undef); + } } } - else { - # Starting or stopping - HMCCU_SetState ($hash, 'busy'); - } - - HMCCU_Log ($hash, 4, "Set rpcstate to $state", undef); - HMCCU_Log ($hash, 1, $msg, undef) if (defined ($msg)); } - + + # Set I/O device state + if ($rpcstate eq 'running' || $rpcstate eq 'inactive') { + HMCCU_SetState ($hash, "OK"); + } + elsif ($rpcstate eq 'error') { + HMCCU_SetState ($hash, "error"); + } + else { + HMCCU_SetState ($hash, "busy"); + } + return undef; } @@ -3422,13 +3438,13 @@ sub HMCCU_IsRPCServerRunning ($$$) $c = $r; } } - elsif ($ccuflags =~ /procprc/) { + elsif ($ccuflags =~ /procrpc/) { @$pids = () if (defined ($pids)); my @iflist = HMCCU_GetRPCInterfaceList ($hash); foreach my $ifname (@iflist) { my ($rpcdev, $save) = HMCCU_GetRPCDevice ($hash, 0, $ifname); next if ($rpcdev eq ''); - my ($rc, $msg) = HMCCURPCPROC_CheckProcessState ($defs{$rpcdev}, 'running'); + my $rc = HMCCURPCPROC_CheckProcessState ($defs{$rpcdev}, 'running'); if ($rc < 0 || $rc > 1) { push (@$pids, $rc); $c++; @@ -5038,7 +5054,7 @@ sub HMCCU_ReadRPCQueue ($) # Output statistic counters foreach my $cnt (sort keys %{$hash->{hmccu}{ev}}) { - Log3 $name, 2, "HMCCU: Eventcount $cnt = ".$hash->{hmccu}{ev}{$cnt}; + Log3 $name, 3, "HMCCU: Eventcount $cnt = ".$hash->{hmccu}{ev}{$cnt}; } } @@ -6988,7 +7004,7 @@ sub HMCCU_CCURPC_ListDevicesCB ($$) practice for creating a custom default attribute file is by exporting predefined default attributes from HMCCU with command 'get exportdefaults'.
-
  • ccuflags {extrpc, procprc, intrpc}
    +
  • ccuflags {extrpc, procrpc, intrpc}
    Control behaviour of several HMCCU functions:
    ackState - Acknowledge command execution by setting STATE to error or success.
    dptnocheck - Do not check within set or get commands if datapoint is valid
    diff --git a/fhem/FHEM/88_HMCCUCHN.pm b/fhem/FHEM/88_HMCCUCHN.pm index 375f3e335..73318027e 100644 --- a/fhem/FHEM/88_HMCCUCHN.pm +++ b/fhem/FHEM/88_HMCCUCHN.pm @@ -4,7 +4,7 @@ # # $Id$ # -# Version 4.2 +# Version 4.2.001 # # (c) 2018 zap (zap01 t-online de) # @@ -760,11 +760,10 @@ sub HMCCUCHN_Get ($@) dewpoint = calculate dewpoint, dp-list = <temperature>,<humidity>
    abshumidity = calculate absolute humidity, dp-list = <temperature>,<humidity>
    inc = increment datapoint value considering reset of datapoint, dp-list = <counter-datapoint>
    - inc = increment datapoint value considering reset of datapoint, dp-list = <counter-datapoint>
    min = calculate minimum continuously, dp-list = <datapoint>
    max = calculate maximum continuously, dp-list = <datapoint>
    sum = calculate sum continuously, dp-list = <datapoint>
    - avg = calculate average continuously, dp-list = <datapoint> + avg = calculate average continuously, dp-list = <datapoint>
    Example:
    dewpoint:taupunkt:1.TEMPERATURE,1.HUMIDITY

  • diff --git a/fhem/FHEM/88_HMCCURPC.pm b/fhem/FHEM/88_HMCCURPC.pm index 8ceee784a..1a6ba75f6 100644 --- a/fhem/FHEM/88_HMCCURPC.pm +++ b/fhem/FHEM/88_HMCCURPC.pm @@ -1556,13 +1556,13 @@ sub HMCCURPC_RPCServerStarted ($$) # $hash->{hmccu}{rpcstarttime} = 0; HMCCURPC_SetRPCState ($hash, "running", "All RPC servers running"); HMCCURPC_SetState ($hash, "OK"); - if (defined ($hmccu_hash)) { - HMCCU_SetState ($hmccu_hash, "OK"); - ($c_ok, $c_err) = HMCCU_UpdateClients ($hmccu_hash, '.*', 'Attr', 0, undef); - Log3 $name, 2, "HMCCURPC: Updated devices. Success=$c_ok Failed=$c_err"; - } +# if (defined ($hmccu_hash)) { +# HMCCU_SetState ($hmccu_hash, "OK"); +# ($c_ok, $c_err) = HMCCU_UpdateClients ($hmccu_hash, '.*', 'Attr', 0, undef); +# Log3 $name, 2, "HMCCURPC: Updated devices. Success=$c_ok Failed=$c_err"; +# } RemoveInternalTimer ($hash); - DoTrigger ($name, "RPC server running"); +# DoTrigger ($name, "RPC server running"); } return ($run, $c_ok, $c_err); @@ -2441,15 +2441,23 @@ sub HMCCURPC_EncDouble ($) { my ($v) = @_; - my $s = $v < 0 ? -1.0 : 1.0; - my $l = log (abs($v))/log (2); - my $f = $l; - - if ($l-int ($l) > 0) { - $f = ($l < 0) ? -int (abs ($l)+1.0) : int ($l); +# my $s = $v < 0 ? -1.0 : 1.0; +# my $l = log (abs($v))/log (2); +# my $f = $l; +# +# if ($l-int ($l) > 0) { +# $f = ($l < 0) ? -int (abs ($l)+1.0) : int ($l); +# } +# my $e = $f+1; +# my $m = int ($s*$v*2**-$e*0x40000000); + + my $m = 0; + my $e = 0; + + if ($v != 0.0) { + $e = int(log(abs($v))/log(2.0))+1; + $m = int($v/(2**$e)*0x40000000); } - my $e = $f+1; - my $m = int ($s*$v*2**-$e*0x40000000); return pack ('NNN', $BINRPC_DOUBLE, $m, $e); } @@ -2664,10 +2672,17 @@ sub HMCCURPC_DecDouble ($$) return (undef, undef) if ($i+8 > length ($d)); - my $m = unpack ('N', substr ($d, $i, 4)); - my $e = unpack ('N', substr ($d, $i+4, 4)); +# my $m = unpack ('N', substr ($d, $i, 4)); +# my $e = unpack ('N', substr ($d, $i+4, 4)); +# +# return (sprintf ("%.6f",$m/0x40000000*(2**$e)), 8); - return (sprintf ("%.6f",$m/0x40000000*(2**$e)), 8); + my $m = unpack ('l', reverse (substr ($d, $i, 4))); + my $e = unpack ('l', reverse (substr ($d, $i+4, 4))); + $m = $m/(1<<30); + my $v = $m*(2**$e); + + return (sprintf ("%.6f",$v), 8); } ###################################################################### diff --git a/fhem/FHEM/88_HMCCURPCPROC.pm b/fhem/FHEM/88_HMCCURPCPROC.pm index 8760b7bef..f169fbd65 100755 --- a/fhem/FHEM/88_HMCCURPCPROC.pm +++ b/fhem/FHEM/88_HMCCURPCPROC.pm @@ -4,7 +4,7 @@ # # $Id$ # -# Version 1.0.001 +# Version 1.0.002 # # Subprocess based RPC Server module for HMCCU. # @@ -35,7 +35,7 @@ use SetExtensions; ###################################################################### # HMCCURPC version -my $HMCCURPCPROC_VERSION = '1.0.001'; +my $HMCCURPCPROC_VERSION = '1.0.002'; # Maximum number of events processed per call of Read() my $HMCCURPCPROC_MAX_EVENTS = 100; @@ -590,7 +590,9 @@ sub HMCCURPCPROC_SetRPCState ($$$$) my ($hash, $state, $msg, $level) = @_; my $name = $hash->{NAME}; my $hmccu_hash = $hash->{IODev}; - + + return undef if (exists ($hash->{RPCState}) && $hash->{RPCState} eq $state); + $hash->{hmccu}{rpc}{state} = $state; $hash->{RPCState} = $state; @@ -822,7 +824,7 @@ sub HMCCURPCPROC_ProcessEvent ($$) # Input: TO|clkey|Time # Output: TO, clkey, Port, Time # - if ($evttimeout > 0) { + if ($evttimeout > 0 && $evttimeout >= $t[0]) { Log3 $name, 2, "HMCCURPCPROC: [$name] Received no events from interface $clkey for ".$t[0]." seconds"; $hash->{ccustate} = 'timeout'; if ($hash->{RPCState} eq 'running' && $ccuflags =~ /reconnect/) { @@ -1257,12 +1259,12 @@ sub HMCCURPCPROC_CleanupIO ($) delete $hash->{FD} if (defined ($hash->{FD})); } if (defined ($hash->{hmccu}{sockchild})) { - Log3 $name, 2, "HMCCURPCPROC: [$name] Close child socket"; + Log3 $name, 3, "HMCCURPCPROC: [$name] Close child socket"; $hash->{hmccu}{sockchild}->close (); delete $hash->{hmccu}{sockchild}; } if (defined ($hash->{hmccu}{sockparent})) { - Log3 $name, 2, "HMCCURPCPROC: [$name] Close parent socket"; + Log3 $name, 3, "HMCCURPCPROC: [$name] Close parent socket"; $hash->{hmccu}{sockparent}->close (); delete $hash->{hmccu}{sockparent}; } @@ -2080,16 +2082,24 @@ sub HMCCURPCPROC_EncDouble ($) { my ($v) = @_; - my $s = $v < 0 ? -1.0 : 1.0; - my $l = log (abs($v))/log (2); - my $f = $l; - - if ($l-int ($l) > 0) { - $f = ($l < 0) ? -int (abs ($l)+1.0) : int ($l); +# my $s = $v < 0 ? -1.0 : 1.0; +# my $l = $v != 0.0 ? log (abs($v))/log (2) : 0.0; +# my $f = $l; +# +# if ($l-int ($l) > 0) { +# $f = ($l < 0) ? -int (abs ($l)+1.0) : int ($l); +# } +# my $e = $f+1; +# my $m = int ($v*2**-$e*0x40000000); + + my $m = 0; + my $e = 0; + + if ($v != 0.0) { + $e = int(log(abs($v))/log(2.0))+1; + $m = int($v/(2**$e)*0x40000000); } - my $e = $f+1; - my $m = int ($s*$v*2**-$e*0x40000000); - + return pack ('NNN', $BINRPC_DOUBLE, $m, $e); } @@ -2303,10 +2313,12 @@ sub HMCCURPCPROC_DecDouble ($$) return (undef, undef) if ($i+8 > length ($d)); - my $m = unpack ('N', substr ($d, $i, 4)); - my $e = unpack ('N', substr ($d, $i+4, 4)); - - return (sprintf ("%.6f",$m/0x40000000*(2**$e)), 8); + my $m = unpack ('l', reverse (substr ($d, $i, 4))); + my $e = unpack ('l', reverse (substr ($d, $i+4, 4))); + $m = $m/(1<<30); + my $v = $m*(2**$e); + + return (sprintf ("%.6f",$v), 8); } ###################################################################### diff --git a/fhem/FHEM/HMCCUConf.pm b/fhem/FHEM/HMCCUConf.pm index c9c3ee6c2..f26b7b4c6 100644 --- a/fhem/FHEM/HMCCUConf.pm +++ b/fhem/FHEM/HMCCUConf.pm @@ -42,6 +42,14 @@ use vars qw(%HMCCU_SCRIPTS); statedatapoint => "STATE", substitute => "STATE!(0|false):closed,(1|true):open" }, + "HmIP-SWDO-I" => { + _description => "Tuer/Fensterkontakt verdeckt", + _channels => "1", + ccureadingfilter => "STATE", + hmstatevals => "SABOTAGE!1:sabotage", + statedatapoint => "STATE", + substitute => "STATE!(0|false):closed,(1|true):open" + }, "HM-Sec-RHS|HM-Sec-RHS-2" => { _description => "Fenster Drehgriffkontakt", _channels => "1", @@ -391,6 +399,13 @@ use vars qw(%HMCCU_SCRIPTS); statedatapoint => "1.STATE", substitute => "STATE!(0|false):closed,(1|true):open" }, + "HmIP-SWDO-I" => { + _description => "Tuer/Fensterkontakt verdeckt", + ccureadingfilter => "STATE", + hmstatevals => "SABOTAGE!1:sabotage", + statedatapoint => "1.STATE", + substitute => "STATE!(0|false):closed,(1|true):open" + }, "HM-Sec-RHS|HM-Sec-RHS-2" => { _description => "Fenster Drehgriffkontakt", ccureadingfilter => "STATE",