{"id":18103953,"url":"https://github.com/svoop/ogn_client-ruby","last_synced_at":"2025-06-16T01:35:54.024Z","repository":{"id":56886229,"uuid":"47460302","full_name":"svoop/ogn_client-ruby","owner":"svoop","description":"Subscriber and parser for APRS messages from OGN","archived":false,"fork":false,"pushed_at":"2024-12-26T18:54:45.000Z","size":554,"stargazers_count":7,"open_issues_count":3,"forks_count":2,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-05-16T02:07:42.885Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/svoop.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"svoop","custom":"https://donorbox.org/bitcetera"}},"created_at":"2015-12-05T15:07:12.000Z","updated_at":"2024-12-26T18:54:40.000Z","dependencies_parsed_at":"2023-12-29T00:24:28.304Z","dependency_job_id":"63f5f1ed-a4f8-469b-866e-f059a4aecf63","html_url":"https://github.com/svoop/ogn_client-ruby","commit_stats":{"total_commits":86,"total_committers":2,"mean_commits":43.0,"dds":"0.023255813953488413","last_synced_commit":"accddef5195346bb215c18391aea2d170a5867f1"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/svoop/ogn_client-ruby","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/svoop%2Fogn_client-ruby","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/svoop%2Fogn_client-ruby/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/svoop%2Fogn_client-ruby/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/svoop%2Fogn_client-ruby/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/svoop","download_url":"https://codeload.github.com/svoop/ogn_client-ruby/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/svoop%2Fogn_client-ruby/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260081832,"owners_count":22956193,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-31T22:13:36.256Z","updated_at":"2025-06-16T01:35:54.006Z","avatar_url":"https://github.com/svoop.png","language":"Ruby","funding_links":["https://github.com/sponsors/svoop","https://donorbox.org/bitcetera"],"categories":[],"sub_categories":[],"readme":"[![Version](https://img.shields.io/gem/v/ogn_client-ruby.svg?style=flat)](https://rubygems.org/gems/ogn_client-ruby)\n[![Tests](https://img.shields.io/github/actions/workflow/status/svoop/ogn_client-ruby/test.yml?style=flat\u0026label=tests)](https://github.com/svoop/ogn_client-ruby/actions?workflow=Test)\n[![Code Climate](https://img.shields.io/codeclimate/maintainability/svoop/ogn_client-ruby.svg?style=flat)](https://codeclimate.com/github/svoop/ogn_client-ruby)\n[![GitHub Sponsors](https://img.shields.io/github/sponsors/svoop.svg)](https://github.com/sponsors/svoop)\n\n# ogn_client-ruby\n\n[OGN](http://glidernet.org) broadcasts aircraft positions as [APRS](http://www.aprs.org)/[APRS-IS](http://www.aprs-is.net) messages. This gem hooks into this stream of data and provides the necessary classes to parse the raw message strings into meaningful objects.\n\n* Homepage: https://github.com/svoop/ogn_client-ruby\n* Author: [Sven Schwyn](http://bitcetera.com)\n\nThank you for supporting free and open-source software by sponsoring on [GitHub](https://github.com/sponsors/svoop) or on [Donorbox](https://donorbox.com/bitcetera). Any gesture is appreciated, from a single Euro for a ☕️ cup of coffee to 🍹 early retirement.\n\n## Installation\n\n### Security\n\nThis gem is [cryptographically signed](https://guides.rubygems.org/security/#using-gems) in order to assure it hasn't been tampered with. Unless already done, please add the author's public key as a trusted certificate now:\n\n```\ngem cert --add \u003c(curl -Ls https://raw.github.com/svoop/ogn_client-ruby/master/certs/svoop.pem)\n```\n\n### Bundler\n\nAdd the following to the \u003ctt\u003eGemfile\u003c/tt\u003e or \u003ctt\u003egems.rb\u003c/tt\u003e of your [Bundler](https://bundler.io) powered Ruby project:\n\n```ruby\ngem 'ogn_client-ruby', require: 'ogn_client'\n```\n\nAnd then install the bundle:\n\n```\nbundle install --trust-policy MediumSecurity\n```\n\n### Standalone\n\nIf you're only going to use [the executables](#executables):\n\n```\ngem install ogn_client-ruby --trust-policy MediumSecurity\n```\n\n## Usage\n\n### Subscribe to OGN\n\nChoose a [valid callsign](http://www.aprs-is.net/Connecting.aspx#loginrules) and [appropriate filters](http://www.aprs-is.net/javAPRSFilter.aspx), then start listening to the broadcasted raw messages:\n\n```ruby\nrequire 'ogn_client'\n\nOGNClient::APRS.start(callsign: \"ROCT#{rand(1000)}\", filter: 'r/47/2/500') do |aprs|\n  while raw = aprs.gets\n    puts raw   # do more interesting stuff here\n  end\nend\n```\n\n### Parse Raw Message Strings\n\n:point_up: Refer to the wiki for an introduction to [OGN flavoured APRS](https://github.com/svoop/ogn_client-ruby/wiki) messages.\n\nIn the above example, each `aprs.gets` returns a raw message string. To decode this string, just pass it to the message parser:\n\n```ruby\nOGNClient::Message.parse(aprs.gets)\n```\n\n:point_up: Raw APRS messages as returned by `aprs.gets` are \"ASCII-8BIT\" encoded and may contain tailing whitespace. The parser removes this whitespace and converts the string to \"UTF-8\".\n\nThe factory method `OGNClient::Message.parse` will return one an instance of `OGNClient::Sender`, `OGNClient::Receiver`, `OGNClient::Comment` or [raise an error](#errors). When this happens, either the message is crippled, the [OGN](http://glidernet.org) specifications have changed or you have found a bug in the parser code.\n\nIn production, you may want to rescue from these errors and ignore the message. You should, however, log the offending messages messages, [file a bug](#community-support) and replay them once the bug has been fixed.\n\n:point_up: Raw APRS messages do not contain the date, but assume the current day. This may cause trouble around midnight, however, the parser deals with such edge cases gracefully. Things are a little different when parsing raw APRS messages recorded in the past e.g. with `ognlogd`. Since the parser has no means to detect the date the APRS messages have been sent, you have to pass it as an option:\n\n```ruby\nraw_aprs = File.open('2017-06-24.log', \u0026:gets)\nOGNClient::Message.parse(raw_aprs, date: '2017-06-24')\n```\n\n#### OGNClient::SenderBeacon\n\nSender beacons are usually coming from aircraft equipped with [FLARM](https://flarm.com) (anti-collision warning system) or similar devices which broadcast position data as RF beacons.\n\nThe data is converted into the metric system since [OGN](http://glidernet.org) is primarily made for gliders which mostly use the metric system for ground speed, climb rate and so forth.\n\nAttributes:\n* **callsign** - origin callsign\n* **receiver** - receiver callsign\n* **time** - zulu/UTC time with date\n* **longitude** - WGS84 degrees from -180 (W) to 180 (E)\n* **latitude** - WGS84 degrees from -90 (S) to 90 (N)\n* **altitude** - WGS84 meters above mean see level QNH\n* **heading** - degrees from 1 to 360\n* **ground_speed** - kilometers per hour\n* **sender_type** - see [SENDER_TYPES](https://github.com/svoop/ogn_client-ruby/blob/master/lib/ogn_client/messages/sender.rb)\n* **address_type** - see [ADDRESS_TYPES](https://github.com/svoop/ogn_client-ruby/blob/master/lib/ogn_client/messages/sender.rb)\n* **id** - device ID\n* **stealth_mode** - boolean (should always be false)\n* **no_tracking** - boolean\n* **flight_level** - 100 feet QNE\n* **climb_rate** - meters per second\n* **turn_rate** - revolutions per minute\n* **signal_power** - power ratio in dBm\n* **signal_quality** - signal to noise ratio in decibel\n* **errors** - number of CRC errors\n* **frequency_offset** - kilohertz\n* **gps_accuracy** - array [vertical meters, horizontal meters]\n* **flarm_software_version** - version as \"major.minor\"\n* **flarm_hardware_version** - version as integer\n* **flarm_id** - FLARM device ID\n* **proximity** - array of FLARM device ID tails\n\n#### OGNClient::ReceiverBeacon\n\nReceivers are little RF boxes which pick up the RF beacons from aircraft and relay them to the OGN servers as messages. They send their own beacons on a regular basis.\n\nAttributes:\n* **callsign** - origin callsign\n* **receiver** - receiver callsign\n* **time** - zulu/UTC time with date\n* **longitude** - WG84 degrees from -180 (W) to 180 (E)\n* **latitude** - WG84 degrees from -90 (S) to 90 (N)\n* **altitude** - WG84 meters above mean sea level QNH\n* **heading** - degrees from 1 to 360\n* **ground_speed** - kilometers per hour\n\nPlease note: These receiver beacons contained status information up until version 0.2.5.\n\n#### OGNClient::ReceiverStatus\n\nReceivers of version 0.2.6 and higher send status messages on a regular basis:\n\nAttributes:\n* **callsign** - origin callsign\n* **receiver** - receiver callsign\n* **time** - zulu/UTC time with date\n* **version** - software version as \"major.minor.patch\"\n* **platform** - e.g. :arm\n* **cpu_load** - as reported by \"uptime\"\n* **cpu_temperature** - in degrees celsius\n* **ram_free** - megabytes\n* **ram_total** - megabytes\n* **ntp_offset** - milliseconds\n* **ntp_correction** - parts-per-million\n* **voltage** - board voltage in V\n* **amperage** - board amperage in A\n* **rf_correction_manual** - manual frequency correction as per configuration\n* **rf_correction_automatic** - automatic frequency correction based on GSM\n* **senders** - number of senders received within the last hour\n* **visible_senders** - number of visible senders withint the last hour\n* **invisible_senders** - number of invisible senders (\"no-track\" on device or \"invisible\" in database)\n* **signal_quality** - signal-to-noise ratio in decibel\n* **senders_signal_quality** - average signal-to-noise ratio across all senders\n* **senders_messages** - number of messages analyzed to calculate the above\n* **good_senders_signal_quality** - average signal-to-noise ratio in decibel of good senders (transmitting properly) within the last 24 hours\n* **good_and_bad_senders** - number of good and bad senders within the last 24 hours\n* **good_senders** - number of good senders (transmitting properly) within the last 24 hours\n* **bad_senders** - number of bad senders (not transmitting properly) within the last 24 hours\n\n#### OGNClient::Comment\n\nComments are sent on a regular basis to keep the connection alive.\n\nAttribute:\n* **comment** - raw message with the comment marker stripped\n\n## Errors\n\nThe following domain specific errors may be raised:\n\n* OGNClient::MessageError - errors during the parsing of a message\n* OGNClient::ReceiverError - errors during the parsing of a receiver message\n\nThey all inherit from `OGNClient::Error`. An fault-tolerant subscription could therefore look as follows:\n\n```ruby\nrequire 'ogn_client'\nrequire 'logger'\n\nlogger = Logger.new('/tmp/ogn_client.log')\noptions = { callsign: \"ROCT#{rand(1000)}\", filter: 'r/47/2/500' }\nloop do\n  OGNClient::APRS.start(options) do |aprs|\n    while raw = aprs.gets\n      begin\n        message = OGNClient::Message.parse aprs.gets\n      rescue OGNClient::Error =\u003e error\n        logger.error error.message\n        next\n      end\n      puts message.raw   # do more interesting stuff here\n    end\n  end\nend\n```\n\n:point_up: Receiver versions (\"major.minor.patch\") are will only raise an error when the offending version has a higher major or minor version digit. Patch level differences will only trigger a warning.\n\n## Executables\n\n### ognlogd\n\nA simple daemon to log raw APRS messages to daily files.\n\n    ognlogd --help\n\n### ogn2kml and ogn2geojson\n\nConvert raw APRS messages (e.g. from `ognlogd`) to KML or GeoJSON.\n\n    ogn2kml --help\n    ogn2geojson --help\n\n## Community Support\n\n* Look for developers and users on [Gitter](https://gitter.im/svoop/ogn_client-ruby).\n* Ask your questions on [Stackoverflow](https://stackoverflow.com/questions/ask?tags=ogn_client-ruby,ruby,gem).\n* Annotated source code on [omniref](https://www.omniref.com/repositories/svoop/ogn_client-ruby)\n* Bug reports, feature and pull requests are welcome on [GitHub](https://github.com/svoop/ogn_client-ruby).\n* [Donations are welcome as well](https://donorbox.org/bitcetera-ogn_client-ruby)l. If you prefer to sponsor a feature, please create an issue on [GitHub](https://github.com/svoop/ogn_client-ruby) first and state your intentions.\n\n## Development\n\nTo install the development dependencies and then run the test suite:\n\n  bundle install\n  bundle exec rake    # run tests once\n  bundle exec guard   # run tests whenever files are modified\n  \nThe test suite may run against live OGN data if you set the `SPEC_SCOPE` environment variable, by default, these tests are skipped.\n\n```\nexport SPEC_SCOPE=all\n```\n\nPlease submit issues on:\n\nhttps://github.com/svoop/ogn_client-ruby/issues\n\nTo contribute code, fork the project on Github, add your code and submit a\npull request:\n\nhttps://help.github.com/articles/fork-a-repo\n\n## Feature Brainstorming\n\n* registration lookups\n* configuration option to switch between metric and aeronautical units\n* more data sources such as ADS-B\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsvoop%2Fogn_client-ruby","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsvoop%2Fogn_client-ruby","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsvoop%2Fogn_client-ruby/lists"}