Skip to content

Commit

Permalink
Map aldb to I2 if get_engine_version returns NAK
Browse files Browse the repository at this point in the history
Handle new device where engine_version is blank
Add failure_reason to Insteon::Message
Add failure callback to get_engine_version message
On message timeout call message failure callback prior to clear_active_message
  • Loading branch information
Michael Stovenour committed Mar 21, 2013
1 parent 0cba9f3 commit 058f80e
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 5 deletions.
54 changes: 52 additions & 2 deletions lib/Insteon/BaseInsteon.pm
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,7 @@ sub _process_message
{
main::print_log("[Insteon::BaseObject] WARN: Now calling message failure callback: "
. $p_setby->active_message->failure_callback) if $main::Debug{insteon};
$p_setby->active_message->failure_reason('NAK');
package main;
eval $p_setby->active_message->failure_callback;
main::print_log("[Insteon::BaseObject] problem w/ retry callback: $@") if $@;
Expand Down Expand Up @@ -1214,13 +1215,51 @@ sub request_status
# $self->_send_cmd('command' => 'status_request', 'is_synchronous' => 1);
}

=item C<get_engine_version>
Queues a get engine version insteon message using L<Insteon::BaseObject::_send_cmd>
and sets a message failure callback to L<Insteon::BaseDevice::_get_engine_version_failure>.
Message response is processed in L<Insteon::BaseObject::_is_info_request>
Returns: nothing
=cut
sub get_engine_version {
my ($self, $requestor) = @_;
my ($self) = @_;

my $message = new Insteon::InsteonMessage('insteon_send', $self, 'get_engine_version');
my $self_object_name = $self->get_object_name;
$message->failure_callback("$self_object_name->_get_engine_version_failure()");
$self->_send_cmd($message);
}

=item C<_get_engine_version_failure>
Callback failure for L<Insteon::BaseDevice::get_engine_version>; called for NAK
and message timeout. Will force engine_version to I2CS which will also remap
the aldb version if the device responds with a NAK. Does nothing for timeouts
except print a message.
Returns: nothing
=cut
sub _get_engine_version_failure
{
my ($self) = @_;
my $failure_reason = $self->interface->active_message->failure_reason();

main::print_log("[Insteon::BaseDevice::_get_engine_version_failure] DEBUG4: "
."failure reason: $failure_reason") if $main::Debug{insteon} >= 4;

if($failure_reason eq 'NAK')
{
#assume I2CS because no other device will NAK this command
main::print_log("[Insteon::BaseDevice] WARN: I2CS device is not "
."linked; Please use 'link to interface' voice command");
$self->engine_version('I2CS');
}
}

sub ping
{
my ($self) = @_;
Expand Down Expand Up @@ -1373,6 +1412,17 @@ sub update_flags
$self->_aldb->update_flags($flags) if $self->_aldb;
}

=item C<engine_version>
Sets or gets the device object engine version. If setting the engine version,
will also call check_aldb_version to map the aldb correctly for I2 devices.
Parameters:
p_engine_version: [I1|I2|I2CS] to set engine version
Returns: engine version string [I1|I2|I2CS]
=cut
sub engine_version
{
my ($self, $p_engine_version) = @_;
Expand Down Expand Up @@ -1403,7 +1453,7 @@ sub check_aldb_version

my $engine_version = $self->SUPER::engine_version();
my $new_version = "";
if($engine_version ne 'I1' and $self->_aldb->aldb_version() ne 'I2') {
if($engine_version and $engine_version ne 'I1' and $self->_aldb->aldb_version() ne 'I2') {
$new_version = "I2";
}
elsif($engine_version eq 'I1' and $self->_aldb->aldb_version() ne 'I1') {
Expand Down
6 changes: 3 additions & 3 deletions lib/Insteon/BaseInterface.pm
Original file line number Diff line number Diff line change
Expand Up @@ -251,20 +251,20 @@ sub process_queue
&main::print_log("[Insteon::BaseInterface] WARN! Unable to clear acknowledge for "
. ((defined($failed_message->setby)) ? $failed_message->setby->get_object_name : "undefined"));
}
# clear active message
$self->clear_active_message();

# may instead want a "failure" callback separate from success callback
if ($failed_message->failure_callback)
{
&::print_log("[Insteon::BaseInterface] WARN: Now calling callback: " .
&::print_log("[Insteon::BaseInterface] WARN: Message Timeout: Now calling callback: " .
$failed_message->failure_callback) if $main::Debug{insteon};
$failed_message->failure_reason('timeout');
package main;
eval $failed_message->failure_callback;
&::print_log("[Insteon::BaseInterface] problem w/ retry callback: $@") if $@;
package Insteon::BaseInterface;
}

$self->clear_active_message();
$self->process_queue();
}
}
Expand Down
19 changes: 19 additions & 0 deletions lib/Insteon/Message.pm
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,25 @@ sub failure_callback
return $$self{failure_callback};
}

=item C<failure_reason>
Stores the resaon for the most recent message failure [NAK | timeout]. Used to
process message callbacks after a message fails. If called with no parameter
returns the saved failure reason.
Parameters:
reason: failure reason
Returns: failure reason
=cut
sub failure_reason
{
my ($self, $reason) = @_;
$$self{failure_reason} = $reason if $reason;
return $$self{failure_reason};
}

sub send_attempts
{
my ($self, $send_attempts) = @_;
Expand Down

0 comments on commit 058f80e

Please sign in to comment.