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 class Moisture 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', '+/moisture') 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) elsif type == "moisture" handle_moisture_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 def handle_moisture_message(device_id, msg) moisture = Moisture.create(timestamp: DateTime.now, device: device_id, value: msg) moisture.errors.each do |error| puts error end end def get_value(type, device_id) entry = nil value = 0.0 if type == :temperature entry = Temperature.last(device: device_id) elsif type == :humidity entry = Humidity.last(device: device_id) elsif type == :moisture entry = Moisture.last(device: device_id) end if entry != nil value = entry[:value] end return value end def get_time(type, device_id) entry = nil value = Time.at(0) if type == :temperature entry = Temperature.last(device: device_id) elsif type == :humidity entry = Humidity.last(device: device_id) elsif type == :moisture entry = Moisture.last(device: device_id) end if entry != nil value = entry[:timestamp] end return value end get '/' do # send_file File.join(settings.public_folder, 'index.html') @temp_prop = get_value(:temperature, "cricket0") @humidity_prop = get_value(:humidity, "cricket0") @temp_air = get_value(:temperature, "mercury") @humidity_air = get_value(:humidity, "mercury") @temp_kitchen = get_value(:temperature, "cricket1") @humidity_kitchen = get_value(:humidity, "cricket1") @moisture_kitchen = (1000-(get_value(:moisture, "cricket1")))/10 time_prop = get_time(:temperature, "cricket0") time_air = get_time(:temperature, "mercury") time_kitchen = get_time(:temperature, "cricket1") @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") @time_formatted_kitchen = time_kitchen.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 = "cricket1" if (params[:device_id] == "kitchen") 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") device_id = "cricket1" if (device_id == "kitchen") humidity = Humidity.last(device: device_id)[:value] "#{humidity}" end get '/moisture/:device_id' do device_id = "mercury" if (device_id == "air" || device_id == "basement") device_id = "cricket0" if (device_id == "propagator") device_id = "cricket1" if (device_id == "kitchen") moisture = Moisture.last(device: device_id)[:value] "#{moisture}" end get '/metrics' do content_type :text temp_prop = get_value(:temperature, "cricket0") humidity_prop = get_value(:humidity, "cricket0") temp_air = get_value(:temperature, "mercury") humidity_air = get_value(:humidity, "mercury") temp_kitchen = get_value(:temperature, "cricket1") humidity_kitchen = get_value(:humidity, "cricket1") moisture_kitchen = (1000-(get_value(:moisture, "cricket1")))/10 "humidity_basement #{humidity_air} humidity_propagator #{humidity_prop} humidity_kitchen #{humidity_kitchen} temperature_basement #{temp_air} temperature_propagator #{temp_prop} temperature_kitchen #{temp_kitchen} moisture_kitchen #{moisture_kitchen}" end init