From 6d8f121f3ae27faac63c697be83219ecb28e02b2 Mon Sep 17 00:00:00 2001 From: H Plato Date: Sun, 31 May 2015 11:44:18 -0600 Subject: [PATCH 01/10] Some cosmetic changes to logging data --- lib/Venstar_Colortouch.pm | 40 ++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/lib/Venstar_Colortouch.pm b/lib/Venstar_Colortouch.pm index cb19ea1bf..d4f5fa845 100644 --- a/lib/Venstar_Colortouch.pm +++ b/lib/Venstar_Colortouch.pm @@ -201,7 +201,7 @@ sub _get_JSON_data { main::print_log("[Venstar Colortouch:". $self->{data}->{name} . "] Warning, failed to get data. Response code $responseCode"); if (defined $self->{child_object}->{comm}) { if ($self->{child_object}->{comm}->state() ne "offline") { - main::print_log "[Venstar Colortouch] Communication Tracking object found. Updating..." if ($self->{loglevel}); + main::print_log "[Venstar Colortouch] Communication Tracking object found. Updating to offline..." if ($self->{loglevel}); $self->{child_object}->{comm}->set("offline",'poll'); } } @@ -209,7 +209,7 @@ sub _get_JSON_data { } else { if (defined $self->{child_object}->{comm}) { if ($self->{child_object}->{comm}->state() ne "online") { - main::print_log "[Venstar Colortouch] Communication Tracking object found. Updating..." if ($self->{loglevel}); + main::print_log "[Venstar Colortouch] Communication Tracking object found. Updating to online..." if ($self->{loglevel}); $self->{child_object}->{comm}->set("online",'poll'); } } @@ -234,6 +234,28 @@ sub _get_JSON_data { sub _push_JSON_data { my ($self, $type, $params) = @_; + my (@fan,@fanstate,@modename,@statename,@schedule,@home); + $fan[0] = "auto"; + $fan[1] = "on"; + $fanstate[0] = "off"; + $fanstate[1] = "running"; + $home[0] = "home"; + $home[1] = "away"; + $modename[0] = "off"; + $modename[1] = "heating"; + $modename[2] = "cooling"; + $modename[3] = "auto"; + $statename[0] = "idle"; + $statename[1] = "heating"; + $statename[2] = "cooling"; + $statename[3] = "lockout"; + $statename[4] = "error"; + $schedule[0] = "morning (occupied1)"; + $schedule[1] = "day (occupied2)"; + $schedule[2] = "evening (occupied3)"; + $schedule[3] = "night (occupied4)"; + $schedule[255] = "inactive"; + my $cmd; #print "VCT DB: $params\n"; $self->stop_timer; #stop timer to prevent a clash of updates @@ -268,14 +290,14 @@ sub _push_JSON_data { } if ($caway ne $away) { - main::print_log("[Venstar Colortouch:". $self->{data}->{name} . "] Changing Away from $caway to $away"); + main::print_log("[Venstar Colortouch:". $self->{data}->{name} . "] Changing Away from $home[$caway] to $home[$away]"); $newaway = $away; } else { $newaway = $caway; } if ($csched ne $sched) { - main::print_log("[Venstar Colortouch:". $self->{data}->{name} . "] Changing Schedule from $csched to $sched"); + main::print_log("[Venstar Colortouch:". $self->{data}->{name} . "] Changing Schedule from $schedule[$csched] to $schedule[$sched]"); $newsched = $sched; } else { $newsched = $csched; @@ -296,7 +318,7 @@ sub _push_JSON_data { } $cmd = "tempunits=$newunits&away=$newaway&schedule=$newsched&hum_setpoint=$newhumsp&dehum_setpoint=$newdehumsp"; - main::print_log("Sending Settings command $cmd to " . $self->{host});# if $self->{debug}; + main::print_log("Sending Settings command $cmd to " . $self->{host}) if $self->{debug}; } elsif ($type eq 'control') { #mode=0&fan=0&heattemp=70&cooltemp=75 @@ -316,18 +338,18 @@ sub _push_JSON_data { $heattemp = $cheattemp if (!$heattemp); $cooltemp = $ccooltemp if (!$cooltemp); - main::print_log("data1=$isSuccessResponse,$cmode,$cfan,$cheattemp,$ccooltemp,$setpointdelta"); #TODO pass object to get debug - main::print_log("data2=$mode,$fan,$heattemp,$cooltemp"); #TODO debug + main::print_log("data1=$isSuccessResponse,$cmode,$cfan,$cheattemp,$ccooltemp,$setpointdelta") if $self->{debug}; #TODO pass object to get debug + main::print_log("data2=$mode,$fan,$heattemp,$cooltemp") if $self->{debug}; #TODO debug if ($cmode ne $mode) { - main::print_log("[Venstar Colortouch:". $self->{data}->{name} . "] Changing mode from $cmode to $mode"); + main::print_log("[Venstar Colortouch:". $self->{data}->{name} . "] Changing mode from $modename[$cmode] to $modename[$mode]"); $newmode = $mode; } else { $newmode = $cmode; } if ($cfan ne $fan) { - main::print_log("[Venstar Colortouch:". $self->{data}->{name} . "] Changing fan from $cfan to $fan"); + main::print_log("[Venstar Colortouch:". $self->{data}->{name} . "] Changing fan from $fanstate[$cfan] to $fanstate[$fan]"); $newfan = $fan; } else { $newfan = $cfan; From 5cd0ba467b33208e12d59f20c5bea46cc9aec529 Mon Sep 17 00:00:00 2001 From: H Plato Date: Sat, 11 Jul 2015 12:24:09 -0600 Subject: [PATCH 02/10] Fixes to the communication tracker object --- lib/Venstar_Colortouch.pm | 53 +++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/lib/Venstar_Colortouch.pm b/lib/Venstar_Colortouch.pm index d4f5fa845..f5147b74e 100644 --- a/lib/Venstar_Colortouch.pm +++ b/lib/Venstar_Colortouch.pm @@ -71,6 +71,7 @@ sub new { $self->{host} = $host; $self->{debug} = 0; $self->{loglevel} = 1; + $self->{status} = ""; $self->{timeout} = 15; #300; $self->_init; @@ -154,23 +155,23 @@ sub poll { $self->{data}->{sensors} = $sensors; $self->{data}->{timestamp} = time; $self->{data}->{retry} = 0; - if (defined $self->{child_object}->{comm}) { - if ($self->{child_object}->{comm}->state() ne "online") { - main::print_log "[Venstar Colortouch] Communication Tracking object found. Updating..." if ($self->{loglevel}); - $self->{child_object}->{comm}->set("online",'poll'); - } - } + #if (defined $self->{child_object}->{comm}) { + # if ($self->{child_object}->{comm}->state() ne "online") { + # main::print_log "[Venstar Colortouch:". $self->{data}->{name} . "]] Communication Tracking object found. Updating from " . $self->{child_object}->{comm}->state() . " to online..." if ($self->{loglevel}); + # $self->{child_object}->{comm}->set("online",'poll'); + # } + #} return ('1'); - } else { - main::print_log("[Venstar Colortouch:". $self->{data}->{name} . "] Problem retrieving poll data from " . $self->{host}); - $self->{data}->{retry}++; - if (defined $self->{child_object}->{comm}) { - if ($self->{child_object}->{comm}->state() ne "offline") { - main::print_log "[Venstar Colortouch] Communication Tracking object found. Updating..." if ($self->{loglevel}); - $self->{child_object}->{comm}->set("offline",'poll'); - } - } - return ('0'); + #} else { + # main::print_log("[Venstar Colortouch:". $self->{data}->{name} . "] Problem retrieving poll data from " . $self->{host}); + # $self->{data}->{retry}++; + # if (defined $self->{child_object}->{comm}) { + # if ($self->{child_object}->{comm}->state() ne "offline") { + # main::print_log "[Venstar Colortouch:". $self->{data}->{name} . "] Communication Tracking object found. Updating from " . $self->{child_object}->{comm}->state() . " to offline..." if ($self->{loglevel}); + # $self->{child_object}->{comm}->set("offline",'poll'); + # } + # } + # return ('0'); } } @@ -200,16 +201,18 @@ sub _get_JSON_data { if (! $isSuccessResponse ) { main::print_log("[Venstar Colortouch:". $self->{data}->{name} . "] Warning, failed to get data. Response code $responseCode"); if (defined $self->{child_object}->{comm}) { - if ($self->{child_object}->{comm}->state() ne "offline") { - main::print_log "[Venstar Colortouch] Communication Tracking object found. Updating to offline..." if ($self->{loglevel}); + if ($self->{status} eq "online") { + main::print_log "[Venstar Colortouch:". $self->{data}->{name} . "] Communication Tracking object found. Updating from " . $self->{child_object}->{comm}->state() . " to offline..." if ($self->{loglevel}); + $self->{status} = "offline"; $self->{child_object}->{comm}->set("offline",'poll'); } } return ('0'); } else { if (defined $self->{child_object}->{comm}) { - if ($self->{child_object}->{comm}->state() ne "online") { - main::print_log "[Venstar Colortouch] Communication Tracking object found. Updating to online..." if ($self->{loglevel}); + if ($self->{status} eq "offline") { + main::print_log "[Venstar Colortouch:". $self->{data}->{name} . "] Communication Tracking object found. Updating from " . $self->{child_object}->{comm}->state() . " to online..." if ($self->{loglevel}); + $self->{status} = "online"; $self->{child_object}->{comm}->set("online",'poll'); } } @@ -413,15 +416,17 @@ sub _push_JSON_data { if (! $isSuccessResponse ) { main::print_log("[Venstar Colortouch:". $self->{data}->{name} . "] Warning, failed to push data. Response code $responseCode"); if (defined $self->{child_object}->{comm}) { - if ($self->{child_object}->{comm}->state() ne "offline") { - main::print_log "[Venstar Colortouch] Communication Tracking object found. Updating..." if ($self->{loglevel}); + if ($self->{status} eq "online") { + main::print_log "[Venstar Colortouch:". $self->{data}->{name} . "] Communication Tracking object found. Updating from " . $self->{child_object}->{comm}->state() . " to offline..." if ($self->{loglevel}); + $self->{status} = "offline"; $self->{child_object}->{comm}->set("offline",'poll'); } } } else { if (defined $self->{child_object}->{comm}) { - if ($self->{child_object}->{comm}->state() ne "online") { - main::print_log "[Venstar Colortouch] Communication Tracking object found. Updating..." if ($self->{loglevel}); + if ($self->{status} eq "offline") { + main::print_log "[Venstar Colortouch:". $self->{data}->{name} . "] Communication Tracking object found. Updating from " . $self->{child_object}->{comm}->state() . " to online..." if ($self->{loglevel}); + $self->{status} = "online"; $self->{child_object}->{comm}->set("online",'poll'); } } From 0c3a8960e98ba19c205d9ace3e265215d4e785b1 Mon Sep 17 00:00:00 2001 From: H Plato Date: Sun, 3 Jan 2016 09:59:55 -0700 Subject: [PATCH 03/10] Fixed a typo when setting setpoints --- lib/Venstar_Colortouch.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Venstar_Colortouch.pm b/lib/Venstar_Colortouch.pm index f5147b74e..a2c9cb9d0 100644 --- a/lib/Venstar_Colortouch.pm +++ b/lib/Venstar_Colortouch.pm @@ -382,8 +382,8 @@ sub _push_JSON_data { $newheatsp=$cheattemp; } - if (($newheatsp - $newcoolsp) < $setpointdelta) { - main::print_log("[Venstar Colortouch:". $self->{data}->{name} . "] Error: Cooling and Heating setpoints need to be less than setpoint $setpointdelta"); + if (($newheatsp - $newcoolsp) > $setpointdelta) { + main::print_log("[Venstar Colortouch:". $self->{data}->{name} . "] Error: Cooling ($newcoolsp) and Heating ($newheatsp) setpoints need to be less than setpoint $setpointdelta"); main::print_log("[Venstar Colortouch:". $self->{data}->{name} . "] Not setting setpoints"); $newcoolsp=$ccooltemp; $newheatsp=$cheattemp; From e5c6abbf47a5a25c448ba1e042ece77fbbc7c306 Mon Sep 17 00:00:00 2001 From: H Plato Date: Tue, 19 Jan 2016 21:55:44 -0700 Subject: [PATCH 04/10] Homebridge configuration file generator --- code/common/homebridge_gen_config.pl | 77 ++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 code/common/homebridge_gen_config.pl diff --git a/code/common/homebridge_gen_config.pl b/code/common/homebridge_gen_config.pl new file mode 100644 index 000000000..8e1ccd740 --- /dev/null +++ b/code/common/homebridge_gen_config.pl @@ -0,0 +1,77 @@ +# cycle through + +my $port = $config_parms{homebridge_port}; +$port = 51826 unless ($port); +my $name = $config_parms{homebridge_name}; +$name = "Homebridge" unless ($name); +my $pin = $config_parms{homebridge_pin}; +$pin = "031-45-154" unless ($pin); +my $username = $config_parms{homebridge_username}; +$username = "CC:22:3D:E3:CE:30" unless ($username); +my $version = "1.0"; +my $filepath = $config_parms{data_dir} . "/homebridge_config.json"; +my $acc_count; +$v_generate_hb_config = new Voice_Cmd("Generate new Homebridge config.json file"); + +if (said $v_generate_hb_config) { + my $config_json = "{\n\t\"bridge\": {\n"; + $config_json .= "\t\t\"name\": " . $name . "\",\n"; + $config_json .= "\t\t\"username\": " . $username . "\",\n"; + $config_json .= "\t\t\"port\": " . $port . "\",\n"; + $config_json .= "\t\t\"pin\": " . $pin . "\"\n\t},\n"; + $config_json .= "\t\"description\": \"MH Generated HomeKit Configuration v" . $version . " " . &time_date_stamp(17) . "\",\n"; + + $config_json .= "\n\t\"accessories\": [\n"; + $acc_count = 0; + $config_json .= add_group("fan"); + $config_json .= add_group("switch"); + $config_json .= add_group("light"); + $config_json .= add_group("lock"); + $config_json .= add_group("garagedoor"); + $config_json .= add_group("blinds"); + + $config_json .= "\t\t}\n\t]\n}\n"; + print_log "Writing configuration to $filepath..."; + print_log $config_json; + file_write($filepath, $config_json); +} + + +sub add_group { + my ($type) = @_; + my %url_types; + $url_types{lock}{on} = "lock"; + $url_types{lock}{off} = "unlock"; + $url_types{blind}{on} = "up"; + $url_types{blind}{off} = "down"; + $url_types{garagedoor}{on} = "open"; + $url_types{garagedoor}{off} = "close"; + my $groupname = "HB__" . (uc $type); + my $group = &get_object_by_name($groupname); + print_log "gn=$groupname"; + return unless ($group); + my $text = ""; + for my $member (list $group) { + $text .= "\t\t},\n" if ($acc_count > 0 ); + $acc_count++; + $text .= "\t\t{\n"; + $text .= "\t\t\"accessory\": \"HttpMulti\",\n"; + my $name = $member->{object_name}; + $name =~ s/_/ /g; + $name =~ s/\$//g; + $name = $member->{label} if (defined $member->{label}); + $text .= "\t\t\"name\": \"" . $name . "\",\n"; + my $on = "on"; + $on = $url_types{$type}{on} if (defined $url_types{$type}{on}); + my $off = "off"; + $off = $url_types{$type}{off} if (defined $url_types{$type}{off}); + $text .= "\t\t\"" . $on . "_url\": \"http://" . $Info{IPAddress_local} . "/SET;none?select_item=" . $member->{object_name} . "&select_state=" .$on . "\",\n"; + $text .= "\t\t\"" . $off . "_url\": \"http://" . $Info{IPAddress_local} . "/SET;none?select_item=" . $member->{object_name} . "&select_state=" .$off . "\",\n"; + $text .= "\t\t\"brightness_url\": \"http://" . $Info{IPAddress_local} . "/SET;none?select_item=" . $member->{object_name} . "&select_state=%VALUE%\",\n" if ($type eq "light"); + $text .= "\t\t\"deviceType\": \"" . $type . "\"\n"; + } + return $text; +} + + + \ No newline at end of file From 39e9c538a7960d1dd37675f62de54f2ea30162e8 Mon Sep 17 00:00:00 2001 From: H Plato Date: Wed, 20 Jan 2016 16:29:44 -0700 Subject: [PATCH 05/10] Fixed some quotes --- code/common/homebridge_gen_config.pl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/common/homebridge_gen_config.pl b/code/common/homebridge_gen_config.pl index 8e1ccd740..82effb0b8 100644 --- a/code/common/homebridge_gen_config.pl +++ b/code/common/homebridge_gen_config.pl @@ -15,10 +15,10 @@ if (said $v_generate_hb_config) { my $config_json = "{\n\t\"bridge\": {\n"; - $config_json .= "\t\t\"name\": " . $name . "\",\n"; - $config_json .= "\t\t\"username\": " . $username . "\",\n"; - $config_json .= "\t\t\"port\": " . $port . "\",\n"; - $config_json .= "\t\t\"pin\": " . $pin . "\"\n\t},\n"; + $config_json .= "\t\t\"name\": \"" . $name . "\",\n"; + $config_json .= "\t\t\"username\": \"" . $username . "\",\n"; + $config_json .= "\t\t\"port\": \"" . $port . "\",\n"; + $config_json .= "\t\t\"pin\": \"" . $pin . "\"\n\t},\n"; $config_json .= "\t\"description\": \"MH Generated HomeKit Configuration v" . $version . " " . &time_date_stamp(17) . "\",\n"; $config_json .= "\n\t\"accessories\": [\n"; From 032c2b018c91c39201fa4a41c0e87ca1d52747e9 Mon Sep 17 00:00:00 2001 From: H Plato Date: Wed, 20 Jan 2016 16:58:00 -0700 Subject: [PATCH 06/10] Added ports for URLs --- code/common/homebridge_gen_config.pl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/code/common/homebridge_gen_config.pl b/code/common/homebridge_gen_config.pl index 82effb0b8..7815f582e 100644 --- a/code/common/homebridge_gen_config.pl +++ b/code/common/homebridge_gen_config.pl @@ -17,7 +17,7 @@ my $config_json = "{\n\t\"bridge\": {\n"; $config_json .= "\t\t\"name\": \"" . $name . "\",\n"; $config_json .= "\t\t\"username\": \"" . $username . "\",\n"; - $config_json .= "\t\t\"port\": \"" . $port . "\",\n"; + $config_json .= "\t\t\"port\": " . $port . ",\n"; $config_json .= "\t\t\"pin\": \"" . $pin . "\"\n\t},\n"; $config_json .= "\t\"description\": \"MH Generated HomeKit Configuration v" . $version . " " . &time_date_stamp(17) . "\",\n"; @@ -32,7 +32,7 @@ $config_json .= "\t\t}\n\t]\n}\n"; print_log "Writing configuration to $filepath..."; - print_log $config_json; + #print_log $config_json; file_write($filepath, $config_json); } @@ -65,9 +65,9 @@ sub add_group { $on = $url_types{$type}{on} if (defined $url_types{$type}{on}); my $off = "off"; $off = $url_types{$type}{off} if (defined $url_types{$type}{off}); - $text .= "\t\t\"" . $on . "_url\": \"http://" . $Info{IPAddress_local} . "/SET;none?select_item=" . $member->{object_name} . "&select_state=" .$on . "\",\n"; - $text .= "\t\t\"" . $off . "_url\": \"http://" . $Info{IPAddress_local} . "/SET;none?select_item=" . $member->{object_name} . "&select_state=" .$off . "\",\n"; - $text .= "\t\t\"brightness_url\": \"http://" . $Info{IPAddress_local} . "/SET;none?select_item=" . $member->{object_name} . "&select_state=%VALUE%\",\n" if ($type eq "light"); + $text .= "\t\t\"" . $on . "_url\": \"http://" . $Info{IPAddress_local} . ":" . $config_parms{http_port} . "/SET;none?select_item=" . $member->{object_name} . "&select_state=" .$on . "\",\n"; + $text .= "\t\t\"" . $off . "_url\": \"http://" . $Info{IPAddress_local} . ":" . $config_parms{http_port} . "/SET;none?select_item=" . $member->{object_name} . "&select_state=" .$off . "\",\n"; + $text .= "\t\t\"brightness_url\": \"http://" . $Info{IPAddress_local} . ":" . $config_parms{http_port} . "/SET;none?select_item=" . $member->{object_name} . "&select_state=%VALUE%\",\n" if ($type eq "light"); $text .= "\t\t\"deviceType\": \"" . $type . "\"\n"; } return $text; From f5bfd0dd944b0f4b47cb94357356ce182577af59 Mon Sep 17 00:00:00 2001 From: H Plato Date: Wed, 20 Jan 2016 19:08:44 -0700 Subject: [PATCH 07/10] Added in some comments --- code/common/homebridge_gen_config.pl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/code/common/homebridge_gen_config.pl b/code/common/homebridge_gen_config.pl index 7815f582e..e96030ff2 100644 --- a/code/common/homebridge_gen_config.pl +++ b/code/common/homebridge_gen_config.pl @@ -1,4 +1,8 @@ -# cycle through +# Category = HomeKit Integration + +#@ This module generates a config.json to be used by the homebridge system +#@ To use several groups need to be set up: +#@ HB__ where type is LIGHT, LOCK, FAN, GARAGEDOOR, BLINDS, SWITCH my $port = $config_parms{homebridge_port}; $port = 51826 unless ($port); From c826b82c60e8d883045f7b485187ef3d2f7d535d Mon Sep 17 00:00:00 2001 From: H Plato Date: Sun, 31 Jan 2016 19:11:55 -0700 Subject: [PATCH 08/10] Added in support for thermostats --- code/common/homebridge_gen_config.pl | 70 ++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 9 deletions(-) diff --git a/code/common/homebridge_gen_config.pl b/code/common/homebridge_gen_config.pl index e96030ff2..5e0bf5a7e 100644 --- a/code/common/homebridge_gen_config.pl +++ b/code/common/homebridge_gen_config.pl @@ -2,7 +2,13 @@ #@ This module generates a config.json to be used by the homebridge system #@ To use several groups need to be set up: -#@ HB__ where type is LIGHT, LOCK, FAN, GARAGEDOOR, BLINDS, SWITCH +#@ HB__ where type is LIGHT, LOCK, FAN, GARAGEDOOR, BLINDS, SWITCH, THERMOSTAT +#@ Thermostat control only tested with a few models. + +# TODO: +# Status Calls: determine if an object is on or off + +# read_url = "http://mh/sub?hb_status('$item')"; my $port = $config_parms{homebridge_port}; $port = 51826 unless ($port); @@ -12,7 +18,7 @@ $pin = "031-45-154" unless ($pin); my $username = $config_parms{homebridge_username}; $username = "CC:22:3D:E3:CE:30" unless ($username); -my $version = "1.0"; +my $version = "2"; my $filepath = $config_parms{data_dir} . "/homebridge_config.json"; my $acc_count; $v_generate_hb_config = new Voice_Cmd("Generate new Homebridge config.json file"); @@ -33,6 +39,7 @@ $config_json .= add_group("lock"); $config_json .= add_group("garagedoor"); $config_json .= add_group("blinds"); + $config_json .= add_group("thermostat"); $config_json .= "\t\t}\n\t]\n}\n"; print_log "Writing configuration to $filepath..."; @@ -65,17 +72,62 @@ sub add_group { $name =~ s/\$//g; $name = $member->{label} if (defined $member->{label}); $text .= "\t\t\"name\": \"" . $name . "\",\n"; - my $on = "on"; - $on = $url_types{$type}{on} if (defined $url_types{$type}{on}); - my $off = "off"; - $off = $url_types{$type}{off} if (defined $url_types{$type}{off}); - $text .= "\t\t\"" . $on . "_url\": \"http://" . $Info{IPAddress_local} . ":" . $config_parms{http_port} . "/SET;none?select_item=" . $member->{object_name} . "&select_state=" .$on . "\",\n"; - $text .= "\t\t\"" . $off . "_url\": \"http://" . $Info{IPAddress_local} . ":" . $config_parms{http_port} . "/SET;none?select_item=" . $member->{object_name} . "&select_state=" .$off . "\",\n"; - $text .= "\t\t\"brightness_url\": \"http://" . $Info{IPAddress_local} . ":" . $config_parms{http_port} . "/SET;none?select_item=" . $member->{object_name} . "&select_state=%VALUE%\",\n" if ($type eq "light"); + if ($type eq "thermostat") { + $text .= "\t\t\"setpoint_url\": \"http://" . $Info{IPAddress_local} . ":" . $config_parms{http_port} . "/sub?hb_thermo_setpoint(%27" . $member->{object_name} . "%27,%VALUE%)\",\n"; + } else { + my $on = "on"; + $on = $url_types{$type}{on} if (defined $url_types{$type}{on}); + my $off = "off"; + $off = $url_types{$type}{off} if (defined $url_types{$type}{off}); + $text .= "\t\t\"" . $on . "_url\": \"http://" . $Info{IPAddress_local} . ":" . $config_parms{http_port} . "/SET;none?select_item=" . $member->{object_name} . "&select_state=" .$on . "\",\n"; + $text .= "\t\t\"" . $off . "_url\": \"http://" . $Info{IPAddress_local} . ":" . $config_parms{http_port} . "/SET;none?select_item=" . $member->{object_name} . "&select_state=" .$off . "\",\n"; + $text .= "\t\t\"brightness_url\": \"http://" . $Info{IPAddress_local} . ":" . $config_parms{http_port} . "/SET;none?select_item=" . $member->{object_name} . "&select_state=%VALUE%\",\n" if ($type eq "light"); + $text .= "\t\t\"speed_url\": \"http://" . $Info{IPAddress_local} . ":" . $config_parms{http_port} . "/SET;none?select_item=" . $member->{object_name} . "&select_state=%VALUE%\",\n" if ($type eq "fan"); + } $text .= "\t\t\"deviceType\": \"" . $type . "\"\n"; } return $text; } +sub hb_status { + my ($item) = @_; + my $object = &get_object_by_name($item); + my $state = $object->state; + my $status = "1 "; + $status = "0 " if (lc $state eq "off"); + print_log "Homebridge: Status request: item=$item status=$status\n"; + return "$status"; +} +sub hb_thermo_setpoint { + my ($item,$value) = @_; + print_log "Homebridge temperature change request for $item to $value"; + my $object = &get_object_by_name($item); + if (UNIVERSAL::isa($object,'Venstar_Colortouch')) { + print_log "Venstar Colortouch found"; + my $sp_delay = 0; + if ($object->get_sched() eq "on") { + print_log "Thermostat on a schedule, turning off schedule for override"; + $object -> set_schedule("off"); + $sp_delay = 5; + } + if (($object->get_mode() eq "cooling") or ($object->get_mode() eq "auto")) { + eval_with_timer '$' . $item . '->set_cool_sp(' . $value . ')";', $sp_delay; + } else { + eval_with_timer '$' . $item . '->set_heat_sp(' . $value . ')";', $sp_delay; + } + + } elsif (UNIVERSAL::isa($object,'Nest_Thermostat')) { + print_log "Nest Thermostat found"; + $object -> set_target_temp($value); + + } elsif (UNIVERSAL::isa($object,'Insteon::Thermostat')) { + print_log "Insteon Thermostat found"; + $object -> heat_setpoint($value); + #how to determine when to select heat or cooling? + #$object -> cool_setpoint($value)"; + } else { + print_log "Unsupported Thermostat type"; + } +} \ No newline at end of file From 60627604635390269fef09ad5eee6102e0062630 Mon Sep 17 00:00:00 2001 From: H Plato Date: Sat, 13 Feb 2016 15:56:30 -0700 Subject: [PATCH 09/10] Added in the temperature autocalc and ability to directly overwrite the homebridge config file --- code/common/homebridge_gen_config.pl | 61 +++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 11 deletions(-) diff --git a/code/common/homebridge_gen_config.pl b/code/common/homebridge_gen_config.pl index 5e0bf5a7e..a32a8daba 100644 --- a/code/common/homebridge_gen_config.pl +++ b/code/common/homebridge_gen_config.pl @@ -20,6 +20,7 @@ $username = "CC:22:3D:E3:CE:30" unless ($username); my $version = "2"; my $filepath = $config_parms{data_dir} . "/homebridge_config.json"; +$filepath = $config_parms{homebridge_config_dir} . "/config.json" if (defined $config_parms{homebridge_config_dir}); my $acc_count; $v_generate_hb_config = new Voice_Cmd("Generate new Homebridge config.json file"); @@ -73,7 +74,9 @@ sub add_group { $name = $member->{label} if (defined $member->{label}); $text .= "\t\t\"name\": \"" . $name . "\",\n"; if ($type eq "thermostat") { - $text .= "\t\t\"setpoint_url\": \"http://" . $Info{IPAddress_local} . ":" . $config_parms{http_port} . "/sub?hb_thermo_setpoint(%27" . $member->{object_name} . "%27,%VALUE%)\",\n"; + my $name2 = $member->{object_name}; + $name2 =~ s/\$//g; + $text .= "\t\t\"setpoint_url\": \"http://" . $Info{IPAddress_local} . ":" . $config_parms{http_port} . "/sub?hb_thermo_setpoint(%27" . $name2 . "%27,%VALUE%)\",\n"; } else { my $on = "on"; $on = $url_types{$type}{on} if (defined $url_types{$type}{on}); @@ -101,33 +104,69 @@ sub hb_status { sub hb_thermo_setpoint { my ($item,$value) = @_; - print_log "Homebridge temperature change request for $item to $value"; + print_log "Homebridge: Temperature change request for $item to $value"; my $object = &get_object_by_name($item); + if (UNIVERSAL::isa($object,'Venstar_Colortouch')) { - print_log "Venstar Colortouch found"; + print_log "Homebridge: Thermostat Venstar Colortouch found"; my $sp_delay = 0; if ($object->get_sched() eq "on") { print_log "Thermostat on a schedule, turning off schedule for override"; $object -> set_schedule("off"); $sp_delay = 5; } - if (($object->get_mode() eq "cooling") or ($object->get_mode() eq "auto")) { - eval_with_timer '$' . $item . '->set_cool_sp(' . $value . ')";', $sp_delay; + my $auto_mode = "" + $auto_mode = &calc_auto_mode($value,$object->get_temp()) if ($object->get_mode() eq "auto"); + print_log "Homebridge: Thermostat calc mode is $auto_mode" if ($auto_mode); + if (($object->get_mode() eq "cooling") or ($auto_mode eq "cool")) { + if ($sp_delay) { + eval_with_timer '$' . $item . '->set_cool_sp(' . $value . ');', $sp_delay; + } else { + $object -> set_cool_sp($value); + } } else { - eval_with_timer '$' . $item . '->set_heat_sp(' . $value . ')";', $sp_delay; + if ($sp_delay) { + eval_with_timer '$' . $item . '->set_heat_sp(' . $value . ');', $sp_delay; + } else { + $object -> set_heat_sp($value); + } } } elsif (UNIVERSAL::isa($object,'Nest_Thermostat')) { - print_log "Nest Thermostat found"; + print_log "Homebridge: Nest Thermostat found"; $object -> set_target_temp($value); } elsif (UNIVERSAL::isa($object,'Insteon::Thermostat')) { - print_log "Insteon Thermostat found"; - $object -> heat_setpoint($value); - #how to determine when to select heat or cooling? - #$object -> cool_setpoint($value)"; + print_log "Homebridge: Insteon Thermostat found"; + my $auto_mode = "" + $auto_mode = &calc_auto_mode($value) if ($object->get_mode() eq "auto"); + print_log "Homebridge: Thermostat calc mode is $auto_mode" if ($auto_mode); + if (($object->get_mode() eq "cool") or ($auto_mode eq "cool")) { + $object -> cool_setpoint($value); + } else { + $object -> heat_setpoint($value); + } } else { print_log "Unsupported Thermostat type"; } } + +sub calc_auto_mode { + my ($value,$intemp,$outtemp) = @_; + + my $mode = "heat"; + my $cool_threshold = 8; #set to cool if outside less + my $outside = ""; + $outside = $Weather{Outdoor} if (defined $Weather{TempOutdoor}); + $outside = $outtemp if (defined $outtemp); + my $inside = ""; + $inside = $Weather{Inside} if (defined $Weather{TempInside}); + $inside = $intemp if (defined $intemp); + $mode = "cool" if ($value < $inside); + $mode = "heat" if (($value - $cool_threshold) > $outside); + + return $mode; +} + + \ No newline at end of file From 623367b5d046a59711acf5e8064a37582d4be4ce Mon Sep 17 00:00:00 2001 From: H Plato Date: Sun, 28 Feb 2016 17:51:28 -0700 Subject: [PATCH 10/10] Added in thermostat and auto temp logic --- code/common/homebridge_gen_config.pl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/code/common/homebridge_gen_config.pl b/code/common/homebridge_gen_config.pl index a32a8daba..6bb2b1998 100644 --- a/code/common/homebridge_gen_config.pl +++ b/code/common/homebridge_gen_config.pl @@ -4,6 +4,7 @@ #@ To use several groups need to be set up: #@ HB__ where type is LIGHT, LOCK, FAN, GARAGEDOOR, BLINDS, SWITCH, THERMOSTAT #@ Thermostat control only tested with a few models. +#@ requires homebridge-httpmulti accessory: https://github.com/hplato/homebridge-httpmulti # TODO: # Status Calls: determine if an object is on or off @@ -20,7 +21,6 @@ $username = "CC:22:3D:E3:CE:30" unless ($username); my $version = "2"; my $filepath = $config_parms{data_dir} . "/homebridge_config.json"; -$filepath = $config_parms{homebridge_config_dir} . "/config.json" if (defined $config_parms{homebridge_config_dir}); my $acc_count; $v_generate_hb_config = new Voice_Cmd("Generate new Homebridge config.json file"); @@ -52,8 +52,8 @@ sub add_group { my ($type) = @_; my %url_types; - $url_types{lock}{on} = "lock"; - $url_types{lock}{off} = "unlock"; + $url_types{lock}{on} = "locked"; + $url_types{lock}{off} = "unlocked"; $url_types{blind}{on} = "up"; $url_types{blind}{off} = "down"; $url_types{garagedoor}{on} = "open"; @@ -115,7 +115,7 @@ sub hb_thermo_setpoint { $object -> set_schedule("off"); $sp_delay = 5; } - my $auto_mode = "" + my $auto_mode = ""; $auto_mode = &calc_auto_mode($value,$object->get_temp()) if ($object->get_mode() eq "auto"); print_log "Homebridge: Thermostat calc mode is $auto_mode" if ($auto_mode); if (($object->get_mode() eq "cooling") or ($auto_mode eq "cool")) { @@ -138,7 +138,7 @@ sub hb_thermo_setpoint { } elsif (UNIVERSAL::isa($object,'Insteon::Thermostat')) { print_log "Homebridge: Insteon Thermostat found"; - my $auto_mode = "" + my $auto_mode = ""; $auto_mode = &calc_auto_mode($value) if ($object->get_mode() eq "auto"); print_log "Homebridge: Thermostat calc mode is $auto_mode" if ($auto_mode); if (($object->get_mode() eq "cool") or ($auto_mode eq "cool")) { @@ -156,6 +156,7 @@ sub calc_auto_mode { my $mode = "heat"; my $cool_threshold = 8; #set to cool if outside less + $cool_threshold = $config_parms{homebridge_auto_sp_threshold} if (defined $config_parms{homebridge_auto_sp_threshold}); my $outside = ""; $outside = $Weather{Outdoor} if (defined $Weather{TempOutdoor}); $outside = $outtemp if (defined $outtemp); @@ -167,6 +168,5 @@ sub calc_auto_mode { return $mode; } - - \ No newline at end of file +