{"id":315,"date":"2016-11-12T10:52:56","date_gmt":"2016-11-12T18:52:56","guid":{"rendered":"http:\/\/www.nathanbak.com\/?p=315"},"modified":"2026-01-02T20:04:41","modified_gmt":"2026-01-03T04:04:41","slug":"i-love-it-when-a-plan-comes-together","status":"publish","type":"post","link":"https:\/\/nathanbak.com\/?p=315","title":{"rendered":"I love it when a plan comes together"},"content":{"rendered":"<p>After spending a lot of effort and encountering difficulties in creating pieces, I am often pleasantly surprised when the pieces come together quickly and easily.\u00a0 This was the case for my latest home improvement tech project.\u00a0 In my home, it seems like some areas are warmer than others&#8211;I realized that some variance will exist, but I wanted to reduce the overall difference between upstairs and downstairs.<\/p>\n<p>The first step was to be able to measure the temperature or each area.\u00a0 Thanks to my ESP8266 development boards, I am able to <a href=\"http:\/\/www.nathanbak.com\/?p=285\">publish the upstairs temperature and publish it to a database and Bakboard<\/a>.\u00a0 With the new Nest thermostat and a little <a href=\"http:\/\/www.nathanbak.com\/?p=306\">playing with the REST API<\/a>, I was able to do something similar and publish the downstairs temperature to the BakBoard.\u00a0 There are now four temperatures published on the <a href=\"http:\/\/www.nathanbak.com\/?p=152\">Bakboard<\/a>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-317\" src=\"http:\/\/www.nathanbak.com\/wp-content\/uploads\/2016\/10\/temps-1024x551.png\" alt=\"temps\" width=\"840\" height=\"452\" srcset=\"https:\/\/nathanbak.com\/wp-content\/uploads\/2016\/10\/temps-1024x551.png 1024w, https:\/\/nathanbak.com\/wp-content\/uploads\/2016\/10\/temps-300x162.png 300w, https:\/\/nathanbak.com\/wp-content\/uploads\/2016\/10\/temps-768x414.png 768w, https:\/\/nathanbak.com\/wp-content\/uploads\/2016\/10\/temps-1200x646.png 1200w, https:\/\/nathanbak.com\/wp-content\/uploads\/2016\/10\/temps.png 1389w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/p>\n<p>I then wrote a simple Java program with that basically does the following:<\/p>\n<ol>\n<li>Get the temperature of the [Downstairs] thermostat<\/li>\n<li>Get the temperature of the [Upstairs] temperature sensor<\/li>\n<li>If the difference between the two temperatures is greater than 2 degrees, turn on the furnace fan<\/li>\n<\/ol>\n<p>I had a little trouble figuring out how to turn on the fan, but this is the way I implemented it in Java:<\/p>\n<pre>public void runFan(String thermostatId, String authToken) throws Exception {\r\n\u00a0\u00a0 \u00a0final String rootUrl = \"https:\/\/developer-api.nest.com\";\r\n\u00a0\u00a0 \u00a0HttpPut httpPut = new HttpPut(String.format(\"%s\/devices\/thermostats\/%s\/fan_timer_active\", rootUrl, thermostatId));\r\n\r\n\u00a0\u00a0 \u00a0StringEntity putEntity = new StringEntity(\"true\");\r\n\u00a0\u00a0 \u00a0httpPut.setEntity(putEntity);\r\n\u00a0\u00a0 \u00a0httpPut.addHeader(\"Content-Type\", \"application\/json\");\r\n\u00a0\u00a0 \u00a0httpPut.addHeader(\"Authorization\", \"Bearer \" + authToken);\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0CloseableHttpClient httpclient = HttpClients.createDefault();\r\n\u00a0\u00a0\u00a0 try {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 CloseableHttpResponse response = httpclient.execute(httpPut);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ We need to handle redirect\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (response.getStatusLine().getStatusCode() == 307) {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0String newUrl = response.getHeaders(\"Location\")[0].getValue();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0httpPut.setURI(new URI(newUrl));\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0response = httpclient.execute(httpPut);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 try {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 HttpEntity entity = response.getEntity();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 EntityUtils.consume(entity);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 } finally {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 response.close();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 } finally {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 httpclient.close();\r\n\u00a0\u00a0\u00a0 }\r\n}<\/pre>\n<p>Of course I want my code to run at regular intervals, but fortunately I had already figured out how to go about <a href=\"http:\/\/www.nathanbak.com\/?p=307\">running a Java program every 15 minutes<\/a>.\u00a0 It was easy to toss everything into a Docker container and let it do its thing.<\/p>\n<p>Here are a few notes\/design decisions that I made when putting things together:<\/p>\n<ul>\n<li>There are no changes to the basic functionality of the Nest thermostat.\u00a0 It is not aware of the external temperature sensor and heats\/cools as normal.\u00a0 This means, even if something goes wrong in my code (or network connection or custom hardware or somewhere else), things can&#8217;t go too crazy.<\/li>\n<li>My code does not control the length the fan runs&#8211;it starts the fan and lets the Nest take care of turning it off.\u00a0 There is a default run time that can be set on the thermostat&#8211;in my case I set it to 15 minutes to match the run duration of my new program.<\/li>\n<li>I have a two stage furnace and when just the fan is run it goes at half speed.\u00a0 Even at full speed the furnace fan is pretty quiet, and at half speed we don&#8217;t even notice.<\/li>\n<li>The thermostat only gives me the temperature in degree increments (if I were using Celsius it would be in half degree increments).\u00a0 My homemade temperature sensor goes to greater precision, but it&#8217;s hard to say whether that greater precision provides better accuracy.\u00a0 I went with a 2 degree variance threshold for enabling the fan to allow for rounding differences as well as accuracy differences between upstairs and downstairs temperatures.<\/li>\n<\/ul>\n<p>As far as I can tell, everything came together smoothly and &#8220;just works&#8221; and has been for the past few weeks.\u00a0 Occasionally I check the log to make sure it&#8217;s still running.\u00a0 Once in awhile when I walk past the Nest I notice the fan icon indicating that the fan is running (and I can verify that by putting my hand near a vent).\u00a0 The weather is still mild, so it will be interesting to see what happens when it gets colder (especially when I rev up the wood stove), but so far there seems less variance in temperature throughout the house.\u00a0 I love it when a plan comes together . . .<\/p>\n","protected":false},"excerpt":{"rendered":"<p>After spending a lot of effort and encountering difficulties in creating pieces, I am often pleasantly surprised when the pieces come together quickly and easily.\u00a0 This was the case for my latest home improvement tech project.\u00a0 In my home, it seems like some areas are warmer than others&#8211;I realized that some variance will exist, but &hellip; <a href=\"https:\/\/nathanbak.com\/?p=315\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;I love it when a plan comes together&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[5,8,13,16,10,15],"class_list":["post-315","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-bakboard","tag-docker","tag-esp8266","tag-java","tag-making","tag-nest"],"_links":{"self":[{"href":"https:\/\/nathanbak.com\/index.php?rest_route=\/wp\/v2\/posts\/315","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nathanbak.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nathanbak.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nathanbak.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nathanbak.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=315"}],"version-history":[{"count":5,"href":"https:\/\/nathanbak.com\/index.php?rest_route=\/wp\/v2\/posts\/315\/revisions"}],"predecessor-version":[{"id":322,"href":"https:\/\/nathanbak.com\/index.php?rest_route=\/wp\/v2\/posts\/315\/revisions\/322"}],"wp:attachment":[{"href":"https:\/\/nathanbak.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=315"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nathanbak.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=315"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nathanbak.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=315"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}