ten_hs_server 0.1.0

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.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.2"
4
+ - "1.9.3"
5
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in ten_hs_server.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2010 Johannes Gorset
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.rst ADDED
@@ -0,0 +1,6 @@
1
+ tenHsServer-ruby
2
+ ================
3
+
4
+ .. image:: https://secure.travis-ci.org/espenhogbakk/tenHsServer-ruby.png?branch=master
5
+
6
+ API wrapper around the (crappy) tenHsServer Homeseer HS2 plugin.
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << 'test'
6
+ #t.test_files = FileList['test/*_test.rb']
7
+ t.test_files = FileList['test/*_test.rb', 'test/ten_hs_server/*_test.rb']
8
+ end
9
+
10
+ desc "Run tests"
11
+ task :default => :test
@@ -0,0 +1,8 @@
1
+ require "ten_hs_server/version"
2
+
3
+ module TenHsServer
4
+ autoload :Adapter, "ten_hs_server/adapter"
5
+ autoload :Device, "ten_hs_server/device"
6
+ autoload :Event, "ten_hs_server/event"
7
+ autoload :Room, "ten_hs_server/room"
8
+ end
@@ -0,0 +1,29 @@
1
+ require 'httparty'
2
+ require 'nokogiri'
3
+
4
+ module TenHsServer
5
+
6
+ # Base class for TenHsServer adapters.
7
+ class Adapter
8
+ include HTTParty
9
+
10
+ base_uri "10.0.0.71/tenHsServer/tenHsServer.aspx"
11
+
12
+ private
13
+
14
+ # Parse the tenHsServer response.
15
+ #
16
+ # tenHsServer returns the results in a <span> element with
17
+ # the id "Result". So we parses the html and returns the
18
+ # string inside the span
19
+ #
20
+ # response - A string describing the response.
21
+ def self.parse response
22
+ doc = Nokogiri::HTML(response)
23
+ doc.xpath('//span[@id="Result"]')[0].content
24
+ end
25
+
26
+ end
27
+
28
+ class Error < StandardError; end
29
+ end
@@ -0,0 +1,270 @@
1
+ module TenHsServer
2
+
3
+ # Adapter for TenHsServer devices endpoint, which returns information
4
+ # for each of the devices in Homeseer
5
+ class Device < Adapter
6
+ attr_reader :id, :_name, :_type, :_room, :_floor
7
+
8
+ def initialize id, name=nil, type=nil, room=nil, floor=nil
9
+ @id = id
10
+ @_name = name
11
+ @_type = type
12
+ @_room = room
13
+ @_floor = floor
14
+ end
15
+
16
+ def query
17
+ @query || @query = self.class.find(id)
18
+ end
19
+
20
+ # Methods
21
+ def toggle
22
+ self.class.toggle(id)
23
+ end
24
+
25
+ def on
26
+ self.class.on(id)
27
+ end
28
+
29
+ def off
30
+ self.class.off(id)
31
+ end
32
+
33
+ def dim value
34
+ if value == 0
35
+ off
36
+ else
37
+ on
38
+ self.class.value(id, value)
39
+ end
40
+ end
41
+
42
+ # Properties
43
+ def on?
44
+ true ? query[:status] == 2 : false
45
+ end
46
+
47
+ def off?
48
+ true ? query[:status] == 3 : false
49
+ end
50
+
51
+ def type
52
+ _type ? _type : query[:type]
53
+ end
54
+
55
+ def room
56
+ _room ? _room : query[:location]
57
+ end
58
+
59
+ def name
60
+ _name ? _name : query[:name]
61
+ end
62
+
63
+ def floor
64
+ _floor ? _floor : query[:floor]
65
+ end
66
+
67
+ def dimmable
68
+ # Boolean that
69
+ query[:dim]
70
+ end
71
+
72
+ def status
73
+ # Status of device
74
+ # 2 On
75
+ # 3 Off
76
+ # 4 Dimmed
77
+ query[:status]
78
+ end
79
+
80
+ def value
81
+ # For dimmable devices this is a value between 0 and 100
82
+ query[:value]
83
+ end
84
+
85
+ # All inside are class methods
86
+ class << self
87
+ # Load all devices.
88
+ #
89
+ # Returns an array of Device instances.
90
+ def all
91
+ response = get "?t=99&f=GetDevices"
92
+ devices = parse_devices response.body
93
+
94
+ devices.map! do |device|
95
+ new(device[:id], device[:name], device[:type], device[:location], device[:floor])
96
+ end
97
+
98
+ devices
99
+ end
100
+
101
+ # Load a single device.
102
+ #
103
+ # id - An string describing the device
104
+ #
105
+ # Returns a hash describing the device.
106
+ def find id
107
+ response = get "?t=99&f=GetDevice&d=#{id}"
108
+
109
+ parse_device response.body
110
+ end
111
+
112
+ # Toggle a device.
113
+ #
114
+ # id - An string describing the device
115
+ #
116
+ # Returns a true or false describing the status of the device
117
+ # false = off
118
+ # true = on
119
+ def toggle id
120
+ response = get "?t=99&f=ToggleDevice&d=#{id}"
121
+
122
+ parse_toggle_device response.body
123
+ end
124
+
125
+ # Turn on a device.
126
+ #
127
+ # id - An string describing the device
128
+ #
129
+ # Returns a true or false describing the status of the device
130
+ # false = off
131
+ # true = on
132
+ def on id
133
+ response = get "?t=99&f=DeviceOn&d=#{id}"
134
+
135
+ parse_toggle_device response.body
136
+ end
137
+
138
+ # Turn off a device.
139
+ #
140
+ # id - An string describing the device
141
+ #
142
+ # Returns a true or false describing the status of the device
143
+ # false = off
144
+ # true = on
145
+ def off id
146
+ response = get "?t=99&f=DeviceOff&d=#{id}"
147
+
148
+ parse_toggle_device response.body
149
+ end
150
+
151
+ # Set device value.
152
+ #
153
+ # id - An string describing the device
154
+ # value - The value to give the device
155
+ #
156
+ def value(id, value)
157
+ response = get "?t=99&f=SetDeviceValue&d=#{id}&a=#{value}"
158
+
159
+ parse_set_device_value response.body
160
+ end
161
+
162
+ end
163
+
164
+ private
165
+
166
+ # Parse the GetDevices response.
167
+ #
168
+ # Response contains multiple device strings, one for each device, separated by ";"
169
+ # Each device string is formatted as:
170
+ #
171
+ # DeviceCode:DeviceType:Location:Name:Location2
172
+ #
173
+ # An example if only two devices were defined in Homeseer:
174
+ # a1:Lamp Module:Kitchen:Counter Pucks:loc2;a2:Applicance Module:Den:Ceiling Light:Loc2;
175
+ #
176
+ # response - A string describing the response.
177
+ def self.parse_devices response
178
+ result = parse response
179
+ results = result.split(";")
180
+
181
+ results.map do |item|
182
+ # DeviceCode:DeviceType:Location:Name:Location2
183
+ values = item.split(":")
184
+ {
185
+ id: values[0],
186
+ type: values[1],
187
+ location: values[2],
188
+ name: values[3],
189
+ floor: values[4],
190
+ }
191
+ end
192
+ end
193
+
194
+ # Parse the GetDevice response.
195
+ #
196
+ # Response contains the device fields in the form:
197
+ # d:loc:name:type:misc:loc2:dim:status:value:string:time:LastChange
198
+ #
199
+ # 0: d=device code
200
+ # 1: loc=location
201
+ # 2: name=device name
202
+ # 3: type=device type
203
+ # 4: misc=misc binary field
204
+ # 5: loc2=location 2
205
+ # 6: dim=can dim
206
+ # 7: status=device status
207
+ # 8: value=device value
208
+ # 9: string= encoded DeviceString (see DeviceString)
209
+ # 10: time=device time (in minutes)
210
+ # 11: LastChange=device LastChange date/time
211
+ #
212
+ # response - A string describing the response.
213
+ def self.parse_device response
214
+ result = parse response
215
+ results = result.split(";")
216
+
217
+ results.map! do |item|
218
+ values = item.split(":")
219
+ {
220
+ id: values[0],
221
+ type: values[3],
222
+ location: values[1],
223
+ name: values[2],
224
+ floor: values[5],
225
+ dim: values[6],
226
+ status: values[7].to_i,
227
+ value: values[8],
228
+ string: values[9],
229
+ time: values[10],
230
+ last_change: values[11],
231
+ misc: values[4]
232
+ }
233
+ end
234
+ results[0]
235
+ end
236
+
237
+ # Parse the ToggleDevice response.
238
+ #
239
+ # Response contains a list of the devices and their new status
240
+ # Q12:2;Q10:3
241
+ #
242
+ # Where device Q12 is on, and Q10 is off
243
+ #
244
+ # response - A string describing the response.
245
+ def self.parse_toggle_device response
246
+ result = parse response
247
+ results = result.split(";")
248
+
249
+ results.map! do |item|
250
+ values = item.split(":")
251
+ {
252
+ id: values[0],
253
+ status: values[1].to_i,
254
+ }
255
+ end
256
+ results[0]
257
+ end
258
+
259
+ # Parse the SetDeviceValue response.
260
+ #
261
+ # Response contains the new value of the device
262
+ #
263
+ # response - A string describing the response.
264
+ def self.parse_set_device_value response
265
+ result = parse response
266
+ result.to_i
267
+ end
268
+
269
+ end
270
+ end
@@ -0,0 +1,74 @@
1
+ require 'nokogiri'
2
+
3
+ module TenHsServer
4
+
5
+ # Adapter for TenHsServer events endpoint, which returns information
6
+ # for each of the events in Homeseer
7
+ class Event < Adapter
8
+
9
+ # Load all events.
10
+ #
11
+ # Returns an array of hashes describing each event.
12
+ def self.all deep=false
13
+ response = get "?t=99&f=GetEvents"
14
+
15
+ parse_events response.body
16
+ end
17
+
18
+ # Load a single event.
19
+ #
20
+ # name - An string describing the event
21
+ #
22
+ # Returns the name of the event
23
+ def self.find name
24
+ all.find { |event| event == name }
25
+ end
26
+
27
+ # Run an event.
28
+ #
29
+ # name - An string describing the event
30
+ #
31
+ # Returns a bool describing if the event was run or not
32
+ def self.run name
33
+ response = get "?t=99&f=RunEvent&d=All%20on"
34
+
35
+ parse_runevent response.body
36
+ end
37
+
38
+ private
39
+
40
+ # Parse the GetEvents response.
41
+ #
42
+ # Response contains multiple events, separated by ";"
43
+ # Event1;Event2;Eventn;
44
+ #
45
+ # response - A string describing the response.
46
+ def self.parse_events response
47
+ result = parse response
48
+ results = result.split(";")
49
+
50
+ results.map do |item|
51
+ item
52
+ end
53
+ end
54
+
55
+ # Parse the RunEvent response.
56
+ #
57
+ # Response contains either 1 or 0
58
+ # 1 = event was run
59
+ # 0 = event failed to run
60
+ #
61
+ # response - A string describing the response.
62
+ def self.parse_runevent response
63
+ result = parse response
64
+
65
+ if result == "1"
66
+ true
67
+ else
68
+ false
69
+ end
70
+
71
+ end
72
+
73
+ end
74
+ end
File without changes
@@ -0,0 +1,130 @@
1
+ module TenHsServer
2
+
3
+ # Adapter for working with Homeseer rooms, tenHsServer has no endpoint for fetching
4
+ # rooms, so we need to get that from device metadata.
5
+ class Room < Adapter
6
+ attr_accessor :name
7
+
8
+ def initialize name
9
+ @name = name
10
+ end
11
+
12
+ def query
13
+ @query || @query = self.class.find(name)
14
+ end
15
+
16
+ def devices
17
+ query[:devices]
18
+ end
19
+
20
+ def floor
21
+ query[:floor]
22
+ end
23
+
24
+ def on
25
+ status = self.class.on(devices)
26
+ true
27
+ end
28
+
29
+ def off
30
+ status = self.class.off(devices)
31
+ true
32
+ end
33
+
34
+ # All inside are class methods
35
+ class << self
36
+ # Load all rooms.
37
+ #
38
+ # Returns an array of Room's.
39
+ def all
40
+ devices = Device.all
41
+ rooms = []
42
+
43
+ # Go through each device, check which room it belongs
44
+ # do, if the room doesn't exist, add it to rooms
45
+ devices.each do |device|
46
+ unless rooms.find {|room| room.name == device.room}
47
+ rooms << new(device.room)
48
+ end
49
+ end
50
+
51
+ rooms
52
+ end
53
+
54
+ # Load a single room.
55
+ #
56
+ # Returns a hash describing the room.
57
+ def find name
58
+ devices = Device.all
59
+ devices_in_room = []
60
+
61
+ # Go through each device, check which room it belongs too.
62
+ # If the device belongs to this room, add it to devices_in_room
63
+ devices.each do |device|
64
+ if device.room == name
65
+ devices_in_room << device
66
+ end
67
+ end
68
+
69
+ {
70
+ name: name,
71
+ floor: devices_in_room[0].floor,
72
+ devices: devices_in_room
73
+ }
74
+
75
+ end
76
+
77
+ # Turn on all devices in this room.
78
+ #
79
+ # devices - An array with devices
80
+ def on devices
81
+ ids = devices.map { |device| device.id }
82
+ ids = ids.join(".")
83
+ response = get "?t=99&f=DeviceOn&d=#{ids}"
84
+
85
+ parse_toggle_devices response.body
86
+ end
87
+
88
+ # Turn off a device.
89
+ #
90
+ # id - An string describing the device
91
+ #
92
+ # Returns a true or false describing the status of the device
93
+ # false = off
94
+ # true = on
95
+ def off devices
96
+ ids = devices.map { |device| device.id }
97
+ ids = ids.join(".")
98
+ response = get "?t=99&f=DeviceOff&d=#{ids}"
99
+
100
+ parse_toggle_devices response.body
101
+ end
102
+
103
+ end
104
+
105
+ private
106
+
107
+ # Parse the ToggleDevice response.
108
+ #
109
+ # Response contains a list of the devices and their new status
110
+ # Q12:2;Q10:3
111
+ #
112
+ # Where device Q12 is on, and Q10 is off
113
+ #
114
+ # response - A string describing the response.
115
+ def self.parse_toggle_devices response
116
+ result = parse response
117
+ results = result.split(";")
118
+
119
+ results.map! do |item|
120
+ values = item.split(":")
121
+ {
122
+ id: values[0],
123
+ status: values[1].to_i,
124
+ }
125
+ end
126
+ results
127
+ end
128
+
129
+ end
130
+ end
@@ -0,0 +1,3 @@
1
+ module TenHsServer
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "ten_hs_server/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "ten_hs_server"
7
+ s.version = TenHsServer::VERSION
8
+ s.authors = ["Espen Hogbakk"]
9
+ s.email = ["espen@hogbakk.no"]
10
+ s.homepage = ""
11
+ s.summary = "tenHsServer Homeseer API wrapper."
12
+ s.description = "API wrapper around the (crappy) tenHsServer Homeseer HS2 plugin."
13
+
14
+ s.rubyforge_project = "ten_hs_server"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ s.add_development_dependency "rake"
23
+ s.add_development_dependency "activesupport"
24
+ s.add_development_dependency "factory_girl"
25
+ s.add_development_dependency "mocha"
26
+ s.add_development_dependency "webmock"
27
+
28
+ s.add_runtime_dependency "httparty"
29
+ s.add_runtime_dependency "nokogiri"
30
+ end
@@ -0,0 +1,14 @@
1
+
2
+
3
+
4
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml"><head><title>
7
+
8
+ </title></head><body><form name="form1" method="post" action="tenHsServer.aspx?t=99&amp;f=DeviceOff&amp;d=Q12" id="form1">
9
+ <div>
10
+ <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTkzNDcxNzcwM2RkkSlaVMiVj2zRiqjrfGv75W35YBM=" />
11
+ </div>
12
+
13
+ <span id="Result">Q12:3;</span>
14
+ </form></body></html>
@@ -0,0 +1,14 @@
1
+
2
+
3
+
4
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml"><head><title>
7
+
8
+ </title></head><body><form name="form1" method="post" action="tenHsServer.aspx?t=99&amp;f=DeviceOn&amp;d=Q12" id="form1">
9
+ <div>
10
+ <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTkzNDcxNzcwM2RkkSlaVMiVj2zRiqjrfGv75W35YBM=" />
11
+ </div>
12
+
13
+ <span id="Result">Q12:2;</span>
14
+ </form></body></html>
@@ -0,0 +1,14 @@
1
+
2
+
3
+
4
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml"><head><title>
7
+
8
+ </title></head><body><form name="form1" method="post" action="tenHsServer.aspx?t=99&amp;f=GetDevice&amp;d=Q12" id="form1">
9
+ <div>
10
+ <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTkzNDcxNzcwM2RkkSlaVMiVj2zRiqjrfGv75W35YBM=" />
11
+ </div>
12
+
13
+ <span id="Result">Q12:Dining room:Chandelier:Z-Wave Switch Multilevel:4096:1. Floor:True:3:0::9737::29.11.2012 23.23.19;</span>
14
+ </form></body></html>
@@ -0,0 +1,14 @@
1
+
2
+
3
+
4
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml"><head><title>
7
+
8
+ </title></head><body><form name="form1" method="post" action="tenHsServer.aspx?t=99&amp;f=GetDevices" id="form1">
9
+ <div>
10
+ <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTkzNDcxNzcwM2RkkSlaVMiVj2zRiqjrfGv75W35YBM=" />
11
+ </div>
12
+
13
+ <span id="Result">A1:Virtual::Away:;Q12:Z-Wave Switch Multilevel:Dining room:Chandelier:1. Floor;Q5:Z-Wave Switch Multilevel:Dining room:Cabinet:1. Floor;Q9:Z-Wave Remote Switch:Kitchen:Ceiling / Cabinets:1. Floor;Q11:Z-Wave Switch Multilevel:Kitchen:Breakfast table:1. Floor;Q7:Z-Wave Switch Multilevel:Kitchen:Ceiling:1. Floor;Q8:Z-Wave Switch Multilevel:Kitchen:Cabinets:1. Floor;Q1:Z-Wave Switch Multilevel:Living room:Lounge:1. Floor;Q2:Z-Wave Switch Multilevel:Living room:TV:1. Floor;Q4:Z-Wave Switch Multilevel:Living room:Hall:1. Floor;Q6:Z-Wave Remote Switch:Living room:Hall / Cabinet:1. Floor;Q3:Z-Wave Remote Switch:Living room:Lounge / TV:1. Floor;Q10:Z-Wave Switch Multilevel:Office:Ceiling:1. Floor;</span>
14
+ </form></body></html>
@@ -0,0 +1,14 @@
1
+
2
+
3
+
4
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml"><head><title>
7
+
8
+ </title></head><body><form name="form1" method="post" action="tenHsServer.aspx?t=a2b&amp;f=DeviceOff&amp;d=Q12.Q5" id="form1">
9
+ <div>
10
+ <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTkzNDcxNzcwM2RkkSlaVMiVj2zRiqjrfGv75W35YBM=" />
11
+ </div>
12
+
13
+ <span id="Result">Q12:3;Q5:3;</span>
14
+ </form></body></html>
@@ -0,0 +1,14 @@
1
+
2
+
3
+
4
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml"><head><title>
7
+
8
+ </title></head><body><form name="form1" method="post" action="tenHsServer.aspx?t=a2b&amp;f=DeviceOn&amp;d=Q12.Q5" id="form1">
9
+ <div>
10
+ <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTkzNDcxNzcwM2RkkSlaVMiVj2zRiqjrfGv75W35YBM=" />
11
+ </div>
12
+
13
+ <span id="Result">Q12:2;Q5:2;</span>
14
+ </form></body></html>
@@ -0,0 +1,14 @@
1
+
2
+
3
+
4
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml"><head><title>
7
+
8
+ </title></head><body><form name="form1" method="post" action="tenHsServer.aspx?t=99&amp;f=GetEvents" id="form1">
9
+ <div>
10
+ <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTkzNDcxNzcwM2RkkSlaVMiVj2zRiqjrfGv75W35YBM=" />
11
+ </div>
12
+
13
+ <span id="Result">All on;Kitchen off;All off;Office on;Living room off;Living room on;Kitchen on;Office off;</span>
14
+ </form></body></html>
@@ -0,0 +1,14 @@
1
+
2
+
3
+
4
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml"><head><title>
7
+
8
+ </title></head><body><form name="form1" method="post" action="tenHsServer.aspx?t=12&amp;f=RunEvent&amp;d=All+on" id="form1">
9
+ <div>
10
+ <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTkzNDcxNzcwM2RkkSlaVMiVj2zRiqjrfGv75W35YBM=" />
11
+ </div>
12
+
13
+ <span id="Result">1</span>
14
+ </form></body></html>
@@ -0,0 +1,14 @@
1
+
2
+
3
+
4
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml"><head><title>
7
+
8
+ </title></head><body><form name="form1" method="post" action="tenHsServer.aspx?t=70&amp;f=SetDeviceValue&amp;d=Q12&amp;a=70" id="form1">
9
+ <div>
10
+ <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTkzNDcxNzcwM2RkkSlaVMiVj2zRiqjrfGv75W35YBM=" />
11
+ </div>
12
+
13
+ <span id="Result">70</span>
14
+ </form></body></html>
@@ -0,0 +1,14 @@
1
+
2
+
3
+
4
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml"><head><title>
7
+
8
+ </title></head><body><form name="form1" method="post" action="tenHsServer.aspx?t=99&amp;f=ToggleDevice&amp;d=Q12" id="form1">
9
+ <div>
10
+ <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTkzNDcxNzcwM2RkkSlaVMiVj2zRiqjrfGv75W35YBM=" />
11
+ </div>
12
+
13
+ <span id="Result">Q12:2;</span>
14
+ </form></body></html>
@@ -0,0 +1,8 @@
1
+ require 'test_helper'
2
+ require "active_support/all"
3
+
4
+ class AdapterTest < ActiveSupport::TestCase
5
+ # test "the truth" do
6
+ # assert true
7
+ # end
8
+ end
@@ -0,0 +1,101 @@
1
+ require 'test_helper'
2
+ require "active_support/all"
3
+ require 'ten_hs_server'
4
+
5
+ class DeviceTest < ActiveSupport::TestCase
6
+ test "should load all devices" do
7
+ TenHsServer::Device.expects(:get).with(
8
+ "?t=99&f=GetDevices",
9
+ ).returns(
10
+ stub body: fixture("devices_result.html")
11
+ )
12
+
13
+ devices = TenHsServer::Device.all
14
+
15
+ assert_equal 13, devices.count
16
+ end
17
+
18
+ test "should load a single device" do
19
+ TenHsServer::Device.expects(:get).with(
20
+ "?t=99&f=GetDevice&d=Q12",
21
+ ).returns(
22
+ stub body: fixture("device_result.html")
23
+ )
24
+
25
+ device = TenHsServer::Device.new "Q12"
26
+ assert_equal "Chandelier", device.name
27
+ end
28
+
29
+ test "should toggle a device" do
30
+ TenHsServer::Device.expects(:get).with(
31
+ "?t=99&f=ToggleDevice&d=Q12",
32
+ ).returns(
33
+ stub body: fixture("toggle_device_result.html")
34
+ )
35
+
36
+ device = TenHsServer::Device.new "Q12"
37
+ assert_equal 2, device.toggle[:status]
38
+ end
39
+
40
+ test "should turn on a device" do
41
+ TenHsServer::Device.expects(:get).with(
42
+ "?t=99&f=DeviceOn&d=Q12",
43
+ ).returns(
44
+ stub body: fixture("device_on_result.html")
45
+ )
46
+
47
+ device = TenHsServer::Device.new "Q12"
48
+ assert_equal 2, device.on[:status]
49
+ end
50
+
51
+ test "should turn off a device" do
52
+ TenHsServer::Device.expects(:get).with(
53
+ "?t=99&f=DeviceOff&d=Q12",
54
+ ).returns(
55
+ stub body: fixture("device_off_result.html")
56
+ )
57
+
58
+ device = TenHsServer::Device.new "Q12"
59
+ assert_equal 3, device.off[:status]
60
+ end
61
+
62
+ test "should dim a device" do
63
+ TenHsServer::Device.expects(:get).with(
64
+ "?t=99&f=DeviceOn&d=Q12",
65
+ ).returns(
66
+ stub body: fixture("device_on_result.html")
67
+ )
68
+ TenHsServer::Device.expects(:get).with(
69
+ "?t=99&f=SetDeviceValue&d=Q12&a=70",
70
+ ).returns(
71
+ stub body: fixture("set_device_value_result.html")
72
+ )
73
+
74
+ device = TenHsServer::Device.new "Q12"
75
+ assert_equal 70, device.dim(70)
76
+ end
77
+
78
+ test "should ask a device if its on or off" do
79
+ TenHsServer::Device.expects(:get).with(
80
+ "?t=99&f=GetDevice&d=Q12",
81
+ ).returns(
82
+ stub body: fixture("device_result.html")
83
+ )
84
+
85
+ device = TenHsServer::Device.new "Q12"
86
+ assert_equal false, device.on?
87
+ assert_equal true, device.off?
88
+ end
89
+
90
+ private
91
+
92
+ # Load a fixture.
93
+ #
94
+ # name - A string describing the name of the fixture load.
95
+ #
96
+ # Returns a string describing the contents of the fixture.
97
+ def fixture name
98
+ cwd = File.expand_path(File.dirname(__FILE__))
99
+ File.read(File.join(cwd, "../fixtures/ten_hs_server/#{name}"))
100
+ end
101
+ end
@@ -0,0 +1,51 @@
1
+ require 'test_helper'
2
+ require "active_support/all"
3
+ require 'ten_hs_server'
4
+
5
+ class EventTest < ActiveSupport::TestCase
6
+ test "should load all events" do
7
+ TenHsServer::Event.expects(:get).with(
8
+ "?t=99&f=GetEvents",
9
+ ).returns(
10
+ stub body: fixture("events_result.html")
11
+ )
12
+
13
+ events = TenHsServer::Event.all
14
+
15
+ assert_equal 8, events.count
16
+ end
17
+
18
+ test "should load a single event" do
19
+ TenHsServer::Event.expects(:get).with(
20
+ "?t=99&f=GetEvents",
21
+ ).returns(
22
+ stub body: fixture("events_result.html")
23
+ )
24
+
25
+ event = TenHsServer::Event.find "All on"
26
+ assert_equal "All on", event
27
+ end
28
+
29
+ test "should run an event" do
30
+ TenHsServer::Event.expects(:get).with(
31
+ "?t=99&f=RunEvent&d=All%20on",
32
+ ).returns(
33
+ stub body: fixture("runevent_result.html")
34
+ )
35
+
36
+ status = TenHsServer::Event.run "All on"
37
+ assert_equal true, status
38
+ end
39
+
40
+ private
41
+
42
+ # Load a fixture.
43
+ #
44
+ # name - A string describing the name of the fixture load.
45
+ #
46
+ # Returns a string describing the contents of the fixture.
47
+ def fixture name
48
+ cwd = File.expand_path(File.dirname(__FILE__))
49
+ File.read(File.join(cwd, "../fixtures/ten_hs_server/#{name}"))
50
+ end
51
+ end
@@ -0,0 +1,73 @@
1
+ require 'test_helper'
2
+ require "active_support/all"
3
+ require 'ten_hs_server'
4
+
5
+ class RoomTest < ActiveSupport::TestCase
6
+ test "should load all rooms" do
7
+ TenHsServer::Device.expects(:get).with(
8
+ "?t=99&f=GetDevices",
9
+ ).returns(
10
+ stub body: fixture("devices_result.html")
11
+ )
12
+
13
+ rooms = TenHsServer::Room.all
14
+
15
+ assert_equal 5, rooms.count
16
+ end
17
+
18
+ test "should load a room" do
19
+ TenHsServer::Device.expects(:get).with(
20
+ "?t=99&f=GetDevices",
21
+ ).returns(
22
+ stub body: fixture("devices_result.html")
23
+ )
24
+
25
+ room = TenHsServer::Room.new "Dining room"
26
+ assert_equal "Dining room", room.name
27
+ assert_equal 2, room.devices.count
28
+ end
29
+
30
+ test "should turn on everything in a room" do
31
+ TenHsServer::Device.expects(:get).with(
32
+ "?t=99&f=GetDevices",
33
+ ).returns(
34
+ stub body: fixture("devices_result.html")
35
+ )
36
+ TenHsServer::Room.expects(:get).with(
37
+ "?t=99&f=DeviceOn&d=Q12.Q5",
38
+ ).returns(
39
+ stub body: fixture("dining_room_on_result.html")
40
+ )
41
+
42
+ room = TenHsServer::Room.new "Dining room"
43
+ assert_equal true, room.on
44
+ end
45
+
46
+ test "should turn off everything in a room" do
47
+ TenHsServer::Device.expects(:get).with(
48
+ "?t=99&f=GetDevices",
49
+ ).returns(
50
+ stub body: fixture("devices_result.html")
51
+ )
52
+ TenHsServer::Room.expects(:get).with(
53
+ "?t=99&f=DeviceOff&d=Q12.Q5",
54
+ ).returns(
55
+ stub body: fixture("dining_room_off_result.html")
56
+ )
57
+
58
+ room = TenHsServer::Room.new "Dining room"
59
+ assert_equal true, room.off
60
+ end
61
+
62
+ private
63
+
64
+ # Load a fixture.
65
+ #
66
+ # name - A string describing the name of the fixture load.
67
+ #
68
+ # Returns a string describing the contents of the fixture.
69
+ def fixture name
70
+ cwd = File.expand_path(File.dirname(__FILE__))
71
+ File.read(File.join(cwd, "../fixtures/ten_hs_server/#{name}"))
72
+ end
73
+ end
@@ -0,0 +1,9 @@
1
+ require 'test/unit'
2
+ require "active_support/all"
3
+
4
+ class TenHsServerTest < ActiveSupport::TestCase
5
+ def test_example
6
+ assert_equal "foo",
7
+ "foo"
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'factory_girl'
2
+
3
+ class ActiveSupport::TestCase
4
+ # Add more helper methods to be used by all tests here...
5
+ include FactoryGirl::Syntax::Methods
6
+ end
7
+
8
+ require 'mocha/setup'
9
+ require 'webmock/test_unit'
metadata ADDED
@@ -0,0 +1,203 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ten_hs_server
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Espen Hogbakk
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: activesupport
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: factory_girl
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: mocha
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: webmock
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: httparty
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: nokogiri
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ description: API wrapper around the (crappy) tenHsServer Homeseer HS2 plugin.
127
+ email:
128
+ - espen@hogbakk.no
129
+ executables: []
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - .gitignore
134
+ - .travis.yml
135
+ - Gemfile
136
+ - LICENSE
137
+ - README.rst
138
+ - Rakefile
139
+ - lib/ten_hs_server.rb
140
+ - lib/ten_hs_server/adapter.rb
141
+ - lib/ten_hs_server/device.rb
142
+ - lib/ten_hs_server/event.rb
143
+ - lib/ten_hs_server/floor.rb
144
+ - lib/ten_hs_server/room.rb
145
+ - lib/ten_hs_server/version.rb
146
+ - ten_hs_server.gemspec
147
+ - test/fixtures/ten_hs_server/device_off_result.html
148
+ - test/fixtures/ten_hs_server/device_on_result.html
149
+ - test/fixtures/ten_hs_server/device_result.html
150
+ - test/fixtures/ten_hs_server/devices_result.html
151
+ - test/fixtures/ten_hs_server/dining_room_off_result.html
152
+ - test/fixtures/ten_hs_server/dining_room_on_result.html
153
+ - test/fixtures/ten_hs_server/events_result.html
154
+ - test/fixtures/ten_hs_server/runevent_result.html
155
+ - test/fixtures/ten_hs_server/set_device_value_result.html
156
+ - test/fixtures/ten_hs_server/toggle_device_result.html
157
+ - test/ten_hs_server/adapter_test.rb
158
+ - test/ten_hs_server/device_test.rb
159
+ - test/ten_hs_server/event_test.rb
160
+ - test/ten_hs_server/room_test.rb
161
+ - test/ten_hs_server_test.rb
162
+ - test/test_helper.rb
163
+ homepage: ''
164
+ licenses: []
165
+ post_install_message:
166
+ rdoc_options: []
167
+ require_paths:
168
+ - lib
169
+ required_ruby_version: !ruby/object:Gem::Requirement
170
+ none: false
171
+ requirements:
172
+ - - ! '>='
173
+ - !ruby/object:Gem::Version
174
+ version: '0'
175
+ required_rubygems_version: !ruby/object:Gem::Requirement
176
+ none: false
177
+ requirements:
178
+ - - ! '>='
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ requirements: []
182
+ rubyforge_project: ten_hs_server
183
+ rubygems_version: 1.8.24
184
+ signing_key:
185
+ specification_version: 3
186
+ summary: tenHsServer Homeseer API wrapper.
187
+ test_files:
188
+ - test/fixtures/ten_hs_server/device_off_result.html
189
+ - test/fixtures/ten_hs_server/device_on_result.html
190
+ - test/fixtures/ten_hs_server/device_result.html
191
+ - test/fixtures/ten_hs_server/devices_result.html
192
+ - test/fixtures/ten_hs_server/dining_room_off_result.html
193
+ - test/fixtures/ten_hs_server/dining_room_on_result.html
194
+ - test/fixtures/ten_hs_server/events_result.html
195
+ - test/fixtures/ten_hs_server/runevent_result.html
196
+ - test/fixtures/ten_hs_server/set_device_value_result.html
197
+ - test/fixtures/ten_hs_server/toggle_device_result.html
198
+ - test/ten_hs_server/adapter_test.rb
199
+ - test/ten_hs_server/device_test.rb
200
+ - test/ten_hs_server/event_test.rb
201
+ - test/ten_hs_server/room_test.rb
202
+ - test/ten_hs_server_test.rb
203
+ - test/test_helper.rb