From ba10bbf9c1722acbba395d012b29f494781fdcef Mon Sep 17 00:00:00 2001 From: Richard Thompson Date: Sun, 2 Jun 2013 10:15:23 -0700 Subject: [PATCH 1/4] added cooling, fan, autoaway, manual away, and humidity --- collect.php | 36 ++++++++++++++++++++++++++++++++++-- dbsetup | 5 +++++ fetch.php | 6 +++--- index.html | 14 ++++++++++++-- insert.php | 4 ++-- test.php | 15 ++++++++------- 6 files changed, 64 insertions(+), 16 deletions(-) diff --git a/collect.php b/collect.php index cb91aa9..b5555e0 100644 --- a/collect.php +++ b/collect.php @@ -11,10 +11,42 @@ function get_nest_data() { $nest = new Nest(); $info = $nest->getDeviceInfo(); + + if (preg_match("/away/", $info->current_state->mode) || preg_match("/range/", $info->current_state->mode)) { + if ($info->current_state->temperature > $info->target->temperature[1]) { + //Hotter then upper temp + $targetTemp = $info->target->temperature[1]; + } + else if ($info->current_state->temperature < $info->target->temperature[0]) { + //Colder then lower temp + $targetTemp = $info->target->temperature[0]; + } + else { + if (($info->target->temperature[1] - $info->current_state->temperature) < + ($info->current_state->temperature - $info->target->temperature[0])) + { + //Closer to upper temp + $targetTemp = $info->target->temperature[1]; + } + else + { + //Closer to lower temp + $targetTemp = $info->target->temperature[0]; + } + } + } + else { + $targetTemp = $info->target->temperature; + } + $data = array('heating' => ($info->current_state->heat == 1 ? 1 : 0), + 'cooling' => ($info->current_state->ac == 1 ? 1 : 0), + 'fan' => ($info->current_state->fan == 1 ? 1 : 0), + 'autoAway' => ($info->current_state->auto_away == 1 ? 1 : ($info->current_state->auto_away == -1 ? -1 : 0)), + 'manualAway' => ($info->current_state->manual_away == 1 ? 1 : 0), + 'leaf' => ($info->current_state->leaf == 1 ? 1 : 0), 'timestamp' => $info->network->last_connection, - 'target_temp' => sprintf("%.02f", (preg_match("/away/", $info->current_state->mode) ? - $info->target->temperature[0] : $info->target->temperature)), + 'target_temp' => sprintf("%.02f", $targetTemp), 'current_temp' => sprintf("%.02f", $info->current_state->temperature), 'humidity' => $info->current_state->humidity ); diff --git a/dbsetup b/dbsetup index 94901e2..9d7ee0f 100644 --- a/dbsetup +++ b/dbsetup @@ -6,6 +6,11 @@ USE nest; CREATE TABLE `data` ( `timestamp` timestamp NOT NULL, `heating` tinyint unsigned NOT NULL, + `cooling` tinyint unsigned NOT NULL, + `fan` tinyint unsigned NOT NULL, + `autoAway` tinyint signed NOT NULL, + `manualAway` tinyint unsigned NOT NULL, + `leaf` tinyint unsigned NOT NULL, `target` numeric(7,3) NOT NULL, `current` numeric(7,3) NOT NULL, `humidity` tinyint unsigned NOT NULL, diff --git a/fetch.php b/fetch.php index e7eefb6..a8ea5f5 100644 --- a/fetch.php +++ b/fetch.php @@ -15,11 +15,11 @@ if ($stmt = $db->res->prepare("SELECT * from data where timestamp>=DATE_SUB(NOW(), INTERVAL ? HOUR) order by timestamp")) { $stmt->bind_param("i", $hrs); $stmt->execute(); - $stmt->bind_result($timestamp, $heating, $target, $current, $humidity, $updated); + $stmt->bind_result($timestamp, $heating, $cooling, $fan, $autoAway, $manualAway, $leaf, $target, $current, $humidity, $updated); header("Content-type: text/tab-separated-values"); - print "timestamp\theating\ttarget\tcurrent\thumidity\tupdated\n"; + print "timestamp\theating\tcooling\tfan\tautoAway\tmanualAway\tleaf\ttarget\tcurrent\thumidity\tupdated\n"; while ($stmt->fetch()) { - print implode("\t", array($timestamp, $heating, $target, $current, $humidity, $updated)) . "\n"; + print implode("\t", array($timestamp, $heating, $cooling, $fan, $autoAway, $manualAway, $leaf, $target, $current, $humidity, $updated)) . "\n"; } $stmt->close(); } diff --git a/index.html b/index.html index 94c1fa5..b19523e 100644 --- a/index.html +++ b/index.html @@ -142,7 +142,7 @@ // fetch the data d3.tsv("fetch.php?hrs=" + hours, function(error, data) { - color.domain(d3.keys(data[0]).filter(function(key) { return (key == "current" || key == "target" || key == "heating"); })); + color.domain(d3.keys(data[0]).filter(function(key) { return (key == "current" || key == "target" || key == "heating"|| key == "cooling"|| key == "fan"|| key == "autoAway"|| key == "manualAway"|| key == "leaf"|| key == "humidity"); })); data.forEach(function(d) { d.date = parseDate(d.timestamp); @@ -153,7 +153,17 @@ name: name, values: data.map(function(d) { if (name == "heating") - return { date: d.date, val: +d[name] + 60 }; + return { date: d.date, val: +d[name] + 53 }; + else if(name == "cooling") + return { date: d.date, val: +d[name] + 50 }; + else if(name == "fan") + return { date: d.date, val: +d[name] + 47 }; + else if(name == "autoAway") + return { date: d.date, val: +d[name] + 44 }; + else if(name == "manualAway") + return { date: d.date, val: +d[name] + 41 }; + else if(name == "leaf") + return { date: d.date, val: +d[name] + 38 }; else return { date: d.date, val: +d[name] }; }) diff --git a/insert.php b/insert.php index 774091b..2ccbb89 100644 --- a/insert.php +++ b/insert.php @@ -8,8 +8,8 @@ $db = new DB($config); $data = get_nest_data(); if (!empty($data['timestamp'])) { - if ($stmt = $db->res->prepare("REPLACE INTO data (timestamp, heating, target, current, humidity, updated) VALUES (?,?,?,?,?,NOW())")) { - $stmt->bind_param("siddi", $data['timestamp'], $data['heating'], $data['target_temp'], $data['current_temp'], $data['humidity']); + if ($stmt = $db->res->prepare("REPLACE INTO data (timestamp, heating, cooling, fan, autoAway, manualAway, leaf, target, current, humidity, updated) VALUES (?,?,?,?,?,?,?,?,?,?,NOW())")) { + $stmt->bind_param("siiiiiiddi", $data['timestamp'], $data['heating'], $data['cooling'], $data['fan'], $data['autoAway'], $data['manualAway'], $data['leaf'], $data['target_temp'], $data['current_temp'], $data['humidity']); $stmt->execute(); $stmt->close(); } diff --git a/test.php b/test.php index 50d5486..1812361 100644 --- a/test.php +++ b/test.php @@ -11,27 +11,28 @@ $status = $nest->getStatus(); print_r($status); +echo "\n
\n
"; $infos = $nest->getDeviceInfo(); print_r($infos); - +echo "\n
\n
"; stuff_we_care_about($infos); function stuff_we_care_about($info) { echo "Heating : "; - printf("%s\n", ($info->current_state->heat == 1 ? 1 : 0)); + printf("%s\n
", ($info->current_state->heat == 1 ? 1 : 0)); echo "Timestamp : "; - printf("%s\n", $info->network->last_connection); + printf("%s\n
", $info->network->last_connection); echo "Target temperature : "; if (preg_match("/away/", $info->current_state->mode)) { - printf("%.02f\n", $info->target->temperature[0]); + printf("%.02f\n
", $info->target->temperature[0]); } else { - printf("%.02f\n", $info->target->temperature); + printf("%.02f\n
", $info->target->temperature); } echo "Current temperature : "; - printf("%.02f\n", $info->current_state->temperature); + printf("%.02f\n
", $info->current_state->temperature); echo "Current humidity : "; - printf("%d\n", $info->current_state->humidity); + printf("%d\n
", $info->current_state->humidity); } From 987904ca3b1d21b634572293edeefad6c37283df Mon Sep 17 00:00:00 2001 From: Richard Thompson Date: Sun, 2 Jun 2013 10:29:30 -0700 Subject: [PATCH 2/4] added cooling, fan, autoaway, manual away, and humidity --- collect.php | 60 ++++++++++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/collect.php b/collect.php index b5555e0..185bb51 100644 --- a/collect.php +++ b/collect.php @@ -14,42 +14,42 @@ function get_nest_data() { if (preg_match("/away/", $info->current_state->mode) || preg_match("/range/", $info->current_state->mode)) { if ($info->current_state->temperature > $info->target->temperature[1]) { - //Hotter then upper temp - $targetTemp = $info->target->temperature[1]; - } - else if ($info->current_state->temperature < $info->target->temperature[0]) { - //Colder then lower temp - $targetTemp = $info->target->temperature[0]; - } - else { - if (($info->target->temperature[1] - $info->current_state->temperature) < - ($info->current_state->temperature - $info->target->temperature[0])) - { - //Closer to upper temp - $targetTemp = $info->target->temperature[1]; - } - else - { - //Closer to lower temp - $targetTemp = $info->target->temperature[0]; - } - } + //Hotter then upper temp + $targetTemp = $info->target->temperature[1]; + } + else if ($info->current_state->temperature < $info->target->temperature[0]) { + //Colder then lower temp + $targetTemp = $info->target->temperature[0]; + } + else { + if (($info->target->temperature[1] - $info->current_state->temperature) < + ($info->current_state->temperature - $info->target->temperature[0])) + { + //Closer to upper temp + $targetTemp = $info->target->temperature[1]; + } + else + { + //Closer to lower temp + $targetTemp = $info->target->temperature[0]; + } + } } else { $targetTemp = $info->target->temperature; } $data = array('heating' => ($info->current_state->heat == 1 ? 1 : 0), - 'cooling' => ($info->current_state->ac == 1 ? 1 : 0), - 'fan' => ($info->current_state->fan == 1 ? 1 : 0), - 'autoAway' => ($info->current_state->auto_away == 1 ? 1 : ($info->current_state->auto_away == -1 ? -1 : 0)), - 'manualAway' => ($info->current_state->manual_away == 1 ? 1 : 0), - 'leaf' => ($info->current_state->leaf == 1 ? 1 : 0), - 'timestamp' => $info->network->last_connection, - 'target_temp' => sprintf("%.02f", $targetTemp), - 'current_temp' => sprintf("%.02f", $info->current_state->temperature), - 'humidity' => $info->current_state->humidity - ); + 'cooling' => ($info->current_state->ac == 1 ? 1 : 0), + 'fan' => ($info->current_state->fan == 1 ? 1 : 0), + 'autoAway' => ($info->current_state->auto_away == 1 ? 1 : ($info->current_state->auto_away == -1 ? -1 : 0)), + 'manualAway' => ($info->current_state->manual_away == 1 ? 1 : 0), + 'leaf' => ($info->current_state->leaf == 1 ? 1 : 0), + 'timestamp' => $info->network->last_connection, + 'target_temp' => sprintf("%.02f", $targetTemp), + 'current_temp' => sprintf("%.02f", $info->current_state->temperature), + 'humidity' => $info->current_state->humidity + ); return $data; } From 357253764617a516cc3ee08a5066f46a5338950f Mon Sep 17 00:00:00 2001 From: Richard Thompson Date: Sat, 8 Jun 2013 09:41:34 -0700 Subject: [PATCH 3/4] validate get data is not empty --- fetch.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fetch.php b/fetch.php index a8ea5f5..5e72c42 100644 --- a/fetch.php +++ b/fetch.php @@ -6,7 +6,7 @@ define('DEFAULT_HRS', 72); $hrs = DEFAULT_HRS; -if ($_GET["hrs"]) { +if (!empty($_GET["hrs"])) { $hrs = $_GET["hrs"]; } From d38b9532242b5eb9e3e6d200ca62db2400be8525 Mon Sep 17 00:00:00 2001 From: Richard Thompson Date: Sat, 8 Jun 2013 21:42:10 -0700 Subject: [PATCH 4/4] added energy collection routines and db setup --- collectEnergy.php | 53 ++++++++++++++++++++++++++++++++++++++++++ dbsetup | 43 ++++++++++++++++++++++++++++++++-- insertEnergy.php | 59 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 153 insertions(+), 2 deletions(-) create mode 100644 collectEnergy.php create mode 100644 insertEnergy.php diff --git a/collectEnergy.php b/collectEnergy.php new file mode 100644 index 0000000..dff9b7a --- /dev/null +++ b/collectEnergy.php @@ -0,0 +1,53 @@ +getDeviceInfo(); + $energy = $nest->getEnergyLatest(); + + //Change nulls to 0 + foreach ($energy->days as &$day) + { + foreach ($day->events as &$events) + { + if ( empty($events -> continuation) ) + { + $events -> continuation = 0; + } + if ( empty($events -> touched_by) ) + { + $events -> touched_by = 0; + } + if ( empty($events -> touched_when) ) + { + $events -> touched_when = 0; + } + if ( empty($events -> touched_timezone_offset) ) + { + $events -> touched_timezone_offset = 0; + } + if ( empty($events -> touched_where) ) + { + $events -> touched_where = 0; + } + } + unset($events); + } + unset($day); + + return $energy; +} + +function c_to_f($c) { + return ($c * 1.8) + 32; +} + +?> \ No newline at end of file diff --git a/dbsetup b/dbsetup index 9d7ee0f..b435eaa 100644 --- a/dbsetup +++ b/dbsetup @@ -17,6 +17,45 @@ CREATE TABLE `data` ( `updated` timestamp NOT NULL, PRIMARY KEY (`timestamp`), UNIQUE KEY `timestamp` (`timestamp`) -) -ENGINE=MyISAM DEFAULT CHARSET=latin1; +)ENGINE=MyISAM DEFAULT CHARSET=latin1; +CREATE TABLE `nest`.`cycles_data` ( + `cycleNum` int(10) unsigned NOT NULL, + `cycleDate` datetime NOT NULL, + `start` int(10) unsigned NOT NULL, + `duration` int(10) unsigned NOT NULL, + `type` int(10) unsigned NOT NULL, + PRIMARY KEY (`cycleNum`,`cycleDate`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +CREATE TABLE `nest`.`energy_data` ( + `energyDate` datetime NOT NULL, + `device_timezone_offset` int(11) NOT NULL, + `total_heating_time` int(10) unsigned NOT NULL, + `total_cooling_time` int(10) unsigned NOT NULL, + `total_fan_cooling_time` int(10) unsigned NOT NULL, + `total_humidifier_time` int(10) unsigned NOT NULL, + `total_dehumidifier_time` int(10) unsigned NOT NULL, + `leafs` int(11) NOT NULL, + `whodunit` int(11) NOT NULL, + `recent_avg_used` int(10) unsigned NOT NULL, + `usage_over_avg` int(10) NOT NULL, + PRIMARY KEY (`energyDate`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +CREATE TABLE `nest`.`events_data` ( + `eventNum` int(10) unsigned NOT NULL, + `eventDate` datetime NOT NULL, + `start` int(10) unsigned NOT NULL, + `end` int(10) unsigned NOT NULL, + `type` int(10) unsigned NOT NULL, + `touched_by` int(10) unsigned NOT NULL, + `touched_when` int(10) unsigned NOT NULL, + `touched_timezone_offset` int(11) NOT NULL, + `touched_where` int(11) NOT NULL, + `heat_temp` int(11) NOT NULL, + `cool_temp` int(11) NOT NULL, + `continuation` int(11) NOT NULL, + `event_touched_by` int(11) NOT NULL, + PRIMARY KEY (`eventNum`,`eventDate`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=latin1; diff --git a/insertEnergy.php b/insertEnergy.php new file mode 100644 index 0000000..86d283a --- /dev/null +++ b/insertEnergy.php @@ -0,0 +1,59 @@ +days as $day) + { + foreach ($day->events as $key => $events) + { + if ($stmt = $db->res->prepare("REPLACE INTO events_data (eventNum, eventDate, start, end, type, touched_by, touched_when, touched_timezone_offset, touched_where, heat_temp, cool_temp, continuation, event_touched_by) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)")) + { + $stmt->bind_param("isiiiiiiiiiii", $key, $day->day, $events->start, $events->end, $events->type, $events->touched_by, $events->touched_when, $events-> touched_timezone_offset, $events->touched_where, $events->heat_temp, $events->cool_temp, $events->continuation, $events->event_touched_by); + $stmt->execute(); + $stmt->close(); + } + } + + if ($stmt = $db->res->prepare("DELETE FROM events_data where eventNum > $key AND eventDate = '$day->day'")) + { + $stmt->execute(); + $stmt->close(); + } + unset($key); + + foreach ($day->cycles as $key => $cycles) + { + if ($stmt = $db->res->prepare("REPLACE INTO cycles_data (cycleNum, cycleDate, start, duration, type) VALUES (?,?,?,?,?)")) + { + $stmt->bind_param("isiii", $key, $day->day, $cycles->start, $cycles->duration, $cycles->type); + $stmt->execute(); + $stmt->close(); + } + } + + if ($stmt = $db->res->prepare("DELETE FROM cycles_data where cycleNum > $key AND cycleDate = '$day->day'")) + { + $stmt->execute(); + $stmt->close(); + } + unset($key); + + if ($stmt = $db->res->prepare("REPLACE INTO energy_data (energyDate, device_timezone_offset, total_heating_time, total_cooling_time, total_fan_cooling_time, total_humidifier_time, total_dehumidifier_time, leafs, whodunit, recent_avg_used, usage_over_avg) VALUES (?,?,?,?,?,?,?,?,?,?,?)")) + { + $stmt->bind_param("siiiiiiiiii", $day->day, $day->device_timezone_offset, $day->total_heating_time, $day->total_cooling_time, $day->total_fan_cooling_time, $day->total_humidifier_time, $day->total_dehumidifier_time, $day->leafs, $day->whodunit, $day->recent_avg_used, $day->usage_over_avg); + $stmt->execute(); + $stmt->close(); + } + } + $db->close(); +} catch (Exception $e) { + $errors[] = ("DB connection error! " . $e->getMessage() . "."); +} + +?> \ No newline at end of file