domotics-core 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +2 -2
- data/lib/domotics/core.rb +42 -2
- data/lib/domotics/core/data/data_hash.rb +38 -0
- data/lib/domotics/core/data/data_mongo.rb +39 -0
- data/lib/domotics/core/data/data_redis.rb +56 -0
- data/lib/domotics/core/device.rb +22 -0
- data/lib/domotics/core/device/arduino_board.rb +37 -0
- data/lib/domotics/core/element.rb +47 -0
- data/lib/domotics/core/element/button.rb +41 -0
- data/lib/domotics/core/element/dimmer.rb +71 -0
- data/lib/domotics/core/element/motion_sensor.rb +18 -0
- data/lib/domotics/core/element/reed_switch.rb +18 -0
- data/lib/domotics/core/element/rgb_strip.rb +94 -0
- data/lib/domotics/core/element/switch.rb +67 -0
- data/lib/domotics/core/element_group.rb +38 -0
- data/lib/domotics/core/helper.rb +73 -0
- data/lib/domotics/core/room.rb +86 -0
- data/lib/domotics/core/server.rb +39 -0
- data/lib/domotics/core/setup.rb +74 -0
- data/lib/domotics/core/version.rb +1 -1
- data/test/config.test.rb +16 -0
- data/test/test_devices.rb +9 -0
- data/test/test_elements.rb +63 -0
- data/test/test_rooms.rb +17 -0
- data/test/test_server.rb +57 -0
- metadata +31 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 096e15387741c6806173272f0da0754df91249d7
|
4
|
+
data.tar.gz: 2555b1a6fd43f0d236edd53d94508072af6c6f10
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 52e29d3445656f7a3b447687986a93e524652e1fa2439e875c36d741095d5863f81e91d1bd1a4ab9ff9333d10545e70bfb22864cdac3e5d9233147c5855cbc57
|
7
|
+
data.tar.gz: d390c82c1906c07a3744288481a2b18b6a8fc72219f05f3bad21968b9e236cc60cba0956a797fc0daf80866c38622244c1d49162849392a30626e4021bc804a4
|
data/Rakefile
CHANGED
@@ -36,7 +36,7 @@ end
|
|
36
36
|
|
37
37
|
def update(msg)
|
38
38
|
# Update version
|
39
|
-
File.open "./lib/domotics/
|
39
|
+
File.open "./lib/domotics/core/version.rb", "r+" do |f|
|
40
40
|
up = f.read.sub(/\d+.\d+.\d+/) { |ver| ver.split('.').map.with_index{ |sv, i| yield sv,i }.join('.') }
|
41
41
|
f.seek 0
|
42
42
|
f.write up
|
@@ -52,4 +52,4 @@ def update(msg)
|
|
52
52
|
puts "Pushed to github."
|
53
53
|
Dir["./*.gemspec"].each { |spec| puts %x(gem build #{spec}) }
|
54
54
|
Dir["./*.gem"].each { |gem| puts %x(gem push #{gem}) }
|
55
|
-
end
|
55
|
+
end
|
data/lib/domotics/core.rb
CHANGED
@@ -1,7 +1,47 @@
|
|
1
|
-
|
1
|
+
# From data_mongo
|
2
|
+
require 'mongo'
|
3
|
+
# From data_redis
|
4
|
+
require 'redis'
|
5
|
+
require 'hiredis'
|
6
|
+
# From arduino_board
|
7
|
+
require 'domotics/arduino'
|
8
|
+
# From server
|
9
|
+
require 'json'
|
2
10
|
|
3
11
|
module Domotics
|
4
12
|
module Core
|
5
|
-
#
|
13
|
+
# Map config names to real classes
|
14
|
+
CLASS_MAP = {}
|
15
|
+
# Scan file for class name and add to CLASS_MAP
|
16
|
+
def self.add_map(args = {})
|
17
|
+
realm = args[:realm] || self
|
18
|
+
if args[:file]
|
19
|
+
class_name = nil
|
20
|
+
index = nil
|
21
|
+
require args[:file]
|
22
|
+
IO.read(args[:file]).each_line do |line|
|
23
|
+
if line =~ /class\s*([A-Z]\w*)[\s\w<]*(#__as__ :(\w*))?/
|
24
|
+
class_name, index = $1, $3 && $3.to_sym
|
25
|
+
break
|
26
|
+
end
|
27
|
+
end
|
28
|
+
return unless class_name
|
29
|
+
end
|
30
|
+
class_name ||= args[:class_name]
|
31
|
+
index ||= class_name.split(/(?=[A-Z])/).map{ |cnp| cnp.downcase }.join('_').to_sym
|
32
|
+
klass = realm.const_get(class_name)
|
33
|
+
CLASS_MAP[index] = [args[:type], klass]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
gem_path = File.dirname(__FILE__)
|
39
|
+
#require all
|
40
|
+
Dir["#{gem_path}/core/data/*.rb"].each {|file| require file}
|
41
|
+
Dir["#{gem_path}/core/*.rb"].each {|file| require file}
|
42
|
+
# scan all devices and elements and populate class map
|
43
|
+
[:device, :room, :element].each do |type|
|
44
|
+
Dir["#{gem_path}/core/#{type}/*.rb"].each do |file|
|
45
|
+
Domotics::Core.add_map type: type, file: file
|
6
46
|
end
|
7
47
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Domotics::Core
|
2
|
+
class DataHash
|
3
|
+
def initialize
|
4
|
+
@store = {}
|
5
|
+
end
|
6
|
+
|
7
|
+
def [](obj)
|
8
|
+
case obj
|
9
|
+
when Element
|
10
|
+
DataHashOperator.new self, "#{obj.room.name}:#{obj.name}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def set(key, value)
|
15
|
+
@store[key] = value
|
16
|
+
end
|
17
|
+
def get(key)
|
18
|
+
@store[key]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class DataHashOperator < BasicObject
|
23
|
+
def initialize(hash, key)
|
24
|
+
@hash, @key = hash, key
|
25
|
+
end
|
26
|
+
|
27
|
+
def method_missing(symbol, *args)
|
28
|
+
# Setter method [*=(value)]
|
29
|
+
if symbol.to_s =~ /.*=\Z/ and args.size == 1
|
30
|
+
@hash.set "#{@key}:#{symbol.to_s[0..-2]}", args[0]
|
31
|
+
elsif args.size == 0
|
32
|
+
@hash.get "#{@key}:#{symbol}"
|
33
|
+
else
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Domotics::Core
|
2
|
+
class DataMongo
|
3
|
+
def initialize(args = {})
|
4
|
+
@logger = args[:logger] || Logger.new(STDERR)
|
5
|
+
@mongo = Mongo::MongoClient.new(args[:host] || "127.0.0.1", args[:port] || 27017).db("domotics")
|
6
|
+
end
|
7
|
+
|
8
|
+
def [](obj)
|
9
|
+
case obj
|
10
|
+
when Element
|
11
|
+
DataMongoOperator.new @mongo.collection(obj.room.name.to_s), obj.name.to_s
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class DataMongoOperator < BasicObject
|
17
|
+
def initialize(coll, element)
|
18
|
+
@coll = coll
|
19
|
+
@element = element
|
20
|
+
end
|
21
|
+
|
22
|
+
def method_missing(symbol, *args)
|
23
|
+
# Setter method [*=(value)]
|
24
|
+
if symbol.to_s =~ /.*=\Z/ and args.size == 1
|
25
|
+
if el = @coll.find_one("element" => @element)
|
26
|
+
@coll.update({ "_id" => el["_id"] }, { "element" => @element, symbol.to_s[0..-2] => args[0] })
|
27
|
+
else
|
28
|
+
@coll.insert("element" => @element, symbol.to_s[0..-2] => args[0])
|
29
|
+
end
|
30
|
+
# Getter method (no arguments allowed)
|
31
|
+
elsif args.size == 0
|
32
|
+
result = @coll.find_one("element" => @element)
|
33
|
+
result && result[symbol.to_s]
|
34
|
+
else
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Domotics::Core
|
2
|
+
class DataRedis
|
3
|
+
def initialize(args = {})
|
4
|
+
@logger = args[:logger] || Logger.new(STDERR)
|
5
|
+
@args = Hash.new
|
6
|
+
@args[:host] = args[:host] || "127.0.0.1"
|
7
|
+
@args[:port] = args[:port] || 6379
|
8
|
+
@args[:driver] = :hiredis
|
9
|
+
connect
|
10
|
+
end
|
11
|
+
|
12
|
+
def [](obj)
|
13
|
+
case obj
|
14
|
+
when Element
|
15
|
+
DataRedisOperator.new self, "#{obj.room.name}:#{obj.name}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def connect(args = {})
|
20
|
+
@logger.debug "Broken connection to redis host [#{@args[:host]}:#{@args[:port]}] detected. Reconnect." if args[:broken]
|
21
|
+
@redis.quit if @redis
|
22
|
+
@redis = Redis.new @args
|
23
|
+
end
|
24
|
+
|
25
|
+
def get(*args)
|
26
|
+
@redis.get *args
|
27
|
+
end
|
28
|
+
def set(*args)
|
29
|
+
@redis.set *args
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class DataRedisOperator < BasicObject
|
34
|
+
def initialize(redis, key)
|
35
|
+
@redis = redis
|
36
|
+
@key = key
|
37
|
+
end
|
38
|
+
|
39
|
+
def method_missing(symbol, *args)
|
40
|
+
# Setter method [*=(value)]
|
41
|
+
if symbol.to_s =~ /.*=\Z/ and args.size == 1
|
42
|
+
@redis.set "#{@key}:#{symbol.to_s[0..-2]}", args[0].to_s
|
43
|
+
# Getter method (no arguments allowed)
|
44
|
+
elsif args.size == 0
|
45
|
+
result = @redis.get "#{@key}:#{symbol}"
|
46
|
+
while result =~ /\AOK\Z/
|
47
|
+
@redis.connect broken: true
|
48
|
+
result = @redis.get "#{@key}:#{symbol}"
|
49
|
+
end
|
50
|
+
result && result.to_isym
|
51
|
+
else
|
52
|
+
nil
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Domotics::Core
|
2
|
+
class Device
|
3
|
+
@@devices = {}
|
4
|
+
attr_reader :name, :type
|
5
|
+
def initialize(args = {})
|
6
|
+
@@devices[@name = args[:name]] = self
|
7
|
+
@type = args[:type]
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.[](symbol = nil)
|
11
|
+
return @@devices[symbol] if symbol
|
12
|
+
@@devices
|
13
|
+
end
|
14
|
+
|
15
|
+
def destroy
|
16
|
+
@@devices[@name] = nil
|
17
|
+
end
|
18
|
+
def to_s
|
19
|
+
"Room[#{@name}](id:#{__id__})"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Domotics::Core
|
2
|
+
class ArduinoBoard < Device #__as__ :arduino
|
3
|
+
include Domotics::Arduino::ArduinoBase
|
4
|
+
|
5
|
+
def initialize(args_hash = {})
|
6
|
+
@pins = Hash.new
|
7
|
+
super
|
8
|
+
end
|
9
|
+
|
10
|
+
# Register pin for watch events
|
11
|
+
def register_pin(pin_object, number)
|
12
|
+
@pins[number] = pin_object
|
13
|
+
end
|
14
|
+
|
15
|
+
# Return pin object
|
16
|
+
def [](number = nil)
|
17
|
+
return @pins[number] if number
|
18
|
+
@pins
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
# Override default handler
|
24
|
+
def event_handler(hash)
|
25
|
+
case hash[:event]
|
26
|
+
# Tell element to change state
|
27
|
+
when :pin_state_changed
|
28
|
+
element = @pins[hash[:pin]]
|
29
|
+
element.state_changed element.to_hls(hash[:state])
|
30
|
+
when :malfunction
|
31
|
+
nil
|
32
|
+
else
|
33
|
+
nil
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Domotics::Core
|
2
|
+
class Element
|
3
|
+
@@data = DataHash.new
|
4
|
+
attr_reader :name, :type, :room
|
5
|
+
|
6
|
+
def initialize(args = {})
|
7
|
+
@room = args[:room]
|
8
|
+
@room.register_element self, @name = args[:name]
|
9
|
+
@type ||= :element
|
10
|
+
set_state(self.state || :off)
|
11
|
+
end
|
12
|
+
|
13
|
+
def state
|
14
|
+
@@data[self].state
|
15
|
+
end
|
16
|
+
|
17
|
+
def verbose_state
|
18
|
+
{ @room.name =>
|
19
|
+
{ :elements =>
|
20
|
+
{ @name =>
|
21
|
+
{ :state => state,
|
22
|
+
:info => (info if respond_to? :info)
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
def set_state(value)
|
30
|
+
@@data[self].state = value
|
31
|
+
@room.notify({ event: :state_set, element: self }) unless @type == :dimmer
|
32
|
+
end
|
33
|
+
|
34
|
+
def state_changed(value)
|
35
|
+
@@data[self].state = value
|
36
|
+
@room.notify event: :state_changed, element: self
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.data=(value)
|
40
|
+
@@data = value
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_s
|
44
|
+
"Element[#{@room.name}@#{@name}](id:#{__id__})"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Domotics::Core
|
2
|
+
class Button < Element
|
3
|
+
def initialize(args = {})
|
4
|
+
@type = args[:type] || :button
|
5
|
+
@touch = args[:touch]
|
6
|
+
@taped = true
|
7
|
+
#@tap_lock = Mutex.new
|
8
|
+
if args[:device_type]
|
9
|
+
eval_str = %(include Domotics::#{args[:device_type].capitalize}::#{@touch ? 'DigitalSensor' : 'NOSensor'})
|
10
|
+
self.class.class_eval(eval_str, __FILE__, __LINE__)
|
11
|
+
end
|
12
|
+
super
|
13
|
+
end
|
14
|
+
def set_state(*args)
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def state_changed(value)
|
19
|
+
case value
|
20
|
+
when :on
|
21
|
+
(@last_on = Time.now; @taped = false) if @taped
|
22
|
+
when :off
|
23
|
+
case Time.now - (@last_on || Time.now)
|
24
|
+
when 0...0.01 then return # debounce
|
25
|
+
when 0.01...0.3 then super :tap; @taped = true
|
26
|
+
when 0.3...1 then super :long_tap; @taped = true
|
27
|
+
#@tap_lock.synchronize do
|
28
|
+
# if @tap and @tap.alive?
|
29
|
+
# @tap.kill
|
30
|
+
# @tap = nil
|
31
|
+
# super :double_tap
|
32
|
+
# else
|
33
|
+
# @tap = Thread.new { sleep 0.25; super :tap }
|
34
|
+
# end
|
35
|
+
#end
|
36
|
+
else super :long_tap_x2; @taped = true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Domotics::Core
|
2
|
+
class Dimmer < Element
|
3
|
+
|
4
|
+
DEFAULT_LEVEL = 0
|
5
|
+
MIN_LEVEL = 0
|
6
|
+
MAX_LEVEL = 255
|
7
|
+
MAX_STEPS = 128
|
8
|
+
STEP_DELAY = 1.0 / MAX_STEPS
|
9
|
+
STEP_SIZE = ((MAX_LEVEL + 1) / MAX_STEPS.to_f).round
|
10
|
+
|
11
|
+
def initialize(args = {})
|
12
|
+
@type = args[:type] || :dimmer
|
13
|
+
@fade_lock = Mutex.new
|
14
|
+
@fade_thread = nil
|
15
|
+
if args[:device_type]
|
16
|
+
eval_str = %(include Domotics::#{args[:device_type].capitalize}::PWMPin)
|
17
|
+
self.class.class_eval(eval_str, __FILE__, __LINE__)
|
18
|
+
end
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
def set_state(value = DEFAULT_LEVEL, opt = {})
|
23
|
+
unless opt[:kill_fader] == :no
|
24
|
+
@fade_lock.synchronize do
|
25
|
+
@fade_thread.kill if @fade_thread and @fade_thread.alive?
|
26
|
+
end
|
27
|
+
end
|
28
|
+
if value.is_a? Integer
|
29
|
+
value = MIN_LEVEL if value < MIN_LEVEL
|
30
|
+
value = MAX_LEVEL if value > MAX_LEVEL
|
31
|
+
end
|
32
|
+
super value
|
33
|
+
end
|
34
|
+
# Decrease brightness level (value 0-100%)
|
35
|
+
def dim(value = nil)
|
36
|
+
if value
|
37
|
+
set_state value * MAX_LEVEL / 100
|
38
|
+
else
|
39
|
+
set_state state - STEP_SIZE
|
40
|
+
end
|
41
|
+
end
|
42
|
+
# Increase brightness level (value 0-100%)
|
43
|
+
def bright(value = nil)
|
44
|
+
if value
|
45
|
+
set_state value * MAX_LEVEL / 100
|
46
|
+
else
|
47
|
+
set_state state + STEP_SIZE
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def off
|
52
|
+
set_state MIN_LEVEL unless state == MIN_LEVEL
|
53
|
+
end
|
54
|
+
|
55
|
+
def fade_to(value = DEFAULT_LEVEL, speed_divisor = 1)
|
56
|
+
@fade_lock.synchronize do
|
57
|
+
@fade_thread.kill if @fade_thread and @fade_thread.alive?
|
58
|
+
@fade_thread = Thread.new do
|
59
|
+
op = (value - state) >= 0 ? :+ : :-
|
60
|
+
steps = ((value - state).abs / STEP_SIZE.to_f).round
|
61
|
+
steps.times do
|
62
|
+
set_state(state.public_send(op, STEP_SIZE), kill_fader: :no)
|
63
|
+
sleep speed_divisor * STEP_DELAY
|
64
|
+
end
|
65
|
+
@fade_lock.synchronize { @fade_thread = nil }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
@fade_thread
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Domotics::Core
|
2
|
+
class MotionSensor < Element
|
3
|
+
def initialize(args = {})
|
4
|
+
@type = args[:type] || :motion_sensor
|
5
|
+
if args[:device_type]
|
6
|
+
eval_str = %(include Domotics::#{args[:device_type].capitalize}::DigitalSensor)
|
7
|
+
self.class.class_eval(eval_str, __FILE__, __LINE__)
|
8
|
+
end
|
9
|
+
super
|
10
|
+
end
|
11
|
+
#def to_hls(state)
|
12
|
+
# super == :on ? :move : :no_move
|
13
|
+
#end
|
14
|
+
def set_state(*args)
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Domotics::Core
|
2
|
+
class ReedSwitch < Element
|
3
|
+
def initialize(args = {})
|
4
|
+
@type = args[:type] || :reed_switch
|
5
|
+
if args[:device_type]
|
6
|
+
eval_str = %(include Domotics::#{args[:device_type].capitalize}::NCSensor)
|
7
|
+
self.class.class_eval(eval_str, __FILE__, __LINE__)
|
8
|
+
end
|
9
|
+
super
|
10
|
+
end
|
11
|
+
#def to_hls(state)
|
12
|
+
# super == :on ? :open : :close
|
13
|
+
#end
|
14
|
+
def set_state(*args)
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Domotics::Core
|
2
|
+
class RgbStrip < Element
|
3
|
+
def initialize(args = {})
|
4
|
+
@type = args[:type] || :rgb_strip
|
5
|
+
@strips = Hash.new
|
6
|
+
@crazy_lock = Mutex.new
|
7
|
+
@crazy_thread = nil
|
8
|
+
super
|
9
|
+
sub_args = args.dup
|
10
|
+
%w(r g b).each do |x|
|
11
|
+
sub_args[:name] = (args[:name].to_s+"_#{x}_strip").to_sym
|
12
|
+
sub_args[:pin] = args[x.to_sym]
|
13
|
+
@strips[x.to_sym] = Dimmer.new(sub_args)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def red
|
18
|
+
@strips[:r]
|
19
|
+
end
|
20
|
+
def green
|
21
|
+
@strips[:g]
|
22
|
+
end
|
23
|
+
def blue
|
24
|
+
@strips[:b]
|
25
|
+
end
|
26
|
+
|
27
|
+
def off
|
28
|
+
kill_crazy
|
29
|
+
@strips.values.each { |strip| strip.off } if on?
|
30
|
+
set_state :off
|
31
|
+
end
|
32
|
+
|
33
|
+
def color
|
34
|
+
@strips.values.map { |strip| strip.state }
|
35
|
+
end
|
36
|
+
|
37
|
+
def on?
|
38
|
+
color.reduce(:+) != 0
|
39
|
+
end
|
40
|
+
|
41
|
+
def on
|
42
|
+
set_color 255, 255, 255
|
43
|
+
end
|
44
|
+
|
45
|
+
def set_color(*args)
|
46
|
+
kill_crazy
|
47
|
+
args=args[0] if args.size == 1 and args[0].is_a? Array
|
48
|
+
if args.size == 3
|
49
|
+
@strips[:r].fade_to args[0]
|
50
|
+
@strips[:g].fade_to args[1]
|
51
|
+
@strips[:b].fade_to args[2]
|
52
|
+
set_state args.reduce(:+) == 0 ? :off : :on
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def set_power(value=50)
|
57
|
+
return unless value.is_a? Integer
|
58
|
+
value=100 if value>100
|
59
|
+
value=0 if value<0
|
60
|
+
if state == :on
|
61
|
+
set_color color.map { |c| c * Dimmer::MAX_LEVEL * value / color.max / 100 }
|
62
|
+
else
|
63
|
+
set_color 3.times.map { Dimmer::MAX_LEVEL * value / 100 }
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def random
|
68
|
+
set_color 3.times.map { rand Dimmer::MAX_LEVEL }
|
69
|
+
end
|
70
|
+
|
71
|
+
def crazy
|
72
|
+
@crazy_lock.synchronize do
|
73
|
+
@crazy_thread.kill if @crazy_thread
|
74
|
+
@crazy_thread = Thread.new do
|
75
|
+
loop do
|
76
|
+
@fade_threads = @strips.values.map { |strip| strip.fade_to(rand(Dimmer::MAX_LEVEL), 1) }
|
77
|
+
@fade_threads.each { |thread| thread.join }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
set_state :on
|
82
|
+
end
|
83
|
+
|
84
|
+
def kill_crazy
|
85
|
+
@crazy_lock.synchronize do
|
86
|
+
if @crazy_thread
|
87
|
+
@crazy_thread.kill
|
88
|
+
@crazy_thread = nil
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Domotics::Core
|
2
|
+
class Switch < Element
|
3
|
+
MINIMUM_LAG = 1
|
4
|
+
def initialize(args = {})
|
5
|
+
@type = args[:type] || :switch
|
6
|
+
@lag = nil
|
7
|
+
@lag_lock = Mutex.new
|
8
|
+
if args[:device_type]
|
9
|
+
eval_str = %(include Domotics::#{args[:device_type].capitalize}::DigitalPin)
|
10
|
+
self.class.class_eval(eval_str, __FILE__, __LINE__)
|
11
|
+
end
|
12
|
+
@initialized = false
|
13
|
+
super
|
14
|
+
@initialized = true
|
15
|
+
end
|
16
|
+
def set_state(value)
|
17
|
+
@initialized ? (super unless state == value) : super
|
18
|
+
end
|
19
|
+
def on(timer = nil)
|
20
|
+
set_state :on
|
21
|
+
lag(:off, timer)
|
22
|
+
end
|
23
|
+
def on?
|
24
|
+
state == :on
|
25
|
+
end
|
26
|
+
def delay_on(timer)
|
27
|
+
lag(:on, timer)
|
28
|
+
end
|
29
|
+
def off(timer = nil)
|
30
|
+
set_state :off
|
31
|
+
lag(:on, timer)
|
32
|
+
end
|
33
|
+
def off?
|
34
|
+
state == :off
|
35
|
+
end
|
36
|
+
def delay_off(timer)
|
37
|
+
lag(:off, timer)
|
38
|
+
end
|
39
|
+
def toggle(timer = nil)
|
40
|
+
set_state state == :off ? :on : :off
|
41
|
+
lag(:toggle, timer)
|
42
|
+
end
|
43
|
+
def delay_toggle(timer)
|
44
|
+
lag(:toggle, timer)
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def lag(action = nil, timer = nil)
|
50
|
+
# Kill previous action -> out of date
|
51
|
+
@lag_lock.synchronize do
|
52
|
+
if @lag and @lag.alive?
|
53
|
+
@lag.kill
|
54
|
+
@lag = nil
|
55
|
+
end
|
56
|
+
raise ArgumentError unless (timer.is_a?(Integer) and timer >= MINIMUM_LAG)
|
57
|
+
# Delayed action
|
58
|
+
@lag = Thread.new do
|
59
|
+
sleep timer
|
60
|
+
public_send action
|
61
|
+
end
|
62
|
+
end
|
63
|
+
rescue ArgumentError
|
64
|
+
nil
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Domotics::Core
|
2
|
+
class ElementGroup < BasicObject
|
3
|
+
attr_reader :name, :type, :room, :elements
|
4
|
+
def initialize(args = {})
|
5
|
+
#::Object.instance_method(:is_a?).bind(self)
|
6
|
+
@name = args[:name] || :undefined
|
7
|
+
@room = Room[args[:room]]
|
8
|
+
@room.register_element self, @name
|
9
|
+
@elements = []
|
10
|
+
@type = :group
|
11
|
+
end
|
12
|
+
def add_element(element)
|
13
|
+
@elements << element
|
14
|
+
end
|
15
|
+
def verbose_state
|
16
|
+
{ @room.name =>
|
17
|
+
{ :elements =>
|
18
|
+
{ @name =>
|
19
|
+
{ :state => nil }
|
20
|
+
}
|
21
|
+
}
|
22
|
+
}
|
23
|
+
end
|
24
|
+
def method_missing(method, *args, &block)
|
25
|
+
if @elements.map{ |el| el.respond_to? method }.reduce{ |res, n| res && n }
|
26
|
+
@elements.map{ |el| el.public_send method, *args, &block }.reduce{ |res, n| res && n }
|
27
|
+
else
|
28
|
+
super
|
29
|
+
end
|
30
|
+
end
|
31
|
+
def respond_to?(method)
|
32
|
+
@elements.map{ |el| el.respond_to? method }.reduce{ |res, n| res && n } || super
|
33
|
+
end
|
34
|
+
def to_s
|
35
|
+
"Group :#{@name} -> #{@elements}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# Debug - Show exception in threads
|
2
|
+
Thread.class_eval do
|
3
|
+
alias_method :initialize_without_exception_show, :initialize
|
4
|
+
def initialize(*args, &block)
|
5
|
+
initialize_without_exception_show(*args) do
|
6
|
+
begin
|
7
|
+
block.call
|
8
|
+
rescue Exception => e
|
9
|
+
$logger.error { e.message }
|
10
|
+
$logger.debug { e.inspect }
|
11
|
+
raise e
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class String
|
18
|
+
# Return integer (if can convert) or symbol
|
19
|
+
def to_isym
|
20
|
+
begin
|
21
|
+
Integer(self)
|
22
|
+
rescue ArgumentError
|
23
|
+
self.to_sym
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
module Domotics::Core
|
29
|
+
# Suppress no method errors
|
30
|
+
class BlackHole
|
31
|
+
def method_missing(*args)
|
32
|
+
self
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module Domotics::Core
|
38
|
+
class TestRoom < Room
|
39
|
+
def initialize(args = {})
|
40
|
+
super
|
41
|
+
@events = {}
|
42
|
+
end
|
43
|
+
def event_handler(msg = {})
|
44
|
+
event, element = msg[:event], msg[:element]
|
45
|
+
if element
|
46
|
+
@events[element.name] ||= []
|
47
|
+
@events[element.name].push event => element.state
|
48
|
+
end
|
49
|
+
super
|
50
|
+
end
|
51
|
+
def last_event(element_name)
|
52
|
+
@events[element_name].pop if @events[element_name].respond_to? :pop
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
module Domotics::Core
|
58
|
+
class TestHelper
|
59
|
+
def self.init
|
60
|
+
$emul = Domotics::Arduino::BoardEmulator.new
|
61
|
+
Domotics::Core.add_map type: :room, class_name: "TestRoom"
|
62
|
+
Domotics::Core::Setup.new IO.read File.expand_path("../../../test/config.test.rb", File.dirname(__FILE__))
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class Object
|
68
|
+
def eigenclass
|
69
|
+
class << self
|
70
|
+
self
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Domotics::Core
|
2
|
+
class Room
|
3
|
+
# All rooms
|
4
|
+
@@rooms = Hash.new
|
5
|
+
attr_reader :name, :type, :elements
|
6
|
+
def initialize(args = {})
|
7
|
+
@logger = args[:logger] || Logger.new(STDERR)
|
8
|
+
# Save self
|
9
|
+
@@rooms[@name = args[:name]] = self
|
10
|
+
@type = args[:type]
|
11
|
+
# Hash of elements
|
12
|
+
@elements = {}
|
13
|
+
class << @elements
|
14
|
+
def light
|
15
|
+
select { |name, element| (element.is_a? Element) and (element.type == :switch) and (name =~ /light/) }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
# New queue thread
|
19
|
+
@room_queue = Queue.new
|
20
|
+
@queue_thread = Thread.new { loop { event_handler @room_queue.pop } }
|
21
|
+
end
|
22
|
+
# Register element
|
23
|
+
def register_element(element, name)
|
24
|
+
@elements[name] = element
|
25
|
+
# define accessor method (singleton)
|
26
|
+
instance_eval(%(def #{name}; @elements[:#{name}]; end;), __FILE__, __LINE__) unless respond_to? name
|
27
|
+
end
|
28
|
+
# Return state of all elements
|
29
|
+
def verbose_state
|
30
|
+
{ @name =>
|
31
|
+
{ :elements =>
|
32
|
+
@elements.inject(Hash.new) { |hash, element| hash.merge element[1].verbose_state[@name][:elements] },
|
33
|
+
:state => state,
|
34
|
+
:info => (info if respond_to? :info)
|
35
|
+
}
|
36
|
+
}
|
37
|
+
end
|
38
|
+
def state
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
# Perform action with light
|
42
|
+
def light(action = :toggle)
|
43
|
+
case action
|
44
|
+
when :on, :off
|
45
|
+
@elements.light.values.each { |element| element.public_send(action) if element.respond_to? action }
|
46
|
+
when :toggle
|
47
|
+
light_off? ? light(:on) : light(:off)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
def light_off?
|
51
|
+
@elements.light.values.reduce(true) { |res, el| res && el.off? }
|
52
|
+
end
|
53
|
+
# Method for pushing into queue
|
54
|
+
def notify(msg)
|
55
|
+
@room_queue.push(msg)
|
56
|
+
end
|
57
|
+
# Default - simple prints event
|
58
|
+
def event_handler(msg = {})
|
59
|
+
event, element = msg[:event], msg[:element]
|
60
|
+
@logger.info { "Event message :#{event} from #{element} with state [#{element.state}]" }
|
61
|
+
end
|
62
|
+
|
63
|
+
def destroy
|
64
|
+
@queue_thread.exit
|
65
|
+
end
|
66
|
+
|
67
|
+
# Return element object
|
68
|
+
def [](symbol = nil)
|
69
|
+
return @elements[symbol] if symbol
|
70
|
+
@elements
|
71
|
+
end
|
72
|
+
# Return requested room like element of array
|
73
|
+
def self.[](symbol = nil)
|
74
|
+
return @@rooms[symbol] if symbol
|
75
|
+
@@rooms
|
76
|
+
end
|
77
|
+
# Return requested room like variable
|
78
|
+
def method_missing(symbol, *args)
|
79
|
+
super unless args.size == 0
|
80
|
+
@@rooms[symbol] || BlackHole.new
|
81
|
+
end
|
82
|
+
def to_s
|
83
|
+
"Room[#{@name}](id:#{__id__})"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Domotics::Core
|
2
|
+
class Server
|
3
|
+
def initialize(args = {})
|
4
|
+
@logger = $logger || Logger.new(STDERR)
|
5
|
+
end
|
6
|
+
def call(env)
|
7
|
+
# [object]/[action]/[params]
|
8
|
+
request = env['PATH_INFO'][1..-1].split('/')
|
9
|
+
object = request.shift
|
10
|
+
return invalid 'room' unless object and object = Room[object.to_sym]
|
11
|
+
return invalid 'element or action' unless object_action = request.shift
|
12
|
+
if sub_object = object[object_action.to_isym]
|
13
|
+
room, object = object, sub_object
|
14
|
+
action = request.shift
|
15
|
+
else
|
16
|
+
room = object
|
17
|
+
action = object_action
|
18
|
+
end
|
19
|
+
return invalid 'action' unless action and object.respond_to? action
|
20
|
+
begin
|
21
|
+
object.public_send(action, *request.map { |param| param.to_isym })
|
22
|
+
rescue Exception => e
|
23
|
+
@logger.error { e.message }
|
24
|
+
@logger.debug { e }
|
25
|
+
return invalid 'request'
|
26
|
+
end
|
27
|
+
return ok object.verbose_state.to_json
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def invalid(param)
|
33
|
+
[400, {"Content-Type" => "text/html"}, ["Processing error: invalid #{param}."]]
|
34
|
+
end
|
35
|
+
def ok(param)
|
36
|
+
[200, {"Content-Type" => "text/html"}, [param]]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
module Domotics::Core
|
3
|
+
CLASS_MAP[:group] = :element_group
|
4
|
+
class Setup < BasicObject
|
5
|
+
@@logger = ::Logger.new(::STDERR)
|
6
|
+
@@logger.level = ::Logger::FATAL
|
7
|
+
$logger = @@logger
|
8
|
+
def self.logger
|
9
|
+
@@logger
|
10
|
+
end
|
11
|
+
def self.logger=(logger)
|
12
|
+
@@logger = logger
|
13
|
+
$logger = @@logger
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(conf)
|
17
|
+
@current_room = {}
|
18
|
+
@current_device = {}
|
19
|
+
@groups = []
|
20
|
+
instance_eval conf, __FILE__, __LINE__
|
21
|
+
end
|
22
|
+
|
23
|
+
def element_group(args = {})
|
24
|
+
raise "Element group must have room" unless @current_room.any?
|
25
|
+
args[:room] = @current_room[:name]
|
26
|
+
unless gr = Room[@current_room[:name]][args[:name]]
|
27
|
+
gr = ElementGroup.new args
|
28
|
+
@groups[-1].add_element gr if @groups[-1]
|
29
|
+
end
|
30
|
+
@groups.push(gr)
|
31
|
+
yield if ::Kernel.block_given?
|
32
|
+
@groups.pop
|
33
|
+
end
|
34
|
+
|
35
|
+
def room(klass, args = {})
|
36
|
+
@current_room[:name] = args[:name]
|
37
|
+
@current_room[:type] = args[:type]
|
38
|
+
klass.new(args) unless Room[args[:name]]
|
39
|
+
yield if ::Kernel.block_given?
|
40
|
+
@current_room.clear
|
41
|
+
end
|
42
|
+
|
43
|
+
def device(klass, args = {})
|
44
|
+
@current_device[:name] = args[:name]
|
45
|
+
@current_device[:type] = args[:type]
|
46
|
+
klass.new(args) unless Device[args[:name]]
|
47
|
+
yield if ::Kernel.block_given?
|
48
|
+
@current_device.clear
|
49
|
+
end
|
50
|
+
|
51
|
+
def element(klass, args = {})
|
52
|
+
raise "Element must have room" unless @current_room.any?
|
53
|
+
args[:room] = Room[@current_room[:name]]
|
54
|
+
args[:room_type] = @current_room[:type]
|
55
|
+
args[:device] = Device[@current_device[:name]]
|
56
|
+
args[:device_type] = @current_device[:type]
|
57
|
+
klass = klass.dup if args[:device_type]
|
58
|
+
el = klass.new(args) unless Room[@current_room[:name]][args[:name]]
|
59
|
+
@groups[-1].add_element el if @groups[-1]
|
60
|
+
end
|
61
|
+
|
62
|
+
def method_missing(symbol, *args, &block)
|
63
|
+
if CLASS_MAP[symbol] and name = args.shift
|
64
|
+
args_hash = args.shift || {}
|
65
|
+
args_hash[:name] = name
|
66
|
+
args_hash[:type] = symbol if CLASS_MAP[symbol][0] != :element
|
67
|
+
args_hash[:logger] = @@logger
|
68
|
+
__send__(*CLASS_MAP[symbol], args_hash, &block)
|
69
|
+
else
|
70
|
+
super
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/test/config.test.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
test_room :test do
|
2
|
+
button :button_no_dev
|
3
|
+
dimmer :dimmer_no_dev
|
4
|
+
motion_sensor :ms_no_dev
|
5
|
+
reed_switch :rs_no_dev
|
6
|
+
rgb_strip :rgb_no_dev
|
7
|
+
switch :light_no_dev
|
8
|
+
arduino :nano, board: :nano, port: $emul.port do
|
9
|
+
button :button, pin: 6
|
10
|
+
dimmer :dimmer, pin: 3
|
11
|
+
motion_sensor :ms, pin: 7
|
12
|
+
reed_switch :rs, pin: 8
|
13
|
+
rgb_strip :rgb, r: 9, g: 10, b: 11
|
14
|
+
switch :light_1, pin: 13
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
ENV['RACK_ENV'] = 'test'
|
2
|
+
|
3
|
+
require "test/unit"
|
4
|
+
require "domotics/core"
|
5
|
+
|
6
|
+
class DomoticsElementsTestCase < Test::Unit::TestCase
|
7
|
+
def test_dimmer
|
8
|
+
dimmer = Domotics::Core::Room[:test].dimmer
|
9
|
+
# Should turn on max and convert state to int
|
10
|
+
dimmer.set_state :on
|
11
|
+
assert_equal 255, dimmer.state
|
12
|
+
# Should turn off and convert state to int
|
13
|
+
dimmer.set_state :off
|
14
|
+
assert_equal 0, dimmer.state
|
15
|
+
# Dim
|
16
|
+
[0,3,24,127,237,255].each do |val|
|
17
|
+
dimmer.set_state val
|
18
|
+
assert_equal val, dimmer.state
|
19
|
+
end
|
20
|
+
# Off
|
21
|
+
dimmer.off
|
22
|
+
assert_equal 0, dimmer.state
|
23
|
+
# Fade to
|
24
|
+
dimmer.fade_to 255
|
25
|
+
sleep 1.6
|
26
|
+
assert_equal 255, dimmer.state
|
27
|
+
dimmer.fade_to 127
|
28
|
+
sleep 0.8
|
29
|
+
assert_equal 127, dimmer.state
|
30
|
+
dimmer.fade_to 0
|
31
|
+
sleep 0.8
|
32
|
+
assert_equal 0, dimmer.state
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_rgb_strip
|
36
|
+
rgb = Domotics::Core::Room[:test].rgb
|
37
|
+
rgb.on
|
38
|
+
sleep 1.6
|
39
|
+
assert_equal 255, rgb.red.state
|
40
|
+
rgb.off
|
41
|
+
assert_equal 0, rgb.red.state
|
42
|
+
assert_equal :dimmer, rgb.red.type
|
43
|
+
assert_equal :dimmer, rgb.green.type
|
44
|
+
assert_equal :dimmer, rgb.blue.type
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_button
|
48
|
+
room = Domotics::Core::Room[:test]
|
49
|
+
btn = room.button
|
50
|
+
|
51
|
+
$emul.set_internal_state 6, 1
|
52
|
+
$emul.toggle_pin 6
|
53
|
+
sleep 0.1
|
54
|
+
$emul.toggle_pin 6
|
55
|
+
sleep 0.05
|
56
|
+
assert_equal room.last_event(btn.name), :state_changed => :tap
|
57
|
+
$emul.toggle_pin 6
|
58
|
+
sleep 0.6
|
59
|
+
$emul.toggle_pin 6
|
60
|
+
sleep 0.01
|
61
|
+
assert_equal room.last_event(btn.name), :state_changed => :long_tap
|
62
|
+
end
|
63
|
+
end
|
data/test/test_rooms.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
ENV['RACK_ENV'] = 'test'
|
2
|
+
|
3
|
+
require "test/unit"
|
4
|
+
require "domotics/core"
|
5
|
+
|
6
|
+
class DomoticsRoomsTestCase < Test::Unit::TestCase
|
7
|
+
def test_room
|
8
|
+
tr = Domotics::Core::Room.new name: :tr
|
9
|
+
assert_raise NoMethodError do
|
10
|
+
tr.instance_eval { no_method :arg1 }
|
11
|
+
end
|
12
|
+
assert_nothing_raised do
|
13
|
+
tr.instance_eval { nothing.off }
|
14
|
+
tr.instance_eval { nothing.light :off }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/test/test_server.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
#ENV['RACK_ENV'] = 'test'
|
2
|
+
|
3
|
+
require "domotics/core"
|
4
|
+
require 'test/unit'
|
5
|
+
require 'rack/test'
|
6
|
+
|
7
|
+
class DomoticsTest < Test::Unit::TestCase
|
8
|
+
include Rack::Test::Methods
|
9
|
+
|
10
|
+
def app
|
11
|
+
Domotics::Core::Server.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_valid_object
|
15
|
+
get '/to_s'
|
16
|
+
assert last_response.bad_request?
|
17
|
+
get '/test/to_s'
|
18
|
+
assert last_response.ok?
|
19
|
+
get '/test/light_1/to_s'
|
20
|
+
assert last_response.ok?
|
21
|
+
get '/invalid_object/to_s'
|
22
|
+
assert last_response.bad_request?
|
23
|
+
get '/test/invalid_object/to_s'
|
24
|
+
assert last_response.bad_request?
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_query_action
|
28
|
+
get '/test/light_1/state'
|
29
|
+
assert last_response.ok?
|
30
|
+
get '/test/light_1/abracadabra'
|
31
|
+
assert last_response.bad_request?
|
32
|
+
get '/test/light_1/state/abracadabra'
|
33
|
+
assert last_response.bad_request?
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_switch_element
|
37
|
+
get '/test/light_1/on'
|
38
|
+
assert last_response.ok?
|
39
|
+
get '/test/light_1/delay_off/1'
|
40
|
+
assert last_response.ok?
|
41
|
+
sleep 1.2
|
42
|
+
get '/test/light_1/delay_on/1'
|
43
|
+
assert last_response.ok?
|
44
|
+
sleep 1.2
|
45
|
+
3.times do
|
46
|
+
sleep 1
|
47
|
+
get '/test/light_1/toggle'
|
48
|
+
assert last_response.ok?
|
49
|
+
end
|
50
|
+
get '/test/light_1/delay_toggle/1'
|
51
|
+
assert last_response.ok?
|
52
|
+
sleep 2
|
53
|
+
get '/test/light_1/off'
|
54
|
+
assert last_response.ok?
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: domotics-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- goredar
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-03-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,7 +52,29 @@ files:
|
|
52
52
|
- Rakefile
|
53
53
|
- domotics-core.gemspec
|
54
54
|
- lib/domotics/core.rb
|
55
|
+
- lib/domotics/core/data/data_hash.rb
|
56
|
+
- lib/domotics/core/data/data_mongo.rb
|
57
|
+
- lib/domotics/core/data/data_redis.rb
|
58
|
+
- lib/domotics/core/device.rb
|
59
|
+
- lib/domotics/core/device/arduino_board.rb
|
60
|
+
- lib/domotics/core/element.rb
|
61
|
+
- lib/domotics/core/element/button.rb
|
62
|
+
- lib/domotics/core/element/dimmer.rb
|
63
|
+
- lib/domotics/core/element/motion_sensor.rb
|
64
|
+
- lib/domotics/core/element/reed_switch.rb
|
65
|
+
- lib/domotics/core/element/rgb_strip.rb
|
66
|
+
- lib/domotics/core/element/switch.rb
|
67
|
+
- lib/domotics/core/element_group.rb
|
68
|
+
- lib/domotics/core/helper.rb
|
69
|
+
- lib/domotics/core/room.rb
|
70
|
+
- lib/domotics/core/server.rb
|
71
|
+
- lib/domotics/core/setup.rb
|
55
72
|
- lib/domotics/core/version.rb
|
73
|
+
- test/config.test.rb
|
74
|
+
- test/test_devices.rb
|
75
|
+
- test/test_elements.rb
|
76
|
+
- test/test_rooms.rb
|
77
|
+
- test/test_server.rb
|
56
78
|
homepage: https://goredar.it
|
57
79
|
licenses:
|
58
80
|
- MIT
|
@@ -73,8 +95,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
73
95
|
version: '0'
|
74
96
|
requirements: []
|
75
97
|
rubyforge_project:
|
76
|
-
rubygems_version: 2.2.
|
98
|
+
rubygems_version: 2.2.2
|
77
99
|
signing_key:
|
78
100
|
specification_version: 4
|
79
101
|
summary: Home automation system.
|
80
|
-
test_files:
|
102
|
+
test_files:
|
103
|
+
- test/config.test.rb
|
104
|
+
- test/test_devices.rb
|
105
|
+
- test/test_elements.rb
|
106
|
+
- test/test_rooms.rb
|
107
|
+
- test/test_server.rb
|