52_I2C_PCF8574.pm 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. ##############################################
  2. # $Id: 52_I2C_PCF8574.pm 13601 2017-03-05 01:36:56Z klausw $
  3. package main;
  4. use strict;
  5. use warnings;
  6. use SetExtensions;
  7. use Scalar::Util qw(looks_like_number);
  8. my %setsP = (
  9. 'off' => 0,
  10. 'on' => 1,
  11. );
  12. sub I2C_PCF8574_Initialize($) {
  13. my ($hash) = @_;
  14. #$hash->{Match} = ".*";
  15. $hash->{DefFn} = "I2C_PCF8574_Define";
  16. $hash->{InitFn} = 'I2C_PCF8574_Init';
  17. $hash->{AttrFn} = "I2C_PCF8574_Attr";
  18. $hash->{SetFn} = "I2C_PCF8574_Set";
  19. $hash->{StateFn} = "I2C_PCF8574_State";
  20. $hash->{GetFn} = "I2C_PCF8574_Get";
  21. $hash->{UndefFn} = "I2C_PCF8574_Undef";
  22. #$hash->{ParseFn} = "I2C_PCF8574_Parse";
  23. $hash->{I2CRecFn} = "I2C_PCF8574_I2CRec";
  24. $hash->{AttrList} = "IODev do_not_notify:1,0 ignore:1,0 showtime:1,0 ".
  25. "poll_interval OnStartup ".
  26. "InputPorts:multiple-strict,0,1,2,3,4,5,6,7 ".
  27. "InvrtPorts:multiple-strict,0,1,2,3,4,5,6,7 ".
  28. "$readingFnAttributes";
  29. }
  30. ###################################
  31. sub I2C_PCF8574_Set($@) { #
  32. my ($hash, @a) = @_;
  33. my $name =$a[0];
  34. my $cmd = $a[1];
  35. my $val = $a[2];
  36. my %sendpackage = ( i2caddress => $hash->{I2C_Address}, direction => "i2cwrite" );
  37. if ( $cmd && $cmd =~ m/^P(ort|)((0|)[0-7])(,(P|)(ort|)((0|)[0-7])){0,7}$/i) {
  38. return "wrong value: $val for \"set $name $cmd\" use one of: off, on"
  39. unless(exists($setsP{$val}));
  40. my @scmd = split(",", $cmd);
  41. my $scms = 0;
  42. my $msg = undef;
  43. foreach (@scmd) {
  44. $_ =~ tr/[a-zA-Z]//d; #Nummer aus String extrahieren
  45. $msg .= (defined $msg ? "," : "") . "Port" . $_ if ( ((1 << $_) & $hash->{helper}{InputPorts}) != 0 ); #Pruefen ob entsprechender Port Input ist
  46. $scms |= 1 << $_;
  47. #Log3 $hash, 1, "$hash->{NAME} test: $_|$scms|@scmd|";
  48. }
  49. return "$name error: $msg is defined as input" if $msg;
  50. my $sbyte = 0;
  51. foreach (0..7) {
  52. #if ($_ ~~ @inports) { #Port der als Input konfiguriert ist wird auf 1 gesetzt
  53. ##if ( grep { $_ eq $clientAddress} @inports ) { #test
  54. # $sbyte += 1 << (1 * $_);
  55. #} elsif( $_ ~~ @scmd ) { #Port der geaendert werden soll
  56. # $sbyte += $setsP{$val} << (1 * $_);
  57. #} else { #alle anderen Portwerte werden den Readings entnommen
  58. # $sbyte += $setsP{ReadingsVal($name,'Port'.$_,"off")} << (1 * $_); #->sonst aus dem Reading holen
  59. #}
  60. if( ((1 << $_) & $scms) != 0 ) { #Port der geaendert werden soll
  61. $sbyte += $setsP{$val} << (1 * $_);
  62. Log3 $hash, 5, "$hash->{NAME} Port$_ soll auf $val gesetzt werden";
  63. } else { #alle anderen Portwerte werden den Readings entnommen
  64. $sbyte += $setsP{ReadingsVal($name,'Port'.$_,"off")} << (1 * $_); #->sonst aus dem Reading holen
  65. }
  66. }
  67. $sendpackage{data} = $sbyte;
  68. } elsif ( $cmd && $cmd eq "setfromreading" ) {
  69. my $sbyte = 0;
  70. foreach (0..7) {
  71. #if ($_ ~~ @inports) { #Port der als Input konfiguriert ist wird auf 1 gesetzt
  72. # $sbyte += 1 << (1 * $_);
  73. #} else { #alle anderen Portwerte werden den Readings entnommen
  74. $sbyte += $setsP{ReadingsVal($name,'Port'.$_,"off")} << (1 * $_);
  75. #}
  76. }
  77. $sendpackage{data} = $sbyte;
  78. } else {
  79. my $list = undef;
  80. foreach (0..7) {
  81. #next if ( $_ ~~ @inports ); #Inputs ueberspringen
  82. next if ( ((1 << $_) & $hash->{helper}{InputPorts}) != 0 ); #Inputs ueberspringen ohne Smartmatch
  83. $list .= "Port" . $_ . ":" . join(',', (sort { $setsP{ $a } <=> $setsP{ $b } } keys %setsP) ) . " ";
  84. }
  85. return "Unknown argument $a[1], choose one of " . $list if defined $list;
  86. return "Unknown argument $a[1]";
  87. }
  88. Log3 $hash, 5, "$hash->{NAME} Output: 0b" . sprintf("%08b",$sendpackage{data});
  89. Log3 $hash, 5, "$hash->{NAME} Inverts: 0b" . sprintf("%08b",$hash->{helper}{InvrtPorts});
  90. Log3 $hash, 5, "$hash->{NAME} Inputs: 0b" . sprintf("%08b",$hash->{helper}{InputPorts});
  91. $sendpackage{data} = ($sendpackage{data} ^ ($hash->{helper}{InvrtPorts} ||= 0) ) | ($hash->{helper}{InputPorts} ||= 0);
  92. Log3 $hash, 5, "$hash->{NAME} Result: 0b" . sprintf("%08b",$sendpackage{data});
  93. return "$name: no IO device defined" unless ($hash->{IODev});
  94. my $phash = $hash->{IODev};
  95. my $pname = $phash->{NAME};
  96. CallFn($pname, "I2CWrtFn", $phash, \%sendpackage);
  97. I2C_PCF8574_Get($hash, $name) if $phash->{TYPE} ne "RPII2C"; # Bei allen IODevs ausser RPII2C Daten zuruecklesen, da diese sondt nicht aktualisiert werden
  98. #Log3 $hash, 1, "$hash->{NAME} IODev Typ: $phash->{TYPE}";
  99. #%sendpackage = ();
  100. #%sendpackage = ( i2caddress => $hash->{I2C_Address}, direction => "i2cread");
  101. #CallFn($pname, "I2CWrtFn", $phash, \%sendpackage);
  102. return undef;
  103. }
  104. ###################################
  105. sub I2C_PCF8574_Get($@) {
  106. my ($hash, @a) = @_;
  107. my $name =$a[0];
  108. my %sendpackage = ();
  109. #%sendpackage = ( direction => "i2cread", id => (defined( $hash->{ID} )? $hash->{ID} : "00"), i2caddress => $hash->{I2C_Address});
  110. %sendpackage = ( i2caddress => $hash->{I2C_Address}, direction => "i2cread");
  111. return "$name: no IO device defined" unless ($hash->{IODev});
  112. my $phash = $hash->{IODev};
  113. my $pname = $phash->{NAME};
  114. CallFn($pname, "I2CWrtFn", $phash, \%sendpackage);
  115. }
  116. ###################################
  117. sub I2C_PCF8574_Attr(@) { #
  118. my ($command, $name, $attr, $val) = @_;
  119. my $hash = $defs{$name};
  120. my $msg = undef;
  121. if ($command && $command eq "set" && $attr && $attr eq "IODev") {
  122. if ($main::init_done and (!defined ($hash->{IODev}) or $hash->{IODev}->{NAME} ne $val)) {
  123. main::AssignIoPort($hash,$val);
  124. my @def = split (' ',$hash->{DEF});
  125. I2C_PCF8574_Init($hash,\@def) if (defined ($hash->{IODev}));
  126. }
  127. }
  128. if ($attr eq 'poll_interval') {
  129. if ( defined($val) ) {
  130. if ( looks_like_number($val) && $val > 0) {
  131. RemoveInternalTimer($hash);
  132. InternalTimer(1, 'I2C_PCF8574_Poll', $hash, 0);
  133. } else {
  134. $msg = "$hash->{NAME}: Wrong poll intervall defined. poll_interval must be a number > 0";
  135. }
  136. } else {
  137. RemoveInternalTimer($hash);
  138. }
  139. } elsif ($attr && $attr eq "InputPorts") {
  140. if ( defined($val) ) {
  141. my @tmp = split(/\D+/, $val);
  142. my $tmpattr;
  143. foreach (@tmp) {
  144. if ($_ =~ /^[0-7]$/) {
  145. $tmpattr += 1 << (1 * $_);
  146. } else {
  147. $msg = "wrong value: $_ for \"attr $name $attr\" use comma separated numbers 0-7";
  148. }
  149. }
  150. $hash->{helper}{$attr} = $tmpattr unless defined $msg;
  151. } else {
  152. $hash->{helper}{$attr} = 0;
  153. }
  154. } elsif ($attr && $attr eq "InvrtPorts") {
  155. if ( defined($val) ) {
  156. my @tmp = split(/\D+/, $val);
  157. my $tmpattr;
  158. foreach (@tmp) {
  159. if ($_ =~ /^[0-7]$/) {
  160. $tmpattr += 1 << (1 * $_);
  161. } else {
  162. $msg = "wrong value: $_ for \"attr $name $attr\" use comma separated numbers 0-7";
  163. }
  164. }
  165. $hash->{helper}{$attr} = $tmpattr unless defined $msg;
  166. } else {
  167. #delete $hash->{helper}{$attr} if defined $hash->{helper}{$attr};
  168. $hash->{helper}{$attr} = 0;
  169. }
  170. }elsif ($attr && $attr eq "OnStartup") {
  171. if (defined $val) {
  172. foreach (split (/,/,$val)) {
  173. my @pair = split (/=/,$_);
  174. $msg = "wrong value: $_ for \"attr $hash->{NAME} $attr\" use comma separated <port>=on|off|last where <port> = 0 - 7"
  175. unless ( scalar(@pair) == 2 && ($pair[0] =~ m/^[0-7]$/i && ( $pair[1] eq "last" || exists($setsP{$pair[1]}) ) ) );
  176. }
  177. }
  178. }
  179. return $msg
  180. }
  181. ###################################
  182. sub I2C_PCF8574_Define($$) { #
  183. my ($hash, $def) = @_;
  184. my @a = split("[ \t]+", $def);
  185. $hash->{STATE} = 'defined';
  186. $hash->{helper}{InvrtPorts} = 0;
  187. $hash->{helper}{InputPorts} = 0;
  188. if ($main::init_done) {
  189. eval { I2C_PCF8574_Init( $hash, [ @a[ 2 .. scalar(@a) - 1 ] ] ); };
  190. return I2C_PCF8574_Catch($@) if $@;
  191. }
  192. return undef;
  193. }
  194. ###################################
  195. sub I2C_PCF8574_Init($$) { #
  196. my ( $hash, $args ) = @_;
  197. #my @a = split("[ \t]+", $args);
  198. my $name = $hash->{NAME};
  199. if (defined $args && int(@$args) != 1) {
  200. return "Define: Wrong syntax. Usage:\n" .
  201. "define <name> I2C_PCA9532 <i2caddress>";
  202. }
  203. if (defined (my $address = shift @$args)) {
  204. $hash->{I2C_Address} = $address =~ /^0.*$/ ? oct($address) : $address;
  205. } else {
  206. return "$name I2C Address not valid";
  207. }
  208. AssignIoPort($hash);
  209. $hash->{STATE} = 'Initialized';
  210. I2C_PCF8574_Set($hash, $name, "setfromreading");
  211. return;
  212. }
  213. ###################################
  214. sub I2C_PCF8574_Catch($) {
  215. my $exception = shift;
  216. if ($exception) {
  217. $exception =~ /^(.*)( at.*FHEM.*)$/;
  218. return $1;
  219. }
  220. return undef;
  221. }
  222. ###################################
  223. sub I2C_PCF8574_State($$$$) { #reload readings at FHEM start
  224. my ($hash, $tim, $sname, $sval) = @_;
  225. Log3 $hash, 4, "$hash->{NAME}: $sname kann auf $sval wiederhergestellt werden $tim";
  226. if ($sname =~ m/^Port[0-7]$/i) {
  227. my $po = $sname; #noch �ndern
  228. $po =~ tr/[a-zA-Z]//d; #Nummer aus String extrahieren
  229. #my @inports = sort(split(/\D+/,AttrVal($hash->{NAME}, "InputPorts", "")));
  230. unless ( ((1 << $po) & $hash->{helper}{InputPorts}) != 0 ) {
  231. my %onstart = split /[,=]/, AttrVal($hash->{NAME}, "OnStartup", "");
  232. if ( exists($onstart{$po}) && exists($setsP{$onstart{$po}})) {
  233. Log3 $hash, 5, "$hash->{NAME}: $sname soll auf $onstart{$po} gesetzt werden";
  234. readingsSingleUpdate($hash,$sname, $onstart{$po}, 1);
  235. } else {
  236. Log3 $hash, 5, "$hash->{NAME}: $sname soll auf Altzustand: $sval gesetzt werden";
  237. $hash->{READINGS}{$sname}{VAL} = $sval;
  238. $hash->{READINGS}{$sname}{TIME} = $tim;
  239. }
  240. } else {
  241. Log3 $hash, 5, "$hash->{NAME}: $sname ist Eingang";
  242. }
  243. }
  244. return undef;
  245. }
  246. ###################################
  247. sub I2C_PCF8574_Undef($$) { #
  248. my ($hash, $name) = @_;
  249. RemoveInternalTimer($hash) if ( defined (AttrVal($hash->{NAME}, "poll_interval", undef)) );
  250. return undef;
  251. }
  252. ###################################
  253. sub I2C_PCF8574_Poll($) { # for attr poll_intervall -> readout pin values
  254. my ($hash) = @_;
  255. I2C_PCF8574_Get($hash, $hash->{NAME}); # Read values
  256. my $pollInterval = AttrVal($hash->{NAME}, 'poll_interval', 0);
  257. InternalTimer(gettimeofday() + ($pollInterval * 60), 'I2C_PCF8574_Poll', $hash, 0) if ($pollInterval > 0);
  258. }
  259. ###################################
  260. sub I2C_PCF8574_I2CRec($@) { # ueber CallFn vom physical aufgerufen
  261. my ($hash, $clientmsg) = @_;
  262. my $name = $hash->{NAME};
  263. my $phash = $hash->{IODev};
  264. my $pname = $phash->{NAME};
  265. while ( my ( $k, $v ) = each %$clientmsg ) { #erzeugen von Internals fuer alle Keys in $clientmsg die mit dem physical Namen beginnen
  266. $hash->{$k} = $v if $k =~ /^$pname/ ;
  267. }
  268. my $sval;
  269. if ($clientmsg->{direction} && $clientmsg->{$pname . "_SENDSTAT"} && $clientmsg->{$pname . "_SENDSTAT"} eq "Ok") {
  270. readingsBeginUpdate($hash);
  271. if ($clientmsg->{direction} eq "i2cread" && defined($clientmsg->{received})) {
  272. readingsBulkUpdate($hash, 'state', $clientmsg->{received});
  273. $clientmsg->{received} ^= $hash->{helper}{InvrtPorts};
  274. foreach (0..7) {
  275. $sval = $clientmsg->{received} & (1 << $_);
  276. $sval = $sval == 0 ? "off" :"on";
  277. readingsBulkUpdate($hash, 'Port'.$_ , $sval) if (ReadingsVal($name,'Port'.$_,"") ne $sval);
  278. }
  279. } elsif ($clientmsg->{direction} eq "i2cwrite" && defined($clientmsg->{data})) {
  280. #my @inports = sort(split( /\D+/,AttrVal($name, "InputPorts", "")));
  281. readingsBulkUpdate($hash, 'state', $clientmsg->{data});
  282. $clientmsg->{data} ^= $hash->{helper}{InvrtPorts};
  283. foreach (0..7) {
  284. $sval = $clientmsg->{data} & (1 << $_);
  285. $sval = $sval == 0 ? "off" :"on";
  286. readingsBulkUpdate($hash, 'Port'.$_ , $sval) unless (ReadingsVal($name,'Port'.$_,"") eq $sval);# || $_ ~~ @inports );
  287. }
  288. }
  289. readingsEndUpdate($hash, 1);
  290. }
  291. }
  292. ###################################
  293. #sub I2C_PCF8574_Parse($$) { #wird ueber dispatch vom physical device aufgerufen (dispatch wird im mom nicht verwendet)
  294. # my ($hash, $msg) = @_;
  295. # my($sid, $addr, @msg) = split(/ /,$msg);
  296. # #Log3 $hash, 4, "Vom Netzerparse $hash->{NAME}: sid: $sid, Msg: @msg";
  297. #
  298. # my $def = $modules{I2C_PCF8574}{defptr}{"$sid $addr"};
  299. # if($def) {
  300. # my @list;
  301. # foreach my $n (keys %{ $def }) {
  302. # my $lh = $def->{$n}; # Hash bekommen
  303. # $n = $lh->{NAME}; # It may be renamed
  304. # return "" if(IsIgnored($n)); # Little strange.
  305. # ################################################
  306. # my $cde = join(" ",@msg);
  307. # my $sval;
  308. # readingsBeginUpdate($lh);
  309. # if ( int(@msg) == 1) {
  310. # for (my $i = 0; $i < 8; $i++) {
  311. # #$sval = hex($cde) & (1 << $i);
  312. # $sval = $cde & (1 << $i);
  313. # $sval = $sval == 0 ? "0" :"1";
  314. # readingsBulkUpdate($lh, 'P'.$i , $sval) if (ReadingsVal($n,'P'.$i,2) ne $sval);
  315. # }
  316. # }
  317. # readingsBulkUpdate($lh, 'state', join(" ", @msg));
  318. # readingsEndUpdate($lh, 1);
  319. # ################################################
  320. # Log3 $n, 4, "I2C_PCF8574 $n $cde";
  321. #
  322. # push(@list, $n);
  323. # }
  324. # return @list;
  325. #
  326. # } else {
  327. # Log3 $hash, 3, "I2C_PCF8574 Unknown device $addr Id $sid";
  328. # #return "UNDEFINED I2C_PCF8574_$addr$sid I2C_PCF8574 $addr $sid";
  329. # }
  330. #
  331. #}
  332. ###################################
  333. 1;
  334. =pod
  335. =item device
  336. =item summary controls/reads GPIOs from an via I2C connected PCF8574 port extender
  337. =item summary_DE steuern/lesen der GPIOs eines &uuml;ber I2C angeschlossenen PCF8574
  338. =begin html
  339. <a name="I2C_PCF8574"></a>
  340. <h3>I2C_PCF8574</h3>
  341. (en | <a href="commandref_DE.html#I2C_PCF8574">de</a>)
  342. <ul>
  343. <a name="I2C_PCF8574"></a>
  344. Provides an interface to the PCA9532 8 channel port extender IC. On Raspberry Pi the Interrupt Pin can be connected to an GPIO and <a href="#RPI_GPIO">RPI_GPIO</a> can be used to get the port values if an interrupt occurs.<br>
  345. The I2C messages are send through an I2C interface module like <a href="#RPII2C">RPII2C</a>, <a href="#FRM">FRM</a>
  346. or <a href="#NetzerI2C">NetzerI2C</a> so this device must be defined first.<br>
  347. <b>attribute IODev must be set</b><br>
  348. <a name="I2C_PCF8574Define"></a><br>
  349. <b>Define</b>
  350. <ul>
  351. <code>define &lt;name&gt; I2C_PCF8574 &lt;I2C Address&gt;</code><br>
  352. where <code>&lt;I2C Address&gt;</code> is without direction bit<br>
  353. </ul>
  354. <a name="I2C_PCF8574Set"></a>
  355. <b>Set</b>
  356. <ul>
  357. <code>set &lt;name&gt; &lt;port[,port[...]]&gt; &lt;value&gt;</code><br><br>
  358. <ul>
  359. <li><code>&lt;port&gt;</code> is one of Port0 to Port7 and <code>&lt;value&gt;</code> is one of:<br>
  360. <ul>
  361. <code>
  362. off<br>
  363. on<br>
  364. </code>
  365. </ul>
  366. </li>
  367. </ul>
  368. <br>
  369. Example:
  370. <ul>
  371. <code>set mod1 Port4 on</code><br>
  372. <code>set mod1 Port4,Port6 off</code><br>
  373. <code>set mod1 Port4,6 on</code><br>
  374. </ul><br>
  375. </ul>
  376. <a name="I2C_PCF8574Get"></a>
  377. <b>Get</b>
  378. <ul>
  379. <code>get &lt;name&gt;</code>
  380. <br><br>
  381. refreshes all readings
  382. </ul><br>
  383. <a name="I2C_PCF8574Attr"></a>
  384. <b>Attributes</b>
  385. <ul>
  386. <li>poll_interval<br>
  387. Set the polling interval in minutes to query the GPIO's level<br>
  388. Default: -, valid values: decimal number<br><br>
  389. </li>
  390. <li>InputPorts<br>
  391. Comma separated list of Portnumers that are used as Inputs<br>
  392. Ports in this list can't be written<br>
  393. Default: -, valid values: 0 - 7<br><br>
  394. </li>
  395. <li>InvrtPorts<br>
  396. Comma separated list of Portnumers that will be inverted<br>
  397. Default: -, valid values: 0 - 7<br><br>
  398. </li>
  399. <li>OnStartup<br>
  400. Comma separated list of output ports and their desired state after start<br>
  401. Without this atribut all output ports will set to last state<br>
  402. Default: -, valid values: &lt;port&gt;=on|off|last where &lt;port&gt; = 0 - 7<br><br>
  403. </li>
  404. <li><a href="#IODev">IODev</a></li>
  405. <li><a href="#ignore">ignore</a></li>
  406. <li><a href="#do_not_notify">do_not_notify</a></li>
  407. <li><a href="#showtime">showtime</a></li>
  408. </ul>
  409. <br>
  410. </ul>
  411. =end html
  412. =begin html_DE
  413. <a name="I2C_PCF8574"></a>
  414. <h3>I2C_PCF8574</h3>
  415. (<a href="commandref.html#I2C_PCF8574">en</a> | de)
  416. <ul>
  417. <a name="I2C_PCF8574"></a>
  418. Erm&ouml;glicht die Verwendung eines PCF8574 I2C 8 Bit Portexenders.
  419. Auf einem Raspberry Pi kann der Interrupt Pin des PCF8574 mit einem GPIO verbunden werden und &uml;ber die Interrupt Funktionen von <a href="#RPI_GPIO">RPI_GPIO</a> l&aml;sst sich dann ein get f&uuml;r den PCF8574 bei Pegel&aml;nderung ausl&oml;sen.<br>
  420. I2C-Botschaften werden &uuml;ber ein I2C Interface Modul wie beispielsweise das <a href="#RPII2C">RPII2C</a>, <a href="#FRM">FRM</a>
  421. oder <a href="#NetzerI2C">NetzerI2C</a> gesendet. Daher muss dieses vorher definiert werden.<br>
  422. <b>Das Attribut IODev muss definiert sein.</b><br>
  423. <a name="I2C_PCF8574Define"></a><br>
  424. <b>Define</b>
  425. <ul>
  426. <code>define &lt;name&gt; I2C_PCF8574 &lt;I2C Address&gt;</code><br>
  427. Der Wert <code>&lt;I2C Address&gt;</code> ist ohne das Richtungsbit<br>
  428. </ul>
  429. <a name="I2C_PCF8574Set"></a>
  430. <b>Set</b>
  431. <ul>
  432. <code>set &lt;name&gt; &lt;port[,port[...]]&gt; &lt;value&gt;</code><br><br>
  433. <ul>
  434. <li><code>&lt;port&gt;</code> kann Port0 bis Port7 annehmen und <code>&lt;value&gt;</code> folgende Werte:<br>
  435. <ul>
  436. <code>
  437. off<br>
  438. on<br>
  439. </code>
  440. </ul>
  441. </li>
  442. </ul>
  443. <br>
  444. Beispiel:
  445. <ul>
  446. <code>set mod1 Port4 on</code><br>
  447. <code>set mod1 Port4,Port6 off</code><br>
  448. <code>set mod1 Port4,6 on</code><br>
  449. </ul><br>
  450. </ul>
  451. <a name="I2C_PCF8574Get"></a>
  452. <b>Get</b>
  453. <ul>
  454. <code>get &lt;name&gt;</code>
  455. <br><br>
  456. Aktualisierung aller Werte
  457. </ul><br>
  458. <a name="I2C_PCF8574Attr"></a>
  459. <b>Attribute</b>
  460. <ul>
  461. <li>poll_interval<br>
  462. Aktualisierungsintervall aller Werte in Minuten.<br>
  463. Standard: -, g&uuml;ltige Werte: Dezimalzahl<br><br>
  464. </li>
  465. <li>InputPorts<br>
  466. Durch Komma getrennte Portnummern die als Inputs genutzt werden.<br>
  467. Ports in dieser Liste k&ouml;nnen nicht geschrieben werden.<br>
  468. Standard: -, g&uuml;ltige Werte: 0 - 7<br><br>
  469. </li>
  470. <li>InvrtPorts<br>
  471. Durch Komma getrennte Portnummern die invertiert werden.<br>
  472. Standard: -, g&uuml;ltige Werte: 0 - 7<br><br>
  473. </li>
  474. <li>OnStartup<br>
  475. Durch Komma getrennte Output Ports und ihr gew&uuml;nschter Status nach dem Start.<br>
  476. Ohne dieses Attribut werden alle Ausg&auml;nge nach dem Start auf den letzten Status gesetzt.<br>
  477. Standard: -, g&uuml;ltige Werte: &lt;port&gt;=on|off|last wobei &lt;port&gt; = 0 - 7<br><br>
  478. </li>
  479. <li><a href="#IODev">IODev</a></li>
  480. <li><a href="#ignore">ignore</a></li>
  481. <li><a href="#do_not_notify">do_not_notify</a></li>
  482. <li><a href="#showtime">showtime</a></li>
  483. </ul>
  484. <br>
  485. </ul>
  486. =end html_DE
  487. =cut