mios 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 +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +58 -0
- data/Rakefile +8 -0
- data/lib/mios/action.rb +25 -0
- data/lib/mios/device.rb +93 -0
- data/lib/mios/interface.rb +68 -0
- data/lib/mios/job.rb +79 -0
- data/lib/mios/services/camera1.rb +9 -0
- data/lib/mios/services/dimmable_light1.rb +20 -0
- data/lib/mios/services/door_lock1.rb +38 -0
- data/lib/mios/services/energy_metering1.rb +13 -0
- data/lib/mios/services/generic_sensor1.rb +9 -0
- data/lib/mios/services/ha_device1.rb +17 -0
- data/lib/mios/services/humidity_sensor1.rb +14 -0
- data/lib/mios/services/light_sensor1.rb +21 -0
- data/lib/mios/services/scene_controller1.rb +9 -0
- data/lib/mios/services/security_sensor1.rb +33 -0
- data/lib/mios/services/switch_power1.rb +25 -0
- data/lib/mios/services/temperature_sensor1.rb +13 -0
- data/lib/mios/services/window_covering1.rb +21 -0
- data/lib/mios/services/zwave_device1.rb +9 -0
- data/lib/mios/services/zwave_network1.rb +9 -0
- data/lib/mios/version.rb +3 -0
- data/lib/mios.rb +7 -0
- data/mios.gemspec +26 -0
- data/spec/random_spec.rb +8 -0
- data/spec/spec_helper.rb +5 -0
- metadata +163 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Kelley Reynolds
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# MiOS
|
2
|
+
|
3
|
+
Gem that uses the URL API for the Vera family of products from [MiCasaVerde](http://micasaverde.com).
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'mios'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install mios
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
MiOS works on a job queue. If you wish to change an attribute or the status of a particular device, you must submit a
|
22
|
+
job to MiOS and wait for it to be succeed or fail or require a requeue. Most of this functionality is hidden behind the scenes
|
23
|
+
and an idiomatic synchronous closure interface is exposed that manages it all for you, as you'll see below. Most methods can also
|
24
|
+
be used asynchronously but you need to know what you are doing as this is not really an event-driven system and inconsistencies can
|
25
|
+
occur if used improperly.
|
26
|
+
|
27
|
+
### Create a reference to your local MiOS device
|
28
|
+
mios = MiOS::Interface.new('http://192.168.15.1:3480')
|
29
|
+
|
30
|
+
### Devices could be anything of course, assuming here the first is a switch
|
31
|
+
switch = mios.devices[0]
|
32
|
+
|
33
|
+
### Turn the switch off (light switch or outlet or anything classed as a switch)
|
34
|
+
switch.off!
|
35
|
+
|
36
|
+
### The job object is returned from calls that require API calls
|
37
|
+
job = switch.on!
|
38
|
+
|
39
|
+
### Execute some code once the job has finished
|
40
|
+
switch.off! { |obj|
|
41
|
+
puts "The #{obj.name} is now off"
|
42
|
+
}
|
43
|
+
puts "This will get printed once the switch is off and the block has been executed"
|
44
|
+
|
45
|
+
### Execute some code asynchronously from the job
|
46
|
+
switch.on!(true) { |obj|
|
47
|
+
puts "The #{obj.name} is now on"
|
48
|
+
}
|
49
|
+
puts "This will output immediately"
|
50
|
+
sleep(5) # Sleep to wait for the thread to finish, will clean this up later
|
51
|
+
|
52
|
+
## Contributing
|
53
|
+
|
54
|
+
1. Fork it
|
55
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
56
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
57
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
58
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/lib/mios/action.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
3
|
+
module MiOS
|
4
|
+
class Action
|
5
|
+
def initialize(device, service_id, action, parameters={})
|
6
|
+
@device, @service_id, @action, @parameters = device, service_id, action, parameters
|
7
|
+
end
|
8
|
+
|
9
|
+
def take(async=false, &block)
|
10
|
+
response = @device.class.get url
|
11
|
+
# Are there ever more than one jobs from a device action?
|
12
|
+
Job.new(@device, response.values.first['JobID'], async, &block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def url
|
16
|
+
url = "/data_request?output_format=json&id=action"
|
17
|
+
url += "&DeviceNum=#{@device.id}"
|
18
|
+
url += "&action=#{@action}"
|
19
|
+
url += "&serviceId=#{@service_id}&"
|
20
|
+
url += @parameters.map { |k, v|
|
21
|
+
"#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}"
|
22
|
+
}.join("&")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/mios/device.rb
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
module MiOS
|
2
|
+
class Device
|
3
|
+
|
4
|
+
class << self
|
5
|
+
def new(uri, *args)
|
6
|
+
Class.new(AbstractInterface) { |klass|
|
7
|
+
klass.base_uri(uri)
|
8
|
+
}.new(*args)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class AbstractInterface
|
13
|
+
include HTTParty
|
14
|
+
format :json
|
15
|
+
|
16
|
+
attr_reader :attributes
|
17
|
+
|
18
|
+
def initialize(data)
|
19
|
+
parse(data)
|
20
|
+
end
|
21
|
+
|
22
|
+
def inspect
|
23
|
+
"#<MiOS::Device:0x#{'%x' % (self.object_id << 1)} name=#{@attributes['name']}>"
|
24
|
+
end
|
25
|
+
|
26
|
+
def method_missing(method, *args)
|
27
|
+
if @attributes.has_key?(method.to_s)
|
28
|
+
@attributes[method.to_s]
|
29
|
+
else
|
30
|
+
super
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def reload
|
35
|
+
parse(self.class.get("/data_request?id=status&DeviceNum=#{id}").parsed_response["Device_Num_#{id}"], true)
|
36
|
+
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def set(urn, action, params, async=false, &block)
|
43
|
+
MiOS::Action.new(self, urn, action, params).take(async, &block)
|
44
|
+
end
|
45
|
+
|
46
|
+
def timestamp_for(urn, key)
|
47
|
+
Time.at integer_for(urn, key)
|
48
|
+
end
|
49
|
+
|
50
|
+
def boolean_for(urn, key)
|
51
|
+
integer_for(urn, key) == 1
|
52
|
+
end
|
53
|
+
|
54
|
+
def integer_for(urn, key)
|
55
|
+
value_for(urn, key).to_i
|
56
|
+
end
|
57
|
+
|
58
|
+
def value_for(urn, key)
|
59
|
+
@states.each do |state_hash|
|
60
|
+
if state_hash['service'] == urn
|
61
|
+
if state_hash['variable'] == key
|
62
|
+
return state_hash['value']
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
nil
|
68
|
+
end
|
69
|
+
|
70
|
+
def parse(data, skip_attributes=false)
|
71
|
+
|
72
|
+
@attributes = Hash[
|
73
|
+
data.select { |k, v|
|
74
|
+
!data[k].kind_of?(Hash) and !data[k].kind_of?(Array)
|
75
|
+
}.to_a
|
76
|
+
] unless skip_attributes
|
77
|
+
|
78
|
+
@states = data['states']
|
79
|
+
@states.map { |state|
|
80
|
+
state['service'].split(":").last
|
81
|
+
}.uniq.each { |service|
|
82
|
+
if MiOS::Services.const_defined?(service)
|
83
|
+
extend MiOS::Services.const_get(service)
|
84
|
+
else
|
85
|
+
$stderr.puts "WARNING: #{service} not yet supported"
|
86
|
+
end
|
87
|
+
}
|
88
|
+
|
89
|
+
true
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module MiOS
|
2
|
+
class Interface
|
3
|
+
|
4
|
+
class << self
|
5
|
+
def new(uri, *args)
|
6
|
+
Class.new(AbstractInterface) { |klass|
|
7
|
+
klass.base_uri(uri)
|
8
|
+
}.new(*args)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class AbstractInterface
|
13
|
+
include HTTParty
|
14
|
+
format :json
|
15
|
+
|
16
|
+
attr_reader :attributes
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
refresh!
|
20
|
+
end
|
21
|
+
|
22
|
+
def method_missing(method, *args)
|
23
|
+
if @attributes.has_key?(method.to_s)
|
24
|
+
@attributes[method.to_s]
|
25
|
+
else
|
26
|
+
super
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def inspect
|
31
|
+
"#<MiOS::Interface:0x#{'%x' % (self.object_id << 1)} @attributes=#{@attributes.inspect}>"
|
32
|
+
end
|
33
|
+
|
34
|
+
def refresh!
|
35
|
+
data = self.class.get "/data_request?id=user_data"
|
36
|
+
@attributes = Hash[
|
37
|
+
data.select { |k, v|
|
38
|
+
!data[k].kind_of?(Hash) and !data[k].kind_of?(Array)
|
39
|
+
}.map { |k, v|
|
40
|
+
[k.downcase, v]
|
41
|
+
}
|
42
|
+
]
|
43
|
+
# Convert some time objects
|
44
|
+
['loadtime', 'devicesync'].each do |attr|
|
45
|
+
@attributes[attr] = Time.at(@attributes[attr].to_i)
|
46
|
+
end
|
47
|
+
|
48
|
+
@devices = Hash[
|
49
|
+
data['devices'].map { |device|
|
50
|
+
[device['id'], Device.new(self.class.base_uri, device)]
|
51
|
+
}
|
52
|
+
]
|
53
|
+
|
54
|
+
true
|
55
|
+
end
|
56
|
+
|
57
|
+
def categories
|
58
|
+
@devices.values.map { |device|
|
59
|
+
device.category
|
60
|
+
}.uniq.sort
|
61
|
+
end
|
62
|
+
|
63
|
+
def devices; @devices.values; end
|
64
|
+
|
65
|
+
def device_names; devices.map(&:name); end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/mios/job.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'timeout'
|
2
|
+
|
3
|
+
module MiOS
|
4
|
+
module Error
|
5
|
+
class JobNonexistent < StandardError; end
|
6
|
+
class JobError < StandardError; end
|
7
|
+
class JobAborted < StandardError; end
|
8
|
+
class JobRequeue < StandardError; end
|
9
|
+
class JobTimeout < StandardError; end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Job
|
13
|
+
Status = {
|
14
|
+
-1 => "Nonexistent",
|
15
|
+
0 => "Waiting",
|
16
|
+
1 => "In progress",
|
17
|
+
2 => "Error",
|
18
|
+
3 => "Aborted",
|
19
|
+
4 => "Completed",
|
20
|
+
5 => "Waiting for callback",
|
21
|
+
6 => "Requeue",
|
22
|
+
7 => "In progress with pending data"
|
23
|
+
}
|
24
|
+
attr_reader :id
|
25
|
+
|
26
|
+
def initialize(obj, id, async=false, &block)
|
27
|
+
@obj, @id = obj, id
|
28
|
+
reload_status!
|
29
|
+
|
30
|
+
if block_given?
|
31
|
+
if async
|
32
|
+
Thread.new do
|
33
|
+
when_complete(&block)
|
34
|
+
end
|
35
|
+
else
|
36
|
+
when_complete(&block)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def when_complete(&block)
|
42
|
+
raise Error::JobTimeout if !exists?
|
43
|
+
Timeout::timeout(20) do
|
44
|
+
sleep_interval = 0.25
|
45
|
+
|
46
|
+
# If the job is still processing, wait a bit and try again
|
47
|
+
while waiting? || in_progress? || waiting_for_callback? || in_progress_with_pending_data? do
|
48
|
+
sleep(sleep_interval += 0.25)
|
49
|
+
reload_status!
|
50
|
+
end
|
51
|
+
raise JobError if error?
|
52
|
+
raise JobAborted if aborted?
|
53
|
+
raise JobRequeue if requeue?
|
54
|
+
end
|
55
|
+
yield @obj.reload
|
56
|
+
rescue Timeout::Error
|
57
|
+
$stderr.puts "Timed out waiting for job status to become complete"
|
58
|
+
raise Error::JobTimeout
|
59
|
+
end
|
60
|
+
|
61
|
+
def exists?; status != -1; end
|
62
|
+
def waiting?; status == 0; end
|
63
|
+
def in_progress?; status == 1; end
|
64
|
+
def error?; status == 2; end
|
65
|
+
def aborted?; status == 3; end
|
66
|
+
def completed?; status == 4; end
|
67
|
+
def waiting_for_callback?; status == 5; end
|
68
|
+
def requeue?; status == 6; end
|
69
|
+
def in_progress_with_pending_data?; status == 7; end
|
70
|
+
|
71
|
+
def status
|
72
|
+
@status || reload_status!
|
73
|
+
end
|
74
|
+
|
75
|
+
def reload_status!
|
76
|
+
@status = @obj.class.get("/data_request?id=jobstatus&job=#{@id}&plugin=zwave")['status']
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module MiOS
|
2
|
+
module Services
|
3
|
+
module Dimming1
|
4
|
+
def self.extended(base)
|
5
|
+
base.instance_variable_set("@dimming1_urn", "urn:upnp-org:serviceId:Dimming1")
|
6
|
+
end
|
7
|
+
|
8
|
+
def level
|
9
|
+
integer_for(@dimming1_urn, 'LoadLevelStatus')
|
10
|
+
end
|
11
|
+
|
12
|
+
def set_level!(new_level, async=false, &block)
|
13
|
+
new_level = new_load_level.to_i
|
14
|
+
new_level = 100 if new_load_level > 100
|
15
|
+
new_level = 0 if new_load_level < 0
|
16
|
+
set(@dimming1_urn, "SetLoadLevelTarget", {"newLoadLevelTarget" => new_level}, async, &block)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module MiOS
|
2
|
+
module Services
|
3
|
+
module DoorLock1
|
4
|
+
def self.extended(base)
|
5
|
+
base.instance_variable_set("@doorlock1_urn", "urn:micasaverde-com:serviceId:DoorLock1")
|
6
|
+
end
|
7
|
+
|
8
|
+
def locked?
|
9
|
+
boolean_for(@doorlock1_urn, 'Status')
|
10
|
+
end
|
11
|
+
|
12
|
+
def unlocked?
|
13
|
+
!locked?
|
14
|
+
end
|
15
|
+
|
16
|
+
def pincodes
|
17
|
+
tmp = value_for(@doorlock1_urn, 'PinCodes')
|
18
|
+
tmp.gsub!(/^<[^>]+>/, '').split("\t")
|
19
|
+
end
|
20
|
+
|
21
|
+
def lock!(async=false, &block)
|
22
|
+
set(@doorlock1_urn, "SetTarget", {"newTargetValue" => 1}, async, &block)
|
23
|
+
end
|
24
|
+
|
25
|
+
def unlock!(async=false, &block)
|
26
|
+
set(@doorlock1_urn, "SetTarget", {"newTargetValue" => 0}, async, &block)
|
27
|
+
end
|
28
|
+
|
29
|
+
def set_pin(name, pin, index, async=false, &block)
|
30
|
+
set(@doorlock1_urn, "SetPin", {"UserCodeName" => name, "newPin" => pin, "user" => index}, async, &block)
|
31
|
+
end
|
32
|
+
|
33
|
+
def clear_pin(index, async=false, &block)
|
34
|
+
set(@doorlock1_urn, "ClearPin", {"UserCode" => index}, async, &block)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module MiOS
|
2
|
+
module Services
|
3
|
+
module EnergyMetering1
|
4
|
+
def self.extended(base)
|
5
|
+
base.instance_variable_set("@energymetering1_urn", "urn:upnp-org:serviceId:EnergyMetering1")
|
6
|
+
end
|
7
|
+
|
8
|
+
def watts
|
9
|
+
integer_for(@energymetering1_urn, 'Watts')
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module MiOS
|
2
|
+
module Services
|
3
|
+
module HaDevice1
|
4
|
+
def self.extended(base)
|
5
|
+
base.instance_variable_set("@hadevice1_urn", "urn:micasaverde-com:serviceId:HaDevice1")
|
6
|
+
end
|
7
|
+
|
8
|
+
def battery_level
|
9
|
+
integer_for(@hadevice1_urn, "BatteryLevel")
|
10
|
+
end
|
11
|
+
|
12
|
+
def battery_date
|
13
|
+
timestamp_for(@hadevice1_urn, "BatteryDate")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# NOTE: Currently untested with a real humidity sensor
|
2
|
+
module MiOS
|
3
|
+
module Services
|
4
|
+
module HumiditySensor1
|
5
|
+
def self.extended(base)
|
6
|
+
base.instance_variable_set("@humiditysensor1_urn", "urn:upnp-org:serviceId:HumiditySensor1")
|
7
|
+
end
|
8
|
+
|
9
|
+
def humidity
|
10
|
+
integer_for(@humiditysensor1_urn, 'CurrentHumidity')
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module MiOS
|
2
|
+
module Services
|
3
|
+
module LightSensor1
|
4
|
+
def self.extended(base)
|
5
|
+
base.instance_variable_set("@lightsensor1_urn", "urn:micasaverde-com:serviceId:LightSensor1")
|
6
|
+
end
|
7
|
+
|
8
|
+
def level
|
9
|
+
@states.each do |state_hash|
|
10
|
+
if state_hash['service'] == @lightsensor1_urn
|
11
|
+
if state_hash['variable'] == "CurrentLevel"
|
12
|
+
return state_hash['value'].to_i
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
return nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module MiOS
|
2
|
+
module Services
|
3
|
+
module SecuritySensor1
|
4
|
+
def self.extended(base)
|
5
|
+
base.instance_variable_set("@securitysensor1_urn", "urn:micasaverde-com:serviceId:SecuritySensor1")
|
6
|
+
end
|
7
|
+
|
8
|
+
def tripped?
|
9
|
+
boolean_for(@securitysensor1_urn, 'Tripped')
|
10
|
+
end
|
11
|
+
|
12
|
+
def armed?
|
13
|
+
boolean_for(@securitysensor1_urn, 'Armed')
|
14
|
+
end
|
15
|
+
|
16
|
+
def disarmed?
|
17
|
+
!armed?
|
18
|
+
end
|
19
|
+
|
20
|
+
def lasttrip
|
21
|
+
timestamp_for(@securitysensor1_urn, 'LastTrip')
|
22
|
+
end
|
23
|
+
|
24
|
+
def arm!(async=false, &block)
|
25
|
+
set(@securitysensor1_urn, "SetArmed", {"newArmedValue" => 1}, async, &block)
|
26
|
+
end
|
27
|
+
|
28
|
+
def disarm!(async=false, &block)
|
29
|
+
set(@securitysensor1_urn, "SetArmed", {"newArmedValue" => 0}, async, &block)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module MiOS
|
2
|
+
module Services
|
3
|
+
module SwitchPower1
|
4
|
+
def self.extended(base)
|
5
|
+
base.instance_variable_set("@switchpower1_urn", "urn:upnp-org:serviceId:SwitchPower1")
|
6
|
+
end
|
7
|
+
|
8
|
+
def on?
|
9
|
+
boolean_for(@switchpower1_urn, 'Status')
|
10
|
+
end
|
11
|
+
|
12
|
+
def off?
|
13
|
+
!on?
|
14
|
+
end
|
15
|
+
|
16
|
+
def on!(async=false, &block)
|
17
|
+
set(@switchpower1_urn, "SetTarget", {"newTargetValue" => 1}, async, &block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def off!(async=false, &block)
|
21
|
+
set(@switchpower1_urn, "SetTarget", {"newTargetValue" => 0}, async, &block)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module MiOS
|
2
|
+
module Services
|
3
|
+
module TemperatureSensor1
|
4
|
+
def self.extended(base)
|
5
|
+
base.instance_variable_set("@temperaturesensor1_urn", "urn:upnp-org:serviceId:TemperatureSensor1")
|
6
|
+
end
|
7
|
+
|
8
|
+
def temperature
|
9
|
+
integer_for(@temperaturesensor1_urn, 'CurrentTemperature')
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module MiOS
|
2
|
+
module Services
|
3
|
+
module WindowCovering1
|
4
|
+
def self.extended(base)
|
5
|
+
base.instance_variable_set("@windowcovering1_urn", "urn:upnp-org:serviceId:WindowCovering1")
|
6
|
+
end
|
7
|
+
|
8
|
+
def up!(async=false, &block)
|
9
|
+
set(@windowcovering1_urn, "Up", async, &block)
|
10
|
+
end
|
11
|
+
|
12
|
+
def down!(async=false, &block)
|
13
|
+
set(@windowcovering1_urn, "Down", async, &block)
|
14
|
+
end
|
15
|
+
|
16
|
+
def stop!(async=false, &block)
|
17
|
+
set(@windowcovering1_urn, "Stop", async, &block)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/mios/version.rb
ADDED
data/lib/mios.rb
ADDED
data/mios.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'mios/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "mios"
|
8
|
+
gem.version = MiOS::VERSION
|
9
|
+
gem.authors = ["Kelley Reynolds"]
|
10
|
+
gem.email = ["kelley.reynolds@rubyscale.com"]
|
11
|
+
gem.description = %q{Object-oriented interactions with MiOS from MiCasaVerde}
|
12
|
+
gem.summary = %q{Object-oriented interactions with MiOS from MiCasaVerde}
|
13
|
+
gem.homepage = ""
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency "httparty", ">= 0.9.0"
|
21
|
+
|
22
|
+
gem.add_development_dependency "rspec", ">= 2.8.0"
|
23
|
+
gem.add_development_dependency "syntax"
|
24
|
+
gem.add_development_dependency "rake", ">= 0.9.2"
|
25
|
+
gem.add_development_dependency "yard", ">= 0.7.2"
|
26
|
+
end
|
data/spec/random_spec.rb
ADDED
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mios
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Kelley Reynolds
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-10-07 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: httparty
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.9.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.9.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 2.8.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: 2.8.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: syntax
|
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: rake
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 0.9.2
|
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.9.2
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: yard
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 0.7.2
|
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.7.2
|
94
|
+
description: Object-oriented interactions with MiOS from MiCasaVerde
|
95
|
+
email:
|
96
|
+
- kelley.reynolds@rubyscale.com
|
97
|
+
executables: []
|
98
|
+
extensions: []
|
99
|
+
extra_rdoc_files: []
|
100
|
+
files:
|
101
|
+
- .gitignore
|
102
|
+
- Gemfile
|
103
|
+
- LICENSE.txt
|
104
|
+
- README.md
|
105
|
+
- Rakefile
|
106
|
+
- lib/mios.rb
|
107
|
+
- lib/mios/action.rb
|
108
|
+
- lib/mios/device.rb
|
109
|
+
- lib/mios/interface.rb
|
110
|
+
- lib/mios/job.rb
|
111
|
+
- lib/mios/services/camera1.rb
|
112
|
+
- lib/mios/services/dimmable_light1.rb
|
113
|
+
- lib/mios/services/door_lock1.rb
|
114
|
+
- lib/mios/services/energy_metering1.rb
|
115
|
+
- lib/mios/services/generic_sensor1.rb
|
116
|
+
- lib/mios/services/ha_device1.rb
|
117
|
+
- lib/mios/services/humidity_sensor1.rb
|
118
|
+
- lib/mios/services/light_sensor1.rb
|
119
|
+
- lib/mios/services/scene_controller1.rb
|
120
|
+
- lib/mios/services/security_sensor1.rb
|
121
|
+
- lib/mios/services/switch_power1.rb
|
122
|
+
- lib/mios/services/temperature_sensor1.rb
|
123
|
+
- lib/mios/services/window_covering1.rb
|
124
|
+
- lib/mios/services/zwave_device1.rb
|
125
|
+
- lib/mios/services/zwave_network1.rb
|
126
|
+
- lib/mios/version.rb
|
127
|
+
- mios.gemspec
|
128
|
+
- spec/random_spec.rb
|
129
|
+
- spec/spec_helper.rb
|
130
|
+
homepage: ''
|
131
|
+
licenses: []
|
132
|
+
post_install_message:
|
133
|
+
rdoc_options: []
|
134
|
+
require_paths:
|
135
|
+
- lib
|
136
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
segments:
|
143
|
+
- 0
|
144
|
+
hash: -1148143416777399406
|
145
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
|
+
none: false
|
147
|
+
requirements:
|
148
|
+
- - ! '>='
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: '0'
|
151
|
+
segments:
|
152
|
+
- 0
|
153
|
+
hash: -1148143416777399406
|
154
|
+
requirements: []
|
155
|
+
rubyforge_project:
|
156
|
+
rubygems_version: 1.8.23
|
157
|
+
signing_key:
|
158
|
+
specification_version: 3
|
159
|
+
summary: Object-oriented interactions with MiOS from MiCasaVerde
|
160
|
+
test_files:
|
161
|
+
- spec/random_spec.rb
|
162
|
+
- spec/spec_helper.rb
|
163
|
+
has_rdoc:
|