Skip to content

Commit 3b7c3f6

Browse files
authored
Merge pull request #170 from semuconsulting/RC-1.5.1
RC 1.5.1
2 parents 620c430 + 0fd7f2a commit 3b7c3f6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1784
-613
lines changed

.vscode/settings.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44
"editor.formatOnSave": true,
55
"modulename": "pygpsclient",
66
"distname": "pygpsclient",
7-
"moduleversion": "1.5.0",
7+
"moduleversion": "1.5.1",
88
"python.defaultInterpreterPath": "python3",
99
}

README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ You will need to logout and login for the launcher to take effect.
259259
| User-selectable 'widgets' | To show or hide the various widgets, go to Menu..View and click on the relevant hide/show option. |
260260
|---------------------------|---------------------------------------------------------------------------------------------------|
261261
|![banner widget](https://github.com/semuconsulting/PyGPSClient/blob/master/images/banner_widget.png?raw=true)| Expandable banner showing key navigation status information based on messages received from receiver. To expand or collapse the banner or serial port configuration widgets, click the ![expand icon](https://github.com/semuconsulting/PyGPSClient/blob/master/src/pygpsclient/resources/iconmonstr-arrow-80-16.png?raw=true)/![expand icon](https://github.com/semuconsulting/PyGPSClient/blob/master/src/pygpsclient/resources/iconmonstr-triangle-1-16.png?raw=true) buttons. **NB**: some fields (e.g. hdop/vdop, hacc/vacc) are only available from proprietary NMEA or UBX messages and may not be output by default. The minimum messages required to populate all available fields are: NMEA: GGA, GSA, GSV, RMC, UBX00 (proprietary); UBX: NAV-DOP, NAV-PVT, NAV_SAT |
262-
|![console widget](https://github.com/semuconsulting/PyGPSClient/blob/master/images/console_widget.png?raw=true)| Configurable serial console widget showing all incoming data streams (both GNSS and RTK) in either parsed, binary or tabular hexadecimal formats. Double-click to copy contents of console to clipboard. The scroll behaviour and number of lines retained in the console can be configured via the settings panel. Supports user-configurable color tagging of selected strings for easy identification. Color tags are loaded from the `"colortag_b":` value (`0` = disable, `1` = enable) and `"colortags_l":` list (`[string, color]` pairs) in your json configuration file (see example provided). If color is set to "HALT", streaming will halt on any match and a warning displayed. NB: color tagging does impose a small performance overhead - turning it off will improve console response times at very high transaction rates.|
262+
|![console widget](https://github.com/semuconsulting/PyGPSClient/blob/master/images/console_widget.png?raw=true)| Configurable serial console widget showing all incoming data streams (both GNSS and RTK) in either parsed, binary or tabular hexadecimal formats. Double-right-click to copy contents of console to clipboard. The scroll behaviour and number of lines retained in the console can be configured via the settings panel. Supports user-configurable color tagging of selected strings for easy identification. Color tags are loaded from the `"colortag_b":` value (`0` = disable, `1` = enable) and `"colortags_l":` list (`[string, color]` pairs) in your json configuration file (see example provided). If color is set to "HALT", streaming will halt on any match and a warning displayed. NB: color tagging does impose a small performance overhead - turning it off will improve console response times at very high transaction rates.|
263263
|![skyview widget](https://github.com/semuconsulting/PyGPSClient/blob/master/images/skyview_widget.png?raw=true)| Skyview widget showing current satellite visibility and position (elevation / azimuth). Satellite icon borders are colour-coded to distinguish between different GNSS constellations. For consistency between NMEA and UBX data sources, will display GLONASS NMEA SVID (65-96) rather than slot (1-24). |
264264
|![graphview widget](https://github.com/semuconsulting/PyGPSClient/blob/master/images/graphview_widget.png?raw=true)| Graphview widget showing current satellite reception (carrier-to-noise ratio or cnr). Double-click to toggle legend. |
265265
|![static map](https://github.com/semuconsulting/PyGPSClient/blob/master/images/staticmap.png?raw=true)| Map widget with various modes of display. Map Type = 'world': a static offline Mercator world map showing current global location.
@@ -268,8 +268,9 @@ You will need to logout and login for the launcher to take effect.
268268
|![import custom map](https://github.com/semuconsulting/PyGPSClient/blob/master/images/importcustommap.png?raw=true)| <a name="custommap">Import Custom Map dialog</a>. Click ![load icon](https://github.com/semuconsulting/PyGPSClient/blob/master/src/pygpsclient/resources/iconmonstr-folder-18-24.png?raw=true) to open the custom map image location (*the default file suffix is `*.tif` - select Show Options to select any file suffix `*.*`*). If the `rasterio` library is installed and the image is georeferenced (e.g. using [QGIS](https://qgis.org/)), the map extent will be automatically extracted - otherwise it must be entered manually. Import the custom map path anad extent settings by clicking ![play icon](https://github.com/semuconsulting/PyGPSClient/blob/master/src/pygpsclient/resources/iconmonstr-arrow-12-24.png?raw=true). See [Creating Custom Maps for PyGPSClient](https://www.semuconsulting.com/gnsswiki/custommapwiki/) for tips on how to create a suitable georeferenced map image.|
269269
|![spectrum widget](https://github.com/semuconsulting/PyGPSClient/blob/master/images/spectrum_widget.png?raw=true)| Spectrum widget showing a spectrum analysis chart (*GNSS receiver must be capable of outputting UBX MON-SPAN messages*). Clicking anywhere in the spectrum chart will display the frequency and decibel reading at that point. Double-clicking anywhere in the chart will toggle the GNSS frequency band markers (L1, G2, etc.) on or off. Right-click anywhere in the chart to capture a snapshot of the spectrum data, which will then be superimposed on the live data. Double-right-click to clear snapshot. **NB:** Some receivers (e.g. NEO-F10N) will not output the requisite MON-SPAN messages unless the port baud rate is at least 57,600. |
270270
|![sysmon widget](https://github.com/semuconsulting/PyGPSClient/blob/master/images/sysmon_widget.png?raw=true)| System Monitor widget showing device cpu, memory and I/O utilisation (*GNSS receiver must be capable of outputting UBX MON-SYS and/or MON-COMMS messages*). Tick checkbox to toggle between actual (cumulative) I/O stats and pending I/O. |
271-
|![scatterplot widget](https://github.com/semuconsulting/PyGPSClient/blob/master/images/scatterplot_widget.png?raw=true)| Scatterplot widget showing variability in position reporting over time. (Optional) Enter fixed reference position. Select Average to center plot on dynamic average position (*displayed at top left*), or Fixed to center on fixed reference position (*if entered*). Check Autorange to set plot range automatically. Set the update interval (e.g. 4 = every 4th navigation solution). Use the range slider or mouse wheel to adjust plot range. Right-click to set fixed reference point to the current mouse cursor position. Double-click clear existing plot. The default center mode, autorange, update increment, scale index and fixed reference position settings can be stored in the json configuration file as `scattercenter_s`/`scatterautorange_b`/`scatterinterval_n`/`scatterscale_n`/`scatterlat_f`/`scatterlon_f`. |
271+
|![scatterplot widget](https://github.com/semuconsulting/PyGPSClient/blob/master/images/scatterplot_widget.png?raw=true)| Scatterplot widget showing variability in position reporting over time. (Optional) Enter fixed reference position. Select Average to center plot on dynamic average position (*displayed at top left*), or Fixed to center on fixed reference position (*if entered*). Check Autorange to set plot range automatically. Set the update interval (e.g. 4 = every 4th navigation solution). Use the range slider or mouse wheel to adjust plot range. Right-click to set fixed reference point to the current mouse cursor position. Double-click to clear the existing data. Settings may be saved to a json configuration file. |
272272
|![rover widget](https://github.com/semuconsulting/PyGPSClient/blob/master/images/rover_widget.png?raw=true) | Rover widget plots the relative 2D position, track and status information for the roving receiver in a fixed or moving base / rover RTK configuration. Can also display relative position of NTRIP mountpoint and receiver in a static RTK configuration. Double-click to clear existing plot. (*GNSS rover receiver must be capable of outputting UBX NAV-RELPOSNED messages.*) |
273+
|![chart view](/images/chart_widget.png?raw=true) | Chart widget acts as a multi-channel "oscilloscope", allowing the user to plot a series of named numeric data attributes from any NMEA, UBX, RTCM or SPARTN data source, with configurable y (value) and x (time) axes. By default, the number of channels is set to 4, but this can be manually edited by the user via the json configuration file setting `chartsettings_d["numchn_n"]`. For each channel, user can select: (*optional*) identity of message source e.g. `NAV-PVT`; attribute name e.g. `hAcc`; scaling factor (divisor) e.g. 1000; y axis range e.g. 0 - 5. Wildcards are available for attribute groups - "\*" (average of group values), "+" (maximum of group values), "-" (minimum of group values) e.g. `cno*` will plot the average `cno` value for a group of satellites. Double-click to clear the existing data. Double-right-click to save the current chart data to the clipboard in CSV format. Settings may be saved to a json configuration file. |
273274
---
274275
## <a name="ubxconfig">UBX Configuration Facilities</a>
275276

RELEASE_NOTES.md

+15
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
# PyGPSClient Release Notes
22

3+
### RELEASE 1.5.1
4+
5+
1. Add new user-selectable and configurable "Chart" widget:
6+
- The Chart widget broadly emulates a multi-channel "oscilloscope", allowing the user to plot designated numeric data attribute values over time. By default, the number of channels is set to 4, but this can be manually edited by the user via the json configuration file setting `chartsettings_d["numchn_n"]`.
7+
- Any numeric attribute from any incoming NMEA, UBX, RTCM or SPARTN message can be plotted.
8+
- For each channel, user must specify the parsed data attribute name e.g. "hAcc" or "numSV".
9+
- User can optionally specify a message identity e.g. "GNGGA" or "NAV-PVT", in which case only the attribute from that message identity will be plotted.
10+
- Nested group attributes must include the full group index e.g. "cno_04". Alternatively, one of three wildcard characters '*', '+' or '-' can be appended, representing the average, minimum or maximum of the nested group values e.g. "cno\*" = (cno_01 + cno_02 + ... + cno_0n) / n ; "cno+" = max(cno_01, cno_02, ..., cno_0n).
11+
- X (time) and Y (value) axes are fully configurable.
12+
- Double-right-click will save the current chart data to the clipboard in CSV format.
13+
- The maximum number of datapoints per channel is configurable, though **NB** the practical maximum will be dependent on available platform memory and performance. 100,000 datapoints per channel is roughly equivalent to 3 MB in-memory data.
14+
- Chart settings will be saved to the json configuration file when "Save Configuration" is invoked.
15+
- Principally intended to provide a real-time view of incoming data trends over relatively short periods (minutes or hours). *Analyses of much long time-series data (days or weeks) can probably be done more efficiently by saving a binary log of the incoming data and processing the data offline through a standard Python graphing tool like `matplotlib`*.
16+
1. Add Check (for updates) on startup option to About dialog (NB: check requires internet connectivity)
17+
318
### RELEASE 1.5.0
419

520
FIXES:

docs/pygpsclient.rst

+16
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,22 @@ pygpsclient.banner\_frame module
2828
:undoc-members:
2929
:show-inheritance:
3030

31+
pygpsclient.chart\_frame module
32+
-------------------------------
33+
34+
.. automodule:: pygpsclient.chart_frame
35+
:members:
36+
:undoc-members:
37+
:show-inheritance:
38+
39+
pygpsclient.confirm\_box module
40+
-------------------------------
41+
42+
.. automodule:: pygpsclient.confirm_box
43+
:members:
44+
:undoc-members:
45+
:show-inheritance:
46+
3147
pygpsclient.console\_frame module
3248
---------------------------------
3349

images/chart_widget.png

186 KB
Loading

images/good_sats.png

-138 KB
Binary file not shown.

images/high_precision.png

-38 KB
Binary file not shown.

images/low_precision.png

-36.9 KB
Binary file not shown.

images/poor_sats.png

-116 KB
Binary file not shown.

pygpsclient.json

+43-6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"Spectrum": false,
1010
"System Monitor": false,
1111
"Scatter Plot": false,
12+
"checkforupdate_b": 0,
1213
"mapupdateinterval_n": 60,
1314
"defaultport_s": "USB",
1415
"mqapikey_s": "<======= YOUR MQ API KEY ======>",
@@ -110,12 +111,48 @@
110111
"spartndecode_b": 0,
111112
"spartnkey_s": "abcd1234abcd1234abcd1234abcd1234",
112113
"spartnbasedate_n": -1,
113-
"scatterautorange_b": 0,
114-
"scattercenter_s": "Average",
115-
"scatterinterval_n": 1,
116-
"scatterscale_n": 6,
117-
"scatterlat_f": 37.23345133,
118-
"scatterlon_f": -115.81513477,
114+
"scattersettings_d": {
115+
"maxpoints_n": 2000,
116+
"scatterautorange_b": 1,
117+
"scattercenter_s": "Average",
118+
"scatterinterval_n": 1,
119+
"scatterscale_n": 12,
120+
"scatterlat_f": 37.23345,
121+
"scatterlon_f": -115.81513
122+
},
123+
"chartsettings_d": {
124+
"numchn_n": 4,
125+
"timrng_n": "240",
126+
"maxpoints_n": "2000",
127+
"0": {
128+
"id_s": "NAV-PVT",
129+
"name_s": "hAcc",
130+
"scale_f": "100",
131+
"miny_f": "0",
132+
"maxy_f": "1"
133+
},
134+
"1": {
135+
"id_s": "NAV-PVT",
136+
"name_s": "pDOP",
137+
"scale_f": "1",
138+
"miny_f": "0",
139+
"maxy_f": "10"
140+
},
141+
"2": {
142+
"id_s": "NAV-PVT",
143+
"name_s": "numSV",
144+
"scale_f": "1",
145+
"miny_f": "0",
146+
"maxy_f": "50"
147+
},
148+
"3": {
149+
"id_s": "NAV-PVT",
150+
"name_s": "carrSoln",
151+
"scale_f": "1",
152+
"miny_f": "0",
153+
"maxy_f": "5"
154+
}
155+
},
119156
"ubxpresets_l": [
120157
"Force HOT Reset (!!! Will require reconnection !!!), CFG, CFG-RST, 00000000, 1",
121158
"Force WARM Reset (!!! Will require reconnection !!!), CFG, CFG-RST, 00010000, 1",

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ name = "pygpsclient"
77
authors = [{ name = "semuadmin", email = "[email protected]" }]
88
maintainers = [{ name = "semuadmin", email = "[email protected]" }]
99
description = "GNSS Diagnostic and UBX Configuration GUI Application"
10-
version = "1.5.0"
10+
version = "1.5.1"
1111
license = { file = "LICENSE" }
1212
keywords = [
1313
"PyGPSClient",

src/pygpsclient/_version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@
88
:license: BSD 3-Clause
99
"""
1010

11-
__version__ = "1.5.0"
11+
__version__ = "1.5.1"

src/pygpsclient/about_dialog.py

+21-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from platform import python_version
1414
from subprocess import CalledProcessError, run
1515
from sys import platform
16-
from tkinter import Button, E, Frame, Label, Tcl, Toplevel, W
16+
from tkinter import Button, Checkbutton, E, Frame, IntVar, Label, Tcl, Toplevel, W
1717
from webbrowser import open_new_tab
1818

1919
from PIL import Image, ImageTk
@@ -69,6 +69,9 @@ def __init__(self, app, **kwargs):
6969
self._img_github = ImageTk.PhotoImage(Image.open(ICON_GITHUB).resize((32, 32)))
7070
self._img_exit = ImageTk.PhotoImage(Image.open(ICON_EXIT))
7171
self._img_sponsor = ImageTk.PhotoImage(Image.open(ICON_SPONSOR))
72+
self._checkonstartup = IntVar()
73+
cfu = self.__app.saved_config.get("checkforupdate_b", False)
74+
self._checkonstartup.set(cfu)
7275
self._updates = []
7376

7477
self._body()
@@ -112,6 +115,11 @@ def _body(self):
112115
font=self.__app.font_sm,
113116
cursor="hand2",
114117
)
118+
self._chk_checkupdate = Checkbutton(
119+
self._frm_container,
120+
text="Check on startup",
121+
variable=self._checkonstartup,
122+
)
115123
self._lbl_giticon = Label(
116124
self._frm_container,
117125
image=self._img_github,
@@ -159,7 +167,10 @@ def _do_layout(self):
159167
column=0, row=4 + i, columnspan=2, padx=2, pady=2
160168
)
161169
self._btn_checkupdate.grid(
162-
column=0, row=5 + i, ipadx=3, ipady=3, columnspan=2, padx=3, pady=3
170+
column=0, row=5 + i, ipadx=3, ipady=3, padx=3, pady=3
171+
)
172+
self._chk_checkupdate.grid(
173+
column=1, row=5 + i, ipadx=3, ipady=3, padx=3, pady=3
163174
)
164175
self._lbl_giticon.grid(column=0, row=6 + i, padx=(3, 1), pady=3, sticky=E)
165176
self._lbl_sponsoricon.grid(column=1, row=6 + i, padx=(3, 1), pady=3, sticky=W)
@@ -181,6 +192,7 @@ def _attach_events(self):
181192
self._lbl_copyright.bind("<Button>", self._on_license)
182193
self._btn_ok.bind("<Return>", self._ok_press)
183194
self._btn_ok.focus_set()
195+
self._checkonstartup.trace_add("write", self._on_save_settings)
184196

185197
def _on_github(self, *args, **kwargs): # pylint: disable=unused-argument
186198
"""
@@ -272,3 +284,10 @@ def _do_update(self, *args, **kwargs): # pylint: disable=unused-argument
272284

273285
self._btn_checkupdate.config(text="RESTART APP", fg="green")
274286
self._btn_checkupdate.bind("<Button>", self.__app.on_exit)
287+
288+
def _on_save_settings(self, var, index, mode): # pylint: disable=unused-argument
289+
"""
290+
Save current settings to saved app config dict.
291+
"""
292+
293+
self.__app.saved_config["checkforupdate_b"] = self._checkonstartup.get()

0 commit comments

Comments
 (0)