Files
grossanzeige/coords.py
T
admin d8a9953b73 Niedrig-/Hochpraezision der Montierung + IP eingetragen
Die GM4000 laeuft in Niedrigpraezision (keine Sekunden): RA HH:MM.T,
DEC sDD°MM. Anzeige daran angepasst:
- config.HIGH_PRECISION (Vorgabe False) steuert die DEC-Darstellung:
  False -> ohne Sekunden (-00°55'), True -> mit Sekunden (+38°47'01)
- RA immer mit Sekunden (11h36m54s); bei Niedrigpraezision aus den
  Zehntel-Minuten abgeleitet (6-Sekunden-Schritte), kein Dezimalpunkt
  (der wirkt in der Sperrschrift zu luftig)
- coords.format_ra/format_dec nehmen high_precision=
- MOUNT_HOST auf die echte IP (192.168.1.115)

Hinweis: Das 'ß' in der Konsole ist nur der Rohwert (Grad-Byte 0xDF);
auf der Anzeige erscheint korrekt der Gradring.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-18 23:07:22 +02:00

116 lines
4.2 KiB
Python

"""Rektaszension und Deklination einlesen und fuer die Anzeige formatieren.
Die Eingabe ist bewusst tolerant, damit man beim Testen nicht auf ein Format
festgelegt ist: 12h34m56s | 12:34:56 | "12 34 56" | 12.5824 (Stunden dezimal)
Bei der Deklination entsprechend mit Vorzeichen und Grad/Bogenminuten.
Ausgegeben wird die breiteste Schreibweise, die noch in die Zeile passt --
die tatsaechliche Zeichenbreite der Anzeige kennen wir erst nach dem Livetest.
"""
import config
_SEPARATORS = "hHmMsSdD°'\"::,"
def _split(value):
"""Zahlenfelder aus einer Koordinatenangabe holen, Trennzeichen egal."""
out, cur = [], ""
for ch in str(value).strip():
if ch.isdigit() or ch == ".":
cur += ch
elif ch in "+-" and not cur and not out:
cur += ch
else:
if cur:
out.append(cur)
cur = ""
if cur:
out.append(cur)
if not out:
raise ValueError("keine Zahlen in %r gefunden" % (value,))
return out
def _to_sexagesimal(value, unit_max, name):
"""Eingabe in (Vorzeichen, Ganzteil, Minuten, Sekunden) zerlegen."""
fields = _split(value)
negative = fields[0].startswith("-")
fields[0] = fields[0].lstrip("+-")
if len(fields) == 1: # dezimal, z.B. 12.5824
total = float(fields[0]) * 3600.0
else:
parts = [float(f) for f in fields[:3]] + [0.0] * (3 - len(fields[:3]))
total = parts[0] * 3600.0 + parts[1] * 60.0 + parts[2]
total = int(round(total))
big, rest = divmod(total, 3600)
minutes, seconds = divmod(rest, 60)
if big >= unit_max:
raise ValueError("%s: %s ausserhalb des gueltigen Bereichs" % (name, value))
return negative, big, minutes, seconds
def parse_ra(value):
"""Rektaszension -> (Stunden, Minuten, Sekunden)."""
_, h, m, s = _to_sexagesimal(value, 24, "Rektaszension")
return h, m, s
def parse_dec(value):
"""Deklination -> (Vorzeichen als '+'/'-', Grad, Bogenminuten, Bogensekunden)."""
neg, d, m, s = _to_sexagesimal(value, 91, "Deklination")
if d > 90 or (d == 90 and (m or s)):
raise ValueError("Deklination %s liegt ausserhalb +/-90 Grad" % (value,))
return ("-" if neg else "+"), d, m, s
def _fit(candidates, width):
"""Erste Schreibweise nehmen, die in die Zeile passt; sonst die kuerzeste."""
for text in candidates:
if len(text) <= width:
return text
return candidates[-1][:width]
def format_ra(value, width=None, high_precision=None):
"""Rektaszension formatieren, immer mit Sekunden (HHhMMmSSs).
Bei Niedrigpraezision liefert die Montierung nur Zehntel-Minuten; die
Sekunden kommen dann in 6-Sekunden-Schritten. Das Format ist dasselbe wie
bei Hochpraezision -- der Unterschied steckt allein in der Aufloesung der
Rohdaten, nicht in der Darstellung. high_precision wird daher fuer RA nicht
ausgewertet (nur bei DEC relevant, siehe format_dec).
"""
width = config.CHARS_PER_LINE if width is None else width
h, m, s = parse_ra(value)
return _fit([
"%02dh%02dm%02ds" % (h, m, s),
"%02d:%02d:%02d" % (h, m, s),
"%02dh%02dm" % (h, m),
], width)
def format_dec(value, width=None, high_precision=None):
width = config.CHARS_PER_LINE if width is None else width
high = config.HIGH_PRECISION if high_precision is None else high_precision
sign, d, m, s = parse_dec(value)
deg = config.DEGREE_MARKER
if high:
candidates = [
"%s%02d%s%02d'%02d\"" % (sign, d, deg, m, s), # 10: mit Bogensekundenzeichen
"%s%02d%s%02d'%02d" % (sign, d, deg, m, s), # 9: Gradzeichen, ohne " am Ende
"%s%02d:%02d:%02d" % (sign, d, m, s), # 9: Doppelpunkte
"%s%02d%s%02d'" % (sign, d, deg, m), # 7: ohne Bogensekunden
"%s%02d:%02d" % (sign, d, m), # 6
]
else:
# Niedrigpraezision: ohne Sekunden (die Montierung liefert nur sDD MM).
candidates = [
"%s%02d%s%02d'" % (sign, d, deg, m), # 7: -00°55'
"%s%02d:%02d" % (sign, d, m), # 6: -00:55
]
return _fit(candidates, width)