Skip to content

Commit 2a97635

Browse files
committed
update NMEA preset panel
1 parent a18e554 commit 2a97635

4 files changed

Lines changed: 52 additions & 26 deletions

File tree

README.md

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
[Mapquest API Key](#mapquestapi) |
1515
[User-defined Presets](#userdefined) |
1616
[CLI Utilities](#cli) |
17-
[Known Issues](#knownissues) |
17+
[Troubleshooting](#troubleshoot) |
1818
[License](#license) |
1919
[Author Information](#author)
2020

@@ -220,7 +220,7 @@ The UBX Configuration Dialog currently provides the following UBX configuration
220220
1. Message Rate panel (CFG-MSG) sets message rates per port for UBX and NMEA messages (*legacy protocols only*). Message rate is relative to navigation solution frequency e.g. a message rate of '4' means 'every 4th navigation solution' (higher = less frequent).
221221
1. Configuration Interface widget (CFG-VALSET, CFG-VALDEL and CFG-VALGET) queries and sets configuration for *modern protocols only*.
222222
1. UBX Legacy Command configuration panel providing structured updates for a range of legacy CFG-* configuration commands (*legacy protocols only*). Note: 'X' (byte) type attributes can be entered as integers or hexadecimal strings e.g. 522125312 or 0x1f1f0000. Once a command is selected, the configuration is polled and the current values displayed. The user can then amend these values as required and send the updated configuration. Some polls require input arguments (e.g. portID) - these are highlighted and will be set at default values initially (e.g. portID = 0), but can be amended by the user and re-polled using the ![refresh](https://github.com/semuconsulting/PyGPSClient/blob/master/src/pygpsclient/resources/iconmonstr-refresh-lined-24.png?raw=true) button.
223-
1. Preset Commands widget supports a variety of user-defined UBX commands and queries - see [user defined presets](#userdefined).
223+
1. Preset Commands widget supports a variety of user-defined UBX commands and queries - see [user-defined presets](#userdefined).
224224

225225
An icon to the right of each 'SEND'
226226
![send icon](https://github.com/semuconsulting/PyGPSClient/blob/master/src/pygpsclient/resources/iconmonstr-arrow-12-24.png?raw=true) button indicates the confirmation status of the configuration command;
@@ -238,16 +238,17 @@ warning ![warning icon](https://github.com/semuconsulting/PyGPSClient/blob/maste
238238
- Receiver capable of being configured via proprietary NMEA sentences, connected to the workstation via USB or UART port.
239239
- The facility includes support for a wide range of Quectel LG and LC series receivers via `PQTM*`, `PSTM*` and `PAIR*` sentences¹ ². Additional types may be supported in the underlying NMEA parser library [pynmeagps](https://github.com/semuconsulting/pynmeagps) in later releases (*contributions welcome*).
240240

241-
¹ Note that Quectel receivers implement a bewildering array of different configuration protocols (based on a mixture of proprietary `PQTM*`, `PSTM*` and `PAIR*` NMEA message types). Support depends on the *specific model variant and firmware version*, and several models (e.g. LG290 and LC29) exist in a wide range of variants. Refer to the GNSS Protocol Guide for your *specific* variant.
241+
¹ Note that Quectel receivers implement a bewildering array of different configuration protocols, based on a mixture of proprietary NMEA `PQTM*`, `PSTM*` and `PAIR*` message types. Implementation depends on the *specific model variant and firmware version*, and several models (e.g. LG290 and LC29) exist in a wide range of variants. Refer to the GNSS Protocol Guide for your *specific* variant for details on the available configuration commands.
242242

243-
² Note that several Quectel configuration commands require a Hot Restart (PQTMHOT) *or* Save (PQTMSAVEPAR or PAIR513) and Reset (PQTMSRR) before taking effect, including for example PQTMCFGCNST (Enable/Disable Constellations), PQTMCFGFIX (Configure Fix Rate), PQTMCFGSAT (Configure Satellite Masks), PQTMCFGSIGNAL (Configure Signal Masks), PAIR050 (Set Fix Rate) and PAIR864 (Set Baud Rate). Devices (e.g. some LC variants) that don't implement a software reset command may have to be physically disconnected and reconnected.
243+
² Note that several Quectel configuration commands require a Hot Restart (PQTMHOT) *or* Save (PQTMSAVEPAR or PAIR513) and Reset (PQTMSRR) before taking effect, including for example PQTMCFGCNST (Enable/Disable Constellations), PQTMCFGFIX (Configure Fix Rate), PQTMCFGSAT (Configure Satellite Masks), PQTMCFGSIGNAL (Configure Signal Masks), PAIR050 (Set Fix Rate) and PAIR864 (Set Baud Rate). Devices (e.g. some LC variants) that don't implement a software reset command may have to be physically disconnected and reconnected.
244244

245245
**Instructions:**
246246

247247
The NMEA Configuration Dialog currently provides the following NMEA configuration panels:
248248
1. Version panel shows current device hardware/firmware versions (*Double-left-click to refresh*).
249249
1. Dynamic configuration panel providing structured updates for supported receivers e.g. Quectel LGSERIES via PQTM* sentences, or LCSERIES via PAIR* sentences. Once a command is selected, the configuration is polled and the current values displayed. The user can then amend these values as required and send the updated configuration. Some polls require input arguments (e.g. portid or msgname) - these are highlighted and will be set at default values initially (e.g. portid = 1), but can be amended by the user and re-polled using the ![refresh](https://github.com/semuconsulting/PyGPSClient/blob/master/src/pygpsclient/resources/iconmonstr-refresh-lined-24.png?raw=true) button.
250250
1. Preset Commands widget supports a variety of user-defined NMEA commands and queries - see [user defined presets](#userdefined).
251+
1. Preset commands, once selected, can be edited or overwritten in the 'Commands' field before sending, but commands must observe the format `<talker>; <message id>; <payload as comma-separated string>; <msgmode>` (e.g. `P; QTMCFGUART; W,115200; 1` - see [user-defined presets](#userdefined)).
251252

252253
An icon to the right of each 'SEND'
253254
![send icon](https://github.com/semuconsulting/PyGPSClient/blob/master/src/pygpsclient/resources/iconmonstr-arrow-12-24.png?raw=true) button indicates the confirmation status of the configuration command;
@@ -442,17 +443,21 @@ that this is a User variable rather than a System/Global variable.
442443
---
443444
## <a name="userdefined">User Defined Presets</a>
444445

445-
The UBX, NMEA and TTY Configuration Dialogs include the facility to send user-defined configuration messages or message sequences to a compatible receiver. These can be set up by adding appropriate comma- or semicolon-delimited message descriptions and payload definitions to the `"ubxpresets_l"`, `"nmeapresets_l"` or `"ttypresets_l"` settings in your json configuration file (see [example provided](https://github.com/semuconsulting/PyGPSClient/blob/master/pygpsclient.json#L189)). The message definition comprises a free-format text description (*avoid embedded commas or semi-colons*) followed by one or more pyubx2 (UBX), pynmeagps (NMEA) or tty (ASCII) message constructors, e,g.
446+
The UBX, NMEA and TTY Configuration Dialogs include the facility to send user-defined configuration messages or message sequences to a compatible receiver. These can be set up as follows:
446447

447-
- UBX - `<description>, <message class>, <message id>, <payload as hexadecimal string>, <msgmode>`
448-
- NMEA - `<description>; <talker>; <message id>; <payload as comma-separated string>; <msgmode>`
449-
- TTY - `<description>; <tty command>`
448+
1. By manually adding appropriate comma- or semicolon-delimited message descriptions and payload definitions to the `"ubxpresets_l"`, `"nmeapresets_l"` or `"ttypresets_l"` sections of your json configuration file (see [example provided](https://github.com/semuconsulting/PyGPSClient/blob/master/pygpsclient.json#L189)). The message definition comprises a free-format text description (*avoid embedded commas or semi-colons*) followed by one or more pyubx2 (UBX), pynmeagps (NMEA) or tty (ASCII) message constructors, e.g.
449+
450+
- UBX - `<description>, [<message class>, <message id>, <payload as hexadecimal string>, <msgmode>, ...]`
451+
- NMEA - `<description>; [<talker>; <message id>; <payload as comma-separated string>; <msgmode>; ...]`
452+
- TTY - `<description>; [<tty command>; ...]`
453+
454+
2. By using the [Configuration Command Load/Save/Record](#recorder) facility to record commands as they are sent to the receiver, and automatically import these recorded commands into the relevant `"...presets_l"` section of the json configuration file.
450455

451456
If the command description contains the term `CONFIRM`, a pop-up confirmation box will appear before the command is actioned.
452457

453-
When PyGPSClient is first started, these settings are pre-populated with an initial set of preset commands, which can be saved to a \*.json configuration file and then manually removed, amended or supplemented in accordance with the user's preferences. To reinstate this initial set at a later date, insert the line `"INIT_PRESETS",` at the top of the relevant `"ubxpresets_l"`, `"nmeapresets_l"` or `"ttypresets_l"` configuration setting.
458+
When PyGPSClient is first started, the preset command sections are pre-populated in-memory with an initial set of preset commands, which can be saved to a json configuration file and then manually edited in accordance with the user's preferences. To reinstate this initial set at a later date, insert the line `"INIT_PRESETS"` at the top of the relevant `"ubxpresets_l"`, `"nmeapresets_l"` or `"ttypresets_l"` configuration section.
454459

455-
The `pygpsclient.ubx2preset()`, `pygpsclient.nmea2preset()` and `pygpsclient.tty2preset()` helper functions may be used to convert a `UBXMessage`, `NMEAMessage` or ASCII text object into a preset string suitable for copying and pasting into the `"ubxpresents_l":`, `"nmeapresets_l":` or `"ttypresets_l":` JSON configuration sections:
460+
The `pygpsclient.ubx2preset()`, `pygpsclient.nmea2preset()` and `pygpsclient.tty2preset()` helper functions may be used to convert a `UBXMessage`, `NMEAMessage` or ASCII text object into a string suitable for copying and pasting into the `"ubxpresets_l":`, `"nmeapresets_l":` or `"ttypresets_l":` configuration file sections:
456461

457462
```python
458463
from pygpsclient import ubx2preset, nmea2preset, tty2preset
@@ -476,8 +481,6 @@ IM19 System reset CONFIRM; AT+SYSTEM_RESET
476481

477482
Multiple commands can be concatenated on a single line. Illustrative examples are shown in the sample [pygpsclient.json](https://github.com/semuconsulting/PyGPSClient/blob/master/pygpsclient.json#L189) file.
478483

479-
The [Configuration Command Load/Save/Record facility](#configuration-command-loadsaverecord-facility) can also be used to import recorded configuration command sequences into the presets section of the json configuration file.
480-
481484
---
482485
## <a name="cli">Command Line Utilities</a>
483486

@@ -486,11 +489,11 @@ The `pygnssutils` and `pyubxutils` libraries which underpin many of the function
486489
For further details, refer to the `pygnssutils` homepage at [https://github.com/semuconsulting/pygnssutils](https://github.com/semuconsulting/pygnssutils) or `pyubxutils` homepage at [https://github.com/semuconsulting/pyubxutils](https://github.com/semuconsulting/pyubxutils).
487490

488491
---
489-
## <a name="knownissues">Known Issues</a>
492+
## <a name="troubleshoot">Troubleshooting</a>
490493

491494
1. If you encounter persistent `WARNING>>Error parsing data stream Serial stream terminated unexpectedly` messages in the console, this may be indicative of insufficient serial port bandwidth (baudrate or timeout) for the current output message cohort (*particularly if this includes Ephemera or Observation data*). Try increasing the baudrate in the first instance.
492495

493-
2. Most budget USB-UART adapters (e.g. FT232, CH345, CP2102, *including those embedded on development boards*) have a bandwidth limit of around 3MB/s (≈ 375000 baud) and may not work reliably above 230600 baud, even if the receiver supports higher baud rates. If you're using an adapter and notice significant message corruption (e.g. frequent `WARNING>>..invalid checksum` messages), try reducing the baud rate to a maximum 230600.
496+
2. Most [budget USB-UART adapters](https://www.amazon.co.uk/DSD-TECH-adapter-FT232RL-Compatible/dp/B07BBPX8B8?ref_=ast_sto_dp) (e.g. FT232, CH345, CP2102, *including those embedded on development boards*) have a bandwidth limit of around 3Mbps (≈ 375000 baud) and may not work reliably above 230600 baud, even if the receiver supports higher baud rates. If you're using an adapter and notice significant message corruption (e.g. frequent `WARNING>>..invalid checksum` messages), try reducing the baud rate to a maximum 230600.
494497

495498
3. Some Linux Wayland platforms appear to require Toplevel dialog windows to be non-transient (`transient_dialog_b: 0`) for the window 'maximise' icon to work properly.
496499

RELEASE_NOTES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
1. Add preset description entry field to Configuration Command Recorder import facility.
66
1. Make TTY Presets dialog fully resizeable.
7+
1. Update NMEA config panel to allow preset commands to be edited or entered manually before sending.
78
1. Update NMEA config panel to recognise correct PAIR responses for some Quectel set and poll commands (e.g. a PAIR864 Set baud rate command corresponds to a PAIR865 poll response).
89

910
### RELEASE 1.6.4

images/nmeaconfig_widget.png

54.7 KB
Loading

src/pygpsclient/nmea_preset_frame.py

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@
1818
VERTICAL,
1919
Button,
2020
E,
21+
Entry,
2122
Frame,
2223
Label,
2324
Listbox,
2425
N,
2526
S,
2627
Scrollbar,
28+
StringVar,
2729
W,
2830
)
2931

@@ -39,7 +41,9 @@
3941
ICON_WARNING,
4042
NMEA_PRESET,
4143
OKCOL,
44+
VALNONBLANK,
4245
)
46+
from pygpsclient.helpers import validate
4347
from pygpsclient.strings import (
4448
CONFIRM,
4549
DLGACTION,
@@ -80,6 +84,8 @@ def __init__(self, app: Frame, parent: Frame, *args, **kwargs):
8084
self._img_warn = ImageTk.PhotoImage(Image.open(ICON_WARNING))
8185
self._preset_command = None
8286
self._configfile = None
87+
self._command = StringVar()
88+
self._confirm = False
8389
self._body()
8490
self._do_layout()
8591
self._attach_events()
@@ -90,6 +96,16 @@ def _body(self):
9096
Set up frame and widgets.
9197
"""
9298

99+
self._lbl_command = Label(
100+
self,
101+
text="Command",
102+
)
103+
self._ent_command = Entry(
104+
self,
105+
textvariable=self._command,
106+
relief="sunken",
107+
width=55,
108+
)
93109
self._lbl_presets = Label(self, text=LBLNMEAPRESET, anchor=W)
94110
self._lbx_preset = Listbox(
95111
self,
@@ -119,15 +135,17 @@ def _do_layout(self):
119135
Layout widgets.
120136
"""
121137

122-
self._lbl_presets.grid(column=0, row=0, columnspan=6, padx=3, sticky=EW)
138+
self._lbl_command.grid(column=0, row=0, padx=3, sticky=W)
139+
self._ent_command.grid(column=1, row=0, columnspan=5, padx=3, sticky=EW)
140+
self._lbl_presets.grid(column=0, row=1, columnspan=6, padx=3, sticky=EW)
123141
self._lbx_preset.grid(
124-
column=0, row=1, columnspan=3, rowspan=20, padx=3, pady=3, sticky=EW
142+
column=0, row=2, columnspan=3, rowspan=20, padx=3, pady=3, sticky=EW
125143
)
126-
self._scr_presetv.grid(column=2, row=1, rowspan=20, sticky=(N, S, E))
127-
self._scr_preseth.grid(column=0, row=21, columnspan=3, sticky=EW)
128-
self._btn_send_command.grid(column=3, row=1, padx=3, ipadx=3, ipady=3, sticky=E)
144+
self._scr_presetv.grid(column=2, row=2, rowspan=20, sticky=(N, S, E))
145+
self._scr_preseth.grid(column=0, row=22, columnspan=3, sticky=EW)
146+
self._btn_send_command.grid(column=3, row=2, padx=3, ipadx=3, ipady=3, sticky=E)
129147
self._lbl_send_command.grid(
130-
column=3, row=2, padx=3, ipadx=3, ipady=3, sticky=EW
148+
column=3, row=3, padx=3, ipadx=3, ipady=3, sticky=EW
131149
)
132150

133151
cols, rows = self.grid_size()
@@ -152,27 +170,31 @@ def reset(self):
152170
self.__app.configuration.init_presets("nmea")
153171
for i, preset in enumerate(self.__app.configuration.get("nmeapresets_l")):
154172
self._lbx_preset.insert(i, preset)
173+
self._command.set("")
174+
self._confirm = False
155175

156176
def _on_select_preset(self, *args, **kwargs): # pylint: disable=unused-argument
157177
"""
158178
Preset command has been selected.
159179
"""
160180

161-
idx = self._lbx_preset.curselection()
162-
self._preset_command = self._lbx_preset.get(idx)
181+
cmd = self._lbx_preset.get(self._lbx_preset.curselection())
182+
self._confirm = CONFIRM in cmd
183+
self._command.set(cmd[cmd.find(";", 1) + 1 :].strip())
163184

164185
def _on_send_preset(self, *args, **kwargs): # pylint: disable=unused-argument
165186
"""
166187
Preset command send button has been clicked.
167188
"""
168189

169-
if self._preset_command in ("", None):
170-
self.__container.status_label = ("Select preset", ERRCOL)
190+
if not self._ent_command.validate(VALNONBLANK):
191+
self.__container.status_label = ("Select preset or enter command", ERRCOL)
171192
return
193+
self._preset_command = self._command.get()
172194

173195
confids = []
174196
try:
175-
if CONFIRM in self._preset_command:
197+
if self._confirm:
176198
if ConfirmBox(self, DLGACTION, DLGACTIONCONFIRM).show():
177199
confids = self._do_user_defined(self._preset_command)
178200
status = CONFIRMED
@@ -212,7 +234,7 @@ def _do_user_defined(self, command: str) -> list:
212234
confids = []
213235
try:
214236
seg = command.split(";")
215-
for i in range(1, len(seg), 4):
237+
for i in range(0, len(seg), 4):
216238
talker = seg[i].strip()
217239
msg_id = seg[i + 1].strip()
218240
payload = seg[i + 2].strip()

0 commit comments

Comments
 (0)