Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Insteon: Some Fixes to Scan Link Tables and Link Table Nomeclature #467

Merged
merged 8 commits into from
Jul 27, 2015
74 changes: 36 additions & 38 deletions lib/Insteon/AllLinkDatabase.pm
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ sub aldb_version
return $$self{aldb_version};
}

=item C<health([out-of-sync|unknown|empty|good])>
=item C<health([changed|unknown|empty|unchanged])>

Used to track the health of MisterHouse's copy of a device's ALDB.

Expand All @@ -82,11 +82,7 @@ sub health

=item C<get_linkkey($deviceid, $group, $is_controller, $data3)>

Used to track the health of MisterHouse's copy of a device's ALDB.

If provided, saves status to memory.

Returns the saved health status.
Returns the key in the ALDB hash that identifies this link.

=cut

Expand Down Expand Up @@ -164,9 +160,9 @@ sub query_aldb_delta
{
my ($self, $action) = @_;
$$self{aldb_delta_action} = $action;
if ($action eq "check" && $self->health ne "good" && $self->health ne "empty"){
if ($action eq "check" && $self->health ne "unchanged" && $self->health ne "empty"){
&::print_log("[Insteon::AllLinkDatabase] WARN The link table for "
. $self->{device}->get_object_name . " is out-of-sync.");
. $self->{device}->get_object_name . " has changed.");
if (defined $self->{_aldb_changed_callback}) {
package main;
my $callback = $self->{_aldb_changed_callback};
Expand All @@ -179,7 +175,7 @@ sub query_aldb_delta
} elsif ($action eq "check" && ((&main::get_tickcount - $self->scandatetime()) <= 2000)){
#if we just did a aldb_query less than 2 seconds ago, don't repeat
&::print_log("[Insteon::AllLinkDatabase] The link table for "
. $self->{device}->get_object_name . " is in sync.");
. $self->{device}->get_object_name . " is unchanged.");
#Further extend Scan Time in case of serial aldb requests
$self->scandatetime(&main::get_tickcount);
if (defined $self->{_aldb_unchanged_callback}) {
Expand Down Expand Up @@ -314,7 +310,7 @@ sub scan_link_table
$$self{_mem_activity} = 'scan';
$$self{_success_callback} = ($success_callback) ? $success_callback : undef;
$$self{_failure_callback} = ($failure_callback) ? $failure_callback : undef;
$self->health('out-of-sync'); # allow acknowledge to set otherwise
$self->health('changed'); # allow acknowledge to set otherwise
if($self->isa('Insteon::ALDB_i1')) {
$self->_peek('0FF8',0);
} else {
Expand Down Expand Up @@ -349,7 +345,7 @@ sub delete_link
$$self{_success_callback} = ($link_parms{callback}) ? $link_parms{callback} : undef;
$$self{_failure_callback} = ($link_parms{failure_callback}) ? $link_parms{failure_callback} : undef;
if (!defined($link_parms{aldb_check}) && (!$$self{device}->isa('Insteon_PLM'))){
## Check whether ALDB is in sync
## Check whether ALDB has changed
$self->{callback_parms} = \%link_parms;
$$self{_aldb_unchanged_callback} = '&Insteon::AllLinkDatabase::delete_link('.$$self{device}->{object_name}."->_aldb, 'ok')";
$$self{_aldb_changed_callback} = '&Insteon::AllLinkDatabase::delete_link('.$$self{device}->{object_name}."->_aldb, 'fail')";
Expand Down Expand Up @@ -441,7 +437,7 @@ sub delete_orphan_links
my $selfname = $$self{device}->get_object_name;

# first, make sure that the health of ALDB is ok
if ($self->health ne 'good' || ($$self{device}->is_deaf && $is_batch_mode)) {
if ($self->health ne 'unchanged' || ($$self{device}->is_deaf && $is_batch_mode)) {
my $sent_to_failure = 0;
if ($$self{device}->is_deaf) {
::print_log("[Insteon::AllLinkDatabase] Will not delete ".
Expand All @@ -452,7 +448,7 @@ sub delete_orphan_links
::print_log("[Insteon::AllLinkDatabase] Skipping $selfname, because it has no links");
}
else {
::print_log("[Insteon::AllLinkDatabase] Delete orphan links: skipping $selfname because health: "
::print_log("[Insteon::AllLinkDatabase] Delete orphan links: skipping $selfname because the link table is: "
. $self->health . ". Please rescan the link table of this device and rerun delete "
. "orphans if necessary");
#log the failure
Expand Down Expand Up @@ -607,10 +603,10 @@ sub delete_orphan_links
}

# Do not delete links to unhealthy devices
if ($linked_device->_aldb->health ne 'good' && $linked_device->_aldb->health ne 'empty') {
if ($linked_device->_aldb->health ne 'unchanged' && $linked_device->_aldb->health ne 'empty') {
$delete_req{skip} = "$selfname -- Skipping check for reciprocal links on "
. $linked_device->get_object_name . " because aldb health of that device is "
. $linked_device->_aldb->health . ". Please rescan this device.";
. $linked_device->get_object_name . " because link table of that device has "
. $linked_device->_aldb->health . ". Please rescan the link table on this device.";
next LINKKEY;
}

Expand Down Expand Up @@ -870,7 +866,7 @@ sub add_link
$$self{_success_callback} = ($link_parms{callback}) ? $link_parms{callback} : undef;
$$self{_failure_callback} = ($link_parms{failure_callback}) ? $link_parms{failure_callback} : undef;
if (!defined($link_parms{aldb_check}) && (!$$self{device}->isa('Insteon_PLM'))){
## Check whether ALDB is in sync
## Check whether ALDB has changed
$self->{callback_parms} = \%link_parms;
$$self{_aldb_unchanged_callback} = '&Insteon::AllLinkDatabase::add_link('.$$self{device}->{object_name}."->_aldb, 'ok')";
$$self{_aldb_changed_callback} = '&Insteon::AllLinkDatabase::add_link('.$$self{device}->{object_name}."->_aldb, 'fail')";
Expand Down Expand Up @@ -995,7 +991,7 @@ sub update_link
my $deviceid = $insteon_object->device_id;
my $key = $self->get_linkkey($deviceid, $group, $is_controller, $data3);
if (!defined($link_parms{aldb_check}) && (!$$self{device}->isa('Insteon_PLM'))){
## Check whether ALDB is in sync
## Check whether ALDB has changed
$self->{callback_parms} = \%link_parms;
$$self{_aldb_unchanged_callback} = '&Insteon::AllLinkDatabase::update_link('.$$self{device}->{object_name}."->_aldb, 'ok')";
$$self{_aldb_changed_callback} = '&Insteon::AllLinkDatabase::update_link('.$$self{device}->{object_name}."->_aldb, 'fail')";
Expand Down Expand Up @@ -1047,7 +1043,7 @@ sub log_alllink_table

&::print_log("[Insteon::AllLinkDatabase] Link table for "
. $$self{device}->get_object_name
. " health: " . $self->health);
. " is: " . $self->health);

# We want to log links sorted by ALDB address. Since the ALDB
# addresses are scattered throughout the %{$$self{aldb}} hash,
Expand Down Expand Up @@ -1084,7 +1080,7 @@ sub log_alllink_table
}

# Finally traverse the ALDB, but this time sorted by ALDB address
if ($self->health eq 'good')
if ($self->health eq 'unchanged')
{
foreach my $address (sort keys %aldb)
{
Expand Down Expand Up @@ -1164,7 +1160,7 @@ sub log_alllink_table
}
else
{
main::print_log("[Insteon::AllLinkDatabase] ALDB is ".$self->health." and will not be listed");
main::print_log("[Insteon::AllLinkDatabase] The link table is ".$self->health." and will not be listed");
}
}

Expand Down Expand Up @@ -1334,11 +1330,11 @@ sub _on_poke
$$self{aldb}{$aldbkey}{deviceid} = lc $$self{pending_aldb}{deviceid};
$$self{aldb}{$aldbkey}{group} = lc $$self{pending_aldb}{group};
$$self{aldb}{$aldbkey}{address} = $$self{pending_aldb}{address};
$self->health("good");
$self->health("unchanged");
}
# clear out mem_activity flag
$$self{_mem_activity} = undef;
$self->health("good");
$self->health("unchanged");
# Put the new ALDB Delta into memory
$self->query_aldb_delta('set');
}
Expand Down Expand Up @@ -1388,7 +1384,7 @@ sub _on_poke
$$self{pending_aldb}{data3});
delete $$self{aldb}{$key};
}
$self->health("good");
$self->health("unchanged");
# Put the new ALDB Delta into memory
$self->query_aldb_delta('set');
}
Expand Down Expand Up @@ -1502,12 +1498,12 @@ sub _on_peek
}
else
{
$self->health("good");
$self->health("unchanged");
}

&::print_log("[Insteon::ALDB_i1] " . $$self{device}->get_object_name . " completed link memory scan")
if $self->{device}->debuglevel(1, 'insteon');
$self->health("good");
$self->health("unchanged");
# Put the new ALDB Delta into memory
$self->query_aldb_delta('set');
}
Expand Down Expand Up @@ -2138,13 +2134,13 @@ sub on_read_write_aldb
}
else
{
$self->health("good");
$self->health("unchanged");
}

&::print_log("[Insteon::ALDB_i2] " . $$self{device}->get_object_name
. " completed link memory scan: status: " . $self->health())
. " completed link memory scan. Status: " . $self->health())
if $self->{device}->debuglevel(1, 'insteon');
$self->health("good");
$self->health("unchanged");
# Put the new ALDB Delta into memory
$self->query_aldb_delta('set');
}
Expand Down Expand Up @@ -2218,7 +2214,7 @@ sub on_read_write_aldb
main::print_log("[Insteon::ALDB_i2] DEBUG3: " . $$self{device}->get_object_name
. " link write completed for [".$$self{aldb}{$aldbkey}{address}."]")
if $self->{device}->debuglevel(3, 'insteon');
$self->health("good");
$self->health("unchanged");
# Put the new ALDB Delta into memory
$self->query_aldb_delta('set');
} else {
Expand All @@ -2236,7 +2232,7 @@ sub on_read_write_aldb
$$self{pending_aldb}{data3});
delete $$self{aldb}{$key};
}
$self->health("good");
$self->health("unchanged");
# Put the new ALDB Delta into memory
$self->query_aldb_delta('set');
}
Expand Down Expand Up @@ -2604,7 +2600,7 @@ Sends the request for the first alllink entry on the PLM.
sub get_first_alllink
{
my ($self) = @_;
$self->health('out-of-sync'); # set as corrupt and allow acknowledge to set otherwise
$self->health('changed'); # set as corrupt and allow acknowledge to set otherwise
$$self{device}->queue_message(new Insteon::InsteonMessage('all_link_first_rec', $$self{device}));
}

Expand Down Expand Up @@ -2702,6 +2698,7 @@ sub _process_delete_queue_failure {
push @{$$self{_delete_device_failures}}, $$self{current_delete_device};
::print_log("[Insteon::ALDB_PLM] WARN: failure occurred when deleting orphan links from: "
. $$self{current_delete_device} . ". Moving on...");
$self->health('changed');
$self->_process_delete_queue;

}
Expand Down Expand Up @@ -2849,7 +2846,7 @@ sub add_link
$$self{aldb}{$linkkey}{data2} = lc $data2;
$$self{aldb}{$linkkey}{data3} = lc $data3;
$$self{aldb}{$linkkey}{inuse} = 1;
$self->health('good') if($self->health() eq 'empty');
$self->health('unchanged') if($self->health() eq 'empty');
my $message = new Insteon::InsteonMessage('all_link_manage_rec', $$self{device});
$message->interface_data($cmd);
$$self{_success_callback} = ($link_parms{callback}) ? $link_parms{callback} : undef;
Expand All @@ -2861,10 +2858,11 @@ sub add_link

=item C<add_link_to_hash()>

This is used by the C<Insteon::BaseInterface::link_to_interface_i2cs> routine.
This routine manually adds a record to MH's cache of the PLM ALDB. Normally
you only want to add records during a scan of the ALDB, so use this routine
with caution.
This is used in response to an all_link_complete command received by the PLM.
This may be from the C<Insteon::BaseInterface::link_to_interface_i2cs> routine,
or it may be as a result of a manual link creation. This routine manually adds
a record to MH's cache of the PLM ALDB. Normally you only want to add records
during a scan of the ALDB, so use this routine with caution.

=cut

Expand All @@ -2880,7 +2878,7 @@ sub add_link_to_hash {
$$self{aldb}{$linkkey}{data2} = lc $data2;
$$self{aldb}{$linkkey}{data3} = lc $data3;
$$self{aldb}{$linkkey}{inuse} = 1;
$self->health('good') if($self->health() eq 'empty');
$self->health('unchanged') if($self->health() eq 'empty');
return;
}

Expand Down
18 changes: 9 additions & 9 deletions lib/Insteon/BaseInsteon.pm
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ sub _is_info_request
{
if ($self->_aldb->aldb_delta() eq $msg{cmd_code}){
&::print_log("[Insteon::BaseObject] The link table for "
. $self->{object_name} . " is in sync.");
. $self->{object_name} . " is unchanged.");
#Link Table Scan Successful, Record Current Time
$self->_aldb->scandatetime(&main::get_tickcount);
if (defined $self->_aldb->{_aldb_unchanged_callback}) {
Expand All @@ -716,16 +716,16 @@ sub _is_info_request
}
} else {
&::print_log("[Insteon::BaseObject] WARN The link table for "
. $self->{object_name} . " is out-of-sync.");
$self->_aldb->health('out-of-sync');
. $self->{object_name} . " has changed.");
$self->_aldb->health('changed');
if (defined $self->_aldb->{_aldb_changed_callback}) {
$callback = $self->_aldb->{_aldb_changed_callback};
$self->_aldb->{_aldb_changed_callback} = undef;
}
}
}
$self->_aldb->{aldb_delta_action} = undef;
$self->_aldb->health('out-of-sync') if($self->_aldb->aldb_delta() ne $msg{cmd_code});
$self->_aldb->health('changed') if($self->_aldb->aldb_delta() ne $msg{cmd_code});
if ($callback){
package main;
eval ($callback);
Expand Down Expand Up @@ -841,7 +841,7 @@ sub _process_message
else
{
if (($pending_cmd eq 'do_read_ee') &&
($self->_aldb->health eq "good" || $self->_aldb->health eq "empty") &&
($self->_aldb->health eq "unchanged" || $self->_aldb->health eq "empty") &&
($self->isa('Insteon::KeyPadLincRelay') || $self->isa('Insteon::KeyPadLinc'))){
## Update_Flags ends up here, set aldb_delta to new value
$self->_aldb->query_aldb_delta("set");
Expand Down Expand Up @@ -3172,7 +3172,7 @@ sub sync_links
."command on this specific device.");
$insteon_object_is_syncable = 0;
}
elsif ($insteon_object->_aldb->health ne 'good' && $insteon_object->_aldb->health ne 'empty'){
elsif ($insteon_object->_aldb->health ne 'unchanged' && $insteon_object->_aldb->health ne 'empty'){
::print_log("[Insteon::BaseController] WARN! The ALDB of $self_link_name is ".$insteon_object->_aldb->health
.", links will be added to devices "
."linked to this device, but no links will be added to $self_link_name. Please rescan this device and attempt "
Expand Down Expand Up @@ -3244,7 +3244,7 @@ sub sync_links

# 3. Does the responder link exist
if (!$member_root->has_link($insteon_object, $self->group, 0, $member->group) &&
($member_root->_aldb->health eq 'good' || $member_root->_aldb->health eq 'empty')){
($member_root->_aldb->health eq 'unchanged' || $member_root->_aldb->health eq 'empty')){
my %link_req = ( member => $member, cmd => 'add', object => $insteon_object,
group => $self->group, is_controller => 0,
on_level => $tgt_on_level, ramp_rate => $tgt_ramp_rate,
Expand All @@ -3255,7 +3255,7 @@ sub sync_links
push @{$$self{sync_queue}}, \%link_req;
$has_link = 0;
}
elsif ($member_root->_aldb->health ne 'good' && $member_root->_aldb->health ne 'empty'){
elsif ($member_root->_aldb->health ne 'unchanged' && $member_root->_aldb->health ne 'empty'){
my %link_req = ( member => $member, cmd => 'add', object => $insteon_object,
group => $self->group, is_controller => 0,
on_level => $tgt_on_level, ramp_rate => $tgt_ramp_rate,
Expand Down Expand Up @@ -3306,7 +3306,7 @@ sub sync_links
}
}
if ($requires_update &&
($member_root->_aldb->health eq 'good' || $member_root->_aldb->health eq 'empty')) {
($member_root->_aldb->health eq 'unchanged' || $member_root->_aldb->health eq 'empty')) {
my %link_req = ( member => $member, cmd => 'update', object => $insteon_object,
group => $self->group, is_controller => 0,
on_level => $tgt_on_level, ramp_rate => $tgt_ramp_rate,
Expand Down
38 changes: 19 additions & 19 deletions lib/Insteon/BaseInterface.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1007,25 +1007,25 @@ sub get_voice_cmds
my ($self) = @_;
my $object_name = $self->get_object_name;
my %voice_cmds = (
'complete linking as responder' => "$object_name->complete_linking_as_responder",
'initiate linking as controller' => "$object_name->initiate_linking_as_controller",
'initiate unlinking' => "$object_name->initiate_unlinking_as_controller",
'cancel linking' => "$object_name->cancel_linking",
'log links' => "$object_name->log_alllink_table",
'scan link table' => "$object_name->scan_link_table(\"" . '\$self->log_alllink_table' . "\")",
'scan changed device link tables' => "Insteon::scan_all_linktables(1)",
'delete orphan links' => "$object_name->delete_orphan_links",
'AUDIT - delete orphan links' => "$object_name->delete_orphan_links(1)",
'scan all device link tables' => "Insteon::scan_all_linktables",
'sync all links' => "Insteon::sync_all_links(0)",
'AUDIT - sync all links' => "Insteon::sync_all_links(1)",
'print all message stats' => "Insteon::print_all_message_stats",
'reset all message stats' => "Insteon::reset_all_message_stats",
'stress test ALL devices' => "Insteon::stress_test_all(5,1)",
'ping test ALL devices' => "Insteon::ping_all(5)",
'log all device ALDB status' => "Insteon::log_all_ADLB_status",
'enable monitor mode' => "$object_name->enable_monitor_mode(1)",
'disable monitor mode' => "$object_name->enable_monitor_mode(0)",
'plm - complete linking as responder' => "$object_name->complete_linking_as_responder",
'plm - initiate linking as controller' => "$object_name->initiate_linking_as_controller",
'plm - initiate unlinking' => "$object_name->initiate_unlinking_as_controller",
'plm - cancel linking' => "$object_name->cancel_linking",
'plm - log links' => "$object_name->log_alllink_table",
'plm - scan PLM link table' => "$object_name->scan_link_table(\"" . '\$self->log_alllink_table' . "\")",
'global - scan changed device link tables' => "Insteon::scan_all_linktables(1)",
'global - delete orphan links' => "$object_name->delete_orphan_links",
'global - audit delete orphan links' => "$object_name->delete_orphan_links(1)",
'global - force scan all device link tables' => "Insteon::scan_all_linktables",
'global - sync all links' => "Insteon::sync_all_links(0)",
'global - audit sync all links' => "Insteon::sync_all_links(1)",
'global - print all message stats' => "Insteon::print_all_message_stats",
'global - reset all message stats' => "Insteon::reset_all_message_stats",
'global - stress test ALL devices' => "Insteon::stress_test_all(5,1)",
'global - ping test ALL devices' => "Insteon::ping_all(5)",
'global - log all device ALDB status' => "Insteon::log_all_ADLB_status",
'plm - enable monitor mode' => "$object_name->enable_monitor_mode(1)",
'plm - disable monitor mode' => "$object_name->enable_monitor_mode(0)",
);
return \%voice_cmds;
}
Expand Down
Loading