Skip to content

Instantly share code, notes, and snippets.

@soulcutter
Last active August 29, 2015 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save soulcutter/9415570 to your computer and use it in GitHub Desktop.
Save soulcutter/9415570 to your computer and use it in GitHub Desktop.
Conversion methods
# encoding: utf-8
require 'datapoint_value'
class Datapoint < ActiveRecord::Base
include DatapointValue::Conversions
before_save :normalize_value
def self.upsert(params)
dp = where(token: params[:token], at: params[:at]).first
return create!(params) if dp.nil?
if DatapointValue(dp.value) != DatapointValue(params[:value])
# log datapoint mismatch
end
dp
end
private
def normalize_value
self.value = DatapointValue(value).value
end
end
class DatapointValue
include Comparable
attr_reader :value
def initialize(value)
@value = value
end
private_class_method :new
def <=>(other)
other = Conversions::DatapointValue(other)
return 0 if [value, other.value].all?(&:nil?)
return -1 if value.nil?
return 1 if other.value.nil?
rounded_value <=> other.rounded_value
end
def rounded_value
value.try :round, 1
end
end
class DatapointValue
module Conversions
def self.included(base)
base.extend self
end
module_function
def DatapointValue(value)
case value
when DatapointValue then value
when String then ::DatapointValue.send(:new, value.to_f)
# K thermocouple devices report -454.0 for unplugged probes
when ->(value) { value.to_f == -454 } then ::DatapointValue.send(:new, nil)
# other devices send values of -500 for unplugged probes
when ->(value) { value.to_f <= -500 } then ::DatapointValue.send(:new, nil)
else
::DatapointValue.send(:new, value.try(:to_f))
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment