commit ab751d68c04df980e9367081201909c3d5ad8130 Author: Roscoe Date: Sun Oct 26 22:51:10 2025 +0000 Add sauce diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..64fb944 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,8 @@ +root = true + +[*] +indent_style = space +indent_size = 4 + +[*.rb] +indent_size = 2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a173f1f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.env +.ruby-lsp diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..9ced3f2 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,12 @@ +Layout/HashAlignment: + Enabled: false +Style/HashSyntax: + Enabled: false +Layout/FirstHashElementIndentation: + Enabled: false +Style/FrozenStringLiteralComment: + Enabled: false +Layout/IndentationWidth: + Enabled: false +Layout/FirstArgumentIndentation: + Enabled: false diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..a317a04 --- /dev/null +++ b/Gemfile @@ -0,0 +1,6 @@ +source 'https://rubygems.org' + +gem 'pony' +gem 'mysql2' +gem 'dotenv' +gem 'terminal-table' diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..359588a --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,46 @@ +GEM + remote: https://rubygems.org/ + specs: + bigdecimal (3.3.1) + date (3.4.1) + dotenv (3.1.8) + logger (1.7.0) + mail (2.9.0) + logger + mini_mime (>= 0.1.1) + net-imap + net-pop + net-smtp + mini_mime (1.1.5) + mysql2 (0.5.7) + bigdecimal + net-imap (0.5.12) + date + net-protocol + net-pop (0.1.2) + net-protocol + net-protocol (0.2.2) + timeout + net-smtp (0.5.1) + net-protocol + pony (1.13.1) + mail (>= 2.0) + terminal-table (4.0.0) + unicode-display_width (>= 1.1.1, < 4) + timeout (0.4.3) + unicode-display_width (3.2.0) + unicode-emoji (~> 4.1) + unicode-emoji (4.1.0) + +PLATFORMS + arm64-darwin-24 + ruby + +DEPENDENCIES + dotenv + mysql2 + pony + terminal-table + +BUNDLED WITH + 2.7.1 diff --git a/main.rb b/main.rb new file mode 100644 index 0000000..167fe18 --- /dev/null +++ b/main.rb @@ -0,0 +1,216 @@ +require 'dotenv/load' +require 'pony' +require 'mysql2' +require 'terminal-table' +require 'time' + +options = { + :address => ENV['SMTP_HOST'], + :port => ENV['SMTP_PORT'], + :enable_starttls_auto => ENV['SMTP_TLS'], + :user_name => ENV['SMTP_UNAME'], + :password => ENV['SMTP_PWORD'], + :authentication => :plain, # :plain, :login, :cram_md5, no auth by default + :domain => ENV['SMTP_DOMAIN'], # the HELO domain provided by the client to the server +} + +begin + client = Mysql2::Client.new( + host: ENV['MARIA_HOST'], + port: ENV['MARIA_PORT'], + username: ENV['MARIA_UNAME'], + password: ENV['MARIA_PWORD'], + database: ENV['MARIA_DBASE'] + ) + puts "Successfully connected to MariaDB!" + + puts "Compiling data..." + results_today = client.query(%( + SELECT LogDateTime, temp, dew, hum, rrate, rmonth, ryear + FROM Realtime + WHERE CAST(LogDateTime AS DATE) = CAST(NOW() AS DATE) + ORDER BY LogDateTime ASC + )) + results_now = client.query(%( + SELECT LogDateTime, temp, dew, hum, press, presstrendval, rfall, rrate, rainunit, wspeed, wgust, windunit, + windTM, TwindTM, wgustTM, TwgustTM + FROM Realtime + ORDER BY LogDateTime DESC + LIMIT 1 + )) + + today = results_today.first + now = results_now.first + + maxmin = { + :temp => { + :max => { + :value => -1000, + :time => nil + }, + :min => { + :value => 1000, + :time => nil + } + }, + :dew => { + :max => { + :value => -1000, + :time => nil + }, + :min => { + :value => 1000, + :time => nil + } + }, + :hum => { + :max => { + :value => -1, + :time => nil + }, + :min => { + :value => 101, + :time => nil + } + }, + :rainrate => { + :max => { + :value => 0, + :time => nil + } + } + } + + results_today.each do |result| + # Max Temp + if result['temp'] >= maxmin[:temp][:max][:value] + maxmin[:temp][:max][:value] = result['temp'].to_f + maxmin[:temp][:max][:time] = result['LogDateTime'].strftime("%H:%M") + end + + # Min Temp + if result['temp'] <= maxmin[:temp][:min][:value] + maxmin[:temp][:min][:value] = result['temp'].to_f + maxmin[:temp][:min][:time] = result['LogDateTime'].strftime("%H:%M") + end + + # Max Dew Point + if result['dew'] >= maxmin[:dew][:max][:value] + maxmin[:dew][:max][:value] = result['dew'].to_f + maxmin[:dew][:max][:time] = result['LogDateTime'].strftime("%H:%M") + end + + # Min Dew Point + if result['dew'] <= maxmin[:dew][:min][:value] + maxmin[:dew][:min][:value] = result['dew'].to_f + maxmin[:dew][:min][:time] = result['LogDateTime'].strftime("%H:%M") + end + + # Max Humidity + if result['hum'] >= maxmin[:hum][:max][:value] + maxmin[:hum][:max][:value] = result['hum'] + maxmin[:hum][:max][:time] = result['LogDateTime'].strftime("%H:%M") + end + + # Min Humidity + if result['hum'] <= maxmin[:hum][:min][:value] + maxmin[:hum][:min][:value] = result['hum'] + maxmin[:hum][:min][:time] = result['LogDateTime'].strftime("%H:%M") + end + + # Max Rain Rate + if result['rrate'] >= maxmin[:rainrate][:max][:value] + maxmin[:rainrate][:max][:value] = result['rrate'].to_f + maxmin[:rainrate][:max][:time] = result['LogDateTime'].strftime("%H:%M") + end + end + + puts "Data compiled!" + + puts "Generating e-mail body..." + + table = Terminal::Table.new :title => "Weather Summary as of #{now["LogDateTime"].strftime("%l:%M %p, %a %b %d %Y")}" do |t| + t << [ + { :value => "Temperature", :colspan => 2, :alignment => :center}, + { :value => "Dew Point", :colspan => 2, :alignment => :center} + ] + t << :separator + t << [ + "Current", "#{now["temp"].to_s("F")}C", + "Current", "#{now["dew"].to_s("F")}C" + ] + t << [ + "Today's High", "#{maxmin[:temp][:max][:value]}C at #{maxmin[:temp][:max][:time]}", + "Today's High", "#{maxmin[:dew][:max][:value]}C at #{maxmin[:dew][:max][:time]}" + ] + t << [ + "Today's Low", "#{maxmin[:temp][:min][:value]}C at #{maxmin[:temp][:min][:time]}", + "Today's Low", "#{maxmin[:dew][:min][:value]}C at #{maxmin[:dew][:min][:time]}" + ] + t << :separator + t << [ + { :value => "Humidity", :colspan => 2, :alignment => :center}, + { :value => "Barometric Pressure (SL)", :colspan => 2, :alignment => :center} + ] + t << :separator + t << [ + "Current", "#{now["hum"]}%", + "Current", "#{now["press"].to_s("F")} mb" + ] + t << [ + "Today's High", "#{maxmin[:hum][:max][:value]}% at #{maxmin[:hum][:max][:time]}", + "Trend", "#{now["presstrendval"]} mb/hr" + ] + t << [ + "Today's Low", "#{maxmin[:hum][:min][:value]}% at #{maxmin[:hum][:min][:time]}", + "","" + ] + t << :separator + t << [ + { :value => "Rain", :colspan => 2, :alignment => :center}, + { :value => "Wind", :colspan => 2, :alignment => :center} + ] + t << :separator + t << [ + "Current Rate", "#{now["rrate"]} #{now["rainunit"]}", + "Current Speed", "#{now["wspeed"].to_s} #{now["windunit"]}" + ] + t << [ + "Today's High Rate", "#{maxmin[:rainrate][:max][:value]} #{now["rainunit"]} at #{maxmin[:rainrate][:max][:time]}", + "Gust", "#{now["wgust"].to_s} #{now["windunit"]}" + ] + t << [ + "Today's Total", "#{now["rfall"].to_s("F")} #{now["rainunit"]}", + "Today's High Speed", "#{now["windTM"].to_s} #{now["windunit"]} at #{now["TwindTM"]}" + ] + t << [ + "Monthly Total","#{today["rmonth"].to_s("F")} #{now["rainunit"]}", + "Today's High Gust", "#{now["wgustTM"]} #{now["windunit"]} at #{now["TwgustTM"]}" + ] + t << [ + "Yearly Total","#{today["ryear"].to_s("F")} #{now["rainunit"]}", + "", "" + ] + end + + puts "E-mail body generated!" + + puts "Sending e-mail..." + + Pony.mail( + :to => ENV['MAIL_RECIPIENT'], + :from => ENV['MAIL_SENDER'], + :subject => 'Daily Weather Summary', + :body => table.to_s, + :via => :smtp, + :via_options => options + ) + + puts "E-mail sent!" + puts "DONE!" + +rescue Mysql2::Error => e + puts "Error connecting to database: #{e.message}" +ensure + client&.close # Ensure the connection is closed +end