Created
July 13, 2019 12:22
-
-
Save mitio/bfbcb5458ad543a41c1a5467b0a1b6db to your computer and use it in GitHub Desktop.
Graphs OBD data exported from Auto Doctor and generates HTML. Depends on https://metricsgraphicsjs.org/ and D3.js. Usage: `ruby graph-obd-data *.csv`
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'csv' | |
require 'time' | |
require 'cgi' | |
require 'erb' | |
require 'json' | |
template = | |
<<~HTML | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title><%= start_time %> - <%= end_time %> (<%= CGI.h filename %>)</title> | |
<link rel="stylesheet" type="text/css" href="metrics-graphics-2.15.6/dist/metricsgraphics.css"> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<script src="metrics-graphics-2.15.6/dist/metricsgraphics.min.js"></script> | |
</head> | |
<body> | |
<% datapoints.keys.each do |group| %> | |
<div id="<%= sanitize_key(group) %>"></div> | |
<% end %> | |
<script type="text/javascript"> | |
<% datapoints.each do |group, group_datapoints| %> | |
var combined = <%= group_datapoints.values.to_json %>; | |
for (var i = 0; i < combined.length; i++) { | |
for (var j = 0; j < combined[i].length; j++) { | |
combined[i][j]['date'] = new Date(combined[i][j]['date']); | |
} | |
} | |
MG.data_graphic({ | |
title: <%= group.to_json %>, | |
data: combined, | |
width: <%= width || 1000 %>, | |
height: 200, | |
y_extended_ticks: true, | |
legend: <%= group_datapoints.keys.to_json %>, | |
target: document.getElementById(<%= sanitize_key(group).to_json %>), | |
area: false, | |
}); | |
<% end %> | |
</script> | |
</body> | |
</html> | |
HTML | |
def sanitize_key(string) | |
string.strip.downcase.gsub /\W+/, '-' | |
end | |
only_o2 = width = nil | |
ARGV.each do |arg| | |
case arg | |
when '--only-o2' then only_o2 = true | |
when /--width=(\d+)/ then width = $1.to_i | |
end | |
end | |
ARGV.each do |sensors_data_path| | |
next if sensors_data_path.start_with? '--' | |
filename = File.basename sensors_data_path | |
start_time = end_time = nil | |
datapoints = {} | |
CSV.foreach(sensors_data_path, headers: true) do |row| | |
time = Time.parse row['Time'] | |
start_time ||= time | |
end_time = time | |
row.to_h.keys.each do |key| | |
next if key == 'Time' | |
next if key == 'Bank 1 - Sensor 2 (O2S): Short Term Fuel Trim [%]' # Has no data. | |
next if only_o2 && key !~ /Oxygen Sensor/ | |
group = | |
case key | |
when /Oxygen Sensor/ then 'Oxygen Sensors' | |
else key | |
end | |
datapoints[group] ||= {} | |
datapoints[group][key] ||= [] | |
datapoints[group][key] << {date: time.to_f * 1000, value: (row[key] || 0).to_f} | |
end | |
end | |
generated_html = ERB.new(template).result(binding) | |
bytes_written = File.write "#{filename}.html", generated_html | |
puts "Generated #{filename}.html (#{bytes_written} bytes)" | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment