diff --git a/lib/Insteon.pm b/lib/Insteon.pm index 251b41145..eb3b59c47 100755 --- a/lib/Insteon.pm +++ b/lib/Insteon.pm @@ -6,22 +6,169 @@ use strict; #@ This module creates voice commands for all insteon related items. -=head1 NAME +=head1 B -B - This module ..... +=head2 DESCRIPTION -=head1 SYNOPSIS +Provides the basic infrastructure for the Insteon stack, contains many of the +startup routines. +=head2 INHERITS -=head1 DESCRIPTION +None + +=head2 VOICE COMMANDS + +=head3 PLM + +=over + +=item C + +If a device is first placed into linking mode, calling this command will cause +the PLM to complete the link, thus making the PLM the responder. The +C device voice command is likely an easier way to do this, +but this may be need for hard to reach devices or deaf devices. + +=item C + +Call this first, then press and hold the set button on a device that you wish +to have the PLM control. The C device voice command is +likely an easier way to do this, but this may be need for hard to reach devices +or deaf devices. This is also needed for i2cs devices in which the first link +must currently be manually created this way. + +=item C + +Cancel either of the above two commands without completing a link. + +=item C + +This does nothing and shoudl be removed. + +=item C + +This will scan and output to the log only the PLM link table. + +=item C + +This will output only the PLM link table to log. + +=item C + +Misterhouse will review the state of all of the links in your system, as it knows +them without any additional scanning. If any of these links are not defined in +your mht file or the links are only half links (controller with no responder or +vice versa) MisterHouse will delete these links. + +It is usually best to: + +1. Run C first unless you know that the +information in MisterHouse is up-to-date. +2. Run C and verify that what is being added is correct. -=head1 INHERITS +3. Run C to add the links -This module inherits nothing +4. Run C first to see what will happen. +5. If everything looks right, run C to clean up the old links -=head1 METHODS +Deleting the orphan links will make your devices happier. If you have unintended +links on your devices, they can run slower and may unnecessarily increase the +number of messages sent on your network. + +=item C + +Does the same thing as C but doesn't actually delete anything +instead it just prints what it would have done to the log. + +=item C + +Scans the link tables of the PLM and all devices on your network. On a large +network this can take sometime. You can generally run C +which is much faster without any issue. + +=item C + +Scans the link tables of the PLM and all devices whose link tables have changed +on your network. + +=item C + +Similar to C exccept this adds any links that are missing. +This is helpful when adding a bunch of new devices, new scenes, or cleaning things +up. + +See the workflow described in C. + +=item C + +Same as C but prints what it would do to the log, without doing +anything else. + +=item C + +Logs some details about each device to the log. See C + +=back + +=head3 Devices + +=over + +=item on + +Turns the device on. + +=item off + +Turns the device off. + +=item Sync Links + +Similar to C above, but this will only add links that are related +to this device. Useful when adding a new device. + +=item Link to Interface + +Will create the controller/responder links between the device and the PLM. + +=item Unlink with Interface + +Will delete the controller/responder links between the device and the PLM. +Useful if you are removing a device from your network. + +=item Status + +Requests the status of the device. + +=item Get Engine Version + +Requests the engine version of the device. Generally you would not need to call +this, but every now and then it is needed when a new device is installed. + +=item Scan Link Table + +This will scan and output to the log only the link table of this device. + +=item Log Links + +Will output to the log only the link table of this device. + +=item Initiate Linking as Controller + +Generally only available for PLM Scenes. This places the PLM in linking mode +and adds any device which the set button is pressed for 4 seconds as a responder +to this scene. Generally not needed. + +=item Cancel Linking + +Cancels the above linking session without creating a link. + +=back + +=head2 METHODS =over @@ -93,6 +240,13 @@ sub scan_all_linktables &_get_next_linkscan($skip_unchanged); } +=item C<_get_next_linkscan_failure()> + +Called if a the scanning of a device fails. Logs the failure and proceeds to +the next device. + +=cut + sub _get_next_linkscan_failure { my($skip_unchanged) = @_; @@ -103,6 +257,12 @@ sub _get_next_linkscan_failure } +=item C<_get_next_linkscan()> + +Gets the next device to scan. + +=cut + sub _get_next_linkscan { my($skip_unchanged, $changed_device) = @_; @@ -151,10 +311,10 @@ calling the device's sync_links() command. sync_all_links() loads up the module global variable @_sync_devices then kicks off the recursive call backs by calling _get_next_linksync. -=item B - Causes sync to walk through but not actually +Paramter B - Causes sync to walk through but not actually send any commands to the devices. Useful with the insteon:3 debug setting for troubleshooting. - + =cut sub sync_all_links @@ -256,24 +416,39 @@ sub _get_next_linksync_failure } + =item C Walks through every Insteon device and logs: -=over(8) +=back + +=over8 + +=item * + +Hop Count -- Hop Count +=item * -- Engine Version +Engine Version -- ALDB Type +=item * -- ALDB Health +ALDB Type -- ALDB Scan Time +=item * + +ALDB Health + +=item * + +ALDB Scan Time =back +=over + =cut sub log_all_ADLB_status @@ -313,6 +488,11 @@ sub log_all_ADLB_status } } +=item C + +Initiates the insteon stack, mostly just sets the trigger. + +=cut sub init { @@ -357,6 +537,15 @@ sub init { } +=item C + +Generates and sets the voice commands for all Insteon devices. + +Note: At some point, this function will be pushed out to the specific classes +so that each class can have its own unique set of voice commands. + +=cut + sub generate_voice_commands { @@ -455,6 +644,13 @@ sub generate_voice_commands package Insteon; } +=item C + +Adds object to the list of insteon objects that are managed by the stack. Makes +the object eligible for linking, scanning, and global functions. + +=cut + sub add { my ($object) = @_; @@ -466,6 +662,12 @@ sub add $insteon_manager->add_item($object); } +=item C + +Called as a non-object routine. Returns the object named name. + +=cut + sub find_members { my ($name) = @_; @@ -474,6 +676,13 @@ sub find_members return $insteon_manager->find_members($name); } +=item C + +Returns the object identified by p_id and p_group. Where p_id is the 6 digit +hexadecimal address of the object without periods and group is a two digit +representation of the group number of the device. + +=cut sub get_object { @@ -509,6 +718,13 @@ sub get_object return $retObj; } +=item C + +Sets p_interface as the new active interface. Should likely only be called on +startup or reload. + +=cut + sub active_interface { my ($interface) = @_; @@ -555,12 +771,59 @@ sub check_all_aldb_versions main::print_log("[Insteon] DEBUG4 Checking aldb version of all devices completed") if ($main::Debug{insteon} >= 4); } +=back + +=head2 INI PARAMETERS + +=over + +=item insteon_menu_states + +A comma seperated list of states that will be added as voice commands to dimmable +devices. + +=back + +=head2 AUTHOR + +Gregg Limming, Kevin Robert Keegan, Micheal Stovenour, many others + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=head1 B + +=head2 DESCRIPTION + +Provides the basic infrastructure for the Insteon stack, contains many of the +startup routines. + +=head2 INHERITS + +L + +=head2 METHODS + +=over + +=cut package InsteonManager; use strict; use base 'Class::Singleton'; +=item C<_new_instance()> + +Defines a new instance of the class. + +=cut + sub _new_instance { my $class = shift; @@ -569,6 +832,13 @@ sub _new_instance return $self; } +=item C<_active_interface()> + +Sets and returns the active interface. Likely should only be caled on startup +or reload. It also sets all of the hooks for the Insteon stack. + +=cut + sub _active_interface { my ($self, $interface) = @_; @@ -586,6 +856,12 @@ sub _active_interface return $$self{active_interface}; } +=item C + +Adds a list of objects to be tracked. + +=cut + sub add { my ($self,@p_objects) = @_; @@ -604,6 +880,12 @@ sub add } } +=item C + +Adds an object to be tracked. + +=cut + sub add_item { my ($self,$p_object) = @_; @@ -615,6 +897,12 @@ sub add_item return $p_object; } +=item C + +Removes all of the Insteon objects. + +=cut + sub remove_all_items { my ($self) = @_; @@ -626,6 +914,12 @@ sub remove_all_items { delete $self->{objects}; } +=item C + +Adds an item to be tracked if it is not already in the list. + +=cut + sub add_item_if_not_present { my ($self, $p_object) = @_; @@ -640,6 +934,12 @@ sub add_item_if_not_present { return 1; } +=item C + +Removes the Insteon object. + +=cut + sub remove_item { my ($self, $p_object) = @_; return 0 unless $p_object and ref $p_object; @@ -654,6 +954,11 @@ sub remove_item { return 0; } +=item C + +Returns true if object is in the list. + +=cut sub is_member { my ($self, $p_object) = @_; @@ -667,6 +972,13 @@ sub is_member { return 0; } +=item C + +Find and return all tracked objects of type p_type where p_type is an object +class. + +=cut + sub find_members { my ($self,$p_type) = @_; @@ -680,7 +992,9 @@ sub find_members { return @l_found; } -=head1 INI PARAMETERS +=back + +=head2 INI PARAMETERS =over @@ -690,15 +1004,15 @@ For debugging debug=insteon or debug=insteon:level where level is 1-4. =back -=head1 AUTHOR +=head2 AUTHOR -Bruce Winter +Bruce Winter, Gregg Liming, Kevin Robert Keegan, Michael Stovenour, many others -=head1 SEE ALSO +=head2 SEE ALSO None -=head1 LICENSE +=head2 LICENSE This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/lib/Insteon/AllLinkDatabase.pm b/lib/Insteon/AllLinkDatabase.pm index 52cdea2c0..5c7918641 100644 --- a/lib/Insteon/AllLinkDatabase.pm +++ b/lib/Insteon/AllLinkDatabase.pm @@ -1,27 +1,34 @@ -=begin comment -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +package Insteon::AllLinkDatabase; -File: - AllLinkDatabase.pm +=head1 B -Description: - Generic class implementation of an insteon device's all link database. +=head2 SYNOPSIS -Author(s): - Gregg Liming / gregg@limings.net +Generic class implementation of an insteon device's all link database. -License: - This free software is licensed under the terms of the GNU public license. +=head2 DESCRIPTION +Generally this object should be interacted with through the insteon objects and +not by directly calling any of the following methods. -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -=cut +=head2 INHERITS +None -package Insteon::AllLinkDatabase; +=head2 METHODS + +=over + +=cut use strict; +=item C + +Instantiate a new object. + +=cut + sub new { my ($class, $device) = @_; @@ -39,6 +46,16 @@ sub _send_cmd $$self{device}->_send_cmd($msg); } +=item C + +Used to track the ALDB version type. + +If provided, saves version to memory. + +Returns the saved version type. + +=cut + sub aldb_version { my ($self, $aldb_version) = @_; @@ -46,17 +63,33 @@ sub aldb_version return $$self{aldb_version}; } +=item C + +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. + +=cut + sub health { - # out-of-sync - # unknown - # empty - # good my ($self, $health) = @_; $$self{health} = $health if defined $health; return $$self{health}; } +=item C + +Used to track the time, in unix time seconds, of the last ALDB scan. + +If provided, saves the time to memory. + +Returns the time of the last ALDB scan. + +=cut + sub scandatetime { my ($self, $scandatetime) = @_; @@ -64,6 +97,19 @@ sub scandatetime return $$self{scandatetime}; } +=item C + +Used to track the ALDB Delta. The ALDB Delta starts at 00 and iterates ++1 for each change to a device's ALDB. The ALDB Delta will be reset to 00 +whenever power is lost to the device or if the device is factory reset. + +If provided, saves the hex value to memory. (This should likely only be done by +C) + +Returns the current ALDB Delta. + +=cut + sub aldb_delta { my ($self, $p_aldb_delta) = @_; @@ -71,6 +117,21 @@ sub aldb_delta return $$self{aldb_delta}; } +=item C + +Interacts with the device's ALDB Delta. + +If called with "check", MisterHouse will query the device to obtain the current +ALDB Delta. If the ALDB Delta matches the version stored in C +MisterHouse will eval the code stored in C<$self->{_aldb_unchanged_callback}>. +If the ALDB Delta does not match, MisterHouse will eval the code stored in +C<$self->{_aldb_changed_callback}>. + +If called with "set" will cause MisterHouse to query the device for its ALDB +Delta and will store it with C. + +=cut + sub query_aldb_delta { my ($self, $action) = @_; @@ -107,6 +168,12 @@ sub query_aldb_delta } } +=item C + +This is called by mh on exit to save the cached ALDB of a device to persistant data. + +=cut + sub restore_string { my ($self) = @_; @@ -158,6 +225,12 @@ sub restore_string return $restore_string; } +=item C + +Used to reload MisterHouse's cached version of a device's ALDB on restart. + +=cut + sub restore_aldb { my ($self,$aldb) = @_; @@ -203,6 +276,12 @@ sub restore_aldb } } +=item C + +Scans a device's link table and caches a copy. + +=cut + sub scan_link_table { my ($self,$success_callback,$failure_callback) = @_; @@ -218,6 +297,12 @@ sub scan_link_table } } +=item C + +Deletes a specific link from a device. Generally called by C. + +=cut + sub delete_link { my ($self, $parms_text) = @_; @@ -316,6 +401,14 @@ sub delete_link } } +=item C + +Reviews the cached version of all of the ALDBs and based on this review removes +links from this device which are not present in the mht file, not defined in the +code, or links which are only half-links.. + +=cut + sub delete_orphan_links { my ($self, $audit_mode) = @_; @@ -768,6 +861,12 @@ sub _process_delete_queue { } } +=item C + +Adds address to the duplicate link hash. Called as part of C. + +=cut + sub add_duplicate_link_address { my ($self, $address) = @_; @@ -779,6 +878,12 @@ sub add_duplicate_link_address } +=item C + +Removes address from the duplicate link hash. Called as part of C. + +=cut + sub delete_duplicate_link_address { my ($self, $address) = @_; @@ -800,6 +905,13 @@ sub delete_duplicate_link_address } } +=item C + +Adds address to the empty link hash. Called as part of C +or C. + +=cut + sub add_empty_address { my ($self, $address) = @_; @@ -829,6 +941,14 @@ sub add_empty_address } +=item C + +Returns the highest empty link address, or if no empty addresses exist, returns +the highest unused address. Called as part of C or +C.. + +=cut + sub get_first_empty_address { my ($self) = @_; @@ -866,6 +986,13 @@ sub get_first_empty_address return $first_address; } +=item C + +Adds the link to the device's ALDB. Generally called from the "sync links" or +"link to interface" voice commands. + +=cut + sub add_link { my ($self, $parms_text) = @_; @@ -992,6 +1119,13 @@ sub add_link } } +=item C + +Updates the on_level and/or ramp_rate associated with a link to match the defined +value in MisterHouse. Generally called from the "sync links" voice command. + +=cut + sub update_link { my ($self, %link_parms) = @_; @@ -1063,6 +1197,14 @@ sub update_link } } +=item C + +Prints a human readable form of MisterHouse's cached version of a device's ALDB +to the print log. Called as part of the "scan links" voice command +or in response to the "log links" voice command. + +=cut + sub log_alllink_table { my ($self) = @_; @@ -1191,6 +1333,13 @@ sub log_alllink_table } } +=item C + +Checks and returns true if a link with the passed details exists on the device +or false if it does not. Generally called as part of C. + +=cut + sub has_link { my ($self, $insteon_object, $group, $is_controller, $subaddress) = @_; @@ -1212,12 +1361,59 @@ sub has_link return (defined $$self{aldb}{$key}); } +=back + +=head2 INI PARAMETERS + +None + +=head2 AUTHOR + +Gregg Liming / gregg@limings.net, Kevin Robert Keegan, Michael Stovenour + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut + package Insteon::ALDB_i1; +=head1 B + +=head2 SYNOPSIS + +Unique class for storing a cahced copy of a verion i1 device's ALDB. + +=head2 DESCRIPTION + +Generally this object should be interacted with through the insteon objects and +not by directly calling any of the following methods. + +=head2 INHERITS + +L + +=head2 METHODS + +=over + +=cut + use strict; @Insteon::ALDB_i1::ISA = ('Insteon::AllLinkDatabase'); +=item C + +Instantiate a new object. + +=cut + sub new { my ($class,$device) = @_; @@ -1717,6 +1913,12 @@ sub _on_peek } } +=item C + +Used to update the local on level and ramp rate of a device. Called by +L. + +=cut sub update_local_properties { @@ -1731,6 +1933,12 @@ sub update_local_properties } } +=item C + +Used to update the flags of a device. Called by L. + +=cut + sub update_flags { my ($self, $flags, $aldb_check) = @_; @@ -1746,6 +1954,14 @@ sub update_flags } } +=item C + +Gets and returns the details of a link. Called by L. + +NOTE - This routine may be obsolete, its parent routine is not called by any code. + +=cut + sub get_link_record { my ($self,$link_key) = @_; @@ -1823,14 +2039,59 @@ sub _peek } } +=back + +=head2 INI PARAMETERS + +None + +=head2 AUTHOR +Gregg Liming / gregg@limings.net, Kevin Robert Keegan, Michael Stovenour + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut package Insteon::ALDB_i2; +=head1 B + +=head2 SYNOPSIS + +Unique class for storing a cahced copy of a verion i2 device's ALDB. + +=head2 DESCRIPTION + +Generally this object should be interacted with through the insteon objects and +not by directly calling any of the following methods. + +=head2 INHERITS + +L + +=head2 METHODS + +=over + +=cut + use strict; @Insteon::ALDB_i2::ISA = ('Insteon::AllLinkDatabase'); +=item C + +Instantiate a new object. + +=cut + sub new { my ($class,$device) = @_; @@ -1841,6 +2102,11 @@ sub new return $self; } +=item C + +Called as part of any process to read or write to a device's ALDB. + +=cut sub on_read_write_aldb { @@ -2199,6 +2465,12 @@ sub _write_delete } } +=item C + +Called as part of "scan link table" voice command. + +=cut + sub send_read_aldb { my ($self, $address) = @_; @@ -2214,13 +2486,59 @@ sub send_read_aldb $self->_send_cmd($message); } +=back + +=head2 INI PARAMETERS + +None + +=head2 AUTHOR + +Michael Stovenour + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut package Insteon::ALDB_PLM; +=head1 B + +=head2 SYNOPSIS + +Unique class for storing a cahced copy of a the PLM's link database. + +=head2 DESCRIPTION + +Generally this object should be interacted with through the insteon objects and +not by directly calling any of the following methods. + +=head2 INHERITS + +L + +=head2 METHODS + +=over + +=cut + use strict; @Insteon::ALDB_PLM::ISA = ('Insteon::AllLinkDatabase'); +=item C + +Instantiate a new object. + +=cut + sub new { my ($class,$device) = @_; @@ -2230,6 +2548,12 @@ sub new return $self; } +=item C + +This is called by mh on exit to save the cached ALDB of a device to persistant data. + +=cut + sub restore_string { my ($self) = @_; @@ -2262,6 +2586,12 @@ sub restore_string return $restore_string; } +=item C + +Used to reload MisterHouse's cached version of a device's ALDB on restart. + +=cut + sub restore_linktable { my ($self, $links) = @_; @@ -2288,6 +2618,14 @@ sub restore_linktable } } +=item C + +Prints a human readable form of MisterHouse's cached version of a device's ALDB +to the print log. Called as part of the "scan links" voice command +or in response to the "log links" voice command. + +=cut + sub log_alllink_table { my ($self) = @_; @@ -2319,6 +2657,12 @@ sub log_alllink_table } } +=item C + +Parses the alllink message sent from the PLM. + +=cut + sub parse_alllink { my ($self, $data) = @_; @@ -2338,6 +2682,12 @@ sub parse_alllink } } +=item C + +Sends the request for the first alllink entry on the PLM. + +=cut + sub get_first_alllink { my ($self) = @_; @@ -2346,12 +2696,26 @@ sub get_first_alllink $$self{device}->queue_message(new Insteon::InsteonMessage('all_link_first_rec', $$self{device})); } +=item C + +Sends the request for the next alllink entry on the PLM. + +=cut + sub get_next_alllink { my ($self) = @_; $$self{device}->queue_message(new Insteon::InsteonMessage('all_link_next_rec', $$self{device})); } +=item C + +Reviews the cached version of all of the ALDBs and based on this review removes +links from this device which are not present in the mht file, not defined in the +code, or links which are only half-links.. + +=cut + sub delete_orphan_links { my ($self, $audit_mode) = @_; @@ -2548,6 +2912,12 @@ sub _process_delete_queue { } +=item C + +Deletes a specific link from a device. Generally called by C. + +=cut + sub delete_link { # linkkey is concat of: deviceid, group, is_controller @@ -2602,6 +2972,13 @@ sub delete_link return $num_deleted; } +=item C + +Adds the link to the device's ALDB. Generally called from the "sync links" or +"link to interface" voice commands. + +=cut + sub add_link { my ($self, $parms_text) = @_; @@ -2681,6 +3058,13 @@ sub add_link } } +=item C + +Checks and returns true if a link with the passed details exists on the device +or false if it does not. Generally called as part of C. + +=cut + sub has_link { my ($self, $insteon_object, $group, $is_controller, $subaddress) = @_; @@ -2689,7 +3073,25 @@ sub has_link return (defined $$self{aldb}{$key}) ? 1 : 0; } +=back + +=head2 INI PARAMETERS + +None +=head2 AUTHOR + +Gregg Liming / gregg@limings.net, Kevin Robert Keegan, Michael Stovenour + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut 1; diff --git a/lib/Insteon/BaseInsteon.pm b/lib/Insteon/BaseInsteon.pm index f2680b43c..d5ebbb457 100644 --- a/lib/Insteon/BaseInsteon.pm +++ b/lib/Insteon/BaseInsteon.pm @@ -1,29 +1,26 @@ -=begin comment -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +=head1 B -File: - BaseInsteon.pm +=head2 SYNOPSIS -Description: - Generic class implementation of an Insteon Device. +Usage -Author(s): - Gregg Liming / gregg@limings.net +In user code: -License: - This free software is licensed under the terms of the GNU public license. + $ip_patio_light = new Insteon_Device($myPLM,"33.44.55"); + $ip_patio_light->set("ON"); -Usage: +=head2 DESCRIPTION - $ip_patio_light = new Insteon_Device($myPLM,"33.44.55"); +Generic class implementation of an Insteon Device. - $ip_patio_light->set("ON"); +=head2 INHERITS -Special Thanks to: - Brian Warren for significant testing and patches - Bruce Winter - MH +L + +=head2 METHODS + +=over -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ =cut package Insteon::BaseObject; @@ -46,6 +43,13 @@ our %nack_messages = ( ff => 'sender_id_not_in_responder_aldb', ); +=item C + +Takes the various states available to insteon devices and returns a derived +state of either ON or OFF. + +=cut + sub derive_link_state { my ($p_state) = @_; @@ -64,6 +68,12 @@ sub derive_link_state return $link_state; } +=item C + +Instantiates a new object. + +=cut + sub new { my ($class,$p_deviceid,$p_interface) = @_; @@ -107,6 +117,13 @@ sub new return $self; } +=item C + +A former holdover from when MisterHouse used to ping devices to get their device +category. May not be needed anymore. + +=cut + sub initialize { my ($self) = @_; @@ -121,6 +138,14 @@ sub initialize # unless $self->group eq '01' and defined $self->devcat; } +=item C + +Used to store and return the associated interface of a device. + +If provided, stores interface as the device's interface. + +=cut + sub interface { my ($self,$p_interface) = @_; @@ -134,6 +159,16 @@ sub interface return $$self{interface}; } +=item C + +Used to store and return the associated device_id of a device. + +If provided, stores id as the device's id. + +Returns device id without any delimiters. + +=cut + sub device_id { my ($self,$p_device_id) = @_; @@ -146,6 +181,14 @@ sub device_id return $$self{device_id}; } +=item C + +Used to store and return the associated group of a device. + +If provided, stores group as the device's group. + +=cut + sub group { my ($self, $p_group) = @_; @@ -153,6 +196,20 @@ sub group return $$self{m_group}; } +=item C + +Used to track the number of hops needed to reach a device. Will store the past +20 hop counts for the device. Hop counts are added based on the number of hops +needed for an incomming message to arrive. Additionally, any time a message is +resent, a hop count equal to the prior default_hop_count + 1 is added. + +If provided, stores hop as a new hop count for the device. If more than 20 hop +counts have been stored, will drop the oldest hop count until only 20 exist. + +Returns the highest hop count of the past 20 hop counts + +=cut + sub default_hop_count { my ($self, $hop_count) = @_; @@ -171,6 +228,14 @@ sub default_hop_count return $$self{default_hop_count}; } +=item C + +Used to store and return the associated engine version of a device. + +If provided, stores the engine version of the device. + +=cut + sub engine_version { my ($self, $p_engine_version) = @_; @@ -178,6 +243,12 @@ sub engine_version return $$self{engine_version}; } +=item C + +Returns 1 if object is the same as $self, otherwise returns 0. + +=cut + sub equals { my ($self, $compare_object) = @_; @@ -192,6 +263,14 @@ sub equals return 0; } +=item C + +Used to set the device's state. If called by device or a device linked to device, +calls C. If called by something +else, will send the command to the device. + +=cut + sub set { my ($self,$p_state,$p_setby,$p_response) = @_; @@ -263,6 +342,12 @@ sub set } } +=item C + +If ack is true, calls C. If ack is false, clears awaiting_ack flag. + +=cut + sub is_acknowledged { my ($self, $p_ack) = @_; @@ -286,6 +371,16 @@ sub is_acknowledged return $$self{is_acknowledged}; } +=item C + +Updates the device's state in MisterHouse. Triggers state_now, state_changed, and +state_final variables to update accordingly. Which causes tie_events to occur. + +If state was set to the same state within the last 1 second, then this is ignored. +This prevents the accidental calling of state_now if duplicate messages are received. + +=cut + sub set_receive { my ($self, $p_state, $p_setby, $p_response) = @_; @@ -302,6 +397,16 @@ sub set_receive } } +=item C + +NOTE - This routine appears to be nearly identical, if not identical to the +C routine, it is not clear why this routine is +needed here. + +See full description of this routine in C + +=cut + sub set_with_timer { my ($self, $state, $time, $return_state, $additional_return_states) = @_; return if &main::check_for_tied_filters($self, $state); @@ -346,6 +451,12 @@ sub _send_cmd $self->_process_command_stack(); } +=item C + +Generates and returns a basic on/off message from a command. + +=cut + sub derive_message { my ($self, $p_command, $p_extra) = @_; @@ -427,18 +538,39 @@ sub derive_message return $message; } +=item C + +Takes msg, a text based msg type, and returns the corresponding text version of +the hexadecimal message type. + +=cut + sub message_type_code { my ($self, $msg) = @_; return $$self{message_types}->{$msg}; } +=item C + +Takes msg, a text based msg type, and returns the corresponding message type as +a hex. + +=cut + sub message_type_hex { my ($self, $msg) = @_; return unpack( 'H*', pack( 'c', $self->message_type_code($msg))); } +=item C + +Takes cmd, text based hexadecimal code, and returns the text based description +of the message code. + +=cut + sub message_type { my ($self, $cmd1) = @_; @@ -838,7 +970,13 @@ sub _is_valid_state } } -# Provide human readable nack message. +=item C + +Takes msg, text based hexadecimal code, and returns the text based description +of the NACK code. + +=cut + sub get_nack_msg_for { my ($self,$msg) = @_; return $nack_messages{ $msg }; @@ -864,14 +1002,67 @@ sub failure_reason return $$self{failure_reason}; } +=back + +=head2 INI PARAMETERS + +=over + +=item Insteon_PLM_max_queue_time + +Was previously used to set the maximum amount of time +a message could remain in the queue. This parameter is no longer used in the code +but it still appears in the initialization. It may be removed at a future date. +This also gets set in L +as well for some reason, but is not used there either. + +=back + +=head2 AUTHOR + +Gregg Liming / gregg@limings.net, Kevin Robert Keegan, Michael Stovenour + +=head2 NOTES + +Special thanks to: + Brian Warren for significant testing and patches + Bruce Winter - MH + +=head2 SEE ALSO + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut + #################################### ### ##################### -### BaseObject ##################### +### BaseDevice ##################### ### ##################### #################################### -package Insteon::BaseDevice; +=head1 B + +=head2 DESCRIPTION + +Generic class implementation of a Base Insteon Device. + +=head2 INHERITS +L + +=head2 METHODS + +=over + +=cut + +package Insteon::BaseDevice; @Insteon::BaseDevice::ISA = ('Insteon::BaseObject'); @@ -927,6 +1118,11 @@ my %operating_flags = ( 'one_minute_warn_enabled' => '0b' ); +=item C + +Instantiates a new object. + +=cut sub new { @@ -959,6 +1155,13 @@ sub new return $self; } +=item C + +A former holdover from when MisterHouse used to ping devices to get their device +category. May not be needed anymore. + +=cut + sub initialize { my ($self) = @_; @@ -971,6 +1174,14 @@ sub initialize $$self{ping_timerTime} = 300; } +=item C + +Used to store and return the associated ramp rate of a device. + +If provided, stores rate as the device's ramp rate in MisterHouse. + +=cut + sub rate { my ($self,$p_rate) = @_; @@ -978,6 +1189,13 @@ sub rate return $$self{rate}; } +=item C + +Updates the device's level if it can level, then calls +C. + +=cut + sub set_receive { my ($self, $p_state, $p_setby, $p_response) = @_; @@ -985,12 +1203,24 @@ sub set_receive $self->SUPER::set_receive($p_state, $p_setby, $p_response); } +=item C + +Returns true if the device is a controller. + +=cut + sub is_controller { my ($self) = @_; return $$self{is_controller}; } +=item C + +Stores and returns whether a device is a responder. + +=cut + sub is_responder { my ($self,$is_responder) = @_; @@ -1012,6 +1242,22 @@ sub is_responder } } +=item C + +If a controller link from the device to the interface does not exist, this will +create that link on the device. + +Next, if a responder link from the device to the interface does not exist on the +interface, this will create that link on the interface. + +The group is the group on the device that is the controller, such as a button on +a keypad link. It will default to 01. + +Data3 is optional and is used to set the Data3 value in the controller link on +the device. + +=cut + sub link_to_interface { my ($self,$p_group, $p_data3) = @_; @@ -1035,6 +1281,18 @@ sub link_to_interface } } +=item C + +Will delete the contoller link from the device to the interface if such a link exists. + +Next, will delete the responder link from the device to the interface on the +interface, if such a link exists. + +The group is the group on the device that is the controller, such as a button on +a keypad link. It will default to 01. + +=cut + sub unlink_to_interface { my ($self,$p_group) = @_; @@ -1088,6 +1346,11 @@ sub _aldb return $$root_obj{aldb}; } +=item C + +Sets the defined flag on the device. + +=cut sub set_operating_flag { my ($self, $flag) = @_; @@ -1118,6 +1381,12 @@ sub set_operating_flag { } } +=item C + +Requests the device's operating flag and prints it to the log. + +=cut + sub get_operating_flag { my ($self) = @_; @@ -1135,6 +1404,13 @@ sub get_operating_flag { } } +=item C + +Appears to set and or return the "writable" state. Does not appear to be used +in the Insteon code, but may be necessary for supporting other classes? + +=cut + sub writable { my ($self, $p_write) = @_; if (defined $p_write) @@ -1151,17 +1427,36 @@ sub writable { return $$self{m_write}; } +=item C + +Returns the is_locally_set variable. Doesn't appear to be used in Insteon code. +Likely was used to test whether setby was equal to the device itself. May not +always be properly updated since it appears unused. + +=cut + sub is_locally_set { my ($self) = @_; return $$self{m_is_locally_set}; } +=item C + +Returns true if the object is the base object, generally group 01, on the device. + +=cut sub is_root { my ($self) = @_; return (($self->group eq '01') and !($self->isa('Insteon::InterfaceController'))) ? 1 : 0; } +=item C + +Returns the root object of a device. + +=cut + sub get_root { my ($self) = @_; if ($self->is_root) @@ -1179,6 +1474,13 @@ sub get_root { } } +=item C + +If a device has an ALDB, passes link_details onto one of the has_link() routines +within L. Generally called as part of C. + +=cut + sub has_link { my ($self, $insteon_object, $group, $is_controller, $subaddress) = @_; @@ -1194,6 +1496,14 @@ sub has_link } +=item C + +If a device has an ALDB, passes link_details onto one of the add_link() routines +within L. Generally called from the "sync links" or +"link to interface" voice commands. + +=cut + sub add_link { my ($self, $parms_text) = @_; @@ -1215,6 +1525,14 @@ sub add_link } +=item C + +If a device has an ALDB, passes link_details onto one of the update_link() routines +within L. Generally called from the "sync links" +voice command. + +=cut + sub update_link { my ($self, $parms_text) = @_; @@ -1235,6 +1553,13 @@ sub update_link } } +=item C + +If a device has an ALDB, passes link_details onto one of the delete_link() routines +within L. Generally called by C. + +=cut + sub delete_link { my ($self, $parms_text) = @_; @@ -1255,6 +1580,12 @@ sub delete_link } } +=item C + +Scans a device's link table and caches a copy. + +=cut + sub scan_link_table { my ($self, $success_callback, $failure_callback) = @_; @@ -1266,6 +1597,15 @@ sub scan_link_table } +=item C + +Prints a human readable description of various settings and attributes associated +with a device including: + +Hop Count, Engine Version, ALDB Type, ALDB Health, and Last ALDB Scan Time + +=cut + sub log_aldb_status { my ($self) = @_; @@ -1280,7 +1620,16 @@ sub log_aldb_status } } -### WARN: Testing using the following does not produce results as expected. Use at your own risk. [GL] +=item C + +In theory, would have the same effect as manually tapping the set button on the +device repeat times. + +WARN: Testing using the following does not produce results as expected. Use at +your own risk. [GL] + +=cut + sub remote_set_button_tap { my ($self,$p_number_taps) = @_; @@ -1291,6 +1640,13 @@ sub remote_set_button_tap # $self->_send_cmd('command' => 'remote_set_button_tap', 'extra' => $taps); } +=item C + +Requests the current status of the device and calls C on the response. +This will trigger tied_events. + +=cut + sub request_status { my ($self, $requestor) = @_; @@ -1347,6 +1703,12 @@ sub _get_engine_version_failure } } +=item C + +Sends a ping command to the device. + +=cut + sub ping { my ($self) = @_; @@ -1355,6 +1717,12 @@ sub ping # $self->_send_cmd('command' => 'ping'); } +=item C + +Used to set the led staatus of SwitchLinc companion leds. + +=cut + sub set_led_status { my ($self, $status_mask) = @_; @@ -1364,6 +1732,12 @@ sub set_led_status # $self->_send_cmd('command' => 'set_led_status', 'extra' => $status_mask); } +=item C + +This is called by mh on exit to save the cached ALDB of a device to persistant data. + +=cut + sub restore_string { my ($self) = @_; @@ -1386,6 +1760,12 @@ sub restore_string return $restore_string; } +=item C + +Used to reload the persistent states of variables on restart. + +=cut + sub restore_states { my ($self, $states) = @_; @@ -1395,6 +1775,12 @@ sub restore_states } } +=item C + +Used to reload the aldb of a device on restart. + +=cut + sub restore_aldb { my ($self,$aldb) = @_; @@ -1404,6 +1790,12 @@ sub restore_aldb } } +=item C + +NOT USED - Sets and returns the device category of a device. No longer used. + +=cut + sub devcat { my ($self, $devcat) = @_; @@ -1418,6 +1810,12 @@ sub devcat return $$self{devcat}; } +=item C + +Sets and returns the available states for a device. + +=cut + sub states { my ($self, $states) = @_; @@ -1434,6 +1832,12 @@ sub states } +=item C + +Sets and returns the local onlevel for the device in MH only. Level is a +percentage from 0%-100% + +=cut sub local_onlevel { @@ -1446,6 +1850,14 @@ sub local_onlevel return $$self{_onlevel}; } +=item C + +Sets and returns the local ramp rate for the device in MH only. Rate is a time +between .1 and 540 seconds. Only 32 rate steps exist, to MH will pick a time +equal to of the closest below this time. + +=cut + sub local_ramprate { my ($self, $p_ramprate) = @_; @@ -1456,6 +1868,17 @@ sub local_ramprate } +=item C + +Reviews the cached version of all of the ALDBs and based on this review removes +links from this device which are not present in the mht file, not defined in the +code, or links which are only half-links. + +If audit_mode is true, prints the actions that would be taken to the log, but +does nothing. + +=cut + sub delete_orphan_links { my ($self, $audit_mode) = @_; @@ -1467,12 +1890,28 @@ sub _process_delete_queue { $self->_aldb->_process_delete_queue() if $self->_aldb; } +=item C + +Prints a human readable form of MisterHouse's cached version of a device's ALDB +to the print log. Called as part of the "scan links" voice command +or in response to the "log links" voice command. + +=cut + sub log_alllink_table { my ($self) = @_; $self->_aldb->log_alllink_table if $self->_aldb; } +=item C + +Pushes the values set in C and C to the device. +The device will only reread these values when it is power-cycled. This can be +done by pulling the air-gap for 4 seconds or unplugging the device. + +=cut + sub update_local_properties { my ($self) = @_; @@ -1486,6 +1925,23 @@ sub update_local_properties } } +=item C + +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 at some point. + +=cut + sub update_flags { my ($self, $flags) = @_; @@ -1519,24 +1975,28 @@ sub engine_version return $engine_version; } -sub check_aldb_version -{ - #Because of the way MH saves / restores states "after" object creation - #the aldb must be initially created before the engine_version is restored. - #It is therefore impossible to know the device is i2 before creating - #the aldb object. The solution is to keep the existing logic which assumes - #the device is peek/poke capable (i1 or i2) and then delete/recreate the - #aldb object if it is later determined to be an i2 device. +=item C + +Because of the way MH saves / restores states "after" object creation +the aldb must be initially created before the engine_version is restored. +It is therefore impossible to know the device is i2 before creating +the aldb object. The solution is to keep the existing logic which assumes +the device is peek/poke capable (i1 or i2) and then delete/recreate the +aldb object if it is later determined to be an i2 device. - #There is a use case where a device is initially I2 but the user replaces - #the device with an I1 device, reusing the same object name. In this case - #the object state restore will build an I2 aldb object. The user must - #manually initiate the 'get engine version' voice command or stop/start - #MH so the initial poll will detect the change. +There is a use case where a device is initially I2 but the user replaces +the device with an I1 device, reusing the same object name. In this case +the object state restore will build an I2 aldb object. The user must +manually initiate the 'get engine version' voice command or stop/start +MH so the initial poll will detect the change. - #This is called anytime the engine_version is queried (initial startup poll) and - #in the Reload_post_hooks once object_states_restore completes +This is called anytime the engine_version is queried (initial startup poll) and +in the Reload_post_hooks once object_states_restore completes +=cut + +sub check_aldb_version +{ my ($self) = @_; my $engine_version = $self->SUPER::engine_version(); @@ -1572,6 +2032,35 @@ sub check_aldb_version } } +=back + +=head2 INI PARAMETERS + +=over + +=item Insteon_PLM_max_queue_time + +Was previously used to set the maximum amount of time +a message could remain in the queue. This parameter is no longer used in the code +but it still appears in the initialization. It may be removed at a future date. +This also gets set in L +as well for some reason, but is not used there either. + +=back + +=head2 AUTHOR + +Gregg Liming / gregg@limings.net, Kevin Robert Keegan, Michael Stovenour + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut #################################### ### ################# @@ -1579,12 +2068,34 @@ sub check_aldb_version ### ################# #################################### +=head1 B + +=head2 DESCRIPTION + +Generic class implementation of an Insteon Controller. + +=head2 INHERITS + +L + +=head2 METHODS + +=over + +=cut + package Insteon::BaseController; use strict; @Insteon::BaseController::ISA = ('Generic_Item'); +=item C + +Instantiates a new object. + +=cut + sub new { my ($class,$p_deviceid,$p_interface,$p_devcat) = @_; @@ -1597,6 +2108,13 @@ sub new return $self; } +=item C + +Adds object as a responder to the device. If on_level and ramp_rate are specified +they will be used, otherwise 100% .1s will be used. + +=cut + sub add { my ($self, $obj, $on_level, $ramp_rate) = @_; @@ -1632,6 +2150,17 @@ sub add } } +=item C + +Causes MisterHouse to review the list of objects that should be linked to device +and to check to make sure these links are complete. If any link is not complete +MisterHouse will add the link. + +If audit_mode is true, MisterHouse will print the actions it would have taken to +the log, but will not take any actions. + +=cut + sub sync_links { my ($self, $audit_mode, $callback, $failure_callback) = @_; @@ -1895,6 +2424,16 @@ sub _process_sync_queue { } } +=item C + +Returns -1 if setby was set by this object. + +Returns -1 if setby a tied_filter. + +Otherwise calls C and returns 0. + +=cut + sub set { my ($self, $p_state, $p_setby, $p_respond) = @_; @@ -1913,6 +2452,14 @@ sub set return 0; } +=item C + +Checks each linked member of device. If the linked member is a C, +then sets that item to state. If the linked member is a C +then call C for the member. + +=cut + sub set_linked_devices { my ($self, $link_state) = @_; @@ -1970,6 +2517,16 @@ sub set_linked_devices } +=item C + +NOTE - This routine appears to be nearly identical, if not identical to the +C routine, it is not clear why this routine is +needed here. + +See full description of this routine in C + +=cut + sub set_with_timer { my ($self, $state, $time, $return_state, $additional_return_states) = @_; return if &main::check_for_tied_filters($self, $state); @@ -1990,6 +2547,12 @@ sub set_with_timer { $$self{set_timer}->set($time, $action); } +=item C + +This appears to be a depricated routine that is no longer used. At a cursory +glance, it may throw an error if called. + +=cut sub update_members { @@ -2023,6 +2586,14 @@ sub update_members } } +=item C + +Places the interface in linking mode as the controller. To complete the process +press the set button on the responder device until it beeps. Alternatively, +you may be able to complete the process with +C. + +=cut sub initiate_linking_as_controller { @@ -2041,6 +2612,12 @@ sub initiate_linking_as_controller $self->interface()->initiate_linking_as_controller($p_group); } +=item C + +Generates and returns a basic on/off message from a command. + +=cut + sub derive_message { my ($self, $p_state, $p_extra) = @_; @@ -2051,6 +2628,15 @@ sub derive_message } } +=item C + +Returns a list of objects that are members of device. If type is specified, only +members of that type are returned. Type is a package name, for example: + + $member->find_members('Insteon::BaseDevice'); + +=cut + sub find_members { my ($self,$p_type) = @_; @@ -2071,6 +2657,12 @@ sub find_members } +=item C + +Returns true if object is a member of device, else returns false. + +=cut + sub has_member { my ($self, $compare_object) = @_; @@ -2085,12 +2677,43 @@ sub has_member return 0; } +=back + +=head2 AUTHOR + +Gregg Liming / gregg@limings.net, Kevin Robert Keegan, Michael Stovenour + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut + #################################### ### ##################### ### DeviceController ############### ### ############### #################################### +=head1 B + +=head2 DESCRIPTION + +Generic class implementation of an Device Controller. + +=head2 INHERITS + +L + +=head2 METHODS + +=over + +=cut package Insteon::DeviceController; @@ -2098,6 +2721,12 @@ use strict; @Insteon::DeviceController::ISA = ('Insteon::BaseController'); +=item C + +Instantiates a new object. + +=cut + sub new { my ($class,$p_deviceid,$p_interface,$p_devcat) = @_; @@ -2108,6 +2737,14 @@ sub new return $self; } +=item C + +If C returns a true value returns that. + +Else, calls C and returns 0 + +=cut + sub set { my ($self, $p_state, $p_setby, $p_respond) = @_; @@ -2122,6 +2759,12 @@ sub set return 0; } +=item C + +Requests the current status of the device and calls C on the response. +This will trigger tied_events. + +=cut sub request_status { @@ -2148,6 +2791,22 @@ sub request_status } } +=item C + +If a controller link from the device to the interface does not exist, this will +create that link on the device. + +Next, if a responder link from the device to the interface does not exist on the +interface, this will create that link on the interface. + +The group is the group on the device that is the controller, such as a button on +a keypad link. It will default to 01. + +Data3 is optional and is used to set the Data3 value in the controller link on +the device. + +=cut + sub link_to_interface { my ($self, $p_group, $p_data3) = @_; @@ -2177,6 +2836,18 @@ sub link_to_interface } } +=item C + +Will delete the contoller link from the device to the interface if such a link exists. + +Next, will delete the responder link from the device to the interface on the +interface, if such a link exists. + +The group is the group on the device that is the controller, such as a button on +a keypad link. It will default to 01. + +=cut + sub unlink_to_interface { my ($self,$p_group) = @_; @@ -2196,7 +2867,21 @@ sub unlink_to_interface } } +=back + +=head2 AUTHOR + +Gregg Liming / gregg@limings.net, Kevin Robert Keegan, Michael Stovenour +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut #################################### ### ############ @@ -2204,6 +2889,22 @@ sub unlink_to_interface ### ############ #################################### +=head1 B + +=head2 DESCRIPTION + +Generic class implementation of an Interface Controller. These are the PLM Scenes. + +=head2 INHERITS + +L, +L + +=head2 METHODS + +=over + +=cut package Insteon::InterfaceController; @@ -2211,6 +2912,12 @@ use strict; @Insteon::InterfaceController::ISA = ('Insteon::BaseController','Insteon::BaseObject'); +=item C + +Instantiates a new object. + +=cut + sub new { my ($class,$p_deviceid,$p_interface) = @_; @@ -2221,6 +2928,14 @@ sub new return $self; } +=item C + +If C returns a true value returns that. + +Else, calls C and returns 0 + +=cut + sub set { my ($self, $p_state, $p_setby, $p_respond) = @_; @@ -2238,4 +2953,20 @@ sub is_root return 0; } +=back + +=head2 AUTHOR + +Gregg Liming / gregg@limings.net, Kevin Robert Keegan, Michael Stovenour + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut + 1; diff --git a/lib/Insteon/BaseInterface.pm b/lib/Insteon/BaseInterface.pm index 1e8f03e47..b2493956a 100644 --- a/lib/Insteon/BaseInterface.pm +++ b/lib/Insteon/BaseInterface.pm @@ -1,3 +1,18 @@ +=head1 B + +=head2 SYNOPSIS + +Provides support for the Insteon Interface. + +=head2 INHERITS + +L + +=head2 METHODS + +=over + +=cut package Insteon::BaseInterface; @@ -5,12 +20,32 @@ use strict; use Insteon::Message; @Insteon::BaseInterface::ISA = ('Class::Singleton'); +=item C + +Locates the active_interface from the main Insteon class and calls +C on it. Called once per loop to get data from the PLM. + +=cut + sub check_for_data { my $interface = &Insteon::active_interface(); $interface->check_for_data(); } +=item C + +Called on startup or reload. Will always request and print the plm_info, which +contains the PLM revision number, to the log on startup. + +If Insteon_PLM_scan_at_startup is set to 1 in the ini file, this routine will poll +all insteon devices and request their current state. Useful for making sure that +no devices changed their state while MisterHouse was off. Will also call +L on each device to ensure that +the proper ALDB object is created for them. + +=cut + sub poll_all { my $scan_at_startup = $main::config_parms{Insteon_PLM_scan_at_startup}; @@ -45,6 +80,12 @@ sub poll_all } } +=item C + +Instantiate a new object. + +=cut + sub new { my ($class) = @_; @@ -59,6 +100,12 @@ sub new return $self; } +=item C + +Returns 1 if object is the same as $self, otherwise returns 0. + +=cut + sub equals { my ($self, $compare_object) = @_; @@ -77,6 +124,12 @@ sub equals } } +=item C<_is_duplicate(cmd)> + +Returns true if cmd already exists in the command stack. + +=cut + sub _is_duplicate { my ($self, $cmd) = @_; @@ -94,6 +147,13 @@ sub _is_duplicate return $duplicate_detected; } +=item C + +If a device has an ALDB, passes link_details onto one of the has_link() routines +within L. Generally called as part of C. + +=cut + sub has_link { my ($self, $insteon_object, $group, $is_controller, $subaddress) = @_; @@ -104,6 +164,14 @@ sub has_link return 0; } +=item C + +If a device has an ALDB, passes link_details onto one of the add_link() routines +within L. Generally called from the "sync links" or +"link to interface" voice commands. + +=cut + sub add_link { my ($self, $parms_text) = @_; @@ -123,6 +191,13 @@ sub add_link } } +=item C + +If a device has an ALDB, passes link_details onto one of the delete_link() routines +within L. Generally called by C. + +=cut + sub delete_link { my ($self, $parms_text) = @_; @@ -142,6 +217,12 @@ sub delete_link } } +=item C + +Optionally stores, and returns the message currently being processed by the interface. + +=cut + sub active_message { my ($self, $message) = @_; @@ -152,6 +233,13 @@ sub active_message return $$self{active_message}; } +=item C + +Clears the message currently being processed by the interface, and sets the +transmit in progress flag to false. + +=cut + sub clear_active_message { my ($self) = @_; @@ -159,12 +247,25 @@ sub clear_active_message $self->transmit_in_progress(0); } +=item C + +Sets the transmit in progress flag to false. + +=cut + sub retry_active_message { my ($self) = @_; $self->transmit_in_progress(0); } +=item C + +Sets the transmit in progress flag to xmit_flag, returns true if xmit_flag +true or xmit timout has not elapsed. + +=cut + sub transmit_in_progress { my ($self, $xmit_flag) = @_; @@ -177,6 +278,15 @@ sub transmit_in_progress return $$self{xmit_in_progress} || ($self->_check_timeout('xmit')==0); } +=item C + +If no msg is passed, returns the queue length. + +Msg is optionally a message, if sent is added to the message queue. +C is then called. + +=cut + sub queue_message { my ($self, $message) = @_; @@ -206,6 +316,17 @@ sub queue_message $self->process_queue(); } +=item C + +If C is true returns queue size. + +If there is a pending message, will leave it as active_message. If retries are +exceeded, will log an error, clear the message, and call the message failure_callback. + +Else, will pull a message from the queue and place it as the active_message. + +=cut + sub process_queue { my ($self) = @_; @@ -278,12 +399,28 @@ sub process_queue return $command_queue_size; } +=item C + +Used to store and return the associated device_id of a device. + +If provided, stores id as the device's id. + +Returns device id without any delimiters. + +=cut + sub device_id { my ($self, $p_deviceid) = @_; $$self{deviceid} = $p_deviceid if defined $p_deviceid; return $$self{deviceid}; } +=item C + +This is called by mh on exit to save the cached ALDB of a device to persistant data. + +=cut + sub restore_string { my ($self) = @_; @@ -292,6 +429,12 @@ sub restore_string return $restore_string; } +=item C + +Used to reload the link table of a device on restart. + +=cut + sub restore_linktable { my ($self,$aldb) = @_; @@ -300,6 +443,13 @@ sub restore_linktable } } +=item C + +Prints a human readable form of MisterHouse's cached version of a device's ALDB +to the print log. Called as part of the "scan links" voice command +or in response to the "log links" voice command. + +=cut sub log_alllink_table { @@ -307,15 +457,33 @@ sub log_alllink_table $self->_aldb->log_alllink_table if $self->_aldb; } +=item C + +Reviews the cached version of all of the ALDBs and based on this review removes +links from this device which are not present in the mht file, not defined in the +code, or links which are only half-links. + +If audit_mode is true, prints the actions that would be taken to the log, but +does nothing. + +=cut + sub delete_orphan_links { my ($self, $audit_mode) = @_; return $self->_aldb->delete_orphan_links($audit_mode) if $self->_aldb; } - ###################### - ### EVENT HANDLERS ### ###################### +### EVENT HANDLERS ### +###################### + +=item C + +Called to process the plm_info request sent by the C command. +Prints output to log. + +=cut sub on_interface_info_received { @@ -326,6 +494,13 @@ sub on_interface_info_received $self->clear_active_message(); } +=item C + +Called to process standard length insteon messages. The routine is rather complex +some messsages are processed right here. The majority are passed off to the +C<_is_info_request()> and C<_process_message()> routines for each device. + +=cut sub on_standard_insteon_received { @@ -479,6 +654,14 @@ sub on_standard_insteon_received } } +=item C + +Called to process extended length insteon messages. The majority of messages are +passed off to the C<_process_message()> routines for each device. + +=cut + + sub on_extended_insteon_received { my ($self, $message_data) = @_; @@ -529,9 +712,17 @@ sub on_extended_insteon_received } - ################################# - ### INTERNAL METHODS/FUNCTION ### ################################# +### INTERNAL METHODS/FUNCTION ### +################################# + +=item C<_set_timeout(timeout_name, timeout_millis)> + +Sets an internal variable, timeout_name, the current time plus the number of +milliseconds specified by timeout_millis. + +=cut + sub _set_timeout { @@ -541,11 +732,17 @@ sub _set_timeout $$self{"_timeout_$timeout_name"} = $tickcount; } -# -# return -1 if timeout_name does not match an existing timer -# return 0 if timer has not expired -# return 1 if timer has expired -# +=item C<_check_timeout(timeout_name)> + +Checks to see if the current number of milliseconds has exceeded the number of +milliseconds defined in timeout_name, which was set by C<_set_timeout()>. + +return -1 if timeout_name does not match an existing timer +return 0 if timer has not expired +return 1 if timer has expired + +=cut + sub _check_timeout { my ($self, $timeout_name) = @_; @@ -556,32 +753,49 @@ sub _check_timeout return ($current_tickcount > $$self{"_timeout_$timeout_name"}) ? 1 : 0; } +=item C<_check_timeout(timeout_name)> + +Erases timeout_name, which was set by C<_set_timeout()>. + +=cut sub _clear_timeout { my ($self, $timeout_name) = @_; $$self{"_timeout_$timeout_name"} = undef; } +=item C<_aldb()> + +Returns the ALDB object associated with the device. + +=cut + sub _aldb { my ($self) = @_; return $$self{aldb}; } -# This function attempts to identify erroneous duplicative incoming messages -# while still permitting identical messages to arrive in close proximity. For -# example, a valid identical message is the ACK of an extended aldb read which -# is always 2F00. -# -# Messages are deemed to be identical if, excluding the max_hops and hops_left -# bits, they are otherwise the same. Identical messages are deemed to be -# erroneous if they are received within a calculated message window, $delay. -# -# The message window is calculated depending on whether the PLM is sending an ACK. -# - -# Returns 1 if the received message is a duplicate message -# See discussion at: https://github.com/hollie/misterhouse/issues/169 +=item C<_is_duplicate_received()> + +This function attempts to identify erroneous duplicative incoming messages +while still permitting identical messages to arrive in close proximity. For +example, a valid identical message is the ACK of an extended aldb read which +is always 2F00. + +Messages are deemed to be identical if, excluding the max_hops and hops_left +bits, they are otherwise the same. Identical messages are deemed to be +erroneous if they are received within a calculated message window, $delay. + +The message window is calculated based on the amount of time that should have +elapsed before a subsequent identical message could have been received.. + +Returns 1 if the received message is an erroneous duplicate message + +See discussion at: https://github.com/hollie/misterhouse/issues/169 + +=cut + sub _is_duplicate_received { my ($self, $message_data, %msg) = @_; my $is_duplicate; @@ -638,4 +852,36 @@ sub _is_duplicate_received { return $is_duplicate; } +=back + +=head2 INI PARAMETERS + +=over + +=item Insteon_PLM_scan_at_startup + +By default, MisterHouse will scan all devices at startup. This scan involves +asking each device for its current state and asking each device for its engine +version. In a larger network this can take a few seconds to complete and it does +send a lot of messages all at once, but polling at startup is a good way to make +sure that MisterHouse has an accurate understanding of the network. + +If set to false, will disable the scan at startup. + +=back + +=head2 AUTHOR + +Gregg Liming / gregg@limings.net, Kevin Robert Keegan, Michael Stovenour + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut + 1 diff --git a/lib/Insteon/Controller.pm b/lib/Insteon/Controller.pm index 2484a2973..573439dc9 100644 --- a/lib/Insteon/Controller.pm +++ b/lib/Insteon/Controller.pm @@ -40,7 +40,8 @@ must first be put into "awake mode." =head2 INHERITS -B, B +L, +L, =head2 METHODS @@ -62,6 +63,12 @@ my %message_types = ( extended_set_get => 0x2e ); +=item C + +Instantiates a new object. + +=cut + sub new { my ($class,$p_deviceid,$p_interface) = @_; @@ -76,6 +83,15 @@ sub new return $self; } +=item C + +Handles messages received from the device. Ignores attempts to set the same state +in less than 1 second. (This can likely be removed as the same process exists +now in BaseInsteon set_receive.) If this is not a duplicate message calls +C. + +=cut + sub set { my ($self,$p_state,$p_setby,$p_response) = @_; @@ -180,6 +196,12 @@ sub set_battery_timer { return; } +=item C<_is_battery_time_expired()> + +Returns true if the battery timer has expired, else returns false. + +=cut + sub _is_battery_time_expired { my ($self) = @_; my $root = $self->get_root(); @@ -190,6 +212,15 @@ sub _is_battery_time_expired { return 0; } +=item C<_process_message()> + +Checks for and handles unique RemoteLinc messages such as battery voltage messages. +All other messages are transferred to L. + +Also checks the battery timer and sends a battery request if needed. + +=cut + sub _process_message { my ($self,$p_setby,%msg) = @_; my $clear_message = 0; @@ -263,6 +294,18 @@ sub is_responder =back +=head2 AUTHOR + +Gregg Liming / gregg@limings.net, Kevin Robert Keegan + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + =head1 B =head2 SYNOPSIS @@ -293,7 +336,7 @@ you when the battery is low. =head2 INHERITS -B +L =head2 METHODS @@ -306,6 +349,12 @@ use strict; @Insteon::RemoteLinc_Battery::ISA = ('Generic_Item'); +=item C + +Instantiates a new object. + +=cut + sub new { my ($class, $parent) = @_; my $self = new Generic_Item(); @@ -315,6 +364,13 @@ sub new { return $self; } +=item C + +Receives voltage messages from the parent object and sets the state of this +device accordingly. + +=cut + sub set_receive { my ($self, $p_state) = @_; $self->SUPER::set($p_state); @@ -322,17 +378,9 @@ sub set_receive { =back -=head2 INI PARAMETERS - -None. - =head2 AUTHOR -Bruce Winter, Gregg Limming, Kevin Robert Keegan - -=head2 SEE ALSO - - +Kevin Robert Keegan =head2 LICENSE diff --git a/lib/Insteon/IOLinc.pm b/lib/Insteon/IOLinc.pm index 11837ab72..a6b5bc20d 100755 --- a/lib/Insteon/IOLinc.pm +++ b/lib/Insteon/IOLinc.pm @@ -1,47 +1,48 @@ -=begin comment +=head1 B + +=head2 SYNOPSIS -INITIAL CONFIGURATION In user code: - use Insteon::IOLinc; - $io_device = new Insteon::IOLinc('12.34.56',$myPLM); + use Insteon::IOLinc; + $io_device = new Insteon::IOLinc('12.34.56',$myPLM); In items.mht: -INSTEON_IOLINC, 12.34.56, io_device, io_group - -Where commands sent to io_device control the relay, however commands received -from io_device represent the sensor state.. - -EXAMPLE USAGE + INSTEON_IOLINC, 12.34.56, io_device, io_group Turning on a relay: - $io_device->set('on'); + $io_device->set('on'); Turning off a relay: - $io_device->set('off'); + $io_device->set('off'); Requesting sensor status: - $io_device->request_sensor_status(); + $io_device->request_sensor_status(); + +Print the Current Device Settings to the log: + + $io_device->get_operating_flag(); + +=head2 DESCRIPTION + +Support for the Insteon IOLinc. The IOLinc is a strange device in that commands sent to it control one aspect of the device, but commands received from it are from another aspect of the device. -Print the Current Device Settings to the log: - $io_device->get_operating_flag(); - -LINKING +=head3 LINKING As a result of the IOLinc's oddities, when the IOLinc is set as a controller of another device, that other device will be controlled by the sensor state. However, when the IOLinc is set as a responder in a link, the relay of the IOLinc will change with the commands sent by the controller. -STATE REPORTED IN MisterHouse +=head3 STATE REPORTED IN MisterHouse MisterHouse objects are only designed to hold the state of a single aspect. As a result of the IOLinc's oddities, the $io_device defined using the examples above @@ -52,23 +53,20 @@ One more oddity is that using the "set" button on the side of the device to change the state of the relay, will cause MH to perceive this as a change in the state of the sensor, thus placing the sensor and relay objects out of sync. -SENSOR STATE CHILD OBJECT +=head3 SENSOR STATE CHILD OBJECT To create a device that directly tracks the state of the sensor, you can use -the following code to create a generic child object. The state of the child -object will reflect the state of the sensor and it will be automatically updated -as long as the IOLinc is linked to the PLM. Tie_events can be used on this -child object. However, if you want to directly link an obect to the sensor +C. The state of the child object will reflect the state +of the sensor and it will be automatically updated as long as the IOLinc is +linked to the + +However, if you want to directly link an obect to the sensor be sure to use the normal SCENE_MEMBER code in your mht file with the IOLinc defined as the controller. -User Code: - - $io_device_sensor = new Insteon::IOLinc_sensor($io_device); - -Where $io_device is the parent device defined above. +Instructions for this object are contained in C. -NOTES +=head2 NOTES This module works with the Insteon IOLinc device from Smarthome. The EZIO device uses a different set of commands and this code will offer only limited, if any @@ -77,11 +75,19 @@ support at all, for EZIO devices. The state that the relay is in when the device is linked to the PLM matters if you are using relay mode Momentary_A. -BUGS +=head2 BUGS The relay state will not be accurate if you are using a momentary mode. +=head2 INHERITS + +L, +L + +=head2 METHODS + =over + =cut use strict; @@ -121,6 +127,12 @@ my %message_types = ( extended_set_get => 0x2e ); +=item C + +Instantiates a new object. + +=cut + sub new { my ($class, $p_deviceid, $p_interface) = @_; @@ -133,6 +145,16 @@ sub new return $self; } +=item C + +Handles setting and receiving states from the device. + +If the set command originates from the device, it represents the sensor state +and is processed accordingly. All other set commands are sent to the device +and control the relay state. + +=cut + sub set { my ($self, $p_state, $p_setby, $p_respond) = @_; @@ -153,6 +175,16 @@ sub set return; } +=item C + +Works just like C but it requests the status of the sensor. +Will cause the sensor status to be printed to the log. + +As an alternative to calling the function repeatedly, you can define an +L object. + +=cut + sub request_sensor_status { my ($self, $requestor) = @_; @@ -162,6 +194,14 @@ sub request_sensor_status $self->_send_cmd($message); } +=item C<_is_info_request()> + +Checks to see if an incomming message contains the sensor state or the operating +flags for the device. If not the message is passed on to +L. + +=cut + sub _is_info_request { my ($self, $cmd, $ack_setby, %msg) = @_; @@ -202,6 +242,13 @@ sub _is_info_request return $is_info_request; } +=item C<_process_message()> + +Checks for and handles unique IOLinc messages such as the momentary time settings. +All other messages are transferred to C. + +=cut + sub _process_message { my ($self,$p_setby,%msg) = @_; my $clear_message = 0; @@ -403,11 +450,63 @@ sub set_relay_mode return; } +=back + +=head2 AUTHOR + +Kevin Robert Keegan + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut + +=head1 B + +=head2 SYNOPSIS + +User Code: + + $io_device_sensor = new Insteon::IOLinc_sensor($io_device); + +Where $io_device is the parent device defined above. + +=head2 DESCRIPTION + +Creates a device that directly tracks the state of the IOLinc sensor. The state +of this object will reflect the state of the sensor and it will be automatically +updated as long as the IOLinc is linked to the PLM. + +Tie_events can be used on this child object. However, if you want to directly +link an obect to the sensor be sure to use the normal SCENE_MEMBER code in your +mht file with the main IOLinc device defined as the controller. + +=head2 INHERITS + +L + +=head2 METHODS + +=over + +=cut + package Insteon::IOLinc_sensor; use strict; @Insteon::IOLinc_sensor::ISA = ('Generic_Item'); +=item C + +Instantiates a new object. + +=cut + sub new { my ($class, $parent) = @_; my $self = new Generic_Item(); @@ -417,12 +516,32 @@ sub new { return $self; } +=item C + +Receives sensor state messages from the parent object and sets the state of this +device accordingly. + +=cut + sub set_receive { my ($self, $p_state, $p_setby, $p_respond) = @_; $self->SUPER::set($p_state, $p_setby, $p_respond); } - -1; =back + +=head2 AUTHOR + +Kevin Robert Keegan + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + =cut + +1; diff --git a/lib/Insteon/Irrigation.pm b/lib/Insteon/Irrigation.pm index 42464a0e9..50633d7a9 100755 --- a/lib/Insteon/Irrigation.pm +++ b/lib/Insteon/Irrigation.pm @@ -1,12 +1,7 @@ -=begin comment +=head1 B -AUTHORS -Gregg Liming -David Norwood -Evan P. Hall -Kevin R Keegan - Updated to new Insteon code +=head2 SYNOPSIS -INITIAL CONFIGURATION In user code: use Insteon::Irrigation; @@ -14,45 +9,49 @@ In user code: In items.mht: -INSTEON_IRRIGATION, 12.34.56, irrigation, Irrigation - -BUGS - - -EXAMPLE USAGE + INSTEON_IRRIGATION, 12.34.56, irrigation, Irrigation Creating the object: - use Insteon::Irrigation; - $irrigation = new Insteon::Irrigation('12.34.56', $myPLM); + + use Insteon::Irrigation; + $irrigation = new Insteon::Irrigation('12.34.56', $myPLM); Turning on a valve: - $v_valve_on = new Voice_Cmd "Turn on valve [1,2,3,4,5,6,7,8]"; - if (my $valve = state_now $v_valve_on) { - $valve--; - set_valve $irrigation "0$valve", "on"; - } + + $v_valve_on = new Voice_Cmd "Turn on valve [1,2,3,4,5,6,7,8]"; + if (my $valve = state_now $v_valve_on) { + $valve--; + set_valve $irrigation "0$valve", "on"; + } Turning off a valve: - $v_valve_off = new Voice_Cmd "Turn off valve [1,2,3,4,5,6,7,8]"; - if (my $valve = state_now $v_valve_off) { - $valve--; - set_valve $irrigation "0$valve", "off"; - } + + $v_valve_off = new Voice_Cmd "Turn off valve [1,2,3,4,5,6,7,8]"; + if (my $valve = state_now $v_valve_off) { + $valve--; + set_valve $irrigation "0$valve", "off"; + } Requesting valve status: - $v_valve_status = new Voice_Cmd "Request valve status"; - if (state_now $v_valve_status) { - poll_valve_status $irrigation; - } + + $v_valve_status = new Voice_Cmd "Request valve status"; + if (state_now $v_valve_status) { + poll_valve_status $irrigation; + } + +=head2 DESCRIPTION + +Provides basic support for the EzFlora (aka EzRain) sprinkler controller. -NOTES +=head2 INHERITS -This module works with the EzFlora (aka EzRain) sprinkler controller, documented -here http://www.simplehomenet.com/Downloads/EZRain%20Command%20Set.pdf +L, +L +=head2 METHODS + +=over -#TODO - - Should be able to intitialize programs. =cut use strict; @@ -75,6 +74,12 @@ our %message_types = ( # -------------------- START OF SUBROUTINES -------------------- # -------------------------------------------------------------- +=item C + +Instantiates a new object. + +=cut + sub new { my ($class, $p_deviceid, $p_interface) = @_; @@ -90,6 +95,13 @@ sub new { return $self; } +=item C + +Sends a message to the device requesting the valve status. The response from the +device is printed to the log and stores the result in memory. + +=cut + sub poll_valve_status { my ($self) = @_; my $subcmd = '02'; @@ -98,6 +110,13 @@ sub poll_valve_status { return; } +=item C + +Used to directly control valves. Valve_id is a two digit number 00-07, +valve_state may be on or off. + +=cut + sub set_valve { my ($self, $valve_id, $state) = @_; my $subcmd = $valve_id; @@ -117,6 +136,13 @@ sub set_valve { return; } +=item C + +Used to directly control programs. Program_id is a two digit number 00-03, +valve_state may be on or off. + +=cut + sub set_program { my ($self, $program_id, $state) = @_; my $subcmd = $program_id; @@ -136,31 +162,75 @@ sub set_program { return; } +=item C + +Returns the active valve number identified by the device in response to the last +C request. + +=cut + sub get_active_valve_id() { my ($self) = @_; return $$self{'active_valve_id'}; } +=item C + +Returns true if the active valve identified by the device in response to the last +C request is running. + +=cut + sub get_valve_is_running() { my ($self) = @_; return $$self{'valve_is_running'}; } +=item C + +Returns the active program number identified by the device in response to the last +C request. + +=cut + sub get_active_program_number() { my ($self) = @_; return $$self{'active_program_number'}; } +=item C + +Returns true if the active program identified by the device in response to the last +C request is running. + +=cut + sub get_program_is_running() { my ($self) = @_; return $$self{'program_is_running'}; } +=item C + +Returns true if valve 8 is set to be a pump. In this setup, valve 8 will also +turn on when any other valve is enabled. Generally used if you have some sort +of water pump that runs to provide water to your sprinklers. + +=cut + sub get_pump_enabled() { my ($self) = @_; return $$self{'pump_enabled'}; } +=item C + +Sends a request to the device asking for it to respond with the current timers. +It does not appear that there is code to interpret the response provided by the +device. + +=cut + sub get_timers() { my ($self) = @_; my $cmd = 'sprinkler_timers_request'; @@ -170,6 +240,13 @@ sub get_timers() { return; } +=item C<_is_info_request()> + +Used to intercept and handle unique EZFlora messages, all others are passed on +to C. + +=cut + sub _is_info_request { my ($self, $cmd, $ack_setby, %msg) = @_; my $is_info_request = 0; @@ -198,8 +275,38 @@ sub _is_info_request { } +=item C + +This does nothing and returns 0, it prevents a request_status message, which the +device does not support, from being sent to the device. + +=cut # Overload methods we don't use, but would otherwise cause Insteon traffic. sub request_status { return 0 } +=back + +=head2 AUTHOR + +Gregg Liming +David Norwood +Evan P. Hall +Kevin Robert Keegan + +=head2 SEE ALSO + +L, +L + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut + 1; \ No newline at end of file diff --git a/lib/Insteon/Lighting.pm b/lib/Insteon/Lighting.pm index 0896d6798..c7660e965 100644 --- a/lib/Insteon/Lighting.pm +++ b/lib/Insteon/Lighting.pm @@ -1,3 +1,19 @@ +=head1 B + +=head2 DESCRIPTION + +A generic base class for all Insteon lighting objects. + +=head2 INHERITS + +L + +=head2 METHODS + +=over + +=cut + package Insteon::BaseLight; use strict; @@ -5,6 +21,12 @@ use Insteon::BaseInsteon; @Insteon::BaseLight::ISA = ('Insteon::BaseDevice'); +=item C + +Instantiates a new object. + +=cut + sub new { my ($class,$p_deviceid,$p_interface) = @_; @@ -17,6 +39,12 @@ sub new return $self; } +=item C + +Takes the p_level, and stores it as a numeric level in memory. + +=cut + sub level { my ($self, $p_level) = @_; @@ -32,6 +60,38 @@ sub level } +=back + +=head2 AUTHOR + +Gregg Limming + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut + +=head1 B + +=head2 DESCRIPTION + +A generic base class for all dimmable Insteon lighting objects. + +=head2 INHERITS + +L + +=head2 METHODS + +=over + +=cut + package Insteon::DimmableLight; use strict; @@ -80,6 +140,17 @@ my %ramp_h2n = ( '1f' => .1 ); +=item C + +Takes ramp_seconds in numeric seconds and returns the hexadecimal value of that +ramp rate or the next lowest value if the passed value doesn't exist. Possible +ramp rates are: + +540, 480, 420, 360, 300, 270, 240, 210, 180, 150, 120, 90, 60, 47, 43, 39, 34, +32, 30, 28, 26, 23.5, 21.5, 19, 8.5, 6.5, 4.5, 2, .5, .3, .2, and .1 + +=cut + sub convert_ramp { my ($ramp_in_seconds) = @_; @@ -92,6 +163,13 @@ sub convert_ramp } } +=item C + +Takes ramp_code as a hexadecimal representation of the device's ramp rate and +returns the equivalent ramp rate in decimal seconds. + +=cut + sub get_ramp_from_code { my ($ramp_code) = @_; @@ -102,6 +180,13 @@ sub get_ramp_from_code } } +=item C + +Takes on_level as an integer percentage and converts it to a hexadecimal +representation of that on_level that is used by a device. + +=cut + sub convert_level { my ($on_level) = @_; @@ -119,6 +204,12 @@ sub convert_level return $level; } +=item C + +Instantiates a new object. + +=cut + sub new { my ($class,$p_deviceid,$p_interface) = @_; @@ -128,6 +219,14 @@ sub new return $self; } +=item C + +Takes the p_level, and stores it as a numeric level in memory. If the p_level +is ON and the device has a defined local_onlevel, the local_onlevel is stored +as the numeric level in memory. + +=cut + sub level { my ($self, $p_level) = @_; @@ -156,6 +255,48 @@ sub level } +=back + +=head2 AUTHOR + +Gregg Limming + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut + +=head1 B + +=head2 SYNOPSIS + +User code: + + use Insteon::ApplianceLinc; + $appliance_device = new Insteon::ApplianceLinc('12.34.56',$myPLM); + +In mht file: + + INSTEON_APPLIANCELINC, 12.34.56, appliance_device, appliance_group + +=head2 DESCRIPTION + +Provides support for the Insteon ApplianceLinc. + +=head2 INHERITS + +L + +=head2 METHODS + +=over + +=cut package Insteon::ApplianceLinc; @@ -164,6 +305,12 @@ use Insteon::BaseInsteon; @Insteon::ApplianceLinc::ISA = ('Insteon::BaseLight'); +=item C + +Instantiates a new object. + +=cut + sub new { my ($class,$p_deviceid,$p_interface) = @_; @@ -173,6 +320,15 @@ sub new return $self; } +=item C + +Handles setting and receiving states from the device. + +NOTE - Maybe this should be moved to BaseLight, or something farther up the stack? +The only thing this routine does is convert p_state with derive_link_state. + +=cut + sub set { my ($self, $p_state, $p_setby, $p_respond) = @_; @@ -182,6 +338,49 @@ sub set return $self->Insteon::BaseDevice::set($link_state, $p_setby, $p_respond); } +=back + +=head2 AUTHOR + +Gregg Limming + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut + +=head1 B + +=head2 SYNOPSIS + +User code: + + use Insteon::LampLinc; + $lamp_device = new Insteon::LampLinc('12.34.56',$myPLM); + +In mht file: + + INSTEON_LAMPLINC, 12.34.56, lamp_device, All_Lights + +=head2 DESCRIPTION + +Provides support for the Insteon LampLinc. + +=head2 INHERITS + +L, +L + +=head2 METHODS + +=over + +=cut package Insteon::LampLinc; @@ -190,6 +389,11 @@ use Insteon::BaseInsteon; @Insteon::LampLinc::ISA = ('Insteon::DimmableLight','Insteon::DeviceController'); +=item C + +Instantiates a new object. + +=cut sub new { @@ -200,6 +404,50 @@ sub new return $self; } +=back + +=head2 AUTHOR + +Gregg Limming + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut + +=head1 B + +=head2 SYNOPSIS + +User code: + + use Insteon::SwitchLincRelay; + $light_device = new Insteon::SwitchLincRelay('12.34.56',$myPLM); + +In mht file: + + INSTEON_SWITCHLINCRELAY, 12.34.56, light_device, All_Lights + +=head2 DESCRIPTION + +Provides support for the Insteon SwitchLinc Relay. + +=head2 INHERITS + +L, +L + +=head2 METHODS + +=over + +=cut + package Insteon::SwitchLincRelay; use strict; @@ -207,6 +455,11 @@ use Insteon::BaseInsteon; @Insteon::SwitchLincRelay::ISA = ('Insteon::BaseLight','Insteon::DeviceController'); +=item C + +Instantiates a new object. + +=cut sub new { @@ -217,6 +470,15 @@ sub new return $self; } +=item C + +Handles setting and receiving states from the device. + +NOTE - Maybe this should be moved to BaseLight, or something farther up the stack? +The only thing this routine does is convert p_state with derive_link_state. + +=cut + sub set { my ($self, $p_state, $p_setby, $p_respond) = @_; @@ -226,6 +488,50 @@ sub set return $self->Insteon::DeviceController::set($link_state, $p_setby, $p_respond); } +=back + +=head2 AUTHOR + +Gregg Limming + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut + +=head1 B + +=head2 SYNOPSIS + +User code: + + use Insteon::SwitchLinc; + $light_device = new Insteon::SwitchLinc('12.34.56',$myPLM); + +In mht file: + + INSTEON_SWITCHLINC, 12.34.56, light_device, All_Lights + +=head2 DESCRIPTION + +Provides support for the Insteon SwitchLinc. + +=head2 INHERITS + +L, +L + +=head2 METHODS + +=over + +=cut + package Insteon::SwitchLinc; use strict; @@ -233,6 +539,12 @@ use Insteon::BaseInsteon; @Insteon::SwitchLinc::ISA = ('Insteon::DimmableLight','Insteon::DeviceController'); +=item C + +Instantiates a new object. + +=cut + sub new { my ($class,$p_deviceid,$p_interface) = @_; @@ -242,6 +554,17 @@ sub new return $self; } +=item C + +Handles setting and receiving states from the device. + +NOTE - This is just silly, the only thing this routine does is push the set +command to the L +class. Simply reording the class +inheritance of this object would remove the need to do this. + +=cut + sub set { my ($self, $p_state, $p_setby, $p_respond) = @_; @@ -249,6 +572,54 @@ sub set return $self->Insteon::DeviceController::set($p_state, $p_setby, $p_respond); } +=back + +=head2 AUTHOR + +Gregg Limming + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut + +=head1 B + +=head2 SYNOPSIS + +User code: + + use Insteon::KeyPadLincRelay; + $light_device = new Insteon::KeyPadLincRelay('12.34.56:01',$myPLM); + $button1_device = new Insteon::KeyPadLincRelay('12.34.56:02',$myPLM); + $button2_device = new Insteon::KeyPadLincRelay('12.34.56:03',$myPLM); + +In mht file: + + INSTEON_KEYPADLINCRELAY, 12.34.56:01, light_device, All_Lights + INSTEON_KEYPADLINCRELAY, 12.34.56:02, button1_device, All_Buttons + INSTEON_KEYPADLINCRELAY, 12.34.56:03, button2_device, All_Buttons + +=head2 DESCRIPTION + +Provides support for the Insteon KeypadLinc Relay. + +=head2 INHERITS + +L, +L + +=head2 METHODS + +=over + +=cut + package Insteon::KeyPadLincRelay; use strict; @@ -256,6 +627,11 @@ use Insteon::BaseInsteon; @Insteon::KeyPadLincRelay::ISA = ('Insteon::BaseLight','Insteon::DeviceController'); +=item C + +Instantiates a new object. + +=cut sub new { @@ -266,6 +642,13 @@ sub new return $self; } +=item C + +Handles setting and receiving states from the device and specifically its +subordinate buttons. + +=cut + sub set { my ($self, $p_state, $p_setby, $p_respond) = @_; @@ -301,6 +684,53 @@ sub set } +=back + +=head2 AUTHOR + +Gregg Limming + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut + +=head1 B + +=head2 SYNOPSIS + +User code: + + use Insteon::KeyPadLinc; + $light_device = new Insteon::KeyPadLinc('12.34.56:01',$myPLM); + $button1_device = new Insteon::KeyPadLinc('12.34.56:02',$myPLM); + $button2_device = new Insteon::KeyPadLinc('12.34.56:03',$myPLM); + +In mht file: + + INSTEON_KEYPADLINC, 12.34.56:01, light_device, All_Lights + INSTEON_KEYPADLINC, 12.34.56:02, button1_device, All_Buttons + INSTEON_KEYPADLINC, 12.34.56:03, button2_device, All_Buttons + +=head2 DESCRIPTION + +Provides support for the Insteon KeypadLinc. + +=head2 INHERITS + +L, +L + +=head2 METHODS + +=over + +=cut package Insteon::KeyPadLinc; @@ -309,6 +739,11 @@ use Insteon::BaseInsteon; @Insteon::KeyPadLinc::ISA = ('Insteon::DimmableLight','Insteon::DeviceController'); +=item C + +Instantiates a new object. + +=cut sub new { @@ -319,6 +754,16 @@ sub new return $self; } +=item C + +Handles setting and receiving states from the device and specifically its +subordinate buttons. + +NOTE: This could be merged somehow with the set() function in +C + +=cut + sub set { my ($self, $p_state, $p_setby, $p_respond) = @_; @@ -354,6 +799,52 @@ sub set } +=back + +=head2 AUTHOR + +Gregg Limming + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut + +=head1 B + +=head2 SYNOPSIS + +User code: + + use Insteon::FanLinc; + $light_device = new Insteon::FanLinc('12.34.56:01',$myPLM); + $fan_device = new Insteon::FanLinc('12.34.56:02',$myPLM); + +In mht file: + + INSTEON_FANLINC, 12.34.56:01, light_device, All_Lights + INSTEON_FANLINC, 12.34.56:02, fan_device, All_Fans + +=head2 DESCRIPTION + +Provides support for the Insteon FanLinc. + +=head2 INHERITS + +L, +L + +=head2 METHODS + +=over + +=cut + package Insteon::FanLinc; use strict; @@ -361,6 +852,12 @@ use Insteon::BaseInsteon; @Insteon::FanLinc::ISA = ('Insteon::DimmableLight','Insteon::DeviceController'); +=item C + +Instantiates a new object. + +=cut + sub new { my ($class,$p_deviceid,$p_interface) = @_; @@ -369,6 +866,13 @@ sub new return $self; } +=item C + +Handles setting and receiving states from the device and specifically its +fan object. + +=cut + sub set { my ($self, $p_state, $p_setby, $p_respond) = @_; @@ -412,6 +916,14 @@ sub set } } +=item C + +Will request the status of the device. For the light device, the process is +handed off to the L routine. This routine +specifically handles the fan request. + +=cut + sub request_status { my ($self,$requestor) = @_; @@ -427,6 +939,14 @@ sub request_status } } +=item C<_is_info_request()> + +Handles incoming messages from the device which are unique to the FanLinc, +specifically this handles the C response for the Fan device, +all other responses are handed off to the C. + +=cut + sub _is_info_request { my ($self, $cmd, $ack_setby, %msg) = @_; @@ -448,6 +968,14 @@ sub _is_info_request return $is_info_request; } +=item C + +Handles command acknowledgement messages received from the device that are +unique to the FanLinc, specifically the acknowledgement of commands sent to the +fan device. All other instances are handed off to the C. + +=cut + sub is_acknowledged { my ($self, $p_ack) = @_; @@ -468,5 +996,20 @@ sub is_acknowledged } } +=back + +=head2 AUTHOR + +Kevin Robert Keegan + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut 1 \ No newline at end of file diff --git a/lib/Insteon/Message.pm b/lib/Insteon/Message.pm index 238ed3138..a9c8966b2 100644 --- a/lib/Insteon/Message.pm +++ b/lib/Insteon/Message.pm @@ -1,8 +1,31 @@ +=head1 B + +=head2 DESCRIPTION + +Generic base class for L object messages, including +L. Primarily just +stores variables for the object. + +=head2 INHERITS + +Nothing + +=head2 METHODS + +=over + +=cut package Insteon::BaseMessage; use strict; +=item C + +Instantiates a new object. + +=cut + sub new { my ($class) = @_; @@ -15,6 +38,12 @@ sub new return $self; } +=item C + +Save and retrieve the interface data defined by C. + +=cut + sub interface_data { my ($self, $interface_data) = @_; @@ -25,6 +54,13 @@ sub interface_data return $$self{interface_data}; } +=item C + +Stores the time at which a message was added to the queue. Used for calculating +how long a message was delayed. + +=cut + sub queue_time { my ($self, $queue_time) = @_; @@ -35,6 +71,12 @@ sub queue_time return $$self{queue_time}; } +=item C + +Data will be evaluated each time the message is sent. + +=cut + sub callback { my ($self, $callback) = @_; @@ -45,6 +87,13 @@ sub callback return $$self{callback}; } +=item C + +Data will be evaluated if the maximum number of retry attempts has been made +and the message is not acknowledged. + +=cut + sub failure_callback { my ($self, $callback) = @_; @@ -55,6 +104,12 @@ sub failure_callback return $$self{failure_callback}; } +=item C + +Stores and retrieves the number of times Misterhouse has tried to send the message. + +=cut + sub send_attempts { my ($self, $send_attempts) = @_; @@ -65,6 +120,12 @@ sub send_attempts return $$self{send_attempts}; } +=item C + +Stores and retrieves what the source of this message was. + +=cut + sub setby { my ($self, $setby) = @_; @@ -75,6 +136,12 @@ sub setby return $$self{setby}; } +=item C + +Stores and retrieves respond variable. + +=cut + sub respond { my ($self, $respond) = @_; @@ -85,6 +152,17 @@ sub respond return $$self{respond}; } + +=item C + +Stores and retrieves no_hop_increase variable, if set to true, when the message +is retried, no additional hops will be added. Typically used where the failure +to deliver the last message attempt was not caused by a failure of the object +to receive the message such as when the PLM is too busy to even attempt sending +the message. + +=cut + sub no_hop_increase { my ($self, $no_hop_increase) = @_; @@ -95,6 +173,16 @@ sub no_hop_increase return $$self{no_hop_increase}; } +=item C + +Stores and retrieves the number of times MisterHouse should try to deliver this +message. If B is set in the ini parameters will default +to that value, otherwise defaults to 5. Some messages types have specific +retry counts, such as L +battery level requests which are only sent once. + +=cut + sub retry_count { my ($self, $retry_count) = @_; if ($retry_count) @@ -107,6 +195,18 @@ sub retry_count { return $result_retry; } +=item C + +Sends this message using the interface p_interface. If C is +greater than 0 then +L +is increase by one. Calls C +when the message is sent. + +Returns 1 if message sent or 0 if message retry count exceeds C. + +=cut + sub send { my ($self, $interface) = @_; @@ -155,6 +255,13 @@ sub send } +=item C + +Returns the number of seconds that elapsed between time set in C +and when this routine was called. + +=cut + sub seconds_delayed { my ($self) = @_; @@ -169,6 +276,13 @@ sub seconds_delayed return $delay_time; } +=item C + +Stores and returns the number of milliseconds, p_timeout, that MisterHouse +should wait before retrying this message again. + +=cut + sub send_timeout { my ($self, $timeout) = @_; @@ -176,17 +290,72 @@ sub send_timeout return $$self{send_timeout}; } +=item C + +Returns the hexadecimal representation of the message. + +=cut + sub to_string { my ($self) = @_; return $self->interface_data; } +=back + +=head2 INI PARAMETERS + +=over + +=item Insteon_retry_count + +Sets the number of times MisterHouse will attempt to resend a message that has +not been acknowledged. The default setting is 5. + +=back + +=head2 AUTHOR + +Gregg Limming, Kevin Robert Keegan + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut + +=head1 B + +=head2 DESCRIPTION + +Main class for all L messages. + +=head2 INHERITS + +L + +=head2 METHODS + +=over + +=cut + package Insteon::InsteonMessage; use strict; @Insteon::InsteonMessage::ISA = ('Insteon::BaseMessage'); +=item C + +Instantiates a new object. + +=cut + sub new { my ($class, $command_type, $setby, $command, $extra) = @_; @@ -202,6 +371,12 @@ sub new return $self; } +=item C + +Takes msg, a hexadecimal message, and returns a hash of the message details. + +=cut + sub command_to_hash { my ($p_state) = @_; @@ -282,6 +457,11 @@ sub command_to_hash return %msg; } +=item C + +Stores and retrieves the Cmd1 value for this message. + +=cut sub command { @@ -290,6 +470,12 @@ sub command return $$self{command}; } +=item C + +Stores and retrieves the Command Type value for this message. + +=cut + sub command_type { my ($self, $command_type) = @_; @@ -297,6 +483,13 @@ sub command_type return $$self{command_type}; } +=item C + +Stores and retrieves the extra value for this message. For standard messages +extra is Cmd2. For extended messages extra is Cmd2 + D1-D14. + +=cut + sub extra { my ($self, $extra) = @_; @@ -304,16 +497,33 @@ sub extra return $$self{extra}; } +=item C + +Calculates and returns the number of milliseconds that MisterHouse should wait +for this message to be delivered. The time is based on message type, command type, +and hop count. + + Peek Related Messages = 4000 + PLM Scene Commands = 3000 + Ext / Std + 0 Hop 2220 1400 + 1 Hop 2690 1700 + 2 Hop 3000 1900 + 3 Hop 3170 2000 + +These times were intially calculated by Gregg Limming and appear to have been +calculated based on experience. In reality each hop of a standard message +should take 50 ms and 108 for extended messages. Each time needs to be at least +doubled to compensate for the return hops as well. + +In reality, the PLM and even some Insteon devices appear to react much slower +than the spec defines. These settings generally appear to work without causing +errors or too much undue delay. + +=cut + sub send_timeout { -# hop timing in seconds; this method returns timeout in millisconds -# hops standard extended -# ---- -------- -------- -# 0 1.40 2.22 -# 1 1.70 2.69 -# 2 1.90 3.01 -# 3 2.00 3.17 - my ($self, $ignore) = @_; my $hop_count = (ref $self->setby and $self->setby->isa('Insteon::BaseObject')) ? $self->setby->default_hop_count : $self->send_attempts; @@ -366,6 +576,12 @@ sub send_timeout } } +=item C + +Returns text based human readable representation of the message. + +=cut + sub to_string { my ($self) = @_; @@ -394,6 +610,13 @@ sub to_string return $result; } +=item C + +Stores data as the hexadecimal message, or if data is not specified, then derives +the hexadecimal message and returns it. + +=cut + sub interface_data { my ($self, $interface_data) = @_; @@ -412,6 +635,13 @@ sub interface_data } } +=item C<_derive_interface_data()> + +Converts all of the attributes set for this message into a hexadecimal message +that can be sent to the PLM. Will add checksums and crcs when necessary. + +=cut + sub _derive_interface_data { @@ -547,6 +777,8 @@ The calculation if the crc value involves data bytes from command 1 to the data byte. This function will return two bytes, which are generally added to the data 13 & 14 bytes in an extended message. +To add a crc16 to a message set the $$message{add_crc16} flag to true. + =cut sub calculate_crc16 @@ -573,6 +805,37 @@ sub calculate_crc16 return uc(sprintf("%x", $crc)); } +=back + +=head2 AUTHOR + +Gregg Limming, Kevin Robert Keegan, Michael Stovenour + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut + +=head1 B + +=head2 DESCRIPTION + +Main class for all L X10 messages. + +=head2 INHERITS + +L + +=head2 METHODS + +=over + +=cut package Insteon::X10Message; use strict; @@ -709,6 +972,12 @@ my %mh_commands = ( '8' => 'hail_request' ); +=item C + +Instantiates a new object. + +=cut + sub new { my ($class, $interface_data) = @_; @@ -721,6 +990,13 @@ sub new return $self; } +=item C + +Converts an X10 message from the interface into the generic humand readable X10 +message format. + +=cut + sub get_formatted_data { my ($self) = @_; @@ -753,6 +1029,12 @@ sub get_formatted_data return $msg; } +=item C + +Generates and returns the X10 hexadecimal message for sending to the PLM. + +=cut + sub generate_commands { my ($p_state, $p_setby) = @_; @@ -821,4 +1103,20 @@ sub generate_commands return @data; } +=back + +=head2 AUTHOR + +Gregg Limming + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut + 1; diff --git a/lib/Insteon/Security.pm b/lib/Insteon/Security.pm index e60e89118..27f7d04f0 100644 --- a/lib/Insteon/Security.pm +++ b/lib/Insteon/Security.pm @@ -2,8 +2,6 @@ =head2 SYNOPSIS -Configuration: - In user code: use Insteon::MotionSensor; @@ -86,7 +84,7 @@ contains a specific light and voltage level, as opposed to the simple binary states provided by the GROUP method. To use this method, set the C routine. - + You can further create child objects that automatically track the state of the light and voltage levels. These objects allow you to display the state of the light and voltage levels on the MisterHouse webpage. The child objects are @@ -96,7 +94,8 @@ certain threshold. =head2 INHERITS -B, B +L, +L =head2 METHODS @@ -116,6 +115,12 @@ my %message_types = ( extended_set_get => 0x2e ); +=item C + +Instantiates a new object. + +=cut + sub new { my ($class,$p_deviceid,$p_interface) = @_; @@ -130,6 +135,12 @@ sub new return $self; } +=item C + +Handles setting and receiving states from the device. + +=cut + sub set { my ($self, $p_state, $p_setby, $p_respond) = @_; @@ -356,6 +367,13 @@ sub enable_all_motion { return; } +=item C<_is_query_time_expired()> + +Returns true if the last battery level response received by MisterHouse is older +than C. + +=cut + sub _is_query_time_expired { my ($self) = @_; my $root = $self->get_root(); @@ -366,6 +384,14 @@ sub _is_query_time_expired { return 0; } +=item C<_process_message()> + +Processes unique messages sent to the device, notably battery level messages, and +settings messages but passes the rest of the messages off to +L. + +=cut + sub _process_message { my ($self,$p_setby,%msg) = @_; my $clear_message = 0; @@ -457,6 +483,12 @@ sub _process_message { return $clear_message; } +=item C + +Always returns 0. + +=cut + sub is_responder { return 0; @@ -464,6 +496,18 @@ sub is_responder =back +=head2 AUTHOR + +Kevin Robert Keegan, Gregg Limming + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + =head1 B =head2 SYNOPSIS @@ -494,7 +538,7 @@ battery_low_event code in the parent B object. =head2 INHERITS -B +L =head2 METHODS @@ -507,6 +551,12 @@ use strict; @Insteon::MotionSensor_Battery::ISA = ('Generic_Item'); +=item C + +Instantiates a new object. + +=cut + sub new { my ($class, $parent) = @_; my $self = new Generic_Item(); @@ -516,6 +566,12 @@ sub new { return $self; } +=item C + +Handles state updates provided by the parent object. + +=cut + sub set_receive { my ($self, $p_state) = @_; $self->SUPER::set($p_state); @@ -523,6 +579,18 @@ sub set_receive { =back +=head2 AUTHOR + +Kevin Robert Keegan + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + =head1 B =head2 SYNOPSIS @@ -554,7 +622,7 @@ B object. =head2 INHERITS -B +L =head2 METHODS @@ -567,6 +635,12 @@ use strict; @Insteon::MotionSensor_Light_Level::ISA = ('Generic_Item'); +=item C + +Instantiates a new object. + +=cut + sub new { my ($class, $parent) = @_; my $self = new Generic_Item(); @@ -576,6 +650,12 @@ sub new { return $self; } +=item C + +Handles state updates provided by the parent object. + +=cut + sub set_receive { my ($self, $p_state) = @_; $self->SUPER::set($p_state); @@ -589,11 +669,7 @@ None. =head2 AUTHOR -Bruce Winter, Gregg Limming, Kevin Robert Keegan - -=head2 SEE ALSO - - +Kevin Robert Keegan =head2 LICENSE diff --git a/lib/Insteon_PLM.pm b/lib/Insteon_PLM.pm index 79b2d0704..90e670463 100644 --- a/lib/Insteon_PLM.pm +++ b/lib/Insteon_PLM.pm @@ -1,43 +1,24 @@ -=begin comment -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +=head1 B -File: - Insteon_PLM.pm +=head2 SYNOPSIS -Description: +---Example Code and Usage--- - This is the base interface class for Insteon Power Line Modem (PLM) +=head2 DESCRIPTION - For more information regarding the technical details of the PLM: - http://www.smarthome.com/manuals/2412sdevguide.pdf +This is the base interface class for Insteon Power Line Modem (PLM) -Author(s): - Jason Sharpee / jason@sharpee.com - Gregg Liming / gregg@limings.net +=head2 INHERITS -License: - This free software is licensed under the terms of the GNU public license. GPLv2 +L, +L -Usage: - Use these mh.ini parameters to enable this code: - - Insteon_PLM_serial_port=/dev/ttyS4 - - Example initialization: - - -Notes: - -Special Thanks to: - Brian Warren for significant testing and patches - Bruce Winter - MH - -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +=head2 METHODS +=over =cut - package Insteon_PLM; use strict; @@ -82,6 +63,11 @@ my %prefix = ( plm_get_config => '0273' ); +=item C + +Creates a new serial port connection. + +=cut sub serial_startup { my ($instance) = @_; @@ -93,6 +79,12 @@ sub serial_startup { } +=item C + +Instantiates a new object. + +=cut + sub new { my ($class, $port_name, $p_deviceid) = @_; $port_name = 'Insteon_PLM' if !$port_name; @@ -126,6 +118,11 @@ sub new { return $self; } +=item C + +This is called by mh on exit to save the cached ALDB of a device to persistant data. + +=cut sub restore_string { @@ -137,6 +134,17 @@ sub restore_string return $restore_string; } +=item C + +Called once per loop. This checks for any data waiting on the serial port, if +data exists it is sent to C<_parse_data>. If there is no data waiting, then +this checks to see if the timers for any previous commands have expired, if they +have, it calls C. Else, this checks to see if there +is any timeout preventing a transmission right now, if there is no timeout it +calles C. + +=cut + sub check_for_data { my ($self) = @_; @@ -194,6 +202,11 @@ sub check_for_data { } } +=item C + +Used to send X10 messages, generates an X10 command and queues it. + +=cut sub set { @@ -206,6 +219,12 @@ sub set } } +=item C + +Puts the PLM into linking mode as a responder. + +=cut + sub complete_linking_as_responder { my ($self, $group) = @_; @@ -220,12 +239,24 @@ sub complete_linking_as_responder $self->queue_message($message) } +=item C + +Causes MisterHouse to dump its cache of the PLM link table to the log. + +=cut + sub log_alllink_table { my ($self) = @_; $self->_aldb->log_alllink_table if $self->_aldb; } +=item C + +Causes MisterHouse to scan the link table of the PLM only. + +=cut + sub scan_link_table { my ($self,$callback) = @_; @@ -236,6 +267,13 @@ sub scan_link_table $self->_aldb->get_first_alllink(); } +=item C + +Puts the PLM into linking mode as a controller, if p_group is specified the +controller will be added for this group, otherwise it will be for group 00. + +=cut + sub initiate_linking_as_controller { my ($self, $group) = @_; @@ -249,6 +287,14 @@ sub initiate_linking_as_controller $self->queue_message($message); } +=item C + +Puts the PLM into unlinking mode, if p_group is specified the PLM will try +to unlink any devices linked to that group that identify themselves with a set +button press. + +=cut + sub initiate_unlinking_as_controller { my ($self, $group) = @_; @@ -262,6 +308,11 @@ sub initiate_unlinking_as_controller $self->queue_message($message); } +=item C + +Cancels any pending linking session that has not completed. + +=cut sub cancel_linking { @@ -269,13 +320,23 @@ sub cancel_linking $self->queue_message(new Insteon::InsteonMessage('all_link_cancel', $self)); } +=item C<_aldb()> + +Returns the PLM's aldb object. + +=cut + sub _aldb { my ($self) = @_; return $$self{aldb}; } +=item C<_send_cmd()> +Causes a message to be sent to the serial port. + +=cut sub _send_cmd { my ($self, $message, $cmd_timeout) = @_; @@ -330,6 +391,15 @@ sub _send_cmd { } } +=item C<_parse_data()> + +A complex routine that parses data comming in from the serial port. In many cases +multiple messages or fragments of messages may arrive at once. This routine sorts +through the string of hexadecimal characters and determines what type of message +has arrived and its full content. Based on the type of message, it is then +passed off to lower level message handling routines. + +=cut sub _parse_data { my ($self, $data) = @_; @@ -753,17 +823,86 @@ sub _parse_data { return; } -# dummy sub required to support the X10 integrtion +=item C + +Dummy sub required to support the X10 integrtion, does nothing. + +=cut sub add_id_state { # do nothing } +=item C + +Stores and returns the firmware version of the PLM. + +=cut + sub firmware { my ($self, $p_firmware) = @_; $$self{firmware} = $p_firmware if defined $p_firmware; return $$self{firmware}; } +=back + +=head2 INI PARAMETERS + +=over + +=item Insteon_PLM_serial_port + +Identifies the port on which the PLM is attached. Example: + + Insteon_PLM_serial_port=/dev/ttyS4 + +=item Insteon_PLM_xmit_delay + +Sets the minimum amount of seconds that must elapse between sending Insteon messages +to the PLM. Defaults to 0.25. + +=item Insteon_PLM_xmit_x10_delay + +Sets the minimum amount of seconds that must elapse between sending X10 messages +to the PLM. Defaults to 0.50. + +=item Insteon_PLM_disable_throttling + +Periodically, the PLM will report that it is too busy to accept a message from +MisterHouse. When this happens, MisterHouse will wait 1 second before trying +to send a message to the PLM. If this is set to 1, downgrades the delay to only +.3 seconds. Most of the issues which caused the PLM to overload have been handled +it is unlikely that you would need to set this. + +=back + +=head2 NOTES + +Special Thanks to: + +Brian Warren for significant testing and patches + +Bruce Winter - MH + +=head2 AUTHOR + +Jason Sharpee / jason@sharpee.com, Gregg Liming / gregg@limings.net, Kevin Robert Keegan, Michael Stovenour + +=head2 SEE ALSO + +For more information regarding the technical details of the PLM: +L + +=head2 LICENSE + +This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut + 1;