ogn_client-ruby 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +14 -0
- data/exe/ogn2kml +126 -0
- data/exe/ognlogd +80 -0
- data/lib/ogn_client/version.rb +1 -1
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cc7bfb92c9ee1a6a43a8fbe34b66a795c1a34551
|
4
|
+
data.tar.gz: 663f89af96ca723f2042fa46c943abf831c0dc9e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 47cd82bc99d6c9147ab1af0cbf29dbff876d536e50416f914a00a292b82dbb50b8f3e87a91faad2fe91ff52eb8024d57baa83541d504389895c6030a7852330e
|
7
|
+
data.tar.gz: 58a4744ec0cb1b4bcb9c35a3138b080d7bca6c301f953ceb08cb0204f0e8669ea6237aa04e5c0db68a8a88baeb8ba76332e4e97d577738a961627c506ff67618
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -180,6 +180,20 @@ end
|
|
180
180
|
|
181
181
|
: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.
|
182
182
|
|
183
|
+
## Executables
|
184
|
+
|
185
|
+
### ognlogd
|
186
|
+
|
187
|
+
A simple daemon to log raw APRS messages to daily files.
|
188
|
+
|
189
|
+
ognlogd --help
|
190
|
+
|
191
|
+
### ogn2kml
|
192
|
+
|
193
|
+
Convert raw APRS messages (e.g. from `ognlogd`) to KML.
|
194
|
+
|
195
|
+
ogn2kml --help
|
196
|
+
|
183
197
|
## Community Support
|
184
198
|
|
185
199
|
* Look for developers and users on [Gitter](https://gitter.im/svoop/ogn_client-ruby).
|
data/exe/ogn2kml
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/inline'
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
gemfile do
|
7
|
+
source 'https://rubygems.org'
|
8
|
+
ruby '>= 2.4'
|
9
|
+
gem 'progressbar', '~> 1.8'
|
10
|
+
gem 'libxml-ruby', '~> 3.0', require: 'xml'
|
11
|
+
gem 'ogn_client-ruby', '~> 0.2', require: 'ogn_client'
|
12
|
+
end
|
13
|
+
|
14
|
+
class Converter
|
15
|
+
def initialize
|
16
|
+
OptionParser.new do |o|
|
17
|
+
o.banner = <<~END
|
18
|
+
Convert raw OGN APRS to KML tracks.
|
19
|
+
Usage: ogn2kml [options] infile
|
20
|
+
END
|
21
|
+
o.on('-a', '--about', 'author and license information') { puts 'Written by Sven Schwyn (bitcetera.com) and distributed under MIT license.'; exit }
|
22
|
+
o.on('-c', '--callsign STRING', String, 'aircraft callsign (e.g. FLRAABBCC)') { |v| @callsign = v }
|
23
|
+
o.on('-o', '--outfile FILE', String, 'generated KML file (default: INFILE.kml)') { |v| @outfile = v.sub(/\.kml$/, '') + '.kml' }
|
24
|
+
end.parse!
|
25
|
+
@infile = ARGV.pop
|
26
|
+
fail 'infile not found' unless @infile && File.exists?(@infile)
|
27
|
+
@outfile ||= @infile.sub(/\.\w+$/, '') + '.kml'
|
28
|
+
end
|
29
|
+
|
30
|
+
def style_nodes
|
31
|
+
fragment = <<~END
|
32
|
+
<Fragment>
|
33
|
+
<Style id="track_normal">
|
34
|
+
<IconStyle>
|
35
|
+
<Icon>
|
36
|
+
<href>http://earth.google.com/images/kml-icons/track-directional/track-0.png</href>
|
37
|
+
</Icon>
|
38
|
+
</IconStyle>
|
39
|
+
<LineStyle>
|
40
|
+
<color>99ffac59</color>
|
41
|
+
<width>6</width>
|
42
|
+
</LineStyle>
|
43
|
+
</Style>
|
44
|
+
<Style id="track_highlight">
|
45
|
+
<IconStyle>
|
46
|
+
<scale>1.2</scale>
|
47
|
+
<Icon>
|
48
|
+
<href>http://earth.google.com/images/kml-icons/track-directional/track-0.png</href>
|
49
|
+
</Icon>
|
50
|
+
</IconStyle>
|
51
|
+
<LineStyle>
|
52
|
+
<color>99ffac59</color>
|
53
|
+
<width>8</width>
|
54
|
+
</LineStyle>
|
55
|
+
</Style>
|
56
|
+
<StyleMap id="track">
|
57
|
+
<Pair>
|
58
|
+
<key>normal</key>
|
59
|
+
<styleUrl>#track_normal</styleUrl>
|
60
|
+
</Pair>
|
61
|
+
<Pair>
|
62
|
+
<key>highlight</key>
|
63
|
+
<styleUrl>#track_highlight</styleUrl>
|
64
|
+
</Pair>
|
65
|
+
</StyleMap>
|
66
|
+
</Fragment>
|
67
|
+
END
|
68
|
+
XML::Parser.string(fragment).parse.root.each_child { |c| yield c }
|
69
|
+
end
|
70
|
+
|
71
|
+
def convert!
|
72
|
+
lines = File.readlines(@infile)
|
73
|
+
progressbar = ProgressBar.create(format: '%e |%b>%i| %p%% %t', total: lines.count)
|
74
|
+
xml = XML::Document.new
|
75
|
+
root = xml.root = XML::Node.new(:kml)
|
76
|
+
root['xmlns'] = 'http://www.opengis.net/kml/2.2'
|
77
|
+
root['xmlns:gx'] = 'http://www.google.com/kml/ext/2.2'
|
78
|
+
root << (document = XML::Node.new(:Document))
|
79
|
+
document << XML::Node.new(:name, 'OGN')
|
80
|
+
style_nodes { |n| document << xml.import(n) }
|
81
|
+
document << (folder = XML::Node.new(:Folder))
|
82
|
+
folder << XML::Node.new(:name, 'Tracks')
|
83
|
+
folder << (placemark = XML::Node.new(:Placemark))
|
84
|
+
placemark << XML::Node.new(:name, @callsign || 'all')
|
85
|
+
placemark << XML::Node.new(:styleUrl, '#track')
|
86
|
+
placemark << (track = XML::Node.new(:'gx:Track'))
|
87
|
+
track << XML::Node.new(:altitudeMode, 'absolute')
|
88
|
+
time = XML::Node.new(:'gx:SimpleArrayData')
|
89
|
+
time['name'] = 'Time'
|
90
|
+
ground_speed = XML::Node.new(:'gx:SimpleArrayData')
|
91
|
+
ground_speed['name'] = 'Ground Speed'
|
92
|
+
climb_rate = XML::Node.new(:'gx:SimpleArrayData')
|
93
|
+
climb_rate['name'] = 'Climb Rate'
|
94
|
+
turn_rate = XML::Node.new(:'gx:SimpleArrayData')
|
95
|
+
turn_rate['name'] = 'Turn Rate'
|
96
|
+
lines.each do |line|
|
97
|
+
if (sender = OGNClient::Message.parse(line)).is_a? OGNClient::SenderBeacon
|
98
|
+
if !@callsign || sender.callsign == @callsign
|
99
|
+
track << XML::Node.new(:when, sender.time.xmlschema)
|
100
|
+
track << XML::Node.new(:'gx:coord', "#{sender.longitude} #{sender.latitude} #{sender.altitude}")
|
101
|
+
track << XML::Node.new(:'gx:angles', "#{sender.heading} 0 0")
|
102
|
+
time << XML::Node.new(:'gx:value', sender.time.getlocal.strftime('%H:%M:%S'))
|
103
|
+
ground_speed << XML::Node.new(:'gx:value', sender.ground_speed.to_i.to_s)
|
104
|
+
climb_rate << XML::Node.new(:'gx:value', sender.climb_rate.to_i.to_s)
|
105
|
+
turn_rate << XML::Node.new(:'gx:value', sender.turn_rate.to_i.to_s)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
progressbar.increment
|
109
|
+
end
|
110
|
+
track << (extended_data = XML::Node.new(:ExtendedData))
|
111
|
+
extended_data << (schema_data = XML::Node.new(:SchemaData))
|
112
|
+
schema_data['schemaUrl'] = '#schema'
|
113
|
+
schema_data << time
|
114
|
+
schema_data << ground_speed
|
115
|
+
schema_data << climb_rate
|
116
|
+
schema_data << turn_rate
|
117
|
+
xml.save(@outfile, encoding: XML::Encoding::UTF_8)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
begin
|
122
|
+
Converter.new.convert!
|
123
|
+
rescue => exception
|
124
|
+
puts "#{File.basename($0)}: #{exception.message}"
|
125
|
+
exit 1
|
126
|
+
end
|
data/exe/ognlogd
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/inline'
|
4
|
+
require 'optparse'
|
5
|
+
require 'time'
|
6
|
+
|
7
|
+
gemfile do
|
8
|
+
source 'https://rubygems.org'
|
9
|
+
ruby '>= 2.4'
|
10
|
+
gem 'ogn_client-ruby', '~> 0.2', require: 'ogn_client'
|
11
|
+
gem 'daemons', '~> 1.2'
|
12
|
+
end
|
13
|
+
|
14
|
+
class Daemon
|
15
|
+
attr_reader :name, :command, :rundir, :monitor
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@name = File.basename($0)
|
19
|
+
@callsign = "ROCD#{rand(1000)}"
|
20
|
+
@filter = "r/44/4/20"
|
21
|
+
@outdir = "/tmp"
|
22
|
+
@rundir = '/var/run'
|
23
|
+
@gzip = true
|
24
|
+
@monitor = false
|
25
|
+
OptionParser.new do |o|
|
26
|
+
o.banner = <<~END
|
27
|
+
Log raw OGN APRS messages to daily files.
|
28
|
+
Usage: #{@name} [options] {start|stop|restart|run|status|zap}
|
29
|
+
END
|
30
|
+
o.on('-a', '--about', 'author and license information') { puts 'Written by Sven Schwyn (bitcetera.com) and distributed under MIT license.'; exit }
|
31
|
+
o.on('-c', '--callsign STRING', String, 'daemon callsign (default: ROCDnnnn)') { |v| @callsign = v }
|
32
|
+
o.on('-f', '--filter STRING', String, "APRS filter (default: #{@filter})") { |v| @filter = v }
|
33
|
+
o.on('-g', '--[no-]gzip', "gzip log files at midnight (default: #{@gzip})") { |v| @gzip = v }
|
34
|
+
o.on('-m', '--[no-]monitor', "automatically restart daemon after crash (default: #{@monitor})") { |v| @monitor = v }
|
35
|
+
o.on('-o', '--outdir DIR', String, "directory to write the files (default: #{@outdir})") { |v| @outdir = v }
|
36
|
+
o.on('-r', '--rundir DIR', String, "directory to write the PID file (default: #{@rundir})") { |v| @rundir = v }
|
37
|
+
end.parse!
|
38
|
+
@command = ARGV.pop&.to_sym
|
39
|
+
fail "command not recognized" unless %i(start stop restart run status zap).include? @command
|
40
|
+
end
|
41
|
+
|
42
|
+
def capture!
|
43
|
+
loop do
|
44
|
+
catch :cut do
|
45
|
+
`gzip "#{logfile}"` if @gzip && defined?(logfile)
|
46
|
+
logfile = "#{@outdir}/ogn.log-#{Time.now.strftime('%Y%m%d')}"
|
47
|
+
end_of_day = Time.parse("24:00").to_i
|
48
|
+
File.open(logfile, 'a') do |file|
|
49
|
+
file.sync = true
|
50
|
+
loop do
|
51
|
+
OGNClient::APRS.start(callsign: @callsign, filter: @filter) do |aprs|
|
52
|
+
while raw = aprs.gets
|
53
|
+
file.puts raw
|
54
|
+
throw :cut if end_of_day < Process.clock_gettime(Process::CLOCK_REALTIME, :second)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
begin
|
65
|
+
daemon = Daemon.new
|
66
|
+
Daemons.run_proc(
|
67
|
+
daemon.name,
|
68
|
+
multiple: false,
|
69
|
+
ARGV: [daemon.command.to_s],
|
70
|
+
dir_mode: :normal,
|
71
|
+
dir: daemon.rundir,
|
72
|
+
monitor: daemon.monitor,
|
73
|
+
monitor_interval: 60
|
74
|
+
) do
|
75
|
+
daemon.capture!
|
76
|
+
end
|
77
|
+
rescue => exception
|
78
|
+
puts "#{File.basename($0)}: #{exception.message}"
|
79
|
+
exit 1
|
80
|
+
end
|
data/lib/ogn_client/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ogn_client-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sven Schwyn
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-04-
|
11
|
+
date: 2017-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -99,7 +99,9 @@ description: OGN (glidernet.org) broadcasts aircraft positions as APRS/APRS-IS m
|
|
99
99
|
the raw message strings into meaningful objects.
|
100
100
|
email:
|
101
101
|
- ruby@bitcetera.com
|
102
|
-
executables:
|
102
|
+
executables:
|
103
|
+
- ogn2kml
|
104
|
+
- ognlogd
|
103
105
|
extensions: []
|
104
106
|
extra_rdoc_files: []
|
105
107
|
files:
|
@@ -116,6 +118,8 @@ files:
|
|
116
118
|
- Rakefile
|
117
119
|
- bin/console
|
118
120
|
- bin/setup
|
121
|
+
- exe/ogn2kml
|
122
|
+
- exe/ognlogd
|
119
123
|
- lib/ogn_client.rb
|
120
124
|
- lib/ogn_client/aprs.rb
|
121
125
|
- lib/ogn_client/errors.rb
|