summaryrefslogtreecommitdiff
path: root/power-logger
diff options
context:
space:
mode:
Diffstat (limited to 'power-logger')
-rwxr-xr-xpower-logger119
1 files changed, 71 insertions, 48 deletions
diff --git a/power-logger b/power-logger
index 827451f..dd94bb3 100755
--- a/power-logger
+++ b/power-logger
@@ -1,52 +1,59 @@
#!/usr/bin/env ruby
# FIXME
-$LOAD_PATH << "/home/pks/.local/lib/ruby/gems/json-2.3.1/lib/"
-$LOAD_PATH << "/home/pks/.local/lib/ruby/gems/mqtt-0.5.0/lib/"
-$LOAD_PATH << "/home/pks/.local/lib/ruby/gems/optimist-3.0.1/lib/"
-$LOAD_PATH << "/home/pks/.local/lib/ruby/gems/sqlite3-1.4.2/lib/"
-$LOAD_PATH << "/home/pks/.local/lib/ruby/gems/zipf-1.2.6/lib/"
+$LOAD_PATH << '/usr/local/lib/ruby/gems/mqtt-0.5.0/lib/'
+$LOAD_PATH << '/usr/local/lib/ruby/gems/optimist-3.0.1/lib/'
+
+$stdout.sync = true
+$stderr.sync = true
require 'json'
require 'mqtt'
require 'optimist'
require 'sqlite3'
require 'time'
-require 'zipf'
+
+$handles = {
+ 'baker' => 'fridge',
+ 'batum' => 'microwave',
+ 'bembry' => 'modem+printer',
+ 'crowder' => 'desk-2',
+ 'davis' => 'hifi',
+ 'doncic' => 'desk-1',
+ 'fournier' => 'air_washer',
+ 'gibson' => 'dishwasher',
+ 'gooden' => 'couch',
+ 'grant' => 'washing_machine',
+ 'kukoc' => 'rack',
+ 'nogueira' => 'kitchen_tech',
+ 'world-peace' => 'kettle+toaster'
+}
def shutdown
- STDERR.write "Shutting down ...\n"
+ STDERR.write 'Shutting down ...'
$db.close
- $logfile.close
- STDERR.write "Done!\n"
+ STDERR.write " done!\n"
exit
end
-Signal.trap("INT") { shutdown }
-Signal.trap("TERM") { shutdown }
+Signal.trap('INT') { shutdown }
+Signal.trap('TERM') { shutdown }
-def db_open_or_new filename
+def db_open_or_create filename
if File.exists? filename
$db = SQLite3::Database.open filename
else
$db = SQLite3::Database.new filename
$db.execute <<-SQL
- create table power_log(
+ create table power(
id INTEGER PRIMARY KEY,
timestamp DATETIME,
- device_name TEXT,
- device_location TEXT,
+ device TEXT,
+ handle TEXT,
total FLOAT,
total_start_time DATETIME
);
SQL
- $db.execute <<-SQL
- create table power_meter(
- id INTEGER PRIMARY KEY,
- timestamp DATETIME,
- total FLOAT
- );
- SQL
end
end
@@ -57,45 +64,55 @@ def db_execute sql, data
break
rescue SQLite3::BusyException
STDERR.write "DB busy, skipping data point '#{d.to_s}'\n"
- sleep 1
+ sleep rand
end
}
end
+def db_insert device, handle, data
+ timestamp = Time.parse(data['Time']).utc.to_i
+ total_start_time = Time.parse(data['ENERGY']['TotalStartTime']).utc.to_i
+ db_execute \
+ "INSERT INTO power(timestamp, device, handle, total, total_start_time) VALUES(?,?,?,?,?)", \
+ [timestamp, device, handle, data['ENERGY']['Total'], total_start_time]
+end
+
def parse_topic topic
- parts = topic.split "/"
- else
- _, device_name, _, device_location_1, device_location_2, _ = parts
- end
- device_location = [device_location_1, device_location_2]
- return device_name, device_location
+ parts = topic.split '/'
+ _, device, _ = parts
+ handle = $handles[device]
+
+ return device, handle
end
def parse_message message
return JSON.parse message
end
-def insert_power device_name, device_location, data
- if data.has_key? "ENERGY"
- timestamp = Time.parse(data["Time"]).utc.to_i
- total_start_time = Time.parse(data["ENERGY"]["TotalStartTime"]).utc.to_i
- db_execute \
- "INSERT INTO power(timestamp, device_name, device_location_primary, device_location_secondary, total, total_start_time) VALUES(?,?,?,?,?,?)", \
- [timestamp, device_name, device_location[0], device_location[1], data["ENERGY"]["Total"], total_start_time]
+def check_and_maybe_create_pidfile filename
+ if File.exists? filename
+ File.open filename, 'r' do |f|
+ STDERR.write "Possibly already running as PID #{f.read}, exiting"
+ end
+ else
+ File.open filename, 'w' do |f|
+ puts "Running as PID #{Process.pid}"
+ f.write "#{Process.pid}\n"
+ end
end
end
def main
options = Optimist::options do
- opt :host, "MQTT hostname", :type => :string, :default => 'localhost', :short => '-h'
- opt :port, "MQTT port", :type => :int, :default => 1883, :short => '-p'
- opt :db, "SQLite3 database file", :type => :string, :required => true, :short => '-d'
- opt :log, "Logfile", :type => :string, :required => true, :short => '-l'
+ opt :host, 'MQTT hostname', :type => :string, :default => 'localhost', :short => '-h'
+ opt :port, 'MQTT port', :type => :int, :default => 1883, :short => '-p'
+ opt :db, 'SQLite3 database file', :type => :string, :default => '/usr/local/share/power_logger/power.db', :short => '-d'
+ opt :pidfile, 'PID file', :type => :string, :default => '/run/power_logger/logger.pid', :short => '-P'
end
- db_open_or_new options[:db]
+ check_and_maybe_create_pidfile options[:pidfile]
- $logfile = WriteFile.new options[:log]
+ db_open_or_create options[:db]
$mqtt_client = MQTT::Client.connect(
:host => options[:host],
@@ -105,13 +122,19 @@ def main
$mqtt_client.get do |topic,message|
begin
- puts "#{topic}\t#{message}
- #device_name, device_location = parse_topic topic
- #data = parse_message message
- #insert_power device_name, device_location, data
- #$logfile.write "#{topic}\t#{message}\n"
+ logged = false
+ if topic.end_with? '/SENSOR'
+ data = parse_message message
+ if data.keys.include? 'ENERGY'
+ puts "[logged] topic=#{topic} message=#{message}"
+ device, handle = parse_topic topic
+ db_insert device, handle, data
+ logged = true
+ end
+ end
+ if not logged then STDERR.write "[ignored] topic=#{topic} message=#{message}\n" end
rescue => exception
- $logfile.write "[Ignoring]\t#{topic}\t#{message}\n"
+ STDERR.write "Exception: #{exception}\n"
end
end