saal 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +460 -0
- data/README.rdoc +76 -0
- data/Rakefile +160 -0
- data/TODO +24 -0
- data/bin/.gitignore +2 -0
- data/bin/dinrelayset +35 -0
- data/bin/dinrelaystatus +32 -0
- data/bin/saal_chart +110 -0
- data/bin/saal_daemon +22 -0
- data/bin/saal_dump_database +11 -0
- data/bin/saal_import_mysql +18 -0
- data/bin/saal_readall +10 -0
- data/lib/chart_data.rb +30 -0
- data/lib/daemon.rb +63 -0
- data/lib/dbstore.rb +86 -0
- data/lib/dinrelay.rb +67 -0
- data/lib/outliercache.rb +53 -0
- data/lib/owsensor.rb +21 -0
- data/lib/saal.rb +23 -0
- data/lib/sensor.rb +100 -0
- data/lib/sensors.rb +48 -0
- data/saal.gemspec +77 -0
- data/test/chart_data_test.rb +39 -0
- data/test/daemon_test.rb +44 -0
- data/test/dbstore_test.rb +70 -0
- data/test/dinrelay.html.erb +143 -0
- data/test/dinrelay_test.rb +112 -0
- data/test/nonexistant_sensor.yml +5 -0
- data/test/outliercache_test.rb +42 -0
- data/test/sensor_test.rb +109 -0
- data/test/sensors_test.rb +77 -0
- data/test/test_db.yml +4 -0
- data/test/test_dinrelay_sensors.yml +16 -0
- data/test/test_helper.rb +37 -0
- data/test/test_sensor_cleanups.yml +21 -0
- data/test/test_sensors.yml +10 -0
- metadata +166 -0
@@ -0,0 +1,112 @@
|
|
1
|
+
require File.dirname(__FILE__)+'/test_helper.rb'
|
2
|
+
require 'webrick'
|
3
|
+
#require 'webrick/accesslog'
|
4
|
+
|
5
|
+
class TestDINRelay < Test::Unit::TestCase
|
6
|
+
SERVICE_OPTS = {:host => 'localhost', :port => 33333,
|
7
|
+
:user => "someuser", :pass =>"somepass"}
|
8
|
+
|
9
|
+
class BasicServing < WEBrick::HTTPServlet::AbstractServlet
|
10
|
+
def self.get_instance(config, opts)
|
11
|
+
new(opts)
|
12
|
+
end
|
13
|
+
def initialize(opts)
|
14
|
+
@html = opts[:html]
|
15
|
+
@user = opts[:user]
|
16
|
+
@pass = opts[:pass]
|
17
|
+
@feedback = opts[:feedback] || {}
|
18
|
+
end
|
19
|
+
def do_GET(req, res)
|
20
|
+
@feedback[:uri] = req.request_uri.to_s
|
21
|
+
WEBrick::HTTPAuth.basic_auth(req, res, "My Realm") {|user, pass|
|
22
|
+
user == @user && pass == @pass
|
23
|
+
}
|
24
|
+
res.body = @html
|
25
|
+
res['Content-Type'] = "text/xml"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def with_webrick(opts)
|
30
|
+
opts = SERVICE_OPTS.merge(opts)
|
31
|
+
|
32
|
+
Socket.do_not_reverse_lookup = true # Speed up startup
|
33
|
+
log = WEBrick::Log.new($stderr, WEBrick::Log::ERROR)
|
34
|
+
access_log = [[log, WEBrick::AccessLog::COMBINED_LOG_FORMAT]]
|
35
|
+
s = WEBrick::HTTPServer.new(:Port => opts[:port],
|
36
|
+
:Logger => log,
|
37
|
+
:AccessLog => access_log)
|
38
|
+
s.mount('/', BasicServing, opts.merge(:feedback => (f = {})))
|
39
|
+
|
40
|
+
thread = Thread.new do
|
41
|
+
s.start
|
42
|
+
end
|
43
|
+
while s.status != :Running; sleep 0.1; end # Make sure the server is up
|
44
|
+
yield f
|
45
|
+
s.shutdown
|
46
|
+
thread.exit
|
47
|
+
end
|
48
|
+
|
49
|
+
def create_index_html(hash)
|
50
|
+
outlets = hash
|
51
|
+
erb = ERB.new(File.open(File.dirname(__FILE__)+'/dinrelay.html.erb').read)
|
52
|
+
erb.result(binding)
|
53
|
+
end
|
54
|
+
|
55
|
+
def setup
|
56
|
+
@og=SAAL::DINRelay::OutletGroup.new(SERVICE_OPTS)
|
57
|
+
@vals={1=>"OFF",2=>"OFF",3=>"ON",4=>"OFF",5=>"ON",6=>"ON",7=>"ON",8=>"OFF"}
|
58
|
+
@rvals={1=>"ON",2=>"ON",3=>"OFF",4=>"ON",5=>"OFF",6=>"OFF",7=>"OFF",8=>"ON"}
|
59
|
+
end
|
60
|
+
|
61
|
+
def assert_path(path, uri)
|
62
|
+
assert_equal "http://localhost:#{SERVICE_OPTS[:port]}"+path, uri
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_read_state
|
66
|
+
with_webrick(:html=>create_index_html(@vals)) do |feedback|
|
67
|
+
@vals.each do |num, state|
|
68
|
+
assert_equal state, @og.state(num)
|
69
|
+
assert_path '/index.htm', feedback[:uri]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_set_state
|
75
|
+
with_webrick(:html=>create_index_html(@rvals)) do |feedback|
|
76
|
+
@vals.each do |num, state|
|
77
|
+
newstate = state == "ON" ? "OFF" : "ON"
|
78
|
+
assert @og.set_state(num,newstate), "State change not working"
|
79
|
+
assert_path "/outlet?#{num}=#{newstate}", feedback[:uri]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_enumerate_sensors
|
85
|
+
sensors = SAAL::Sensors.new(TEST_SENSORS_DINRELAY_FILE, TEST_DBCONF)
|
86
|
+
assert_equal((1..8).map{|i| "name#{i}"}, sensors.map{|s| s.name}.sort)
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_read_sensors
|
90
|
+
sensors = SAAL::Sensors.new(TEST_SENSORS_DINRELAY_FILE, TEST_DBCONF)
|
91
|
+
with_webrick(:html=>create_index_html(@vals)) do |feedback|
|
92
|
+
@vals.each do |num, state|
|
93
|
+
value = state == "ON" ? 1.0 : 0.0
|
94
|
+
assert_equal value, sensors.send('name'+num.to_s).read
|
95
|
+
assert_path '/index.htm', feedback[:uri]
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_set_sensors
|
101
|
+
sensors = SAAL::Sensors.new(TEST_SENSORS_DINRELAY_FILE, TEST_DBCONF)
|
102
|
+
with_webrick(:html=>create_index_html(@rvals)) do |feedback|
|
103
|
+
@vals.each do |num, state|
|
104
|
+
newval = state == "ON" ? 0.0 : 1.0
|
105
|
+
newstate = state == "ON" ? "OFF" : "ON"
|
106
|
+
assert_equal newval, sensors.send('name'+num.to_s).write(newval),
|
107
|
+
"State change not working"
|
108
|
+
assert_path "/outlet?#{num}=#{newstate}", feedback[:uri]
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require File.dirname(__FILE__)+'/test_helper.rb'
|
2
|
+
|
3
|
+
class TestOutlierCache < Test::Unit::TestCase
|
4
|
+
def test_clean_setup
|
5
|
+
cache = SAAL::OutlierCache.new
|
6
|
+
assert !cache.live, "Live empty cache"
|
7
|
+
20.times {cache.validate(10)}
|
8
|
+
assert cache.live, "Not Live full cache"
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_failed_dirty_setup
|
12
|
+
cache = SAAL::OutlierCache.new
|
13
|
+
assert !cache.live, "Live empty cache"
|
14
|
+
(1..20).each {|i| cache.validate(i)}
|
15
|
+
assert !cache.live, "Live cache with dirty results"
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_working_dirty_setup
|
19
|
+
cache = SAAL::OutlierCache.new
|
20
|
+
assert !cache.live, "Live empty cache"
|
21
|
+
[1,1,1,2,1,1,1,1,1,1,1,1,1].each {|i| cache.validate(i)}
|
22
|
+
assert cache.live, "Not Live full cache"
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_validate
|
26
|
+
cache = SAAL::OutlierCache.new
|
27
|
+
20.times {cache.validate(10)}
|
28
|
+
assert cache.live, "Not Live full cache"
|
29
|
+
assert cache.validate(10), "Non validated good value"
|
30
|
+
assert !cache.validate(15), "Validated bad value"
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_setup_recover_from_discontinuity
|
34
|
+
cache = SAAL::OutlierCache.new
|
35
|
+
20.times {cache.validate(10)}
|
36
|
+
assert cache.live, "Not Live full cache"
|
37
|
+
20.times {cache.validate(15)}
|
38
|
+
assert cache.live, "Not Live full cache"
|
39
|
+
assert cache.validate(15), "Non validated good value"
|
40
|
+
assert !cache.validate(10), "Validated bad value"
|
41
|
+
end
|
42
|
+
end
|
data/test/sensor_test.rb
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
require File.dirname(__FILE__)+'/test_helper.rb'
|
2
|
+
|
3
|
+
class MockConnection
|
4
|
+
attr_accessor :value, :values
|
5
|
+
def initialize
|
6
|
+
@value = @values = nil
|
7
|
+
end
|
8
|
+
def read(serial)
|
9
|
+
@value ? @value : @values.shift
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class MockDBStore
|
14
|
+
attr_accessor :value
|
15
|
+
def average(sensor, from, to)
|
16
|
+
@value
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class TestSensor < Test::Unit::TestCase
|
21
|
+
def fake_sensor(name, opts={})
|
22
|
+
SAAL::Sensors.sensors_from_defs(@dbstore, name, @defs[name],
|
23
|
+
opts.merge(:owconn => @conn))[0]
|
24
|
+
end
|
25
|
+
|
26
|
+
def setup
|
27
|
+
@defs = YAML::load File.new(TEST_SENSOR_CLEANUPS_FILE)
|
28
|
+
@conn = MockConnection.new
|
29
|
+
@dbstore = MockDBStore.new
|
30
|
+
@fake = fake_sensor('fake', :no_outliercache => true)
|
31
|
+
@fake2 = fake_sensor('fake2', :no_outliercache => true)
|
32
|
+
@fake3 = fake_sensor('fake3')
|
33
|
+
@max_value = @defs['fake2']['max_value']
|
34
|
+
@max_correctable = @defs['fake2']['max_correctable']
|
35
|
+
@min_value = @defs['fake2']['min_value']
|
36
|
+
@min_correctable = @defs['fake2']['min_correctable']
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_read_too_high_values
|
40
|
+
@conn.value = @max_value+1
|
41
|
+
assert_nil @fake.read
|
42
|
+
assert_nil @fake.read_uncached
|
43
|
+
@conn.value = @max_value
|
44
|
+
assert_equal @max_value, @fake.read
|
45
|
+
assert_equal @max_value, @fake.read_uncached
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_read_too_high_but_correctable_values
|
49
|
+
@conn.value = @max_correctable
|
50
|
+
assert_equal @max_value, @fake2.read
|
51
|
+
assert_equal @max_value, @fake2.read_uncached
|
52
|
+
@conn.value = @max_correctable+1
|
53
|
+
assert_nil @fake2.read
|
54
|
+
assert_nil @fake2.read_uncached
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_read_too_low_values
|
58
|
+
@conn.value = @min_value-1
|
59
|
+
assert_nil @fake.read
|
60
|
+
assert_nil @fake.read_uncached
|
61
|
+
@conn.value = @min_value
|
62
|
+
assert_equal @min_value, @fake.read
|
63
|
+
assert_equal @min_value, @fake.read_uncached
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_read_too_low_but_correctable_values
|
67
|
+
@conn.value = @min_correctable
|
68
|
+
assert_equal @min_value, @fake2.read
|
69
|
+
assert_equal @min_value, @fake2.read_uncached
|
70
|
+
@conn.value = @min_correctable-1
|
71
|
+
assert_nil @fake2.read
|
72
|
+
assert_nil @fake2.read_uncached
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_read_without_limits
|
76
|
+
@conn.value = 200
|
77
|
+
assert_equal 200, @fake3.read
|
78
|
+
assert_equal 200, @fake3.read_uncached
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_eliminate_outliers
|
82
|
+
@conn.values = [200]*20 + [1000,200]
|
83
|
+
assert_equal [200]*21, (1..21).map{@fake3.read}
|
84
|
+
@conn.values = [200]*20 + [1000,200,1000,200]
|
85
|
+
assert_equal [200]*21, (1..21).map{@fake3.read_uncached}
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_eliminate_outliers_zeroes
|
89
|
+
@conn.values = [0]*20 + [1000,0]
|
90
|
+
assert_equal [0]*20+[1000], (1..21).map{@fake3.read}
|
91
|
+
@conn.values = [0]*20 + [1000,0]
|
92
|
+
assert_equal [0]*20+[1000], (1..21).map{@fake3.read_uncached}
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_mocked
|
96
|
+
@mockable = fake_sensor('fake3')
|
97
|
+
@conn.value = 1.0
|
98
|
+
assert_equal 1.0, @mockable.read
|
99
|
+
@mockable.mock_set(:value => 2.0)
|
100
|
+
assert_equal 2.0, @mockable.read
|
101
|
+
@mockable.write(3.0)
|
102
|
+
assert_equal 3.0, @mockable.read
|
103
|
+
@mockable.mock_set(:minimum => 1.0, :average => 2.0, :maximum => 3.0)
|
104
|
+
assert_equal 1.0, @mockable.minimum(0,100)
|
105
|
+
assert_equal 2.0, @mockable.average(0,100)
|
106
|
+
assert_equal 3.0, @mockable.maximum(0,100)
|
107
|
+
assert_equal 3.0, @mockable.read
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require File.dirname(__FILE__)+'/test_helper.rb'
|
2
|
+
|
3
|
+
class TestSensors < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@defs = YAML::load File.new(TEST_SENSORS_FILE)
|
6
|
+
@sensors = SAAL::Sensors.new(TEST_SENSORS_FILE, TEST_DBCONF)
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_get_sensor
|
10
|
+
@defs.each do |name, value|
|
11
|
+
s = @sensors.send name
|
12
|
+
assert_equal s.description, value['name']
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_read
|
17
|
+
with_fake_owserver do
|
18
|
+
assert_instance_of Float, @sensors.fake_temp.read
|
19
|
+
assert_nil @sensors.non_existant.read
|
20
|
+
assert_raise(NoMethodError) { @sensors.no_such_name.read }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_read_uncached
|
25
|
+
with_fake_owserver do
|
26
|
+
assert_instance_of Float, @sensors.fake_temp.read_uncached
|
27
|
+
assert_nil @sensors.non_existant.read_uncached
|
28
|
+
assert_raise(NoMethodError) { @sensors.no_such_name.read_uncached }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_each
|
33
|
+
expected = @defs.map{ |name, value| value['name']}
|
34
|
+
assert_equal expected, @sensors.map {|sensor| sensor.description}
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_writeable
|
38
|
+
dinsensors = SAAL::Sensors.new(TEST_SENSORS_DINRELAY_FILE, TEST_DBCONF)
|
39
|
+
dinsensors.each {|s| assert s.writeable?}
|
40
|
+
owsensors = SAAL::Sensors.new(TEST_SENSORS_FILE, TEST_DBCONF)
|
41
|
+
owsensors.each {|s| assert !s.writeable?}
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_average
|
45
|
+
db_setup
|
46
|
+
|
47
|
+
test_values = [[10, 7.323],[12, 5.432],[23, -2.125], [44, 0.123]]
|
48
|
+
test_average = (5.432 - 2.125)/2.0
|
49
|
+
test_values.each do |values|
|
50
|
+
@dbstore.write(:fake_temp, *values)
|
51
|
+
end
|
52
|
+
|
53
|
+
assert_instance_of Float, @sensors.fake_temp.average(11, 25)
|
54
|
+
assert_in_delta test_average, @sensors.fake_temp.average(11, 25), 0.001
|
55
|
+
assert_in_delta test_average, @sensors.fake_temp.average(12, 25), 0.001
|
56
|
+
assert_in_delta test_average, @sensors.fake_temp.average(11, 23), 0.001
|
57
|
+
|
58
|
+
# when there are no points it's nil
|
59
|
+
assert_nil @sensors.fake_temp.average(50, 60)
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_store_value
|
63
|
+
db_setup
|
64
|
+
|
65
|
+
with_fake_owserver do
|
66
|
+
@sensors.fake_temp.store_value
|
67
|
+
end
|
68
|
+
|
69
|
+
db_test_query("SELECT * FROM sensor_reads") do |res|
|
70
|
+
assert_equal 1, res.num_rows
|
71
|
+
row = res.fetch_row
|
72
|
+
assert_equal "fake_temp", row[0]
|
73
|
+
assert_in_delta Time.now.utc.to_i, row[1], 100
|
74
|
+
assert_instance_of Float, row[2].to_f
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/test/test_db.yml
ADDED
data/test/test_helper.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'yaml'
|
3
|
+
require 'fileutils'
|
4
|
+
require File.dirname(__FILE__)+'/../lib/saal.rb'
|
5
|
+
|
6
|
+
class Test::Unit::TestCase
|
7
|
+
TEST_SENSORS_FILE = File.dirname(__FILE__)+'/test_sensors.yml'
|
8
|
+
TEST_SENSORS_DINRELAY_FILE = File.dirname(__FILE__)+'/test_dinrelay_sensors.yml'
|
9
|
+
TEST_SENSOR_CLEANUPS_FILE = File.dirname(__FILE__)+'/test_sensor_cleanups.yml'
|
10
|
+
TEST_NONEXIST_SENSOR_FILE = File.dirname(__FILE__)+'/nonexistant_sensor.yml'
|
11
|
+
TEST_DBCONF = File.dirname(__FILE__)+'/test_db.yml'
|
12
|
+
TEST_DBOPTS = YAML::load(File.new(TEST_DBCONF))
|
13
|
+
|
14
|
+
def with_fake_owserver
|
15
|
+
pid = fork do
|
16
|
+
exec("owserver", "--fake", "1F,10", "--foreground")
|
17
|
+
end
|
18
|
+
sleep 1 # Potential timing bug when the system is under load
|
19
|
+
yield
|
20
|
+
Process.kill("KILL", pid)
|
21
|
+
Process.waitpid(pid)
|
22
|
+
end
|
23
|
+
|
24
|
+
def db_setup
|
25
|
+
@dbstore = SAAL::DBStore.new(TEST_DBCONF)
|
26
|
+
@dbstore.db_wipe
|
27
|
+
@dbstore.db_initialize
|
28
|
+
end
|
29
|
+
|
30
|
+
def db_test_query(query)
|
31
|
+
db = Mysql.new(TEST_DBOPTS['host'],TEST_DBOPTS['user'],
|
32
|
+
TEST_DBOPTS['pass'],TEST_DBOPTS['db'])
|
33
|
+
res = db.query(query)
|
34
|
+
yield res
|
35
|
+
db.close
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
fake:
|
2
|
+
name: "A fake temperature sensor"
|
3
|
+
max_value: 500
|
4
|
+
min_value: 100
|
5
|
+
onewire:
|
6
|
+
serial: /10.4AEC29CDBAAB/temperature
|
7
|
+
|
8
|
+
fake2:
|
9
|
+
name: "A fake temperature sensor"
|
10
|
+
max_value: 500
|
11
|
+
max_correctable: 550
|
12
|
+
min_value: 100
|
13
|
+
min_correctable: 50
|
14
|
+
onewire:
|
15
|
+
serial: /10.4AEC29CDBAAB/temperature
|
16
|
+
|
17
|
+
fake3:
|
18
|
+
name: "A fake temperature sensor"
|
19
|
+
onewire:
|
20
|
+
serial: /10.4AEC29CDBAAB/temperature
|
21
|
+
|
metadata
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: saal
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 19
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
- 2
|
10
|
+
version: 0.2.2
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- "Pedro C\xC3\xB4rte-Real"
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-12-29 00:00:00 +00:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: ownet
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 27
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 1
|
33
|
+
- 0
|
34
|
+
version: 0.1.0
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: nokogiri
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 3
|
46
|
+
segments:
|
47
|
+
- 0
|
48
|
+
version: "0"
|
49
|
+
type: :runtime
|
50
|
+
version_requirements: *id002
|
51
|
+
- !ruby/object:Gem::Dependency
|
52
|
+
name: mysql
|
53
|
+
prerelease: false
|
54
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 3
|
60
|
+
segments:
|
61
|
+
- 0
|
62
|
+
version: "0"
|
63
|
+
type: :runtime
|
64
|
+
version_requirements: *id003
|
65
|
+
description: |
|
66
|
+
A daemon and libraries to create an abstraction layer that interfaces with
|
67
|
+
sensors and actuators, recording their state, responding to requests
|
68
|
+
for current and historical values, and allowing changes of state.
|
69
|
+
|
70
|
+
email: pedro@pedrocr.net
|
71
|
+
executables:
|
72
|
+
- saal_readall
|
73
|
+
- saal_dump_database
|
74
|
+
- dinrelayset
|
75
|
+
- dinrelaystatus
|
76
|
+
- saal_import_mysql
|
77
|
+
- saal_daemon
|
78
|
+
- saal_chart
|
79
|
+
extensions: []
|
80
|
+
|
81
|
+
extra_rdoc_files:
|
82
|
+
- README.rdoc
|
83
|
+
- LICENSE
|
84
|
+
files:
|
85
|
+
- LICENSE
|
86
|
+
- README.rdoc
|
87
|
+
- Rakefile
|
88
|
+
- TODO
|
89
|
+
- bin/.gitignore
|
90
|
+
- bin/dinrelayset
|
91
|
+
- bin/dinrelaystatus
|
92
|
+
- bin/saal_chart
|
93
|
+
- bin/saal_daemon
|
94
|
+
- bin/saal_dump_database
|
95
|
+
- bin/saal_import_mysql
|
96
|
+
- bin/saal_readall
|
97
|
+
- lib/chart_data.rb
|
98
|
+
- lib/daemon.rb
|
99
|
+
- lib/dbstore.rb
|
100
|
+
- lib/dinrelay.rb
|
101
|
+
- lib/outliercache.rb
|
102
|
+
- lib/owsensor.rb
|
103
|
+
- lib/saal.rb
|
104
|
+
- lib/sensor.rb
|
105
|
+
- lib/sensors.rb
|
106
|
+
- saal.gemspec
|
107
|
+
- test/chart_data_test.rb
|
108
|
+
- test/daemon_test.rb
|
109
|
+
- test/dbstore_test.rb
|
110
|
+
- test/dinrelay.html.erb
|
111
|
+
- test/dinrelay_test.rb
|
112
|
+
- test/nonexistant_sensor.yml
|
113
|
+
- test/outliercache_test.rb
|
114
|
+
- test/sensor_test.rb
|
115
|
+
- test/sensors_test.rb
|
116
|
+
- test/test_db.yml
|
117
|
+
- test/test_dinrelay_sensors.yml
|
118
|
+
- test/test_helper.rb
|
119
|
+
- test/test_sensor_cleanups.yml
|
120
|
+
- test/test_sensors.yml
|
121
|
+
has_rdoc: true
|
122
|
+
homepage: https://github.com/pedrocr/saal
|
123
|
+
licenses: []
|
124
|
+
|
125
|
+
post_install_message:
|
126
|
+
rdoc_options:
|
127
|
+
- -S
|
128
|
+
- -w 2
|
129
|
+
- -N
|
130
|
+
- -c utf8
|
131
|
+
require_paths:
|
132
|
+
- lib
|
133
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
134
|
+
none: false
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
hash: 3
|
139
|
+
segments:
|
140
|
+
- 0
|
141
|
+
version: "0"
|
142
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
143
|
+
none: false
|
144
|
+
requirements:
|
145
|
+
- - ">="
|
146
|
+
- !ruby/object:Gem::Version
|
147
|
+
hash: 3
|
148
|
+
segments:
|
149
|
+
- 0
|
150
|
+
version: "0"
|
151
|
+
requirements: []
|
152
|
+
|
153
|
+
rubyforge_project:
|
154
|
+
rubygems_version: 1.3.7
|
155
|
+
signing_key:
|
156
|
+
specification_version: 2
|
157
|
+
summary: Thin abstraction layer for interfacing and recording sensors (currently onewire) and actuators (currently dinrelay)
|
158
|
+
test_files:
|
159
|
+
- test/chart_data_test.rb
|
160
|
+
- test/daemon_test.rb
|
161
|
+
- test/dbstore_test.rb
|
162
|
+
- test/dinrelay_test.rb
|
163
|
+
- test/outliercache_test.rb
|
164
|
+
- test/sensor_test.rb
|
165
|
+
- test/sensors_test.rb
|
166
|
+
- test/test_helper.rb
|