Tuesday, December 6, 2011

Ruby code posts to thingspeak.com as well as timestamped csv file

#!/usr/bin/env ruby
# Encoding: UTF-8
# Copyright 2011 Michael Fellinger - MIT License
# http://manveru.name
# Currently running ruby 1.9.2p290 (2011-07-09 revision 32553) [i686-linux]
# Gem.loaded_specs["serialport"].version 1.0.4

api_key = 'yourthingspeakKEYhere2'
min_temperature = 5 # ° Fahrenheit
max_temperature = 250 # ° Fahrenheit
run_every = 60 # Seconds
fields_count = 8 # add more as you add sensors. Also need to add fields on thingspeak.com to match.
 
###
# Here be Dragons!
###
require 'csv' 
require 'serialport'
require 'logger'
require 'rest-client'
log = Logger.new('/home/djash/scripts/logs/temperature.log', 'daily')
 
port_str = "/dev/ttyACM0" # may be different for you
baud_rate = 9600
data_bits = 8
stop_bits = 1
parity = SerialPort::NONE
 
sp = SerialPort.new(port_str, baud_rate, data_bits, stop_bits, parity)
sleep(2)
last_run = Time.now
buffer = ''
 
loop do
  begin
    found = select([sp], nil, nil, run_every)
 
    next unless found && found[0]
 
    buffer << sp.getc
 
    next unless buffer.include? ",\r\n"
 
    line, buffer = buffer.split(",\r\n", 2)
    fields = line.split(',', fields_count)
    unless fields.size == fields_count
      log.debug "Insufficient Data, might be starting up..."
      next
    end
  
    fields.map!{|field| Float(field) }
 
    unless fields.all?{|field| field > min_temperature && field < max_temperature }
      log.warn "The fields are outside the #{min_temperature}..#{max_temperature} range: %p" % [fields]
      log.warn "Won't post to thingspeak"
      next
    end
 
    params = {key: api_key}
    (0...fields_count).each do |n|
      params["field#{n + 1}"] = "%.2f" % [fields[n]]
    end
 
    log.debug(params)
fieldstocsv = line.split(',', fields_count).unshift Time.now
CSV.open('/home/djash/scripts/logs/temperature.csv', 'a') do |writer| 
writer << (fieldstocsv)
end 
 
RestClient.post('https://api.thingspeak.com/update', params)

# djash added below 2 lines hopefully to clear what seems to be temperature hanging. So if we clear the buffer then we must get new data to post.
# never did figure this out so I simply restart this script every 15 minutes with a bash script. I think it's serialport issue.
 buffer.clear
# $stdout.flush # 
 
    time_diff = run_every - (Time.now - last_run)
    sleep [time_diff, run_every].max

  rescue => exception
    log.error(exception)
    log.error(line: line)
    log.error(buffer: buffer)
    log.error(fields: fields)
  end
end
 

No comments:

Post a Comment