or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-parsing.mddepth-sonar.mdgps-positioning.mdindex.mdnavigation-course.mdproprietary-sentences.mdstream-processing.mdutilities.mdwind-weather.md

utilities.mddocs/

0

# Utility Functions and Mixins

1

2

Utility functions and mixin classes provide coordinate conversion, timestamp parsing, validation helpers, and extended functionality for NMEA sentence objects.

3

4

## Utility Functions

5

6

### Timestamp and Date Parsing

7

8

```python { .api }

9

def timestamp(s: str) -> datetime.time:

10

"""

11

Convert HHMMSS[.ss] ASCII string to datetime.time object.

12

13

Args:

14

s: Time string in format HHMMSS or HHMMSS.ss

15

16

Returns:

17

datetime.time object with UTC timezone

18

19

Example:

20

timestamp('184353.07') -> datetime.time(18, 43, 53, 70000, tzinfo=datetime.timezone.utc)

21

"""

22

23

def datestamp(s: str) -> datetime.date:

24

"""

25

Convert DDMMYY ASCII string to datetime.date object.

26

27

Args:

28

s: Date string in format DDMMYY

29

30

Returns:

31

datetime.date object

32

33

Example:

34

datestamp('120598') -> datetime.date(1998, 5, 12)

35

"""

36

```

37

38

### Coordinate Conversion

39

40

```python { .api }

41

def dm_to_sd(dm: str) -> float:

42

"""

43

Convert degrees/minutes format to signed decimal degrees.

44

45

Args:

46

dm: Coordinate in DDDMM.MMMM format (e.g., '12319.943281')

47

48

Returns:

49

Decimal degrees as float

50

51

Raises:

52

ValueError: If format is invalid

53

54

Example:

55

dm_to_sd('12319.943281') -> 123.33238801666667

56

"""

57

```

58

59

### Status Validation

60

61

```python { .api }

62

def valid(s: str) -> bool:

63

"""

64

Check if status flag equals 'A' (active/valid).

65

66

Args:

67

s: Status character

68

69

Returns:

70

True if s == 'A', False otherwise

71

"""

72

```

73

74

### Usage Examples

75

76

```python

77

import pynmea2

78

from pynmea2 import timestamp, datestamp, dm_to_sd, valid

79

80

# Parse timestamps

81

time_obj = timestamp('184353.07')

82

print(f"Time: {time_obj}") # 18:43:53.070000+00:00

83

print(f"Hour: {time_obj.hour}") # 18

84

print(f"Microseconds: {time_obj.microsecond}")# 70000

85

86

# Parse dates

87

date_obj = datestamp('120598')

88

print(f"Date: {date_obj}") # 1998-05-12

89

90

# Convert coordinates

91

decimal_deg = dm_to_sd('12319.943281')

92

print(f"Decimal degrees: {decimal_deg}") # 123.33238801666667

93

94

# Validate status

95

print(f"Valid status A: {valid('A')}") # True

96

print(f"Valid status V: {valid('V')}") # False

97

```

98

99

## Mixin Classes

100

101

### LatLonFix

102

103

```python { .api }

104

class LatLonFix:

105

"""

106

Mixin adding latitude/longitude properties as signed decimal degrees.

107

108

Requires sentence to have lat, lat_dir, lon, lon_dir fields.

109

"""

110

111

@property

112

def latitude(self) -> float:

113

"""

114

Latitude in signed decimal degrees.

115

116

Returns:

117

Positive for North, negative for South

118

"""

119

120

@property

121

def longitude(self) -> float:

122

"""

123

Longitude in signed decimal degrees.

124

125

Returns:

126

Positive for East, negative for West

127

"""

128

129

@property

130

def latitude_minutes(self) -> float:

131

"""Minutes component of latitude."""

132

133

@property

134

def longitude_minutes(self) -> float:

135

"""Minutes component of longitude."""

136

137

@property

138

def latitude_seconds(self) -> float:

139

"""Seconds component of latitude."""

140

141

@property

142

def longitude_seconds(self) -> float:

143

"""Seconds component of longitude."""

144

```

145

146

### DatetimeFix

147

148

```python { .api }

149

class DatetimeFix:

150

"""

151

Mixin adding datetime property combining date and time fields.

152

153

Requires sentence to have datestamp and timestamp fields.

154

"""

155

156

@property

157

def datetime(self) -> datetime.datetime:

158

"""Combined date and time as datetime object."""

159

```

160

161

### Validation Mixins

162

163

```python { .api }

164

class ValidStatusFix:

165

"""

166

Mixin adding is_valid property checking status == 'A'.

167

168

Requires sentence to have status field.

169

"""

170

171

@property

172

def is_valid(self) -> bool:

173

"""True if status field equals 'A'."""

174

175

class ValidGGAFix:

176

"""

177

Mixin for GGA sentence validity checking.

178

179

Requires sentence to have gps_qual field.

180

"""

181

182

@property

183

def is_valid(self) -> bool:

184

"""True if GPS quality indicates valid fix (1-5)."""

185

186

class ValidGSAFix:

187

"""

188

Mixin for GSA sentence validity checking.

189

190

Requires sentence to have mode_fix_type field.

191

"""

192

193

@property

194

def is_valid(self) -> bool:

195

"""True if fix type is 2D or 3D (2 or 3)."""

196

197

class ValidRMCStatusFix(ValidStatusFix):

198

"""

199

Extended validity checking for RMC sentences.

200

201

Checks status, mode_indicator, and nav_status fields.

202

"""

203

204

@property

205

def is_valid(self) -> bool:

206

"""True if all status indicators are valid."""

207

```

208

209

## Usage Examples

210

211

```python

212

import pynmea2

213

214

# LatLonFix example

215

msg = pynmea2.parse("$GPGGA,184353.07,1929.045,S,02410.506,E,1,04,2.6,100.00,M,-33.9,M,,0000*6D")

216

217

# Decimal degrees (most useful)

218

print(f"Position: {msg.latitude:.6f}, {msg.longitude:.6f}") # -19.484083, 24.175100

219

220

# Component access

221

print(f"Lat minutes: {msg.latitude_minutes:.3f}") # 29.045

222

print(f"Lon minutes: {msg.longitude_minutes:.3f}") # 10.506

223

print(f"Lat seconds: {msg.latitude_seconds:.1f}") # 2.7

224

print(f"Lon seconds: {msg.longitude_seconds:.1f}") # 30.4

225

226

# Format coordinates in different ways

227

abs_lat, abs_lon = abs(msg.latitude), abs(msg.longitude)

228

print(f"DMS: {abs_lat:.0f}°{msg.latitude_minutes:.3f}'{msg.lat_dir} {abs_lon:.0f}°{msg.longitude_minutes:.3f}'{msg.lon_dir}")

229

230

# DatetimeFix example

231

msg = pynmea2.parse("$GPRMC,184353.07,A,1929.045,S,02410.506,E,0.13,309.62,120598,,A*70")

232

print(f"Date: {msg.datestamp}") # 1998-05-12

233

print(f"Time: {msg.timestamp}") # 18:43:53.070000+00:00

234

print(f"Combined: {msg.datetime}") # 1998-05-12 18:43:53.070000+00:00

235

236

# Validation examples

237

gga_msg = pynmea2.parse("$GPGGA,184353.07,1929.045,S,02410.506,E,1,04,2.6,100.00,M,-33.9,M,,0000*6D")

238

print(f"GGA valid: {gga_msg.is_valid}") # True (GPS quality = 1)

239

240

rmc_msg = pynmea2.parse("$GPRMC,184353.07,A,1929.045,S,02410.506,E,0.13,309.62,120598,,A*70")

241

print(f"RMC valid: {rmc_msg.is_valid}") # True (status = A)

242

243

gsa_msg = pynmea2.parse("$GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39")

244

print(f"GSA valid: {gsa_msg.is_valid}") # True (3D fix)

245

```

246

247

## Timezone Support

248

249

```python { .api }

250

class TZInfo(datetime.tzinfo):

251

"""Custom timezone info class for local time zones."""

252

253

def __init__(self, hh: int, mm: int):

254

"""

255

Initialize with hour and minute offset from UTC.

256

257

Args:

258

hh: Hour offset from UTC

259

mm: Minute offset from UTC

260

"""

261

262

def utcoffset(self, dt: datetime.datetime) -> datetime.timedelta:

263

"""Return offset from UTC."""

264

265

def tzname(self, dt: datetime.datetime) -> str:

266

"""Return timezone name."""

267

268

def dst(self, dt: datetime.datetime) -> datetime.timedelta:

269

"""Return DST offset (always 0)."""

270

```

271

272

### Usage Example

273

274

```python

275

import pynmea2

276

from pynmea2 import TZInfo

277

278

# Create timezone info for UTC+5:30 (India Standard Time)

279

ist = TZInfo(5, 30)

280

281

msg = pynmea2.parse("$GPZDA,184353.07,12,05,1998,05,30*4F")

282

utc_time = msg.datetime

283

284

# Convert to local time

285

local_time = utc_time.replace(tzinfo=pynmea2.datetime.timezone.utc).astimezone(ist)

286

print(f"UTC: {utc_time}") # 1998-05-12 18:43:53.070000

287

print(f"Local: {local_time}") # 1998-05-13 00:13:53.070000+05:30

288

```

289

290

## SeaTalk Support

291

292

```python { .api }

293

class SeaTalk:

294

"""

295

Mixin adding SeaTalk protocol functionality.

296

297

Based on Thomas Knauf's SeaTalk documentation.

298

Requires sentence to have cmd field.

299

"""

300

301

byte_to_command: Dict[str, str] # Mapping of command bytes to descriptions

302

303

@property

304

def command_name(self) -> str:

305

"""Get human-readable command name from cmd field."""

306

```

307

308

### Usage Example

309

310

```python

311

import pynmea2

312

313

# Parse SeaTalk sentence (ALK sentence type)

314

msg = pynmea2.parse("$STALK,84,96,82,00,00,00,08,02,00*77")

315

print(f"Command: {msg.cmd}") # 84

316

print(f"Command name: {msg.command_name}") # Compass heading Autopilot course and Rudder position

317

```