Skip to content

Commit

Permalink
Insteon: Attempt to Reconnect PLM if it Appears to be Down
Browse files Browse the repository at this point in the history
- Add flag to track if a message sent to the PLM has been acknowledged by the PLM
- On retry, if no receipt was acknowledged by the PLM, attempt to re-open the PLM serial port

Should fix hollie#397
  • Loading branch information
krkeegan committed Apr 19, 2014
1 parent ec288a7 commit 8e00ab9
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 0 deletions.
24 changes: 24 additions & 0 deletions lib/Insteon/Message.pm
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,10 @@ sub send
if $self->setby->debuglevel(1, 'insteon');
$$self{no_hop_increase} = undef;
}

# If No PLM-Receipt has been received for this message
# then attempt to reconnect the PLM
$interface->serial_restart() unless $self->plm_receipt;
}

# need to set timeout as a function of retries; also need to alter hop count
Expand All @@ -262,6 +266,10 @@ sub send
$self->setby->outgoing_hop_count($self->setby->default_hop_count)
if $self->setby->can('outgoing_hop_count');
}

# Clear PLM-Receipt Flag
$self->plm_receipt(0);

$self->send_attempts($self->send_attempts + 1);
$interface->_send_cmd($self, $self->send_timeout);
if ($self->callback)
Expand Down Expand Up @@ -327,6 +335,22 @@ sub to_string
return $self->interface_data;
}

=item C<plm_receipt()>
Used to track whether the PLM has acknowledged receiving this message, either
an ACK or NAK. This is used to determine situations in which the serial
connection to the PLM may have collapsed and may need to be restarted.
=cut

sub plm_receipt
{
my ($self, $receipt) = @_;
$$self{plm_receipt} = $receipt if defined $receipt;
return $$self{plm_receipt};
}


=back
=head2 INI PARAMETERS
Expand Down
37 changes: 37 additions & 0 deletions lib/Insteon_PLM.pm
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,25 @@ sub serial_startup {

}

=item C<serial_restart()>
Attempt to restart/reconnect the serial port connection.
=cut

sub serial_restart {
my ($self) = @_;
my $instance = $$self{port_name};
my $PLM_use_tcp = $::config_parms{$instance . "_use_TCP"};

# TCP Port gets reconnected elsewhere
return if $PLM_use_tcp;

::print_log("[Insteon_PLM] WARN: The PLM did not respond to the last command."
." The port may have closed, attempting to reopen the port.");
::serial_port_open($instance);
}

=item C<new()>
Instantiates a new object.
Expand Down Expand Up @@ -620,6 +639,9 @@ sub _parse_data {

# STEP 4b Is this a PLM Response to a command MH sent?
if ($is_ack) {
#Note Receipt of PLM ACK
$pending_message->plm_receipt(1);

::print_log( "[Insteon_PLM] DEBUG4:\n".
Insteon::MessageDecoder::plm_decode($data))
if $debug_obj->debuglevel(4, 'insteon');
Expand Down Expand Up @@ -676,6 +698,9 @@ sub _parse_data {
$data =~ s/^$ackcmd//;
}
elsif ($is_nack) {
#Note Receipt of PLM NAK
$pending_message->plm_receipt(1);

::print_log( "[Insteon_PLM] DEBUG4:\n".
Insteon::MessageDecoder::plm_decode($data))
if $debug_obj->debuglevel(4, 'insteon');
Expand Down Expand Up @@ -759,6 +784,9 @@ sub _parse_data {
$data =~ s/^$nackcmd//;
}
elsif ($is_badcmd){
#Note Receipt of PLM Bad Cmd
$pending_message->plm_receipt(1);

::print_log( "[Insteon_PLM] DEBUG4:\n".
Insteon::MessageDecoder::plm_decode($data))
if $debug_obj->debuglevel(4, 'insteon');
Expand Down Expand Up @@ -910,6 +938,9 @@ sub _parse_data {
$data = substr($data, 12);
}
elsif ($record_type eq $prefix{all_link_record} and (length($data) >= 20)) {
#Note Receipt of PLM Response
$pending_message->plm_receipt(1);

#ALL-Link Record Response
my $message_data = substr($data,4,16);
&::print_log( "[Insteon_PLM] DEBUG4:\n".Insteon::MessageDecoder::plm_decode($data))
Expand Down Expand Up @@ -962,6 +993,9 @@ sub _parse_data {
$data = substr($data, 6);
}
elsif ($record_type eq $prefix{plm_info} and (length($data) >= 18)){
#Note Receipt of PLM Response
$pending_message->plm_receipt(1);

::print_log( "[Insteon_PLM] DEBUG4:\n".Insteon::MessageDecoder::plm_decode($data))
if $self->debuglevel(4, 'insteon');

Expand All @@ -972,6 +1006,9 @@ sub _parse_data {
$data = substr($data, 18);
}
elsif ($record_type eq $prefix{plm_get_config} and (length($data) >= 12)){
#Note Receipt of PLM Response
$pending_message->plm_receipt(1);

::print_log( "[Insteon_PLM] DEBUG4:\n".Insteon::MessageDecoder::plm_decode($data))
if $self->debuglevel(4, 'insteon');
my $message_data = substr($data,4,8);
Expand Down

0 comments on commit 8e00ab9

Please sign in to comment.