require 'sinatra' require 'mqtt' require 'sqlite3' require 'date' require 'dm-core' require 'dm-timestamps' require 'dm-validations' require 'dm-migrations' set :public_folder, File.dirname(__FILE__) + '/public' set :bind, '::' configure do mime_type :text, 'text/plain' end DataMapper.setup(:default, ENV['DATABASE_URL'] || "sqlite3://#{Dir.pwd}/scarecrow.sqlite") class Temperature include DataMapper::Resource property :id, Serial property :device, String property :timestamp, DateTime property :value, Float end class Humidity include DataMapper::Resource property :id, Serial property :device, String property :timestamp, DateTime property :value, Float end def init DataMapper.auto_migrate! DataMapper.auto_upgrade! # sleep 10 Thread.new do MQTT::Client.connect('192.168.0.59') do |c| c.subscribe('+/temperature', '+/humidity') loop do while !c.queue_empty? do topic, message = c.get handle_msg(topic, message) end sleep 1 end end end end def handle_msg(topic, msg) puts "#{topic}: #{msg}" topic_parts = topic.split("/") device_id = topic_parts[0] type = topic_parts[-1] if type == "humidity" handle_humidity_msg(device_id, msg) elsif type == "temperature" handle_temp_message(device_id, msg) end end def handle_humidity_msg(device_id, msg) humidity = Humidity.create(timestamp: DateTime.now, device: device_id, value: msg) humidity.errors.each do |error| puts error end end def handle_temp_message(device_id, msg) temp = Temperature.create(timestamp: DateTime.now, device: device_id, value: msg) temp.errors.each do |error| puts error end end get '/' do # send_file File.join(settings.public_folder, 'index.html') @temp_prop = Temperature.last(device: "cricket0")[:value] @humidity_prop = Humidity.last(device: "cricket0")[:value] @temp_air = Temperature.last(device: "mercury")[:value] @humidity_air = Humidity.last(device: "mercury")[:value] time_prop = Temperature.last(device: "mercury")[:timestamp] time_air = Temperature.last(device: "cricket0")[:timestamp] @time_formatted_prop = time_prop.strftime("%A, %d %b %Y %l:%M %p") @time_formatted_air = time_air.strftime("%A, %d %b %Y %l:%M %p") erb :index # return "#{temp_val}°C and #{humidity_val}% humidity at #{time_formatted}" end get '/temperature/:device_id' do device_id = "mercury" if (params[:device_id] == "air" || params[:device_id] == "kitchen") device_id = "cricket0" if (params[:device_id] == "propagator") device_id ||= params[:device_id] temp = Temperature.last(device: device_id)[:value] return "#{temp}" end get '/humidity/:device_id' do device_id = "mercury" if (device_id == "air" || device_id == "basement") device_id = "cricket0" if (device_id == "propagator") humidity = Humidity.last(device: device_id)[:value] "#{humidity}" end get '/metrics' do content_type :text temp_prop = Temperature.last(device: "cricket0")[:value] humidity_prop = Humidity.last(device: "cricket0")[:value] temp_air = Temperature.last(device: "mercury")[:value] humidity_air = Humidity.last(device: "mercury")[:value] "humidity_basement #{humidity_air} humidity_propagator #{humidity_prop} temperature_basement #{temp_air} temperature_propagator #{temp_prop}" end init