Skip to content

Commit 73d04ff

Browse files
committed
DNA fixes and improvements
- added proper parser functions where they were missing - added handling for GSI format - added connection testing on init
1 parent c64db07 commit 73d04ff

File tree

6 files changed

+70
-35
lines changed

6 files changed

+70
-35
lines changed

src/geocompy/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,7 @@ def __init__(
364364
logger = Logger("/dev/null")
365365
logger.addHandler(NullHandler())
366366
self._logger: Logger = logger
367+
self.gsi16 = False
367368

368369
def setrequest(
369370
self,

src/geocompy/data.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,15 +161,20 @@ def gsiword(
161161
negative: bool = False,
162162
gsi16: bool = False
163163
) -> str:
164-
data = data.zfill(16 if gsi16 else 8)
164+
if gsi16:
165+
data = f"{data.zfill(16):.16s}"
166+
else:
167+
data = f"{data.zfill(8):.8s}"
168+
165169
sign = "-" if negative else "+"
166170
info = f"{info:.4s}"
167171
if len(info) < 4:
168-
wistr = f"{str(wi):.3s}"
172+
idx = f"{str(wi):.3s}"
169173
else:
170-
wistr = f"{str(wi):.2s}"
171-
padding = "." * (6 - len(wistr) - len(info))
172-
return f"{wistr}{padding}{info}{sign}{data:.8s} "
174+
idx = f"{str(wi):.2s}"
175+
padding = "." * (6 - len(idx) - len(info))
176+
mark = "*" if gsi16 else ""
177+
return f"{mark}{idx}{padding}{info}{sign}{data} "
173178

174179

175180
class AngleUnit(Enum):

src/geocompy/dna/__init__.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from typing import Callable, TypeVar
66
from traceback import format_exc
77
import logging
8+
from time import sleep
89

910
from .. import (
1011
GsiOnlineProtocol,
@@ -46,12 +47,31 @@ class BEEPTYPE(Enum):
4647
def __init__(
4748
self,
4849
connection: Connection,
49-
logger: logging.Logger | None = None
50+
logger: logging.Logger | None = None,
51+
retry: int = 2
5052
):
5153
super().__init__(connection, logger)
5254
self.settings: DNASettings = DNASettings(self)
5355
self.measurements: DNAMeasurements = DNAMeasurements(self)
5456

57+
for i in range(retry):
58+
try:
59+
reply = self._conn.exchange1("a")
60+
if reply == "?":
61+
break
62+
except Exception:
63+
pass
64+
65+
sleep(1)
66+
else:
67+
raise ConnectionError(
68+
"could not establish connection to instrument"
69+
)
70+
71+
response = self.settings.get_format()
72+
if response.value is not None:
73+
self.gsi16 = response.value == self.settings.FORMAT.GSI16
74+
5575
def setrequest(
5676
self,
5777
param: int,

src/geocompy/dna/measurements.py

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@ def get_point_id(self) -> GsiOnlineResponse[str | None]:
1414
return self._getrequest(
1515
"M",
1616
11,
17-
lambda v: v.strip().split("+")[1].lstrip("0")
17+
lambda v: v.strip("* ")[7:].lstrip("0")
1818
)
1919

2020
def set_point_id(
2121
self,
2222
ptid: str
2323
) -> GsiOnlineResponse[bool]:
2424
wi = 11
25-
word = gsiword(wi, ptid)
25+
word = gsiword(wi, ptid, gsi16=self._parent.gsi16)
2626

2727
return self._putrequest(
2828
wi,
@@ -33,15 +33,15 @@ def get_note(self) -> GsiOnlineResponse[str | None]:
3333
return self._getrequest(
3434
"M",
3535
71,
36-
lambda v: v.strip().split("+")[1].lstrip("0")
36+
lambda v: v.strip("* ")[7:].lstrip("0")
3737
)
3838

3939
def set_note(
4040
self,
4141
note: str
4242
) -> GsiOnlineResponse[bool]:
4343
wi = 71
44-
word = gsiword(wi, note)
44+
word = gsiword(wi, note, gsi16=self._parent.gsi16)
4545

4646
return self._putrequest(
4747
wi,
@@ -50,6 +50,7 @@ def set_note(
5050

5151
def get_time(self) -> GsiOnlineResponse[time | None]:
5252
def parsetime(value: str) -> time:
53+
value = value.strip("* ")
5354
return time(
5455
int(value[-6:-4]),
5556
int(value[-4:-2]),
@@ -70,7 +71,8 @@ def set_time(
7071
word = gsiword(
7172
wi,
7273
f"{value.hour:02d}{value.minute:02d}{value.second:02d}",
73-
info="6"
74+
info="6",
75+
gsi16=self._parent.gsi16
7476
)
7577

7678
return self._putrequest(
@@ -80,6 +82,7 @@ def set_time(
8082

8183
def get_date(self) -> GsiOnlineResponse[tuple[int, int] | None]:
8284
def parsedate(value: str) -> tuple[int, int]:
85+
value = value.strip("* ")
8386
return int(value[-6:-4]), int(value[-4:-2])
8487

8588
return self._getrequest(
@@ -97,7 +100,8 @@ def set_date(
97100
word = gsiword(
98101
wi,
99102
f"{month:02d}{day:02d}00",
100-
info="6"
103+
info="6",
104+
gsi16=self._parent.gsi16
101105
)
102106

103107
return self._putrequest(
@@ -109,7 +113,7 @@ def get_year(self) -> GsiOnlineResponse[int | None]:
109113
return self._getrequest(
110114
"I",
111115
562,
112-
lambda v: int(v.lstrip("0"))
116+
lambda v: int(v.strip("* ")[7:].lstrip("0"))
113117
)
114118

115119
def set_year(
@@ -119,7 +123,8 @@ def set_year(
119123
wi = 562
120124
word = gsiword(
121125
wi,
122-
str(year)
126+
str(year),
127+
gsi16=self._parent.gsi16
123128
)
124129

125130
return self._putrequest(
@@ -129,14 +134,14 @@ def set_year(
129134

130135
def get_distance(self) -> GsiOnlineResponse[float | None]:
131136
def parsedist(value: str) -> float:
132-
data = float(value.strip()[6:])
133-
unit = int(value[5])
134-
match unit:
135-
case 0 | 1:
137+
value = value.strip("* ")
138+
data = float(value[6:])
139+
match value[5]:
140+
case "0" | "1":
136141
data /= 1000
137-
case 6 | 7:
142+
case "6" | "7":
138143
data /= 10000
139-
case 8:
144+
case "8":
140145
data /= 100000
141146

142147
return data
@@ -149,14 +154,14 @@ def parsedist(value: str) -> float:
149154

150155
def get_reading(self) -> GsiOnlineResponse[float | None]:
151156
def parsereading(value: str) -> float:
152-
data = float(value.strip()[6:])
153-
unit = int(value[5])
154-
match unit:
155-
case 0 | 1:
157+
value = value.strip("* ")
158+
data = float(value[6:])
159+
match value[5]:
160+
case "0" | "1":
156161
data /= 1000
157-
case 6 | 7:
162+
case "6" | "7":
158163
data /= 10000
159-
case 8:
164+
case "8":
160165
data /= 100000
161166

162167
return data
@@ -167,30 +172,30 @@ def parsereading(value: str) -> float:
167172
parsereading
168173
)
169174

170-
def get_temperature(self) -> GsiOnlineResponse[int | None]:
175+
def get_temperature(self) -> GsiOnlineResponse[float | None]:
171176
return self._getrequest(
172177
"M",
173178
95,
174-
lambda v: int(v.strip()[6:])
179+
lambda v: int(v.strip("* ")[6:]) / 10000
175180
)
176181

177182
def get_serialnumber(self) -> GsiOnlineResponse[str | None]:
178183
return self._getrequest(
179184
"I",
180185
12,
181-
str
186+
lambda v: v.strip("* ")[7:].lstrip("0")
182187
)
183188

184189
def get_instrument_type(self) -> GsiOnlineResponse[str | None]:
185190
return self._getrequest(
186191
"I",
187192
13,
188-
str
193+
lambda v: v.strip("* ")[7:].lstrip("0")
189194
)
190195

191196
def get_full_date(self) -> GsiOnlineResponse[datetime | None]:
192197
def parsedate(value: str) -> datetime:
193-
value = value.strip()
198+
value = value.strip("* ")
194199
return datetime(
195200
int(value[-4:]),
196201
int(value[-6:-4]),
@@ -205,7 +210,7 @@ def parsedate(value: str) -> datetime:
205210

206211
def get_day_time(self) -> GsiOnlineResponse[tuple[int, int, time] | None]:
207212
def parse(value: str) -> tuple[int, int, time]:
208-
value = value.strip()
213+
value = value.strip("* ")
209214
return (
210215
int(value[-8:-6]),
211216
int(value[-6:-4]),
@@ -225,5 +230,5 @@ def get_software_version(self) -> GsiOnlineResponse[str | None]:
225230
return self._getrequest(
226231
"I",
227232
599,
228-
str
233+
lambda v: v.strip("* ")[7:].lstrip("0")
229234
)

src/geocompy/dna/meta.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
word_descriptions: dict[int, str] = {
3131
11: "Point ID",
32-
71: "Remark",
32+
71: "Note",
3333
560: "Time",
3434
561: "Date",
3535
562: "Year",

src/geocompy/dna/settings.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,11 @@ def set_format(
282282
format: FORMAT | str
283283
) -> GsiOnlineResponse[bool]:
284284
_format = toenum(self.FORMAT, format)
285-
return self._setrequest(137, _format.value)
285+
response = self._setrequest(137, _format.value)
286+
if response.value:
287+
self._parent.gsi16 = _format == self.FORMAT.GSI16
288+
289+
return response
286290

287291
def get_format(self) -> GsiOnlineResponse[FORMAT | None]:
288292
return self._confrequest(

0 commit comments

Comments
 (0)