diff --git a/fhem/FHEM/00_Neuron.pm b/fhem/FHEM/00_Neuron.pm index c9493ad3e..b45aa841a 100644 --- a/fhem/FHEM/00_Neuron.pm +++ b/fhem/FHEM/00_Neuron.pm @@ -66,8 +66,8 @@ sub Neuron_Initialize(@) { $hash->{AttrFn} = 'Neuron_Attr'; $hash->{NotifyFn} = 'Neuron_Notify'; $hash->{AttrList} = "connection:websockets,polling poll_interval " - ."wsFilter:multiple-strict,ai,ao,input,led,relay,wd " - ."logicalDev:multiple-strict,ai,ao,input,led,relay,wd,temp " + ."wsFilter:multiple-strict,ai,ao,input,led,relay,wd,temp,unit_register " + ."logicalDev:multiple-strict,ai,ao,input,led,relay,wd,temp,unit_register " ."$readingFnAttributes"; return undef; } @@ -97,7 +97,8 @@ sub Neuron_Set(@) { my ($hash, $name, $cmd, @args) = @_; my $sets = $hash->{HELPER}{SETS}; if ($hash->{HELPER}{SETS} && index($hash->{HELPER}{SETS}, $cmd) != -1) { # dynamisch erzeugte outputs - my ($dev, $circuit) = (split '_', $cmd, 2); + my ($dev, $circuit) = Neuron_GetExt($hash, $cmd); + #my ($dev, $circuit) = (split '_', $cmd, 2); my $value = (looks_like_number($args[0]) ? $args[0] : $setsP{$args[0]}); if ($hash->{HELPER}{wsKey} && DevIo_IsOpen($hash)) { my $string = Neuron_wsEncode('{"cmd":"set", "dev":"'.$dev.'", "circuit":"'.$circuit.'", "value":"'.$value.'"}'); @@ -118,8 +119,6 @@ sub Neuron_Set(@) { } } elsif ($cmd eq "clearreadings") { fhem("deletereading $hash->{NAME} .*", 1); - } elsif ($cmd eq "testdispatch") { - Neuron_ParseWsResponse($hash, '{"dev":"temp","time":1527316294.23915,"temp":"23.4375","vis":"0.0002441","circuit":"2620531402000075","vad":"2.58","interval":15,"typ":"DS2438","humidity":51.9139754019274,"lost":false,"vdd":"5.34"}'); } else { return "Unknown argument $cmd, choose one of clearreadings:noArg websocket:open,close " . ($hash->{HELPER}{SETS} ? $hash->{HELPER}{SETS} : ''); } @@ -134,7 +133,7 @@ sub Neuron_Get(@) { Neuron_ReadingstoSets($hash); } elsif ($cmd eq "value") { if (index($hash->{HELPER}{GETS}, $args[0]) != -1) { - my ($dev, $circuit) = (split '_', $args[0], 2); + my ($dev, $circuit) = Neuron_GetExt($hash, $args[0]); $hash->{HELPER}{CLVAL} = $hash->{CL}; Neuron_HTTP($hash, $dev, $circuit); } else { @@ -142,7 +141,7 @@ sub Neuron_Get(@) { } } elsif ($cmd eq "conf") { if (index($hash->{HELPER}{GETS}, $args[0]) != -1) { - my ($dev, $circuit) = (split '_', $args[0], 2); + my ($dev, $circuit) = Neuron_GetExt($hash, $args[0]); $hash->{HELPER}{CLCONF} = $hash->{CL}; Neuron_HTTP($hash, $dev, $circuit); } else { @@ -159,6 +158,19 @@ sub Neuron_Get(@) { return undef; } +sub Neuron_GetExt(@) { # bei Extensions mithilfe von ExtensionNamen splitten (geht sonst bei Typen mit "_" wie unit_register schief) + my ($hash, $pinname) = @_; + my $n = 2; + while (exists($hash->{$n."_CIRCUIT"})){ + my $pos = index($pinname, $hash->{$n."_CIRCUIT"}); + if ( $pos != -1) { + return (substr($pinname,0,$pos - 1), substr($pinname,$pos)); + } + $n +=1; + } + return (split '_', $pinname, 2); +} + sub Neuron_Attr(@) { my ($cmd, $name, $attr, $val) = @_; @@ -290,7 +302,7 @@ sub Neuron_HTTP(@){ $data = '{"value":'.$data.'}'; # Sonderlösung, da der Analoge Ausgang den Wert nur ohne Hochkommas akzeptiert } } - Log3($hash, 3,"$hash->{TYPE} ($hash->{NAME}): sending ".($data ? "POST ($data)" : "GET")." request to url $url"); + Log3($hash, 4,"$hash->{TYPE} ($hash->{NAME}): sending ".($data ? "POST ($data)" : "GET")." request to url $url"); my $param= { url => $url, hash => $hash, @@ -333,15 +345,23 @@ sub Neuron_callback(@) { if($err){ Log3($hash, 3, "$hash->{TYPE} ($hash->{NAME}) received callback with error:\n$err"); + readingsSingleUpdate($hash,"state",$err,1); } elsif($data){ Log3($hash, 5, "$hash->{TYPE} ($hash->{NAME}) received callback with:\n$data"); - my $parser = $param->{parser}; - &$parser($hash, $data); - asyncOutput($hash->{HELPER}{CLCONF}, $data) if $hash->{HELPER}{CLCONF}; - delete $hash->{HELPER}{CLCONF}; + if( substr($data,0,6) eq "" ) { + (my $title) = $data =~ /\(.*)\<\/title\>/; + readingsSingleUpdate($hash,"state",$title,1); + } else { + my $parser = $param->{parser}; + &$parser($hash, $data); + asyncOutput($hash->{HELPER}{CLCONF}, $data) if $hash->{HELPER}{CLCONF}; + } + #delete $hash->{HELPER}{CLCONF}; } else { Log3($hash, 2, "$hash->{TYPE} ($hash->{NAME}) received callback without Data and Error String!!!"); + readingsSingleUpdate($hash,"state","no data received",1); } + delete $hash->{HELPER}{CLCONF}; return undef; } @@ -377,10 +397,16 @@ sub Neuron_ParseSingle(@){ } if (ref $result eq 'HASH') { - readingsSingleUpdate($hash,$result->{dev}."_".$result->{circuit},$result->{value},1); + if (exists $result->{address}) { + # {"interval": 15, "value": 23.7, "circuit": "VlTiba", "address": "28751F1F0C000067", "time": 1624541181.043978, "typ": "DS18B20", "lost": false, "dev": "temp"} + # Besonderheit für 1Wire, dort ist im circuit scheinbar das alias enthalten + readingsSingleUpdate($hash,$result->{dev}."_".$result->{address},$result->{value},1); + } else { + readingsSingleUpdate($hash,$result->{dev}."_".$result->{circuit},$result->{value},1); + } asyncOutput($hash->{HELPER}{CLVAL}, $result->{value}) if $hash->{HELPER}{CLVAL}; delete $hash->{HELPER}{CLVAL}; - Dispatch($hash, $result, (%addvals ? \%addvals : undef)) if index(AttrVal($hash->{NAME}, 'logicalDev', 'relay,input,led,ao,temp') , $result->{dev}) != -1; + Dispatch($hash, $result, (%addvals ? \%addvals : undef)) if index(AttrVal($hash->{NAME}, 'logicalDev', 'relay,input,led,ao,temp,unit_register') , $result->{dev}) != -1; } else { Log3 ($hash, 3, "$hash->{TYPE} ($hash->{NAME}) http response not JSON: ".$result); } @@ -439,7 +465,7 @@ sub Neuron_ParseAll(@){ $value = $subdev->{value}; #$value = $rsetsP{$value} if ($subdev->{dev} eq 'input' || $subdev->{dev} eq 'relay' || $subdev->{dev} eq 'led'); # on,off anstelle von 1,0 readingsBulkUpdateIfChanged($hash,$subdev->{dev}."_".$subdev->{circuit},$value) if defined($value); - Dispatch($hash, $subdev, (%addvals ? \%addvals : undef)) if index(AttrVal($hash->{NAME}, 'logicalDev', 'relay,input,led,ao'), $subdev->{dev}) != -1; + Dispatch($hash, $subdev, (%addvals ? \%addvals : undef)) if index(AttrVal($hash->{NAME}, 'logicalDev', 'relay,input,led,ao,temp,,unit_register'), $subdev->{dev}) != -1; delete $subdev->{value}; readingsBulkUpdateIfChanged($hash,".".$subdev->{dev}."_".$subdev->{circuit},toJSON($subdev),0); Log3 ($hash, 4, "$hash->{TYPE} ($hash->{NAME}) ".$subdev->{dev}."_".$subdev->{circuit} .": ". toJSON($subdev)); @@ -494,7 +520,7 @@ sub Neuron_DecodeWsJSON($$){ my ($hash, $dev)=@_; eval { readingsBulkUpdate($hash,$dev->{dev}."_".$dev->{circuit},$dev->{value}); - Dispatch($hash, $dev, undef) if index(AttrVal($hash->{NAME}, 'logicalDev', 'relay,input,led,ao') , $dev->{dev}) != -1; + Dispatch($hash, $dev, undef) if index(AttrVal($hash->{NAME}, 'logicalDev', 'relay,input,led,ao,temp,unit_register') , $dev->{dev}) != -1; }; if ($@) { Log3 ($hash, 3, "$hash->{TYPE} ($hash->{NAME}): error decoding JSON $@\nData:\n$dev"); @@ -786,7 +812,7 @@ sub Neuron_wsDecode($$) { } #String kürzer als Längenangabe -> Zwischenspeichern? if (length($wsString) < $offset + $len) { - Log3 $hash, 3, "Neuron_wsDecode Incomplete:\n" . $wsString; + Log3 $hash, 4, "Neuron_wsDecode Incomplete:\n" . $wsString; return; } my $payload = substr($wsString, $offset, $len); # Daten aus String extrahieren @@ -843,51 +869,51 @@ sub Neuron_wsMasking($$) {

Neuron

Set
Get
@@ -896,19 +922,23 @@ sub Neuron_wsMasking($$) { @@ -922,13 +952,12 @@ sub Neuron_wsMasking($$) {

Neuron


Get =end html_DE -=cut \ No newline at end of file +=cut diff --git a/fhem/FHEM/10_NeuronPin.pm b/fhem/FHEM/10_NeuronPin.pm index fb3c1972d..9a01f5e46 100644 --- a/fhem/FHEM/10_NeuronPin.pm +++ b/fhem/FHEM/10_NeuronPin.pm @@ -7,6 +7,7 @@ package main; use strict; use warnings; use SetExtensions; +use Encode qw(decode encode); my %sets = ( 'on' => 1, @@ -40,11 +41,28 @@ sub NeuronPin_Initialize($) { sub NeuronPin_Define($$) { my ($hash, $def) = @_; my @a = split('[ \t][ \t]*', $def); -# hier fehlt noch Überprüfung der Attribute - $modules{NeuronPin}{defptr}{$a[2]." ".$a[3]} = $hash; - return "$hash->{NAME} Pintype not valid" unless ($a[2] =~ /^(input|relay|ai|ao|led|temp|wd)$/ ); + if (scalar(@a) == 4) { + #altes Define (enthält noch nicht den Namen vom IODev), untauglich für mehrere Neurons + $modules{NeuronPin}{defptr}{$a[2]." ".$a[3]} = $hash; + #Log3 $hash, 1, "$hash->{TYPE} ($hash->{NAME}) Define: $a[2] $a[3]"; + my @EVOKS = devspec2array("TYPE=Neuron"); + if (scalar(@EVOKS) == 1) { + Log3 ($hash, 1, "$hash->{TYPE} ($hash->{NAME}) one Neuron Device defined. Try to correct define." ); + $hash->{DEF} = $hash->{DEF} . " " . $EVOKS[0]; + $modules{NeuronPin}{defptr}{$a[2]." ".$a[3]." ".$EVOKS[0]} = $hash; + } elsif (scalar(@EVOKS) >> 1) { + Log3 ($hash, 0, "$hash->{TYPE} ($hash->{NAME}) more than one Neuron Device defined. Unable to autocorrect define." ); + $modules{NeuronPin}{defptr}{$a[2]." ".$a[3]} = $hash; + } + } elsif (scalar(@a) == 5) { + $modules{NeuronPin}{defptr}{$a[2]." ".$a[3]." ".$a[4]} = $hash; + } else { + return "Define: Wrong syntax. Usage:\n" . + "define NeuronPin "; + } + AssignIoPort($hash, AttrVal($hash->{NAME},"IODev", (split " ", $hash->{DEF})[2] ) ); + #return "$hash->{NAME} Pintype not valid" unless ($a[2] =~ /^(input|relay|ai|ao|led|temp|wd)$/ ); $hash->{DEV} = $a[2]; - #return "$hash->{NAME} Circuit Name not valid" unless ($a[3] =~ /^[1-9]_((0[1-9])|[1-9][0-9])$/ ); $hash->{CIRCUIT} = $a[3]; $hash->{STATE} = "defined"; @@ -57,12 +75,10 @@ sub NeuronPin_Define($$) { sub NeuronPin_Init($$) { my ( $hash, $args ) = @_; - unless (defined $args && int(@$args) == 2) { + unless (defined $args && int(@$args) >= 2) { return "Define: Wrong syntax. Usage:\n" . - "define NeuronPin "; + "define NeuronPin "; } - AssignIoPort($hash); - #$hash->{STATE} = 'Initialized'; if (ReadingsVal($hash->{NAME}, '.conf', '')) { NeuronPin_CreateSets($hash); if (AttrVal($hash->{NAME},"restoreOnStartup",'')) { @@ -72,7 +88,8 @@ sub NeuronPin_Init($$) { } } else { return if(IsDisabled($hash->{NAME})); - IOWrite($hash, split " ", $hash->{DEF}); + #IOWrite($hash, split " ", $hash->{DEF}); + IOWrite($hash, $hash->{DEV}, $hash->{CIRCUIT}); } $hash->{STATE} = ReadingsVal($hash->{NAME},'state','') if ReadingsVal($hash->{NAME},'state',''); return undef; @@ -90,7 +107,6 @@ sub NeuronPin_Catch($) { sub NeuronPin_State($$$$) { #reload readings at FHEM start my ($hash, $tim, $sname, $sval) = @_; #Log3 $hash, 5, "$hash->{TYPE} ($hash->{NAME}): $sname kann auf $sval wiederhergestellt werden $tim"; - if ( $sname ne "STATE" && (my $pval = AttrVal($hash->{NAME},"restoreOnStartup",'')) && $hash->{DEV} =~ /relay|ao/ ) { if ($sname eq "state") { if ($pval eq 'on' || $pval eq 'off' || looks_like_number($pval)) { @@ -108,75 +124,110 @@ sub NeuronPin_State($$$$) { #reload readings at FHEM start sub NeuronPin_Parse ($$) { my ( $io_hash, $message) = @_; - my $port = $message->{dev}." ".$message->{circuit}; - Log3 (undef, 4, "NeuronPin_Parse von $io_hash->{NAME} empfangen:\n" . encode_json $message); + my $port = $message->{dev}." ".$message->{circuit}; + + Log3 (undef, 4, "NeuronPin_Parse von $io_hash->{NAME} empfangen: " . encode_json $message); if (my $hash = $modules{NeuronPin}{defptr}{$port}) { - my $value = $message->{value}; - # zusätzliche Daten als Internal - $hash->{RELAY_TYPE} = $message->{relay_type} if $message->{relay_type}; - $hash->{TYP} = $message->{typ} if defined $message->{typ}; - $hash->{GLOB_DEV_ID} = $message->{glob_dev_id} if defined $message->{glob_dev_id}; - $value = $rsets{$value} if ($message->{dev} eq 'input' || $message->{dev} eq 'relay' || $message->{dev} eq 'led'); - readingsBeginUpdate($hash); - readingsBulkUpdate($hash,"state",$value); - readingsBulkUpdate($hash,"dim",$value) if $message->{dev} eq 'ao'; - - # my @readings = ("mode","unit","range","debounce","counter","counter_mode","alias","pwm_freq","pwm_duty","temp","humidity","vdd","vad"); - # foreach (@readings){ - # if (exists($message->{$_})) { - # readingsBulkUpdate($hash,"Z_".$_,$message->{$_}); - # } else { - # readingsDelete($hash, "Z_".$_); - # } - # } + foreach my $dev (devspec2array("TYPE=Neuron")) { + Log3 (undef, 1, "NeuronPin_Parse Neuron Device gefunden: " . InternalVal($dev,"NAME","") ); + } + } + if (my $hash = $modules{NeuronPin}{defptr}{$port ." ". $io_hash->{NAME}}) { + NeuronPin_TransferVals ($hash, $message); + } elsif (my $hash = $modules{NeuronPin}{defptr}{$port}) { + Log3 (undef, 1, "NeuronPin_Parse from $io_hash->{NAME} to $hash->{NAME} : incomplete Define"); + NeuronPin_TransferVals ($hash, $message); + } else { + Log3 ($hash, 4, "NeuronPin_Parse von $io_hash->{NAME} nothing found...create logical device"); + return "UNDEFINED $io_hash->{NAME}_".$message->{dev}."_".$message->{circuit}." NeuronPin " . $port . " " . $io_hash->{NAME}; + } +} - my @skipreadings = split(',', AttrVal($hash->{NAME}, 'skipreadings', "relay_type,typ,dev,circuit,glob_dev_id,value,pending") ); - foreach (keys %{$hash->{READINGS}}) { - #next if substr($_,0,2) eq "Z_"; - readingsDelete($hash, $_) unless exists($message->{$_}) || $_ eq "state" || $_ eq ".conf" || $_ eq "dim"; +sub NeuronPin_TransferVals ($$) { +my ( $hash, $message) = @_; + my @skipreadings = split(',', AttrVal($hash->{NAME}, 'skipreadings', "relay_type,typ,dev,circuit,glob_dev_id,pending") ); + my @uichreadings = split(',', "mode,unit,range,address,address,name"); + # zusätzliche Daten als Internal + $hash->{RELAY_TYPE} = $message->{relay_type} if $message->{relay_type}; + $hash->{TYP} = $message->{typ} if defined $message->{typ}; + $hash->{GLOB_DEV_ID} = $message->{glob_dev_id} if defined $message->{glob_dev_id}; + my $value = $message->{value}; + my $basequantity = ""; + my $unit = defined $message->{unit} ? encode("UTF-8", " " . $message->{unit}) : ""; + if ($message->{dev} eq 'input' || $message->{dev} eq 'relay' || $message->{dev} eq 'led') { + $value = $rsets{$value} + } else { + #$value = sprintf('%.2f', $value); #nur 2 Nachkommastellen + #$value =~ s/\.(?:|.*[^0]\K)0*\z//; #keine 0 am Ende nach dem Komma + #$value =~ s/^-0$/0/; #kein -0 + $value = round($value,2); + if ($message->{mode}) { + $basequantity = lc($message->{mode}); + } elsif ( $message->{dev} eq 'temp' ) { + $basequantity = "temperature"; + $unit = " °C"; + } elsif ( $message->{dev} eq 'unit_register' ) { + $basequantity = $message->{name}; } - foreach my $key (keys %$message){ - if (ref $message->{$key} eq 'ARRAY') { # alle Arrays überspringen - } elsif (grep( /^$key/, @skipreadings )) { # Wer soll nicht als reading angelegt werden - readingsDelete($hash, $key); - } elsif ($key eq 'alias') { # al_ am Anfang von alias weg - # my $alias = (split '_', $message->{$key})[1]; - my @aliases = (split '_', $message->{$key}); - my $alias = join(" ",@aliases[1 .. $#aliases]); - readingsBulkUpdate($hash,$key,$alias); - # autocreate alias attribute - if (AttrVal($hash->{NAME}, 'alias', '?') ne $alias && defined AttrVal($hash->{NAME}, 'autoalias', '')) { - my $msg = CommandAttr(undef, $hash->{NAME} . " alias $alias"); - Log3 ($hash, 2, "$hash->{TYPE} ($hash->{NAME}): Error creating alias $msg") if ($msg); - } - }else { + } + +# $value = $rsets{$value} if ($message->{dev} eq 'input' || $message->{dev} eq 'relay' || $message->{dev} eq 'led'); +# unless ( $value == 0 || $value == 1 ) { +# $value = sprintf('%.2f', $value); +# $value =~ s/\.(?:|.*[^0]\K)0*\z//; +# $value =~ s/^-0$/0/; +# } + + readingsBeginUpdate($hash); + readingsBulkUpdate($hash,"state", $value . $unit ); + readingsBulkUpdate($hash,"dim",$value) if $message->{dev} eq 'ao'; + + foreach (keys %{$hash->{READINGS}}) { + #next if substr($_,0,2) eq "Z_"; + readingsDelete($hash, $_) unless exists($message->{$_}) || $_ eq "state" || $_ eq ".conf" || $_ eq "dim"; + } + foreach my $key (keys %$message){ + if (ref $message->{$key} eq 'ARRAY') { # alle Arrays überspringen + } elsif (grep( /^$key/, @skipreadings )) { # Wer soll nicht als reading angelegt werden + readingsDelete($hash, $key); + } elsif ($key eq 'alias') { # al_ am Anfang von alias weg + my @aliases = (split '_', $message->{$key}); + my $alias = join(" ",@aliases[1 .. $#aliases]); + readingsBulkUpdate($hash,$key,$alias); + # autocreate alias attribute + if (AttrVal($hash->{NAME}, 'alias', '?') ne $alias && defined AttrVal($hash->{NAME}, 'autoalias', '')) { + my $msg = CommandAttr(undef, $hash->{NAME} . " alias $alias"); + Log3 ($hash, 2, "$hash->{TYPE} ($hash->{NAME}): Error creating alias $msg") if ($msg); + } + } else { + if (grep( /^$key/, @uichreadings )) { + readingsBulkUpdateIfChanged($hash,$key,encode("UTF-8",$message->{$key})); + } else { readingsBulkUpdate($hash,$key,$message->{$key}); } } - delete $message->{value}; - readingsBulkUpdateIfChanged($hash,".conf",encode_json $message,0); - readingsEndUpdate($hash,1); - - NeuronPin_CreateSets($hash); - - if ($hash->{HELPER}{SETREQ} && not $hash->{IODev}->{HELPER}{WESOCKETS}) { # workaround because neuron sends old value after set - RemoveInternalTimer($hash,'NeuronPin_RereadPin'); - InternalTimer(gettimeofday() + 1, 'NeuronPin_RereadPin', $hash); - delete $hash->{HELPER}{SETREQ}; - } - asyncOutput($hash->{HELPER}{CL}, encode_json $message) if $hash->{HELPER}{CL}; # show conf after get - delete $hash->{HELPER}{CL}; - return $hash->{NAME}; - } else { - Log3 ($hash, 4, "NeuronPin_Parse von $io_hash->{NAME} nix gefunden...anlegen"); - return "UNDEFINED $io_hash->{NAME}_Pin_".$message->{dev}."_".$message->{circuit}." NeuronPin " . $port; } + readingsBulkUpdate($hash, $basequantity, $message->{value} . $unit ) if $basequantity; + delete $message->{value}; + readingsBulkUpdateIfChanged($hash,".conf",encode_json $message,0); + readingsEndUpdate($hash,1); + + NeuronPin_CreateSets($hash); + + if ($hash->{HELPER}{SETREQ} && not $hash->{IODev}->{HELPER}{WESOCKETS}) { # workaround because neuron sends old value after set + RemoveInternalTimer($hash,'NeuronPin_RereadPin'); + InternalTimer(gettimeofday() + 1, 'NeuronPin_RereadPin', $hash); + delete $hash->{HELPER}{SETREQ}; + } + asyncOutput($hash->{HELPER}{CL}, encode_json $message) if $hash->{HELPER}{CL}; # show conf after get + delete $hash->{HELPER}{CL}; + return $hash->{NAME}; } sub NeuronPin_RereadPin($) { my ($hash) = @_; return if(IsDisabled($hash->{NAME})); - IOWrite( $hash, split(" ", $hash->{DEF}) ); + IOWrite($hash, $hash->{DEV}, $hash->{CIRCUIT}); } sub NeuronPin_Attr (@) { @@ -245,15 +296,6 @@ sub NeuronPin_CreateSets($) { } } } - # my @stypes = ("modes","range_modes","counter_modes"); - # my @stype = ("mode","range_mode","counter_mode"); - # foreach my $i (0 .. $#stypes) { - # if ($result->{$stypes[$i]} && scalar keys @{$result->{$stypes[$i]}} > 1) { - # foreach (@{$result->{$stypes[$i]}}){ - # $hash->{HELPER}{SETS}{$stype[$i]}{$_} = 1; - # } - # } - # } my @freesets = split(';', AttrVal($hash->{NAME}, 'ownsets', "debounce;counter;interval;pwm_freq;pwm_duty:slider,0,0.1,100") ); foreach (@freesets) { @@ -294,13 +336,11 @@ sub NeuronPin_Set($@) { my $cmd = $a[1]; my $arg = $a[2]; - my @arguments = (split(" ",$hash->{DEF})); + my @arguments = ($hash->{DEV}, $hash->{CIRCUIT}); - #if(!defined($sets{$cmd})) { if(!defined($hash->{HELPER}{SETS}{$cmd})) { if (my $setlist = $hash->{HELPER}{SET}) { return SetExtensions($hash, $setlist, @a) ; - #return 'Unknown argument ' . $cmd . ', choose one of ' . $setlist; } return undef } elsif ($cmd eq "dim") { @@ -323,20 +363,17 @@ sub NeuronPin_Set($@) { $arguments[2] = $cmd; $arguments[3] = $arg; } - #$hash->{HELPER}{SETREQ} = 1; - #my @arguments = (split(" ",$hash->{DEF}),$sets{$cmd}); return if(IsDisabled($hash->{NAME})); IOWrite($hash, @arguments); } sub NeuronPin_Get($@) { my ($hash, $name, $cmd, @args) = @_; + my @arguments = ($hash->{DEV}, $hash->{CIRCUIT}); if ($cmd && $cmd eq "refresh") { - my @arguments = (split " ", $hash->{DEF}); return if(IsDisabled($hash->{NAME})); IOWrite($hash, @arguments); } elsif ($cmd && $cmd eq "config") { - my @arguments = (split " ", $hash->{DEF}); $hash->{HELPER}{CL} = $hash->{CL}; return if(IsDisabled($hash->{NAME})); IOWrite($hash, @arguments); @@ -353,17 +390,20 @@ sub NeuronPin_Undef($$) { return undef; } -#sub NeuronPin_DbLog_splitFn($) { -# my ($event) = @_; -# Log3 undef, 5, "in DbLog_splitFn empfangen: $event"; -# my ($reading, $value, $unit) = ""; -# my @parts = split(/ /,$event); -# $reading = shift @parts; -# $reading =~ tr/://d; -# $value = $parts[0]; -# $unit = "V" if(lc($reading) =~ m/spannung/); -# return ($reading, $value, $unit); -#} +sub NeuronPin_DbLog_splitFn($) { + my ($event) = @_; + Log3 undef, 5, "in NeuronPin DbLog_splitFn empfangen: $event"; + my ($reading, $value, $unit) = ""; + my @parts = split(/ /,$event); + $reading = shift @parts; + $reading =~ tr/://d; + $unit = ''; # ReadingsVal($hash->{NAME},'unit',''); + if ($reading eq "value" && $unit) { + $value = $parts[0]; + Log3 undef, 3, "in NeuronPin DbLog_splitFn empfangen: $event, return: |$reading|$value|$unit|"; + return ($reading, $value, $unit); + } +} 1; @@ -383,14 +423,15 @@ sub NeuronPin_Undef($$) { Define
    - define NeuronPin <dev> <circuit>

    + define NeuronPin <dev> <circuit> <Neuron IODev>

    <dev> is an device type like input, ai (analog input), relay (digital output) etc.
    - <circuit> ist the number of the device. + <circuit> is the number of the device.
    + <Neuron IODev> is the EVOK device where this subdevice is connected

    Example:
    -      define  NeuronPin_relay_2_01 NeuronPin relay 2_01
    +      define  NeuronPin_relay_2_01 NeuronPin relay 2_01 Neuron1
         
@@ -411,7 +452,7 @@ sub NeuronPin_Undef($$) { Other set values depending on the options of the device function. Details can be found in the UniPi Evok documentation. - +
Get @@ -430,27 +471,33 @@ sub NeuronPin_Undef($$) {
  • poll_interval
    Set the polling interval in minutes to query all readings
    - Default: -, valid values: decimal number

    + Default: -
    + valid values: decimal number

  • restoreOnStartup
    Restore Readings and sets after reboot
    - Default: last, valid values: last, on, off, no

    + Default: last
    + valid values: last, on, off, no

  • aomax
    Maximum value for the slider from the analog output ports
    - Default: 10, valid values: decimal number

    + Default: 10
    + valid values: decimal number

  • skipreadings
    Values which will be sent from the Device and which shall not be listed as readings
    - Default: relay_type,typ,dev,circuit,glob_dev_id,value,pending; valid values: comma separated list

    + Default: relay_type,typ,dev,circuit,glob_dev_id,value,pending
    + valid values: comma separated list

  • ownsets
    Values which will be sent from the Device which can be changed via set. For Values for where the device sends fixed choices, the sets will created automatically
    - Default: debounce;counter;interval;pwm_freq;pwm_duty:slider,0,0.1,100 valid values: semicolon separated list

    + Default: debounce;counter;interval;pwm_freq;pwm_duty:slider,0,0.1,100
    + valid values: semicolon separated list

  • autoalias
    If set to 1, reading alias will automatically change the attribute "alias"
    - Default: 0, valid values: 0,1

    + Default: 1
    + valid values: 0,1

  • IODev
  • readingFnAttributes
  • @@ -469,20 +516,21 @@ sub NeuronPin_Undef($$) {

    NeuronPin

      - Logisches Modul fü Geräte auf denen EVOK läuft. + Logisches Modul für Geräte auf denen EVOK läuft. Diese werden automatisch vom Neuron Modul angelegt.
      Define
        - define NeuronPin <dev> <circuit>

        + define NeuronPin <dev> <circuit> <Neuron IODev>

        <dev> ist der Typ des Subdevices/Pins z.B. input, ai (analoger Eingang), relay (digitaler Ausgang) etc.
        - <circuit> ist die Nummer des Subdevices/Pins. + <circuit> ist die Nummer des Subdevices/Pins.
        + <Neuron IODev> ist der Name des EVOK Devices zu dem dieses Subdevice gehört.

        Beispiel:
        -      define  NeuronPin_relay_2_01 NeuronPin relay 2_01
        +      define  NeuronPin_relay_2_01 NeuronPin relay 2_01 Neuron1
             
      @@ -503,7 +551,7 @@ sub NeuronPin_Undef($$) {
    Weitere set values sind abhängig von den jeweiligen Subdevice Funktionen. Details dazu sind in der UniPi Evok Dokumentation zu finden. -
+
Get @@ -522,27 +570,33 @@ sub NeuronPin_Undef($$) {
  • poll_interval
    Interval in Minuten in dem alle Werte gelesen werden.
    - Standard: -, gültige Werte: Dezimalzahl

    + Standard: -
    + gültige Werte: Dezimalzahl

  • restoreOnStartup
    Readings nach Neustart wiederherstellen
    - Standard: last, gültige Werte: last, on, off

    + Standard: last
    + gültige Werte: last, on, off

  • aomax
    Maxwert für den Schieberegler beim Analogen Ausgang
    - Standard: 10, gültige Werte: Dezimalzahl

    + Standard: 10
    + gültige Werte: Dezimalzahl

  • skipreadings
    Werte, die vom Gerät gesendet, aber nicht als Reading dargestellt werden sollen.
    - Standard: relay_type,typ,dev,circuit,glob_dev_id,value,pending; gültige Werte: kommaseparierte Liste

    + Standard: relay_type,typ,dev,circuit,glob_dev_id,value,pending
    + gültige Werte: kommaseparierte Liste

  • ownsets
    Werte, die vom Gerät gesendet, und über set verändert werden können. Schickt das Gerät feste Auswahllisten für einen Wert dann werden die sets automatisch angelegt.
    - Standard: debounce;counter;interval;pwm_freq;pwm_duty:slider,0,0.1,100; gültige Werte: semikolonseparierte Liste

    + Standard: debounce;counter;interval;pwm_freq;pwm_duty:slider,0,0.1,100
    + gültige Werte: semikolonseparierte Liste

  • autoalias
    Wenn auf 1 wird das reading alias automatisch als Attribut alias gesetzt.
    - Standard: 0, gültige Werte: 0,1

    + Standard: 1
    + gültige Werte: 0,1

  • IODev
  • readingFnAttributes