A program to read a Phidget IR sensor and log pull-ups with Fitbit's API
1require "getoptlong"
2
3$:.unshift(File.dirname(__FILE__))
4require "lib/config_hash"
5require "lib/loggerish"
6require "lib/sensor/phidget"
7
8# bring in all loggers
9Dir.glob(File.dirname(__FILE__) << "/lib/logger/*.rb").sort.each do |f|
10 require File.absolute_path(f)
11end
12
13class PullupCounter
14 OPTS = [
15 [ "--debug", "-d", GetoptLong::NO_ARGUMENT,
16 "enable debugging (show sensor values)" ],
17 [ "--help", "-h", GetoptLong::NO_ARGUMENT,
18 "show this help" ],
19 [ "--no-log", "-n", GetoptLong::NO_ARGUMENT,
20 "don't actually log" ],
21 [ "--verbose", "-v", GetoptLong::NO_ARGUMENT,
22 "be verbose" ],
23 ]
24
25 attr_accessor :config, :loggers
26
27 def initialize
28 @config = ConfigHash.new
29 @semaphore = Mutex.new
30
31 # add in options from each logger
32 @loggers = []
33 opts = OPTS
34 ObjectSpace.each_object(Class) do |cl|
35 if cl < Loggerish && cl.args.any?
36 @loggers.push cl
37 opts += cl.args
38 end
39 end
40
41 # put args into @config or show help
42 GetoptLong.new(*opts.map{|o| o[0 ... -1] }).each do |opt,arg|
43 case opt
44 when "--help"
45 puts "#{$0} [options]"
46 opts.each do |o|
47 print " #{o[1]}\t#{o[0]}"
48
49 tl = o[0].length
50 if o[2] != GetoptLong::NO_ARGUMENT
51 print "=<arg>"
52 tl += 6
53 end
54
55 puts "\t" << (tl < 8 ? "\t" : "") << o[3]
56 end
57
58 exit 1
59
60 else
61 @config[opt.gsub(/^--/, "")] = arg.to_s == "" ? true : arg
62 end
63 end
64
65 # initialize each logger and let it enable itself
66 self.loggers.each_with_index do |cl,x|
67 self.loggers[x] = cl.new(self)
68 end
69
70 Phidget.new(self).main_loop
71 end
72
73 # asynchronously send to each logger
74 def log_pullup!(time)
75 self.loggers.select{|l| l.enabled }.each do |logger|
76 Thread.new do
77 begin
78 logger.log_pullup!(time)
79 rescue => e
80 eputs "error from #{logger.class} logger: " << e.message
81 end
82 end
83 end
84 end
85
86 def aputs(str)
87 @semaphore.synchronize do
88 STDOUT.puts Time.now.strftime("%Y-%m-%d %H:%M:%S.%L") << " - #{str}"
89 end
90 end
91
92 def dputs(str)
93 if @config["debug"]
94 @semaphore.synchronize do
95 STDOUT.puts Time.now.strftime("%Y-%m-%d %H:%M:%S.%L") << " - #{str}"
96 end
97 end
98 end
99
100 def vputs(str)
101 if @config["verbose"] || @config["debug"]
102 @semaphore.synchronize do
103 STDOUT.puts Time.now.strftime("%Y-%m-%d %H:%M:%S.%L") << " - #{str}"
104 end
105 end
106 end
107
108 def eputs(str)
109 @semaphore.synchronize do
110 STDERR.puts Time.now.strftime("%Y-%m-%d %H:%M:%S.%L") << " - #{str}"
111 end
112 end
113end
114
115PullupCounter.new