Skip to content

Commit edf9664

Browse files
authored
Merge pull request #8 from semuconsulting/RC-1.0.0
Rc 1.0.0
2 parents 69d082c + 920d3f4 commit edf9664

15 files changed

Lines changed: 107 additions & 77 deletions

.github/workflows/checkpr.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ jobs:
1111
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
1212

1313
steps:
14-
- uses: actions/checkout@v4
14+
- uses: actions/checkout@v6
1515
- name: Set up Python ${{ matrix.python-version }}
16-
uses: actions/setup-python@v5
16+
uses: actions/setup-python@v6
1717
with:
1818
python-version: ${{ matrix.python-version }}
1919
- name: Install deploy dependencies

.github/workflows/deploy.yml

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@ jobs:
1111
release-build:
1212
runs-on: ubuntu-latest
1313
steps:
14-
15-
- uses: actions/checkout@v4
16-
- name: Set up Python
17-
uses: actions/setup-python@v5
14+
- uses: actions/checkout@v6
15+
- name: Set up Python
16+
uses: actions/setup-python@v6
1817
with:
1918
python-version: 3.13
2019

@@ -24,7 +23,7 @@ jobs:
2423
python -m build
2524
2625
- name: Upload distributions # upload build artifacts
27-
uses: actions/upload-artifact@v4
26+
uses: actions/upload-artifact@v6
2827
with:
2928
name: release-dists
3029
path: dist/
@@ -35,13 +34,12 @@ jobs:
3534
name: Upload release to PyPI
3635
runs-on: ubuntu-latest
3736
environment:
38-
name: pypi
37+
name: pypi
3938
permissions:
4039
id-token: write
4140
steps:
42-
4341
- name: Download all the dists # download build artifacts saved in previous job
44-
uses: actions/download-artifact@v4
42+
uses: actions/download-artifact@v8
4543
with:
4644
name: release-dists
4745
path: dist/

.github/workflows/main.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ jobs:
1313
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
1414

1515
steps:
16-
- uses: actions/checkout@v4
16+
- uses: actions/checkout@v6
1717
- name: Set up Python ${{ matrix.python-version }}
18-
uses: actions/setup-python@v5
18+
uses: actions/setup-python@v6
1919
with:
2020
python-version: ${{ matrix.python-version }}
2121
- name: Install deploy dependencies

.vscode/settings.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,10 @@
1717
"C_Cpp.copilotHover": "disabled",
1818
"chat.agent.enabled": false,
1919
"chat.commandCenter.enabled": false,
20-
"chat.notifyWindowOnConfirmation": false,
20+
"chat.notifyWindowOnConfirmation": "off",
2121
"telemetry.feedback.enabled": false,
2222
"python.analysis.addHoverSummaries": false,
2323
"python-envs.defaultEnvManager": "ms-python.python:venv",
24-
"python-envs.pythonProjects": [],
2524
"python.defaultInterpreterPath": "${userHome}/pygpsclient/bin/python3",
2625
"python.testing.unittestEnabled": true,
2726
"python.testing.unittestArgs": [

README.md

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -173,40 +173,43 @@ The `parse()` method accepts the following optional keyword arguments:
173173
* `parsebitfield`: 1 = parse bitfields ('X' type properties) as individual bit flags, where defined (default), 0 = leave bitfields as byte sequences
174174
* `msgmode`: `GET` (0) (default), `SET` (1), `POLL` (2)
175175

176-
Example A - parsing VERSION output message:
176+
Example A - parsing BESTNAV output message:
177177
```python
178178
from pyunigps import GET, VALCKSUM, UNIReader
179179

180180
msg = UNIReader.parse(
181-
b'\xaaD\xb5\x00\x11\x004\x01\x00\x00f\t\x8f\xf4\x0e\x02\x00\x00\x00\x00\x00\x00\x00\x00M982R4.10Build5251 HRPT00-S10C-P - ffff48ffff0fffff 2021/11/26 #\x87\x83\xb9'
182-
,
181+
b"\xaaD\xb5YF\x08x\x00\x00\xa0e\t\xe8\...\x98\x15\xa5\xf1",
183182
validate=VALCKSUM,
184183
parsebitfield=1,
185184
)
186185
print(msg)
187186
```
188187
```
189-
<UNI(VERSION, cpuidle=0, timeref=0, timestatus=0, wno=2406, tow=34534543, version=0, leapsecond=0, delay=0, device=18, swversion=R4.10Build5251, authtype=HRPT00-S10C-P, psn=-, efuseid=ffff48ffff0fffff, comptime=2021/11/26)>
188+
"<UNI(BESTNAV, cpuidle=89, timeref=0, timestatus=160, wno=2405, tow=75521000, version=0, leapsecond=18, delay=13, solstatus=0, postype=16, lat=43.450634678833644, lon=-1.1303087675041795, hmsl=36.32093767914921, undulation=51.67765808105469, datumid=61, latstd=2.6222991943359375, lonstd=1.9253981113433838, hmslstd=2.7721946239471436, stationid=0, diffage=0.0, solage=0.0, numsvs=25, numsolnsvs=21, reserved1=21, reserved2=0, reserved3=1, rtkverify=0, psrionocorr=1, gale1=1, gale5b=0, gale5a=0, bdsb1l=1, bdsb3l=0, bdsb2a=0, bdsb1c=0, gpsl1=1, gpsl2=0, gpsl5=0, glol1=1, glol2=0, bdsb2l=0, vsolstatus=0, veltype=8, latency=0.0, age=0.0, horspd=0.06034742542911377, trkgnd=192.53216796929004, vertspd=-0.001533079795667136, verspdstd=0.14649531245231628, horspdstd=0.11643162369728088)>"
190189
```
191190

192-
The `UNIMessage` object exposes different public attributes depending on its message type or 'identity'. Attributes which are enumerations may have corresponding decodes in `pyunigps.unitypes_decodes` e.g. the `VERSION` message has the following attributes:
191+
The `UNIMessage` object exposes different public attributes depending on its message type or 'identity'. Helper methods are available to convert position coordinates into different formats. Attributes which are enumerations may have corresponding decodes in `pyunigps.unitypes_decodes` e.g. the `BESTNAV` message has the following attributes:
193192

194193
```python
195-
from pyunigps import DEVICE
196-
print(msg)
194+
from pyunigps import POSTYPE, PSRIONOCORR, SOLSTATUS, latlon2dms, llh2iso6709, wnotow2utc
197195
print(msg.identity)
198-
print(msg.device)
199-
print(DEVICE[msg.device])
200-
print(swversion)
201-
print(comptime)
196+
print(wnotow2utc(msg.wno, msg.tow, msg.leapsecond))
197+
print(msg.lat, msg.lon, msg.hmsl)
198+
print(latlon2dms(msg.lat, msg.lon))
199+
print(llh2iso6709(msg.lat, msg.lon, msg.hmsl))
200+
print(msg.solstatus, SOLSTATUS[msg.solstatus])
201+
print(msg.postype, POSTYPE[msg.postype])
202+
print(msg.psrionocorr, PSRIONOCORR[msg.psrionocorr])
202203
```
203204
```
204-
<UNI(VERSION, cpuidle=0, timeref=0, timestatus=0, wno=2406, tow=34534543, version=0, leapsecond=18, delay=0, device=18, swversion=R4.10Build5251, authtype=HRPT00-S10C-P, psn=-, efuseid=ffff48ffff0fffff, comptime=2021/11/26)>
205-
VERSION
206-
18
207-
UM980
208-
R4.10Build5251
209-
2021/11/26
205+
BESTNAV
206+
2026-02-08 20:58:23+00:00
207+
43.450634678833644, -1.1303087675041795, 36.32093767914921
208+
('43°27′2.28484″N', '1°7′49.11156″W')
209+
+43.450634678833644-1.1303087675041794+36.32093767914921CRSWGS_84/
210+
0 SOL_COMPUTED
211+
16 SINGLE
212+
1 Klobuchareph
210213
```
211214

212215
The `payload` attribute always contains the raw payload as bytes. Attributes within repeating groups are parsed with a two-digit suffix (prn_01, prn_02, etc.).

RELEASE_NOTES.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# pyunigps Release Notes
22

3+
### RELEASE 1.0.0
4+
5+
1. Update status to Stable.
6+
1. Remove duplicate keys from DEVICE decode.
7+
1. Inherit helper methods from pynmeagps.
8+
39
### RELEASE 0.2.0
410

511
1. Update for Protocol Specification R1.13 Dec 2025.

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ readme = "README.md"
1414
requires-python = ">=3.10"
1515
classifiers = [
1616
"Operating System :: OS Independent",
17-
"Development Status :: 4 - Beta",
17+
"Development Status :: 5 - Production/Stable",
1818
"Environment :: MacOS X",
1919
"Environment :: Win32 (MS Windows)",
2020
"Environment :: X11 Applications",
@@ -32,7 +32,7 @@ classifiers = [
3232
"Topic :: Scientific/Engineering :: GIS",
3333
]
3434

35-
dependencies = ["pynmeagps >= 1.1.0", "pyrtcm>=1.1.10"]
35+
dependencies = ["pynmeagps >= 1.1.2", "pyrtcm>=1.1.11"]
3636

3737
[project.urls]
3838
homepage = "https://github.com/semuconsulting/pyunigps"

src/pyunigps/__init__.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,24 @@
66
:license: BSD 3-Clause
77
"""
88

9-
from pynmeagps import SocketWrapper
9+
from pynmeagps import (
10+
SocketWrapper,
11+
area,
12+
bearing,
13+
deg2dmm,
14+
deg2dms,
15+
dms2deg,
16+
ecef2llh,
17+
haversine,
18+
latlon2dmm,
19+
latlon2dms,
20+
leapsecond,
21+
llh2ecef,
22+
llh2iso6709,
23+
planar,
24+
utc2wnotow,
25+
wnotow2utc,
26+
)
1027

1128
from pyunigps._version import __version__
1229
from pyunigps.exceptions import (

src/pyunigps/_version.py

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

11-
__version__ = "0.2.0"
11+
__version__ = "1.0.0"

src/pyunigps/unihelpers.py

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
Collection of UNI helper methods which can be used
33
outside the UNIMessage or UNIReader classes.
44
5+
pyunigps also inherits pynmeagps helper methods.
6+
57
Created on 6 Oct 2025
68
79
:author: semuadmin (Steve Smith)
@@ -14,7 +16,7 @@
1416
from types import NoneType
1517
from typing import Any
1618

17-
from pynmeagps import leapsecond
19+
from pynmeagps import utc2wnotow
1820

1921
import pyunigps.exceptions as une
2022
from pyunigps.unitypes_core import ATTTYPE, SCALROUND, U4, UNI_MSGIDS
@@ -492,27 +494,6 @@ def nomval(adef: str) -> Any:
492494
return val
493495

494496

495-
def utc2wnotow(utc: datetime | NoneType = None) -> tuple[int, int, int]:
496-
"""
497-
Get GPS Week number (wno), Time of Week (tow) in milliseconds
498-
and leapsecond offset for given utc datetime.
499-
500-
GPS Epoch 0 = 6th Jan 1980
501-
502-
:param datetime | NoneType utc: utc datetime (defaults to now if None)
503-
:return: wno, tow, leapsecond
504-
:rtype: tuple[int,int, int]
505-
"""
506-
507-
if utc is None:
508-
utc = datetime.now(tz=timezone.utc)
509-
ls = leapsecond(utc.replace(tzinfo=None)) # method is not tz aware
510-
ts = ((utc - GPSEPOCH0).total_seconds() + ls) * 1000
511-
wno = int((utc - GPSEPOCH0).days / 7)
512-
tow = int(ts - wno * 604800000)
513-
return wno, tow, ls
514-
515-
516497
def val2bytes(val: Any, adef: str) -> bytes:
517498
"""
518499
Convert value to bytes for given UNI attribute type.

0 commit comments

Comments
 (0)