56_POKEYS.pm 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. ################################################################
  2. #
  3. # Copyright notice
  4. #
  5. # (c) 2012 Axel Berner (bikensnow@googlemail.com)
  6. #
  7. # This script is free software; you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation; either version 2 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # The GNU General Public License can be found at
  13. # http://www.gnu.org/copyleft/gpl.html.
  14. # A copy is found in the textfile GPL.txt and important notices to the license
  15. # from the author is found in LICENSE.txt distributed with these scripts.
  16. #
  17. # This script is distributed in the hope that it will be useful,
  18. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. # GNU General Public License for more details.
  21. #
  22. # This copyright notice MUST APPEAR in all copies of the script!
  23. #
  24. ################################################################
  25. ##############################################
  26. package main;
  27. use strict;
  28. use warnings;
  29. use Data::Dumper;
  30. my %POKEYS_IOTYPE = (
  31. "Obsolete" => 0x0100,
  32. "DigIn" => 0x8200,
  33. "DigOut" => 0x8400,
  34. "AdcIn" => 0x0800,
  35. "DigInCtRise" => 0x4001,
  36. "DigInCtFall" => 0x4002,
  37. "ExtDigOut" => 0xEF00,
  38. "GetBasic" => 0xFFFF
  39. );
  40. my %sets = (
  41. "off" => 0,
  42. "on" => 1,
  43. "off-for-timer" => 2,
  44. "on-for-timer" => 3
  45. );
  46. my %gets = (
  47. "Version" => 0,
  48. "DevName" => 1,
  49. "Serial" => 2,
  50. "User" => 3,
  51. "Value" => 4,
  52. "CPUload" => 5
  53. );
  54. sub
  55. POKEYS_Initialize($)
  56. {
  57. my ($hash) = @_;
  58. $hash->{DefFn} = "POKEYS_Define";
  59. # $hash->{UndefFn} = "POKEYS_Undef";
  60. $hash->{SetFn} = "POKEYS_Set";
  61. $hash->{GetFn} = "POKEYS_Get";
  62. $hash->{AttrList} = "loglevel:0,1,2,3,4,5,6"; #info
  63. Log(3,"POKEYS_Initialize OK");
  64. }
  65. sub
  66. POKEYS_Get($@)
  67. {
  68. my ($hash, @a) = @_;
  69. if ( (int(@a) != 2) ) {
  70. return "Wrong syntax: use get <Name> <Type>";
  71. }
  72. if (!defined($gets{$a[1]})) {
  73. return "State \"$a[1]\" not known. Use ".join(",", sort keys %gets);
  74. }
  75. my $Type = $a[1];
  76. my $buf = undef;
  77. if ($hash->{IOTYPE} eq "GetBasic" ) {
  78. if($Type eq "Version") {
  79. $buf = POKEYS_IO($hash, 0x00, 0x00, 0x00, 0x00, 0x00, ""); #get version
  80. if (defined($buf)) {
  81. my ($ReCtrl,$ReOp,$ReOP1,$ReOP2,$ReOP3,$ReOP4,$ReReqId,$Chk,$ReOPX) = unpack("CCCCCCCCH56", "$buf");
  82. Log(3, "Version:".(1+$ReOP3/16).".".($ReOP3%16).".".$ReOP4);
  83. }
  84. }
  85. elsif ($Type eq "Serial") {
  86. $buf = POKEYS_IO($hash, 0x00, 0x00, 0x00, 0x00, 0x00, ""); #get serial number
  87. if (defined($buf)) {
  88. my ($ReCtrl,$ReOp,$ReOP1,$ReOP2,$ReOP3,$ReOP4,$ReReqId,$Chk,$ReOPX) = unpack("CCCCCCCCH56", "$buf");
  89. Log(3, "Serial:".($ReOP1*256+$ReOP2));
  90. }
  91. }
  92. elsif ($Type eq "User") {
  93. $buf = POKEYS_IO($hash, 0x03, 0x00, 0x00, 0x00, 0x00, ""); #get user id
  94. if (defined($buf)) {
  95. my ($ReCtrl,$ReOp,$ReOP1,$ReOP2,$ReOP3,$ReOP4,$ReReqId,$Chk,$ReOPX) = unpack("CCCCCCCCH56", "$buf");
  96. Log(3, "UserId: ".$ReOP1);
  97. }
  98. }
  99. elsif ($Type eq "DevName") {
  100. $buf = POKEYS_IO($hash, 0x06, 0x00, 0x00, 0x00, 0x00, ""); #get device name
  101. if (defined($buf)) {
  102. my ($ReCtrl,$ReOp,$ReOP1,$ReOP2,$ReOP3,$ReOP4,$ReReqId,$Chk,$ReOPX) = unpack("CCCCCCCCH56", "$buf");
  103. Log(3, "Name: ".unpack("A*",pack("H*",$ReOPX)));
  104. }
  105. }
  106. elsif ($Type eq "CPUload") {
  107. $buf = POKEYS_IO($hash, 0x05, 0x00, 0x00, 0x00, 0x00, ""); #get CPU load
  108. if (defined($buf)) {
  109. my ($ReCtrl,$ReOp,$ReOP1,$ReOP2,$ReOP3,$ReOP4,$ReReqId,$Chk,$ReOPX) = unpack("CCCCCCCCH56", "$buf");
  110. Log(3, "CPUload: ".(($ReOP1*100)/256)."%");
  111. }
  112. }
  113. else {
  114. return "Get $Type not supported by GetBasic-Pin";
  115. }
  116. } else {
  117. return "Get function not supported for $hash->{IOTYPE}";
  118. }
  119. return undef;
  120. }
  121. sub
  122. POKEYS_Set($@)
  123. {
  124. my ($hash, @a) = @_;
  125. if ( (int(@a) == 0) #internal call by on/off-for-timer
  126. && (defined($hash->{NEXTSTATE}))) {
  127. $a[1] = $hash->{NEXTSTATE};
  128. delete($hash->{NEXTSTATE});
  129. }
  130. if ( (int(@a) < 2) ) {
  131. return "Wrong syntax: use set <Name> <State> <hold time>" ;
  132. }
  133. if (!defined($sets{$a[1]})) {
  134. return "State \"$a[1]\" not known. Use ".join(",", sort keys %sets);
  135. }
  136. my $State = $sets{$a[1]} % 2;
  137. my $TimerActive = (($a[1] eq "on-for-timer") || ($a[1] eq "off-for-timer"));
  138. my $HoldTime = (defined($a[2])) ? $a[2] : 1;
  139. if ($hash->{IOTYPE} eq "ExtDigOut" ) {
  140. my $p = $hash->{PIN} - 101;
  141. my @extPinArray = (0,0,0,0,0,0,0,0,0,0);
  142. if ($State eq "on") {
  143. $extPinArray[9- int($p/8)] = 2**($p % 8);
  144. } else {
  145. #todo clear
  146. Log(3,"clear not yet supported");
  147. }
  148. #print "@extPinArray\n";
  149. my $pS = unpack("H*", pack("C*", @extPinArray));
  150. #p += 1; print "$p->$pS<-";
  151. my $buf = POKEYS_IO($hash, 0xDA, 0x01, 0x00, 0x00, 0x00, $pS); #set pin config
  152. return "POKEYS_IO error" if (!defined($buf));
  153. my ($ReCtrl,$ReOp,$ReOP1,$ReOP2,$ReOP3,$ReOP4,$ReReqId,$Chk,$ReOPX) = unpack("CCCCCCCCH56", "$buf");
  154. Log(3, "Set ExtPin $hash->{PIN} to $State: $ReOP1 $ReOP2");
  155. $hash->{STATE} = $State;
  156. $hash->{CHANGED}[0] = $State;
  157. DoTrigger($hash->{NAME}, undef);
  158. }
  159. elsif ($hash->{IOTYPE} eq "DigOut"){
  160. my $buf = POKEYS_IO($hash, 0x40, $hash->{PIN}-1, $State, 0x00, 0x00, ""); #set pin config
  161. return "POKEYS_IO error" if (!defined($buf));
  162. my ($ReCtrl,$ReOp,$ReOP1,$ReOP2,$ReOP3,$ReOP4,$ReReqId,$Chk,$ReOPX) = unpack("CCCCCCCCH56", "$buf");
  163. Log(3, "Set Pin $hash->{PIN} to $State: (0=OK) $ReOP1");
  164. $hash->{STATE} = $State;
  165. $hash->{CHANGED}[0] = $State;
  166. DoTrigger($hash->{NAME}, undef);
  167. }
  168. else {
  169. return "Pin is no output";
  170. }
  171. if ($TimerActive != 0) {
  172. $hash->{NEXTSTATE} = ($State == 0) ? "on" : "off";
  173. RemoveInternalTimer($hash); #remove old trigger
  174. InternalTimer(gettimeofday()+ $HoldTime, "POKEYS_Set", $hash, 0);
  175. }
  176. return undef;
  177. }
  178. sub
  179. POKEYS_Define($$)
  180. {
  181. my ($hash, $def) = @_;
  182. my @a = split("[ \t][ \t]*", $def);
  183. if ( (int(@a) < 5) ) {
  184. return "Wrong syntax: use define <name> POKEYS <PokeysName or IP> <Pin> <IOState> <updateTime>" ;
  185. }
  186. #create connection to device
  187. $hash->{POKEYSNAME} = $a[2];
  188. my $err = POKEYS_Connect($hash);
  189. if (defined($err)) {
  190. return "Connect failed: $err";
  191. }
  192. #define pin
  193. $hash->{STATE} = "undefined";
  194. $hash->{PIN} = $a[3];
  195. $hash->{IOTYPE} = $a[4];
  196. $hash->{INTERVAL} = (defined($a[5])) ? $a[5] : 1; #if no time is defined -> default 1sec
  197. $err = POKEYS_PinDefine($hash);
  198. if (defined($err)) {
  199. $hash->{PIN} = undef;
  200. $hash->{IOTYPE} = undef;
  201. $hash->{INTERVAL} = undef;
  202. return "PinDefine failed: $err ";
  203. }
  204. return undef;
  205. }
  206. sub
  207. POKEYS_ReDefine($)
  208. {
  209. my ($hash) = @_;
  210. my $err = POKEYS_Connect($hash);
  211. if (defined($err)) {
  212. #connect failed retry in 5sec
  213. InternalTimer(gettimeofday()+5, "POKEYS_ReDefine", $hash, 0);
  214. return undef;
  215. }
  216. foreach my $d (keys %defs) {
  217. next if ($defs{$d}->{TYPE} ne $hash->{TYPE}); #no POKEYS device
  218. next if ($defs{$d}->{POKEYSNAME} ne $hash->{POKEYSNAME}); #other POKEYS device
  219. # redefine of pin
  220. POKEYS_PinDefine($defs{$d});
  221. }
  222. }
  223. sub
  224. POKEYS_GetIPAdress($)
  225. {
  226. #Log(3, "$PokeysName is found at $Host");
  227. return '192.168.178.34';
  228. }
  229. sub
  230. POKEYS_Connect($)
  231. {
  232. my ($hash) = @_;
  233. if ( (defined($hash->{TYPE}))
  234. && (defined($hash->{POKEYSNAME})
  235. && (defined($modules{$hash->{TYPE}}{$hash->{POKEYSNAME}}))
  236. && ($modules{$hash->{TYPE}}{$hash->{POKEYSNAME}}{STATE} eq "connected"))) {
  237. return undef; #Pokeys is already successfully connected
  238. }
  239. my $PokeysDev = $hash->{TYPE};
  240. my $PokeysName = $hash->{POKEYSNAME};
  241. my $Host;
  242. my $Host_Port = '20055'; #default Port of Pokeys
  243. if ($PokeysName ~~ m/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/ ) {
  244. # Pokeys IP-adress is directly set
  245. $Host = $PokeysName;
  246. } else {
  247. #get Pokeys IP-adrress by UDP broadcast request
  248. $Host = POKEYS_GetIPAdress($PokeysName);
  249. return "PokeysName: $PokeysName does not exist" if (!defined($Host));
  250. }
  251. my $conn = IO::Socket::INET->new(PeerAddr => $Host,
  252. PeerPort => $Host_Port,
  253. Proto => 'tcp');
  254. if($conn) {
  255. Log(3, "Connected to $PokeysName at $conn");
  256. $modules{$PokeysDev}{$PokeysName}{IP} = $Host;
  257. $modules{$PokeysDev}{$PokeysName}{PORT} = $Host_Port;
  258. $modules{$PokeysDev}{$PokeysName}{STATE} = "connected";
  259. $modules{$PokeysDev}{$PokeysName}{TCPDev} = $conn;
  260. } else {
  261. return "Can't connect to $PokeysName at $Host";
  262. }
  263. return undef;
  264. }
  265. sub
  266. POKEYS_PinDefine($)
  267. {
  268. my ($hash) = @_;
  269. return "Pin \"$hash->{PIN}\" no number" if ($hash->{PIN} !~ /[0-9]+$/);
  270. return "IOState \"$hash->{IOTYPE}\" not known. Use ".join(",", sort keys %POKEYS_IOTYPE)
  271. if (!defined($POKEYS_IOTYPE{$hash->{IOTYPE}}));
  272. if ($hash->{IOTYPE} eq "GetBasic") {
  273. return "Pin $hash->{PIN} not supported (0)" if ( $hash->{PIN} != 0);
  274. }
  275. elsif ($hash->{IOTYPE} eq "ExtDigOut") {
  276. return "ExtPin $hash->{PIN} not supported (101-180)" if ( ($hash->{PIN} < 101) || (180 < $hash->{PIN}) );
  277. }
  278. else {
  279. return "Pin $hash->{PIN} not supported (1-55)" if ( ($hash->{PIN} < 1) || (55 < $hash->{PIN}) );
  280. }
  281. if ($hash->{IOTYPE} eq "GetBasic") {
  282. #No config on POKEYS needed
  283. #todo InternalTimer(gettimeofday()+1, "POKEYS_UpdateInputs", $hash, 0); #start cyclic input read
  284. Log(3, "GetBasic device defined");
  285. }
  286. elsif ($hash->{IOTYPE} eq "ExtDigOut") {
  287. #No config on POKEYS needed (Ext is default DigOut)
  288. Log(3, "ExtPin $hash->{PIN} is configured with $hash->{IOTYPE} (0=NOK, 255=OK): 255");
  289. }
  290. else {
  291. my $IOTYPE_HB = $POKEYS_IOTYPE{$hash->{IOTYPE}} / 0xFF;
  292. my $IOTYPE_LB = $POKEYS_IOTYPE{$hash->{IOTYPE}} % 0xFF;
  293. my $buf = POKEYS_IO($hash, 0x10, $hash->{PIN}-1, $IOTYPE_HB, $IOTYPE_LB, 0x00, ""); #0x10 set pin config
  294. return "POKEYS_IO error" if (!defined($buf));
  295. my ($ReCtrl,$ReOp,$ReOP1,$ReOP2,$ReOP3,$ReOP4,$ReReqId,$Chk,$ReOPX) = unpack("CCCCCCCCH56", "$buf");
  296. Log(3, "Pin $hash->{PIN} is configured with $hash->{IOTYPE} (0=NOK, 255=OK): $ReOP1");
  297. if ($hash->{IOTYPE} eq "DigIn") {
  298. RemoveInternalTimer($hash);
  299. InternalTimer(gettimeofday()+$hash->{INTERVAL}, "POKEYS_UpdateDigIn", $hash, 0); #start cyclic DigIn read
  300. }
  301. elsif ($hash->{IOTYPE} eq "AdcIn") {
  302. RemoveInternalTimer($hash);
  303. InternalTimer(gettimeofday()+$hash->{INTERVAL}, "POKEYS_UpdateAdcIn", $hash, 0); #start cyclic AdcIn read
  304. }
  305. elsif ($hash->{IOTYPE} eq "DigInCtRise") {
  306. RemoveInternalTimer($hash);
  307. InternalTimer(gettimeofday()+$hash->{INTERVAL}, "POKEYS_UpdateDigInCt", $hash, 0); #start cyclic DigInCt read
  308. }
  309. elsif ($hash->{IOTYPE} eq "DigInCtFall") {
  310. RemoveInternalTimer($hash);
  311. InternalTimer(gettimeofday()+$hash->{INTERVAL}, "POKEYS_UpdateDigInCt", $hash, 0); #start cyclic DigInCt read
  312. }
  313. else {
  314. # DigOut -> No cyclic update needed
  315. }
  316. }
  317. return undef;
  318. }
  319. sub
  320. POKEYS_UpdateDigIn($)
  321. {
  322. my ($hash) = @_;
  323. InternalTimer(gettimeofday()+$hash->{INTERVAL}, "POKEYS_UpdateDigIn", $hash, 0); #trigger next input read
  324. my $buf = POKEYS_IO($hash, 0x30, $hash->{PIN}-1, 0x00, 0x00, 0x00, ""); #get DigIn
  325. return "POKEYS_IO error" if (!defined($buf));
  326. my ($ReCtrl,$ReOp,$ReOP1,$ReOP2,$ReOP3,$ReOP4,$ReReqId,$Chk,$ReOPX) = unpack("CCCCCCCCH56", "$buf");
  327. if ($ReOP1 == 0) { #Pin state is OK
  328. my $newSTATE = ($ReOP2)? "on":"off";
  329. if ($hash->{STATE} ne $newSTATE) {
  330. $hash->{STATE} = $newSTATE;
  331. $hash->{CHANGED}[0] = $newSTATE;
  332. DoTrigger($hash->{NAME}, undef);
  333. }
  334. } else {
  335. $hash->{STATE} = "Unknown";
  336. }
  337. }
  338. sub
  339. POKEYS_UpdateAdcIn($)
  340. {
  341. my ($hash) = @_;
  342. InternalTimer(gettimeofday()+$hash->{INTERVAL}, "POKEYS_UpdateAdcIn", $hash, 0); #trigger next input read
  343. my $buf = POKEYS_IO($hash, 0x35, $hash->{PIN}-1, 0x00, 0x00, 0x00, ""); #get AdcIn
  344. return "POKEYS_IO error" if (!defined($buf));
  345. my ($ReCtrl,$ReOp,$ReOP1,$ReOP2,$ReOP3,$ReOP4,$ReReqId,$Chk,$ReOPX) = unpack("CCCCCCCCH56", "$buf");
  346. if ($ReOP1 == 0) { #Pin state is OK
  347. my $newSTATE = $ReOP2; #todo cast
  348. if ($hash->{STATE} ne $newSTATE) {
  349. $hash->{STATE} = $newSTATE;
  350. $hash->{CHANGED}[0] = $newSTATE;
  351. DoTrigger($hash->{NAME}, undef);
  352. }
  353. } else {
  354. $hash->{STATE} = "Unknown";
  355. }
  356. }
  357. sub
  358. POKEYS_IO($$$$$$$)
  359. {
  360. my ($hash, $SendOperation, $SOP1, $SOP2, $SOP3, $SOP4, $SOPX) = @_;
  361. if ($modules{$hash->{TYPE}}{$hash->{POKEYSNAME}}{STATE} ne "connected") {
  362. return undef;
  363. }
  364. my $conn = $modules{$hash->{TYPE}}{$hash->{POKEYSNAME}}{TCPDev};
  365. if (!defined($conn)) {
  366. Log(3, "POKEYS_IO: No handle (TCPDev) defined");
  367. POKEYS_Disconnect($hash);
  368. return undef;
  369. }
  370. my $SendControl = 0xBB;
  371. my $SendRequestId = 0x05; #todo random
  372. my $SChk = ($SendControl + $SendOperation + $SOP1 + $SOP2 + $SOP3 + $SOP4 + $SendRequestId) % 0x100;
  373. # add 8 bytes, plus string (max 56byte) and rest filled with zero
  374. my $msg = pack ("CCCCCCCCH112",$SendControl,$SendOperation,$SOP1, $SOP2, $SOP3, $SOP4,$SendRequestId,$SChk,$SOPX);
  375. my $res = syswrite($conn, $msg);
  376. if (!defined($res)) {
  377. Log(3, "POKEYS_IO write error");
  378. POKEYS_Disconnect($hash);
  379. return undef;
  380. }
  381. my $bufRaw;
  382. $res = sysread($conn, $bufRaw, 64);
  383. if(!defined($res)) {
  384. Log(3, "POKEYS_IO read error");
  385. POKEYS_Disconnect($hash);
  386. return undef;
  387. }
  388. #my $buf = unpack("H*","$bufRaw");
  389. #print "$buf\n";
  390. my ($ResControl,$ResOperation,$ROP1,$ROP2,$ROP3,$ROP4,$ResRequestId, $RChk) = unpack("CCCCCCCC", "$bufRaw");
  391. #print "$ResControl $ResOperation $ROP1 $ROP2 $ROP3 $ROP4 $ResRequestId $RChk\n";
  392. if (($ResControl + $ResOperation + $ROP1 + $ROP2 +$ROP3 + $ROP4 + $ResRequestId) % 0x100 != $RChk)
  393. { Log(3, "Wrong chk"); return undef; }
  394. if ($ResControl != 0xAA)
  395. { Log(3, "Control wrong"); return undef;}
  396. if ($ResOperation != $SendOperation)
  397. { Log(3, "Control Operation: $ResOperation vs $SendOperation"); return undef;}
  398. if ($SendRequestId != $ResRequestId)
  399. { Log(3, "Wrong Id: $SendRequestId vs $ResRequestId"); return undef;}
  400. return $bufRaw;
  401. }
  402. sub
  403. POKEYS_Disconnect($)
  404. {
  405. my ($hash) = @_;
  406. $modules{$hash->{TYPE}}{$hash->{POKEYSNAME}}{STATE} = "disconnected";
  407. Log(3, "Disconnect of $hash->{POKEYSNAME}. Try reconnect");
  408. InternalTimer(gettimeofday()+0.1, "POKEYS_ReDefine", $hash, 0);
  409. }
  410. 1;
  411. =pod
  412. =begin html
  413. <a name="POKEYS"></a>
  414. <h3>POKEYS</h3>
  415. <ul>
  416. The POKEYS module is used to control the LAN POKEYS device (<a href="http://www.poscope.com/pokeys56e">POKEYS56e</a>) which supports
  417. up to 56 digital input, analog inputs, counter inputs and digital outputs.
  418. Each port/pin has to be configured before it can be used.
  419. <br>
  420. <br>
  421. <a name="POKEYSdefine"></a>
  422. <b>Define</b>
  423. <ul>
  424. <code>define &lt;name&gt; POKEYS &lt;ip-address&gt; &lt;pin&gt; &lt;io-state&gt; [&lt;time in ms&gt;]</code> <br>
  425. <br>
  426. <code>&lt;ip-address&gt;</code> the IP address where the POKEYS device can be accessed<br>
  427. <code>&lt;pin&gt;</code> the pin number which should be configured<br>
  428. <code>&lt;io-state&gt;</code> the new io state of the pin <code>Obsolete(=undef) DigIn DigOut AdcIn DigInCtRise DigInCtFall ExtDigOut GetBasic </code> <br>
  429. <code>&lt;time in ms&gt;</code> optional else 1000ms: cyclic update time for Input pin <br>
  430. <br>
  431. Example:
  432. <ul>
  433. <code>define PoInfo POKEYS 192.168.178.34 0 GetBasic</code><br>
  434. # creates a virtual pin for getting infos about the device with the <code>get</code> command<br>
  435. <code>define Pin44in POKEYS 192.168.178.34 44 DigIn 200</code><br>
  436. # creates a digitial input port on pin 44<br>
  437. <code>define Pin25out POKEYS 192.168.178.34 25 DigOut</code><br>
  438. # creates a digial output port on pin 25<br>
  439. </ul>
  440. </ul> <br>
  441. <a name="POKEYSset"></a>
  442. <b>Set</b>
  443. <ul>
  444. <code>set &lt;name&gt; &lt;state&gt; [&lt;time in ms&gt;]</code> <br>
  445. <br>
  446. <code>&lt;state&gt;</code> can be <code>OFF ON OFF_PULSE ON_PULSE </code><br>
  447. <code>&lt;time in ms&gt;</code> optional else 1000ms hold time for the <code>ON_PULSE OFF_PULSE</code> state<br>
  448. <br>
  449. Example:
  450. <ul>
  451. <code>set Pin25out ON</code><br>
  452. # sets Pin25out to ON (0V)<br>
  453. </ul>
  454. </ul><br>
  455. <a name="POKEYSget"></a>
  456. <b>Get</b>
  457. <ul>
  458. <code>get &lt;name&gt; &lt;type&gt; </code> <br>
  459. <br>
  460. only supported for pins of type <code>GetBasic</code><br>
  461. <code>&lt;type&gt;</code> can be <code>Version DevName Serial User CPUload</code><br>
  462. <br>
  463. Example:
  464. <ul>
  465. <code>get PoInfo Version</code><br>
  466. # gets the version of the POKEYS device<br>
  467. </ul>
  468. </ul><br>
  469. <a name="POKEYSattr"></a>
  470. <b>Attributes</b>
  471. <ul>
  472. todo <br>
  473. </ul>
  474. <br>
  475. </ul>
  476. =end html
  477. =cut