diff --git a/bin/mh b/bin/mh index b62216e8c..db2a14347 100755 --- a/bin/mh +++ b/bin/mh @@ -5707,7 +5707,7 @@ sub serial_port_close { my $port = $Serial_Ports{$name}{port}; # Recommended Steps to Close a Serial Port from CPAN - $Serial_Ports{$name}{object}->close() || ::print_log("[Insteon_PLM] Close of serial port failed."); + $Serial_Ports{$name}{object}->close() if (defined $Serial_Ports{$name}{object}); undef $Serial_Ports{$name}{object}; # Remove all references in Global Vars diff --git a/lib/Insteon/Message.pm b/lib/Insteon/Message.pm index 57b54d576..9829361ab 100644 --- a/lib/Insteon/Message.pm +++ b/lib/Insteon/Message.pm @@ -256,8 +256,12 @@ sub send } # If No PLM-Receipt has been received for this message - # then attempt to reconnect the PLM - $interface->serial_restart() unless $self->plm_receipt; + # then check to see if we are supposed to restart the PLM + if (!$self->plm_receipt) { + if ($self->is_plm_down($interface) <= 0){ + $interface->serial_restart(); + } + } } # need to set timeout as a function of retries; also need to alter hop count @@ -350,6 +354,37 @@ sub plm_receipt return $$self{plm_receipt}; } +=item C + +Used to determine whether the PLM needs to be restarted. The PLM should ACK the +receipt of every command MisterHouse sends to it. If no ACK is received then +plm_receipt is zero on the retry attempt. If the number of sequential no ACK +instances for a specific command reaches the defined number, MisterHouse will +attempt to reconnect the PLM port. You can set the threshold to any number you +like, but if the no ACK number is higher than your retry number, which defaults +to 5, then the PLM will never be restarted. The no ACK number can be set using +the ini key: + +B + +by default this number will be set to 99, which in will prevent the PLM from +being restarted. If you have PLM disconnect issues, try setting this to 2 or 3. +The restart code has been known to be incompatible with certain perl installations. + +=cut + +sub is_plm_down +{ + my ($self, $interface) = @_; + my $instance = $$interface{port_name}; + my $reconnect_count = 99; + $reconnect_count = $::config_parms{$instance . "_reconnect_count"} + if defined $::config_parms{$instance . "_reconnect_count"}; + $$self{is_plm_down} = $reconnect_count unless defined $$self{is_plm_down}; + $$self{is_plm_down} -= 1; + return $$self{is_plm_down}; +} + =back diff --git a/lib/Insteon_PLM.pm b/lib/Insteon_PLM.pm index 4385965ad..5b91483ae 100644 --- a/lib/Insteon_PLM.pm +++ b/lib/Insteon_PLM.pm @@ -1211,6 +1211,28 @@ to send a message to the PLM. If this is set to 1, downgrades the delay to only .3 seconds. Most of the issues which caused the PLM to overload have been handled it is unlikely that you would need to set this. +=item Insteon_PLM_reconnect_count + +The PLM acknowledges the receipt of a command from MisterHouse with an ACK +message. It is very rare for a well functioning PLM to fail to send the ACK +message. In many cases, the failure to receive an ACK message from the PLM +is a sign that the connection between MisterHouse and the PLM (Serial or USB) +has died. + +This setting defines the number of missed ACK messages that must occur for +MisterHouse to deem the PLM connection lost. The number of missed ACK messages +must all occur while sending a single Insteon command. So if you want this +to do anything, this number needs to be less than or equal to the +Insteon_retry_count. Once the number of missed ACK messages occurs, MisterHouse +will attempt to reconnect the PLM. For some people, the reconnect routine +causes errors, so you may want to test this out by manually pulling the +connection cable to the PLM to see how your system will react. + +By default, this is set to 99, essentially disabling an automatic restart. + +Note the ACK messages discussed here refer to PLM ACK messages not the ACK +messages received from an Insteon device in response to a command. + =back =head2 NOTES