Background: I am trying to write a simple piece of code which interfaces with gpsd to return the number of GPS satellites visible and the number which gpsd is actually using. This is at the limits of my capabilities, but I have got as far as getting a string in Python which has the information embedded.
For each satellite, there is a string pair (excuse my terminology - I don't know Python) which is either u'used': False or u'used' True. I would like the program to return two values: the total number of satellites visible (the number of u'used' strings) and the total number used (the number of u'used': True strings). Is there a nice easy way to do this?
(Were this FreePascal/Lazarus I guess it would be easy, or if I knew more JSON!).
Great - and it seems it's a JSON encoded string so rather than doing any string processing on it why not decode it using the json module (loads method) which will turn it into a list of dicts which you can loop through something roughly like this.
import json
sats = json.loads(gps_str) total_sats = len(sats) used_sats = 0 for sat in sats: if sat['used']: used_sats = used_sats + 1
--
Steve O'Hara-Smith | Directable Mirror Arrays
C:>WIN | A better way to focus the sun
The computer obeys and wins. | licences available see
You lose and Bill collects. | http://www.sohara.org/
Thanks, Stefan. I had searched, and tried a function such as you suggest, but unfortunately it returned 0 when searching for either "used" or "True". There were no compiler errors, but I don't know Python well enough to know where I'm going wrong.
On 10/04/2016 11:15, Ahem A Rivet's Shot wrote: []
Thanks, Ahem, I appreciate your help. I did try that but it seems not to work for my data at least. Here's the error message and the program:
Traceback (most recent call last): File "gpsdRead.py", line 22, in sats = json.loads (report.satellites) File "/usr/lib/python2.7/json/__init__.py", line 338, in loads return _default_decoder.decode(s) File "/usr/lib/python2.7/json/decoder.py", line 366, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) TypeError: expected string or buffer ===========================
import gps import json from collections import Counter
# Listen on port 2947 (gpsd) of localhost session = gps.gps("localhost", "2947") session.stream(gps.WATCH_ENABLE | gps.WATCH_NEWSTYLE)
while True: try: report = session.next() # Wait for a 'SKY' report and display the current time # To see all report data, uncomment the line below # print report if report['class'] == 'SKY': # print report session = None if hasattr(report, 'satellites'): # print report.satellites # print report.satellites.count("used") # print report.satellites.count("True") sats = json.loads (report.satellites) total_sats = len (sats) used_sats = 0 for sat in sats: if sat['used']: used_sats = used_sats + 1 print total_sats print used_sats session = None quit() except KeyError: pass except KeyboardInterrupt: quit() except StopIteration: session = None print "GPSD has terminated"
On Sun, 10 Apr 2016 15:17:37 +0100, David Taylor declaimed the following:
From your earlier post:
How did you produce that "report". I'm not up on JSON myself, but those structures don't seem valid. With them in place I get
ValueError: No JSON object could be decoded
Removing them got me to
ValueError: Expecting property name: line 2 column 3 (char 3)
After much trial and error I managed to get
report = """ [ {"ss": 24, "el": 10, "PRN": 67, "az": 130, "used":"False"}, {"ss": 30, "el": 63, "PRN": 68, "az": 130, "used":"False"}, {"ss": 14, "el": 59, "PRN": 69, "az": 309, "used":"False"}, {"ss": 12, "el": 73, "PRN": 78, "az": 118, "used": "False"}, {"ss": 26, "el": 39, "PRN": 79, "az": 190, "used":"False"}, {"ss": 17, "el": 18, "PRN": 85, "az": 315, "used":"False"}, {"ss": 31, "el": 26, "PRN": 136, "az": 170, "used":"True"}, {"ss": 30, "el": 23, "PRN": 28, "az": 137, "used": "True"}, {"ss": 38, "el": 66, "PRN": 30, "az": 92, "used":"True"}, {"ss": 31, "el": 40, "PRN": 20, "az": 297, "used":"True"}, {"ss": 27, "el": 15, "PRN": 21, "az": 327, "used":"True"}, {"ss": 11, "el": 8, "PRN": 27, "az": 23, "used":"False"}, {"ss": 32, "el": 66, "PRN": 5, "az": 212, "used": "True"}, {"ss": 27, "el": 40, "PRN": 7, "az": 61, "used": "True"}, {"ss": 17, "el": 4, "PRN": 9, "az": 96, "used":"False"}, {"ss": 38, "el": 54, "PRN": 13, "az": 269, "used":"True"} ] """ to feed to the loader. The order has changed as I was cut&pasting from one record up to the full set. Note that I had to:
1) remove the
2) remove the u' leaving just the ' (actually, I also ended up changing all ' to ")
3) True and False had to be quoted; without the quotes I got errors.
How you massage your input data to fit is another matter...
There are newsgroups for python too, which should be used in preference unless your problem is specific to the Raspberry Pi, which in this case it isn't.
You're right, of course, about the newsgroups, although in this case the issues /may/ be RPi-specific since it has not got the up-to-date versions of gpsd. I'm more tending towards writing my own program in Pascal (Lazarus) as the delay in getting the required message (SKY) is annoying me!
Ah I see it's already structured and what you posted was the result of python turning it into a string to print it - then I was trying to get you to turn it back into what you started with :)
Life is simpler for you. Ignore this bit:
In here use report.satellites where I have sats.
Or you can use the more compact way of counting suggested by Dennis - I wouldn't because it allocates an array that isn't used for anything but counting it's length.
One more thing this:
Would be nicer as:
if 'satellites' in report:
--
Steve O'Hara-Smith | Directable Mirror Arrays
C:>WIN | A better way to focus the sun
The computer obeys and wins. | licences available see
You lose and Bill collects. | http://www.sohara.org/
Thanks for everyone's help with this. Whilst I did get a working solution with Python, I found a much quick way was to write a small piece of C. For those interested, please see:
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here.
All logos and trade names are the property of their respective owners.