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 ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mios.gemspec
4
+ gemspec
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
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rake'
4
+ require 'rspec/core'
5
+ require 'rspec/core/rake_task'
6
+
7
+ require 'yard'
8
+ YARD::Rake::YardocTask.new
@@ -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
@@ -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,9 @@
1
+ module MiOS
2
+ module Services
3
+ module Camera1
4
+ def self.extended(base)
5
+ base.instance_variable_set("@camera1_urn", "urn:micasaverde-com:serviceId:Camera1")
6
+ end
7
+ end
8
+ end
9
+ 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,9 @@
1
+ module MiOS
2
+ module Services
3
+ module GenericSensor1
4
+ def self.extended(base)
5
+ base.instance_variable_set("@genericsensor1_urn", "urn:micasaverde-com:serviceId:GenericSensor1")
6
+ end
7
+ end
8
+ end
9
+ 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,9 @@
1
+ module MiOS
2
+ module Services
3
+ module SceneController1
4
+ def self.extended(base)
5
+ base.instance_variable_set("@scenecontroller1_urn", "urn:micasaverde-com:serviceId:SceneController1")
6
+ end
7
+ end
8
+ end
9
+ 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
@@ -0,0 +1,9 @@
1
+ module MiOS
2
+ module Services
3
+ module ZWaveDevice1
4
+ def self.extended(base)
5
+ base.instance_variable_set("@zwavedevice1_urn", "urn:micasaverde-com:serviceId:ZWaveDevice1")
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module MiOS
2
+ module Services
3
+ module ZWaveNetwork1
4
+ def self.extended(base)
5
+ base.instance_variable_set("@zwavenetwork1_urn", "urn:micasaverde-com:serviceId:ZWaveNetwork1")
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module MiOS
2
+ VERSION = "0.1.0"
3
+ end
data/lib/mios.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'httparty'
2
+ require "mios/version"
3
+ require "mios/interface"
4
+ require "mios/device"
5
+ require "mios/action"
6
+ require "mios/job"
7
+ Dir[File.dirname(__FILE__) + '/mios/services/*.rb'].each {|file| require file }
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
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+ require File.expand_path('spec_helper.rb', File.dirname(__FILE__))
3
+
4
+ describe "truth" do
5
+ it "trivial test" do
6
+ 1.should eq 1
7
+ end
8
+ end
@@ -0,0 +1,5 @@
1
+ require 'rubygems'
2
+ require 'rspec'
3
+
4
+ $LOAD_PATH << "#{File.expand_path(File.dirname(__FILE__))}/../lib"
5
+ require "mios"
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: