e-meter-gom-daemon 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
6
+ *.gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 art+com AG/dirk luesebrink
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,26 @@
1
+ # e-meter-gom-daemon
2
+
3
+ see: https://t-gallery.artcom.de/trac/wiki/e-meter-in-production?version=1
4
+
5
+ ## Install
6
+
7
+ As this gem uses jeweler you can make use of the rake gem tasks to install:
8
+
9
+ $ rake gemspec build install
10
+
11
+ ## Dependencies
12
+
13
+ ## Note on Patches/Pull Requests
14
+
15
+ * Fork the project.
16
+ * Make your feature addition or bug fix.
17
+ * Add tests for it. This is important so I don't break it in a
18
+ future version unintentionally.
19
+ * Commit, do not mess with rakefile, version, or history.
20
+ (if you want to have your own version, that is fine but
21
+ bump version in a commit by itself I can ignore when I pull)
22
+ * Send me a pull request. Bonus points for topic branches.
23
+
24
+ ## Copyright
25
+
26
+ Copyright (c) 2009 art+com/dirk luesebrink. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,51 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "e-meter-gom-daemon"
8
+ gem.summary = %Q{e-meter GOM sensor daemon}
9
+ gem.description = %Q{
10
+ Periodically polling the t-gallery e-meter and updating its GOM sensor
11
+ node accordingly.
12
+ }.gsub /\n\n/, ''
13
+ gem.email = "dirk@sebrink.de"
14
+ gem.homepage = "http://github.com/crux/e-meter-gom-daemon"
15
+ gem.authors = ["art+com/dirk luesebrink"]
16
+ gem.add_development_dependency "rspec gom-script applix"
17
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
18
+ end
19
+ rescue LoadError
20
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
21
+ end
22
+
23
+ require 'spec/rake/spectask'
24
+ Spec::Rake::SpecTask.new(:spec) do |spec|
25
+ spec.libs << 'lib' << 'spec'
26
+ spec.spec_files = FileList['spec/**/*_spec.rb']
27
+ end
28
+
29
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
30
+ spec.libs << 'lib' << 'spec'
31
+ spec.pattern = 'spec/**/*_spec.rb'
32
+ spec.rcov = true
33
+ end
34
+
35
+ task :spec => :check_dependencies
36
+
37
+ task :default => :spec
38
+
39
+ require 'rake/rdoctask'
40
+ Rake::RDocTask.new do |rdoc|
41
+ if File.exist?('VERSION')
42
+ version = File.read('VERSION')
43
+ else
44
+ version = ""
45
+ end
46
+
47
+ rdoc.rdoc_dir = 'rdoc'
48
+ rdoc.title = "e-meter-gom-daemon #{version}"
49
+ rdoc.rdoc_files.include('README*')
50
+ rdoc.rdoc_files.include('lib/**/*.rb')
51
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.1
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'applix'
5
+
6
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
7
+ require 'e-meter-gom-daemon'
8
+
9
+ #Thread.abort_on_exception = true
10
+ $stderr.sync = true
11
+ $stdout.sync = true
12
+
13
+ def main argv
14
+ options = Hash.from_argv argv
15
+ args = (options.delete :args)
16
+ options[:callback_port] ||= 32119
17
+
18
+ sensor_url = args.shift
19
+ sensor_url or (raise Usage, "no <sensor_url>")
20
+ puts " -- starting e-meter GOM daemon: #{Time.now}"
21
+
22
+ #daemon = EmeterGomDaemon::Daemon.new sensor_url, options
23
+ #daemon.run
24
+
25
+ Gom::Remote::Daemon.new(sensor_url, options) do |daemon, path|
26
+ sensor = EmeterGomDaemon::Node.new path, options
27
+ daemon.sensor_loop(sensor.interval) { |daemon| (sensor.tic daemon) }
28
+ end
29
+
30
+ rescue => e
31
+ puts " ## #{e}\n -> #{e.backtrace.join "\n "}"
32
+ end
33
+
34
+ main ARGV
35
+ # vim: syntax=ruby
@@ -0,0 +1,97 @@
1
+ #!/bin/sh
2
+ ### BEGIN INIT INFO
3
+ # Provides: e-meter-gom-daemon
4
+ # Required-Start: $remote_fs $syslog
5
+ # Required-Stop: $remote_fs $syslog
6
+ # X-Start-Before: kdm gdm xdm
7
+ # X-Stop-After: kdm gdm xdm
8
+ # Default-Start: 2 3 4 5
9
+ # Default-Stop: 1
10
+ # Short-Description: Start the e-meter daemon
11
+ # Description: e-meter values are polled and updated in the GOM
12
+ ### END INIT INFO
13
+
14
+ set -e
15
+
16
+ NAME=e-meter-gom-daemon
17
+ DESC="t-gallery e-meter daemon"
18
+ EMETER_NODE="http://gom.bonn.t-gallery/sensors/e-meter/home"
19
+ LOGFILE="/var/log/e-meter-gom-daemon.log"
20
+ DAEMON_USER="webs"
21
+ DAEMON=$(which e-meter-gom-daemon)
22
+ VERBOSITY="--verbose"
23
+
24
+ PIDDIR=/var/run/e-meter-gom-daemon
25
+ PIDFILE=$PIDDIR/pid
26
+ #VERBOSITY="--quiet"
27
+ PARAMS="--logfile=${LOGFILE} ${EMETER_NODE}"
28
+
29
+ test -x $DAEMON || exit 0
30
+
31
+ # Get lsb functions
32
+ . /lib/lsb/init-functions
33
+ . /etc/default/rcS
34
+
35
+ start_it_up()
36
+ {
37
+ if [ ! -d $PIDDIR ]; then
38
+ mkdir -p $PIDDIR
39
+ chown $DAEMON_USER $PIDDIR
40
+ #chgrp $DAEMON_USER $PIDDIR
41
+ fi
42
+
43
+ touch $LOGFILE
44
+ chown $DAEMON_USER $LOGFILE
45
+
46
+ if [ -e $PIDFILE ]; then
47
+ PIDDIR=/proc/$(cat $PIDFILE)
48
+ if [ -d ${PIDDIR} -a "$(readlink -f ${PIDDIR}/exe)" = "${DAEMON}" ]; then
49
+ log_success_msg "$DESC already started; not starting."
50
+ return
51
+ else
52
+ log_success_msg "Removing stale PID file $PIDFILE."
53
+ rm -f $PIDFILE
54
+ fi
55
+ fi
56
+
57
+ log_daemon_msg "Starting $DESC" "$NAME"
58
+ /sbin/start-stop-daemon --start --background $VERBOSITY \
59
+ --make-pidfile --pidfile $PIDFILE \
60
+ -c $DAEMON_USER --exec $DAEMON -- $PARAMS
61
+
62
+ log_end_msg $?
63
+ }
64
+
65
+
66
+ shut_it_down()
67
+ {
68
+ log_daemon_msg "Stopping $DESC" "$NAME"
69
+ /sbin/start-stop-daemon $VERBOSITY --stop --retry 5 --oknodo \
70
+ --pidfile $PIDFILE --user $DAEMON_USER
71
+ # We no longer include these arguments so that start-stop-daemon
72
+ # can do its job even given that we may have been upgraded.
73
+ # We rely on the pidfile being sanely managed
74
+ # --exec $DAEMON -- --system $EMETER_NODE
75
+ log_end_msg $?
76
+ rm -f $PIDFILE
77
+ }
78
+
79
+ case "$1" in
80
+ start)
81
+ start_it_up
82
+ ;;
83
+ stop)
84
+ shut_it_down
85
+ ;;
86
+ restart)
87
+ shut_it_down
88
+ start_it_up
89
+ ;;
90
+ status)
91
+ status_of_proc -p $PIDFILE $DAEMON $NAME && exit 0 || exit $?
92
+ ;;
93
+ *)
94
+ log_success_msg "Usage: /etc/init.d/${NAME} {start|stop|restart|status}"
95
+ exit 2
96
+ esac
97
+
@@ -0,0 +1,164 @@
1
+ module EmeterGomDaemon
2
+ class Daemon
3
+
4
+ Defaults = {
5
+ :logfile => '-',
6
+ :interval => 5,
7
+ :threshold => 5, # in percent
8
+ :nagios_port => 9918,
9
+ :stealth => false,
10
+ }
11
+
12
+ # option precedence is:
13
+ # 1. commands line options
14
+ # 2. GOM Sensor node values
15
+ # 3. built-in Default values (see #Defaults)
16
+ #
17
+ def initialize sensor_url, options = {}
18
+ @sensor_url = sensor_url
19
+ @gom, @sensor_path = (Gom::Remote::Connection.init @sensor_url)
20
+
21
+ @options = Defaults.merge(gnode(@sensor_path)).merge(options)
22
+ puts "options: #{@options.inspect}"
23
+
24
+ redirect_to logfile
25
+ end
26
+
27
+ def logfile
28
+ @logfile ||= @options[:logfile]
29
+ end
30
+
31
+ def interval
32
+ @interval ||= Integer(@options[:interval])
33
+ end
34
+
35
+ def emeter_ip
36
+ @emeter_ip ||= @options[:emeter_ip]
37
+ end
38
+
39
+ def nagios_port
40
+ @nagios_port ||= @options[:nagios_port]
41
+ end
42
+
43
+ def threshold
44
+ @threshold ||= Float(@options[:threshold])
45
+ end
46
+
47
+ def stealth?
48
+ @stealth ||= @options[:stealth]
49
+ end
50
+
51
+ def run
52
+ run_nagios_thread # become visible to nagios
53
+ gom_checkin
54
+ loop do
55
+ begin
56
+ tic
57
+ rescue Exception => e
58
+ callstack = "#{e.backtrace.join "\n "}"
59
+ puts " ## #{self} - #{e}\n -> #{callstack}"
60
+ ensure
61
+ sleep interval
62
+ end
63
+ end
64
+ ensure
65
+ stop_nagios_thread
66
+ end
67
+
68
+ private
69
+
70
+ def tic
71
+ old = @current_value || 0
72
+ readout = poll
73
+ _, _, _, @current_value = readout
74
+ change_in_percent = 100 * (1 - (@current_value / old)).abs
75
+ if threshold < change_in_percent
76
+ t = Time.now
77
+ puts "#{t} :: #{readout.inspect}"
78
+ puts "#{t} :: #{@current_value}"
79
+ @gom.write "#{@sensor_path}:current_value", @current_value
80
+ end
81
+ end
82
+
83
+ def poll
84
+ # expected: '172.20.10.24;WEBIO-042BFF;Sensor 1 0..50A;0,150 A'
85
+ line = (open "http://#{emeter_ip}/Single1").read
86
+ ip, id, name, val = (line.split /;/)
87
+ [ip, id, name, (val.sub! /,/, '.').to_f]
88
+ end
89
+
90
+ private
91
+
92
+ def redirect_to logfile
93
+ (@logfile_fd && @logfile_fd.close) rescue nil
94
+ puts " -- redirecting stdout/stderr to: #{logfile}"
95
+ if logfile == '-'
96
+ if @stdout
97
+ $stderr, $stdout = @stdout, @stderr
98
+ end
99
+ else
100
+ @stderr, @stdout = $stdout, $stderr
101
+ @logfile_fd = File.open(logfile, File::WRONLY|File::APPEND|File::CREAT)
102
+ @logfile_fd.sync = true
103
+ $stderr = $stdout = @logfile_fd
104
+ end
105
+ # first line after redirect
106
+ puts " -- e-meter daemon logile redirect at #{Time.now}"
107
+ end
108
+
109
+ # push own ip and monitoring port back to GOM node
110
+ def gom_checkin
111
+ if stealth?
112
+ puts "skipping gom check-in in stealth mode"
113
+ else
114
+ @gom.write "#{@sensor_path}:daemon_ip", @gom.callback_ip
115
+ @gom.write "#{@sensor_path}:nagios_port", nagios_port
116
+ end
117
+ end
118
+
119
+ def stop_nagios_thread
120
+ @nagios_thread or return
121
+ puts ' -- killing nagios thread...'
122
+ @nagios_thread.kill
123
+ @nagios_thread = nil
124
+ puts ' and gone.'
125
+ self
126
+ end
127
+
128
+ def run_nagios_thread
129
+ @nagios_thread .nil? or (raise "already running!")
130
+ port = nagios_port
131
+ @nagios_thread = Thread.new do
132
+ infinity = Proc.new do |env|
133
+ [200, {"Content-Type" => "text/plain"}, env.inspect]
134
+ end
135
+ puts " -- running nagios server on port: #{port}"
136
+ Rack::Handler::Mongrel.run infinity, :Port => port
137
+ end
138
+ self
139
+ end
140
+
141
+ #
142
+ # TODO: The GOM helper stuff is experimental and being tested here. Once
143
+ # it's prove i'll move it into the gom-script gem
144
+ #
145
+
146
+ #def gattr name
147
+ # (Gom::Remote.connection.read "#{@sensor_path}:#{name}.txt")
148
+ #rescue NameError
149
+ # nil
150
+ #end
151
+
152
+ def gnode path
153
+ json = (Gom::Remote.connection.read "#{path}.json")
154
+ (JSON.parse json)["node"]["entries"].select do |entry|
155
+ # 1. select attribute entries
156
+ entry.has_key? "attribute"
157
+ end.inject({}) do |h, a|
158
+ # 2. make it a key, value list
159
+ kv = a["attribute"]
160
+ h.update(kv["name"].to_sym => kv["value"])
161
+ end
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,173 @@
1
+ module EmeterGomDaemon
2
+ class Node < Gom::Remote::Entry
3
+
4
+ Defaults = {
5
+ :logfile => '-',
6
+ :interval => 5,
7
+ :threshold => 5, # in percent
8
+ :nagios_port => 9918,
9
+ :stealth => false,
10
+ :base_value => 0,
11
+ :scale_factor => 1.0,
12
+ }
13
+
14
+ # option precedence is:
15
+ # 1. commands line options
16
+ # 2. GOM Sensor node values
17
+ # 3. built-in Default values (see #Defaults)
18
+ #
19
+ def initialize path, options = {}
20
+ @path = path
21
+ @options = Defaults.merge(gnode @path).merge(options)
22
+ puts "options: #{@options.inspect}"
23
+
24
+ redirect_to logfile
25
+ end
26
+
27
+ def logfile
28
+ @logfile ||= @options[:logfile]
29
+ end
30
+
31
+ def interval
32
+ @interval ||= Integer(@options[:interval])
33
+ end
34
+
35
+ def scale_factor
36
+ @scale_factor ||= Float(@options[:scale_factor])
37
+ end
38
+
39
+ def base_value
40
+ @base_value ||= Float(@options[:base_value])
41
+ end
42
+
43
+ def emeter_ip
44
+ @emeter_ip ||= @options[:emeter_ip]
45
+ end
46
+
47
+ def nagios_port
48
+ @nagios_port ||= @options[:nagios_port]
49
+ end
50
+
51
+ def threshold
52
+ @threshold ||= Float(@options[:threshold])
53
+ end
54
+
55
+ def stealth?
56
+ @stealth ||= @options[:stealth]
57
+ end
58
+
59
+ #def run
60
+ # run_nagios_thread # become visible to nagios
61
+ # gom_checkin
62
+ # loop do
63
+ # begin
64
+ # tic
65
+ # rescue Exception => e
66
+ # callstack = "#{e.backtrace.join "\n "}"
67
+ # puts " ## #{self} - #{e}\n -> #{callstack}"
68
+ # ensure
69
+ # sleep interval
70
+ # end
71
+ # end
72
+ #ensure
73
+ # stop_nagios_thread
74
+ #end
75
+
76
+ def tic *args
77
+ old = @current_value || 0
78
+ readout = poll
79
+ #puts "#{t} :: #{readout.inspect}"
80
+ _, _, _, @current_value = readout
81
+ change_in_percent = 100 * (1 - (@current_value / old)).abs
82
+ return if change_in_percent < threshold
83
+
84
+ t = Time.now
85
+ val = scale_factor * @current_value + base_value
86
+ puts "#{t} :: #{@current_value} -> #{val}"
87
+ connection.write "#{@path}:current_value", val
88
+ end
89
+
90
+ private
91
+
92
+ def poll
93
+ # expected: '172.20.10.24;WEBIO-042BFF;Sensor 1 0..50A;0,150 A'
94
+ line = (open "http://#{emeter_ip}/Single1").read
95
+ ip, id, name, val = (line.split /;/)
96
+ [ip, id, name, (val.sub! /,/, '.').to_f]
97
+ end
98
+
99
+ private
100
+
101
+ def redirect_to logfile
102
+ (@logfile_fd && @logfile_fd.close) rescue nil
103
+ puts " -- redirecting stdout/stderr to: #{logfile}"
104
+ if logfile == '-'
105
+ if @stdout
106
+ $stderr, $stdout = @stdout, @stderr
107
+ end
108
+ else
109
+ @stderr, @stdout = $stdout, $stderr
110
+ @logfile_fd = File.open(logfile, File::WRONLY|File::APPEND|File::CREAT)
111
+ @logfile_fd.sync = true
112
+ $stderr = $stdout = @logfile_fd
113
+ end
114
+ # first line after redirect
115
+ puts " -- e-meter daemon logile redirect at #{Time.now}"
116
+ end
117
+
118
+ # push own ip and monitoring port back to GOM node
119
+ def gom_checkin
120
+ if stealth?
121
+ puts "skipping gom check-in in stealth mode"
122
+ else
123
+ @gom.write "#{@sensor_path}:daemon_ip", @gom.callback_ip
124
+ @gom.write "#{@sensor_path}:nagios_port", nagios_port
125
+ end
126
+ end
127
+
128
+ def stop_nagios_thread
129
+ @nagios_thread or return
130
+ puts ' -- killing nagios thread...'
131
+ @nagios_thread.kill
132
+ @nagios_thread = nil
133
+ puts ' and gone.'
134
+ self
135
+ end
136
+
137
+ def run_nagios_thread
138
+ @nagios_thread .nil? or (raise "already running!")
139
+ port = nagios_port
140
+ @nagios_thread = Thread.new do
141
+ infinity = Proc.new do |env|
142
+ [200, {"Content-Type" => "text/plain"}, env.inspect]
143
+ end
144
+ puts " -- running nagios server on port: #{port}"
145
+ Rack::Handler::Mongrel.run infinity, :Port => port
146
+ end
147
+ self
148
+ end
149
+
150
+ #
151
+ # TODO: The GOM helper stuff is experimental and being tested here. Once
152
+ # it's prove i'll move it into the gom-script gem
153
+ #
154
+
155
+ #def gattr name
156
+ # (Gom::Remote.connection.read "#{@sensor_path}:#{name}.txt")
157
+ #rescue NameError
158
+ # nil
159
+ #end
160
+
161
+ #def gnode path
162
+ # json = (Gom::Remote.connection.read "#{path}.json")
163
+ # (JSON.parse json)["node"]["entries"].select do |entry|
164
+ # # 1. select attribute entries
165
+ # entry.has_key? "attribute"
166
+ # end.inject({}) do |h, a|
167
+ # # 2. make it a key, value list
168
+ # kv = a["attribute"]
169
+ # h.update(kv["name"].to_sym => kv["value"])
170
+ # end
171
+ #end
172
+ end
173
+ end
@@ -0,0 +1,2 @@
1
+ require 'gom/remote'
2
+ require 'e-meter-gom-daemon/node'
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "EMeterGomDaemon" do
4
+ it "at least finds the e-meter module" do
5
+ EmeterGomDaemon.should_not == nil
6
+ end
7
+ end
@@ -0,0 +1,34 @@
1
+ # figure out where we are being loaded from
2
+ if $LOADED_FEATURES.grep(/spec\/spec_helper\.rb/).any?
3
+ begin
4
+ raise "foo"
5
+ rescue => e
6
+ puts <<-MSG
7
+ ===================================================
8
+ It looks like spec_helper.rb has been loaded
9
+ multiple times. Normalize the require to:
10
+
11
+ require "spec/spec_helper"
12
+
13
+ Things like File.join and File.expand_path will
14
+ cause it to be loaded multiple times.
15
+
16
+ Loaded this time from:
17
+
18
+ #{e.backtrace.join("\n ")}
19
+ ===================================================
20
+ MSG
21
+ end
22
+ end
23
+
24
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
25
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
26
+ #$LOAD_PATH.unshift File.join(File.dirname(__FILE__), %w{.. .. gom-remote lib})
27
+ require 'rubygems'
28
+ require 'e-meter-gom-daemon'
29
+ require 'spec'
30
+ require 'spec/autorun'
31
+
32
+ Spec::Runner.configure do |config|
33
+
34
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: e-meter-gom-daemon
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.1
5
+ platform: ruby
6
+ authors:
7
+ - art+com/dirk luesebrink
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-13 00:00:00 +01:00
13
+ default_executable: e-meter-gom-daemon
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec gom-script applix
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description: " \n Periodically polling the t-gallery e-meter and updating its GOM sensor\n node accordingly.\n "
26
+ email: dirk@sebrink.de
27
+ executables:
28
+ - e-meter-gom-daemon
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - LICENSE
33
+ - README.markdown
34
+ files:
35
+ - .document
36
+ - .gitignore
37
+ - LICENSE
38
+ - README.markdown
39
+ - Rakefile
40
+ - VERSION
41
+ - bin/e-meter-gom-daemon
42
+ - etc/e-meter-gom-daemon-debian-init-script
43
+ - lib/e-meter-gom-daemon.rb
44
+ - lib/e-meter-gom-daemon/daemon.rb
45
+ - lib/e-meter-gom-daemon/node.rb
46
+ - spec/e-meter-gom-daemon_spec.rb
47
+ - spec/spec_helper.rb
48
+ has_rdoc: true
49
+ homepage: http://github.com/crux/e-meter-gom-daemon
50
+ licenses: []
51
+
52
+ post_install_message:
53
+ rdoc_options:
54
+ - --charset=UTF-8
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ version:
69
+ requirements: []
70
+
71
+ rubyforge_project:
72
+ rubygems_version: 1.3.5
73
+ signing_key:
74
+ specification_version: 3
75
+ summary: e-meter GOM sensor daemon
76
+ test_files:
77
+ - spec/e-meter-gom-daemon_spec.rb
78
+ - spec/spec_helper.rb