| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- # $Id: 32_speedtest.pm 12056 2016-08-22 19:30:31Z justme1968 $
- package main;
- use strict;
- use warnings;
- use Blocking;
- sub
- speedtest_Initialize($)
- {
- my ($hash) = @_;
- $hash->{DefFn} = "speedtest_Define";
- $hash->{UndefFn} = "speedtest_Undefine";
- $hash->{SetFn} = "speedtest_Set";
- $hash->{AttrList} = "checks-till-disable ".
- "disable:0,1 ".
- "path ".
- $readingFnAttributes;
- }
- #####################################
- sub
- speedtest_Define($$)
- {
- my ($hash, $def) = @_;
- my @a = split("[ \t][ \t]*", $def);
- return "Usage: define <name> speedtest [interval [server]]" if(@a < 2);
- my $name = $a[0];
- my $interval = 60*60;
- $interval = $a[2] if(int(@a)>=3);
- $interval = 30*60 if( $interval < 30*60 );
- my $server = $a[3] if(int(@a)>=4);
- delete( $hash->{SERVER} );
- $hash->{NAME} = $name;
- $hash->{STATE} = "Initialized";
- $hash->{INTERVAL} = $interval;
- $hash->{SERVER} = $server if( defined( $server ) );
- RemoveInternalTimer($hash);
- InternalTimer(gettimeofday()+$hash->{INTERVAL}, "speedtest_GetUpdate", $hash, 0);
- return undef;
- }
- sub
- speedtest_Undefine($$)
- {
- my ($hash, $arg) = @_;
- RemoveInternalTimer($hash);
- BlockingKill($hash->{helper}{RUNNING_PID}) if(defined($hash->{helper}{RUNNING_PID}));
- return undef;
- }
- sub
- speedtest_Set($$@)
- {
- my ($hash, $name, $cmd) = @_;
- if($cmd eq 'statusRequest') {
- $hash->{LOCAL} = 1;
- speedtest_GetUpdate($hash);
- $hash->{LOCAL} = 0;
- return undef;
- }
- my $list = "statusRequest:noArg";
- return "Unknown argument $cmd, choose one of $list";
- }
- sub
- speedtest_GetUpdate($)
- {
- my ($hash) = @_;
- my $name = $hash->{NAME};
- if(!$hash->{LOCAL}) {
- RemoveInternalTimer($hash);
- InternalTimer(gettimeofday()+$hash->{INTERVAL}, "speedtest_GetUpdate", $hash, 0);
- }
- my $server ="";
- $server = $hash->{SERVER} if( defined($hash->{SERVER}) );
- if( !$hash->{LOCAL} ) {
- return undef if( AttrVal($name, "disable", 0 ) == 1 );
- my $checks = AttrVal($name, "checks-till-disable", undef );
- if( defined($checks) )
- {
- $checks -= 1;
- $attr{$name}{"checks-till-disable"} = max(0,$checks);
- $attr{$name}{"disable"} = 1 if( $checks <= 0 );
- }
- }
- readingsSingleUpdate($hash,"state", "running", 1);
- $hash->{helper}{RUNNING_PID} = BlockingCall("speedtest_DoSpeedtest", $name."|".$server, "speedtest_SpeedtestDone", 300, "speedtest_SpeedtestAborted", $hash) unless(exists($hash->{helper}{RUNNING_PID}));
- }
- sub
- speedtest_DoSpeedtest($)
- {
- my ($string) = @_;
- my ($name, $server) = split("\\|", $string);
- my $cmd = AttrVal($name, "path", "/usr/local/speedtest-cli" );
- $cmd .= "/speedtest-cli --simple";
- $cmd .= " --server $server" if( $server );
- Log3 $name, 5, "starting speedtest";
- my $speedstr = qx($cmd);
- Log3 $name, 5, "speedtest done";
- my @speedarr = split(/\n/, $speedstr);
- for( my $i = 0; $i < 3; ++$i )
- {
- $speedarr[$i] = $1 if( $speedarr[$i] && $speedarr[$i] =~ m/^\w+: (.*)/i );
- }
- return "$name|$speedarr[0]|$speedarr[1]|$speedarr[2]";
- }
- sub
- speedtest_SpeedtestDone($)
- {
- my ($string) = @_;
- return unless(defined($string));
- my @a = split("\\|",$string);
- my $hash = $defs{$a[0]};
- delete($hash->{helper}{RUNNING_PID});
- return if($hash->{helper}{DISABLED});
- Log3 $hash, 5, "speedtest_SpeedtestDone: $string";
- if( $a[1] eq "Invalid server ID" ) {
- readingsSingleUpdate($hash,"state", "failed", 1);
- return;
- }
- $a[1] =~ s/\s.*// if( defined($a[1]) );
- $a[2] =~ s/\s.*// if( defined($a[2]) );
- $a[3] =~ s/\s.*// if( defined($a[3]) );
- readingsBeginUpdate($hash);
- readingsBulkUpdate($hash,"ping",$a[1]);
- readingsBulkUpdate($hash,"download",$a[2]);
- readingsBulkUpdate($hash,"upload",$a[3]);
- readingsBulkUpdate($hash,"state",defined($a[3])?"ok":"failed");
- readingsEndUpdate($hash,1);
- }
- sub
- speedtest_SpeedtestAborted($)
- {
- my ($hash) = @_;
- delete($hash->{helper}{RUNNING_PID});
- }
- 1;
- =pod
- =item device
- =item summary internet speedtest data
- =item summary_DE Internet Speedtest überwachung
- =begin html
- <a name="speedtest"></a>
- <h3>speedtest</h3>
- <ul>
- Provides internet speed data via <a href="https://github.com/sivel/speedtest-cli">speedtest-cli</a>.<br><br>
- Notes:
- <ul>
- <li>speedtest-cli hast to be installed on the FHEM host.</li>
- </ul>
- <a name="speedtest_Define"></a>
- <b>Define</b>
- <ul>
- <code>define <name> speedtest [<interval> [<server>]]</code><br>
- <br>
- Defines a speedtest device.<br><br>
- The data is updated every <interval> seconds. The default is 3600 and the minimum is 1800.<br><br>
- <server> gives the speedtest sever id. the list of all servers is available with <PRE>speedtest-cli --list</PRE>.
- Examples:
- <ul>
- <code>define speedtest speedtest</code><br>
- <code>define speedtest speedtest 3600 2760</code><br>
- </ul>
- </ul><br>
- <a name="speedtest_Readings"></a>
- <b>Readings</b>
- <ul>
- <li>ping</li>
- <li>download</li>
- <li>upload</li>
- </ul><br>
- <a name="speedtest_Set"></a>
- <b>Set</b>
- <ul>
- <li>statusRequest<br>
- manualy start a test. this works even if the device is set to disable.</li>
- </ul>
- <a name="speedtest_Attr"></a>
- <b>Attributes</b>
- <ul>
- <li>path<br>
- The path to the speedtest binary.</li>
- <li>checks-till-disable<br>
- how often the speedtest should be run before it is automaticaly set to disabled. the value will be decreased by 1 for every run.</li>
- <li>disable<br>
- set to 1 to disable the test.</li>
- </ul>
- </ul>
- =end html
- =cut
|