thermostat 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (5) hide show
  1. data/README +36 -0
  2. data/lib/pdp/constants.rb +130 -0
  3. data/lib/pdp/oid.rb +37 -0
  4. data/lib/thermostat.rb +95 -0
  5. metadata +50 -0
data/README ADDED
@@ -0,0 +1,36 @@
1
+ Copyright (c) 2008 - Sean Dague <sean at dague dot net>
2
+
3
+ THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS
4
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
6
+ DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
7
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
8
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
9
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
10
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
11
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
12
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
13
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
+
15
+
16
+ This code is based on the Proliphix Software API which can be found
17
+ here ( http://www.proliphix.com/Documentation.aspx ). I am writing
18
+ this software to interface with my NT20e unit. The API looks to be
19
+ the same across all their IP units, but I will only be testing on my
20
+ unit in my house.
21
+
22
+ Important notices from the manual:
23
+
24
+ **Limitations on the Frequency of Operations**
25
+
26
+ While the device can handle numerous back to back requests, it is
27
+ advisable to not sustain an operation frequency higher than 1 request
28
+ per 60 second period for a substantial amount of time. In other words,
29
+ sustained polling of the device should not exceed a few requests per
30
+ minute. A prolonged burst of requests higher than 1 request per 60
31
+ second period may degrade the main function of the thermostat. Also,
32
+ if one is making a PIB set and wishes to observe a reaction from the
33
+ device, it is advisable to wait for at least 1 second between the set
34
+ request and subsequent get request.
35
+
36
+
@@ -0,0 +1,130 @@
1
+
2
+ module Proliphix
3
+ # a whole crap load of constants for the proliphix API
4
+
5
+ # read/write
6
+ ThermHvacMode = OID.new("HVAC Mode",
7
+ "4.1.1",
8
+ false,
9
+ {
10
+ 1 => "Off",
11
+ 2 => "Heat",
12
+ 3 => "Cool",
13
+ 4 => "Auto",
14
+ })
15
+
16
+ ThermHvacState = OID.new("HVAC State",
17
+ "4.1.2",
18
+ true,
19
+ {
20
+ 1 => "Initializing",
21
+ 2 => "Off",
22
+ 3 => "Heat",
23
+ 4 => "Heat2",
24
+ 5 => "Heat3",
25
+ 6 => "Cool",
26
+ 7 => "Cool2",
27
+ 8 => "Delay",
28
+ 9 => "ResetRelays"
29
+ })
30
+
31
+ ThermFanMode = OID.new("Fan Mode",
32
+ "4.1.3",
33
+ false,
34
+ {
35
+ 1 => "Auto",
36
+ 2 => "On",
37
+ 3 => "Schedule",
38
+ })
39
+
40
+ ThermFanState = OID.new("Fan State",
41
+ "4.1.4",
42
+ true,
43
+ {
44
+ 0 => "Init",
45
+ 1 => "Off",
46
+ 2 => "On",
47
+ })
48
+
49
+ ThermSetbackHeat = OID.new("Setback Heat",
50
+ "4.1.5",
51
+ false)
52
+
53
+ ThermSetbackCool = OID.new("Setback Cool",
54
+ "4.1.6",
55
+ false)
56
+
57
+ # only on the NT150, and the math won't really work on this now anyway
58
+ ThermConfigHumidyCool = OID.new("thermConfigHumidityCool",
59
+ "4.2.22",
60
+ false)
61
+
62
+ ThermSetbackStatus = OID.new("Setback Status",
63
+ "4.1.9",
64
+ false,
65
+ {
66
+ 1 => "Normal",
67
+ 2 => "Hold",
68
+ 3 => "Override"
69
+ })
70
+
71
+ ThermCurrentPeriod = OID.new("Current Period",
72
+ "4.1.10",
73
+ true, # false, but the spec says writes are ignored
74
+ {
75
+ 1 => "Morn",
76
+ 2 => "Day",
77
+ 3 => "Eve",
78
+ 4 => "Night",
79
+ })
80
+
81
+ ThermActivePeriod = OID.new("Activity Period",
82
+ "4.1.12",
83
+ true,
84
+ {
85
+ 1 => "Morn",
86
+ 2 => "Day",
87
+ 3 => "Eve",
88
+ 4 => "Night",
89
+ 5 => "Hold",
90
+ 6 => "Override"
91
+ })
92
+
93
+ ThermCurrentClass = OID.new("Current Day Class",
94
+ "4.1.11",
95
+ true,
96
+ {
97
+ 1 => "In",
98
+ 2 => "Out",
99
+ 3 => "Away"
100
+ })
101
+
102
+ ThermAverageTemp = OID.new("Temperature (degrees F)",
103
+ "4.1.13",
104
+ true)
105
+
106
+ ThermHeat1Usage = OID.new("Heat Usage (minutes)",
107
+ "4.5.1",
108
+ true, nil, false) # it says false, but that's just too hard for me to wrap my brain around
109
+
110
+ ThermHeat2Usage = OID.new("Heat 2 Usage (minutes)",
111
+ "4.5.2",
112
+ true, nil, false) # it says false, but that's just too hard for me to wrap my brain around
113
+
114
+ ThermCool1Usage = OID.new("Cooling Usage (minutes)",
115
+ "4.5.3",
116
+ true, nil, false) # it says false, but that's just too hard for me to wrap my brain around
117
+
118
+ ThermCool2Usage = OID.new("Cooling 2 Usage (minutes)",
119
+ "4.5.4",
120
+ true, nil, false) # it says false, but that's just too hard for me to wrap my brain around
121
+
122
+ ThermFanUsage = OID.new("Fan Usage (minutes)",
123
+ "4.5.5",
124
+ true, nil, false)
125
+
126
+ ThermLastUsageReset = OID.new("Last Usage Reset",
127
+ "4.5.6",
128
+ false, nil, false) # we're going to have to be tricky about this one
129
+
130
+ end
@@ -0,0 +1,37 @@
1
+ module Proliphix
2
+ class OID
3
+ def initialize(name, oid, readonly, valuemap = nil, scale = true)
4
+ @name = name
5
+ @oid = oid
6
+ @valuemap = valuemap
7
+ @readonly = readonly
8
+ @scale = scale
9
+ end
10
+
11
+ def oid
12
+ return @oid
13
+ end
14
+
15
+ def name
16
+ return @name
17
+ end
18
+
19
+ def ro?
20
+ return @readonly
21
+ end
22
+
23
+ # a little tricky, but not too bad. Basically the access
24
+ # gives us either the value off the value map, or the degrees
25
+ # reading (as we always get degrees as 10x ints)
26
+
27
+ def [](value)
28
+ if @valuemap
29
+ return @valuemap[value.to_i]
30
+ elsif @scale
31
+ return value.to_i / 10.0
32
+ else
33
+ return value.to_i
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,95 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+ require 'open-uri'
4
+
5
+ # order here is important
6
+ require 'pdp/oid'
7
+ require 'pdp/constants'
8
+
9
+ # Some docs
10
+ class Thermostat
11
+
12
+ def initialize(ip, user, passwd)
13
+ @ip = ip
14
+ @user = user
15
+ @passwd = passwd
16
+ @fetched = {}
17
+ @sensors = []
18
+ end
19
+
20
+ def [](reading)
21
+ return @fetched[reading]
22
+ end
23
+
24
+ def url
25
+ return "http://#{@ip}"
26
+ end
27
+
28
+ def set_senors(*array)
29
+ @sensors = array
30
+ return self
31
+ end
32
+
33
+ def get_query_url
34
+ query = ""
35
+ for item in @sensors
36
+ if query != ""
37
+ query += "&"
38
+ end
39
+ query += "OID#{item.oid}="
40
+ end
41
+ query = url + "/get?" + query
42
+ end
43
+
44
+ def set_query_url(mod, value)
45
+ query = "OID#{mod.oid}=#{value}"
46
+ query = url + "/pdp?" + query + "&sumbit=Submit"
47
+ end
48
+
49
+ # Because of the timing issues with the thermostat we want to get all the data we can in one packet.
50
+ def fetch_data()
51
+ open(get_query_url, :http_basic_authentication => [@user, @passwd]) do |line|
52
+ parse_data(line.read)
53
+ end
54
+ return self
55
+ end
56
+
57
+ def set_data(mod, value)
58
+ unless mod.ro?
59
+ open(set_query_url(mod, value), :http_basic_authentication => [@user, @passwd]) do |line|
60
+ parse_data(line.read)
61
+ end
62
+ end
63
+ return self
64
+ end
65
+
66
+
67
+ def parse_data(raw_data)
68
+ results = raw_data.split('&')
69
+ results.each do |r|
70
+ (oid, value) = r.split('=')
71
+ mod = lookup_oid(oid)
72
+ if mod
73
+ @fetched[mod] = mod[value]
74
+ end
75
+ end
76
+ end
77
+
78
+ def lookup_oid(oid)
79
+ newid = oid.sub(/^OID/, '')
80
+ @sensors.each do |s|
81
+ if s.oid == newid
82
+ return s
83
+ end
84
+ end
85
+ return nil
86
+ end
87
+
88
+ def to_s
89
+ s = ""
90
+ @fetched.each do |k, v|
91
+ s += "#{k.name}: #{v}\n"
92
+ end
93
+ return s
94
+ end
95
+ end
metadata ADDED
@@ -0,0 +1,50 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.4
3
+ specification_version: 1
4
+ name: thermostat
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.0.2
7
+ date: 2008-03-10 00:00:00 -04:00
8
+ summary: Ruby modules to control Prolipix IP Thermostats
9
+ require_paths:
10
+ - lib
11
+ email: sean at dague dot net
12
+ homepage: http://rubyforge.net/projects/rtc
13
+ rubyforge_project:
14
+ description:
15
+ autorequire: thermostat
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Sean Dague
31
+ files:
32
+ - lib/thermostat.rb
33
+ - lib/pdp
34
+ - lib/pdp/constants.rb
35
+ - lib/pdp/oid.rb
36
+ - README
37
+ test_files: []
38
+
39
+ rdoc_options: []
40
+
41
+ extra_rdoc_files:
42
+ - README
43
+ executables: []
44
+
45
+ extensions: []
46
+
47
+ requirements: []
48
+
49
+ dependencies: []
50
+