diff --git a/lib/Insteon.pm b/lib/Insteon.pm index d882a0a97..e65106b9a 100755 --- a/lib/Insteon.pm +++ b/lib/Insteon.pm @@ -253,7 +253,7 @@ sub generate_voice_commands $cmd_states .= ",link to interface,unlink with interface"; } if ($object->is_root and !($object->isa('Insteon::InterfaceController'))) { - $cmd_states .= ",status,scan link table,log links"; + $cmd_states .= ",status,get engine version,scan link table,log links"; push @_scannable_link, $object_name; } $object_string .= "$object_name_v = new Voice_Cmd '$command [$cmd_states]';\n"; @@ -261,6 +261,7 @@ sub generate_voice_commands $object_string .= "$object_name_v -> tie_event('$object_name->interface()->cancel_linking','cancel linking');\n\n"; if ($object->is_root and !($object->isa('Insteon::InterfaceController'))) { $object_string .= "$object_name_v -> tie_event('$object_name->request_status','status');\n\n"; + $object_string .= "$object_name_v -> tie_event('$object_name->get_engine_version','get engine version');\n\n"; $object_string .= "$object_name_v -> tie_event('$object_name->scan_link_table(\"" . '\$self->log_alllink_table' . "\")','scan link table');\n\n"; $object_string .= "$object_name_v -> tie_event('$object_name->log_alllink_table()','log links');\n\n"; } @@ -272,7 +273,7 @@ sub generate_voice_commands } elsif ($object->isa('Insteon::BaseDevice')) { $states = $insteon_menu_states if $insteon_menu_states && ($object->can('is_dimmable') && $object->is_dimmable); - my $cmd_states = "$states,status,scan link table,log links,update onlevel/ramprate"; #,on level,ramp rate"; + my $cmd_states = "$states,status,get engine version,scan link table,log links,update onlevel/ramprate"; #,on level,ramp rate"; $cmd_states .= ",link to interface,unlink with interface" if $object->isa("Insteon::BaseController") || $object->is_controller; $object_string .= "$object_name_v = new Voice_Cmd '$command [$cmd_states]';\n"; foreach my $state (split(/,/,$states)) { @@ -280,6 +281,7 @@ sub generate_voice_commands } $object_string .= "$object_name_v -> tie_event('$object_name->log_alllink_table()','log links');\n\n"; $object_string .= "$object_name_v -> tie_event('$object_name->request_status','status');\n\n"; + $object_string .= "$object_name_v -> tie_event('$object_name->get_engine_version','get engine version');\n\n"; $object_string .= "$object_name_v -> tie_event('$object_name->update_local_properties','update onlevel/ramprate');\n\n"; $object_string .= "$object_name_v -> tie_event('$object_name->scan_link_table(\"" . '\$self->log_alllink_table' . "\")','scan link table');\n\n"; if ($object->isa("Insteon::BaseController") || $object->is_controller) { @@ -504,4 +506,4 @@ sub find_members { return @l_found; } -1 \ No newline at end of file +1 diff --git a/lib/Insteon/BaseInsteon.pm b/lib/Insteon/BaseInsteon.pm index 0f144ba2f..ae2db4270 100755 --- a/lib/Insteon/BaseInsteon.pm +++ b/lib/Insteon/BaseInsteon.pm @@ -40,6 +40,14 @@ our %message_types = ( off => 0x13 ); +our %nack_messages = ( + fb => 'illegal_value_in_cmd', + fc => 'pre_nak_long_db_search', + fd => 'bad_checksum_or_unknown_cmd', + fe => 'load_sense_detects_no_load', + ff => 'sender_id_not_in_responder_aldb', +); + sub derive_link_state { my ($p_state) = @_; @@ -435,6 +443,19 @@ sub _is_info_request } # if this were a scene controller, then also propogate the result to all members } + elsif ( $cmd eq 'get_engine_version' ) { + my $version = $msg{extra}; + $version++; # version retuned in cmd2 is 0 indexed + if ( $version == 3 ) { + $version = 'I2CS'; + } + else { + $version = 'I'. sprintf( "%1d",$version); + } + &::print_log("[Insteon::BaseObject] received engine version for " + . $self->{object_name} . " of $version."); + } + return $is_info_request; } @@ -503,16 +524,21 @@ sub _process_message # } # else # { - if ($self->isa('Insteon::BaseLight')) - { - &::print_log("[Insteon::BaseObject] WARN!! encountered a nack message for " . $self->{object_name} + if ($self->isa('Insteon::BaseLight')) { + + &::print_log("[Insteon::BaseObject] WARN!! encountered a nack message (" + . $self->get_nack_msg_for( $msg{extra} ) + .") for " + . $self->{object_name} . ". It may be unplugged or have a burned out bulb") if $main::Debug{insteon}; - } - else - { - &::print_log("[Insteon::BaseObject] WARN!! encountered a nack message for " . $self->{object_name} + } + else { + &::print_log("[Insteon::BaseObject] WARN!! encountered a nack message (" + . $self->get_nack_msg_for( $msg{extra} ) + .") for " + . $self->{object_name} . " ... skipping"); - } + } $self->is_acknowledged(0); $self->_process_command_stack(%msg); # } @@ -635,6 +661,11 @@ sub _is_valid_state } } +# Provide human readable nack message. +sub get_nack_msg_for { + my ($self,$msg) = @_; + return $nack_messages{ $msg }; +} #################################### ### ##################### @@ -656,6 +687,7 @@ our %message_types = ( delete_from_group => 0x02, linking_mode => 0x09, unlinking_mode => 0x0A, + get_engine_version => 0x0D, ping => 0x10, on_fast => 0x12, off_fast => 0x14, @@ -1020,6 +1052,13 @@ sub request_status # $self->_send_cmd('command' => 'status_request', 'is_synchronous' => 1); } +sub get_engine_version { + my ($self, $requestor) = @_; + + my $message = new Insteon::InsteonMessage('insteon_send', $self, 'get_engine_version'); + $self->_send_cmd($message); +} + sub ping { my ($self) = @_; @@ -1815,4 +1854,4 @@ sub is_root return 0; } -1; \ No newline at end of file +1;