89_FULLY.pm 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  1. ##############################################################################
  2. #
  3. # 89_FULLY.pm 0.6
  4. #
  5. # $Id: 89_FULLY.pm 15968 2018-01-23 12:36:57Z zap $
  6. #
  7. # Control Fully browser on Android tablets from FHEM.
  8. # Requires Fully Plus license!
  9. #
  10. ##############################################################################
  11. package main;
  12. use strict;
  13. use warnings;
  14. use Blocking;
  15. use SetExtensions;
  16. # Declare functions
  17. sub FULLY_Initialize ($);
  18. sub FULLY_Define ($$);
  19. sub FULLY_Undef ($$);
  20. sub FULLY_Shutdown ($);
  21. sub FULLY_Set ($@);
  22. sub FULLY_Get ($@);
  23. sub FULLY_Attr ($@);
  24. sub FULLY_UpdateDeviceInfo ($);
  25. sub FULLY_Execute ($$$$);
  26. sub FULLY_ScreenOff ($);
  27. sub FULLY_GetDeviceInfo ($);
  28. sub FULLY_ProcessDeviceInfo ($$);
  29. sub FULLY_GotDeviceInfo ($);
  30. sub FULLY_Abort ($);
  31. sub FULLY_UpdateReadings ($$);
  32. sub FULLY_Ping ($$);
  33. my $FULLY_VERSION = "0.6";
  34. my $FULLY_TIMEOUT = 4;
  35. my $FULLY_POLL_INTERVAL = 3600;
  36. ##################################################
  37. # Initialize module
  38. ##################################################
  39. sub FULLY_Initialize ($)
  40. {
  41. my ($hash) = @_;
  42. $hash->{DefFn} = "FULLY_Define";
  43. $hash->{UndefFn} = "FULLY_Undef";
  44. $hash->{SetFn} = "FULLY_Set";
  45. $hash->{GetFn} = "FULLY_Get";
  46. $hash->{AttrFn} = "FULLY_Attr";
  47. $hash->{ShutdownFn} = "FULLY_Shutdown";
  48. $hash->{parseParams} = 1;
  49. $hash->{AttrList} = "pingBeforeCmd:0,1,2 pollInterval requestTimeout repeatCommand:0,1,2 " .
  50. "disable:0,1 " .
  51. $readingFnAttributes;
  52. }
  53. ##################################################
  54. # Define device
  55. ##################################################
  56. sub FULLY_Define ($$)
  57. {
  58. my ($hash, $a, $h) = @_;
  59. my $name = $hash->{NAME};
  60. my $rc = 0;
  61. return "Usage: define devname FULLY IP_or_Hostname password [poll-interval]"
  62. if (@$a < 4);
  63. return "FULLY: polling interval must be in range 10 - 86400"
  64. if (@$a == 5 && ($$a[4] !~ /^[1-9][0-9]+$/ || $$a[4] < 10 || $$a[4] > 86400));
  65. $hash->{host} = $$a[2];
  66. $hash->{version} = $FULLY_VERSION;
  67. $hash->{onForTimer} = 'off';
  68. $hash->{fully}{password} = $$a[3];
  69. $hash->{fully}{schedule} = 0;
  70. Log3 $name, 1, "FULLY: Opening device ".$hash->{host};
  71. my $result = FULLY_GetDeviceInfo ($name);
  72. if (!FULLY_UpdateReadings ($hash, $result)) {
  73. Log3 $name, 2, "FULLY: Update of device info failed";
  74. }
  75. if (@$a == 5) {
  76. $attr{$name}{'pollInterval'} = $$a[4];
  77. $hash->{nextUpdate} = strftime "%d.%m.%Y %H:%M:%S", localtime (time+$$a[4]);
  78. InternalTimer (gettimeofday()+$$a[4], "FULLY_UpdateDeviceInfo", $hash, 0);
  79. }
  80. else {
  81. $hash->{nextUpdate} = 'off';
  82. }
  83. return undef;
  84. }
  85. #####################################
  86. # Set or delete attribute
  87. #####################################
  88. sub FULLY_Attr ($@)
  89. {
  90. my ($cmd, $name, $attrname, $attrval) = @_;
  91. my $hash = $defs{$name};
  92. if ($cmd eq 'set') {
  93. if ($attrname eq 'pollInterval') {
  94. if ($attrval >= 10 && $attrval <= 86400) {
  95. my $curval = AttrVal ($name, 'pollInterval', $FULLY_POLL_INTERVAL);
  96. if ($attrval != $curval) {
  97. Log3 $name, 2, "FULLY: Polling interval set to $attrval";
  98. RemoveInternalTimer ($hash);
  99. $hash->{nextUpdate} = strftime "%d.%m.%Y %H:%M:%S", localtime (time+$attrval);
  100. InternalTimer (gettimeofday()+$attrval, "FULLY_UpdateDeviceInfo", $hash, 0);
  101. }
  102. }
  103. elsif ($attrval == 0) {
  104. RemoveInternalTimer ($hash);
  105. $hash->{nextUpdate} = 'off';
  106. }
  107. else {
  108. return "FULLY: Polling interval must be in range 10-86400";
  109. }
  110. }
  111. elsif ($attrname eq 'requestTimeout') {
  112. return "FULLY: Timeout must be greater than 0" if ($attrval < 1);
  113. }
  114. }
  115. elsif ($cmd eq 'del') {
  116. if ($attrname eq 'pollInterval') {
  117. RemoveInternalTimer ($hash);
  118. $hash->{nextUpdate} = 'off';
  119. }
  120. }
  121. return undef;
  122. }
  123. #####################################
  124. # Delete device
  125. #####################################
  126. sub FULLY_Undef ($$)
  127. {
  128. my ($hash, $arg) = @_;
  129. RemoveInternalTimer ($hash);
  130. BlockingKill ($hash->{fully}{bc}) if (defined ($hash->{fully}{bc}));
  131. return undef;
  132. }
  133. #####################################
  134. # Shutdown FHEM
  135. #####################################
  136. sub FULLY_Shutdown ($)
  137. {
  138. my ($hash) = @_;
  139. RemoveInternalTimer ($hash);
  140. BlockingKill ($hash->{fully}{bc}) if (defined ($hash->{fully}{bc}));
  141. return undef;
  142. }
  143. #####################################
  144. # Set commands
  145. #####################################
  146. sub FULLY_Set ($@)
  147. {
  148. my ($hash, $a, $h) = @_;
  149. my $name = shift @$a;
  150. my $opt = shift @$a;
  151. my $options = "brightness clearCache:noArg exit:noArg lock:noArg motionDetection:on,off ".
  152. "off:noArg on:noArg on-for-timer restart:noArg unlock:noArg speak url";
  153. my $response;
  154. # Fully commands without argument
  155. my %cmds = (
  156. "clearCache" => "clearCache",
  157. "exit" => "exitApp", "restart" => "restartApp",
  158. "on" => "screenOn", "off" => "screenOff",
  159. "lock" => "enabledLockedMode", "unlock" => "disableLockedMode"
  160. );
  161. my $disable = AttrVal ($name, 'disable', 0);
  162. return undef if ($disable);
  163. if (exists ($cmds{$opt})) {
  164. $response = FULLY_Execute ($hash, $cmds{$opt}, undef, 1);
  165. }
  166. elsif ($opt eq 'on-for-timer') {
  167. my $par = shift @$a;
  168. $par = "forever" if (!defined ($par));
  169. if ($par eq 'forever') {
  170. $response = FULLY_Execute ($hash, "setBooleanSetting",
  171. { "key" => "keepScreenOn", "value" => "true" }, 1);
  172. $response = FULLY_Execute ($hash, "screenOn", undef, 0)
  173. if (defined ($response) && $response ne '');
  174. }
  175. elsif ($par eq 'off') {
  176. $response = FULLY_Execute ($hash, "setBooleanSetting",
  177. { "key" => "keepScreenOn", "value" => "false" }, 1);
  178. $response = FULLY_Execute ($hash, "setStringSetting",
  179. { "key" => "timeToScreenOffV2", "value" => "0" }, 0)
  180. if (defined ($response) && $response ne '');
  181. }
  182. elsif ($par =~ /^[0-9]+$/) {
  183. $response = FULLY_Execute ($hash, "setBooleanSetting",
  184. { "key" => "keepScreenOn", "value" => "true" }, 1);
  185. $response = FULLY_Execute ($hash, "screenOn", undef, 0)
  186. if (defined ($response) && $response ne '');
  187. InternalTimer (gettimeofday()+$par, "FULLY_ScreenOff", $hash, 0);
  188. }
  189. else {
  190. return "Usage: set $name on-for-timer [{ Seconds | forever | off }]";
  191. }
  192. RemoveInternalTimer ($hash, "FULLY_ScreenOff") if ($par eq 'off' || $par eq 'forever');
  193. $hash->{onForTimer} = $par if (defined ($response) && $response ne '');
  194. }
  195. elsif ($opt eq 'brightness') {
  196. my $value = shift @$a;
  197. return "Usage: set $name brightness 0-255" if (!defined ($value));
  198. $value = 255 if ($value > 255);
  199. $response = FULLY_Execute ($hash, "setStringSetting",
  200. { "key" => "screenBrightness", "value" => "$value" }, 1);
  201. }
  202. elsif ($opt eq 'motionDetection') {
  203. my $state = shift @$a;
  204. return "Usage: set $name motionDetection { on | off }" if (!defined ($state));
  205. my $value = $state eq 'on' ? 'true' : 'false';
  206. $response = FULLY_Execute ($hash, "setBooleanSetting",
  207. { "key" => "motionDetection", "value" => "$value" }, 1);
  208. }
  209. elsif ($opt eq 'speak') {
  210. my $text = shift @$a;
  211. return 'Usage: set $name speak "{Text}"' if (!defined ($text));
  212. while ($text =~ /\[(.+):(.+)\]/) {
  213. my ($device, $reading) = ($1, $2);
  214. my $value = ReadingsVal ($device, $reading, '');
  215. $text =~ s/\[$device:$reading\]/$value/g;
  216. }
  217. my $enctext = urlEncode ($text);
  218. $response = FULLY_Execute ($hash, "textToSpeech", { "text" => "$enctext" }, 1);
  219. }
  220. elsif ($opt eq 'url') {
  221. my $url = shift @$a;
  222. my $cmd = defined ($url) ? "loadURL" : "loadStartURL";
  223. $response = FULLY_Execute ($hash, $cmd, { "url" => "$url" }, 1);
  224. }
  225. else {
  226. return "FULLY: Unknown argument $opt, choose one of ".$options;
  227. }
  228. my $result = FULLY_ProcessDeviceInfo ($name, $response);
  229. if (!FULLY_UpdateReadings ($hash, $result)) {
  230. Log3 $name, 2, "FULLY: Command failed";
  231. return "FULLY: Command failed";
  232. }
  233. return undef;
  234. }
  235. #####################################
  236. # Get commands
  237. #####################################
  238. sub FULLY_Get ($@)
  239. {
  240. my ($hash, $a, $h) = @_;
  241. my $name = shift @$a;
  242. my $opt = shift @$a;
  243. my $options = "info:noArg stats:noArg update:noArg";
  244. my $response;
  245. my $disable = AttrVal ($name, 'disable', 0);
  246. return undef if ($disable);
  247. if ($opt eq 'info') {
  248. my $result = FULLY_Execute ($hash, 'deviceInfo', undef, 1);
  249. if (!defined ($result) || $result eq '') {
  250. Log3 $name, 2, "FULLY: Command failed";
  251. return "FULLY: Command failed";
  252. }
  253. elsif ($response =~ /Wrong password/) {
  254. Log3 $name, 2, "FULLY: Wrong password";
  255. return "FULLY: Wrong password";
  256. }
  257. $response = '';
  258. while ($result =~ /table-cell\">([^<]+)<\/td><td class="table-cell">([^<]+)</g) {
  259. $response .= "$1 = $2<br/>\n";
  260. }
  261. return $response;
  262. }
  263. elsif ($opt eq 'stats') {
  264. return "FULLY: Command not implemented";
  265. }
  266. elsif ($opt eq 'update') {
  267. my $result = FULLY_GetDeviceInfo ($name);
  268. if (!FULLY_UpdateReadings ($hash, $result)) {
  269. Log3 $name, 2, "FULLY: Command failed";
  270. return "FULLY: Command failed";
  271. }
  272. }
  273. else {
  274. return "FULLY: Unknown argument $opt, choose one of ".$options;
  275. }
  276. return undef;
  277. }
  278. #####################################
  279. # Execute Fully command
  280. #####################################
  281. sub FULLY_Execute ($$$$)
  282. {
  283. my ($hash, $command, $param, $doping) = @_;
  284. my $name = $hash->{NAME};
  285. # Get attributes
  286. my $timeout = AttrVal ($name, 'requestTimeout', $FULLY_TIMEOUT);
  287. my $repeatCommand = min (AttrVal ($name, 'repeatCommand', 0), 2);
  288. my $ping = min (AttrVal ($name, 'pingBeforeCmd', 0), 2);
  289. my $response = '';
  290. my $url = "http://".$hash->{host}.":2323/?cmd=$command";
  291. if (defined ($param)) {
  292. foreach my $parname (keys %$param) {
  293. if (defined ($param->{$parname})) {
  294. $url .= "&$parname=".$param->{$parname};
  295. }
  296. }
  297. }
  298. # Ping tablet device
  299. FULLY_Ping ($hash, $ping) if ($doping && $ping > 0);
  300. my $i = 0;
  301. while ($i <= $repeatCommand && (!defined ($response) || $response eq '')) {
  302. $response = GetFileFromURL ("$url&password=".$hash->{fully}{password}, $timeout);
  303. Log3 $name, 4, "FULLY: HTTP response empty" if (defined ($response) && $response eq '');
  304. $i++;
  305. }
  306. return $response;
  307. }
  308. #####################################
  309. # Timer function: Turn screen off
  310. #####################################
  311. sub FULLY_ScreenOff ($)
  312. {
  313. my ($hash) = @_;
  314. my $response = FULLY_Execute ($hash, "setBooleanSetting",
  315. { "key" => "keepScreenOn", "value" => "false" }, 1);
  316. $response = FULLY_Execute ($hash, "screenOff", undef, 1)
  317. if (defined ($response) && $response ne '');
  318. $hash->{onForTimer} = 'off' if (defined ($response) && $response ne '');
  319. }
  320. #####################################
  321. # Timer function: Read device info
  322. #####################################
  323. sub FULLY_UpdateDeviceInfo ($)
  324. {
  325. my ($hash) = @_;
  326. my $name = $hash->{NAME};
  327. my $disable = AttrVal ($name, 'disable', 0);
  328. if (!exists ($hash->{fully}{bc}) && $disable == 0) {
  329. $hash->{fully}{bc} = BlockingCall ("FULLY_GetDeviceInfo", $name, "FULLY_GotDeviceInfo",
  330. 120, "FULLY_Abort", $hash);
  331. }
  332. }
  333. #####################################
  334. # Get tablet device information
  335. #####################################
  336. sub FULLY_GetDeviceInfo ($)
  337. {
  338. my ($name) = @_;
  339. my $hash = $defs{$name};
  340. my $result = FULLY_Execute ($hash, 'deviceInfo', undef, 1);
  341. return FULLY_ProcessDeviceInfo ($name, $result);
  342. }
  343. #####################################
  344. # Extract parameters from HTML code
  345. #####################################
  346. sub FULLY_ProcessDeviceInfo ($$)
  347. {
  348. my ($name, $result) = @_;
  349. return "$name|0|state=failed" if (!defined ($result) || $result eq '');
  350. return "$name|0|state=wrong password" if ($result =~ /Wrong password/);
  351. my $parameters = "$name|1";
  352. while ($result =~ /table-cell\">([^<]+)<\/td><td class="table-cell">([^<]+)</g) {
  353. my $rn = lc($1);
  354. my $rv = $2;
  355. $rn =~ s/\:/\./g;
  356. $rn =~ s/[^A-Za-z\d_\.-]+/_/g;
  357. $rn =~ s/[_]+$//;
  358. if ($rn eq 'battery_level') {
  359. if ($rv =~ /^([0-9]+)% \(([^\)]+)\)$/) {
  360. $parameters .= "|$rn=$1|power=$2";
  361. next;
  362. }
  363. }
  364. elsif ($rn eq 'screen_brightness') {
  365. $rn = "brightness";
  366. }
  367. elsif ($rn eq 'screen_status') {
  368. $parameters .= "|state=$rv";
  369. }
  370. $parameters .= "|$rn=$rv";
  371. }
  372. return $parameters;
  373. }
  374. #####################################
  375. # Success function for blocking call
  376. #####################################
  377. sub FULLY_GotDeviceInfo ($)
  378. {
  379. my ($string) = @_;
  380. my ($name, $result) = split ('\|', $string, 2);
  381. my $hash = $defs{$name};
  382. my $pollInterval = AttrVal ($name, 'pollInterval', $FULLY_POLL_INTERVAL);
  383. my $timeout = AttrVal ($name, 'requestTimeout', $FULLY_TIMEOUT);
  384. delete $hash->{fully}{bc} if (exists ($hash->{fully}{bc}));
  385. my $rc = FULLY_UpdateReadings ($hash, $string);
  386. if (!$rc) {
  387. Log3 $name, 2, "FULLY: Request timed out";
  388. if ($hash->{fully}{schedule} == 0) {
  389. $hash->{fully}{schedule} += 1;
  390. Log3 $name, 2, "FULLY: Rescheduling in $timeout seconds.";
  391. $pollInterval = $timeout;
  392. }
  393. else {
  394. $hash->{fully}{schedule} = 0;
  395. }
  396. }
  397. $hash->{nextUpdate} = strftime "%d.%m.%Y %H:%M:%S", localtime (time+$pollInterval);
  398. InternalTimer (gettimeofday()+$pollInterval, "FULLY_UpdateDeviceInfo", $hash, 0)
  399. if ($pollInterval > 0);
  400. }
  401. #####################################
  402. # Abort function for blocking call
  403. #####################################
  404. sub FULLY_Abort ($)
  405. {
  406. my ($hash) = @_;
  407. my $name = $hash->{NAME};
  408. my $pollInterval = AttrVal ($name, 'pollInterval', $FULLY_POLL_INTERVAL);
  409. my $timeout = AttrVal ($name, 'requestTimeout', $FULLY_TIMEOUT);
  410. delete $hash->{fully}{bc} if (exists ($hash->{fully}{bc}));
  411. Log3 $name, 2, "FULLY: request timed out";
  412. if ($hash->{fully}{schedule} == 0) {
  413. $hash->{fully}{schedule} += 1;
  414. Log3 $name, 2, "FULLY: Rescheduling in $timeout seconds.";
  415. $pollInterval = $timeout;
  416. }
  417. else {
  418. $hash->{fully}{schedule} = 0;
  419. }
  420. $hash->{nextUpdate} = strftime "%d.%m.%Y %H:%M:%S", localtime (time+$pollInterval);
  421. InternalTimer (gettimeofday()+$pollInterval, "FULLY_UpdateDeviceInfo", $hash, 0)
  422. if ($pollInterval > 0);
  423. }
  424. #####################################
  425. # Update readings
  426. #####################################
  427. sub FULLY_UpdateReadings ($$)
  428. {
  429. my ($hash, $result) = @_;
  430. my $name = $hash->{NAME};
  431. my $rc = 1;
  432. if (!defined ($result) || $result eq '') {
  433. Log3 $name, 2, "FULLY: empty response";
  434. return 0;
  435. }
  436. my @parameters = split ('\|', $result);
  437. if (scalar (@parameters) == 0) {
  438. Log3 $name, 2, "FULLY: empty response";
  439. return 0;
  440. }
  441. if ($parameters[0] eq $name) {
  442. my $n = shift @parameters;
  443. $rc = shift @parameters;
  444. }
  445. readingsBeginUpdate ($hash);
  446. foreach my $parval (@parameters) {
  447. my ($rn, $rv) = split ('=', $parval);
  448. readingsBulkUpdate ($hash, $rn, $rv);
  449. }
  450. readingsEndUpdate ($hash, 1);
  451. return $rc;
  452. }
  453. #####################################
  454. # Send ICMP request to tablet device
  455. # Adapted from presence module.
  456. # Thx Markus.
  457. #####################################
  458. sub FULLY_Ping ($$)
  459. {
  460. my ($hash, $count) = @_;
  461. my $name = $hash->{NAME};
  462. my $host = $hash->{host};
  463. my $temp;
  464. if ($^O =~ m/(Win|cygwin)/)
  465. {
  466. $temp = qx(ping -n $count -4 $host);
  467. }
  468. elsif ($^O =~ m/solaris/)
  469. {
  470. $temp = qx(ping $host $count 2>&1);
  471. }
  472. else
  473. {
  474. $temp = qx(ping -c $count $host 2>&1);
  475. }
  476. Log3 $name, 4, "FULLY: Ping response = $temp" if (defined ($temp));
  477. sleep (1);
  478. return $temp;
  479. }
  480. 1;
  481. =pod
  482. =item device
  483. =item summary FULLY Browser Integration
  484. =begin html
  485. <a name="FULLY"></a>
  486. <h3>FULLY</h3>
  487. <ul>
  488. Module for controlling of Fully browser on Android tablets.
  489. </br></br>
  490. <a name="HMCCUdefine"></a>
  491. <b>Define</b><br/><br/>
  492. <ul>
  493. <code>define &lt;name&gt; FULLY &lt;HostOrIP&gt; &lt;password&gt; [&lt;poll-interval&gt;]</code>
  494. <br/><br/>
  495. The parameter <i>password</i> is the password set in Fully browser.
  496. </ul>
  497. <br/>
  498. <a name="FULLYset"></a>
  499. <b>Set</b><br/><br/>
  500. <ul>
  501. <li><b>set &lt;name&gt; brightness 0-255</b><br/>
  502. Adjust screen brightness.
  503. </li><br/>
  504. <li><b>set &lt;name&gt; clearCache</b><br/>
  505. Clear browser cache.
  506. </li><br/>
  507. <li><b>set &lt;name&gt; exit</b><br/>
  508. Terminate Fully.
  509. </li><br/>
  510. <li><b>set &lt;name&gt; motionDetection { on | off }</b><br/>
  511. Turn motion detection by camera on or off.
  512. </li><br/>
  513. <li><b>set &lt;name&gt; { lock | unlock }</b><br/>
  514. Lock or unlock display.
  515. </li><br/>
  516. <li><b>set &lt;name&gt; { on | off }</b><br/>
  517. Turn tablet display on or off.
  518. </li><br/>
  519. <li><b>set &lt;name&gt; on-for-timer [{ &lt;Seconds&gt; | <u>forever</u> | off }]</b><br/>
  520. Set timer for display. Default is forever.
  521. </li><br/>
  522. <li><b>set &lt;name&gt; restart</b><br/>
  523. Restart Fully.
  524. </li><br/>
  525. <li><b>set &lt;name&gt; speak &lt;text&gt;</b><br/>
  526. Audio output of <i>text</i>. If <i>text</i> contains blanks it must be enclosed
  527. in double quotes. The text can contain device readings in format [device:reading].
  528. </li><br/>
  529. <li><b>set &lt;name&gt; url [&lt;URL&gt;]</b><br/>
  530. Navigate to <i>URL</i>. If no URL is specified navigate to start URL.
  531. </li><br/>
  532. </ul>
  533. <br/>
  534. <a name="FULLYget"></a>
  535. <b>Get</b><br/><br/>
  536. <ul>
  537. <li><b>get &lt;name&gt; info</b><br/>
  538. Display Fully information.
  539. </li><br/>
  540. <li><b>get &lt;name&gt; stats</b><br/>
  541. Show Fully statistics.
  542. </li><br/>
  543. <li><b>get &lt;name&gt; update</b><br/>
  544. Update readings.
  545. </li><br/>
  546. </ul>
  547. <br/>
  548. <a name="FULLYattr"></a>
  549. <b>Attributes</b><br/>
  550. <br/>
  551. <ul>
  552. <li><b>disable &lt;0 | 1&gt;</b><br/>
  553. Disable device and automatic polling.
  554. </li><br/>
  555. <li><b>pingBeforeCmd &lt;Count&gt;</b><br/>
  556. Send <i>Count</i> ping request to tablet before executing commands. Valid values
  557. for <i>Count</i> are 0,1,2. Default is 0 (do not send ping request).
  558. </li><br/>
  559. <li><b>pollInterval &lt;seconds&gt;</b><br/>
  560. Set polling interval for FULLY device information.
  561. If <i>seconds</i> is 0 polling is turned off. Valid values are from 10 to
  562. 86400 seconds.
  563. </li><br/>
  564. <li><b>requestTimeout &lt;seconds&gt;</b><br/>
  565. Set timeout for http requests. Default is 4 seconds.
  566. </li><br/>
  567. <li><b>repeatCommand &lt;Count&gt;</b><br/>
  568. Repeat fully command on failure. Valid values for <i>Count</i> are 0,1,2. Default
  569. is 0 (do not repeat commands).
  570. </li><br/>
  571. </ul>
  572. </ul>
  573. =end html
  574. =cut