my_gpsd_client 0.1.30 → 0.02.00

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ee600b4280ec136fb4493892c58b4bb008e33c1f8224ce20bbf1991ea534e469
4
- data.tar.gz: 2b760c07a8cb3e090f2b4a2d53f11edbc3811425004e093e902913fdceeaba52
3
+ metadata.gz: 55ba906b7dbaf8ff492fb7a06409f631e4365f28afbad9ce304feb8c7be1e000
4
+ data.tar.gz: 72381fa6a0ee53da5880cba4e4c7d414296b9beab632890e6858814897f3eb4a
5
5
  SHA512:
6
- metadata.gz: 9596d2cd259de9f857a47124e0b171be2a3378cc73b47de6b22e00eee3bea431caf15af18e97d4ace0864808c0c73325604887e3426ca5315d1400dc2efac105
7
- data.tar.gz: 731aea1ff46f96c1c60909c4cf41c02c45772b5bf458f7177129df18fc6ca17cb220a318d2fc9de3f8a7cc24fd019ea75427e211ebc3da16beca8d922244300f
6
+ metadata.gz: 2a827c3021083ac68f84e622dad8812695e69ed8219f1bc7cb1e95dda40106efa3373715c4ecaec53ad2b335128110117b404b8bb99c075e9a08d99475314f32
7
+ data.tar.gz: cb009e38a29b6e0d2b2826a1d234d9b0e4c579d20025d52714844413fb74d18c33490d54672f7818677b4e13a191c8813d87a99c255c38005e379f86df1b94d3
data/.gitignore CHANGED
@@ -6,3 +6,4 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+ /log/
@@ -2,12 +2,27 @@ require "my_gpsd_client/version"
2
2
  require 'socket'
3
3
  require 'json'
4
4
  require 'date'
5
+ require 'logger'
5
6
 
6
7
  class MyGpsdClient
7
- attr_accessor :host, :port, :watch, :verbose, :min_speed, :watchdog_max, :watchdog_force
8
- attr_reader :version, :socket_ready, :msg_counts, :watchdog_fired_count
8
+ attr_accessor :host, :port, :command, :log_level, :min_speed, :watchdog_max, :watchdog_force
9
+ attr_reader :version, :last_watch, :socket_ready, :msg_counts, :watchdog_fired_count
10
+
11
+ DEFAULT_HOST = 'localhost'
12
+ DEFAULT_PORT = 2947
13
+ DEFAULT_WATCH = {"enable":false,"json":false,"nmea":false}
14
+ DEFAULT_LOG_LEVEL = 0
15
+ DEFAULT_WATCHDOG_MAX = 5.0
16
+ WATCHDOG_STEP = 0.1 # Check watchdog ten times per second
17
+
18
+ THREAD_NAMES = { # Keep displayed names the same length
19
+ MainThread: "MainThread ",
20
+ SocketInitThread: "SockInitThd",
21
+ WatchdogThread: "WatchdogThd",
22
+ ReadThread: "ReadThread "
23
+ }
24
+ Thread.current[:name]=THREAD_NAMES[:MainThread]
9
25
 
10
- DEFAULT_WATCH = {"enable":true,"json":true,"nmea":false}
11
26
 
12
27
  # A simple gpsd client that dump's json objects contianing all info received from the gpsd deamon
13
28
  # you need to at least setup either the raw callback (on_raw_change) or position callback (on_position_change) to use GPSD2JSON. the raw callback just passes the json objects it received from the daemon on to the block you pass it. the on_position_change and on_satellites_change are a bit easier to use.
@@ -24,19 +39,20 @@ class MyGpsdClient
24
39
  # gps.start
25
40
  # #when done
26
41
  # gps.stop
27
- def initialize(host: 'localhost', port: 2947, watch: DEFAULT_WATCH, verbose: false)
42
+ def initialize(host: DEFAULT_HOST, port: DEFAULT_PORT, watch: DEFAULT_WATCH, log_level: DEFAULT_LOG_LEVEL)
28
43
  @version = MyGpsdClient_version::VERSION
29
- @verbose = verbose
30
- @socket = nil
31
- @socket_ready = false
32
44
  @host = host
33
45
  @port = port
34
- @watch = watch
35
- @trackthread = nil
46
+ @last_watch = watch
47
+ @log_level = log_level
48
+
49
+ @socket = nil
50
+ @socket_ready = false
51
+ @readthread = nil
36
52
  @socket_init_thread = nil
37
53
  @watchdog_thread = nil
38
- @watchdog_count = 0
39
- @watchdog_max = 10
54
+ @watchdog_count = 0.0
55
+ @watchdog_max = DEFAULT_WATCHDOG_MAX
40
56
  @watchdog_fired_count = 0
41
57
  @watchdog_force = false
42
58
  @min_speed = 0 # speed needs to be higher than this to make the gps info count
@@ -51,175 +67,243 @@ class MyGpsdClient
51
67
  @msg_counts = {wtch: 0, ver: 0, tpv: 0, sky: 0, gst: 0, att: 0,
52
68
  toff: 0, pol: 0, pps: 0, dev: 0, devs: 0, err: 0,
53
69
  unk: 0}
54
- puts "Version: #{@version}" if @verbose
55
- end
56
70
 
57
- def on_raw_send(options:{}, &block)
58
- @sent_raw_callback = block
71
+ MyGpsdClient.logger.progname = MyGpsdClient
72
+ MyGpsdClient.logger.level = @log_level
73
+ my_logger level: 'info', msg: "MyGpsdClient Gem - Version: #{@version}"
59
74
  end
60
75
 
61
- # @param [Object] options Possible options to pass (not used yet)
62
- # @param [Block] block Block to call when new json object comes from gpsd
63
- def on_raw_change(options:{}, &block)
64
- @json_raw_callback = block
76
+ #
77
+ # Receive Commands from User
78
+ #
79
+ def command=(val)
80
+ @command = val
81
+ my_logger level: 'info', msg: "Command: Command received: #{@command}"
82
+ @last_watch = @command if @command[:class].casecmp? "WATCH"
83
+ send_cmmd
65
84
  end
66
85
 
67
- # @param [Object] options Possible options to pass (not used yet)
68
- # @param [Block] block Block to call when new gps position json object comes from gpsd
69
- def on_position_change(options:{}, &block)
70
- @json_pos_callback = block
86
+ def log_level=(val)
87
+ @log_level = val
88
+ MyGpsdClient.logger.level = @log_level
71
89
  end
72
90
 
73
- # @param [Object] options Possible options to pass (not used yet)
74
- # @param [Block] block Block to call when new satellite info json object comes from gpsd
75
- def on_satellites_change(options:{}, &block)
76
- @json_sat_callback = block
91
+ def log_marker level: 'debug', msg: "Log Marker"
92
+ my_logger level: level, msg: "~~~~~~~~~~~~~~~~~~~~~~~ #{msg} ~~~~~~~~~~~~~~~~~~~~~~~"
77
93
  end
78
94
 
79
- # @param [Object] options Possible options to pass (not used yet)
80
- # @param [Block] block Block to call when new pps info json object comes from gpsd
81
- def on_pps_change(options:{}, &block)
82
- @json_pps_callback = block
83
- end
95
+ private
84
96
 
85
- # @param [Object] options Possible options to pass (not used yet)
86
- # @param [Block] block Block to call when new pps info json object comes from gpsd
87
- def on_unk_change(options:{}, &block)
88
- @json_unk_callback = block
89
- end
90
-
91
- def reset_msg_counts
92
- @msg_counts.each_key { |k| @msg_counts[k] = 0 }
97
+ def send_cmmd
98
+ my_logger msg: "Entered Send_cmmd"
99
+ unless @socket_ready
100
+ my_logger msg: "Send_cmmd: Entering 'start'"
101
+ start
102
+ my_logger msg: "Send_cmmd: Wait for 'socket_init_thread' to completed"
103
+ @socket_init_thread.join # wait for socket_ready
104
+ my_logger msg: "Send_cmmd: 'start' completed"
105
+ end
106
+ unless @socket_ready
107
+ my_logger level: 'error', msg: 'Send_cmmd: Socket Initialization Error'
108
+ else
109
+ # it's ready, tell it to start watching and passing
110
+ my_logger msg: "Send_cmmd: socket ready, send cmmd"
111
+ str = "?#{@command[:class].upcase}=#{@command.to_json}"
112
+ my_logger level: 'info', msg: "Send_cmmd: sending: #{str}"
113
+ @sent_raw_callback.call( str) if @sent_raw_callback
114
+ @socket.puts str
115
+ # If Enable was false in the last WATCH command, close the connecction
116
+ stop if @last_watch.key?(:enable) && !@last_watch[:enable]
117
+ end
118
+ my_logger msg: "Send_cmmd: Exiting send_cmmd"
93
119
  end
94
120
 
95
- def self.version
96
- MyGpsdClient_version::VERSION
97
- end
121
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
122
+ #~~~~~~~~~~~~~~~~~~~~~~ PROCESS STARTUP ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
123
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
98
124
 
99
125
 
100
126
  # Open the socket and when ready request the position flow from the gps daemon
101
127
  def start
102
- # background thread that is used to open the socket and wait for it to be ready
103
- @socket_init_thread = Thread.start do
104
- #open the socket
105
- retry_count = 10
106
- while (retry_count -= 1) > 0
107
- #while not @socket_ready
108
- init_socket
109
- #wait for it to be ready
110
- sleep 0.1
111
- break if @socket_ready
112
- end
128
+ my_logger msg: "Entered Start"
113
129
 
114
- unless @socket_ready
115
- puts 'Socket Initialization Error' if @verbose
116
- else
117
- # it's ready, tell it to start watching and passing
118
- puts "socket ready, start watching" if @verbose
119
- str = "?WATCH=#{@watch.to_json}"
120
- puts "sending: #{str}" if @verbose
121
- @sent_raw_callback.call( str) if @sent_raw_callback
122
- @socket.puts str
123
- #puts 'sending: ?WATCH={"enable":true,"json":true}' if @verbose
124
- #@socket.puts '?WATCH={"enable":true,"json":true}'
125
- end
130
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
131
+ # background thread that is used to open the socket and wait for it to be ready
132
+ my_logger level: 'info', msg: "Start: Starting Socket_init Thread"
133
+ @socket_init_thread = Thread.start do
134
+ Thread.current[:name]=THREAD_NAMES[:SocketInitThread]
135
+ my_logger msg: "Socket_init Thread"
136
+ #open the socket
137
+ retry_count = 0
138
+ #while not @socket_ready
139
+ while (retry_count += 1) <= 10 && !@socket_ready
140
+ my_logger msg: "Socket_init Thread: Socket Init Loop - Pass: #{retry_count}"
141
+ init_socket
142
+ my_logger msg: "Socket_init Thread: Return from init_socket - @socket_ready: #{@socket_ready}"
143
+ #wait for it to be ready
144
+ sleep 0.1
126
145
  end
146
+ my_logger level: 'info', msg: "Socket_init Thread: Exiting"
147
+ end
127
148
 
128
- # background thead that is used to read info from the socket and use it
129
- @trackthread = Thread.start do
130
- while true do
131
- begin
132
- read_from_socket
133
- rescue
134
- "error while reading socket: #{$!}" if @verbose
135
- end
136
- end
149
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
150
+ # background thead that is used to read info from the socket and use it
151
+ my_logger msg: "Start: Starting readthread Thread"
152
+ @readthread = Thread.start do
153
+ Thread.current[:name]=THREAD_NAMES[:ReadThread]
154
+ my_logger msg: "Readthread Thread: #{Thread.current[:name]}"
155
+ my_logger msg: "Readthread: Wait for 'socket_init_thread' to completed"
156
+ # wait for socket_init_thread to complete so that @socket_ready will be true
157
+ @socket_init_thread.join if @socket_init_thread && @socket_init_thread.alive?
158
+ while @socket_ready do
159
+ begin
160
+ read_from_socket
161
+ rescue
162
+ my_logger msg: "Readthread Thread: Error while reading socket: #{$!}"
163
+ end
137
164
  end
165
+ my_logger level: 'warn', msg: "Readthread Thread: Exiting, @socket_ready: #{@socket_ready}"
166
+ end
138
167
 
139
- Thread.kill(@watchdogthread) if @watchdog_thread
140
- @watchdogthread = Thread.start do
141
- @watchdog_count = 0
142
- while true do
143
- if @watchdog_force
144
- @watchdog_force = false
145
- @watchdog_count = @watchdog_max
146
- end
147
- if (@watchdog_count += 1) >= @watchdog_max
148
- @watchdog_count = 0
149
- @watchdog_fired_count += 1
168
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
169
+ # background thread to implement a watchdog timer
170
+ my_logger msg: "Start: Starting Watchdog Thread"
171
+ @watchdogthread = Thread.start do
172
+ Thread.current[:name]=THREAD_NAMES[:WatchdogThread]
173
+ my_logger msg: "Watchdog Thread: #{Thread.current[:name]}"
174
+ @watchdog_count = 0.0
175
+ @watchdog_enabled = true
176
+ while @watchdog_enabled do
177
+ if @watchdog_force
178
+ @watchdog_force = false
179
+ # force the watchdog to fire by killing the socket
180
+ @socket.close if @socket && !@socket.closed?
181
+ #@watchdog_count = @watchdog_max
182
+ end
183
+ if (@watchdog_count += WATCHDOG_STEP) >= @watchdog_max
184
+ my_logger level: 'warn', msg: "Watchdog Fired"
185
+ @watchdog_count = 0.0
186
+ @watchdog_fired_count += 1
187
+ @watchdog_enabled = false
188
+ # Kill the readthread...
189
+ my_logger msg: "Watchdog Thread: Killing ReadThread"
190
+ Thread.kill(@readthread) if @readthread && @readthread.alive?
191
+ if @last_watch[:enable]
150
192
  stop
151
- sleep 1
152
- start
193
+ sleep 0.5
194
+ my_logger msg: "Watchdog Thread: Send Last_Watch: #{@last_watch}"
195
+ @command = @last_watch
196
+ send_cmmd
197
+ my_logger msg: "Watchdog Thread: Thread.exit"
198
+ Thread.exit
199
+ else
200
+ close_socket
153
201
  end
154
- sleep 1
155
202
  end
156
- end
203
+ sleep WATCHDOG_STEP
204
+ end # while
205
+ my_logger msg: "Closing Watchdog Thread"
206
+ end # watchdog thread
207
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
157
208
 
158
- end
209
+ my_logger msg: "Start: Exiting Start"
210
+ end # def start
159
211
 
160
- # @return [string] status info string containing nr satellites, fix, speed
161
- def to_status
162
- return "lat: #{last['lat']}, lng: #{last['lon']}, speed:#{last['speed']}, sats: #{@sats.length}(#{@sats.count{|sat| sat['used']}})" if @socket_ready and @last and @sats
163
- return "lat: #{last['lat']}, lng: #{last['lon']}, speed:#{last['speed']}" if @socket_ready and @last and @sats.nil?
164
- return "sats: #{@sats.length}(#{@sats.count{|sat| sat['used']}}), no fix yet" if @socket_ready and @last.nil? and @sats
165
- return "connected with gpsd, waiting for data" if @socket_ready
166
- return "waiting for connection with gpsd" if @socket_ready == false
167
- end
212
+ # initialize gpsd socket
213
+ def init_socket
214
+ my_logger msg: "Entered Init_socket"
215
+ begin
216
+ close_socket if @socket && !@socket.closed?
168
217
 
169
- # Stop the listening loop and close the socket. It will read the last bit of data from the socket, close it, and clean it up
170
- def stop
171
- # last read(s)
172
- 3.times { read_from_socket }
173
- # then close
174
- close_socket
175
- # then cleanup
218
+ # Send the 'Hello' message (Content apparently irrelevant)
219
+ @socket = TCPSocket.new(@host, @port)
220
+ msg="This space for rent"
221
+ my_logger level: 'info', msg: "Init_socket: Sending Cmmd: \"#{msg}\""
222
+ @socket.puts(msg)
223
+ @sent_raw_callback.call( msg) if @sent_raw_callback
224
+
225
+ my_logger msg: "Init_socket: reading socket..."
226
+ welcome = ::JSON.parse @socket.gets.chomp
227
+ @json_raw_callback.call(welcome) if @json_raw_callback
228
+ my_logger level: 'info', msg: "Init_socket: Received welcome: #{welcome.inspect}"
229
+ @socket_ready = (welcome and welcome['class'] and welcome['class'] == 'VERSION')
230
+ @msg_counts[:ver] += 1 if @socket_ready
231
+ my_logger level: 'info',msg: "Init_socket: @socket_ready: #{@socket_ready.inspect}"
232
+ rescue
176
233
  @socket_ready = false
177
- Thread.kill(@socket_init_thread) if @socket_init_thread
178
- Thread.kill(@trackthread) if @trackthread
234
+ my_logger level: 'error', msg: "Init_socket: Rescue: #$!"
179
235
  end
236
+ my_logger msg: "Init_socket: Exiting init_socket"
237
+ end
180
238
 
181
- # initialize gpsd socket
182
- def init_socket
239
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
240
+ #~~~~~~~~~~~~~~~~~~~~~ PROCESS RUN THREAD ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
241
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
242
+
243
+
244
+ # Read from socket. this should happen in a Thread as a continues loop. It should try to read data from the socket but nothing might happen if the gps deamon might not be ready. If ready it will send packets that we read and proces
245
+ def read_from_socket
246
+ my_logger msg: "Entered Read_from_socket"
247
+ if @socket_ready
248
+ my_logger msg: "Read_from_socket: Socket_ready"
183
249
  begin
184
- puts "init_socket" if @verbose
185
- close_socket if @socket
186
- @socket = TCPSocket.new(@host, @port)
187
- #msg="w+"
188
- msg="This space for rent"
189
- @sent_raw_callback.call( msg) if @sent_raw_callback
190
- @socket.puts(msg) #contents seem to be irrelevant here
191
-
192
- puts "reading socket..." if @verbose
193
- welcome = ::JSON.parse @socket.gets.chomp
194
- @json_raw_callback.call(welcome) if @json_raw_callback
195
- puts "welcome: #{welcome.inspect}" if @verbose
196
- @socket_ready = (welcome and welcome['class'] and welcome['class'] == 'VERSION')
197
- @msg_counts[:ver] += 1 if @socket_ready
198
- puts "@socket_ready: #{@socket_ready.inspect}" if @verbose
250
+ if input = @socket.gets.chomp and not input.to_s.empty?
251
+ parse_socket_json(json: JSON.parse(input))
252
+ @watchdog_count = 0
253
+ my_logger level: 'info', msg: "Read_from_socket: Read: #{input}"
254
+ else
255
+ sleep 0.1
256
+ end
199
257
  rescue
200
- @socket_ready = false
201
- puts "#$!" if @verbose
258
+ my_logger level: 'error', msg: "Read_from_socket: error reading from socket: #{$!}"
259
+ @socket_ready = !@socket.closed? if @socket
202
260
  end
261
+ else
262
+ my_logger level: 'warn', msg: "Read_from_socket: socket not ready"
263
+ sleep 0.1
264
+ end
265
+ my_logger msg: "Read_from_socket: Exiting"
203
266
  end
204
267
 
205
- # Read from socket. this should happen in a Thread as a continues loop. It should try to read data from the socket but nothing might happen if the gps deamon might not be ready. If ready it will send packets that we read and proces
206
- def read_from_socket
207
- if @socket_ready
208
- begin
209
- if input = @socket.gets.chomp and not input.to_s.empty?
210
- parse_socket_json(json: JSON.parse(input))
211
- @watchdog_count = 0
212
- else
213
- sleep 0.1
214
- end
215
- rescue
216
- puts "error reading from socket: #{$!}" if @verbose
217
- end
218
- else
219
- sleep 0.1
268
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
269
+ #~~~~~~~~~~~~~~~~~~~~~~~~ PROCESS SHUTDOWN ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
270
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
271
+
272
+ # Stop the listening loop and close the socket. It will read the last bit of data from the socket, close it, and clean it up
273
+ def stop
274
+ my_logger level: 'info', msg: "Entered Stop"
275
+ # last read(s)
276
+ 3.times { |c| my_logger( msg: "Read loop #{c+1}"); read_from_socket }
277
+ # then close
278
+ close_socket
279
+ my_logger level: 'info', msg: "Exiting Stop"
280
+ end
281
+
282
+ # Close the gps deamon socket
283
+ def close_socket
284
+ mutex = Mutex.new
285
+ mutex.synchronize do
286
+ my_logger msg: "Entered CloseSocket"
287
+ begin
288
+ Thread.kill(@socket_init_thread) if @socket_init_thread && @socket_init_thread.alive?
289
+ Thread.kill(@readthread) if @readthread && @readthread.alive?
290
+ @socket_ready = false
291
+ @socket.close if @socket && !@socket.closed?
292
+ @socket = nil
293
+ Thread.kill(@watchdogthread) if @watchdog_thread && @watchdog_thread.alive? && Thread.current[:name] != THREAD_NAMES[:WatchdogThread]
294
+ my_logger level: 'info', msg: "CloseSocket: Socket Closed & Threads Killed"
295
+ rescue
296
+ my_logger level: 'error', msg: "CloseSocket Rescue: #$!"
220
297
  end
298
+ my_logger msg: "Exiting CloseSocket"
299
+ end
221
300
  end
222
301
 
302
+
303
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
304
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
305
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
306
+
223
307
  # Proceses json object returned by gpsd daemon. The TPV and SKY object
224
308
  # are used the most as they give info about satellites used and gps locations
225
309
  # @param [JSON] json The object returned by the daemon
@@ -255,7 +339,7 @@ class MyGpsdClient
255
339
  #we have a 2d or 3d fix
256
340
  if is_new_measurement(json: json)
257
341
  json['time'] = DateTime.parse(json['time'])
258
- puts "lat: #{json['lat']}, lng: #{json['lon']}, alt: #{json['alt']}, speed: #{json['speed']} at #{json['time']}, which is #{(Time.now - json['time'].to_time) * 1000}ms old" if @verbose
342
+ my_logger level: 'info', msg: "lat: #{json['lat']}, lng: #{json['lon']}, alt: #{json['alt']}, speed: #{json['speed']} at #{json['time']}, which is #{(Time.now - json['time'].to_time) * 1000}ms old"
259
343
  @json_pos_callback.call(json) if @json_pos_callback
260
344
  end
261
345
  end
@@ -264,16 +348,16 @@ class MyGpsdClient
264
348
  @msg_counts[:sky] += 1
265
349
  sats = json['satellites']
266
350
  if satellites_changed(sats: sats)
267
- puts "found #{sats.length} satellites, of which #{sats.count{|sat| sat['used']}} are used" if @verbose
351
+ my_logger level: 'info', msg: "found #{sats.length} satellites, of which #{sats.count{|sat| sat['used']}} are used"
268
352
  @json_sat_callback.call(sats) if @json_sat_callback
269
353
  end
270
354
  when 'PPS'
271
355
  @msg_counts[:pps] += 1
272
- puts "found PPS tag: #{json.inspect}" if @verbose
356
+ my_logger level: 'info', msg: "found PPS tag: #{json.inspect}"
273
357
  @json_pps_callback.call(json) if @json_pps_callback
274
358
  else
275
359
  @msg_counts[:unk] += 1
276
- puts "found unknown tag: #{json.inspect}" if @verbose
360
+ my_logger level: 'info', msg: "found unknown tag: #{json.inspect}"
277
361
  @json_unk_callback.call(json) if @json_unk_callback
278
362
  end
279
363
  @json_raw_callback.call(json) if @json_raw_callback
@@ -299,19 +383,73 @@ class MyGpsdClient
299
383
  return false
300
384
  end
301
385
 
302
- # Close the gps deamon socket
303
- def close_socket
304
- begin
305
- if @socket
306
- msg = '?WATCH={"enable":false}'
307
- @sent_raw_callback.call( msg) if @sent_raw_callback
308
- @socket.puts msg
309
- @socket.close
310
- end
311
- @socket = nil
312
- rescue
313
- puts "#$!" if @verbose
314
- end
386
+ # @return [string] status info string containing nr satellites, fix, speed
387
+ def to_status
388
+ return "lat: #{last['lat']}, lng: #{last['lon']}, speed:#{last['speed']}, sats: #{@sats.length}(#{@sats.count{|sat| sat['used']}})" if @socket_ready and @last and @sats
389
+ return "lat: #{last['lat']}, lng: #{last['lon']}, speed:#{last['speed']}" if @socket_ready and @last and @sats.nil?
390
+ return "sats: #{@sats.length}(#{@sats.count{|sat| sat['used']}}), no fix yet" if @socket_ready and @last.nil? and @sats
391
+ return "connected with gpsd, waiting for data" if @socket_ready
392
+ return "waiting for connection with gpsd" if @socket_ready == false
393
+ end
394
+
395
+ def on_raw_send(options:{}, &block)
396
+ @sent_raw_callback = block
397
+ end
398
+
399
+ # @param [Object] options Possible options to pass (not used yet)
400
+ # @param [Block] block Block to call when new json object comes from gpsd
401
+ def on_raw_change(options:{}, &block)
402
+ @json_raw_callback = block
403
+ end
404
+
405
+ # @param [Object] options Possible options to pass (not used yet)
406
+ # @param [Block] block Block to call when new gps position json object comes from gpsd
407
+ def on_position_change(options:{}, &block)
408
+ @json_pos_callback = block
409
+ end
410
+
411
+ # @param [Object] options Possible options to pass (not used yet)
412
+ # @param [Block] block Block to call when new satellite info json object comes from gpsd
413
+ def on_satellites_change(options:{}, &block)
414
+ @json_sat_callback = block
415
+ end
416
+
417
+ # @param [Object] options Possible options to pass (not used yet)
418
+ # @param [Block] block Block to call when new pps info json object comes from gpsd
419
+ def on_pps_change(options:{}, &block)
420
+ @json_pps_callback = block
421
+ end
422
+
423
+ # @param [Object] options Possible options to pass (not used yet)
424
+ # @param [Block] block Block to call when new pps info json object comes from gpsd
425
+ def on_unk_change(options:{}, &block)
426
+ @json_unk_callback = block
427
+ end
428
+
429
+ def reset_msg_counts
430
+ @msg_counts.each_key { |k| @msg_counts[k] = 0 }
431
+ end
432
+
433
+ def self.version
434
+ MyGpsdClient_version::VERSION
435
+ end
436
+
437
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
438
+ #~~~~~~~~~~~~~~~~~~~~~ SETUP LOGGING ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
439
+ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
440
+ LOG_LEVELS = {debug: Logger::DEBUG, info: Logger::INFO, warn: Logger::WARN,
441
+ error: Logger::ERROR, fatal: Logger::FATAL, unknown: Logger::UNKNOWN}
442
+
443
+ def my_logger(level: 'debug', msg: "Blank")
444
+ MyGpsdClient.logger.add (LOG_LEVELS[level.to_sym]) {"#{Thread.current[:name]} -- #{msg}"}
445
+ end
446
+
447
+ def self.logger
448
+ @@logger ||= defined?(Rails) ? Rails.logger : Logger.new("log/MyGpsdClient.log")
449
+ end
450
+
451
+ def self.logger=(logger)
452
+ @@logger = logger
315
453
  end
316
454
 
317
455
 
@@ -1,3 +1,3 @@
1
1
  class MyGpsdClient_version
2
- VERSION = "0.1.30"
2
+ VERSION = "0.02.00"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: my_gpsd_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.30
4
+ version: 0.02.00
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Finnegan
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-10-11 00:00:00.000000000 Z
11
+ date: 2019-10-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler