diff --git a/lib/Yeelight.pm b/lib/Yeelight.pm index 14ffc6d02..d4c0b2925 100644 --- a/lib/Yeelight.pm +++ b/lib/Yeelight.pm @@ -1,4 +1,4 @@ -=head1 B v1.2.6 +=head1 B v1.2.9 =head2 Initial Setup # To set up, first pair with mobile app -- the Yeelight needs to be set up initially with the app @@ -24,15 +24,12 @@ $yeelight_rgb = new Yeelight_RGB($yeelight); =head2 MH.INI CONFIG PARAMS -yeelight_timeout HTTP request timeout (default 5) -yeelight_poll_seconds Number of seconds to poll the raZberry -yeelight_user Authentication username -yeelight_password Authentication password -yeelight_max_cmd_queue Maximum number of commands to queue up (default 6) +yeelight_timeout TCP request timeout (default 5) +yeelight_max_cmd_queue Maximum number of commands to queue up (default 8) yeelight_com_threshold Number of failed polls before controller marked offline (default 4) yeelight_command_timeout Number of seconds after a command is issued before it is abandoned (default 60) yeelight_command_timeout_limit Maximum number of retries for a command before abandoned - +yeelight_ssdp_timeout Maximum number of seconds to wait for SSDP data to return (default 1000) =head2 Notes @@ -51,6 +48,9 @@ what features are supported - comm tracker went offline when commands dropped - 09/02/18 11:54:33 AM [Yeelight:1] WARNING. Queue has grown past 8. Command get_tcp -rn -quiet 192.168.0.173:55443 '{ "id":1, "method":"set_bright", "params":[90,"smooth",500] }' discarded. - 09/02/18 11:54:33 AM [Yeelight:1] Communication Tracking object found. Updating from online to offline... +- comm device offline, didn't go online when data came back +- lost data and didn't reconnect +- check CPU usage for yeelight =cut @@ -108,13 +108,16 @@ sub new { $self->{updating} = 0; $self->{data}->{retry} = 0; $self->{status} = ""; - $self->{module_version} = "v1.2.6"; + $self->{module_version} = "v1.2.9"; $self->{ssdp_timeout} = 1000; + $self->{ssdp_timeout} = $main::config_parms{yeelight_ssdp_timeout} if ( defined $main::config_parms{yeelight_ssdp_timeout} ); + $self->{socket_connected} = 0; $self->{host} = $location; $self->{port} = 55443; $self->{brightness_state_delay} = 1; - $self->{command_timeout_limit} = 3; + $self->{command_timeout_limit} = 4; + $self->{command_timeout_limit} = $main::config_parms{yeelight_max_cmd_queue} if ( defined $main::config_parms{yeelight_max_cmd_queue} ); if ($location =~ m/:/) { ($self->{host}, $self->{port}) = $location =~ /(.*):(.*)/; @@ -130,11 +133,20 @@ sub new { $self->{loglevel} = 5; ( $self->{loglevel} ) = ( $options =~ /loglevel\=(\d+)/i ) if ($options =~ m/loglevel\=/i ); + $self->{timeout} = 5; + $self->{timeout} = $main::config_parms{yeelight_timeout} if ( defined $main::config_parms{yeelight_timeout} ); + $self->{poll_data_timestamp} = 0; $self->{max_poll_queue} = 3; + $self->{max_cmd_queue} = 8; + $self->{max_cmd_queue} = $main::config_parms{yeelight_max_cmd_queue} if ( defined $main::config_parms{yeelight_max_cmd_queue} ); + $self->{cmd_process_retry_limit} = 6; + $self->{cmd_process_retry_limit} = $main::config_parms{yeelight_command_timeout_limit} if ( defined $main::config_parms{yeelight_command_timeout_limit} ); + $self->{command_timeout} = 60; + $self->{command_timeout} = $main::config_parms{yeelight_command_timeout} if ( defined $main::config_parms{yeelight_command_timeout} ); @{ $self->{poll_queue} } = (); $self->{poll_data_file} = "$::config_parms{data_dir}/Yeelight_poll_" . $self->{name} . ".data"; @@ -146,7 +158,7 @@ sub new { unlink "$::config_parms{data_dir}/Yeelight_cmd_" . $self->{name} . ".data"; $self->{cmd_process} = new Process_Item; $self->{cmd_process}->set_output( $self->{cmd_data_file} ); - $self->{init} = 0; + $self->{init} = 0 unless ($self->{init}); $self->{init_data} = 0; $self->{init_v_cmd} = 0; $self->{data_socket} = new Socket_Item(undef, undef, "$self->{host}:$self->{port}", "yeelight" . $self->{id}, 'tcp', 'raw'); @@ -170,7 +182,7 @@ sub check_for_socket_data { # Other objects use a socket in $Socket_Items? # $NewCmd = $Socket_Items{$instance}{'socket'}->said; - my $com_status = ""; + my $com_status = "offline"; if ($self->{data_socket}->active) { my $rec_data = $self->{data_socket}->said; $self->{socket_connected} = 1; @@ -207,14 +219,15 @@ sub check_for_socket_data { } else { if (($self->{init}) and ($self->{socket_connected})) { - main::print_log( "[Yeelight:" . $self->{name} . "] Lost connection to Yeelight. Trying to connect again in $self->{reconnect} seconds" ); - $self->{recon_timer}->set($self->{reconnect_time}, sub {$self->{data_socket}->start;}); + main::print_log( "[Yeelight:" . $self->{name} . "] Lost connection to Yeelight. Trying to connect again in $self->{reconnect_time} seconds" ); + $self->{recon_timer}->set($self->{reconnect_time}, sub {$self->{data_socket}->start();}); $com_status = "offline"; + $self->{socket_connected} = 0; } } - if (( defined $self->{child_object}->{comm} ) and ($self->{socket_connected})) { - if ( $self->{status} ne $com_status ) { + if ( defined $self->{child_object}->{comm} ) { + if (( $self->{status} ne $com_status ) or ($self->{child_object}->{comm}->state() ne $com_status)) { $self->{status} = $com_status; if ($self->{child_object}->{comm}->state() ne $com_status) { main::print_log "[Yeelight:" . $self->{name} . "] Communication Tracking object found. Updating from " . $self->{child_object}->{comm}->state() . " to " . $com_status . "..." if ( $self->{loglevel} ); @@ -256,7 +269,7 @@ sub get_data { } if ( defined $self->{child_object}->{comm} ) { - if ( $self->{status} ne $com_status ) { + if (( $self->{status} ne $com_status ) or ($self->{child_object}->{comm}->state() ne $com_status)) { $self->{status} = $com_status; if ($self->{child_object}->{comm}->state() ne $com_status) { main::print_log "[Yeelight:" . $self->{name} . "] Communication Tracking object found. Updating from " . $self->{child_object}->{comm}->state() . " to " . $com_status . "..." if ( $self->{loglevel} ); @@ -403,7 +416,8 @@ sub _get_TCP_data { my $cmdline = "{\"id\":" . $self->{id} . ",\"method\":" . $method{$mode} . ",\"params\":["; $cmdline .= join(',', @{$param_array{$mode}}); $cmdline .= "]}"; - my $cmd = "get_tcp -rn -quiet $self->{host}:$self->{port} " . "'" . $cmdline . "'"; + my $options = "-timeout " . $self->{timeout} . " -rn -quiet "; + my $cmd = "get_tcp " . $options . " " . $self->{host} . ":" . $self->{port} . " '" . $cmdline . "'"; if ( $self->{poll_process}->done() ) { $self->{poll_process}->set($cmd); $self->{poll_process}->start(); @@ -422,7 +436,8 @@ sub _push_TCP_data { my $cmdline = "{ \"id\":" . $self->{id} . ", \"method\":" . $method{$mode} . ", \"params\":["; $cmdline .= join(',',@params); $cmdline .= "] }"; - my $cmd = "get_tcp -rn -quiet $self->{host}:$self->{port} " . "'" . $cmdline . "'"; + my $options = "-timeout " . $self->{timeout} . " -rn -quiet "; + my $cmd = "get_tcp " . $options . " " . $self->{host} . ":" . $self->{port} . " '" . $cmdline . "'"; if ( $self->{cmd_process}->done() ) { $self->{cmd_process}->set($cmd); @@ -837,6 +852,13 @@ sub set_ct { } } +sub restart_socket { + my ($self) = @_; + + $self->{data_socket}->stop(); + $self->{data_socket}->start(); +} + sub generate_voice_commands { my ($self) = @_; @@ -884,8 +906,8 @@ sub get_voice_cmds { my %voice_cmds = ( 'Print Command Queue to print log' => $self->get_object_name . '->print_command_queue', 'Purge Command Queue' => $self->get_object_name . '->purge_command_queue', - 'Force Yeelight Status query' => $self->get_object_name . '->query_yeelight' - + 'Force Yeelight Status query' => $self->get_object_name . '->query_yeelight', + 'Restart Data Socket connection' => $self->get_object_name . '->restart_socket' ); return \%voice_cmds;