Nest Thermostat, Software Update 2.0

Nest recently released a new update to the software of the thermostat device (as well as their corresponding web and mobile applications).

Some of the details may be found on their blog.

A few of the new features include an historical view of the heating/cooling usage:

image

On Friday, April 6th for example, you can see when the heat turned on and what the set points were for the day for my First Floor thermostat. The data isn’t as interesting during our Midwest Spring as the furnace doesn’t run nearly as much.

Here’s from another day:

image

I doubt I’ll use this feature much. It only has 10 days of information available apparently right now, so I just can’t see this being very useful. I’m skeptical that this will affect my choices as it comes to how we use our HVAC system. I could see potentially how aggregate data of many users (in a similar geographical area) could become more compelling and potentially a source of data that Nest might be able to sell.

The settings for a thermostat have been tweaked visually. The same basic data is available as before:

image

The learning tab has been cleaned up as well:

image

For some reason, our thermostat that we’ve had for four months is apparently still in training (Time to Temp). That seems like an issue that maybe I’ll look into. Although I don’t really care much about the “time to temp” feature normally as I don’t manually adjust the affected thermostat much.

The “Away” tab changed:

image

Not a big improvement for usability. Probably more touch friendly (and it’s logically correct as it heats when less than 58 degrees for example), but it feels wrong. Thermostats aren’t normally left to right oriented (temp goes up and down), so this breaks a typical UX model.

On the Equipment tab, they’ve tweaked the UI as well:

image

I clicked on the Safety Temp word (? it’s not a button, nor a link, so I don’t know what to call it) and the above UI displayed. The same temperature range UX is displayed, but here I like it even less. I suppose we don’t have a maximum temperature in the house during cooling season, but this is clunky. (And given that it’s safety related, I wish it were more clear). I can hear some of you say, “but it’s clear to me.” I do understand it, but I’m confident there is a better way of displaying and adjusting these temperatures that would be more obvious.

(And Nest Labs, go ahead and spell out “TEMP” please? Thanks!)

The technical info tab is the same basically.

There’s now a lock feature (which I have no need for, and am not going to experiment with right now):

image

One of the big new TM’ed features is called Airwave™. Apparently, when it’s hot and the humidity is low (not typical for Wisconsin, as our summers are usually hot and humid), the thermostat apparently will try to do more cooling by turning off the air conditioning system early and using the fan more. (I always thought our air conditioner already did that as the compressor turns off before the fans). If it helps lower our electricity bill, awesome. I’ll report back if I can tell that it is working and helping (without historical data though, it will be difficult for us, especially as we added solar panels to our house last fall).

The scheduling tab looks basically unchanged. The support tab has more content, so you don’t have to go to their web site to read the information. That’s a nice improvement.


OK, this was very strange. As I was writing this post (and in the middle of using the application), I saw the following:

image

image

image

Now, the thermostats are all disconnected in some odd way:

image

A few minutes later, things improved (but not perfect):

image 

Twenty minutes later, the BASEMENT thermostat is still disconnected. I reset the thermostat and it’s back now.

Get path or location of currently executing batch/command file in Windows

I didn’t know it was this simple, and am posting this information on my blog so I find it in the future, but hopefully this will help someone else!

I’ve created a number of batch files over the years which routinely copy files from one location to another, usually as part of a backup strategy. However, I’ve always just hard-coded the paths of the drives, etc. into the batch files. While this works for drives which are permanently attached (or internal), it’s more fragile with external (flash/USB) drives. As I’ve never understood the logic of drive letter selection in Windows (letters usually are the same, but occasionally not), it meant that I was tweaking the drive letter in the batch file before running. Annoying, but it worked.

Thanks to more than a few web sites, I now know there is a much better way!

There are basically two decent options, depending on your scenario and requirements.

Option 1

If you are using drive letters (and not a mapped drive\network share), then you can use the variable %CD%.

It contains the “current directory.” So, that actually may be more than you wanted if the current directory isn’t the root of the drive.

image

Simple, just chop it off:

image

%CD:~0,2%

The colon and tilde character is a flag which indicates that a substring should be returned rather than the entire string. The first value is the zero-based starting index and the second is the number of characters you want to return:

image

The above starts at character 4, and includes 3 characters.

For fun, you can use negative values:

image

With only a single negative parameter, it returns the number of characters requested starting with the rightmost character.  (Check here for a bunch of examples on string manipulation.)

So, you could use knowledge in a batch file:

image

The above line uses robocopy (available in modern versions of Windows without an extra install) to copy from the folder \\server\Backups to the current path appended with \server\backups. So, if the batch file containing the robocopy command was executing on the J: drive, the resulting robocopy command would be:

image

By using the :~0,2 syntax, regardless of the folder the batch file is located in, it always copies to the root of the J drive (as the first two characters are J and : ).

Option 2

The other option is a bit different as it only works in a batch or command file.

image

Parameter zero (%0) in batch file represents the full path of the currently executing file (path and filename). The (dp) modifiers expand the value to be the “drive” and the “path,” excluding the file name.

image

You can manipulate the value as well:

image

I’m immediately going to adopt the first option into all of my “robocopy” batch files.

Some code from SnugUp.Browser (an album browser for SmugMug)

I’ve been doing some tinkering recently with SmugMug again.

Through testing SnugUp for the past 4 years, I’ve made quite the mess of my SmugMug account. Literally hundreds of poorly organized and often completely junk albums. I’ve been wanting to clean it up, but SmugMug’s UI for that is so obnoxiously slow and tedious that I decided I wanted to write a tool to make it easier to manage.

Admittedly, given the amount of time I’ve spent on writing the tool (which I’m not yet finished with), I could have cleaned up my SmugMug account dozens of times. However, with my developer hat on, I thought, how fun would that be? Smile

 

image

So, I’ve started to create the SnugUp.Browser. It’s a bit of an interesting beast in that it is a Windows application that hosts a web browser to display its UI. I’d tried using WPF/XAML and just couldn’t get the look I was wanting in a reasonable amount of time and effort.

<RANT>WPF desperately needs a VirtualizingWrapPanel. Microsoft needs to ship it. </RANT>

So, I created a WinForms project to host the IE Web Browser. (Arrgh, the WPF WebBrowser sucks still. It’s not nearly as feature complete as the one from WinForms!). Internally, the web pages are served via an HttpListener.

try { int portSuggest = GetAvailablePort(); portSuggest = 40000; _listener.Prefixes.Add(string.Format("http://localhost:{0}/", portSuggest)); _listener.Start(); while (maxConnections-- > 0) { _listener.BeginGetContext(HandleRequest, _listener); } } catch (Exception ex) { Debug.WriteLine(ex); }

The HandleRequest method responds in two ways:

  1. Respond with JSON data (as if it were a web service). 99% of the code needed to access SmugMug’s APIs was already written in a C# library I wrote for SnugUp.
  2. Respond with binary data, providing a “proxy” to a service. This was needed to handle downloading images from the application. When the request was directly made from the WebBrowser to SmugMug, it was refused as the http-referer header was not a valid source apparently (SmugMug didn’t like “http://localhost:####” as the referrer.
resourceRequested = context.Request.Url.LocalPath.Replace('/', '.'); if (resourceRequested.StartsWith(".")) { resourceRequested = resourceRequested.Substring(1); } Debug.WriteLine(string.Format("Requested: {0}", resourceRequested)); using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(string.Format("SnugUp.Resources.{0}", resourceRequested))) { if (stream == null) { //context.Response.StatusCode = 404; if (url.LocalPath.StartsWith("/proxy")) { var proxyUrl = url.Query.Substring("?url=".Length); extension = Path.GetFileName(proxyUrl); try { WebClient client = new WebClient(); byte[] buffer = client.DownloadData(proxyUrl); context.Response.Headers.Add("Expires", DateTime.UtcNow.AddDays(30).ToString("R")); context.Response.ContentType = GetContentType(context, extension); context.Response.OutputStream.Write(buffer, 0, buffer.Length); } catch { context.Response.StatusCode = 404; } } } else { string contentType = GetContentType(context, extension); context.Response.ContentType = contentType; stream.CopyTo(context.Response.OutputStream); } // Close the Response to send it to the client. // } }

If the resource can’t be found as an Embedded Resource, it tries a proxy.

I built a tiny router for the web services so that I could easily plug-n-play new functionality:

public virtual object Route(string path, dynamic data) { if (path.StartsWith("/")) { path = path.Substring(1); } var paths = path.Split('/'); if (paths.Length > 0) { var controllerName = paths[0]; var controllerType = Type.GetType(string.Format("SnugUp.Controller.{0}Controller", controllerName), false, true); if (controllerType != null) { var instance = InitializeControllerInstance(controllerType); // default? if (paths.Length > 1) { MethodInfo method = controllerType.GetMethod(paths[1]); if (method != null) { try { object results = method.Invoke(instance, new object[] {data}); return results; } catch (Exception ex) { Debug.WriteLine(ex); } } } } } return null; }

It just looks up a request dynamically, maps to a method, and calls it (the response is eventually serialized as JSON).

For UI, I’m currently using Bootstrap (although that may be removed), Knockout.JS, and jQuery. I’m doing a bit of trickery to make sure that only what’s visible on the screen is loaded (even when the user scrolls up and down … it’s pretty smart).  I’ll likely post more about that in a future update.

The app is becoming larger… and bloated a bit when compared to my original needs. Smile

 

image

It now can show the images from the gallery as well. Smile

image

Nest Thermostat Review, Update #9

Summary/Index

When I woke up this morning, I decided that I’d use the remote features of my Nest Thermostat to increase the temperature of the first floor as the normal schedule hadn’t started yet.

Here’s what I saw on my iPad:

image

Basement: ?

First Floor: ?

When I tapped the Basement image, this alert was displayed:

image

“Thermostat Disconnected: The thermostat Basement last connected to nest.com more than 7 hours ago.”

What?

I next checked the First Floor. Thankfully, it said that it had only been 17 minutes since it last connected. I’ve seen that issue before and it usually resolves. But, I’ve never seen one go more than about 50 53 minutes without reporting in.

The fact that I was using the iPad and the Nest application meant that WiFi Internet was available in our house.

I went to the Basement thermostat and noticed this glaring issue after clicking through to settings:

image

What?  Seriously?

As I wasn’t sure what the best option was at 6:45AM for support, I decided to re-add the thermostat to our account. The thermostat had no trouble accessing the Nest cloud and obtaining one of the one time connection keys. (So, I maintain, it’s not general Internet connectivity issues).

After deleting and adding it back, the web site still reported it as MIA. So, I tried a reset:

image

After resetting, and waiting several minutes after it had completely restarted, it appeared again on the Nest web site.

However, 3 hours later:

image

It’s again, gone missing.

So, I called support this fine Sunday morning and talked to one of the same support engineers I’ve spoken with in the past (“DK”). I explained the general problem (and emphasized that my biggest concern was that it had lost my account information), my “solution”, and said that it was again not reporting in. In a typical (somewhat ironic) support fashion, as I was explaining the issue and walking to the basement, the thermostat reported in successfully to the Nest cloud.

He had me drop the account, add it to my account, and restart it again. He said that resolves the problem in about 70% of the cases. In the other 30%, he mentioned that they often manually update the firmware and that will help. [ugh]

I’m going to keep an eye on it and will add more details as needed/available.

 

If you want to talk and discuss more about digital thermostats with others, I’d suggest here: digtstat.com (it’s a web site I created to help provide a better place to have discussions about the Nest thermostat).