├── public ├── favicon.ico ├── images │ └── rails.png ├── open-flash-chart.swf ├── open-flash-chart-bar-clicking.swf ├── javascripts │ ├── application.js │ └── swfobject.js ├── robots.txt ├── 422.html ├── 404.html ├── 500.html └── stylesheets │ ├── scaffold.css │ └── datalogger.css ├── app ├── views │ ├── report │ │ ├── latest_temps.html.erb │ │ ├── show.html.erb │ │ ├── latest_trends.html.erb │ │ └── index.html.erb │ ├── sources │ │ ├── show.html.erb │ │ ├── new.html.erb │ │ ├── edit.html.erb │ │ └── index.html.erb │ ├── voltages │ │ ├── show.html.erb │ │ ├── new.html.erb │ │ ├── edit.html.erb │ │ └── index.html.erb │ ├── time_periods │ │ ├── show.html.erb │ │ ├── new.html.erb │ │ ├── edit.html.erb │ │ └── index.html.erb │ ├── fahrenheit_temps │ │ ├── show.html.erb │ │ ├── new.html.erb │ │ ├── edit.html.erb │ │ └── index.html.erb │ └── layouts │ │ ├── voltages.html.erb │ │ └── application.html.erb ├── helpers │ ├── sources_helper.rb │ ├── voltages_helper.rb │ ├── time_periods_helper.rb │ └── application_helper.rb ├── models │ ├── report_source.rb │ ├── source.rb │ ├── voltage.rb │ ├── time_period.rb │ ├── #fahrenheit_temp.rb# │ ├── fahrenheit_temp.rb │ ├── log_event.rb │ ├── #report.rb# │ └── report.rb └── controllers │ ├── application_controller.rb │ ├── sources_controller.rb │ ├── voltages_controller.rb │ ├── time_periods_controller.rb │ ├── fahrenheit_temps_controller.rb │ └── report_controller.rb ├── .bash_profile ├── .gitignore ├── arduino ├── dallas_temp_sensor │ ├── applet │ │ ├── dallas_temp_sensor.cpp.eep │ │ ├── core.a │ │ ├── OneWire │ │ │ └── OneWire.cpp.o │ │ ├── DallasTemperature │ │ │ └── DallasTemperature.cpp.o │ │ └── dallas_temp_sensor.cpp │ └── dallas_temp_sensor.pde ├── trip_logger │ └── trip_logger.pde └── max6675_temp_sensor │ └── max6675_temp_sensor.pde ├── vendor └── plugins │ └── open_flash_chart │ ├── uninstall.rb │ ├── lib │ ├── open_flash_chart │ │ ├── upload_image.rb │ │ ├── y_axis.rb │ │ ├── bar_base.rb │ │ ├── y_axis_base.rb │ │ ├── y_axis_right.rb │ │ ├── legend.rb │ │ ├── y_legend_right.rb │ │ ├── x_axis_labels.rb │ │ ├── line.rb │ │ ├── area_line.rb │ │ ├── line_hollow.rb │ │ ├── radar_axis.rb │ │ ├── title.rb │ │ ├── x_legend.rb │ │ ├── area_hollow.rb │ │ ├── y_legend.rb │ │ ├── radar_axis_labels.rb │ │ ├── radar_spoke_labels.rb │ │ ├── chart.rb │ │ ├── scatter_line.rb │ │ ├── bar_3d.rb │ │ ├── bar_glass.rb │ │ ├── area_base.rb │ │ ├── line_base.rb │ │ ├── bar.rb │ │ ├── bar_sketch.rb │ │ ├── line_dot.rb │ │ ├── shape.rb │ │ ├── candle.rb │ │ ├── bar_stack.rb │ │ ├── x_axis_label.rb │ │ ├── bar_filled.rb │ │ ├── tooltip.rb │ │ ├── scatter.rb │ │ ├── h_bar.rb │ │ ├── x_axis.rb │ │ ├── pie.rb │ │ ├── linear_regression.rb │ │ ├── open_flash_chart_object.rb │ │ ├── ofc_ajax.rb │ │ └── base.rb │ └── open_flash_chart.rb │ ├── assets │ ├── open-flash-chart.swf │ ├── open-flash-chart-bar-clicking.swf │ └── javascripts │ │ └── swfobject.js │ ├── tasks │ └── open_flash_chart_tasks.rake │ ├── test │ └── open_flash_chart_test.rb │ ├── init.rb │ ├── Rakefile │ ├── install.rb │ ├── MIT-LICENSE │ └── README ├── db ├── development.sqlite3 ├── migrate │ ├── 20090829142924_rename_report_parameters.rb │ ├── 20090905151907_add_temp_offset_to_sources.rb │ ├── 20090630005902_create_sources.rb │ ├── 20090827003958_add_source_to_report_parameters.rb │ ├── 20100314150814_add_index_to_fahrenheit_temps_created_at.rb │ ├── 20110319183317_add_sampled_at_index_to_fahrenheit_temps.rb │ ├── 20090730022539_create_fahrenheit_temps.rb │ ├── 20090817025242_create_report_parameters.rb │ ├── 20100508201740_create_voltages.rb │ ├── 20090630010143_create_time_periods.rb │ ├── 20090802175653_add_logged_at_to_fahrenheit_temp.rb │ └── 20090829141507_create_report_sources.rb └── schema.rb ├── hardware ├── parts_lib │ └── edebill.lbr ├── stackduino │ ├── stackduino.brd │ └── stackduino.sch ├── stackduino pdip proto shield │ ├── pdip shield.brd │ └── pdip shield.sch └── stackduino xbee shield │ ├── stackduino xbee shield.brd │ └── stackduino xbee shield.sch ├── test ├── unit │ ├── helpers │ │ ├── sources_helper_test.rb │ │ ├── voltages_helper_test.rb │ │ ├── time_periods_helper_test.rb │ │ └── fahrenheit_temps_helper_test.rb │ ├── source_test.rb │ ├── voltage_test.rb │ ├── time_period_test.rb │ ├── fahrenheit_temp_test.rb │ ├── report_sources_test.rb │ └── report_test.rb ├── fixtures │ ├── sources.yml │ ├── fahrenheit_temps.yml │ ├── report_sources.yml │ ├── voltages.yml │ └── time_periods.yml ├── functional │ ├── report_controller_test.rb │ ├── voltages_controller_test.rb │ └── sources_controller_test.rb ├── performance │ └── browsing_test.rb └── test_helper.rb ├── script ├── performance │ ├── profiler │ └── benchmarker ├── about ├── rails └── data_logger_listener ├── config.ru ├── config ├── boot.rb ├── environment.rb ├── locales │ └── en.yml ├── initializers │ ├── mime_types.rb │ ├── inflections.rb │ ├── backtrace_silencers.rb │ ├── new_rails_defaults.rb │ └── session_store.rb ├── routes.rb ├── database.yml.example ├── environments │ ├── development.rb │ ├── test.rb │ └── production.rb ├── backup.rb.example └── application.rb ├── doc └── README_FOR_APP ├── Gemfile ├── Rakefile ├── README ├── lib └── crc16.rb └── Gemfile.lock /public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/views/report/latest_temps.html.erb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.bash_profile: -------------------------------------------------------------------------------- 1 | export PATH=/usr/local/bin:$PATH 2 | 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | logs/*.log 2 | *~ 3 | .#* 4 | db/*.sqlite3 5 | -------------------------------------------------------------------------------- /app/helpers/sources_helper.rb: -------------------------------------------------------------------------------- 1 | module SourcesHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/voltages_helper.rb: -------------------------------------------------------------------------------- 1 | module VoltagesHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/time_periods_helper.rb: -------------------------------------------------------------------------------- 1 | module TimePeriodsHelper 2 | end 3 | -------------------------------------------------------------------------------- /arduino/dallas_temp_sensor/applet/dallas_temp_sensor.cpp.eep: -------------------------------------------------------------------------------- 1 | :00000001FF 2 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/uninstall.rb: -------------------------------------------------------------------------------- 1 | # Uninstall hook code here 2 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/upload_image.rb: -------------------------------------------------------------------------------- 1 | # TODO 2 | -------------------------------------------------------------------------------- /db/development.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edebill/data_logger/master/db/development.sqlite3 -------------------------------------------------------------------------------- /public/images/rails.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edebill/data_logger/master/public/images/rails.png -------------------------------------------------------------------------------- /public/open-flash-chart.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edebill/data_logger/master/public/open-flash-chart.swf -------------------------------------------------------------------------------- /hardware/parts_lib/edebill.lbr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edebill/data_logger/master/hardware/parts_lib/edebill.lbr -------------------------------------------------------------------------------- /hardware/stackduino/stackduino.brd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edebill/data_logger/master/hardware/stackduino/stackduino.brd -------------------------------------------------------------------------------- /hardware/stackduino/stackduino.sch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edebill/data_logger/master/hardware/stackduino/stackduino.sch -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/y_axis.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | class YAxis < YAxisBase ; end 3 | end -------------------------------------------------------------------------------- /test/unit/helpers/sources_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class SourcesHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /test/unit/helpers/voltages_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class VoltagesHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/bar_base.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | class BarBase < Base; end 3 | end 4 | -------------------------------------------------------------------------------- /app/models/report_source.rb: -------------------------------------------------------------------------------- 1 | class ReportSource < ActiveRecord::Base 2 | belongs_to :report 3 | belongs_to :source 4 | 5 | end 6 | -------------------------------------------------------------------------------- /arduino/dallas_temp_sensor/applet/core.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edebill/data_logger/master/arduino/dallas_temp_sensor/applet/core.a -------------------------------------------------------------------------------- /public/open-flash-chart-bar-clicking.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edebill/data_logger/master/public/open-flash-chart-bar-clicking.swf -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/y_axis_base.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | class YAxisBase < Base; end 3 | end 4 | -------------------------------------------------------------------------------- /test/unit/helpers/time_periods_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class TimePeriodsHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/y_axis_right.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | class YAxisRight < YAxisBase; end 3 | end 4 | -------------------------------------------------------------------------------- /test/unit/helpers/fahrenheit_temps_helper_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class FahrenheitTempsHelperTest < ActionView::TestCase 4 | end 5 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/legend.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class Legend < Base 4 | end 5 | 6 | end 7 | 8 | -------------------------------------------------------------------------------- /app/views/report/show.html.erb: -------------------------------------------------------------------------------- 1 | 2 |
<%= @graph.html_safe %>
3 | -------------------------------------------------------------------------------- /script/performance/profiler: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.dirname(__FILE__) + '/../../config/boot' 3 | require 'commands/performance/profiler' 4 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | # Methods added to this helper will be available to all templates in the application. 2 | module ApplicationHelper 3 | end 4 | -------------------------------------------------------------------------------- /hardware/stackduino pdip proto shield/pdip shield.brd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edebill/data_logger/master/hardware/stackduino pdip proto shield/pdip shield.brd -------------------------------------------------------------------------------- /hardware/stackduino pdip proto shield/pdip shield.sch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edebill/data_logger/master/hardware/stackduino pdip proto shield/pdip shield.sch -------------------------------------------------------------------------------- /script/performance/benchmarker: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.dirname(__FILE__) + '/../../config/boot' 3 | require 'commands/performance/benchmarker' 4 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/y_legend_right.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class YLegendRight < YLegend 4 | end 5 | 6 | end 7 | -------------------------------------------------------------------------------- /arduino/dallas_temp_sensor/applet/OneWire/OneWire.cpp.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edebill/data_logger/master/arduino/dallas_temp_sensor/applet/OneWire/OneWire.cpp.o -------------------------------------------------------------------------------- /hardware/stackduino xbee shield/stackduino xbee shield.brd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edebill/data_logger/master/hardware/stackduino xbee shield/stackduino xbee shield.brd -------------------------------------------------------------------------------- /hardware/stackduino xbee shield/stackduino xbee shield.sch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edebill/data_logger/master/hardware/stackduino xbee shield/stackduino xbee shield.sch -------------------------------------------------------------------------------- /test/fixtures/sources.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html 2 | 3 | one: 4 | name: MyString 5 | 6 | two: 7 | name: MyString 8 | -------------------------------------------------------------------------------- /script/about: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require File.dirname(__FILE__) + '/../config/boot' 3 | $LOAD_PATH.unshift "#{RAILTIES_PATH}/builtin/rails_info" 4 | require 'commands/about' -------------------------------------------------------------------------------- /test/functional/report_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require 'ostruct' 3 | 4 | class ReportControllerTest < ActionController::TestCase 5 | 6 | 7 | 8 | end 9 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/assets/open-flash-chart.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edebill/data_logger/master/vendor/plugins/open_flash_chart/assets/open-flash-chart.swf -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/tasks/open_flash_chart_tasks.rake: -------------------------------------------------------------------------------- 1 | # desc "Explaining what the task does" 2 | # task :open_flash_chart do 3 | # # Task goes here 4 | # end 5 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run DataLogger::Application 5 | -------------------------------------------------------------------------------- /public/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // Place your application-specific JavaScript functions and classes here 2 | // This file is automatically included by javascript_include_tag :defaults 3 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | # Set up gems listed in the Gemfile. 3 | if File.exist?(File.expand_path('../../Gemfile', __FILE__)) 4 | require 'bundler' 5 | Bundler.setup 6 | end 7 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the rails application 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the rails application 5 | DataLogger::Application.initialize! 6 | 7 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/assets/open-flash-chart-bar-clicking.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edebill/data_logger/master/vendor/plugins/open_flash_chart/assets/open-flash-chart-bar-clicking.swf -------------------------------------------------------------------------------- /arduino/dallas_temp_sensor/applet/DallasTemperature/DallasTemperature.cpp.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edebill/data_logger/master/arduino/dallas_temp_sensor/applet/DallasTemperature/DallasTemperature.cpp.o -------------------------------------------------------------------------------- /test/unit/source_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class SourceTest < ActiveSupport::TestCase 4 | # Replace this with your real tests. 5 | test "the truth" do 6 | assert true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /test/unit/voltage_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class VoltageTest < ActiveSupport::TestCase 4 | # Replace this with your real tests. 5 | test "the truth" do 6 | assert true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /test/unit/time_period_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class TimePeriodTest < ActiveSupport::TestCase 4 | # Replace this with your real tests. 5 | test "the truth" do 6 | assert true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/x_axis_labels.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class XAxisLabels < Base 4 | def set_vertical 5 | @rotate = "vertical" 6 | end 7 | end 8 | 9 | end -------------------------------------------------------------------------------- /test/fixtures/fahrenheit_temps.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html 2 | 3 | one: 4 | temp: 1.5 5 | source_id: 1 6 | 7 | two: 8 | temp: 1.5 9 | source_id: 1 10 | -------------------------------------------------------------------------------- /test/fixtures/report_sources.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html 2 | 3 | one: 4 | report_id: 1 5 | source_id: 1 6 | 7 | two: 8 | report_id: 1 9 | source_id: 1 10 | -------------------------------------------------------------------------------- /test/unit/fahrenheit_temp_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class FahrenheitTempTest < ActiveSupport::TestCase 4 | # Replace this with your real tests. 5 | test "the truth" do 6 | assert true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /test/unit/report_sources_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ReportSourcesTest < ActiveSupport::TestCase 4 | # Replace this with your real tests. 5 | test "the truth" do 6 | assert true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /doc/README_FOR_APP: -------------------------------------------------------------------------------- 1 | Use this README file to introduce your application and point to useful places in the API for learning more. 2 | Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries. 3 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/line.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class Line < LineBase 4 | def initialize args={} 5 | super 6 | @type = "line" 7 | end 8 | end 9 | 10 | end -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-Agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/test/open_flash_chart_test.rb: -------------------------------------------------------------------------------- 1 | require 'test/unit' 2 | 3 | class OpenFlashChartTest < Test::Unit::TestCase 4 | # Replace this with your real tests. 5 | def test_this_plugin 6 | flunk 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Sample localization file for English. Add more files in this directory for other locales. 2 | # See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. 3 | 4 | en: 5 | hello: "Hello world" -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/area_line.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class AreaLine < AreaBase 4 | def initialize args={} 5 | super 6 | @type = "area_line" 7 | end 8 | end 9 | 10 | end -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/line_hollow.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class LineHollow < LineBase 4 | def initialize args={} 5 | super 6 | @type = "line_hollow" 7 | end 8 | end 9 | 10 | end -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/radar_axis.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class RadarAxis < Base 4 | def initialize(max, args={}) 5 | super args 6 | @max = max 7 | end 8 | end 9 | 10 | end -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/title.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class Title < Base 4 | def initialize(text='', args = {}) 5 | super args 6 | @text = text 7 | end 8 | end 9 | 10 | end -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/x_legend.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class XLegend < Base 4 | def initialize(text, args={}) 5 | super args 6 | @text = text 7 | end 8 | end 9 | 10 | end -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | # Mime::Type.register_alias "text/html", :iphone 6 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/area_hollow.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class AreaHollow < AreaBase 4 | def initialize args={} 5 | super 6 | @type = "area_hollow" 7 | end 8 | end 9 | 10 | end -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/y_legend.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class YLegend < Base 4 | def initialize(text = '', args={}) 5 | super args 6 | @text = text 7 | end 8 | end 9 | 10 | end -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/radar_axis_labels.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class RadarAxisLabels < Base 4 | def initialize(labels, args={}) 5 | super args 6 | @labels = labels 7 | end 8 | end 9 | 10 | end -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/radar_spoke_labels.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class RadarSpokeLabels < Base 4 | def initialize(labels, args={}) 5 | super args 6 | @labels = labels 7 | end 8 | end 9 | 10 | end -------------------------------------------------------------------------------- /app/views/sources/show.html.erb: -------------------------------------------------------------------------------- 1 |

2 | Name: 3 | <%=h @source.name %> 4 |

5 |

6 | Temp Offset: 7 | <%=h @source.temp_offset %> 8 |

9 | 10 | 11 | <%= link_to 'Edit', edit_source_path(@source) %> | 12 | <%= link_to 'Back', sources_path %> 13 | -------------------------------------------------------------------------------- /db/migrate/20090829142924_rename_report_parameters.rb: -------------------------------------------------------------------------------- 1 | class RenameReportParameters < ActiveRecord::Migration 2 | def self.up 3 | rename_table :report_parameters, :reports 4 | end 5 | 6 | def self.down 7 | rename_table :reports, :report_parameters 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20090905151907_add_temp_offset_to_sources.rb: -------------------------------------------------------------------------------- 1 | class AddTempOffsetToSources < ActiveRecord::Migration 2 | def self.up 3 | add_column :sources, :temp_offset, :float 4 | end 5 | 6 | def self.down 7 | remove_column :source, :temp_offset 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /test/fixtures/voltages.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html 2 | 3 | one: 4 | voltage: 1.5 5 | source_id: 1 6 | sampled_at: 2010-05-08 15:17:40 7 | 8 | two: 9 | voltage: 1.5 10 | source_id: 1 11 | sampled_at: 2010-05-08 15:17:40 12 | -------------------------------------------------------------------------------- /db/migrate/20090630005902_create_sources.rb: -------------------------------------------------------------------------------- 1 | class CreateSources < ActiveRecord::Migration 2 | def self.up 3 | create_table :sources do |t| 4 | t.string :name 5 | 6 | t.timestamps 7 | end 8 | end 9 | 10 | def self.down 11 | drop_table :sources 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /test/performance/browsing_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require 'performance_test_help' 3 | 4 | # Profiling results for each test method are written to tmp/performance. 5 | class BrowsingTest < ActionController::PerformanceTest 6 | def test_homepage 7 | get '/' 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20090827003958_add_source_to_report_parameters.rb: -------------------------------------------------------------------------------- 1 | class AddSourceToReportParameters < ActiveRecord::Migration 2 | def self.up 3 | add_column :report_parameters, :source, :string 4 | end 5 | 6 | def self.down 7 | remove_column :report_parameters, :source 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20100314150814_add_index_to_fahrenheit_temps_created_at.rb: -------------------------------------------------------------------------------- 1 | class AddIndexToFahrenheitTempsCreatedAt < ActiveRecord::Migration 2 | def self.up 3 | add_index :fahrenheit_temps, :created_at 4 | end 5 | 6 | def self.down 7 | remove_index :fahrenheit_temps, :created_at 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20110319183317_add_sampled_at_index_to_fahrenheit_temps.rb: -------------------------------------------------------------------------------- 1 | class AddSampledAtIndexToFahrenheitTemps < ActiveRecord::Migration 2 | def self.up 3 | add_index :fahrenheit_temps, :sampled_at 4 | end 5 | 6 | def self.down 7 | remove_index :fahrenheit_temps, :sampled_at 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /test/fixtures/time_periods.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html 2 | 3 | one: 4 | source_id: 1 5 | time_start: 2009-06-29 18:01:43 6 | time_end: 2009-06-29 18:01:43 7 | 8 | two: 9 | source_id: 1 10 | time_start: 2009-06-29 18:01:43 11 | time_end: 2009-06-29 18:01:43 12 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/chart.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class Chart < Base 4 | def initialize( title=nil, args={}) 5 | super args 6 | @title = Title.new( title ) if title 7 | end 8 | end 9 | 10 | class OpenFlashChart < Chart 11 | end 12 | 13 | end 14 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # Edit this Gemfile to bundle your application's dependencies. 2 | # This preamble is the current preamble for Rails 3 apps; edit as needed. 3 | source 'http://rubygems.org' 4 | 5 | gem 'rails', '3.0.5' 6 | gem 'rake', '~> 0.8.7' 7 | gem 'pg' 8 | gem 'serialport' 9 | gem 'shoulda' 10 | gem 'backup-task' 11 | gem 'fog' 12 | -------------------------------------------------------------------------------- /app/views/sources/new.html.erb: -------------------------------------------------------------------------------- 1 |

New source

2 | 3 | <% form_for(@source) do |f| %> 4 | <%= f.error_messages %> 5 | 6 |

7 | <%= f.label :name %>
8 | <%= f.text_field :name %> 9 |

10 |

11 | <%= f.submit 'Create' %> 12 |

13 | <% end %> 14 | 15 | <%= link_to 'Back', sources_path %> -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/scatter_line.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class ScatterLine < Base 4 | def initialize(colour, dot_size, args={}) 5 | super args 6 | @type = 'scatter_line' 7 | @colour = colour 8 | @dot_size = dot_size 9 | end 10 | end 11 | 12 | end -------------------------------------------------------------------------------- /app/models/source.rb: -------------------------------------------------------------------------------- 1 | class Source < ActiveRecord::Base 2 | has_many :report_sources 3 | has_many :reports, :through => :report_sources 4 | 5 | validates_numericality_of :temp_offset, :only_integer => false 6 | 7 | def self.get(name) 8 | self.find_by_name(name) || self.new(:name => name, :temp_offset => 0) 9 | end 10 | 11 | end 12 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require File.expand_path('../config/application', __FILE__) 5 | 6 | require 'rake' 7 | require 'rake/testtask' 8 | require 'rake/rdoctask' 9 | 10 | Rails::Application.load_tasks 11 | -------------------------------------------------------------------------------- /db/migrate/20090730022539_create_fahrenheit_temps.rb: -------------------------------------------------------------------------------- 1 | class CreateFahrenheitTemps < ActiveRecord::Migration 2 | def self.up 3 | create_table :fahrenheit_temps do |t| 4 | t.float :temp 5 | t.integer :source_id 6 | 7 | t.timestamps 8 | end 9 | end 10 | 11 | def self.down 12 | drop_table :fahrenheit_temps 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /app/views/voltages/show.html.erb: -------------------------------------------------------------------------------- 1 |

2 | Voltage: 3 | <%=h @voltage.voltage %> 4 |

5 | 6 |

7 | Source: 8 | <%=h @voltage.source_id %> 9 |

10 | 11 |

12 | Sampled at: 13 | <%=h @voltage.sampled_at %> 14 |

15 | 16 | 17 | <%= link_to 'Edit', edit_voltage_path(@voltage) %> | 18 | <%= link_to 'Back', voltages_path %> -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | DataLogger::Application.routes.draw do 2 | resources :voltages, :fahrenheit_temps, :time_periods 3 | 4 | resources :sources do |source| 5 | resources :fahrenheit_temps do 6 | collection do 7 | get 'latest' 8 | end 9 | end 10 | end 11 | 12 | match '/:controller/:action' 13 | root :to => "report#index" 14 | end 15 | -------------------------------------------------------------------------------- /db/migrate/20090817025242_create_report_parameters.rb: -------------------------------------------------------------------------------- 1 | class CreateReportParameters < ActiveRecord::Migration 2 | def self.up 3 | create_table :report_parameters do |t| 4 | t.timestamp :start 5 | t.timestamp :end 6 | 7 | t.timestamps 8 | end 9 | end 10 | 11 | def self.down 12 | drop_table :report_parameters 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /db/migrate/20100508201740_create_voltages.rb: -------------------------------------------------------------------------------- 1 | class CreateVoltages < ActiveRecord::Migration 2 | def self.up 3 | create_table :voltages do |t| 4 | t.float :voltage 5 | t.integer :source_id 6 | t.datetime :sampled_at 7 | 8 | t.timestamps 9 | end 10 | end 11 | 12 | def self.down 13 | drop_table :voltages 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/bar_3d.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class Bar3d < BarBase 4 | def initialize args={} 5 | super 6 | @type = "bar_3d" 7 | end 8 | end 9 | 10 | class Bar3dValue < Base 11 | def initialize(top, args={}) 12 | @top = top 13 | super args 14 | end 15 | end 16 | 17 | end -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/bar_glass.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class BarGlass < BarBase 4 | def initialize args={} 5 | super 6 | @type = "bar_glass" 7 | end 8 | end 9 | 10 | class BarGlassValue < Base 11 | def initialize(top, args={}) 12 | @top = top 13 | super args 14 | end 15 | end 16 | 17 | end -------------------------------------------------------------------------------- /db/migrate/20090630010143_create_time_periods.rb: -------------------------------------------------------------------------------- 1 | class CreateTimePeriods < ActiveRecord::Migration 2 | def self.up 3 | create_table :time_periods do |t| 4 | t.integer :source_id 5 | t.datetime :time_start 6 | t.datetime :time_end 7 | 8 | t.timestamps 9 | end 10 | end 11 | 12 | def self.down 13 | drop_table :time_periods 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/area_base.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | class AreaBase < Base 3 | def initialize args={} 4 | super 5 | @fill_alpha = 0.35 6 | @values = [] 7 | end 8 | 9 | def set_fill_colour(color) 10 | @fill = color 11 | end 12 | 13 | def set_loop 14 | @loop = true 15 | end 16 | end 17 | end -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/line_base.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class LineBase < Base 4 | def initialize args={} 5 | super 6 | @type = "line_dot" 7 | @text = "Page Views" 8 | @font_size = 10 9 | @values = [9,6,7,9,5,7,6,9,7] 10 | end 11 | 12 | def loop 13 | @loop = true 14 | end 15 | end 16 | 17 | end -------------------------------------------------------------------------------- /app/views/time_periods/show.html.erb: -------------------------------------------------------------------------------- 1 |

2 | Source: 3 | <%=h @time_period.source_id %> 4 |

5 | 6 |

7 | Time start: 8 | <%=h @time_period.time_start %> 9 |

10 | 11 |

12 | Time end: 13 | <%=h @time_period.time_end %> 14 |

15 | 16 | 17 | <%= link_to 'Edit', edit_time_period_path(@time_period) %> | 18 | <%= link_to 'Back', time_periods_path %> -------------------------------------------------------------------------------- /db/migrate/20090802175653_add_logged_at_to_fahrenheit_temp.rb: -------------------------------------------------------------------------------- 1 | class AddLoggedAtToFahrenheitTemp < ActiveRecord::Migration 2 | def self.up 3 | add_column :fahrenheit_temps, :sampled_at, :datetime 4 | execute("update fahrenheit_temps set sampled_at = created_at where sampled_at is null") 5 | end 6 | 7 | def self.down 8 | remove_column :fahrenheit_temps, :sampled_at 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/bar.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class Bar < BarBase 4 | def initialize args={} 5 | super 6 | @type = "bar" 7 | end 8 | end 9 | 10 | class BarValue < Base 11 | def initialize( top, bottom=nil, args={} ) 12 | @top = top 13 | @bottom = bottom 14 | super args 15 | end 16 | end 17 | 18 | end -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/bar_sketch.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class BarSketch < BarBase 4 | def initialize(colour, outline_colour, fun_factor, args = {} ) 5 | super args 6 | @type = "bar_sketch" 7 | @colour = colour 8 | @outline_colour = outline_colour 9 | @offset = fun_factor 10 | end 11 | end 12 | 13 | end -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/line_dot.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class LineDot < LineBase 4 | def initialize args={} 5 | super 6 | @type = "line_dot" 7 | end 8 | end 9 | 10 | class DotValue < Base 11 | def initialize(value, colour, args={}) 12 | @value = value 13 | @colour = colour 14 | super(args) 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /app/views/fahrenheit_temps/show.html.erb: -------------------------------------------------------------------------------- 1 |

2 | Temp: 3 | <%=h @fahrenheit_temp.temp %> 4 |

5 | 6 |

7 | Sampled At: 8 | <%=h @fahrenheit_temp.sampled_at %> 9 |

10 | 11 |

12 | Source: 13 | <%=h @fahrenheit_temp.source_id %> 14 |

15 | 16 | 17 | <%= link_to 'Edit', edit_fahrenheit_temp_path(@fahrenheit_temp) %> | 18 | <%= link_to 'Back', fahrenheit_temps_path %> 19 | -------------------------------------------------------------------------------- /script/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. 3 | 4 | ENV_PATH = File.expand_path('../../config/environment', __FILE__) 5 | BOOT_PATH = File.expand_path('../../config/boot', __FILE__) 6 | APP_PATH = File.expand_path('../../config/application', __FILE__) 7 | 8 | require BOOT_PATH 9 | require 'rails/commands' 10 | -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format 4 | # (all these examples are active by default): 5 | # ActiveSupport::Inflector.inflections do |inflect| 6 | # inflect.plural /^(ox)$/i, '\1en' 7 | # inflect.singular /^(ox)en/i, '\1' 8 | # inflect.irregular 'person', 'people' 9 | # inflect.uncountable %w( fish sheep ) 10 | # end 11 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/shape.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class ShapePoint < Base 4 | def initialize(x, y, args={}) 5 | super args 6 | @x = x 7 | @y = y 8 | end 9 | end 10 | 11 | class Shape < Base 12 | def initialize(colour, args={}) 13 | @type = "shape" 14 | @colour = colour 15 | @values = [] 16 | super args 17 | end 18 | end 19 | 20 | end -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying do debug a problem that might steem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/candle.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class Candle < Base 4 | def initialize(args={}) 5 | super args 6 | @type = "candle" 7 | end 8 | end 9 | 10 | class CandleValue < Base 11 | def initialize( top, bottom, low, high, args={} ) 12 | @top = top 13 | @bottom = bottom 14 | @low = low 15 | @high = high 16 | super args 17 | end 18 | end 19 | 20 | end -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/bar_stack.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class BarStack < BarBase 4 | def initialize args={} 5 | super 6 | @type = "bar_stack" 7 | end 8 | 9 | alias_method :append_stack, :append_value 10 | end 11 | 12 | class BarStackValue < Base 13 | def initialize(val,colour, args={}) 14 | @val = val 15 | @colour = colour 16 | super 17 | end 18 | end 19 | 20 | end -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/init.rb: -------------------------------------------------------------------------------- 1 | require 'open_flash_chart' 2 | 3 | ActionView::Base.send :include, OpenFlashChart::View 4 | OpenFlashChart::Base.send :include, OpenFlashChart::View 5 | ActionController::Base.send :include, OpenFlashChart::Controller 6 | ActionController::Base.send :include, OpenFlashChart 7 | ActiveRecord::Base.send :include, OpenFlashChart::View 8 | ActiveRecord::Base.send :include, OpenFlashChart::Controller 9 | ActiveRecord::Base.send :include, OpenFlashChart -------------------------------------------------------------------------------- /app/views/sources/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Editing source

2 | 3 | <% form_for(@source) do |f| %> 4 | <%= f.error_messages %> 5 | 6 |

7 | <%= f.label :name %>
8 | <%= f.text_field :name %> 9 |

10 |

11 | <%= f.label :temp_offset %>
12 | <%= f.text_field :temp_offset %> 13 |

14 |

15 | <%= f.submit 'Update' %> 16 |

17 | <% end %> 18 | 19 | <%= link_to 'Show', @source %> | 20 | <%= link_to 'Back', sources_path %> 21 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/x_axis_label.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class XAxisLabel < Base 4 | def initialize(text, colour, size, rotate, args={}) 5 | super args 6 | @text = text 7 | @colour = colour 8 | @size = size 9 | @rotate = rotate 10 | end 11 | 12 | def set_vertical 13 | @rotate = "vertical" 14 | end 15 | 16 | def set_visible 17 | @visible = true 18 | end 19 | end 20 | 21 | end -------------------------------------------------------------------------------- /app/models/voltage.rb: -------------------------------------------------------------------------------- 1 | class Voltage < ActiveRecord::Base 2 | belongs_to :source 3 | validates_presence_of :source_id 4 | validates_numericality_of :voltage 5 | 6 | def parse(string) 7 | puts "voltage = #{string}" 8 | if md = string.match(/([^:])+:([^:])+/) 9 | self.voltage = Float(md[1]) 10 | self.sampled_at = Time.at(md[2]) 11 | else 12 | self.voltage = Float(string) 13 | self.sampled_at = Time.now 14 | end 15 | return self 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/bar_filled.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class BarFilled < BarBase 4 | def initialize(colour=nil, outline_colour=nil, args={}) 5 | super args 6 | @type = "bar_filled" 7 | @colour = colour 8 | @outline_colour = outline_colour 9 | end 10 | end 11 | 12 | class BarFilledValue < BarValue 13 | def initialize(top, bottom=nil, args={}) 14 | super 15 | end 16 | end 17 | 18 | end -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/tooltip.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class Tooltip < Base 4 | def set_body_style(style) 5 | @body = style 6 | end 7 | 8 | def set_title_style(style) 9 | @title = style 10 | end 11 | 12 | def set_background_colour(bg) 13 | @background = bg 14 | end 15 | 16 | def set_proximity 17 | @mouse = 1 18 | end 19 | 20 | def set_hover 21 | @mouse = 2 22 | end 23 | end 24 | 25 | end -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | # Filters added to this controller apply to all controllers in the application. 2 | # Likewise, all the methods added will be available for all controllers. 3 | 4 | class ApplicationController < ActionController::Base 5 | helper :all # include all helpers, all the time 6 | protect_from_forgery # See ActionController::RequestForgeryProtection for details 7 | 8 | # Scrub sensitive parameters from your log 9 | # filter_parameter_logging :password 10 | end 11 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/scatter.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class ScatterValue < Base 4 | def initialize(x,y,dot_size=nil, args={}) 5 | super args 6 | @x = x 7 | @y = y 8 | @dot_size = dot_size if dot_size.to_i > 0 9 | end 10 | end 11 | 12 | class Scatter < Base 13 | def initialize(colour, dot_size, args={}) 14 | @type = "scatter" 15 | @colour = colour 16 | @dot_size = dot_size 17 | super args 18 | end 19 | end 20 | 21 | end -------------------------------------------------------------------------------- /app/views/voltages/new.html.erb: -------------------------------------------------------------------------------- 1 |

New voltage

2 | 3 | <% form_for(@voltage) do |f| %> 4 | <%= f.error_messages %> 5 | 6 |

7 | <%= f.label :voltage %>
8 | <%= f.text_field :voltage %> 9 |

10 |

11 | <%= f.label :source_id %>
12 | <%= f.text_field :source_id %> 13 |

14 |

15 | <%= f.label :sampled_at %>
16 | <%= f.datetime_select :sampled_at %> 17 |

18 |

19 | <%= f.submit 'Create' %> 20 |

21 | <% end %> 22 | 23 | <%= link_to 'Back', voltages_path %> -------------------------------------------------------------------------------- /db/migrate/20090829141507_create_report_sources.rb: -------------------------------------------------------------------------------- 1 | class CreateReportSources < ActiveRecord::Migration 2 | def self.up 3 | create_table :report_sources do |t| 4 | t.integer :report_id 5 | t.integer :source_id 6 | 7 | t.timestamps 8 | end 9 | 10 | add_index :report_sources, :report_id 11 | add_index :report_sources, :source_id 12 | 13 | remove_column :report_parameters, :source 14 | end 15 | 16 | def self.down 17 | drop_table :report_sources 18 | add_column :report_parameters, :source, :string 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /app/views/layouts/voltages.html.erb: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | Voltages: <%= controller.action_name %> 8 | <%= stylesheet_link_tag 'scaffold' %> 9 | 10 | 11 | 12 |

<%= flash[:notice] %>

13 | 14 | <%= yield %> 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /app/views/time_periods/new.html.erb: -------------------------------------------------------------------------------- 1 |

New time_period

2 | 3 | <% form_for(@time_period) do |f| %> 4 | <%= f.error_messages %> 5 | 6 |

7 | <%= f.label :source_id %>
8 | <%= f.text_field :source_id %> 9 |

10 |

11 | <%= f.label :time_start %>
12 | <%= f.datetime_select :time_start %> 13 |

14 |

15 | <%= f.label :time_end %>
16 | <%= f.datetime_select :time_end %> 17 |

18 |

19 | <%= f.submit 'Create' %> 20 |

21 | <% end %> 22 | 23 | <%= link_to 'Back', time_periods_path %> -------------------------------------------------------------------------------- /app/views/fahrenheit_temps/new.html.erb: -------------------------------------------------------------------------------- 1 |

New fahrenheit_temp

2 | 3 | <% form_for(@fahrenheit_temp) do |f| %> 4 | <%= f.error_messages %> 5 | 6 |

7 | <%= f.label :temp %>
8 | <%= f.text_field :temp %> 9 |

10 |

11 | <%= f.label :sampled_at %>
12 | <%= f.text_field :sampled_at %> 13 |

14 |

15 | <%= f.label :source_id %>
16 | <%= f.text_field :source_id %> 17 |

18 |

19 | <%= f.submit 'Create' %> 20 |

21 | <% end %> 22 | 23 | <%= link_to 'Back', fahrenheit_temps_path %> 24 | -------------------------------------------------------------------------------- /app/views/voltages/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Editing voltage

2 | 3 | <% form_for(@voltage) do |f| %> 4 | <%= f.error_messages %> 5 | 6 |

7 | <%= f.label :voltage %>
8 | <%= f.text_field :voltage %> 9 |

10 |

11 | <%= f.label :source_id %>
12 | <%= f.text_field :source_id %> 13 |

14 |

15 | <%= f.label :sampled_at %>
16 | <%= f.datetime_select :sampled_at %> 17 |

18 |

19 | <%= f.submit 'Update' %> 20 |

21 | <% end %> 22 | 23 | <%= link_to 'Show', @voltage %> | 24 | <%= link_to 'Back', voltages_path %> -------------------------------------------------------------------------------- /app/views/sources/index.html.erb: -------------------------------------------------------------------------------- 1 |

Listing sources

2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | <% @sources.each do |source| %> 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | <% end %> 18 |
NameTemp Offset
<%=h source.name %><%=h source.temp_offset %><%= link_to 'Show', source %><%= link_to 'Edit', edit_source_path(source) %><%= link_to 'Destroy', source, :confirm => 'Are you sure?', :method => :delete %>
19 | 20 |
21 | 22 | <%= link_to 'New source', new_source_path %> 23 | -------------------------------------------------------------------------------- /app/models/time_period.rb: -------------------------------------------------------------------------------- 1 | class TimePeriod < ActiveRecord::Base 2 | belongs_to :source 3 | validates_presence_of :time_start, :time_end 4 | 5 | validates_each :time_start do |record, attr, value| 6 | record.errors.add attr, 'must be before end_time' if value >= time_end 7 | end 8 | 9 | def parse(string) 10 | if md = string.match(/(\d+):(\d+)/) 11 | self.time_start = Time.at(Integer(md[1])) 12 | self.time_end = Time.at(Integer(md[2])) 13 | else 14 | self.errors.add_to_base "Unable to parse event string" 15 | end 16 | 17 | return self 18 | end 19 | 20 | end 21 | -------------------------------------------------------------------------------- /app/views/time_periods/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Editing time_period

2 | 3 | <% form_for(@time_period) do |f| %> 4 | <%= f.error_messages %> 5 | 6 |

7 | <%= f.label :source_id %>
8 | <%= f.text_field :source_id %> 9 |

10 |

11 | <%= f.label :time_start %>
12 | <%= f.datetime_select :time_start %> 13 |

14 |

15 | <%= f.label :time_end %>
16 | <%= f.datetime_select :time_end %> 17 |

18 |

19 | <%= f.submit 'Update' %> 20 |

21 | <% end %> 22 | 23 | <%= link_to 'Show', @time_period %> | 24 | <%= link_to 'Back', time_periods_path %> -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/h_bar.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class HBarValue < Base 4 | def initialize(left,right=nil, args={}) 5 | super args 6 | @left = left 7 | @right = right || left 8 | end 9 | end 10 | 11 | class HBar < Base 12 | def initialize(colour="#9933CC", args={}) 13 | super args 14 | @type = "hbar" 15 | @colour = colour 16 | @values = [] 17 | end 18 | 19 | def set_values(v) 20 | v.each do |val| 21 | append_value(HBarValue.new(val)) 22 | end 23 | end 24 | end 25 | 26 | end -------------------------------------------------------------------------------- /app/views/fahrenheit_temps/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Editing fahrenheit_temp

2 | 3 | <% form_for(@fahrenheit_temp) do |f| %> 4 | <%= f.error_messages %> 5 | 6 |

7 | <%= f.label :temp %>
8 | <%= f.text_field :temp %> 9 |

10 |

11 | <%= f.label :sampled_at %>
12 | <%= f.text_field :sampled_at %> 13 |

14 |

15 | <%= f.label :source_id %>
16 | <%= f.text_field :source_id %> 17 |

18 |

19 | <%= f.submit 'Update' %> 20 |

21 | <% end %> 22 | 23 | <%= link_to 'Show', @fahrenheit_temp %> | 24 | <%= link_to 'Back', fahrenheit_temps_path %> 25 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/x_axis.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class XAxis < Base 4 | def set_3d(v) 5 | @threed = v 6 | end 7 | # for some reason the json that needs to be produced is like this: 8 | # "x_axis": { "offset": false, "labels": { "labels": [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ] } } 9 | # note the "labels":{"labels": ....} 10 | def set_labels(labels) 11 | @labels = labels 12 | @labels = {:labels => labels} unless labels.is_a?(XAxisLabels) 13 | end 14 | 15 | alias_method :labels=, :set_labels 16 | end 17 | 18 | end -------------------------------------------------------------------------------- /app/views/voltages/index.html.erb: -------------------------------------------------------------------------------- 1 |

Listing voltages

2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | <% @voltages.each do |voltage| %> 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | <% end %> 20 |
VoltageSourceSampled at
<%=h voltage.voltage %><%=h voltage.source_id %><%=h voltage.sampled_at %><%= link_to 'Show', voltage %><%= link_to 'Edit', edit_voltage_path(voltage) %><%= link_to 'Destroy', voltage, :confirm => 'Are you sure?', :method => :delete %>
21 | 22 |
23 | 24 | <%= link_to 'New voltage', new_voltage_path %> -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/Rakefile: -------------------------------------------------------------------------------- 1 | require 'rake' 2 | require 'rake/testtask' 3 | require 'rake/rdoctask' 4 | 5 | desc 'Default: run unit tests.' 6 | task :default => :test 7 | 8 | desc 'Test the open_flash_chart plugin.' 9 | Rake::TestTask.new(:test) do |t| 10 | t.libs << 'lib' 11 | t.pattern = 'test/**/*_test.rb' 12 | t.verbose = true 13 | end 14 | 15 | desc 'Generate documentation for the open_flash_chart plugin.' 16 | Rake::RDocTask.new(:rdoc) do |rdoc| 17 | rdoc.rdoc_dir = 'rdoc' 18 | rdoc.title = 'OpenFlashChart' 19 | rdoc.options << '--line-numbers' << '--inline-source' 20 | rdoc.rdoc_files.include('README') 21 | rdoc.rdoc_files.include('lib/**/*.rb') 22 | end 23 | -------------------------------------------------------------------------------- /config/database.yml.example: -------------------------------------------------------------------------------- 1 | # we're using postgres as our database 2 | development: 3 | adapter: postgresql 4 | encoding: unicode 5 | database: data_logger_dev 6 | username: postgres 7 | password: sergtsop 8 | host: localhost 9 | 10 | 11 | # Warning: The database defined as "test" will be erased and 12 | # re-generated from your development database when you run "rake". 13 | # Do not set this db to the same as development or production. 14 | test: 15 | adapter: sqlite3 16 | database: db/test.sqlite3 17 | pool: 5 18 | timeout: 5000 19 | 20 | production: 21 | adapter: postgresql 22 | encoding: unicode 23 | database: data_logger_prod 24 | username: postgres 25 | password: sergtsop 26 | host: localhost 27 | -------------------------------------------------------------------------------- /app/views/time_periods/index.html.erb: -------------------------------------------------------------------------------- 1 |

Listing time_periods

2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | <% @time_periods.each do |time_period| %> 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | <% end %> 20 |
SourceTime startTime end
<%=h time_period.source_id %><%=h time_period.time_start %><%=h time_period.time_end %><%= link_to 'Show', time_period %><%= link_to 'Edit', edit_time_period_path(time_period) %><%= link_to 'Destroy', time_period, :confirm => 'Are you sure?', :method => :delete %>
21 | 22 |
23 | 24 | <%= link_to 'New time_period', new_time_period_path %> -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/install.rb: -------------------------------------------------------------------------------- 1 | # Workaround a problem with script/plugin and http-based repos. 2 | # See http://dev.rubyonrails.org/ticket/8189 3 | Dir.chdir(Dir.getwd.sub(/vendor.*/, '')) do 4 | 5 | ## 6 | ## Copy over asset files (javascript/css/images) from the plugin directory to public/ 7 | ## 8 | 9 | def copy_files(source_path, destination_path, directory) 10 | source, destination = File.join(directory, source_path), File.join(RAILS_ROOT, destination_path) 11 | # FileUtils.mkdir(destination) unless File.exist?(destination) 12 | FileUtils.cp_r(Dir.glob(source+'/*.*'), destination) 13 | end 14 | 15 | directory = File.dirname(__FILE__) 16 | copy_files("/assets", "/public", directory) 17 | end 18 | -------------------------------------------------------------------------------- /app/models/#fahrenheit_temp.rb#: -------------------------------------------------------------------------------- 1 | class FahrenheitTemp < ActiveRecord::Base 2 | belongs_to :source 3 | validates_presence_of :source_id 4 | validates_numericality_of :temp 5 | 6 | def display_time 7 | self.created_at.asctime 8 | end 9 | 10 | def display_temp 11 | if self.source.temp_offset.nil? 12 | self.temp 13 | else 14 | self.temp + self.source.temp_offset 15 | end 16 | end 17 | 18 | def parse(string) 19 | puts "temp = #{string}" 20 | if md = string.match(/([^:])+:([^:])+/) 21 | self.temp = Float(md[1]) 22 | self.sampled_at = Time.at(md[2]) 23 | else 24 | self.temp = Float(string) 25 | self.sampled_at = Time.now 26 | end 27 | return self 28 | end 29 | 30 | end 31 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | == Data Logger 2 | 3 | This is a fairly basic app designed to read data from a variety of 4 | sensors over a serial port, store them in a PostgreSQL database, and 5 | display them on the web. 6 | 7 | The data comes from Arduino units. The source code for that is in the 8 | arduino directory. 9 | 10 | Eventually it will support downloading data that has been logged in 11 | the past. Currently it assumes all data is freshly generated 12 | (i.e. sensor was read just before transmission). 13 | 14 | == Sensors 15 | 16 | Right now, the only two sensors supported are a temperature sensor 17 | (i.e. DS18B20 one-wire device) and a timing sensor - just counting 18 | seconds between pin transitions. 19 | 20 | The temperature sensors have been used extensively for several months. 21 | 22 | -------------------------------------------------------------------------------- /app/views/fahrenheit_temps/index.html.erb: -------------------------------------------------------------------------------- 1 |

Listing fahrenheit_temps

2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | <% @fahrenheit_temps.each do |fahrenheit_temp| %> 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | <% end %> 20 |
TempSampled atSource
<%=h fahrenheit_temp.temp %><%=h fahrenheit_temp.sampled_at %><%=h fahrenheit_temp.source_id %><%= link_to 'Show', fahrenheit_temp %><%= link_to 'Edit', edit_fahrenheit_temp_path(fahrenheit_temp) %><%= link_to 'Destroy', fahrenheit_temp, :confirm => 'Are you sure?', :method => :delete %>
21 | 22 |
23 | 24 | <%= link_to 'New fahrenheit_temp', new_fahrenheit_temp_path %> 25 | -------------------------------------------------------------------------------- /app/models/fahrenheit_temp.rb: -------------------------------------------------------------------------------- 1 | class FahrenheitTemp < ActiveRecord::Base 2 | belongs_to :source 3 | validates_presence_of :source_id 4 | validates_numericality_of :temp 5 | 6 | def display_time 7 | self.created_at.asctime 8 | end 9 | 10 | def display_temp 11 | dt = if self.source.temp_offset.nil? 12 | self.temp 13 | else 14 | self.temp + self.source.temp_offset 15 | end 16 | 17 | sprintf("%.2f", dt) 18 | end 19 | 20 | def parse(string) 21 | puts "temp = #{string}" 22 | if md = string.match(/([^:])+:([^:])+/) 23 | self.temp = Float(md[1]) 24 | self.sampled_at = Time.at(md[2]) 25 | else 26 | self.temp = Float(string) 27 | self.sampled_at = Time.now 28 | end 29 | return self 30 | end 31 | 32 | end 33 | -------------------------------------------------------------------------------- /app/views/report/latest_trends.html.erb: -------------------------------------------------------------------------------- 1 |
2 | 25 | -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | DataLogger::Application.configure do 2 | # Settings specified here will take precedence over those in config/environment.rb 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the webserver when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Log error messages when you accidentally call methods on nil. 10 | config.whiny_nils = true 11 | 12 | # Show full error reports and disable caching 13 | config.consider_all_requests_local = true 14 | config.action_view.debug_rjs = true 15 | config.action_controller.perform_caching = false 16 | 17 | # Don't care if the mailer can't send 18 | config.action_mailer.raise_delivery_errors = false 19 | end 20 | -------------------------------------------------------------------------------- /config/initializers/new_rails_defaults.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # These settings change the behavior of Rails 2 apps and will be defaults 4 | # for Rails 3. You can remove this initializer when Rails 3 is released. 5 | 6 | if defined?(ActiveRecord) 7 | # Include Active Record class name as root for JSON serialized output. 8 | ActiveRecord::Base.include_root_in_json = true 9 | 10 | # Store the full class name (including module namespace) in STI type column. 11 | ActiveRecord::Base.store_full_sti_class = true 12 | end 13 | 14 | # Use ISO 8601 format for JSON serialized times and dates. 15 | ActiveSupport.use_standard_json_time_format = true 16 | 17 | # Don't escape HTML entities in JSON, leave that for the #json_escape helper. 18 | # if you're including raw json in an HTML page. 19 | ActiveSupport.escape_html_entities_in_json = false -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key for verifying cookie session data integrity. 4 | # If you change this key, all old sessions will become invalid! 5 | # Make sure the secret is at least 30 characters and all random, 6 | # no regular words or you'll be exposed to dictionary attacks. 7 | ActionController::Base.session = { 8 | :key => '_data_logger_session', 9 | :secret => '7992a4f31d46d4ea3143464a1f280733d2a68ef09e2c3790e8238d334f920c88f9af2b0df5bdafcbddd8852ce5517b01b9653c1b515fb8bdac4f85a731c4eb60' 10 | } 11 | 12 | # Use the database for sessions instead of the cookie-based default, 13 | # which shouldn't be used to store highly confidential information 14 | # (create the session table with "rake db:sessions:create") 15 | # ActionController::Base.session_store = :active_record_store 16 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/pie.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | 3 | class PieValue < Base 4 | def initialize(value, label, args={}) 5 | super args 6 | @value = value 7 | @label = label 8 | end 9 | 10 | def set_label(label, label_color, font_size) 11 | self.label = label 12 | self.label_colour = label_color 13 | self.font_size = font_size 14 | end 15 | 16 | def on_click(event) 17 | @on_click = event 18 | end 19 | end 20 | 21 | class Pie < Base 22 | def initialize args={} 23 | @type = "pie" 24 | @colours = ["#d01f3c","#356aa0","#C79810"] 25 | @border = 2 26 | super 27 | end 28 | 29 | def set_no_labels 30 | self.no_labels = true 31 | end 32 | 33 | def on_click(event) 34 | @on_click = event 35 | end 36 | end 37 | 38 | end -------------------------------------------------------------------------------- /app/models/log_event.rb: -------------------------------------------------------------------------------- 1 | require 'crc16' 2 | 3 | class LogEvent 4 | 5 | # event_type:source:event data... 6 | def self.parse(event_string) 7 | if md = event_string.match(/(([^:]+):([^:]+):(.+):)([^:]+)/) 8 | 9 | event = case md[2] 10 | when "P" then TimePeriod.new() 11 | when "T" then FahrenheitTemp.new() 12 | when "V" then Voltage.new() 13 | end 14 | 15 | if event 16 | crc = sprintf("%04X", Crc16.new.crc16(md[1])) 17 | unless crc == md[5] 18 | event.errors.add_to_base("invalid - failed CRC check") 19 | return event 20 | end 21 | 22 | source = Source.get(md[3]) 23 | source.save unless source.id 24 | 25 | event.source = source 26 | event.parse(md[4]) 27 | return event 28 | end 29 | end 30 | 31 | return nil 32 | end 33 | 34 | end 35 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/linear_regression.rb: -------------------------------------------------------------------------------- 1 | # by David Lowenfels @ InternautDesign.com 2 | # example usage: fitted_data = LinearRegression.new(data).fit 3 | 4 | class LinearRegression 5 | attr_accessor :slope, :offset 6 | 7 | def initialize dx, dy=nil 8 | @size = dx.size 9 | if @size == 1 10 | @slope, @offset = 1,0 11 | return 12 | end 13 | dy,dx = dx,axis() unless dy # make 2D if given 1D 14 | raise "arguments not same length!" unless @size == dy.size 15 | sxx = sxy = sx = sy = 0 16 | dx.zip(dy).each do |x,y| 17 | sxy += x*y 18 | sxx += x*x 19 | sx += x 20 | sy += y 21 | end 22 | @slope = ( @size * sxy - sx*sy ) / ( @size * sxx - sx * sx ) 23 | @offset = (sy - @slope*sx) / @size 24 | end 25 | 26 | def fit 27 | return axis.map{|data| predict(data) } 28 | end 29 | 30 | private 31 | 32 | def predict( x ) 33 | y = @slope * x + @offset 34 | end 35 | 36 | def axis 37 | (0...@size).to_a 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | The change you wanted was rejected (422) 9 | 21 | 22 | 23 | 24 | 25 |
26 |

The change you wanted was rejected.

27 |

Maybe you tried to change something you didn't have access to.

28 |
29 | 30 | -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | The page you were looking for doesn't exist (404) 9 | 21 | 22 | 23 | 24 | 25 |
26 |

The page you were looking for doesn't exist.

27 |

You may have mistyped the address or the page may have moved.

28 |
29 | 30 | -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | We're sorry, but something went wrong (500) 9 | 21 | 22 | 23 | 24 | 25 |
26 |

We're sorry, but something went wrong.

27 |

We've been notified about this issue and we'll take a look at it shortly.

28 |
29 | 30 | 31 | -------------------------------------------------------------------------------- /app/views/report/index.html.erb: -------------------------------------------------------------------------------- 1 | You can check out the 2 | <%= link_to "latest temperatures", :action => 'latest_temps' %>, 3 | check the <%= link_to "latest trends", :action => 'latest_trends' %>, 4 | or you can request a custom report: 5 | 6 | 7 | 8 | <%= form_for @report, :url => { :controller => 'report', 9 | :action => 'manual' } do |f| %> 10 |

11 | 12 | 13 | 17 | 22 | 23 | 24 | 27 | 30 | 31 | 32 | 35 | 38 | 39 | 40 | 42 | 45 | 46 |
14 | <%= f.fields_for :sources do |sf| %> 15 | <%= sf.label :name, "Sources" %> 16 | 18 | <%= collection_select :report, :sources, 19 | @sources, :id, :name, {}, {:multiple => true, :size => 6} %> 20 | <% end %> 21 |
25 | <%= f.label :start %> 26 | 28 | <%= f.text_field :start %> 29 |
33 | <%= f.label :end %> 34 | 36 | <%= f.text_field :end %> 37 |
41 | 43 | <%= submit_tag 'submit' %> 44 |
47 | <% end %> 48 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/MIT-LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2008 [name of plugin creator] 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. 21 | -------------------------------------------------------------------------------- /script/data_logger_listener: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | puts 'loading Rails...' 4 | require File.expand_path('../../config/boot', __FILE__) 5 | require File.expand_path('../../config/application', __FILE__) 6 | 7 | 8 | 9 | Rails.application.require_environment! 10 | 11 | serial_port = ENV['SERIAL_PORT'] 12 | unless serial_port 13 | puts "You must set the SERIAL_PORT environment variable in order for" 14 | puts "this script to find your serial port/xbee reader." 15 | puts "\nFor example: " 16 | puts "SERIAL_PORT=/dev/ttyUSB0 bundle exec #{$0}" 17 | exit 1 18 | end 19 | 20 | require 'serialport' 21 | 22 | sp = SerialPort.new serial_port 23 | puts "ready and listening" 24 | 25 | while true 26 | foo = sp.gets 27 | puts foo 28 | foo.chomp! 29 | begin 30 | if e = LogEvent.parse(foo) 31 | puts e.inspect 32 | if e.save 33 | md = foo.match(/:([^:]+)$/) 34 | ack = "R:#{md[1]}" 35 | sp.puts(ack) 36 | puts "#{e.class.to_s} #{e.id} saved" 37 | else 38 | puts e.errors.full_messages 39 | end 40 | end 41 | rescue Object => e 42 | Rails.logger.warn("error parsing and saving event - (#{e})") 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /test/functional/voltages_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class VoltagesControllerTest < ActionController::TestCase 4 | test "should get index" do 5 | get :index 6 | assert_response :success 7 | assert_not_nil assigns(:voltages) 8 | end 9 | 10 | test "should get new" do 11 | get :new 12 | assert_response :success 13 | end 14 | 15 | test "should create voltage" do 16 | assert_difference('Voltage.count') do 17 | post :create, :voltage => { } 18 | end 19 | 20 | assert_redirected_to voltage_path(assigns(:voltage)) 21 | end 22 | 23 | test "should show voltage" do 24 | get :show, :id => voltages(:one).to_param 25 | assert_response :success 26 | end 27 | 28 | test "should get edit" do 29 | get :edit, :id => voltages(:one).to_param 30 | assert_response :success 31 | end 32 | 33 | test "should update voltage" do 34 | put :update, :id => voltages(:one).to_param, :voltage => { } 35 | assert_redirected_to voltage_path(assigns(:voltage)) 36 | end 37 | 38 | test "should destroy voltage" do 39 | assert_difference('Voltage.count', -1) do 40 | delete :destroy, :id => voltages(:one).to_param 41 | end 42 | 43 | assert_redirected_to voltages_path 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /test/functional/sources_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class SourcesControllerTest < ActionController::TestCase 4 | test "should get index" do 5 | get :index 6 | assert_response :success 7 | assert_not_nil assigns(:sources) 8 | end 9 | 10 | test "should get new" do 11 | get :new 12 | assert_response :success 13 | end 14 | 15 | test "should create source" do 16 | assert_difference('Source.count') do 17 | post :create, :source => { :temp_offset => 0 } 18 | end 19 | 20 | assert_redirected_to source_path(assigns(:source)) 21 | end 22 | 23 | test "should show source" do 24 | get :show, :id => sources(:one).to_param 25 | assert_response :success 26 | end 27 | 28 | test "should get edit" do 29 | get :edit, :id => sources(:one).to_param 30 | assert_response :success 31 | end 32 | 33 | test "should update source" do 34 | put :update, :id => sources(:one).to_param, :source => { :temp_offset => 0} 35 | assert_redirected_to source_path(assigns(:source)) 36 | end 37 | 38 | test "should destroy source" do 39 | assert_difference('Source.count', -1) do 40 | delete :destroy, :id => sources(:one).to_param 41 | end 42 | 43 | assert_redirected_to sources_path 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/README: -------------------------------------------------------------------------------- 1 | OpenFlashChart Version 2.0.0 11/14/2008 2 | ============== 3 | 4 | 1) rails ofc2_test_app 5 | 2) cd ofc2_test_app 6 | 3) script/plugin install git://github.com/pullmonkey/open_flash_chart.git 7 | 4) script/generate controller test_it 8 | 9 | 5) Add the following to the test_it_controller.rb in RAILS_ROOT/app/controllers: 10 | class TestItController < ApplicationController 11 | 12 | def index 13 | respond_to do |wants| 14 | wants.html { 15 | @graph = open_flash_chart_object( 600, 300, url_for( :action => 'index', :format => :json ) ) 16 | } 17 | wants.json { 18 | chart = OpenFlashChart.new( "MY TITLE" ) do |c| 19 | c << BarGlass.new( :values => (1..10).sort_by{rand} ) 20 | end 21 | render :text => chart, :layout => false 22 | } 23 | end 24 | end 25 | 26 | end 27 | 28 | 6) Add the following to index.html.erb in RAILS_ROOT/app/views/test_it/: 29 | 30 | 31 | 32 | 33 | 34 | <%= @graph %> 35 | 36 | 37 | 38 | 7) script/server 39 | 8) Let me know how it goes, thanks. 40 | 41 | 42 | Example 43 | ======= 44 | 45 | Example above and more to follow here - http://www.pullmonkey.com/projects/open_flash_chart 46 | 47 | 48 | Copyright (c) 2008 PullMonkey, released under the MIT license 49 | -------------------------------------------------------------------------------- /public/stylesheets/scaffold.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0px; 3 | padding: 0px; 4 | background-color: #f0f8ff; 5 | color: #333; 6 | } 7 | 8 | 9 | body, p, ol, ul, td { 10 | font-family: verdana, arial, helvetica, sans-serif; 11 | font-size: 100%; 12 | line-height: 100%; 13 | } 14 | 15 | @media (min-resolution: 200dpi) { 16 | body, p, ol, ul, td { 17 | font-family: verdana, arial, helvetica, sans-serif; 18 | font-size: 26px; 19 | line-height: 36px; 20 | color: #f00; 21 | } 22 | } 23 | 24 | pre { 25 | background-color: #eee; 26 | padding: 10px; 27 | font-size: 11px; 28 | } 29 | 30 | a { color: #000; } 31 | a:visited { color: #666; } 32 | a:hover { color: #fff; background-color:#000; } 33 | 34 | .fieldWithErrors { 35 | padding: 2px; 36 | background-color: red; 37 | display: table; 38 | } 39 | 40 | #errorExplanation { 41 | width: 400px; 42 | border: 2px solid red; 43 | padding: 7px; 44 | padding-bottom: 12px; 45 | margin-bottom: 20px; 46 | background-color: #f0f0f0; 47 | } 48 | 49 | #errorExplanation h2 { 50 | text-align: left; 51 | font-weight: bold; 52 | padding: 5px 5px 5px 15px; 53 | font-size: 12px; 54 | margin: -7px; 55 | background-color: #c00; 56 | color: #fff; 57 | } 58 | 59 | #errorExplanation p { 60 | color: #333; 61 | margin-bottom: 0; 62 | padding: 5px; 63 | } 64 | 65 | #errorExplanation ul li { 66 | font-size: 12px; 67 | list-style: square; 68 | } 69 | 70 | -------------------------------------------------------------------------------- /app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | <%=h @title %> 9 | <%= stylesheet_link_tag 'scaffold' %> 10 | <%= stylesheet_link_tag 'datalogger' %> 11 | <%= javascript_include_tag 'jquery-1.4.1' %> 12 | <%= javascript_include_tag 'jquery.flot' %> 13 | <% if @custom_script %> 14 | 17 | <% end %> 18 | 19 | 20 |

33 | <%= yield %> 34 |
39 | 40 | -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | DataLogger::Application.configure do 2 | # Settings specified here will take precedence over those in config/environment.rb 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Log error messages when you accidentally call methods on nil. 11 | config.whiny_nils = true 12 | 13 | # Show full error reports and disable caching 14 | config.consider_all_requests_local = true 15 | config.action_controller.perform_caching = false 16 | 17 | # Raise exceptions instead of rendering exception templates 18 | config.action_dispatch.show_exceptions = false 19 | 20 | # Disable request forgery protection in test environment 21 | config.action_controller.allow_forgery_protection = false 22 | 23 | # Tell Action Mailer not to deliver emails to the real world. 24 | # The :test delivery method accumulates sent emails in the 25 | # ActionMailer::Base.deliveries array. 26 | config.action_mailer.delivery_method = :test 27 | 28 | # Use SQL instead of Active Record's schema dumper when creating the test database. 29 | # This is necessary if your schema can't be completely dumped by the schema dumper, 30 | # like if you have constraints or database-specific column types 31 | # config.active_record.schema_format = :sql 32 | end 33 | -------------------------------------------------------------------------------- /config/backup.rb.example: -------------------------------------------------------------------------------- 1 | # 2 | # Backup 3 | # Generated Template 4 | # 5 | # For more information: 6 | # 7 | # View the Git repository at https://github.com/meskyanichi/backup 8 | # View the Wiki/Documentation at https://github.com/meskyanichi/backup/wiki 9 | # View the issue log at https://github.com/meskyanichi/backup/issues 10 | # 11 | # When you're finished configuring this configuration file, 12 | # you can run it from the command line by issuing the following command: 13 | # 14 | # $ backup -t my_backup [-c ] 15 | 16 | database_yml = File.expand_path('../config/database.yml', __FILE__) 17 | RAILS_ENV = ENV['RAILS_ENV'] || 'development' 18 | 19 | require 'yaml' 20 | config = YAML.load_file(database_yml) 21 | 22 | 23 | Backup::Model.new(:db_backup, 'Database Backup to S3') do 24 | 25 | database PostgreSQL do |db| 26 | db.name = config[RAILS_ENV]["database"] 27 | db.username = config[RAILS_ENV]["username"] 28 | db.password = config[RAILS_ENV]["password"] 29 | db.host = config[RAILS_ENV]["host"] 30 | db.port = config[RAILS_ENV]["port"] 31 | db.skip_tables = [] 32 | end 33 | 34 | store_with S3 do |s3| 35 | s3.access_key_id = '' 36 | s3.secret_access_key = '' 37 | s3.region = 'us-east-1' 38 | s3.bucket = '' 39 | s3.path = config[RAILS_ENV]["database"] 40 | s3.keep = 10 41 | end 42 | 43 | compress_with Gzip do |compression| 44 | compression.best = true 45 | compression.fast = false 46 | end 47 | 48 | end 49 | -------------------------------------------------------------------------------- /config/environments/production.rb: -------------------------------------------------------------------------------- 1 | DataLogger::Application.configure do 2 | # Settings specified here will take precedence over those in config/environment.rb 3 | 4 | # The production environment is meant for finished, "live" apps. 5 | # Code is not reloaded between requests 6 | config.cache_classes = true 7 | 8 | # Full error reports are disabled and caching is turned on 9 | config.consider_all_requests_local = false 10 | config.action_controller.perform_caching = true 11 | 12 | # Specifies the header that your server uses for sending files 13 | config.action_dispatch.x_sendfile_header = "X-Sendfile" 14 | 15 | # For nginx: 16 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' 17 | 18 | # If you have no front-end server that supports something like X-Sendfile, 19 | # just comment this out and Rails will serve the files 20 | 21 | # See everything in the log (default is :info) 22 | # config.log_level = :debug 23 | 24 | # Use a different logger for distributed setups 25 | # config.logger = SyslogLogger.new 26 | 27 | # Use a different cache store in production 28 | # config.cache_store = :mem_cache_store 29 | 30 | # Disable Rails's static asset server 31 | # In production, Apache or nginx will already do this 32 | config.serve_static_assets = true 33 | 34 | config.action_mailer.default_url_options = { :host => 'waiter.ediblechaos.net' } 35 | 36 | # Enable serving of images, stylesheets, and javascripts from an asset server 37 | # config.action_controller.asset_host = "http://assets.example.com" 38 | 39 | # Disable delivery errors, bad email addresses will be ignored 40 | # config.action_mailer.raise_delivery_errors = false 41 | 42 | config.action_mailer.default_url_options = { :host => 'waiter.ediblechaos.net' } 43 | # Enable threaded mode 44 | # config.threadsafe! 45 | end 46 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart.rb: -------------------------------------------------------------------------------- 1 | require 'open_flash_chart/base' 2 | require 'open_flash_chart/bar_base' 3 | require 'open_flash_chart/bar' 4 | require 'open_flash_chart/bar_3d' 5 | require 'open_flash_chart/bar_glass' 6 | require 'open_flash_chart/bar_sketch' 7 | require 'open_flash_chart/bar_filled' 8 | require 'open_flash_chart/bar_stack' 9 | require 'open_flash_chart/candle' 10 | require 'open_flash_chart/chart' 11 | require 'open_flash_chart/h_bar' 12 | require 'open_flash_chart/line_base' 13 | require 'open_flash_chart/line' 14 | require 'open_flash_chart/line_dot' 15 | require 'open_flash_chart/line_hollow' 16 | require 'open_flash_chart/pie' 17 | require 'open_flash_chart/scatter' 18 | require 'open_flash_chart/scatter_line' 19 | require 'open_flash_chart/radar_axis_labels' 20 | require 'open_flash_chart/radar_axis' 21 | require 'open_flash_chart/radar_spoke_labels' 22 | require 'open_flash_chart/title' 23 | require 'open_flash_chart/x_axis_label' 24 | require 'open_flash_chart/x_axis_labels' 25 | require 'open_flash_chart/x_axis' 26 | require 'open_flash_chart/x_legend' 27 | require 'open_flash_chart/y_axis_base' 28 | require 'open_flash_chart/y_axis' 29 | require 'open_flash_chart/y_axis_right' 30 | require 'open_flash_chart/y_legend' 31 | require 'open_flash_chart/y_legend_right' 32 | require 'open_flash_chart/legend' 33 | require 'open_flash_chart/tooltip' 34 | require 'open_flash_chart/area_base' 35 | require 'open_flash_chart/area_hollow' 36 | require 'open_flash_chart/area_line' 37 | require 'open_flash_chart/shape' 38 | require 'open_flash_chart/upload_image' 39 | require 'open_flash_chart/scatter_line' 40 | require 'open_flash_chart/radar_axis_labels' 41 | require 'open_flash_chart/radar_axis' 42 | require 'open_flash_chart/radar_spoke_labels' 43 | require 'open_flash_chart/linear_regression' 44 | 45 | require 'open_flash_chart/ofc_ajax' 46 | require 'open_flash_chart/open_flash_chart_object' 47 | -------------------------------------------------------------------------------- /app/models/#report.rb#: -------------------------------------------------------------------------------- 1 | class Report < ActiveRecord::Base 2 | has_many :report_sources 3 | has_many :sources, :through => :report_sources 4 | accepts_nested_attributes_for :report_sources, :allow_destroy => true 5 | 6 | def Report.prepare_temps(report) 7 | 8 | report_end = report.end || Time.now.utc 9 | 10 | temps = [] 11 | report.sources.each do |source| 12 | temps << { :source => source, 13 | :readings => FahrenheitTemp.find(:all, 14 | :conditions => [ 'source_id = ? and sampled_at > ? and sampled_at < ?', source.id, report.start, report_end], 15 | :order => :sampled_at) || [], 16 | :data => [] 17 | } 18 | end 19 | return temps 20 | end 21 | 22 | def calculate_graph_data_for_source(reading_list, first_time, last_time, step_size) 23 | @data = [] 24 | 25 | step_through_readings(reading_list, first_time, last_time, step_size) do |readings_in_bucket| 26 | 27 | puts "#{readings_in_bucket} radings" 28 | @data << nil if readings_in_bucket.length == 0 29 | 30 | total = readings_in_bucket.inject(0) { |t, r| t = t + r.display_temp } 31 | @data << total.to_f / readings_in_bucket.length 32 | end 33 | 34 | 35 | return @data 36 | end 37 | 38 | def step_through_readings(reading_list, first_time, last_time, step_size) 39 | step_starts = first_time 40 | 41 | reading_index = 0 42 | while(step_starts <= last_time) 43 | step_ends = step_starts + step_size.minutes 44 | 45 | readings_this_step = [] 46 | while(reading_index < reading_list.length && 47 | reading_list[reading_index].sampled_at <= step_ends) 48 | readings_this_step << reading_list[reading_index] 49 | reading_index += 1 50 | end 51 | 52 | yield(readings_this_step) 53 | step_starts = step_ends 54 | end 55 | end 56 | 57 | 58 | 59 | end 60 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV["RAILS_ENV"] = "test" 2 | require File.expand_path(File.dirname(__FILE__) + "/../config/environment") 3 | require 'test_help' 4 | 5 | class ActiveSupport::TestCase 6 | # Transactional fixtures accelerate your tests by wrapping each test method 7 | # in a transaction that's rolled back on completion. This ensures that the 8 | # test database remains unchanged so your fixtures don't have to be reloaded 9 | # between every test method. Fewer database queries means faster tests. 10 | # 11 | # Read Mike Clark's excellent walkthrough at 12 | # http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting 13 | # 14 | # Every Active Record database supports transactions except MyISAM tables 15 | # in MySQL. Turn off transactional fixtures in this case; however, if you 16 | # don't care one way or the other, switching from MyISAM to InnoDB tables 17 | # is recommended. 18 | # 19 | # The only drawback to using transactional fixtures is when you actually 20 | # need to test transactions. Since your test is bracketed by a transaction, 21 | # any transactions started in your code will be automatically rolled back. 22 | self.use_transactional_fixtures = true 23 | 24 | # Instantiated fixtures are slow, but give you @david where otherwise you 25 | # would need people(:david). If you don't want to migrate your existing 26 | # test cases which use the @david style and don't mind the speed hit (each 27 | # instantiated fixtures translates to a database query per test method), 28 | # then set this back to true. 29 | self.use_instantiated_fixtures = false 30 | 31 | # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order. 32 | # 33 | # Note: You'll currently still have to declare fixtures explicitly in integration tests 34 | # -- they do not yet inherit this setting 35 | fixtures :all 36 | 37 | # Add more helper methods to be used by all tests here... 38 | end 39 | -------------------------------------------------------------------------------- /app/models/report.rb: -------------------------------------------------------------------------------- 1 | class Report < ActiveRecord::Base 2 | has_many :report_sources 3 | has_many :sources, :through => :report_sources 4 | accepts_nested_attributes_for :report_sources, :allow_destroy => true 5 | 6 | def Report.prepare_temps(report) 7 | 8 | temps = [] 9 | report.sources.each do |source| 10 | temps << { :source => source, 11 | :readings => FahrenheitTemp.find(:all, 12 | :conditions => [ 'source_id = ? and sampled_at > ? and sampled_at < ?', source.id, report.start, report.end || Time.now.utc], 13 | :order => :sampled_at) || [], 14 | :data => [] 15 | } 16 | end 17 | return temps 18 | end 19 | 20 | def calculate_graph_data_for_source(reading_list, first_time, last_time, step_size) 21 | @data = [] 22 | 23 | step_through_readings(reading_list, first_time, last_time, step_size) do |readings_in_bucket| 24 | 25 | if readings_in_bucket.length == 0 26 | @data << nil 27 | else 28 | total = readings_in_bucket.inject(0) { |t, r| t = t + r.display_temp } 29 | @data << total.to_f / readings_in_bucket.length 30 | end 31 | end 32 | 33 | 34 | return @data 35 | end 36 | 37 | def step_through_readings(reading_list, first_time, last_time, step_size) 38 | step_starts = first_time 39 | 40 | reading_index = 0 41 | while(step_starts < last_time) 42 | step_ends = step_starts + step_size.minutes 43 | readings_this_step = [] 44 | while(reading_index < reading_list.length && 45 | reading_list[reading_index].sampled_at <= step_ends) 46 | readings_this_step << reading_list[reading_index] 47 | reading_index += 1 48 | end 49 | 50 | yield(readings_this_step) 51 | step_starts = step_ends 52 | end 53 | end 54 | 55 | 56 | def to_flot_json 57 | temps = Report.prepare_temps(self) 58 | utc_offset = Time.now.utc_offset 59 | temps.map { |s| { 'label' => s[:source].name, 60 | 'data' => s[:readings].map {|r| [(r.sampled_at.to_i + utc_offset) * 1000, r.display_temp ] } } }.to_json 61 | end 62 | end 63 | -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | require 'rails/all' 4 | 5 | # If you have a Gemfile, require the gems listed there, including any gems 6 | # you've limited to :test, :development, or :production. 7 | Bundler.require(:default, Rails.env) if defined?(Bundler) 8 | 9 | module DataLogger 10 | class Application < Rails::Application 11 | # Settings in config/environments/* take precedence over those specified here. 12 | # Application configuration should go into files in config/initializers 13 | # -- all .rb files in that directory are automatically loaded. 14 | 15 | # Add additional load paths for your own custom dirs 16 | # config.load_paths += %W( #{config.root}/extras ) 17 | 18 | # Only load the plugins named here, in the order given (default is alphabetical). 19 | # :all can be used as a placeholder for all plugins not explicitly named 20 | # config.plugins = [ :exception_notification, :ssl_requirement, :all ] 21 | 22 | # Activate observers that should always be running 23 | # config.active_record.observers = :cacher, :garbage_collector, :forum_observer 24 | 25 | config.action_mailer.default_url_options = { :host => 'localhost:3000' } 26 | ActionMailer::Base.smtp_settings[:enable_starttls_auto] = false 27 | 28 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 29 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 30 | config.time_zone = 'Central Time (US & Canada)' 31 | 32 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 33 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 34 | # config.i18n.default_locale = :de 35 | 36 | # Configure generators values. Many other options are available, be sure to check the documentation. 37 | config.generators do |g| 38 | g.orm :active_record 39 | g.template_engine :erb 40 | g.test_framework :rspec, :fixture => true 41 | end 42 | 43 | # Configure the default encoding used in templates for Ruby 1.9. 44 | config.encoding = "utf-8" 45 | 46 | # Configure sensitive parameters which will be filtered from the log file. 47 | config.filter_parameters += [:password] 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /app/controllers/sources_controller.rb: -------------------------------------------------------------------------------- 1 | class SourcesController < ApplicationController 2 | # GET /sources 3 | # GET /sources.xml 4 | def index 5 | @sources = Source.all 6 | 7 | respond_to do |format| 8 | format.html # index.html.erb 9 | format.xml { render :xml => @sources } 10 | end 11 | end 12 | 13 | # GET /sources/1 14 | # GET /sources/1.xml 15 | def show 16 | @source = Source.find(params[:id]) 17 | 18 | respond_to do |format| 19 | format.html # show.html.erb 20 | format.xml { render :xml => @source } 21 | end 22 | end 23 | 24 | # GET /sources/new 25 | # GET /sources/new.xml 26 | def new 27 | @source = Source.new 28 | 29 | respond_to do |format| 30 | format.html # new.html.erb 31 | format.xml { render :xml => @source } 32 | end 33 | end 34 | 35 | # GET /sources/1/edit 36 | def edit 37 | @source = Source.find(params[:id]) 38 | end 39 | 40 | # POST /sources 41 | # POST /sources.xml 42 | def create 43 | @source = Source.new(params[:source]) 44 | 45 | respond_to do |format| 46 | if @source.save 47 | flash[:notice] = 'Source was successfully created.' 48 | format.html { redirect_to(@source) } 49 | format.xml { render :xml => @source, :status => :created, :location => @source } 50 | else 51 | format.html { render :action => "new" } 52 | format.xml { render :xml => @source.errors, :status => :unprocessable_entity } 53 | end 54 | end 55 | end 56 | 57 | # PUT /sources/1 58 | # PUT /sources/1.xml 59 | def update 60 | @source = Source.find(params[:id]) 61 | 62 | respond_to do |format| 63 | if @source.update_attributes(params[:source]) 64 | flash[:notice] = 'Source was successfully updated.' 65 | format.html { redirect_to(@source) } 66 | format.xml { head :ok } 67 | else 68 | format.html { render :action => "edit" } 69 | format.xml { render :xml => @source.errors, :status => :unprocessable_entity } 70 | end 71 | end 72 | end 73 | 74 | # DELETE /sources/1 75 | # DELETE /sources/1.xml 76 | def destroy 77 | @source = Source.find(params[:id]) 78 | @source.destroy 79 | 80 | respond_to do |format| 81 | format.html { redirect_to(sources_url) } 82 | format.xml { head :ok } 83 | end 84 | end 85 | end 86 | -------------------------------------------------------------------------------- /app/controllers/voltages_controller.rb: -------------------------------------------------------------------------------- 1 | class VoltagesController < ApplicationController 2 | # GET /voltages 3 | # GET /voltages.xml 4 | def index 5 | @voltages = Voltage.all 6 | 7 | respond_to do |format| 8 | format.html # index.html.erb 9 | format.xml { render :xml => @voltages } 10 | end 11 | end 12 | 13 | # GET /voltages/1 14 | # GET /voltages/1.xml 15 | def show 16 | @voltage = Voltage.find(params[:id]) 17 | 18 | respond_to do |format| 19 | format.html # show.html.erb 20 | format.xml { render :xml => @voltage } 21 | end 22 | end 23 | 24 | # GET /voltages/new 25 | # GET /voltages/new.xml 26 | def new 27 | @voltage = Voltage.new 28 | 29 | respond_to do |format| 30 | format.html # new.html.erb 31 | format.xml { render :xml => @voltage } 32 | end 33 | end 34 | 35 | # GET /voltages/1/edit 36 | def edit 37 | @voltage = Voltage.find(params[:id]) 38 | end 39 | 40 | # POST /voltages 41 | # POST /voltages.xml 42 | def create 43 | @voltage = Voltage.new(params[:voltage]) 44 | 45 | respond_to do |format| 46 | if @voltage.save 47 | flash[:notice] = 'Voltage was successfully created.' 48 | format.html { redirect_to(@voltage) } 49 | format.xml { render :xml => @voltage, :status => :created, :location => @voltage } 50 | else 51 | format.html { render :action => "new" } 52 | format.xml { render :xml => @voltage.errors, :status => :unprocessable_entity } 53 | end 54 | end 55 | end 56 | 57 | # PUT /voltages/1 58 | # PUT /voltages/1.xml 59 | def update 60 | @voltage = Voltage.find(params[:id]) 61 | 62 | respond_to do |format| 63 | if @voltage.update_attributes(params[:voltage]) 64 | flash[:notice] = 'Voltage was successfully updated.' 65 | format.html { redirect_to(@voltage) } 66 | format.xml { head :ok } 67 | else 68 | format.html { render :action => "edit" } 69 | format.xml { render :xml => @voltage.errors, :status => :unprocessable_entity } 70 | end 71 | end 72 | end 73 | 74 | # DELETE /voltages/1 75 | # DELETE /voltages/1.xml 76 | def destroy 77 | @voltage = Voltage.find(params[:id]) 78 | @voltage.destroy 79 | 80 | respond_to do |format| 81 | format.html { redirect_to(voltages_url) } 82 | format.xml { head :ok } 83 | end 84 | end 85 | end 86 | -------------------------------------------------------------------------------- /db/schema.rb: -------------------------------------------------------------------------------- 1 | # This file is auto-generated from the current state of the database. Instead 2 | # of editing this file, please use the migrations feature of Active Record to 3 | # incrementally modify your database, and then regenerate this schema definition. 4 | # 5 | # Note that this schema.rb definition is the authoritative source for your 6 | # database schema. If you need to create the application database on another 7 | # system, you should be using db:schema:load, not running all the migrations 8 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 9 | # you'll amass, the slower it'll run and the greater likelihood for issues). 10 | # 11 | # It's strongly recommended to check this file into your version control system. 12 | 13 | ActiveRecord::Schema.define(:version => 20110319183317) do 14 | 15 | create_table "fahrenheit_temps", :force => true do |t| 16 | t.float "temp" 17 | t.integer "source_id" 18 | t.datetime "created_at" 19 | t.datetime "updated_at" 20 | t.datetime "sampled_at" 21 | end 22 | 23 | add_index "fahrenheit_temps", ["created_at"], :name => "index_fahrenheit_temps_on_created_at" 24 | add_index "fahrenheit_temps", ["sampled_at"], :name => "index_fahrenheit_temps_on_sampled_at" 25 | 26 | create_table "report_sources", :force => true do |t| 27 | t.integer "report_id" 28 | t.integer "source_id" 29 | t.datetime "created_at" 30 | t.datetime "updated_at" 31 | end 32 | 33 | add_index "report_sources", ["report_id"], :name => "index_report_sources_on_report_id" 34 | add_index "report_sources", ["source_id"], :name => "index_report_sources_on_source_id" 35 | 36 | create_table "reports", :force => true do |t| 37 | t.datetime "start" 38 | t.datetime "end" 39 | t.datetime "created_at" 40 | t.datetime "updated_at" 41 | end 42 | 43 | create_table "sources", :force => true do |t| 44 | t.string "name" 45 | t.datetime "created_at" 46 | t.datetime "updated_at" 47 | t.float "temp_offset" 48 | end 49 | 50 | create_table "time_periods", :force => true do |t| 51 | t.integer "source_id" 52 | t.datetime "time_start" 53 | t.datetime "time_end" 54 | t.datetime "created_at" 55 | t.datetime "updated_at" 56 | end 57 | 58 | create_table "voltages", :force => true do |t| 59 | t.float "voltage" 60 | t.integer "source_id" 61 | t.datetime "sampled_at" 62 | t.datetime "created_at" 63 | t.datetime "updated_at" 64 | end 65 | 66 | end 67 | -------------------------------------------------------------------------------- /lib/crc16.rb: -------------------------------------------------------------------------------- 1 | class Crc16 2 | 3 | def crc16(buf) 4 | crc = 0x00 5 | buf.each_byte do |b| 6 | crc = ((crc >> 8) & 0xff) ^ CRC_LOOKUP[(crc ^ b) & 0xff] 7 | end 8 | crc 9 | end 10 | 11 | private 12 | 13 | CRC_LOOKUP = [ 14 | 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 15 | 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, 16 | 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 17 | 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, 18 | 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 19 | 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 20 | 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, 21 | 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, 22 | 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, 23 | 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, 24 | 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 25 | 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, 26 | 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 27 | 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 28 | 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, 29 | 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, 30 | 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, 31 | 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, 32 | 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 33 | 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, 34 | 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 35 | 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 36 | 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, 37 | 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, 38 | 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, 39 | 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, 40 | 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, 41 | 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, 42 | 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 43 | 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 44 | 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, 45 | 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 46 | ] 47 | 48 | end 49 | -------------------------------------------------------------------------------- /app/controllers/time_periods_controller.rb: -------------------------------------------------------------------------------- 1 | class TimePeriodsController < ApplicationController 2 | # GET /time_periods 3 | # GET /time_periods.xml 4 | def index 5 | @time_periods = TimePeriod.all 6 | 7 | respond_to do |format| 8 | format.html # index.html.erb 9 | format.xml { render :xml => @time_periods } 10 | end 11 | end 12 | 13 | # GET /time_periods/1 14 | # GET /time_periods/1.xml 15 | def show 16 | @time_period = TimePeriod.find(params[:id]) 17 | 18 | respond_to do |format| 19 | format.html # show.html.erb 20 | format.xml { render :xml => @time_period } 21 | end 22 | end 23 | 24 | # GET /time_periods/new 25 | # GET /time_periods/new.xml 26 | def new 27 | @time_period = TimePeriod.new 28 | 29 | respond_to do |format| 30 | format.html # new.html.erb 31 | format.xml { render :xml => @time_period } 32 | end 33 | end 34 | 35 | # GET /time_periods/1/edit 36 | def edit 37 | @time_period = TimePeriod.find(params[:id]) 38 | end 39 | 40 | # POST /time_periods 41 | # POST /time_periods.xml 42 | def create 43 | @time_period = TimePeriod.new(params[:time_period]) 44 | 45 | respond_to do |format| 46 | if @time_period.save 47 | flash[:notice] = 'TimePeriod was successfully created.' 48 | format.html { redirect_to(@time_period) } 49 | format.xml { render :xml => @time_period, :status => :created, :location => @time_period } 50 | else 51 | format.html { render :action => "new" } 52 | format.xml { render :xml => @time_period.errors, :status => :unprocessable_entity } 53 | end 54 | end 55 | end 56 | 57 | # PUT /time_periods/1 58 | # PUT /time_periods/1.xml 59 | def update 60 | @time_period = TimePeriod.find(params[:id]) 61 | 62 | respond_to do |format| 63 | if @time_period.update_attributes(params[:time_period]) 64 | flash[:notice] = 'TimePeriod was successfully updated.' 65 | format.html { redirect_to(@time_period) } 66 | format.xml { head :ok } 67 | else 68 | format.html { render :action => "edit" } 69 | format.xml { render :xml => @time_period.errors, :status => :unprocessable_entity } 70 | end 71 | end 72 | end 73 | 74 | # DELETE /time_periods/1 75 | # DELETE /time_periods/1.xml 76 | def destroy 77 | @time_period = TimePeriod.find(params[:id]) 78 | @time_period.destroy 79 | 80 | respond_to do |format| 81 | format.html { redirect_to(time_periods_url) } 82 | format.xml { head :ok } 83 | end 84 | end 85 | end 86 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/open_flash_chart_object.rb: -------------------------------------------------------------------------------- 1 | require 'digest/sha1' 2 | 3 | module OpenFlashChart 4 | module Controller 5 | def open_flash_chart_object(width, height, url, use_swfobject=true, base="/", swf_file_name="open-flash-chart.swf") 6 | get_object_values(url) 7 | get_html(@ofc_url, @div_name, base, swf_file_name, width, height, @protocol, @obj_id) 8 | end 9 | 10 | # if you want the div name back for working with js, this is the ticket 11 | def open_flash_chart_object_and_div_name(width, height, url, use_swfobject=true, base="/", swf_file_name="open-flash-chart.swf") 12 | get_object_values(url) 13 | html = get_html(@ofc_url, @div_name, base, swf_file_name, width, height, @protocol, @obj_id) 14 | return [html, @div_name] 15 | end 16 | 17 | def open_flash_chart_object_from_hash(url, options={}) 18 | get_object_values(url) 19 | get_html(@ofc_url, 20 | options[:div_name] || @div_name, 21 | options[:base] || "/", 22 | options[:swf_file_name] || "open-flash-chart.swf", 23 | options[:width] || 550, 24 | options[:height] || 300, 25 | options[:protocol] || @protocol, 26 | options[:obj_id] || @obj_id) 27 | end 28 | 29 | def get_object_values(url) 30 | @ofc_url = CGI::escape(url) 31 | # need something that will not be repeated on the same request 32 | @special_hash = Base64.encode64(Digest::SHA1.digest("#{rand(1<<64)}/#{Time.now.to_f}/#{Process.pid}/#{@ofc_url}"))[0..7] 33 | # only good characters for our div 34 | @special_hash = @special_hash.gsub(/[^a-zA-Z0-9]/,rand(10).to_s) 35 | @obj_id = "chart_#{@special_hash}" # some sequencing without all the work of tracking it 36 | @div_name = "flash_content_#{@special_hash}" 37 | @protocol = "http" # !request.nil? ? request.env["HTTPS"] || "http" : "http" 38 | end 39 | 40 | def get_html(url, div_name, base, swf_file_name, width, height, protocol, obj_id) 41 | # NOTE: users should put this in the section themselves: 42 | ## 43 | 44 | <<-HTML 45 |
46 | 49 | HTML 50 | end 51 | end 52 | 53 | end 54 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: http://rubygems.org/ 3 | specs: 4 | abstract (1.0.0) 5 | actionmailer (3.0.5) 6 | actionpack (= 3.0.5) 7 | mail (~> 2.2.15) 8 | actionpack (3.0.5) 9 | activemodel (= 3.0.5) 10 | activesupport (= 3.0.5) 11 | builder (~> 2.1.2) 12 | erubis (~> 2.6.6) 13 | i18n (~> 0.4) 14 | rack (~> 1.2.1) 15 | rack-mount (~> 0.6.13) 16 | rack-test (~> 0.5.7) 17 | tzinfo (~> 0.3.23) 18 | activemodel (3.0.5) 19 | activesupport (= 3.0.5) 20 | builder (~> 2.1.2) 21 | i18n (~> 0.4) 22 | activerecord (3.0.5) 23 | activemodel (= 3.0.5) 24 | activesupport (= 3.0.5) 25 | arel (~> 2.0.2) 26 | tzinfo (~> 0.3.23) 27 | activeresource (3.0.5) 28 | activemodel (= 3.0.5) 29 | activesupport (= 3.0.5) 30 | activesupport (3.0.5) 31 | arel (2.0.9) 32 | backup (3.0.10) 33 | thor (~> 0.14.6) 34 | backup-task (0.2.0) 35 | backup (~> 3.0.9) 36 | builder (2.1.2) 37 | erubis (2.6.6) 38 | abstract (>= 1.0.0) 39 | excon (0.5.6) 40 | fog (0.7.0) 41 | builder 42 | excon (>= 0.5.5) 43 | formatador (>= 0.1.1) 44 | json 45 | mime-types 46 | net-ssh (>= 2.0.23) 47 | nokogiri (>= 1.4.4) 48 | ruby-hmac 49 | formatador (0.1.1) 50 | i18n (0.5.0) 51 | json (1.5.1) 52 | mail (2.2.15) 53 | activesupport (>= 2.3.6) 54 | i18n (>= 0.4.0) 55 | mime-types (~> 1.16) 56 | treetop (~> 1.4.8) 57 | mime-types (1.16) 58 | net-ssh (2.1.3) 59 | nokogiri (1.4.4) 60 | pg (0.10.1) 61 | polyglot (0.3.1) 62 | rack (1.2.2) 63 | rack-mount (0.6.13) 64 | rack (>= 1.0.0) 65 | rack-test (0.5.7) 66 | rack (>= 1.0) 67 | rails (3.0.5) 68 | actionmailer (= 3.0.5) 69 | actionpack (= 3.0.5) 70 | activerecord (= 3.0.5) 71 | activeresource (= 3.0.5) 72 | activesupport (= 3.0.5) 73 | bundler (~> 1.0) 74 | railties (= 3.0.5) 75 | railties (3.0.5) 76 | actionpack (= 3.0.5) 77 | activesupport (= 3.0.5) 78 | rake (>= 0.8.7) 79 | thor (~> 0.14.4) 80 | rake (0.8.7) 81 | ruby-hmac (0.4.0) 82 | serialport (1.0.4) 83 | shoulda (2.11.3) 84 | thor (0.14.6) 85 | treetop (1.4.9) 86 | polyglot (>= 0.3.1) 87 | tzinfo (0.3.25) 88 | 89 | PLATFORMS 90 | ruby 91 | 92 | DEPENDENCIES 93 | backup-task 94 | fog 95 | pg 96 | rails (= 3.0.5) 97 | rake (~> 0.8.7) 98 | serialport 99 | shoulda 100 | -------------------------------------------------------------------------------- /test/unit/report_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require 'ostruct' 3 | 4 | class ReportTest < ActiveRecord::TestCase 5 | 6 | context "ReportController:" do 7 | context "One reading per minute (1 minute step)" do 8 | setup do 9 | @r = Report.new 10 | @input = [] 11 | last = Time.now 12 | 10.times do |i| 13 | last = last + 1.minute 14 | @input << OpenStruct.new(:display_temp => i, 15 | :sampled_at => last) 16 | puts "reading: #{i} at #{last}" 17 | 18 | end 19 | end 20 | 21 | context "1 minute step" do 22 | setup do 23 | puts "inputs has #{@input.length} readings" 24 | @results = @r.calculate_graph_data_for_source(@input, 25 | @input[0].sampled_at - 2.seconds, 26 | @input[-1].sampled_at + 1.seconds, 27 | 1) 28 | puts @results.inspect 29 | end 30 | 31 | should "have 10 periods" do 32 | assert_equal 10, @results.length 33 | end 34 | 35 | should "have same values as inputs" do 36 | @input.length.times do |i| 37 | assert_equal @input[i].display_temp, @results[i] 38 | end 39 | end 40 | end 41 | 42 | context "2 minute step" do 43 | setup do 44 | puts "inputs has #{@input.length} readings" 45 | @results = @r.calculate_graph_data_for_source(@input, 46 | @input[0].sampled_at - 2.seconds, 47 | @input[-1].sampled_at + 1.seconds, 48 | 2) 49 | puts @results.inspect 50 | end 51 | 52 | should "have 5 periods" do 53 | assert_equal 5, @results.length 54 | end 55 | 56 | should "have same correct values" do 57 | assert_equal 0.5, @results[0] 58 | assert_equal 2.5, @results[1] 59 | end 60 | end 61 | 62 | 63 | context "an empty step" do 64 | setup do 65 | puts "inputs has #{@input.length} readings" 66 | @input = [@input[0]] 67 | @results = @r.calculate_graph_data_for_source(@input, 68 | @input[0].sampled_at - 2.seconds, 69 | @input[0].sampled_at - 2.seconds + 20.minutes, 70 | 10) 71 | puts @results.inspect 72 | end 73 | 74 | should "have 2 periods" do 75 | assert_equal 2, @results.length 76 | end 77 | 78 | should "have same correct values" do 79 | assert_equal nil, @results[1] 80 | end 81 | end 82 | end 83 | end 84 | end 85 | -------------------------------------------------------------------------------- /public/stylesheets/datalogger.css: -------------------------------------------------------------------------------- 1 | 2 | #header { 3 | position: relative; 4 | padding: 10px; 5 | 6 | background-color: #e0f0ff; 7 | border-bottom: 1px black solid; 8 | } 9 | 10 | #sitename { 11 | font-size: 20px; 12 | font-weight: bold; 13 | } 14 | 15 | #sitename a { 16 | text-decoration: none; 17 | } 18 | 19 | 20 | #menu { 21 | position: absolute; 22 | right: 0px; 23 | top: 0px; 24 | } 25 | 26 | div.menuitem { 27 | float: right; 28 | padding: 10px 10px 10px 10px; 29 | // border-left: 1px black solid; 30 | } 31 | 32 | 33 | #latest-trends-graph { 34 | width: 100%; 35 | min-height: 300px; 36 | padding: 20px; 37 | } 38 | 39 | .graph-surround { 40 | padding: 20px; 41 | background-color: #ffffff; 42 | } 43 | 44 | #content { 45 | position: relative; 46 | padding: 15px; 47 | padding-bottom: 30px; 48 | background-color: #f0f8ff; 49 | min-height: 300px; 50 | } 51 | 52 | 53 | #footer { 54 | width: 100%; 55 | position: absolute; 56 | bottom: 0px; 57 | 58 | border-top: 1px black solid; 59 | background-color: #e0f0ff; 60 | } 61 | 62 | #copyright { 63 | float: right; 64 | 65 | padding-right: 15px; 66 | font-size: 8px; 67 | } 68 | 69 | @media (orientation: landscape) { 70 | .big_data_block { 71 | float: left; 72 | border: 1px black solid; 73 | padding: 15px; 74 | margin: 10px 10px 40px 10px; 75 | width: 200px; 76 | height: 150px; 77 | background-color: #e0f0ff; 78 | text-align: center; 79 | } 80 | 81 | .big_data_source { 82 | font-size: 24px; 83 | align: center; 84 | margin: 10px; 85 | height: 50px; 86 | } 87 | 88 | .big_data_value { 89 | font-size: 24px; 90 | align: center; 91 | margin-top: 30px; 92 | } 93 | 94 | .big_data_time { 95 | font-size: 12px; 96 | align: center; 97 | margin-top: 30px; 98 | } 99 | } 100 | 101 | @media (orientation: portrait) { 102 | #header { 103 | padding-bottom: 1em; 104 | margin-bottom: 2em; 105 | } 106 | 107 | #sitename { 108 | font-size: 2.0em; 109 | } 110 | 111 | #content { 112 | padding: 0px; 113 | } 114 | 115 | .big_data_block { 116 | float: left; 117 | border-bottom: 1px black solid; 118 | border-top: 1px black solid; 119 | margin-bottom: -1px; 120 | width: 100%; 121 | background-color: #e0f0ff; 122 | text-align: center; 123 | } 124 | 125 | .big_data_source { 126 | font-size: 2em; 127 | float: left; 128 | padding: .5em 0 0 .5em; 129 | } 130 | 131 | .big_data_value { 132 | font-size: 2em; 133 | float: right; 134 | padding: .5em .5em 0 0; 135 | } 136 | 137 | .big_data_time { 138 | clear: right; 139 | float: right; 140 | padding-top: 1em; 141 | padding-right: 1em; 142 | padding-bottom: .5em; 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/ofc_ajax.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | module View 3 | def periodically_call_function(function, options = {}) 4 | frequency = options[:frequency] || 10 # every ten seconds by default 5 | code = "new PeriodicalExecuter(function() {#{function}}, #{frequency})" 6 | ActionView::Base.new.javascript_tag(code) 7 | end 8 | 9 | def js_open_flash_chart_object(div_name, width, height, base="/") 10 | <<-OUTPUT 11 | 14 | #{self.to_open_flash_chart_data} 15 |
16 | OUTPUT 17 | end 18 | 19 | def link_to_ofc_load(link_text, div_name) 20 | data_name = "#{link_text.gsub(" ","_")}_#{div_name.gsub(" ","_")}" 21 | <<-OUTPUT 22 | 29 | #{ActionView::Base.new.link_to_function link_text, "load_#{data_name}()"} 30 | OUTPUT 31 | end 32 | 33 | def link_to_remote_ofc_load(link_text, div_name, url) 34 | fx_name = "#{link_text.gsub(" ","_")}_#{div_name.gsub(" ","_")}" 35 | <<-OUTPUT 36 | 45 | #{ActionView::Base.new.link_to_function link_text, "reload_#{fx_name}()"} 46 | OUTPUT 47 | end 48 | 49 | def periodically_call_to_remote_ofc_load(div_name, url, options={}) 50 | fx_name = "#{div_name.gsub(" ","_")}" 51 | # fix a bug in rails with url_for 52 | url = url.gsub("&","&") 53 | <<-OUTPUT 54 | 63 | #{periodically_call_function("reload_#{fx_name}()", options)} 64 | OUTPUT 65 | end 66 | 67 | 68 | def to_open_flash_chart_data 69 | # this builds the open_flash_chart_data js function 70 | <<-OUTPUT 71 | 86 | OUTPUT 87 | end 88 | 89 | end 90 | end 91 | -------------------------------------------------------------------------------- /vendor/plugins/open_flash_chart/lib/open_flash_chart/base.rb: -------------------------------------------------------------------------------- 1 | module OpenFlashChart 2 | class Base 3 | 4 | def initialize(args={}) 5 | # set all the instance variables we want 6 | # assuming something like this OpenFlashChart.new(:x_axis => 5, :y_axis => 10, :elements => ["one", "two"], ...) 7 | args.each do |k,v| 8 | self.instance_variable_set("@#{k}", v) 9 | end 10 | yield self if block_given? # magic pen pattern 11 | end 12 | 13 | # same as to_s but won't stack overflow ... use this instead of to_s 14 | def render 15 | # need to return the following like this 16 | # 1) font_size as font-size 17 | # 2) dot_size as dot-size 18 | # 3) outline_colour as outline-colour 19 | # 4) halo_size as halo-size 20 | # 5) start_angle as start-angle 21 | # 6) tick_height as tick-height 22 | # 7) grid_colour as grid-colour 23 | # 8) threed as 3d 24 | # 9) tick_length as tick-length 25 | # 10) visible_steps as visible-steps 26 | # 11) key_on_click as key-on-click 27 | returning self.to_json2 do |output| 28 | output.gsub!("threed","3d") 29 | %w(font_size dot_size outline_colour halo_size start_angle tick_height grid_colour tick_length no_labels label_colour gradient_fill fill_alpha on_click spoke_labels visible_steps key_on_click).each do |replace| 30 | output.gsub!(replace, replace.gsub("_", "-")) 31 | end 32 | end 33 | end 34 | 35 | def to_json2 36 | self.instance_values.to_json 37 | end 38 | 39 | alias_method :to_s, :render 40 | 41 | def add_element(element) 42 | @elements ||= [] 43 | @elements << element 44 | end 45 | 46 | def <<(e) 47 | add_element e 48 | end 49 | 50 | def set_key(text, size) 51 | @text = text 52 | @font_size = size 53 | end 54 | 55 | def append_value(v) 56 | @values ||= [] 57 | @values << v 58 | end 59 | 60 | def set_range(min,max,steps=1) 61 | @min = min 62 | @max = max 63 | @steps = steps 64 | end 65 | 66 | def set_offset(v) 67 | @offset = v ? true : false 68 | end 69 | 70 | def set_colours(colour, grid_colour) 71 | @colour = colour 72 | @grid_colour = grid_colour 73 | end 74 | 75 | def set_tooltip(tip) 76 | if tip.is_a?(Tooltip) 77 | #we have a style for our chart's tooltips 78 | @tooltip = tip 79 | else 80 | # the user could just use set_tip(tip) or tip=(tip) to just set the text of the tooltip 81 | @tip = tip 82 | end 83 | end 84 | alias_method "tooltip=", :set_tooltip 85 | 86 | 87 | 88 | def method_missing(method_name, *args, &blk) 89 | case method_name.to_s 90 | when /(.*)=/ # i.e., if it is something x_legend= 91 | # if the user wants to set an instance variable then let them 92 | # the other args (args[0]) are ignored since it is a set method 93 | self.instance_variable_set("@#{$1}", args[0]) 94 | when /^set_(.*)/ 95 | # backwards compatible ... the user can still use the same set_y_legend methods if they want 96 | self.instance_variable_set("@#{$1}", args[0]) 97 | else 98 | # if the method/attribute is missing and it is not a set method then hmmmm better let the user know 99 | super 100 | end 101 | end 102 | 103 | end 104 | end 105 | -------------------------------------------------------------------------------- /app/controllers/fahrenheit_temps_controller.rb: -------------------------------------------------------------------------------- 1 | class FahrenheitTempsController < ApplicationController 2 | 3 | def latest 4 | @source_id = params[:source_id] 5 | @fahrenheit_temp = FahrenheitTemp.find(:first, 6 | :conditions => { :source_id => @source_id}, 7 | :order => 'created_at desc') 8 | 9 | respond_to do |format| 10 | format.html { render :action => 'show' } 11 | format.xml { render :xml => @fahrenheit_temp.to_xml( 12 | :include => [:source], 13 | :methods => [:display_temp, 14 | :display_time]) } 15 | format.json { render :json => @fahrenheit_temp.to_json( 16 | :include => [:source ], 17 | :methods => [:display_temp, 18 | :display_time] ) } 19 | end 20 | end 21 | 22 | # GET /fahrenheit_temps 23 | # GET /fahrenheit_temps.xml 24 | def index 25 | @fahrenheit_temps = FahrenheitTemp.find(:all, :order => :sampled_at) 26 | 27 | respond_to do |format| 28 | format.html # index.html.erb 29 | format.xml { render :xml => @fahrenheit_temps } 30 | end 31 | end 32 | 33 | # GET /fahrenheit_temps/1 34 | # GET /fahrenheit_temps/1.xml 35 | def show 36 | @fahrenheit_temp = FahrenheitTemp.find(params[:id]) 37 | 38 | respond_to do |format| 39 | format.html # show.html.erb 40 | format.xml { render :xml => @fahrenheit_temp } 41 | end 42 | end 43 | 44 | # GET /fahrenheit_temps/new 45 | # GET /fahrenheit_temps/new.xml 46 | def new 47 | @fahrenheit_temp = FahrenheitTemp.new 48 | 49 | respond_to do |format| 50 | format.html # new.html.erb 51 | format.xml { render :xml => @fahrenheit_temp } 52 | end 53 | end 54 | 55 | # GET /fahrenheit_temps/1/edit 56 | def edit 57 | @fahrenheit_temp = FahrenheitTemp.find(params[:id]) 58 | end 59 | 60 | # POST /fahrenheit_temps 61 | # POST /fahrenheit_temps.xml 62 | def create 63 | @fahrenheit_temp = FahrenheitTemp.new(params[:fahrenheit_temp]) 64 | 65 | respond_to do |format| 66 | if @fahrenheit_temp.save 67 | flash[:notice] = 'FahrenheitTemp was successfully created.' 68 | format.html { redirect_to(@fahrenheit_temp) } 69 | format.xml { render :xml => @fahrenheit_temp, :status => :created, :location => @fahrenheit_temp } 70 | else 71 | format.html { render :action => "new" } 72 | format.xml { render :xml => @fahrenheit_temp.errors, :status => :unprocessable_entity } 73 | end 74 | end 75 | end 76 | 77 | # PUT /fahrenheit_temps/1 78 | # PUT /fahrenheit_temps/1.xml 79 | def update 80 | @fahrenheit_temp = FahrenheitTemp.find(params[:id]) 81 | 82 | respond_to do |format| 83 | if @fahrenheit_temp.update_attributes(params[:fahrenheit_temp]) 84 | flash[:notice] = 'FahrenheitTemp was successfully updated.' 85 | format.html { redirect_to(@fahrenheit_temp) } 86 | format.xml { head :ok } 87 | else 88 | format.html { render :action => "edit" } 89 | format.xml { render :xml => @fahrenheit_temp.errors, :status => :unprocessable_entity } 90 | end 91 | end 92 | end 93 | 94 | # DELETE /fahrenheit_temps/1 95 | # DELETE /fahrenheit_temps/1.xml 96 | def destroy 97 | @fahrenheit_temp = FahrenheitTemp.find(params[:id]) 98 | @fahrenheit_temp.destroy 99 | 100 | respond_to do |format| 101 | format.html { redirect_to(fahrenheit_temps_url) } 102 | format.xml { head :ok } 103 | end 104 | end 105 | end 106 | -------------------------------------------------------------------------------- /arduino/trip_logger/trip_logger.pde: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define SWITCH_PIN 6 5 | #define PCF8583_ADDRESS 0xA0 6 | #define EEPROM_ADDRESS 0xA4 >> 1 7 | PCF8583 rtc(PCF8583_ADDRESS); 8 | int last_pin_state = 0; 9 | long int start_time; 10 | long int stop_time; 11 | unsigned int next_address = 0; 12 | 13 | 14 | void setup() { 15 | Serial.begin(9600); 16 | Serial.print("booting..."); 17 | Wire.begin(); 18 | pinMode(SWITCH_PIN, INPUT); 19 | Serial.println("done."); 20 | Serial.print("what time is it?"); 21 | int time_set = 0; 22 | while(time_set == 0){ 23 | if(Serial.available()){ 24 | 25 | rtc.year= (byte) ((Serial.read() - 48) *10 + (Serial.read() - 48)) + 2000; 26 | rtc.month = (byte) ((Serial.read() - 48) *10 + (Serial.read() - 48)); 27 | rtc.day = (byte) ((Serial.read() - 48) *10 + (Serial.read() - 48)); 28 | rtc.hour = (byte) ((Serial.read() - 48) *10 + (Serial.read() - 48)); 29 | rtc.minute = (byte) ((Serial.read() - 48) *10 + (Serial.read() - 48)); 30 | rtc.second = (byte) ((Serial.read() - 48) * 10 + (Serial.read() - 48)); // Use of (byte) type casting and ascii math to achieve result. 31 | 32 | Serial.println("setting date"); 33 | rtc.set_time(); 34 | time_set = 1; 35 | } 36 | } 37 | 38 | Serial.println("checking memory for previous entries:"); 39 | /* 40 | i2c_eeprom_read_buffer(EEPROM_ADDRESS, next_address,(byte *) &start_time, 4); 41 | i2c_eeprom_read_buffer(EEPROM_ADDRESS, next_address + 4,(byte *) &stop_time, 4); 42 | Serial.print("start time = "); 43 | Serial.println(start_time); 44 | 45 | while(start_time != 0) { 46 | Serial.print("period of "); 47 | Serial.print(stop_time - start_time); 48 | Serial.println(" secs"); 49 | next_address += 8; 50 | i2c_eeprom_read_buffer(EEPROM_ADDRESS, next_address,(byte *) &start_time, 4); 51 | i2c_eeprom_read_buffer(EEPROM_ADDRESS, next_address + 4,(byte *) &stop_time, 4); 52 | } 53 | */ 54 | byte foo; 55 | foo = i2c_eeprom_read_byte(EEPROM_ADDRESS, next_address); 56 | while(foo != 0){ 57 | Serial.print("address "); 58 | Serial.print(next_address); 59 | Serial.print(" = "); 60 | Serial.println((int) foo); 61 | next_address++; 62 | foo = i2c_eeprom_read_byte(EEPROM_ADDRESS, next_address); 63 | 64 | } 65 | 66 | Serial.println("done"); 67 | 68 | } 69 | 70 | void loop() { 71 | int val = digitalRead(SWITCH_PIN); 72 | if(last_pin_state == LOW){ // was unpressed 73 | if(val == HIGH){ // low to high transition 74 | rtc.get_time(); 75 | start_time = mktime(rtc.second, rtc.minute, rtc.hour, rtc.day, rtc.month, 76 | rtc.year); 77 | last_pin_state = HIGH; 78 | Serial.println("button pressed"); 79 | } 80 | } else { 81 | if(val == LOW){ // HIGH to LOW transition 82 | last_pin_state = LOW; 83 | rtc.get_time(); 84 | stop_time = mktime(rtc.second, rtc.minute, rtc.hour, rtc.day, rtc.month, 85 | rtc.year); 86 | Serial.println("button released"); 87 | Serial.print("button held for "); 88 | Serial.print(stop_time - start_time); 89 | Serial.println(" seconds"); 90 | i2c_eeprom_write_page(EEPROM_ADDRESS, next_address, (byte *) &start_time, 4); 91 | i2c_eeprom_write_page(EEPROM_ADDRESS, next_address + 4, (byte *) &stop_time, 4); 92 | next_address += 8; 93 | } 94 | } 95 | } 96 | 97 | 98 | void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) { 99 | int rdata = data; 100 | Wire.beginTransmission(deviceaddress); 101 | Wire.send((int)(eeaddress >> 8)); // MSB 102 | Wire.send((int)(eeaddress & 0xFF)); // LSB 103 | Wire.send(rdata); 104 | Wire.endTransmission(); 105 | } 106 | 107 | // WARNING: address is a page address, 6-bit end will wrap around 108 | // also, data can be maximum of about 30 bytes, because the Wire library has a buffer of 32 bytes 109 | void i2c_eeprom_write_page( int deviceaddress, unsigned int eeaddresspage, byte* data, byte length ) { 110 | Wire.beginTransmission(deviceaddress); 111 | Wire.send((int)(eeaddresspage >> 8)); // MSB 112 | Wire.send((int)(eeaddresspage & 0xFF)); // LSB 113 | byte c; 114 | for ( c = 0; c < length; c++) 115 | Wire.send(data[c]); 116 | Wire.endTransmission(); 117 | } 118 | 119 | byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) { 120 | byte rdata = 0xFF; 121 | Wire.beginTransmission(deviceaddress); 122 | Wire.send((int)(eeaddress >> 8)); // MSB 123 | Wire.send((int)(eeaddress & 0xFF)); // LSB 124 | Wire.endTransmission(); 125 | Wire.requestFrom(deviceaddress,1); 126 | if (Wire.available()) rdata = Wire.receive(); 127 | return rdata; 128 | } 129 | 130 | // maybe let's not read more than 30 or 32 bytes at a time! 131 | void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte *buffer, int length ) { 132 | Wire.beginTransmission(deviceaddress); 133 | Wire.send((int)(eeaddress >> 8)); // MSB 134 | Wire.send((int)(eeaddress & 0xFF)); // LSB 135 | Wire.endTransmission(); 136 | Wire.requestFrom(deviceaddress,length); 137 | int c = 0; 138 | for ( c = 0; c < length; c++ ) 139 | if (Wire.available()) buffer[c] = Wire.receive(); 140 | } 141 | 142 | 143 | /***********************************************************************/ 144 | #define EPOCH_YEAR 1970 145 | #define TM_YEAR_BASE 1900 146 | #define SECONDS_PER_MINUTE 60 147 | #define SECONDS_PER_HOUR 60 * SECONDS_PER_MINUTE 148 | #define SECONDS_PER_DAY 24 * SECONDS_PER_HOUR 149 | #define SECONDS_PER_YEAR 365 * SECONDS_PER_DAY 150 | 151 | 152 | 153 | /* Return 1 if YEAR + TM_YEAR_BASE is a leap year. */ 154 | static inline int 155 | leapyear (long int year) 156 | { 157 | /* Don't add YEAR to TM_YEAR_BASE, as that might overflow. 158 | Also, work even if YEAR is negative. */ 159 | return 160 | ((year & 3) == 0 161 | && (year % 100 != 0 162 | || ((year / 100) & 3) == (- (TM_YEAR_BASE / 100) & 3))); 163 | } 164 | 165 | 166 | const unsigned short int __mon_yday[2][13] = 167 | { 168 | /* Normal years. */ 169 | { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, 170 | /* Leap years. */ 171 | { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } 172 | }; 173 | 174 | 175 | long mktime(int sec, int min, int hour, int day, int mon, int year) { 176 | int mon_yday = __mon_yday[leapyear (long(year))] [mon - 1]; 177 | int yday = mon_yday + day; 178 | 179 | int leap_days = 0; 180 | int step_year = 1970; 181 | while(step_year < year) { 182 | if(leapyear(step_year)) { 183 | leap_days++; 184 | } 185 | step_year++; 186 | } 187 | 188 | long time = long((long(year) - EPOCH_YEAR) * SECONDS_PER_YEAR) + 189 | long(yday - 1 + leap_days) * SECONDS_PER_DAY + // -1 because today isn't over 190 | long(hour) * SECONDS_PER_HOUR + min * SECONDS_PER_MINUTE + sec; 191 | 192 | return time; 193 | } 194 | 195 | -------------------------------------------------------------------------------- /public/javascripts/swfobject.js: -------------------------------------------------------------------------------- 1 | /* SWFObject v2.0 2 | Copyright (c) 2007 Geoff Stearns, Michael Williams, and Bobby van der Sluis 3 | This software is released under the MIT License 4 | */ 5 | var swfobject=function(){var Z="undefined",P="object",B="Shockwave Flash",h="ShockwaveFlash.ShockwaveFlash",W="application/x-shockwave-flash",K="SWFObjectExprInst",G=window,g=document,N=navigator,f=[],H=[],Q=null,L=null,T=null,S=false,C=false;var a=function(){var l=typeof g.getElementById!=Z&&typeof g.getElementsByTagName!=Z&&typeof g.createElement!=Z&&typeof g.appendChild!=Z&&typeof g.replaceChild!=Z&&typeof g.removeChild!=Z&&typeof g.cloneNode!=Z,t=[0,0,0],n=null;if(typeof N.plugins!=Z&&typeof N.plugins[B]==P){n=N.plugins[B].description;if(n){n=n.replace(/^.*\s+(\S+\s+\S+$)/,"$1");t[0]=parseInt(n.replace(/^(.*)\..*$/,"$1"),10);t[1]=parseInt(n.replace(/^.*\.(.*)\s.*$/,"$1"),10);t[2]=/r/.test(n)?parseInt(n.replace(/^.*r(.*)$/,"$1"),10):0}}else{if(typeof G.ActiveXObject!=Z){var o=null,s=false;try{o=new ActiveXObject(h+".7")}catch(k){try{o=new ActiveXObject(h+".6");t=[6,0,21];o.AllowScriptAccess="always"}catch(k){if(t[0]==6){s=true}}if(!s){try{o=new ActiveXObject(h)}catch(k){}}}if(!s&&o){try{n=o.GetVariable("$version");if(n){n=n.split(" ")[1].split(",");t=[parseInt(n[0],10),parseInt(n[1],10),parseInt(n[2],10)]}}catch(k){}}}}var v=N.userAgent.toLowerCase(),j=N.platform.toLowerCase(),r=/webkit/.test(v)?parseFloat(v.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,i=false,q=j?/win/.test(j):/win/.test(v),m=j?/mac/.test(j):/mac/.test(v);/*@cc_on i=true;@if(@_win32)q=true;@elif(@_mac)m=true;@end@*/return{w3cdom:l,pv:t,webkit:r,ie:i,win:q,mac:m}}();var e=function(){if(!a.w3cdom){return }J(I);if(a.ie&&a.win){try{g.write("