From f60abb6b984dd47e1a266cd692777ebb3c7e3704 Mon Sep 17 00:00:00 2001 From: DoumP Date: Sun, 7 Dec 2014 17:56:15 -0500 Subject: [PATCH 1/7] Add Support for "Fast On" & "Fast Off" --- lib/Insteon/BaseInsteon.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Insteon/BaseInsteon.pm b/lib/Insteon/BaseInsteon.pm index d512267d0..5a102181d 100644 --- a/lib/Insteon/BaseInsteon.pm +++ b/lib/Insteon/BaseInsteon.pm @@ -68,9 +68,9 @@ sub derive_link_state } my $link_state = 'on'; - if ($p_state eq 'off' or $p_state eq 'off_fast') + if ($p_state eq 'off' or $p_state eq 'off_fast' or $p_state eq 'on_fast') { - $link_state = 'off'; + $link_state = $p_state; } elsif ($p_state =~ /\d+%?/) { From f004badd66b355bcc907fc51a8798c1d4938b1f2 Mon Sep 17 00:00:00 2001 From: DoumP Date: Tue, 6 Jan 2015 23:20:14 -0500 Subject: [PATCH 2/7] Revert "Add Support for "Fast On" & "Fast Off"" This reverts commit f60abb6b984dd47e1a266cd692777ebb3c7e3704. --- lib/Insteon/BaseInsteon.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Insteon/BaseInsteon.pm b/lib/Insteon/BaseInsteon.pm index 5a102181d..d512267d0 100644 --- a/lib/Insteon/BaseInsteon.pm +++ b/lib/Insteon/BaseInsteon.pm @@ -68,9 +68,9 @@ sub derive_link_state } my $link_state = 'on'; - if ($p_state eq 'off' or $p_state eq 'off_fast' or $p_state eq 'on_fast') + if ($p_state eq 'off' or $p_state eq 'off_fast') { - $link_state = $p_state; + $link_state = 'off'; } elsif ($p_state =~ /\d+%?/) { From 57dc6b1859861d611677eb1bfbb66eeb3763dc3d Mon Sep 17 00:00:00 2001 From: DoumP Date: Tue, 6 Jan 2015 23:21:23 -0500 Subject: [PATCH 3/7] Add Support for "Fast On" & "Fast Off" on RemoteLinc --- lib/Insteon/Controller.pm | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/lib/Insteon/Controller.pm b/lib/Insteon/Controller.pm index 03d2ee285..556236c09 100644 --- a/lib/Insteon/Controller.pm +++ b/lib/Insteon/Controller.pm @@ -41,6 +41,7 @@ must first be put into "awake mode." =head2 INHERITS L, +L, L =head2 METHODS @@ -54,7 +55,7 @@ package Insteon::RemoteLinc; use strict; use Insteon::BaseInsteon; -@Insteon::RemoteLinc::ISA = ('Insteon::BaseDevice', 'Insteon::MultigroupDevice'); +@Insteon::RemoteLinc::ISA = ('Insteon::BaseDevice','Insteon::DeviceController', 'Insteon::MultigroupDevice'); my %message_types = ( %Insteon::BaseDevice::message_types, @@ -84,6 +85,39 @@ sub new return $self; } +=item C + +Overrides routine in BaseObject. Takes the various states available to insteon +devices and returns a derived state of on, off, or 0%-100%. + +=cut + +sub derive_link_state +{ + my ($self, $p_state) = @_; + #Convert Relative State to Absolute State + if ($p_state =~ /^([+-])(\d+)/) { + my $rel_state = $1 . $2; + my $curr_state = '100'; + $curr_state = '0' if ($self->state eq 'off'); + $curr_state = $1 if $self->state =~ /(\d{1,3})/; + $p_state = $curr_state + $rel_state; + $p_state = 100 if ($p_state > 100); + $p_state = 0 if ($p_state < 0); + } + + my $link_state = 'on'; + if (grep(/$p_state/i, @{['on_fast', 'off', 'off_fast']})) { + $link_state = $p_state; + } + elsif ($p_state =~ /\d+%?/) + { + $p_state =~ /(\d+)%?/; + $link_state = $1 . '%'; + } + return $link_state; +} + =item C Only available for RemoteLinc 2 models. From 70da073c7b965e5b28285684c8a73ffe1d96ec6f Mon Sep 17 00:00:00 2001 From: DoumP Date: Sun, 15 Nov 2015 20:43:23 -0500 Subject: [PATCH 4/7] Revert "Add Support for "Fast On" & "Fast Off" on RemoteLinc" This reverts commit 57dc6b1859861d611677eb1bfbb66eeb3763dc3d. --- lib/Insteon/Controller.pm | 36 +----------------------------------- 1 file changed, 1 insertion(+), 35 deletions(-) diff --git a/lib/Insteon/Controller.pm b/lib/Insteon/Controller.pm index 556236c09..03d2ee285 100644 --- a/lib/Insteon/Controller.pm +++ b/lib/Insteon/Controller.pm @@ -41,7 +41,6 @@ must first be put into "awake mode." =head2 INHERITS L, -L, L =head2 METHODS @@ -55,7 +54,7 @@ package Insteon::RemoteLinc; use strict; use Insteon::BaseInsteon; -@Insteon::RemoteLinc::ISA = ('Insteon::BaseDevice','Insteon::DeviceController', 'Insteon::MultigroupDevice'); +@Insteon::RemoteLinc::ISA = ('Insteon::BaseDevice', 'Insteon::MultigroupDevice'); my %message_types = ( %Insteon::BaseDevice::message_types, @@ -85,39 +84,6 @@ sub new return $self; } -=item C - -Overrides routine in BaseObject. Takes the various states available to insteon -devices and returns a derived state of on, off, or 0%-100%. - -=cut - -sub derive_link_state -{ - my ($self, $p_state) = @_; - #Convert Relative State to Absolute State - if ($p_state =~ /^([+-])(\d+)/) { - my $rel_state = $1 . $2; - my $curr_state = '100'; - $curr_state = '0' if ($self->state eq 'off'); - $curr_state = $1 if $self->state =~ /(\d{1,3})/; - $p_state = $curr_state + $rel_state; - $p_state = 100 if ($p_state > 100); - $p_state = 0 if ($p_state < 0); - } - - my $link_state = 'on'; - if (grep(/$p_state/i, @{['on_fast', 'off', 'off_fast']})) { - $link_state = $p_state; - } - elsif ($p_state =~ /\d+%?/) - { - $p_state =~ /(\d+)%?/; - $link_state = $1 . '%'; - } - return $link_state; -} - =item C Only available for RemoteLinc 2 models. From 8981e0799b3c560d126366b52a03d0d8f94729b6 Mon Sep 17 00:00:00 2001 From: DoumP Date: Sun, 15 Nov 2015 20:49:51 -0500 Subject: [PATCH 5/7] Add Support for "Fast On" & "Fast Off" on RemoteLinc --- lib/Insteon/Controller.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Insteon/Controller.pm b/lib/Insteon/Controller.pm index 03d2ee285..de2748975 100644 --- a/lib/Insteon/Controller.pm +++ b/lib/Insteon/Controller.pm @@ -41,6 +41,7 @@ must first be put into "awake mode." =head2 INHERITS L, +L, L =head2 METHODS @@ -54,7 +55,7 @@ package Insteon::RemoteLinc; use strict; use Insteon::BaseInsteon; -@Insteon::RemoteLinc::ISA = ('Insteon::BaseDevice', 'Insteon::MultigroupDevice'); +@Insteon::RemoteLinc::ISA = ('Insteon::DimmableLight', 'Insteon::MultigroupDevice'); my %message_types = ( %Insteon::BaseDevice::message_types, From d2128b436bb8e4fd69d0997e6b3b3099ee04e248 Mon Sep 17 00:00:00 2001 From: DoumP Date: Thu, 25 Feb 2016 21:00:43 -0500 Subject: [PATCH 6/7] Adjustment to match new master --- lib/Insteon/Controller.pm | 262 +++++++++++++++++++++----------------- 1 file changed, 142 insertions(+), 120 deletions(-) diff --git a/lib/Insteon/Controller.pm b/lib/Insteon/Controller.pm index de2748975..9c7573117 100644 --- a/lib/Insteon/Controller.pm +++ b/lib/Insteon/Controller.pm @@ -1,3 +1,4 @@ + =head1 B =head2 SYNOPSIS @@ -41,7 +42,6 @@ must first be put into "awake mode." =head2 INHERITS L, -L, L =head2 METHODS @@ -55,12 +55,13 @@ package Insteon::RemoteLinc; use strict; use Insteon::BaseInsteon; -@Insteon::RemoteLinc::ISA = ('Insteon::DimmableLight', 'Insteon::MultigroupDevice'); +@Insteon::RemoteLinc::ISA = + ( 'Insteon::BaseDevice', 'Insteon::MultigroupDevice' ); my %message_types = ( - %Insteon::BaseDevice::message_types, - bright => 0x15, - dim => 0x16 + %Insteon::BaseDevice::message_types, + bright => 0x15, + dim => 0x16 ); =item C @@ -69,20 +70,19 @@ Instantiates a new object. =cut -sub new -{ - my ($class,$p_deviceid,$p_interface) = @_; - - my $self = new Insteon::BaseDevice($p_deviceid,$p_interface); - $$self{message_types} = \%message_types; - if ($self->is_root){ - $self->restore_data('battery_timer', 'last_battery_time'); - $$self{queue_timer} = new Timer; - } - bless $self,$class; - $$self{is_responder} = 0; - $$self{is_deaf} = 1; - return $self; +sub new { + my ( $class, $p_deviceid, $p_interface ) = @_; + + my $self = new Insteon::BaseDevice( $p_deviceid, $p_interface ); + $$self{message_types} = \%message_types; + if ( $self->is_root ) { + $self->restore_data( 'battery_timer', 'last_battery_time' ); + $$self{queue_timer} = new Timer; + } + bless $self, $class; + $$self{is_responder} = 0; + $$self{is_deaf} = 1; + return $self; } =item C @@ -101,14 +101,15 @@ without causing adverse battery drain. =cut sub set_awake_time { - my ($self, $awake) = @_; - $awake = sprintf("%02x", $awake); - my $root = $self->get_root(); - my $extra = '000102' . $awake . '0000000000000000000000'; - $$root{_ext_set_get_action} = "set"; - my $message = new Insteon::InsteonMessage('insteon_ext_send', $root, 'extended_set_get', $extra); - $root->_send_cmd($message); - return; + my ( $self, $awake ) = @_; + $awake = sprintf( "%02x", $awake ); + my $root = $self->get_root(); + my $extra = '000102' . $awake . '0000000000000000000000'; + $$root{_ext_set_get_action} = "set"; + my $message = new Insteon::InsteonMessage( 'insteon_ext_send', $root, + 'extended_set_get', $extra ); + $root->_send_cmd($message); + return; } =item C @@ -126,16 +127,17 @@ expired. =cut sub get_extended_info { - my ($self,$no_retry) = @_; - my $root = $self->get_root(); - my $extra = '000100000000000000000000000000'; - $$root{_ext_set_get_action} = "get"; - my $message = new Insteon::InsteonMessage('insteon_ext_send', $root, 'extended_set_get', $extra); - if ($no_retry){ - $message->retry_count(1); - } - $root->_send_cmd($message); - return; + my ( $self, $no_retry ) = @_; + my $root = $self->get_root(); + my $extra = '000100000000000000000000000000'; + $$root{_ext_set_get_action} = "get"; + my $message = new Insteon::InsteonMessage( 'insteon_ext_send', $root, + 'extended_set_get', $extra ); + if ($no_retry) { + $message->retry_count(1); + } + $root->_send_cmd($message); + return; } =item C @@ -154,12 +156,13 @@ This setting will be saved between MisterHouse reboots. =cut sub set_battery_timer { - my ($self, $minutes) = @_; - my $root = $self->get_root(); - $$root{battery_timer} = sprintf("%u", $minutes); - ::print_log("[Insteon::RemoteLinc] Set battery timer to ". - $$root{battery_timer}." minutes"); - return; + my ( $self, $minutes ) = @_; + my $root = $self->get_root(); + $$root{battery_timer} = sprintf( "%u", $minutes ); + ::print_log( "[Insteon::RemoteLinc] Set battery timer to " + . $$root{battery_timer} + . " minutes" ); + return; } =item C<_is_battery_time_expired()> @@ -169,13 +172,15 @@ Returns true if the battery timer has expired, else returns false. =cut sub _is_battery_time_expired { - my ($self) = @_; - my $root = $self->get_root(); - if ($$root{battery_timer} > 0 && - (time - $$root{last_battery_time}) > ($$root{battery_timer} * 60)) { - return 1; - } - return 0; + my ($self) = @_; + my $root = $self->get_root(); + if ( $$root{battery_timer} > 0 + && ( time - $$root{last_battery_time} ) > + ( $$root{battery_timer} * 60 ) ) + { + return 1; + } + return 0; } =item C<_process_message()> @@ -188,60 +193,79 @@ 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; - my $root = $self->get_root(); - if ($root->_is_battery_time_expired){ - #Queue an get_extended_info request - if ($$root{queue_timer}->active){ - $$root{queue_timer}->restart(); - } - else { - $$root{queue_timer}->set(3, '$root->get_extended_info(1)'); - } - } - my $pending_cmd = ($$self{_prior_msg}) ? $$self{_prior_msg}->command : $msg{command}; - my $ack_setby = (ref $$self{m_status_request_pending}) ? $$self{m_status_request_pending} : $p_setby; - if ($msg{is_ack} && $self->_is_info_request($pending_cmd,$ack_setby,%msg)) { - $clear_message = 1; - $$self{m_status_request_pending} = 0; - $self->_process_command_stack(%msg); - } - elsif ($msg{command} eq "extended_set_get" && $msg{is_ack}){ - $self->default_hop_count($msg{maxhops}-$msg{hopsleft}); - #If this was a get request don't clear until data packet received - main::print_log("[Insteon::RemoteLinc] Extended Set/Get ACK Received for " . $self->get_object_name) if $self->debuglevel(1, 'insteon'); - if ($$self{_ext_set_get_action} eq 'set'){ - main::print_log("[Insteon::RemoteLinc] Clearing active message") if $self->debuglevel(1, 'insteon'); - $clear_message = 1; - $$self{_ext_set_get_action} = undef; - $self->_process_command_stack(%msg); - } - } - elsif ($msg{command} eq "extended_set_get" && $msg{is_extended}) { - if (substr($msg{extra},0,6) eq "000001") { - $self->default_hop_count($msg{maxhops}-$msg{hopsleft}); - #D10 = Battery; - my $voltage = (hex(substr($msg{extra}, 20, 2))/50); - main::print_log("[Insteon::RemoteLinc] The battery level ". - "for device ". $self->get_object_name . " is: ". - $voltage . " of 3.70 volts."); - $$root{last_battery_time} = time; - if (ref $$root{battery_object} && $$root{battery_object}->can('set_receive')) - { - $$root{battery_object}->set_receive($voltage, $root); - } - $clear_message = 1; - $self->_process_command_stack(%msg); - } else { - main::print_log("[Insteon::RemoteLinc] WARN: Corrupt Extended " - ."Set/Get Data Received for ". $self->get_object_name) if $self->debuglevel(1, 'insteon'); - } - } - else { - $clear_message = $self->SUPER::_process_message($p_setby,%msg); - } - return $clear_message; + my ( $self, $p_setby, %msg ) = @_; + my $clear_message = 0; + my $root = $self->get_root(); + if ( $root->_is_battery_time_expired ) { + + #Queue an get_extended_info request + if ( $$root{queue_timer}->active ) { + $$root{queue_timer}->restart(); + } + else { + $$root{queue_timer}->set( 3, '$root->get_extended_info(1)' ); + } + } + my $pending_cmd = + ( $$self{_prior_msg} ) ? $$self{_prior_msg}->command : $msg{command}; + my $ack_setby = + ( ref $$self{m_status_request_pending} ) + ? $$self{m_status_request_pending} + : $p_setby; + if ( $msg{is_ack} + && $self->_is_info_request( $pending_cmd, $ack_setby, %msg ) ) + { + $clear_message = 1; + $$self{m_status_request_pending} = 0; + $self->_process_command_stack(%msg); + } + elsif ( $msg{command} eq "extended_set_get" && $msg{is_ack} ) { + $self->default_hop_count( $msg{maxhops} - $msg{hopsleft} ); + + #If this was a get request don't clear until data packet received + main::print_log( + "[Insteon::RemoteLinc] Extended Set/Get ACK Received for " + . $self->get_object_name ) + if $self->debuglevel( 1, 'insteon' ); + if ( $$self{_ext_set_get_action} eq 'set' ) { + main::print_log("[Insteon::RemoteLinc] Clearing active message") + if $self->debuglevel( 1, 'insteon' ); + $clear_message = 1; + $$self{_ext_set_get_action} = undef; + $self->_process_command_stack(%msg); + } + } + elsif ( $msg{command} eq "extended_set_get" && $msg{is_extended} ) { + if ( substr( $msg{extra}, 0, 6 ) eq "000001" ) { + $self->default_hop_count( $msg{maxhops} - $msg{hopsleft} ); + + #D10 = Battery; + my $voltage = ( hex( substr( $msg{extra}, 20, 2 ) ) / 50 ); + main::print_log( "[Insteon::RemoteLinc] The battery level " + . "for device " + . $self->get_object_name . " is: " + . $voltage + . " of 3.70 volts." ); + $$root{last_battery_time} = time; + if ( ref $$root{battery_object} + && $$root{battery_object}->can('set_receive') ) + { + $$root{battery_object}->set_receive( $voltage, $root ); + } + $clear_message = 1; + $self->_process_command_stack(%msg); + } + else { + main::print_log( "[Insteon::RemoteLinc] WARN: Corrupt Extended " + . "Set/Get Data Received for " + . $self->get_object_name ) + if $self->debuglevel( 1, 'insteon' ); + } + } + else { + $clear_message = $self->SUPER::_process_message( $p_setby, %msg ); + } + return $clear_message; } =item C @@ -257,17 +281,14 @@ necessary voice commands. =cut -sub get_voice_cmds -{ - my ($self) = @_; +sub get_voice_cmds { + my ($self) = @_; my $object_name = $self->get_object_name; - my %voice_cmds = ( - %{$self->SUPER::get_voice_cmds} - ); - if ($self->is_root){ + my %voice_cmds = ( %{ $self->SUPER::get_voice_cmds } ); + if ( $self->is_root ) { %voice_cmds = ( %voice_cmds, - 'sync all device links' => "$object_name->sync_all_links()", + 'sync all device links' => "$object_name->sync_all_links()", 'AUDIT sync all device links' => "$object_name->sync_all_links(1)" ); } @@ -338,12 +359,12 @@ Instantiates a new object. =cut sub new { - my ($class, $parent) = @_; - my $self = new Generic_Item(); - my $root = $parent->get_root(); - bless $self, $class; - $$root{battery_object} = $self; - return $self; + my ( $class, $parent ) = @_; + my $self = new Generic_Item(); + my $root = $parent->get_root(); + bless $self, $class; + $$root{battery_object} = $self; + return $self; } =item C @@ -354,8 +375,8 @@ device accordingly. =cut sub set_receive { - my ($self, $p_state) = @_; - $self->SUPER::set($p_state); + my ( $self, $p_state ) = @_; + $self->SUPER::set($p_state); } =back @@ -373,4 +394,5 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY 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 From 6f21b1ba66abb672667e52557bf24bc34f95d1b8 Mon Sep 17 00:00:00 2001 From: DoumP Date: Sat, 27 Feb 2016 09:18:27 -0500 Subject: [PATCH 7/7] Fix for FastOn-FastOff on RemoteLinc --- lib/Insteon/Controller.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Insteon/Controller.pm b/lib/Insteon/Controller.pm index 9c7573117..0dc4f1060 100644 --- a/lib/Insteon/Controller.pm +++ b/lib/Insteon/Controller.pm @@ -42,6 +42,7 @@ must first be put into "awake mode." =head2 INHERITS L, +L, L =head2 METHODS @@ -56,7 +57,7 @@ use strict; use Insteon::BaseInsteon; @Insteon::RemoteLinc::ISA = - ( 'Insteon::BaseDevice', 'Insteon::MultigroupDevice' ); + ( 'Insteon::DimmableLight', 'Insteon::MultigroupDevice' ); my %message_types = ( %Insteon::BaseDevice::message_types,