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: Redesign Voice Command Creation #236

Merged
merged 4 commits into from
Jul 31, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 23 additions & 73 deletions lib/Insteon.pm
Original file line number Diff line number Diff line change
Expand Up @@ -554,87 +554,37 @@ sub generate_voice_commands
for my $object (&main::list_all_objects) {
next unless ref $object;
next unless $object->isa('Insteon::BaseInterface') or $object->isa('Insteon::BaseObject');

#get object name to use as part of variable in voice command
my $object_name = $object->get_object_name;
# ignore the thermostat
next if $object->isa('Insteon_Thermostat');
my $object_name_v = $object_name . '_v';
$object_string .= "use vars '${object_name}_v';\n";

#Convert object name into readable voice command words
my $command = $object_name;
$command =~ s/^\$//;
$command =~ tr/_/ /;
my $object_name_v = $object_name . '_v';
$object_string .= "use vars '${object_name}_v';\n";
my $states = 'on,off';

my $group = ($object->isa('Insteon_PLM')) ? '' : $object->group;
if ($object->isa('Insteon::BaseController')) {
$states = 'on,off,sync links'; #,resume,enroll,unenroll,manual';
my $cmd_states = $states;
if ($object->isa('Insteon::InterfaceController')) {
$cmd_states .= ',initiate linking as controller,cancel linking';
} else {
$cmd_states .= ",link to interface,unlink with interface";
}
if ($object->is_root and !($object->isa('Insteon::InterfaceController'))) {
$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";
$object_string .= "$object_name_v -> tie_event('$object_name->initiate_linking_as_controller(\"$group\")', 'initiate linking as controller');\n\n";
$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->link_to_interface','link to interface');\n\n";
$object_string .= "$object_name_v -> tie_event('$object_name->unlink_to_interface','unlink with interface');\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->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";
}
$object_string .= "$object_name_v -> tie_event('$object_name->sync_links(0)','sync links');\n\n";
$object_string .= "$object_name_v -> tie_items($object_name, 'on');\n\n";
$object_string .= "$object_name_v -> tie_items($object_name, 'off');\n\n";
$object_string .= &main::store_object_data($object_name_v, 'Voice_Cmd', 'Insteon', 'Insteon_link_commands');
push @_insteon_link, $object_name;
} elsif ($object->isa('Insteon::BaseDevice')) {
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)) {
$object_string .= "$object_name_v -> tie_items($object_name, '$state');\n\n";
}
$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) {
$object_string .= "$object_name_v -> tie_event('$object_name->link_to_interface','link to interface');\n\n";
$object_string .= "$object_name_v -> tie_event('$object_name->unlink_to_interface','unlink with interface');\n\n";
}
# the remote_set_button_taps provide incorrect/inconsistent results
# $object_string .= "$object_name_v -> tie_event('$object_name->remote_set_button_tap(1)','on level');\n\n";
# $object_string .= "$object_name_v -> tie_event('$object_name->remote_set_button_tap(2)','ramp rate');\n\n";
$object_string .= &main::store_object_data($object_name_v, 'Voice_Cmd', 'Insteon', 'Insteon_item_commands');
push @_insteon_device, $object_name if $group eq '01'; # don't allow non-base items to participate
} elsif ($object->isa('Insteon_PLM')) {
my $cmd_states = "complete linking as responder,initiate linking as controller,cancel linking,delete link with PLM,scan link table,log links,delete orphan links,AUDIT - delete orphan links,scan all device link tables,scan changed device link tables,sync all links,AUDIT - sync all links";
$cmd_states .= ",log all device ALDB status";
$object_string .= "$object_name_v = new Voice_Cmd '$command [$cmd_states]';\n";
$object_string .= "$object_name_v -> tie_event('$object_name->complete_linking_as_responder','complete linking as responder');\n\n";
$object_string .= "$object_name_v -> tie_event('$object_name->initiate_linking_as_controller','initiate linking as controller');\n\n";
$object_string .= "$object_name_v -> tie_event('$object_name->initiate_unlinking_as_controller','initiate unlinking');\n\n";
$object_string .= "$object_name_v -> tie_event('$object_name->cancel_linking','cancel linking');\n\n";
$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->scan_link_table(\"" . '\$self->log_alllink_table' . "\")','scan link table');\n\n";
$object_string .= "$object_name_v -> tie_event('&Insteon::scan_all_linktables(1)','scan changed device link tables');\n\n";
$object_string .= "$object_name_v -> tie_event('$object_name->delete_orphan_links','delete orphan links');\n\n";
$object_string .= "$object_name_v -> tie_event('$object_name->delete_orphan_links(1)','AUDIT - delete orphan links');\n\n";
$object_string .= "$object_name_v -> tie_event('&Insteon::scan_all_linktables','scan all device link tables');\n\n";
$object_string .= "$object_name_v -> tie_event('&Insteon::sync_all_links(0)','sync all links');\n\n";
$object_string .= "$object_name_v -> tie_event('&Insteon::sync_all_links(1)','AUDIT - sync all links');\n\n";
$object_string .= "$object_name_v -> tie_event('&Insteon::log_all_ADLB_status','log all device ALDB status');\n\n";
$object_string .= &main::store_object_data($object_name_v, 'Voice_Cmd', 'Insteon', 'Insteon_PLM_commands');
push @_insteon_plm, $object_name;

#Get list of all voice commands from the object
my $voice_cmds = $object->get_voice_cmds();

#Initialize the voice command with all of the possible device commands
$object_string .= "$object_name_v = new Voice_Cmd '$command ["
. join(",", sort keys %$voice_cmds) . "]';\n";

#Tie the proper routine to each voice command
foreach (keys %$voice_cmds) {
$object_string .= "$object_name_v -> tie_event('" . $voice_cmds->{$_}
. "', '$_');\n\n";
}

#Add this object to the list of Insteon Voice Commands on the Web Interface
$object_string .= ::store_object_data($object_name_v, 'Voice_Cmd', 'Insteon', 'Insteon_PLM_commands');
}

#Evaluate the resulting object generating string
package main;
eval $object_string;
print "Error in insteon_item_commands: $@\n" if $@;
Expand Down
2 changes: 1 addition & 1 deletion lib/Insteon/AllLinkDatabase.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1935,7 +1935,7 @@ sub update_local_properties

=item C<update_flags()>

Used to update the flags of a device. Called by L<Insteon::BaseDevice::update_flags()|Insteon::BaseInsteon/Insteon::BaseDevice>.
Used to update the flags of a device. Called by L<Insteon::KeyPadLinc::update_flags()|Insteon::Lighting/Insteon::KeyPadLinc>.

=cut

Expand Down
118 changes: 88 additions & 30 deletions lib/Insteon/BaseInsteon.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1012,6 +1012,34 @@ sub failure_reason
return $$self{failure_reason};
}

=item C<get_voice_cmds>

Returns a hash of voice commands where the key is the voice command name and the
value is the perl code to run when the voice command name is called.

Higher classes which inherit this object may add to this list of voice commands by
redefining this routine while inheriting this routine using the SUPER function.

This routine is called by L<Insteon::generate_voice_commands> to generate the
necessary voice commands.

=cut

sub get_voice_cmds
{
my ($self) = @_;
my %voice_cmds = (
#The Sync Links routine really resides in DeviceController, but that
#class seems a little redundant as in practice all devices are controllers
#in some sense. As a result, that class will likely be folded into
#BaseObject/Device at some future date. In order to avoid a bizarre
#inheritance of this routine by higher classes, this command was placed
#here
'sync links' => $self->get_object_name . '->sync_links(0)'
);
return \%voice_cmds;
}

=back

=head2 INI PARAMETERS
Expand Down Expand Up @@ -1925,36 +1953,6 @@ sub update_local_properties
}
}

=item C<update_flags(flags)>

Can be used to set the button layout and light level on a keypadlinc. Flag
options include:

'0a' - 8 button; backlighting dim
'06' - 8 button; backlighting off
'02' - 8 button; backlighting normal

'08' - 6 button; backlighting dim
'04' - 6 button; backlighting off
'00' - 6 button; backlighting normal

Note: This routine will likely be moved to L<Insteon::KeypadLinc|Insteon::Lighting/Insteon::KeypadLinc> at some point.

=cut

sub update_flags
{
my ($self, $flags) = @_;
if (!($self->isa('Insteon::KeyPadLinc') or $self->isa('Insteon::KeyPadLincRelay')))
{
&::print_log("[Insteon::BaseDevice] Operating flags may only be revised on keypadlincs!");
return;
}
return unless defined $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,
Expand Down Expand Up @@ -2032,6 +2030,40 @@ sub check_aldb_version
}
}

=item C<get_voice_cmds>

Returns a hash of voice commands where the key is the voice command name and the
value is the perl code to run when the voice command name is called.

Higher classes which inherit this object may add to this list of voice commands by
redefining this routine while inheriting this routine using the SUPER function.

This routine is called by L<Insteon::generate_voice_commands> to generate the
necessary voice commands.

=cut

sub get_voice_cmds
{
my ($self) = @_;
my $object_name = $self->get_object_name;
my %voice_cmds = (
%{$self->SUPER::get_voice_cmds},
'link to interface' => "$object_name->link_to_interface",
'unlink with interface' => "$object_name->unlink_to_interface"
);
if ($self->is_root){
%voice_cmds = (
%voice_cmds,
'status' => "$object_name->request_status",
'get engine version' => "$object_name->get_engine_version",
'scan link table' => "$object_name->scan_link_table(\"" . '\$self->log_alllink_table' . "\")",
'log links' => "$object_name->log_alllink_table()"
)
}
return \%voice_cmds;
}

=back

=head2 INI PARAMETERS
Expand Down Expand Up @@ -2953,6 +2985,32 @@ sub is_root
return 0;
}

=item C<get_voice_cmds>

Returns a hash of voice commands where the key is the voice command name and the
value is the perl code to run when the voice command name is called.

Higher classes which inherit this object may add to this list of voice commands by
redefining this routine while inheriting this routine using the SUPER function.

This routine is called by L<Insteon::generate_voice_commands> to generate the
necessary voice commands.

=cut

sub get_voice_cmds
{
my ($self) = @_;
my $object_name = $self->get_object_name;
my $group = $self->group;
my %voice_cmds = (
%{$self->SUPER::get_voice_cmds},
'initiate linking as controller' => "$object_name->initiate_linking_as_controller(\"$group\")",
'cancel linking' => "$object_name->interface()->cancel_linking"
);
return \%voice_cmds;
}

=back

=head2 AUTHOR
Expand Down
35 changes: 35 additions & 0 deletions lib/Insteon/BaseInterface.pm
Original file line number Diff line number Diff line change
Expand Up @@ -852,6 +852,41 @@ sub _is_duplicate_received {
return $is_duplicate;
}

=item C<get_voice_cmds>

Returns a hash of voice commands where the key is the voice command name and the
value is the perl code to run when the voice command name is called.

Higher classes which inherit this object may add to this list of voice commands by
redefining this routine while inheriting this routine using the SUPER function.

This routine is called by L<Insteon::generate_voice_commands> to generate the
necessary voice commands.

=cut

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)",
'log all device ALDB status' => "Insteon::log_all_ADLB_status"
);
return \%voice_cmds;
}

=back

=head2 INI PARAMETERS
Expand Down
41 changes: 41 additions & 0 deletions lib/Insteon/IOLinc.pm
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,47 @@ sub set_relay_mode
return;
}

=item C<get_voice_cmds>

Returns a hash of voice commands where the key is the voice command name and the
value is the perl code to run when the voice command name is called.

Higher classes which inherit this object may add to this list of voice commands by
redefining this routine while inheriting this routine using the SUPER function.

This routine is called by L<Insteon::generate_voice_commands> to generate the
necessary voice commands.

=cut

sub get_voice_cmds
{
my ($self) = @_;
my $object_name = $self->get_object_name;
my %voice_cmds = (
%{$self->SUPER::get_voice_cmds},
#Rename status command to note that it will request status of the
#relay
'on' => "$object_name->set(\"on\")",
'off' => "$object_name->set(\"off\")",
'status - relay' => "$object_name->request_status",
'status - sensor' => "$object_name->request_sensor_status",
'print momentary time' => "$object_name->get_momentary_time",
'link relay to sensor' => "$object_name->set_relay_linked(1)",
'unlink relay from sensor' => "$object_name->set_relay_linked(0)",
'reverse sensor output' => "$object_name->set_trigger_reverse(1)",
'unreverse sensor output' => "$object_name->set_trigger_reverse(0)",
'set relay to latching' => "$object_name->set_relay_mode(\"Latching\")",
'set relay to momentary a' => "$object_name->set_relay_mode(\"Momentary_A\")",
'set relay to momentary b' => "$object_name->set_relay_mode(\"Momentary_B\")",
'set relay to momentary c' => "$object_name->set_relay_mode(\"Momentary_C\")",
'print settings to log' => "$object_name->get_operating_flag"
);
#Remove generic status command
delete $voice_cmds{status};
return \%voice_cmds;
}

=back

=head2 AUTHOR
Expand Down
Loading