00_Neuron.pm: added support for multiple physical deviced

10_NeuronPin.pm: added support for multiple physical deviced


git-svn-id: https://svn.fhem.de/fhem/trunk/fhem@24902 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
klausw 2021-08-31 20:53:36 +00:00
parent 47efe7f67f
commit 338ebed314
2 changed files with 261 additions and 176 deletions

View File

@ -66,8 +66,8 @@ sub Neuron_Initialize(@) {
$hash->{AttrFn} = 'Neuron_Attr'; $hash->{AttrFn} = 'Neuron_Attr';
$hash->{NotifyFn} = 'Neuron_Notify'; $hash->{NotifyFn} = 'Neuron_Notify';
$hash->{AttrList} = "connection:websockets,polling poll_interval " $hash->{AttrList} = "connection:websockets,polling poll_interval "
."wsFilter:multiple-strict,ai,ao,input,led,relay,wd " ."wsFilter:multiple-strict,ai,ao,input,led,relay,wd,temp,unit_register "
."logicalDev:multiple-strict,ai,ao,input,led,relay,wd,temp " ."logicalDev:multiple-strict,ai,ao,input,led,relay,wd,temp,unit_register "
."$readingFnAttributes"; ."$readingFnAttributes";
return undef; return undef;
} }
@ -97,7 +97,8 @@ sub Neuron_Set(@) {
my ($hash, $name, $cmd, @args) = @_; my ($hash, $name, $cmd, @args) = @_;
my $sets = $hash->{HELPER}{SETS}; my $sets = $hash->{HELPER}{SETS};
if ($hash->{HELPER}{SETS} && index($hash->{HELPER}{SETS}, $cmd) != -1) { # dynamisch erzeugte outputs 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]}); my $value = (looks_like_number($args[0]) ? $args[0] : $setsP{$args[0]});
if ($hash->{HELPER}{wsKey} && DevIo_IsOpen($hash)) { if ($hash->{HELPER}{wsKey} && DevIo_IsOpen($hash)) {
my $string = Neuron_wsEncode('{"cmd":"set", "dev":"'.$dev.'", "circuit":"'.$circuit.'", "value":"'.$value.'"}'); my $string = Neuron_wsEncode('{"cmd":"set", "dev":"'.$dev.'", "circuit":"'.$circuit.'", "value":"'.$value.'"}');
@ -118,8 +119,6 @@ sub Neuron_Set(@) {
} }
} elsif ($cmd eq "clearreadings") { } elsif ($cmd eq "clearreadings") {
fhem("deletereading $hash->{NAME} .*", 1); 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 { } else {
return "Unknown argument $cmd, choose one of clearreadings:noArg websocket:open,close " . ($hash->{HELPER}{SETS} ? $hash->{HELPER}{SETS} : ''); 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); Neuron_ReadingstoSets($hash);
} elsif ($cmd eq "value") { } elsif ($cmd eq "value") {
if (index($hash->{HELPER}{GETS}, $args[0]) != -1) { 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}; $hash->{HELPER}{CLVAL} = $hash->{CL};
Neuron_HTTP($hash, $dev, $circuit); Neuron_HTTP($hash, $dev, $circuit);
} else { } else {
@ -142,7 +141,7 @@ sub Neuron_Get(@) {
} }
} elsif ($cmd eq "conf") { } elsif ($cmd eq "conf") {
if (index($hash->{HELPER}{GETS}, $args[0]) != -1) { 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}; $hash->{HELPER}{CLCONF} = $hash->{CL};
Neuron_HTTP($hash, $dev, $circuit); Neuron_HTTP($hash, $dev, $circuit);
} else { } else {
@ -159,6 +158,19 @@ sub Neuron_Get(@) {
return undef; 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(@) { sub Neuron_Attr(@) {
my ($cmd, $name, $attr, $val) = @_; 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 $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= { my $param= {
url => $url, url => $url,
hash => $hash, hash => $hash,
@ -333,15 +345,23 @@ sub Neuron_callback(@) {
if($err){ if($err){
Log3($hash, 3, "$hash->{TYPE} ($hash->{NAME}) received callback with error:\n$err"); Log3($hash, 3, "$hash->{TYPE} ($hash->{NAME}) received callback with error:\n$err");
readingsSingleUpdate($hash,"state",$err,1);
} elsif($data){ } elsif($data){
Log3($hash, 5, "$hash->{TYPE} ($hash->{NAME}) received callback with:\n$data"); Log3($hash, 5, "$hash->{TYPE} ($hash->{NAME}) received callback with:\n$data");
my $parser = $param->{parser}; if( substr($data,0,6) eq "<html>" ) {
&$parser($hash, $data); (my $title) = $data =~ /\<title\>(.*)\<\/title\>/;
asyncOutput($hash->{HELPER}{CLCONF}, $data) if $hash->{HELPER}{CLCONF}; readingsSingleUpdate($hash,"state",$title,1);
delete $hash->{HELPER}{CLCONF}; } else {
my $parser = $param->{parser};
&$parser($hash, $data);
asyncOutput($hash->{HELPER}{CLCONF}, $data) if $hash->{HELPER}{CLCONF};
}
#delete $hash->{HELPER}{CLCONF};
} else { } else {
Log3($hash, 2, "$hash->{TYPE} ($hash->{NAME}) received callback without Data and Error String!!!"); 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; return undef;
} }
@ -377,10 +397,16 @@ sub Neuron_ParseSingle(@){
} }
if (ref $result eq 'HASH') { 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}; asyncOutput($hash->{HELPER}{CLVAL}, $result->{value}) if $hash->{HELPER}{CLVAL};
delete $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 { } else {
Log3 ($hash, 3, "$hash->{TYPE} ($hash->{NAME}) http response not JSON: ".$result); Log3 ($hash, 3, "$hash->{TYPE} ($hash->{NAME}) http response not JSON: ".$result);
} }
@ -439,7 +465,7 @@ sub Neuron_ParseAll(@){
$value = $subdev->{value}; $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 #$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); 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}; delete $subdev->{value};
readingsBulkUpdateIfChanged($hash,".".$subdev->{dev}."_".$subdev->{circuit},toJSON($subdev),0); readingsBulkUpdateIfChanged($hash,".".$subdev->{dev}."_".$subdev->{circuit},toJSON($subdev),0);
Log3 ($hash, 4, "$hash->{TYPE} ($hash->{NAME}) ".$subdev->{dev}."_".$subdev->{circuit} .": ". toJSON($subdev)); Log3 ($hash, 4, "$hash->{TYPE} ($hash->{NAME}) ".$subdev->{dev}."_".$subdev->{circuit} .": ". toJSON($subdev));
@ -494,7 +520,7 @@ sub Neuron_DecodeWsJSON($$){
my ($hash, $dev)=@_; my ($hash, $dev)=@_;
eval { eval {
readingsBulkUpdate($hash,$dev->{dev}."_".$dev->{circuit},$dev->{value}); 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 ($@) { if ($@) {
Log3 ($hash, 3, "$hash->{TYPE} ($hash->{NAME}): error decoding JSON $@\nData:\n$dev"); 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? #String kürzer als Längenangabe -> Zwischenspeichern?
if (length($wsString) < $offset + $len) { if (length($wsString) < $offset + $len) {
Log3 $hash, 3, "Neuron_wsDecode Incomplete:\n" . $wsString; Log3 $hash, 4, "Neuron_wsDecode Incomplete:\n" . $wsString;
return; return;
} }
my $payload = substr($wsString, $offset, $len); # Daten aus String extrahieren my $payload = substr($wsString, $offset, $len); # Daten aus String extrahieren
@ -843,51 +869,51 @@ sub Neuron_wsMasking($$) {
<h3>Neuron</h3> <h3>Neuron</h3>
<ul> <ul>
<a name="Neuron"></a> <a name="Neuron"></a>
Module for EVOK driven devices like UniPi Neuron. Module for EVOK driven devices like UniPi Neuron.<br>
Defines will be automatically created by the Neuron module.
<br> <br>
<a name="NeuronDefine"></a> <a name="NeuronDefine"></a>
<b>Define</b> <b>Define</b>
<ul> <ul>
<code>define <name> Neuron &lt;dev&gt; &lt;circuit&gt;</code><br><br> <code>define <name> Neuron &lt;dev&gt; &lt;circuit&gt;</code><br><br>
&lt;dev&gt; is an device type like input, ai (analog input), relay (digital output) etc.<br> </ul>
&lt;circuit&gt; ist the number of the device.
<br><br>
Example:
<pre>
<code>define <name> Neuron &lt;IP&gt;[:&lt;Port&gt;]</code><br><br>
</pre>
</ul>
<a name="NeuronSet"></a> <a name="NeuronSet"></a>
<b>Set</b> <b>Set</b>
<ul> <ul>
<code>set &lt;name&gt; &lt;value&gt;</code> <code>set &lt;name&gt; &lt;value&gt; [&lt;args&gt;]</code>
<br><br> <br><br>
where <code>value</code> can be e.g.:<br> where <code>value</code> can be e.g.:<br>
<ul><li>for relay <ul><li>dev_circuit<br>
<ul><code> outputs only<br>
off<br> &lt;args&gt;: on, off for outputs and slider for ao<br>
on<br> </li>
</code> <li>clearreadings<br>
</ul> delete all readings
The <a href="#setExtensions"> set extensions</a> are also supported for output devices.<br> </li>
</li> <li>websocket<br>
Other set values depending on the options of the device function. &lt;arg&gt;: open,close<br>
Details can be found in the UniPi Evok documentation. open, close websocket connection
</li>
<li>postjson<br>
&lt;args&gt;: <code>dev circuit type value</code><br>
send JSON command to subdevice<br>
example: <code>set neuron input 1_01 mode simple</code>
</li>
For details please refer to UniPi Evok documentation.
</ul> </ul>
</ul> </ul><br>
<a name="NeuronGet"></a> <a name="NeuronGet"></a>
<b>Get</b> <b>Get</b>
<ul> <ul>
<code>get &lt;name&gt; &lt;value&gt;</code> <code>get &lt;name&gt; &lt;value&gt; [&lt;arg&gt;]</code>
<br><br> <br><br>
where <code>value</code> can be<br> where <code>value</code> can be<br>
<ul> <ul>
<li>refresh: uptates all readings</li> <li>all: refresh all readings</li>
<li>config: returns the configuration JSON</li> <li>config: returns the configuration from the subdevice &lt;arg&gt;</li>
<li>updt_sets_gets: updates all set and get options</li>
<li>value: returns the state from the subdevice &lt;arg&gt;</li>
</ul> </ul>
</ul><br> </ul><br>
@ -896,19 +922,23 @@ sub Neuron_wsMasking($$) {
<ul> <ul>
<li><a name="connection">connection</a><br> <li><a name="connection">connection</a><br>
Set the connection type to the EVOK device<br> Set the connection type to the EVOK device<br>
Default: polling, valid values: websockets, polling<br><br> Default: polling<br>
valid values: websockets, polling<br><br>
</li> </li>
<li><a name="poll_interval">poll_interval</a><br> <li><a name="poll_interval">poll_interval</a><br>
Set the polling interval in minutes to query all readings (and distribute them to logical devices)<br> Set the polling interval in minutes to query all readings (and distribute them to logical devices)<br>
Default: -, valid values: decimal number<br><br> Default: -<br>
valid values: decimal number<br><br>
</li> </li>
<li><a name="wsFilter">wsFilter</a><br> <li><a name="wsFilter">wsFilter</a><br>
Filter to limit the list of devices which should send websocket events<br> Filter to limit the list of devices which should send websocket events<br>
Default: all, valid values: all, ai, ao, input, led, relay, wd<br><br> Default: all<br>
valid values: all, ai, ao, input, led, relay, wd, temp, unit_register<br><br>
</li> </li>
<li><a name="logicalDev">logicalDev</a><br> <li><a name="logicalDev">logicalDev</a><br>
Filter which subdevices should create / communicate with logical device<br> Filter which subdevices should create / communicate with logical device<br>
Default: ao, input, led, relay, valid values: ai, ao, input, led, relay, wd<br><br> Default: ao, input, led, relay<br>
valid values: ai, ao, input, led, relay, wd, temp, unit_register<br><br>
</li> </li>
<li><a href="#readingFnAttributes">readingFnAttributes</a></li> <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
</ul> </ul>
@ -922,13 +952,12 @@ sub Neuron_wsMasking($$) {
<h3>Neuron</h3> <h3>Neuron</h3>
<ul> <ul>
<a name="Neuron"></a> <a name="Neuron"></a>
Modul f&uuml; die Steuerung von Ger&auml;ten auf denen EVOK l&auml;uft z.B. UniPi Neuron. Modul f&uuml;r die Steuerung von Ger&auml;ten auf denen EVOK l&auml;uft z.B. UniPi Neuron.<br>
<br> <br>
<a name="NeuronDefine"></a> <a name="NeuronDefine"></a>
<b>Define</b> <b>Define</b>
<ul> <ul>
<code>define <name> Neuron &lt;IP&gt;[:&lt;Port&gt;]</code><br><br> <code>define <name> Neuron &lt;IP&gt;[:&lt;Port&gt;]</code><br><br>
<br><br>
</ul> </ul>
<a name="NeuronSet"></a> <a name="NeuronSet"></a>
@ -936,12 +965,10 @@ sub Neuron_wsMasking($$) {
<ul> <ul>
<code>set &lt;name&gt; &lt;value&gt; [&lt;args&gt;]</code> <code>set &lt;name&gt; &lt;value&gt; [&lt;args&gt;]</code>
<br><br> <br><br>
clearreadings:noArg websocket:open,close atest postjson Werte f&uuml;r <code>value</code>:<br>
where <code>value</code> can be e.g.:<br>
<ul><li>dev_circuit<br> <ul><li>dev_circuit<br>
nur f&uuml; Ausg&auml;nge<br> nur f&uuml;r Ausg&auml;nge<br>
&lt;args&gt;: on, off f&uuml;r Ausg&auml;nge und Slider f&uumlr ao<br> &lt;args&gt;: on, off f&uuml;r Ausg&auml;nge und Slider f&uumlr ao<br>
<br>
</li> </li>
<li>clearreadings<br> <li>clearreadings<br>
l&ouml;sche alle Readings l&ouml;sche alle Readings
@ -957,17 +984,17 @@ sub Neuron_wsMasking($$) {
</li> </li>
Details dazu sind in der UniPi Evok Dokumentation zu finden. Details dazu sind in der UniPi Evok Dokumentation zu finden.
</ul> </ul>
</ul> </ul><br>
<a name="NeuronGet"></a> <a name="NeuronGet"></a>
<b>Get</b> <b>Get</b>
<ul> <ul>
<code>get &lt;name&gt; &lt;value&gt; [&lt;arg&gt;]</code> <code>get &lt;name&gt; &lt;value&gt; [&lt;arg&gt;]</code>
<br><br> <br><br>
where <code>value</code> can be<br> Werte f&uuml;r <code>value</code>:<br>
<ul> <ul>
<li>all: aktualisiert alle readings</li> <li>all: aktualisiert alle readings</li>
<li>config: gibt das Konfiguration des Subdevices &lt;arg&gt; zur&uuml;ck</li> <li>config: gibt die Konfiguration des Subdevices &lt;arg&gt; zur&uuml;ck</li>
<li>updt_sets_gets: Aktualisierung der Set und Get Auswahllisten</li> <li>updt_sets_gets: Aktualisierung der Set und Get Auswahllisten</li>
<li>value: gibt das Status des Subdevices &lt;arg&gt; zur&uuml;ck</li> <li>value: gibt das Status des Subdevices &lt;arg&gt; zur&uuml;ck</li>
</ul> </ul>
@ -978,19 +1005,23 @@ sub Neuron_wsMasking($$) {
<ul> <ul>
<li><a name="connection">connection</a><br> <li><a name="connection">connection</a><br>
Verbindungsart zum EVOK Device<br> Verbindungsart zum EVOK Device<br>
Standard: polling, g&uuml;ltige Werte: websockets, polling<br><br> Standard: polling<br>
g&uuml;ltige Werte: websockets, polling<br><br>
</li> </li>
<li><a name="poll_interval">poll_interval</a><br> <li><a name="poll_interval">poll_interval</a><br>
Interval in Minuten in dem alle Werte gelesen (und auch an die log. Devices weitergeleitet) werden.<br> Interval in Minuten in dem alle Werte gelesen (und auch an die log. Devices weitergeleitet) werden.<br>
Standard: -, g&uuml;ltige Werte: Dezimalzahl<br><br> Standard: -<br>
g&uuml;ltige Werte: Dezimalzahl<br><br>
</li> </li>
<li><a name="wsFilter">wsFilter</a>wsFilter<br> <li><a name="wsFilter">wsFilter</a>wsFilter<br>
Filter um die liste der Ger&auml;te zu limitieren welche websocket events generieren sollen<br> Filter um die liste der Ger&auml;te zu limitieren welche websocket events generieren sollen<br>
Standard: all, g&uuml;ltige Werte: all, ai, ao, input, led, relay, wd<br><br> Standard: all<br>
g&uuml;ltige Werte: all, ai, ao, input, led, relay, wd, temp, unit_register<br><br>
</li> </li>
<li><a name="logicalDev">logicalDev</a><br> <li><a name="logicalDev">logicalDev</a><br>
Filter um Ger&auml;te zu limitieren die logische Devices anlegen und mit ihnen kommunizieren.<br> Filter um Ger&auml;te zu limitieren die logische Devices anlegen und mit ihnen kommunizieren.<br>
Standard: ao, input, led, relay, g&uuml;ltige Werte: ai, ao, input, led, relay, wd<br><br> Standard: ao, input, led, relay<br>
g&uuml;ltige Werte: ai, ao, input, led, relay, wd, temp, unit_register<br><br>
</li> </li>
<li><a href="#readingFnAttributes">readingFnAttributes</a></li> <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
</ul> </ul>
@ -998,4 +1029,4 @@ sub Neuron_wsMasking($$) {
</ul> </ul>
=end html_DE =end html_DE
=cut =cut

View File

@ -7,6 +7,7 @@ package main;
use strict; use strict;
use warnings; use warnings;
use SetExtensions; use SetExtensions;
use Encode qw(decode encode);
my %sets = ( my %sets = (
'on' => 1, 'on' => 1,
@ -40,11 +41,28 @@ sub NeuronPin_Initialize($) {
sub NeuronPin_Define($$) { sub NeuronPin_Define($$) {
my ($hash, $def) = @_; my ($hash, $def) = @_;
my @a = split('[ \t][ \t]*', $def); my @a = split('[ \t][ \t]*', $def);
# hier fehlt noch Überprüfung der Attribute if (scalar(@a) == 4) {
$modules{NeuronPin}{defptr}{$a[2]." ".$a[3]} = $hash; #altes Define (enthält noch nicht den Namen vom IODev), untauglich für mehrere Neurons
return "$hash->{NAME} Pintype not valid" unless ($a[2] =~ /^(input|relay|ai|ao|led|temp|wd)$/ ); $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 <name> NeuronPin <dev> <circuit> <Neuron IODev>";
}
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]; $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->{CIRCUIT} = $a[3];
$hash->{STATE} = "defined"; $hash->{STATE} = "defined";
@ -57,12 +75,10 @@ sub NeuronPin_Define($$) {
sub NeuronPin_Init($$) { sub NeuronPin_Init($$) {
my ( $hash, $args ) = @_; my ( $hash, $args ) = @_;
unless (defined $args && int(@$args) == 2) { unless (defined $args && int(@$args) >= 2) {
return "Define: Wrong syntax. Usage:\n" . return "Define: Wrong syntax. Usage:\n" .
"define <name> NeuronPin <dev> <circuit>"; "define <name> NeuronPin <dev> <circuit> <Neuron IODev>";
} }
AssignIoPort($hash);
#$hash->{STATE} = 'Initialized';
if (ReadingsVal($hash->{NAME}, '.conf', '')) { if (ReadingsVal($hash->{NAME}, '.conf', '')) {
NeuronPin_CreateSets($hash); NeuronPin_CreateSets($hash);
if (AttrVal($hash->{NAME},"restoreOnStartup",'')) { if (AttrVal($hash->{NAME},"restoreOnStartup",'')) {
@ -72,7 +88,8 @@ sub NeuronPin_Init($$) {
} }
} else { } else {
return if(IsDisabled($hash->{NAME})); 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',''); $hash->{STATE} = ReadingsVal($hash->{NAME},'state','') if ReadingsVal($hash->{NAME},'state','');
return undef; return undef;
@ -90,7 +107,6 @@ sub NeuronPin_Catch($) {
sub NeuronPin_State($$$$) { #reload readings at FHEM start sub NeuronPin_State($$$$) { #reload readings at FHEM start
my ($hash, $tim, $sname, $sval) = @_; my ($hash, $tim, $sname, $sval) = @_;
#Log3 $hash, 5, "$hash->{TYPE} ($hash->{NAME}): $sname kann auf $sval wiederhergestellt werden $tim"; #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 ne "STATE" && (my $pval = AttrVal($hash->{NAME},"restoreOnStartup",'')) && $hash->{DEV} =~ /relay|ao/ ) {
if ($sname eq "state") { if ($sname eq "state") {
if ($pval eq 'on' || $pval eq 'off' || looks_like_number($pval)) { 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 ($$) { sub NeuronPin_Parse ($$) {
my ( $io_hash, $message) = @_; my ( $io_hash, $message) = @_;
my $port = $message->{dev}." ".$message->{circuit}; my $port = $message->{dev}." ".$message->{circuit};
Log3 (undef, 4, "NeuronPin_Parse von $io_hash->{NAME} empfangen:\n" . encode_json $message);
Log3 (undef, 4, "NeuronPin_Parse von $io_hash->{NAME} empfangen: " . encode_json $message);
if (my $hash = $modules{NeuronPin}{defptr}{$port}) { if (my $hash = $modules{NeuronPin}{defptr}{$port}) {
my $value = $message->{value}; foreach my $dev (devspec2array("TYPE=Neuron")) {
# zusätzliche Daten als Internal Log3 (undef, 1, "NeuronPin_Parse Neuron Device gefunden: " . InternalVal($dev,"NAME","") );
$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}; if (my $hash = $modules{NeuronPin}{defptr}{$port ." ". $io_hash->{NAME}}) {
$value = $rsets{$value} if ($message->{dev} eq 'input' || $message->{dev} eq 'relay' || $message->{dev} eq 'led'); NeuronPin_TransferVals ($hash, $message);
readingsBeginUpdate($hash); } elsif (my $hash = $modules{NeuronPin}{defptr}{$port}) {
readingsBulkUpdate($hash,"state",$value); Log3 (undef, 1, "NeuronPin_Parse from $io_hash->{NAME} to $hash->{NAME} : incomplete Define");
readingsBulkUpdate($hash,"dim",$value) if $message->{dev} eq 'ao'; NeuronPin_TransferVals ($hash, $message);
} else {
# my @readings = ("mode","unit","range","debounce","counter","counter_mode","alias","pwm_freq","pwm_duty","temp","humidity","vdd","vad"); Log3 ($hash, 4, "NeuronPin_Parse von $io_hash->{NAME} nothing found...create logical device");
# foreach (@readings){ return "UNDEFINED $io_hash->{NAME}_".$message->{dev}."_".$message->{circuit}." NeuronPin " . $port . " " . $io_hash->{NAME};
# if (exists($message->{$_})) { }
# readingsBulkUpdate($hash,"Z_".$_,$message->{$_}); }
# } else {
# readingsDelete($hash, "Z_".$_);
# }
# }
my @skipreadings = split(',', AttrVal($hash->{NAME}, 'skipreadings', "relay_type,typ,dev,circuit,glob_dev_id,value,pending") ); sub NeuronPin_TransferVals ($$) {
foreach (keys %{$hash->{READINGS}}) { my ( $hash, $message) = @_;
#next if substr($_,0,2) eq "Z_"; my @skipreadings = split(',', AttrVal($hash->{NAME}, 'skipreadings', "relay_type,typ,dev,circuit,glob_dev_id,pending") );
readingsDelete($hash, $_) unless exists($message->{$_}) || $_ eq "state" || $_ eq ".conf" || $_ eq "dim"; 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 # $value = $rsets{$value} if ($message->{dev} eq 'input' || $message->{dev} eq 'relay' || $message->{dev} eq 'led');
readingsDelete($hash, $key); # unless ( $value == 0 || $value == 1 ) {
} elsif ($key eq 'alias') { # al_ am Anfang von alias weg # $value = sprintf('%.2f', $value);
# my $alias = (split '_', $message->{$key})[1]; # $value =~ s/\.(?:|.*[^0]\K)0*\z//;
my @aliases = (split '_', $message->{$key}); # $value =~ s/^-0$/0/;
my $alias = join(" ",@aliases[1 .. $#aliases]); # }
readingsBulkUpdate($hash,$key,$alias);
# autocreate alias attribute readingsBeginUpdate($hash);
if (AttrVal($hash->{NAME}, 'alias', '?') ne $alias && defined AttrVal($hash->{NAME}, 'autoalias', '')) { readingsBulkUpdate($hash,"state", $value . $unit );
my $msg = CommandAttr(undef, $hash->{NAME} . " alias $alias"); readingsBulkUpdate($hash,"dim",$value) if $message->{dev} eq 'ao';
Log3 ($hash, 2, "$hash->{TYPE} ($hash->{NAME}): Error creating alias $msg") if ($msg);
} foreach (keys %{$hash->{READINGS}}) {
}else { #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}); 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($) { sub NeuronPin_RereadPin($) {
my ($hash) = @_; my ($hash) = @_;
return if(IsDisabled($hash->{NAME})); return if(IsDisabled($hash->{NAME}));
IOWrite( $hash, split(" ", $hash->{DEF}) ); IOWrite($hash, $hash->{DEV}, $hash->{CIRCUIT});
} }
sub NeuronPin_Attr (@) { 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") ); my @freesets = split(';', AttrVal($hash->{NAME}, 'ownsets', "debounce;counter;interval;pwm_freq;pwm_duty:slider,0,0.1,100") );
foreach (@freesets) { foreach (@freesets) {
@ -294,13 +336,11 @@ sub NeuronPin_Set($@) {
my $cmd = $a[1]; my $cmd = $a[1];
my $arg = $a[2]; 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(!defined($hash->{HELPER}{SETS}{$cmd})) {
if (my $setlist = $hash->{HELPER}{SET}) { if (my $setlist = $hash->{HELPER}{SET}) {
return SetExtensions($hash, $setlist, @a) ; return SetExtensions($hash, $setlist, @a) ;
#return 'Unknown argument ' . $cmd . ', choose one of ' . $setlist;
} }
return undef return undef
} elsif ($cmd eq "dim") { } elsif ($cmd eq "dim") {
@ -323,20 +363,17 @@ sub NeuronPin_Set($@) {
$arguments[2] = $cmd; $arguments[2] = $cmd;
$arguments[3] = $arg; $arguments[3] = $arg;
} }
#$hash->{HELPER}{SETREQ} = 1;
#my @arguments = (split(" ",$hash->{DEF}),$sets{$cmd});
return if(IsDisabled($hash->{NAME})); return if(IsDisabled($hash->{NAME}));
IOWrite($hash, @arguments); IOWrite($hash, @arguments);
} }
sub NeuronPin_Get($@) { sub NeuronPin_Get($@) {
my ($hash, $name, $cmd, @args) = @_; my ($hash, $name, $cmd, @args) = @_;
my @arguments = ($hash->{DEV}, $hash->{CIRCUIT});
if ($cmd && $cmd eq "refresh") { if ($cmd && $cmd eq "refresh") {
my @arguments = (split " ", $hash->{DEF});
return if(IsDisabled($hash->{NAME})); return if(IsDisabled($hash->{NAME}));
IOWrite($hash, @arguments); IOWrite($hash, @arguments);
} elsif ($cmd && $cmd eq "config") { } elsif ($cmd && $cmd eq "config") {
my @arguments = (split " ", $hash->{DEF});
$hash->{HELPER}{CL} = $hash->{CL}; $hash->{HELPER}{CL} = $hash->{CL};
return if(IsDisabled($hash->{NAME})); return if(IsDisabled($hash->{NAME}));
IOWrite($hash, @arguments); IOWrite($hash, @arguments);
@ -353,17 +390,20 @@ sub NeuronPin_Undef($$) {
return undef; return undef;
} }
#sub NeuronPin_DbLog_splitFn($) { sub NeuronPin_DbLog_splitFn($) {
# my ($event) = @_; my ($event) = @_;
# Log3 undef, 5, "in DbLog_splitFn empfangen: $event"; Log3 undef, 5, "in NeuronPin DbLog_splitFn empfangen: $event";
# my ($reading, $value, $unit) = ""; my ($reading, $value, $unit) = "";
# my @parts = split(/ /,$event); my @parts = split(/ /,$event);
# $reading = shift @parts; $reading = shift @parts;
# $reading =~ tr/://d; $reading =~ tr/://d;
# $value = $parts[0]; $unit = ''; # ReadingsVal($hash->{NAME},'unit','');
# $unit = "V" if(lc($reading) =~ m/spannung/); if ($reading eq "value" && $unit) {
# return ($reading, $value, $unit); $value = $parts[0];
#} Log3 undef, 3, "in NeuronPin DbLog_splitFn empfangen: $event, return: |$reading|$value|$unit|";
return ($reading, $value, $unit);
}
}
1; 1;
@ -383,14 +423,15 @@ sub NeuronPin_Undef($$) {
<a name="NeuronPinDefine"></a> <a name="NeuronPinDefine"></a>
<b>Define</b> <b>Define</b>
<ul> <ul>
<code>define <name> NeuronPin &lt;dev&gt; &lt;circuit&gt;</code><br><br> <code>define <name> NeuronPin &lt;dev&gt; &lt;circuit&gt; &lt;Neuron IODev&gt;</code><br><br>
&lt;dev&gt; is an device type like input, ai (analog input), relay (digital output) etc.<br> &lt;dev&gt; is an device type like input, ai (analog input), relay (digital output) etc.<br>
&lt;circuit&gt; ist the number of the device. &lt;circuit&gt; is the number of the device.<br>
&lt;Neuron IODev&gt; is the EVOK device where this subdevice is connected
<br><br> <br><br>
Example: Example:
<pre> <pre>
define NeuronPin_relay_2_01 NeuronPin relay 2_01 define NeuronPin_relay_2_01 NeuronPin relay 2_01 Neuron1
</pre> </pre>
</ul> </ul>
@ -411,7 +452,7 @@ sub NeuronPin_Undef($$) {
</ul> </ul>
Other set values depending on the options of the device function. Other set values depending on the options of the device function.
Details can be found in the UniPi Evok documentation. Details can be found in the UniPi Evok documentation.
</ul> </ul><br>
<a name="NeuronPinGet"></a> <a name="NeuronPinGet"></a>
<b>Get</b> <b>Get</b>
@ -430,27 +471,33 @@ sub NeuronPin_Undef($$) {
<ul> <ul>
<li><a name="poll_interval">poll_interval</a><br> <li><a name="poll_interval">poll_interval</a><br>
Set the polling interval in minutes to query all readings<br> Set the polling interval in minutes to query all readings<br>
Default: -, valid values: decimal number<br><br> Default: -<br>
valid values: decimal number<br><br>
</li> </li>
<li><a name="restoreOnStartup">restoreOnStartup</a><br> <li><a name="restoreOnStartup">restoreOnStartup</a><br>
Restore Readings and sets after reboot<br> Restore Readings and sets after reboot<br>
Default: last, valid values: last, on, off, no<br><br> Default: last<br>
valid values: last, on, off, no<br><br>
</li> </li>
<li><a name="aomax">aomax</a><br> <li><a name="aomax">aomax</a><br>
Maximum value for the slider from the analog output ports<br> Maximum value for the slider from the analog output ports<br>
Default: 10, valid values: decimal number<br><br> Default: 10<br>
valid values: decimal number<br><br>
</li> </li>
<li><a name="skipreadings">skipreadings</a><br> <li><a name="skipreadings">skipreadings</a><br>
Values which will be sent from the Device and which shall not be listed as readings<br> Values which will be sent from the Device and which shall not be listed as readings<br>
Default: relay_type,typ,dev,circuit,glob_dev_id,value,pending; valid values: comma separated list<br><br> Default: relay_type,typ,dev,circuit,glob_dev_id,value,pending<br>
valid values: comma separated list<br><br>
</li> </li>
<li><a name="ownsets">ownsets</a><br> <li><a name="ownsets">ownsets</a><br>
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<br> 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<br>
Default: debounce;counter;interval;pwm_freq;pwm_duty:slider,0,0.1,100 valid values: semicolon separated list<br><br> Default: debounce;counter;interval;pwm_freq;pwm_duty:slider,0,0.1,100<br>
valid values: semicolon separated list<br><br>
</li> </li>
<li><a name="autoalias">autoalias</a><br> <li><a name="autoalias">autoalias</a><br>
If set to 1, reading alias will automatically change the attribute "alias"<br> If set to 1, reading alias will automatically change the attribute "alias"<br>
Default: 0, valid values: 0,1<br><br> Default: 1<br>
valid values: 0,1<br><br>
</li> </li>
<li><a href="#IODev">IODev</a></li> <li><a href="#IODev">IODev</a></li>
<li><a href="#readingFnAttributes">readingFnAttributes</a></li> <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
@ -469,20 +516,21 @@ sub NeuronPin_Undef($$) {
<h3>NeuronPin</h3> <h3>NeuronPin</h3>
<ul> <ul>
<a name="NeuronPin"></a> <a name="NeuronPin"></a>
Logisches Modul f&uuml; Ger&auml;te auf denen EVOK l&auml;uft. Logisches Modul f&uuml;r Ger&auml;te auf denen EVOK l&auml;uft.
Diese werden automatisch vom <a href="#Neuron"> Neuron</a> Modul angelegt. Diese werden automatisch vom <a href="#Neuron"> Neuron</a> Modul angelegt.
<br> <br>
<a name="NeuronPinDefine"></a> <a name="NeuronPinDefine"></a>
<b>Define</b> <b>Define</b>
<ul> <ul>
<code>define <name> NeuronPin &lt;dev&gt; &lt;circuit&gt;</code><br><br> <code>define <name> NeuronPin &lt;dev&gt; &lt;circuit&gt; &lt;Neuron IODev&gt;</code><br><br>
&lt;dev&gt; ist der Typ des Subdevices/Pins z.B. input, ai (analoger Eingang), relay (digitaler Ausgang) etc.<br> &lt;dev&gt; ist der Typ des Subdevices/Pins z.B. input, ai (analoger Eingang), relay (digitaler Ausgang) etc.<br>
&lt;circuit&gt; ist die Nummer des Subdevices/Pins. &lt;circuit&gt; ist die Nummer des Subdevices/Pins.<br>
&lt;Neuron IODev&gt; ist der Name des EVOK Devices zu dem dieses Subdevice geh&ouml;rt.
<br><br> <br><br>
Beispiel: Beispiel:
<pre> <pre>
define NeuronPin_relay_2_01 NeuronPin relay 2_01 define NeuronPin_relay_2_01 NeuronPin relay 2_01 Neuron1
</pre> </pre>
</ul> </ul>
@ -503,7 +551,7 @@ sub NeuronPin_Undef($$) {
</ul> </ul>
Weitere set values sind abh&auml;ngig von den jeweiligen Subdevice Funktionen. Weitere set values sind abh&auml;ngig von den jeweiligen Subdevice Funktionen.
Details dazu sind in der UniPi Evok Dokumentation zu finden. Details dazu sind in der UniPi Evok Dokumentation zu finden.
</ul> </ul><br>
<a name="NeuronPinGet"></a> <a name="NeuronPinGet"></a>
<b>Get</b> <b>Get</b>
@ -522,27 +570,33 @@ sub NeuronPin_Undef($$) {
<ul> <ul>
<li><a name="poll_interval">poll_interval</a><br> <li><a name="poll_interval">poll_interval</a><br>
Interval in Minuten in dem alle Werte gelesen werden.<br> Interval in Minuten in dem alle Werte gelesen werden.<br>
Standard: -, g&uuml;ltige Werte: Dezimalzahl<br><br> Standard: -<br>
g&uuml;ltige Werte: Dezimalzahl<br><br>
</li> </li>
<li><a name="restoreOnStartup">restoreOnStartup</a><br> <li><a name="restoreOnStartup">restoreOnStartup</a><br>
Readings nach Neustart wiederherstellen<br> Readings nach Neustart wiederherstellen<br>
Standard: last, g&uuml;ltige Werte: last, on, off<br><br> Standard: last<br>
g&uuml;ltige Werte: last, on, off<br><br>
</li> </li>
<li><a name="aomax">aomax</a><br> <li><a name="aomax">aomax</a><br>
Maxwert f&uuml;r den Schieberegler beim Analogen Ausgang<br> Maxwert f&uuml;r den Schieberegler beim Analogen Ausgang<br>
Standard: 10, g&uuml;ltige Werte: Dezimalzahl<br><br> Standard: 10<br>
g&uuml;ltige Werte: Dezimalzahl<br><br>
</li> </li>
<li><a name="skipreadings">skipreadings</a><br> <li><a name="skipreadings">skipreadings</a><br>
Werte, die vom Ger&auml;t gesendet, aber nicht als Reading dargestellt werden sollen.<br> Werte, die vom Ger&auml;t gesendet, aber nicht als Reading dargestellt werden sollen.<br>
Standard: relay_type,typ,dev,circuit,glob_dev_id,value,pending; g&uuml;ltige Werte: kommaseparierte Liste<br><br> Standard: relay_type,typ,dev,circuit,glob_dev_id,value,pending<br>
g&uuml;ltige Werte: kommaseparierte Liste<br><br>
</li> </li>
<li><a name="ownsets">ownsets</a><br> <li><a name="ownsets">ownsets</a><br>
Werte, die vom Ger&auml;t gesendet, und &uuml;ber set ver&auml;ndert werden k&ouml;nnen. Schickt das Ger&auml;t feste Auswahllisten f&uuml;r einen Wert dann werden die sets automatisch angelegt.<br> Werte, die vom Ger&auml;t gesendet, und &uuml;ber set ver&auml;ndert werden k&ouml;nnen. Schickt das Ger&auml;t feste Auswahllisten f&uuml;r einen Wert dann werden die sets automatisch angelegt.<br>
Standard: debounce;counter;interval;pwm_freq;pwm_duty:slider,0,0.1,100; g&uuml;ltige Werte: semikolonseparierte Liste<br><br> Standard: debounce;counter;interval;pwm_freq;pwm_duty:slider,0,0.1,100<br>
g&uuml;ltige Werte: semikolonseparierte Liste<br><br>
</li> </li>
<li><a name="autoalias">autoalias</a><br> <li><a name="autoalias">autoalias</a><br>
Wenn auf 1 wird das reading alias automatisch als Attribut alias gesetzt.<br> Wenn auf 1 wird das reading alias automatisch als Attribut alias gesetzt.<br>
Standard: 0, g&uuml;ltige Werte: 0,1<br><br> Standard: 1<br>
g&uuml;ltige Werte: 0,1<br><br>
</li> </li>
<li><a href="#IODev">IODev</a></li> <li><a href="#IODev">IODev</a></li>
<li><a href="#readingFnAttributes">readingFnAttributes</a></li> <li><a href="#readingFnAttributes">readingFnAttributes</a></li>