Skip to content

Commit b8a8200

Browse files
committed
Added DNA SET and CONF commands
1 parent dd9b736 commit b8a8200

File tree

4 files changed

+428
-38
lines changed

4 files changed

+428
-38
lines changed

src/geocompy/__init__.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@
3737
``geocompy.vivatps``
3838
Communication with instruments running Viva(/Nova)TPS software.
3939
40+
``geocompy.dna``
41+
Communication with DNA digital level instruments.
42+
4043
Submodules
4144
----------
4245
@@ -313,6 +316,30 @@ def __bool__(self) -> bool:
313316
return self.value is not None
314317

315318

319+
class GsiOnlineSubsystem:
320+
"""
321+
Base class for GSI Online subsystems.
322+
"""
323+
324+
def __init__(self, parent: GsiOnlineProtocol):
325+
"""
326+
Parameters
327+
----------
328+
parent : GsiOnlineProtocol
329+
The parent protocol instance of this subsystem.
330+
"""
331+
self._parent: GsiOnlineProtocol = parent
332+
"""Parent protocol instance"""
333+
self._setrequest = self._parent.setrequest
334+
"""Shortcut to the `setrequest` method of the parent protocol."""
335+
self._confrequest = self._parent.confrequest
336+
"""Shortcut to the `confrequest` method of the parent protocol."""
337+
self._putrequest = self._parent.putrequest
338+
"""Shortcut to the `putrequest` method of the parent protocol."""
339+
self._getrequest = self._parent.getrequest
340+
"""Shortcut to the `getrequest` method of the parent protocol."""
341+
342+
316343
class GsiOnlineProtocol:
317344
"""
318345
Base class for GSI Online protocol versions.
@@ -342,7 +369,7 @@ def setrequest(
342369
self,
343370
param: int,
344371
value: int
345-
) -> GsiOnlineResponse[bool | None]:
372+
) -> GsiOnlineResponse[bool]:
346373
"""
347374
Executes a GSI Online SET command and returns the success
348375
of the operation.
@@ -398,7 +425,7 @@ def putrequest(
398425
self,
399426
wordindex: int,
400427
word: str
401-
) -> GsiOnlineResponse[bool | None]:
428+
) -> GsiOnlineResponse[bool]:
402429
"""
403430
Executes a GSI Online PUT command and returns the success
404431
of the operation.

src/geocompy/dna/__init__.py

Lines changed: 100 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,53 +4,72 @@
44
import re
55
from typing import Callable, TypeVar
66
from traceback import format_exc
7+
import logging
78

89
from .. import (
910
GsiOnlineProtocol,
1011
GsiOnlineResponse
1112
)
13+
from ..communication import Connection
1214
from ..data import (
13-
enumparser,
1415
toenum
1516
)
1617
from .meta import (
1718
param_descriptions,
1819
word_descriptions,
1920
DNAErrors
2021
)
22+
from .settings import DNASettings
2123

2224

2325
_T = TypeVar("_T")
2426

2527

2628
class DNA(GsiOnlineProtocol):
2729
_CONFPAT = re.compile(
28-
r"^(?P<conf>\d{4})/"
29-
r"(?P<value>\d{4})$"
30+
r"^(?:\d{4})/"
31+
r"(?:\d{4})$"
3032
)
33+
_GSIPAT = re.compile(
34+
r"^\*?"
35+
r"(?:[0-9\.]{6})"
36+
r"(?:\+|\-)"
37+
r"(?:[a-zA-Z0-9]{8}|[a-zA-Z0-9]{16}) $"
38+
)
39+
40+
class BEEPTYPE(Enum):
41+
SHORT = 0
42+
LONG = 1
43+
ALARM = 2
44+
45+
def __init__(
46+
self,
47+
connection: Connection,
48+
logger: logging.Logger | None = None
49+
):
50+
super().__init__(connection, logger)
51+
self.settings: DNASettings = DNASettings(self)
3152

32-
class BEEP(Enum):
33-
OFF = 0
34-
MEDIUM = 1
35-
LOUD = 2
36-
3753
def setrequest(
3854
self,
3955
param: int,
4056
value: int
41-
) -> GsiOnlineResponse[bool | None]:
57+
) -> GsiOnlineResponse[bool]:
4258
cmd = f"SET/{param:d}/{value:d}"
59+
comment = ""
4360
try:
4461
answer = self._conn.exchange1(cmd)
45-
except:
62+
except Exception:
4663
self._logger.error(format_exc())
4764
answer = DNAErrors.E_UNKNOWN.value
48-
65+
comment = "EXCHANGE"
66+
4967
return GsiOnlineResponse(
5068
param_descriptions.get(param, ""),
5169
cmd,
5270
answer,
53-
answer == "?"
71+
answer == "?",
72+
comment
5473
)
5574

5675
def confrequest(
@@ -59,59 +78,105 @@ def confrequest(
5978
parser: Callable[[str], _T]
6079
) -> GsiOnlineResponse[_T | None]:
6180
cmd = f"CONF/{param:d}"
81+
comment = ""
6282
try:
6383
answer = self._conn.exchange1(cmd)
64-
except:
84+
except Exception:
6585
self._logger.error(format_exc())
6686
answer = DNAErrors.E_UNKNOWN.value
67-
87+
comment = "EXCHANGE"
88+
6889
success = bool(self._CONFPAT.match(answer))
90+
value = None
91+
if success:
92+
try:
93+
value = parser(answer.split("/")[1])
94+
except Exception:
95+
comment = "PARSE"
96+
else:
97+
comment = "INSTRUMENT"
98+
6999
return GsiOnlineResponse(
70100
param_descriptions.get(param, ""),
71101
cmd,
72102
answer,
73-
parser(answer.split("/")[1]) if success else None
103+
value,
104+
comment
74105
)
75106

76107
def putrequest(
77108
self,
78109
wordindex: int,
79110
word: str
80-
) -> GsiOnlineResponse[bool | None]:
111+
) -> GsiOnlineResponse[bool]:
81112
cmd = f"PUT/{word:s} "
82-
answer = self._conn.exchange1(cmd)
113+
comment = ""
114+
try:
115+
answer = self._conn.exchange1(cmd)
116+
except Exception:
117+
self._logger.error(format_exc())
118+
answer = DNAErrors.E_UNKNOWN.value
119+
comment = "failed to exchange messages"
120+
83121
return GsiOnlineResponse(
84-
param_descriptions.get(wordindex, ""),
122+
word_descriptions.get(wordindex, ""),
85123
cmd,
86124
answer,
87-
answer == "?"
125+
answer == "?",
126+
comment
88127
)
89-
128+
90129
def getrequest(
91130
self,
92131
mode: str,
93132
wordindex: int,
94133
parser: Callable[[str], _T]
95134
) -> GsiOnlineResponse[_T | None]:
96-
cmd = f"GET/{mode:s}/WI{wordindex:d} "
97-
answer = self._conn.exchange1(cmd)
98-
success = bool(self._CONFPAT.match(answer))
135+
cmd = f"GET/{mode:s}/WI{wordindex:d}"
136+
comment = ""
137+
try:
138+
answer = self._conn.exchange1(cmd)
139+
except Exception:
140+
self._logger.error(format_exc())
141+
answer = DNAErrors.E_UNKNOWN.value
142+
comment = "EXCHANGE"
143+
144+
success = bool(self._GSIPAT.match(answer))
145+
value = None
146+
if success:
147+
try:
148+
value = parser(answer)
149+
except Exception:
150+
comment = "PARSE"
151+
else:
152+
comment = "INSTRUMENT"
153+
99154
return GsiOnlineResponse(
100-
param_descriptions.get(wordindex, ""),
155+
word_descriptions.get(wordindex, ""),
101156
cmd,
102157
answer,
103-
parser(answer) if success else None
158+
value,
159+
comment
104160
)
105161

106-
def set_beep(
162+
def beep(
107163
self,
108-
status: BEEP | str
109-
) -> GsiOnlineResponse[bool | None]:
110-
_status = toenum(self.BEEP, status)
111-
return self.setrequest(30, _status.value)
112-
113-
def conf_beep(self) -> GsiOnlineResponse[BEEP | None]:
114-
return self.confrequest(
115-
30,
116-
enumparser(self.BEEP)
164+
beeptype: BEEPTYPE | str
165+
) -> GsiOnlineResponse[bool]:
166+
_beeptype = toenum(self.BEEPTYPE, beeptype)
167+
cmd = f"BEEP/{_beeptype.value:d}"
168+
comment = ""
169+
try:
170+
answer = self._conn.exchange1(cmd)
171+
except Exception:
172+
self._logger.error(format_exc())
173+
answer = DNAErrors.E_UNKNOWN.value
174+
comment = "EXCHANGE"
175+
176+
return GsiOnlineResponse(
177+
"Beep",
178+
cmd,
179+
answer,
180+
answer == "?",
181+
comment
117182
)

src/geocompy/dna/meta.py

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

55

66
param_descriptions: dict[int, str] = {
7-
30: "Beep",
7+
30: "Beep intensity",
88
31: "Display illumination",
99
32: "Display constrast",
1010
41: "Distance unit",

0 commit comments

Comments
 (0)