#!/opt/mbari/bin/ruby #Earth Centered Cartesian to Spherical coordinate transform described here: # https://microem.ru/files/2012/08/GPS.G1-X-00006.pdf Epoch = Time.utc(2014,5,11,14,23,55) #Iridium Epoch Platform = ARGV[0] Recipient = ARGV[1] || "mooringtrack" Sender = ARGV[2] || ENV['USER'] || `hostname` Server = ARGV[3] || 'mail' Domain = ARGV[4] || 'mbari.org' if not Platform or Platform.start_with? '-' this=File.basename $0 STDERR.puts <<END #{this} emails most recent lat/long coordinates derived from IridiumLocation entries in Linux system log to #{Recipient}@#{Domain} -- brent@mbari.org 2/27/20 Output time in epoch seconds associated with this update First argument is the ODSS platform name Optional 2nd argument is the recipient [#{Recipient}] Optional 3rd argument is the sender [#{Sender}] Optional 4th argument is the smtp server [#{Server}] Optional 5th argument is the domain name [#{Domain}] Suppress all emails if recipient == '-' Environment: Suppress email while lastUpdate <= Iridium time of last update already emailed Output: stdout: the hexadecimal Iridium time of the most recent update emailed stderr: the text of all updates emailed Example: curl -s ftp://espshore/moe/esp/messages | #{this} GoMex20 END exit 2 end include Math DegPerRad = 180/PI A = 6378.137 B = 6356.7523142451 b2 = B*B a2 = A*A a2lessB2 = a2 - b2 E2 = a2lessB2 / a2 Eprime2 = a2lessB2 / b2 def update match, frame=match[4].hex epochSecs = Epoch + 0.09*frame x,y,z = Integer(match[1]), Integer(match[2]), Integer(match[3]) p = sqrt(x*x + y*y) theta = atan2 A*z, p*B lat = atan2(z + Eprime2*B*sin(theta)**3, p - E2*A*cos(theta)**3) * DegPerRad long = atan2(y,x) * DegPerRad location='%.3f,%.3f' % [long,lat] subject = "#{Platform},#{epochSecs.to_i},#{location}" STDERR.puts subject return if Recipient == '-' msgstr = <<-END Subject: #{subject} Date: #{`date -R`} #{subject} END require 'net/smtp' Net::SMTP.start(Server, 25, Domain) do |smtp| smtp.send_message msgstr, Sender, "#{Recipient}@#{Domain}" end end loc = /\s+IridiumLocation:\s*(-?\d+),(-?\d+),(-?\d+),([0-9a-f]+)/i match = frame = nil lastUpdate = ENV['lastUpdate'] lastUpdate &&= lastUpdate.hex STDIN.each do |logLine| next unless match = loc.match(logLine) frame = match[4].hex raise "Invalid timestamp: #{match[4]}" if frame == 0 update match, frame if lastUpdate and frame > lastUpdate end raise "No IridiumLocation log entries found" unless match update match, frame unless lastUpdate puts "0x%x" % frame