e-meter-gom-daemon 0.2.1

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/.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