thermostat 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,11 @@
1
+ === 1.2.0 2011-01-16
2
+ * fix rakefile so readme is correct
3
+ * added support for aux heat/aux heat offset/system time (Mark Flocco)
4
+
5
+
6
+ === 1.1.1 2010-03-11
7
+ * update examples
8
+
1
9
  === 1.1.0 2010-03-10
2
10
  * relatively complete unit test coverage
3
11
  * add a simulation mode to the network layer so it's easier to test
@@ -9,30 +9,47 @@ the web services provided by the Proliphix line of network
9
9
  thermostats. Their API is documented at
10
10
  http://www.proliphix.com/Documentation.aspx.
11
11
 
12
- The code is tested on the NT20e unit, which is what I own. It should
12
+ The code is tested on the NT20e unit, which is what I own (the NT10e
13
+ is the same hardware, just can't handle remote sensors). It should
13
14
  react that same across all their network accessible units.
14
15
 
15
16
  == FEATURES/PROBLEMS:
16
17
 
17
- Note: It wrote the base module over a year ago, and am now starting to more actively use it in a new project, so interfaces may change to make the api easier to use.
18
+ === Pholiphix Quirks
18
19
 
19
- Important notices from the manual:
20
+ There is an important notice in the manual which states that you
21
+ shouldn't make more than 1 request to the thermostat per 60 seconds
22
+ for any sustainable period of time. Because of that Thermostat.rb
23
+ does internal caching. If you have a long lived Thermostat.rb object,
24
+ it will fetch attributes on demand, and only refresh them after they
25
+ are more than 60 seconds old.
20
26
 
21
- **Limitations on the Frequency of Operations**
27
+ Set calls obviously still have to hit the thermostat, but the rate at
28
+ which you are going to use those calls should be much less. Because
29
+ the thermostat appears to be single threaded to some degree, I've
30
+ found that after a set, an immediate get fails. To get around this,
31
+ I've made the set call wait 1 second, then do a get off all values
32
+ again. This means the value map should be right after the set, so all
33
+ attribute gets should reflect the new state of the world.
22
34
 
23
- While the device can handle numerous back to back requests, it is
24
- advisable to not sustain an operation frequency higher than 1 request
25
- per 60 second period for a substantial amount of time. In other words,
26
- sustained polling of the device should not exceed a few requests per
27
- minute. A prolonged burst of requests higher than 1 request per 60
28
- second period may degrade the main function of the thermostat. Also,
29
- if one is making a PIB set and wishes to observe a reaction from the
30
- device, it is advisable to wait for at least 1 second between the set
31
- request and subsequent get request.
35
+ === Future Todo
36
+
37
+ Unit detection. There is no API to figure out if you are in degrees C
38
+ or degrees F, so I'm currently assuming F (though none of the code
39
+ really cares). I'd like to both detect that correctly, and use my
40
+ Temperature module to ensure you've values have units.
41
+
42
+ Day Classes and Activity Periods. These are in the plumbing but not
43
+ exposed yet. The API won't let you set them, but at least you could
44
+ get the current versions.
45
+
46
+ If anyone else has different thermostats they think could plug into
47
+ this interface, I'd be happy to work with them to do so. The code
48
+ isn't overly generic because I don't like premature abstractions.
32
49
 
33
50
  == SYNOPSIS:
34
51
 
35
- thermostat = Thermostate.new("hostname", "admin", "password")
52
+ thermostat = Thermostat.new("hostname", "admin", "password")
36
53
 
37
54
  # get the current temperature
38
55
  current_temp = thermostat.temp
@@ -43,17 +60,26 @@ request and subsequent get request.
43
60
  # set the thermostat to 69F (units are set in the thermost)
44
61
  thermostat.heat_to = 69
45
62
 
63
+ == DOCUMENTATION
64
+
65
+ Complete API documentation can be found at http://sdaguegems.rubyforge.org/thermostat/rdoc
66
+
46
67
  == REQUIREMENTS:
47
68
 
48
69
  == INSTALL:
49
70
 
50
71
  sudo gem install thermostat
51
72
 
73
+ == AUTHORS:
74
+
75
+ * Sean Dague
76
+ * Mark Flocco
77
+
52
78
  == LICENSE:
53
79
 
54
80
  (The MIT License)
55
81
 
56
- Copyright (c) 2008-2010 Sean Dague
82
+ Copyright (c) 2008-2011 Sean Dague
57
83
 
58
84
  Permission is hereby granted, free of charge, to any person obtaining
59
85
  a copy of this software and associated documentation files (the
data/Rakefile CHANGED
@@ -1,3 +1,4 @@
1
+ # encoding: US-ASCII
1
2
  require 'rubygems'
2
3
  gem 'hoe', '>= 2.1.0'
3
4
  require 'hoe'
@@ -12,10 +13,11 @@ Hoe.plugin :website
12
13
 
13
14
  # Generate all the Rake tasks
14
15
  # Run 'rake -T' to see list of generated tasks (from gem root directory)
15
- $hoe = Hoe.spec 'thermostat' do
16
+ $hoe = Hoe.spec "thermostat" do
16
17
  self.developer 'Sean Dague', 'sean@dague.net'
17
- self.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
18
- self.rubyforge_name = 'sdaguegems'
18
+ self.rubyforge_name = "sdaguegems"
19
+ self.extra_rdoc_files = ["README.rdoc"]
20
+ self.readme_file = "README.rdoc"
19
21
  self.extra_deps = [['temperature', '>= 1.0.0']]
20
22
  # self.extra_deps = [['activesupport','>= 2.0.2']]
21
23
  end
@@ -2,7 +2,19 @@
2
2
  module Proliphix
3
3
  # a whole crap load of constants for the proliphix API
4
4
 
5
- # read/write
5
+ # This is the user setable mode for what state the thermostat is
6
+ # in. This could be one of Off, Heat, Cool, or Auto. These
7
+ # really mean which setback values the thermostat is going to pay
8
+ # attention to.
9
+ #
10
+ # In Off, obviously, it ignores them all. In Heat mode, it only
11
+ # cares if you are below SetbackHeat. In Cool mode, it only cares
12
+ # if you are above SetbackCool. In Auto mode it will both heat
13
+ # and cool to keep within some target range.
14
+ #
15
+ # Unless you are storing great works of art, Auto mode is
16
+ # overkill, and probably going to cost you a lot of money on
17
+ # Spring and Fall days.
6
18
  ThermHvacMode = OID.new("HVAC Mode",
7
19
  "4.1.1",
8
20
  false,
@@ -126,5 +138,22 @@ module Proliphix
126
138
  ThermLastUsageReset = OID.new("Last Usage Reset",
127
139
  "4.5.6",
128
140
  false, nil, false) # we're going to have to be tricky about this one
141
+
142
+ ThermSystemTimeSecs = OID.new("System Time (seconds since epoch)",
143
+ "2.5.1",
144
+ false, nil, false)
145
+
146
+ ThermAuxHeatMode = OID.new("Aux Heat Mode",
147
+ "4.2.30",
148
+ false,
149
+ {
150
+ 1 => "Disabled",
151
+ 2 => "Enabled with Compressors",
152
+ 3 => "Enabled without Compressors"
153
+ })
154
+
155
+ ThermAuxHeatOffset = OID.new("Aux Heat Offset (degrees F)",
156
+ "4.1.24",
157
+ true)
129
158
 
130
159
  end
@@ -27,7 +27,10 @@ module Proliphix
27
27
  ThermHeat1Usage,
28
28
  ThermCool1Usage,
29
29
  ThermFanUsage,
30
- ThermAverageTemp
30
+ ThermAverageTemp,
31
+ ThermSystemTimeSecs,
32
+ ThermAuxHeatMode,
33
+ ThermAuxHeatOffset
31
34
  ]
32
35
  end
33
36
 
@@ -1,7 +1,18 @@
1
1
  module Proliphix
2
2
  # This is the basic encapsulation class for OIDs used by the Proliphix thermostat.
3
-
3
+
4
4
  class OID
5
+ # Create a new OID. It takes 5 parameters
6
+ # * name - some name you want to make up
7
+ # * oid - the oid that Proliphix uses in it's web service call
8
+ # * readonly - is the attribute read only (prevents us from
9
+ # ever trying to do a set call
10
+ # * valuemap - if the return is fundamentally an enumeration,
11
+ # provide a hash that we can map these to strings that make sense
12
+ # * scale - degrees are sent back as ints which are degrees * 10.
13
+ # If scale is set to true these are automatically divided by 10 before
14
+ # returned so that you get the answer in degrees
15
+
5
16
  def initialize(name, oid, readonly, valuemap = nil, scale = true)
6
17
  @name = name
7
18
  @oid = oid
@@ -4,7 +4,7 @@ $:.unshift(File.dirname(__FILE__)) unless
4
4
  # This is the main class for controlling the Proliphix Thermostat.
5
5
  # You must first initialize it with the control point credentials
6
6
  class Thermostat
7
- VERSION = '1.1.1'
7
+ VERSION = '1.2.0'
8
8
 
9
9
  require 'pdp/oid'
10
10
  require 'pdp/constants'
@@ -123,6 +123,44 @@ class Thermostat
123
123
  self[ThermFanMode] = 1
124
124
  self[ThermFanState]
125
125
  end
126
+
127
+ # Get the thermostat system time
128
+ def system_time
129
+ self[ThermSystemTimeSecs]
130
+ end
131
+
132
+ # Set the thermostat system time
133
+ def system_time=(value)
134
+ self[ThermSystemTimeSecs] = value.to_i
135
+ system_time
136
+ end
137
+
138
+ # Get the aux heat mode
139
+ def aux_heat
140
+ self[ThermAuxHeatMode]
141
+ end
142
+
143
+ # Set the aux heat mode
144
+ def aux_heat=(value)
145
+ if (value == "1") or (value == "2") or (value == "3") then
146
+ self[ThermAuxHeatMode] = value.to_i
147
+ end
148
+ aux_heat
149
+ end
150
+
151
+ # Get the aux heat offset
152
+ def aux_heat_offset
153
+ self[ThermAuxHeatOffset]
154
+ end
155
+
156
+ # Set the aux heat offset
157
+ def aux_heat_offset=(value)
158
+ if (value >= 0) and (value <= 10)
159
+ self[ThermAuxHeatOffset] = value.to_i
160
+ end
161
+ aux_heat_offset
162
+ end
163
+
126
164
  end
127
165
 
128
166
 
@@ -18,7 +18,7 @@ class TestThermostatNetwork < Test::Unit::TestCase
18
18
  end
19
19
 
20
20
  def test_get_query_generate
21
- base_query = "http://foo/get?OID4.1.1=&OID4.1.2=&OID4.1.3=&OID4.1.4=&OID4.1.5=&OID4.1.6=&OID4.5.1=&OID4.5.3=&OID4.5.5=&OID4.1.13="
21
+ base_query = "http://foo/get?OID4.1.1=&OID4.1.2=&OID4.1.3=&OID4.1.4=&OID4.1.5=&OID4.1.6=&OID4.5.1=&OID4.5.3=&OID4.5.5=&OID4.1.13=&OID2.5.1=&OID4.2.30=&OID4.1.24="
22
22
 
23
23
  @@t.heat_to
24
24
  assert_equal(base_query, query)
@@ -24,17 +24,23 @@
24
24
  }
25
25
  var versionBox = new curvyCorners(settings, document.getElementById("version"));
26
26
  versionBox.applyCornersToAll();
27
+ var mainBox = new curvyCorners(settings, document.getElementById("main"));
28
+ mainBox.applyCornersToAll();
29
+ var titleBox = new curvyCorners(settings, document.getElementById("title"));
30
+ titleBox.applyCornersToAll();
27
31
  }
28
32
  </script>
29
33
  </head>
30
34
  <body>
31
35
  <div id="main">
32
36
 
33
- <h1>thermostat</h1>
37
+ <div id="title">
38
+ <h1>thermostat</h1>
39
+ </div>
34
40
  <div class="sidebar">
35
41
  <div id="version" class="clickable" onclick='document.location = "http://rubyforge.org/projects/sdaguegems"; return false'>
36
42
  <p>Get Version</p>
37
- <a href="http://rubyforge.org/projects/sdaguegems" class="numbers">1.0.0</a>
43
+ <a href="http://rubyforge.org/projects/sdaguegems" class="numbers">1.1.1</a>
38
44
  </div>
39
45
  </div>
40
46
  <h2>What</h2>
@@ -45,15 +51,30 @@ of some simple home temperature monitoring.</p>
45
51
  <p><pre class='syntax'><span class="ident">sudo</span> <span class="ident">gem</span> <span class="ident">install</span> <span class="ident">thermostat</span></pre></p>
46
52
  <h2>The basics</h2>
47
53
  <h2>Demonstration of usage</h2>
54
+ <p><pre class='syntax'>
55
+ <span class="ident">thermostat</span> <span class="punct">=</span> <span class="constant">Thermostat</span><span class="punct">.</span><span class="ident">new</span><span class="punct">(&quot;</span><span class="string">hostname</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">admin</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">password</span><span class="punct">&quot;)</span>
56
+
57
+ <span class="comment"># get the current temperature</span>
58
+ <span class="ident">current_temp</span> <span class="punct">=</span> <span class="ident">thermostat</span><span class="punct">.</span><span class="ident">temp</span>
59
+
60
+ <span class="comment"># get the current setback heat value</span>
61
+ <span class="ident">current_target_temp</span> <span class="punct">=</span> <span class="ident">thermostat</span><span class="punct">.</span><span class="ident">heat_to</span>
62
+
63
+ <span class="comment"># set the thermostat to 69F (units are set in the thermostat)</span>
64
+ <span class="ident">thermostat</span><span class="punct">.</span><span class="ident">heat_to</span> <span class="punct">=</span> <span class="number">69</span>
65
+ </pre></p>
48
66
  <h2>Documentation</h2>
49
67
  <p>Full module level documentat can be found here:http://sdaguegems.rubyforge.org/thermostat/rdoc</p>
50
68
  <h2>How to submit patches</h2>
51
- <p>Read the <a href="http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/">8 steps for fixing other people&#8217;s code</a> and for section <a href="http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/#8b-google-groups">8b: Submit patch to Google Groups</a>, use the Google Group above.</p>
69
+ <p>Read the <a href="http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/">8 steps for fixing other people&#8217;s code</a></p>
52
70
  <p>You can fetch the source from</p>
53
71
  <ul>
54
72
  <li>github: <a href="http://github.com/sdague/thermostat.rb/tree/master">http://github.com/sdague/thermostat.rb/tree/master</a></li>
55
73
  </ul>
56
74
  <pre>git clone git://github.com/sdague/thermostat.rb.git</pre>
75
+ <p>To send me code updates, fork the tree on github, make your changes,<br />
76
+ then send me a pull request. That will make it easy for me to<br />
77
+ integrate your patches.</p>
57
78
  <h3>Build and test instructions</h3>
58
79
  <pre>cd thermostat
59
80
  rake test
@@ -63,9 +84,10 @@ rake install_gem</pre>
63
84
  <h2>Contact</h2>
64
85
  <p>Comments are welcome. Send an email to <a href="mailto:sean@dague.net">Sean Dague</a></p>
65
86
  <p class="coda">
66
- <a href="FIXME email">FIXME full name</a>, 7th March 2010<br>
87
+ <a href="http://dague.net">Sean Dague</a>, 12th March 2010<br>
67
88
  Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
68
89
  </p>
90
+
69
91
  </div>
70
92
 
71
93
  <!-- insert site tracking codes here, like Google Urchin -->
@@ -15,7 +15,7 @@ h2. The basics
15
15
  h2. Demonstration of usage
16
16
 
17
17
  <pre syntax="ruby">
18
- thermostat = Thermostate.new("hostname", "admin", "password")
18
+ thermostat = Thermostat.new("hostname", "admin", "password")
19
19
 
20
20
  # get the current temperature
21
21
  current_temp = thermostat.temp
@@ -23,7 +23,7 @@ h2. Demonstration of usage
23
23
  # get the current setback heat value
24
24
  current_target_temp = thermostat.heat_to
25
25
 
26
- # set the thermostat to 69F (units are set in the thermost)
26
+ # set the thermostat to 69F (units are set in the thermostat)
27
27
  thermostat.heat_to = 69
28
28
  </pre>
29
29
 
@@ -1,5 +1,5 @@
1
1
  body {
2
- background-color: #8DBD82;
2
+ background-color: #666666;
3
3
  font-family: "Georgia", sans-serif;
4
4
  font-size: 16px;
5
5
  line-height: 1.6em;
@@ -15,8 +15,15 @@ h1 {
15
15
  font-size: 4em;
16
16
  line-height: 0.8em;
17
17
  letter-spacing: -0.1ex;
18
- margin: 5px;
18
+ margin: 5px 0px;
19
+ color: white;
20
+ padding: 20px;
21
+
19
22
  }
23
+ #title {
24
+ background-color: #B30000;
25
+ margin-bottom: 30px;
26
+ }
20
27
  li {
21
28
  padding: 0;
22
29
  margin: 0;
@@ -24,7 +31,6 @@ li {
24
31
  }
25
32
  a {
26
33
  color: #5E5AFF;
27
- background-color: #A1DDB1;
28
34
  font-weight: normal;
29
35
  text-decoration: underline;
30
36
  }
@@ -40,8 +46,10 @@ blockquote {
40
46
 
41
47
  #main {
42
48
  width: 55em;
43
- padding: 0;
49
+ background-color: white;
50
+ padding: 20px;
44
51
  margin: 0 auto;
52
+ margin-bottom: 30px;
45
53
  }
46
54
  .coda {
47
55
  text-align: right;
@@ -24,13 +24,19 @@
24
24
  }
25
25
  var versionBox = new curvyCorners(settings, document.getElementById("version"));
26
26
  versionBox.applyCornersToAll();
27
+ var mainBox = new curvyCorners(settings, document.getElementById("main"));
28
+ mainBox.applyCornersToAll();
29
+ var titleBox = new curvyCorners(settings, document.getElementById("title"));
30
+ titleBox.applyCornersToAll();
27
31
  }
28
32
  </script>
29
33
  </head>
30
34
  <body>
31
35
  <div id="main">
32
36
 
33
- <h1><%= title %></h1>
37
+ <div id="title">
38
+ <h1><%= title %></h1>
39
+ </div>
34
40
  <div class="sidebar">
35
41
  <div id="version" class="clickable" onclick='document.location = "<%= download %>"; return false'>
36
42
  <p>Get Version</p>
@@ -39,9 +45,10 @@
39
45
  </div>
40
46
  <%= body %>
41
47
  <p class="coda">
42
- <a href="FIXME email">FIXME full name</a>, <%= modified.pretty %><br>
48
+ <a href="http://dague.net">Sean Dague</a>, <%= modified.pretty %><br>
43
49
  Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
44
50
  </p>
51
+
45
52
  </div>
46
53
 
47
54
  <!-- insert site tracking codes here, like Google Urchin -->
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: thermostat
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ hash: 31
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 2
9
+ - 0
10
+ version: 1.2.0
5
11
  platform: ruby
6
12
  authors:
7
13
  - Sean Dague
@@ -9,56 +15,81 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2010-03-11 00:00:00 -05:00
18
+ date: 2011-01-16 00:00:00 -05:00
13
19
  default_executable:
14
20
  dependencies:
15
21
  - !ruby/object:Gem::Dependency
16
22
  name: temperature
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
20
26
  requirements:
21
27
  - - ">="
22
28
  - !ruby/object:Gem::Version
29
+ hash: 23
30
+ segments:
31
+ - 1
32
+ - 0
33
+ - 0
23
34
  version: 1.0.0
24
- version:
35
+ type: :runtime
36
+ version_requirements: *id001
25
37
  - !ruby/object:Gem::Dependency
26
38
  name: rubyforge
27
- type: :development
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
30
42
  requirements:
31
43
  - - ">="
32
44
  - !ruby/object:Gem::Version
45
+ hash: 9
46
+ segments:
47
+ - 2
48
+ - 0
49
+ - 3
33
50
  version: 2.0.3
34
- version:
51
+ type: :development
52
+ version_requirements: *id002
35
53
  - !ruby/object:Gem::Dependency
36
54
  name: gemcutter
37
- type: :development
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
40
58
  requirements:
41
59
  - - ">="
42
60
  - !ruby/object:Gem::Version
61
+ hash: 19
62
+ segments:
63
+ - 0
64
+ - 3
65
+ - 0
43
66
  version: 0.3.0
44
- version:
67
+ type: :development
68
+ version_requirements: *id003
45
69
  - !ruby/object:Gem::Dependency
46
70
  name: hoe
47
- type: :development
48
- version_requirement:
49
- version_requirements: !ruby/object:Gem::Requirement
71
+ prerelease: false
72
+ requirement: &id004 !ruby/object:Gem::Requirement
73
+ none: false
50
74
  requirements:
51
75
  - - ">="
52
76
  - !ruby/object:Gem::Version
77
+ hash: 27
78
+ segments:
79
+ - 2
80
+ - 5
81
+ - 0
53
82
  version: 2.5.0
54
- version:
83
+ type: :development
84
+ version_requirements: *id004
55
85
  description: |-
56
86
  Thermostat.rb is an attempt to build an easy to use ruby api around
57
87
  the web services provided by the Proliphix line of network
58
88
  thermostats. Their API is documented at
59
89
  http://www.proliphix.com/Documentation.aspx.
60
90
 
61
- The code is tested on the NT20e unit, which is what I own. It should
91
+ The code is tested on the NT20e unit, which is what I own (the NT10e
92
+ is the same hardware, just can't handle remote sensors). It should
62
93
  react that same across all their network accessible units.
63
94
  email:
64
95
  - sean@dague.net
@@ -71,6 +102,7 @@ extra_rdoc_files:
71
102
  - Manifest.txt
72
103
  - PostInstall.txt
73
104
  - website/index.txt
105
+ - README.rdoc
74
106
  files:
75
107
  - History.txt
76
108
  - Manifest.txt
@@ -105,28 +137,34 @@ has_rdoc: true
105
137
  homepage: http://github.com/sdague/thermostat.rb
106
138
  licenses: []
107
139
 
108
- post_install_message: PostInstall.txt
140
+ post_install_message:
109
141
  rdoc_options:
110
142
  - --main
111
143
  - README.rdoc
112
144
  require_paths:
113
145
  - lib
114
146
  required_ruby_version: !ruby/object:Gem::Requirement
147
+ none: false
115
148
  requirements:
116
149
  - - ">="
117
150
  - !ruby/object:Gem::Version
151
+ hash: 3
152
+ segments:
153
+ - 0
118
154
  version: "0"
119
- version:
120
155
  required_rubygems_version: !ruby/object:Gem::Requirement
156
+ none: false
121
157
  requirements:
122
158
  - - ">="
123
159
  - !ruby/object:Gem::Version
160
+ hash: 3
161
+ segments:
162
+ - 0
124
163
  version: "0"
125
- version:
126
164
  requirements: []
127
165
 
128
166
  rubyforge_project: sdaguegems
129
- rubygems_version: 1.3.5
167
+ rubygems_version: 1.3.7
130
168
  signing_key:
131
169
  specification_version: 3
132
170
  summary: Thermostat.rb is an attempt to build an easy to use ruby api around the web services provided by the Proliphix line of network thermostats