diff --git a/lib/Insteon/Message.pm b/lib/Insteon/Message.pm index bb9c32f26..57b54d576 100644 --- a/lib/Insteon/Message.pm +++ b/lib/Insteon/Message.pm @@ -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 @@ -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) @@ -327,6 +335,22 @@ sub to_string return $self->interface_data; } +=item C + +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 diff --git a/lib/Insteon_PLM.pm b/lib/Insteon_PLM.pm index 3021aff31..4b9686731 100644 --- a/lib/Insteon_PLM.pm +++ b/lib/Insteon_PLM.pm @@ -87,6 +87,25 @@ sub serial_startup { } +=item C + +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 Instantiates a new object. @@ -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'); @@ -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'); @@ -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'); @@ -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)) @@ -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'); @@ -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);