Loading noctua/config/constants.py +7 −5 Original line number Diff line number Diff line Loading @@ -11,6 +11,8 @@ lat = 44.5912 # [°] Latitude North from Greenwich. lon = 9.2034 # [°] Longitude East from Greenwich. alt = 1469 # [m] Altitude above sea level. none_val = 'unkn.' ############ # Dome ############ Loading @@ -31,7 +33,7 @@ open_state = { yes_no = { True: "Yes", False: "No", None: "N/A", None: none_val, } ############ Loading @@ -41,7 +43,7 @@ yes_no = { on_off = { True: "On", False: "Off", None: "N/A", None: none_val, } ############ Loading @@ -61,7 +63,7 @@ filter_state = { 0: "Idle", 1: "Moving", 2: "Error", None: "Off", None: none_val, } filter_name = { Loading @@ -74,7 +76,7 @@ filter_name = { 6: "FREE", 7: "SDSS u", 15: "Filter_error", None: "Off", None: none_val, } # Reversing filter_name Loading @@ -85,7 +87,7 @@ camera_state = { 2: "Exposing", 3: "Readout", 5: "Error", None: "Off", None: none_val, } # Reversing camera state Loading noctua/devices/astelco.py +22 −2 Original line number Diff line number Diff line Loading @@ -160,15 +160,26 @@ class OpenTSI(BaseDevice): str or float or int or None The value returned by the device, or None on error. """ cmd_id = self._get_cmd_id() commands = [(cmd_id, f"GET {message}")] res = self._send(commands) if self.error or not res: return None if res[cmd_id]["status"] != "ERROR": return res[cmd_id]["data"] data = res[cmd_id]["data"] # Catch "FAILED" string returned by OpenTSI despite non-ERROR status if isinstance(data, str) and "FAILED" in data: log.error(f"OpenTSI hardware failure detected on GET {message}: {data}") self.error.append(data) return None return data return None def put(self, key, val): Loading @@ -187,17 +198,26 @@ class OpenTSI(BaseDevice): bool True if the command was completed successfully, False otherwise. """ cmd_id = self._get_cmd_id() commands = [(cmd_id, f"SET {key}={val}")] res = self._send(commands) if self.error or not res: return False if res[cmd_id]["status"] == "COMPLETE": return True # Just in case SET returns a data payload containing FAILED data = res[cmd_id]["data"] if isinstance(data, str) and "FAILED" in data: log.error(f"OpenTSI hardware failure detected on SET {key}={val}: {data}") self.error.append(data) return False return True return False class Telescope(OpenTSI): """ Loading noctua/web/pages/base.html +8 −0 Original line number Diff line number Diff line Loading @@ -92,6 +92,13 @@ </a> </li> <li> <a class="nav-link {% if request.endpoint == 'web.webcam' %}active{% endif %}" href="{{ url_for('web.webcam') }}"> Webcam </a> </li> </ul> <!-- Logo grande, opzionale, visibile solo su schermi larghi --> Loading Loading @@ -130,6 +137,7 @@ </footer> <!-- ── Vendor scripts ─────────────────────────────────────────────────── --> <script type="module" src="{{ url_for('web.static', filename='js/ui-utils.js') }}"></script> <script src="{{ url_for('web.static', filename='js/vendor/bootstrap.bundle.min.js') }}"></script> <script src="{{ url_for('web.static', filename='js/vendor/ansi_up.js') }}"></script> Loading noctua/web/pages/subsystem.html +0 −75 Original line number Diff line number Diff line Loading @@ -11,85 +11,10 @@ {% if subsystem == 'telescope' %} <!-- Is Cab Switch On? --> {{ w.widget_toggle({ 'label': "Is Cab Switch On?", 'info': "/telescope/power", 'buttons': [{'label': "Power on/off", 'endpoint': "/telescope/power"}], 'extra_flags': True }) }} <!-- Is Tel Parked? --> {{ w.widget_toggle({ 'label': "Is Tel Parked?", 'info': "/telescope/coordinates/movement/atpark", 'buttons': [ {'label': "Unpark", 'endpoint': "/telescope/coordinates/movement/unpark", 'method': "POST"}, {'label': "Park", 'endpoint': "/telescope/coordinates/movement/park", 'method': "POST"} ], 'extra_flags': True }) }} <!-- Is Tel Tracking? --> {{ w.widget_toggle({ 'label': "Is Tel Tracking?", 'info': "/telescope/coordinates/tracking", 'buttons': [ {'label': "Point webcam", 'endpoint': "/telescope/coordinates/movement/altaz", 'val': [25, 85], 'method': "POST"}, {'label': "Track Polaris", 'endpoint': "/telescope/coordinates/movement/radec", 'val': "Polaris", 'method': "POST"} ], 'extra_flags': True }) }} <!-- Petals --> {{ w.widget_toggle({ 'label': "Petals", 'info': "/telescope/cover", 'buttons': [ {'label': "Open", 'endpoint': "/telescope/cover/movement", 'val': true, 'method': "POST"}, {'label': "Close", 'endpoint': "/telescope/cover/movement", 'val': false, 'method': "POST"} ], 'extra_flags': True }) }} {% elif subsystem == 'dome' %} <!-- Azimuth Control --> {{ w.widget_toggle({ 'label': "Dome Azimuth", 'info': "/dome/position", 'buttons': [ {'label': "Park", 'endpoint': "/dome/position/movement/park", 'method': "POST"}, {'label': "Stop", 'endpoint': "/dome/position/movement", 'method': "DELETE"} ], 'extra_flags': True, 'info_list': [ {'label': 'slaved', 'status': 'dome-position-slaved'}, {'label': 'az', 'status': 'dome-position-azimuth'} ] }) }} <!-- Shutter --> {{ w.widget_toggle({ 'label': "Shutter", 'info': "/dome/shutter", 'buttons': [ {'label': "Open", 'endpoint': "/dome/shutter/movement", 'val': true, 'method': "POST"}, {'label': "Close", 'endpoint': "/dome/shutter/movement", 'val': false, 'method': "POST"} ], 'extra_flags': True }) }} {% elif subsystem == 'camera' %} <!-- Is Cam Switch On? --> {{ w.widget_toggle({ 'label': "Is Cam Switch On?", 'info': "/camera/power", 'buttons': [{'label': "Power", 'endpoint': "/camera/power"}], 'extra_flags': True }) }} {% else %} <!-- Fallback list for generic subsystems --> <div class="alert alert-info">Generic monitor for unknown subsystem.</div> Loading noctua/web/static/img/synoptic.svg +12 −12 Original line number Diff line number Diff line Loading @@ -23,15 +23,15 @@ inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" inkscape:zoom="3.95" inkscape:cx="200.37975" inkscape:cy="213.16456" inkscape:zoom="2.7930718" inkscape:cx="138.37811" inkscape:cy="197.9899" inkscape:window-width="2511" inkscape:window-height="1371" inkscape:window-x="26" inkscape:window-y="23" inkscape:window-maximized="0" inkscape:current-layer="noctua-synoptic" /><defs inkscape:current-layer="beams" /><defs id="defs2"> Loading Loading @@ -658,22 +658,22 @@ inkscape:groupmode="layer" id="beams" inkscape:label="beams"><path id="beam-photometry" id="structure-beam-incoming" style="fill:none;stroke:#37c8ab;stroke-width:1px" d="m 200.55953,215.34038 -60.48559,-62.72949 h -34.3242" sodipodi:nodetypes="ccc" /><path id="structure-beam-photometry" style="fill:none;stroke:#37c8ab;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="m 202.22718,216.19623 43.3783,43.92979 m 23.12946,22.95946 7.91835,9.30074 m 37.69479,10.90406 34.60451,-0.0996 m -75.69139,-15.59218 24.38124,-24.04571 57.62634,0.0633" sodipodi:nodetypes="ccccccccc" /><path id="beam-spectroscopy" id="structure-beam-spectroscopy" style="display:inline;fill:none;stroke:#37c8ab;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="m 200.55953,216.46393 -84.48558,84.72949 h -66.3242 m 103.4728,-37.30999 -45.85232,3e-5 -67.852326,10e-6" sodipodi:nodetypes="cccccc" /><path id="beam-echelle" id="structure-beam-echelle" style="display:inline;fill:none;stroke:#37c8ab;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="m 203.17512,214.14623 84.48557,-84.72949 66.3242,-2e-5 m -103.4728,37.31002 45.85233,-3e-5 47.85234,-1e-5" sodipodi:nodetypes="cccccc" /><path id="beam-incoming" style="fill:none;stroke:#37c8ab;stroke-width:1px" d="m 200.55953,215.34038 -60.48559,-62.72949 h -34.3242" sodipodi:nodetypes="ccc" /></g><path sodipodi:nodetypes="cccccc" /></g><path id="telemetry:dome:light:indicator" style="fill:#008080;fill-opacity:0.298039;stroke:#cccccc;stroke-width:0.999998;stroke-dasharray:none" d="m 197.14131,44.062272 c 0.0241,0.729645 -0.7628,3.424269 -2.9302,3.424269 -2.1674,0 -2.9302,-2.49921 -2.9302,-3.424269 z m 3.90751,-10.42066 c 1e-4,-0.907814 -0.1805,-1.806613 -0.53144,-2.643868 -0.35094,-0.837246 -0.86499,-1.596196 -1.51237,-2.232645 -0.64738,-0.636439 -1.41499,-1.13759 -2.25811,-1.474211 -0.84301,-0.336631 -1.74473,-0.501963 -2.65241,-0.486403 -1.74249,0.05182 -3.40159,0.757963 -4.64688,1.977902 -1.24529,1.219949 -1.98543,2.86419 -2.07305,4.605265 -0.0417,1.161813 0.21363,2.315042 0.74173,3.350769 0.5281,1.035629 1.31158,1.919572 2.27636,2.56822 0.27192,0.176789 0.49553,0.418432 0.6507,0.70315 0.15518,0.284815 0.23703,0.603718 0.23814,0.927993 v 1.494401 h 5.8604 v -1.494401 c 0,-0.323396 0.0804,-0.641713 0.23383,-0.92643 0.15345,-0.284718 0.37517,-0.52685 0.64523,-0.704713 0.93005,-0.624034 1.69268,-1.467052 2.2206,-2.454822 0.52803,-0.987769 0.80522,-2.090207 0.80727,-3.210207 z" /><path Loading Loading
noctua/config/constants.py +7 −5 Original line number Diff line number Diff line Loading @@ -11,6 +11,8 @@ lat = 44.5912 # [°] Latitude North from Greenwich. lon = 9.2034 # [°] Longitude East from Greenwich. alt = 1469 # [m] Altitude above sea level. none_val = 'unkn.' ############ # Dome ############ Loading @@ -31,7 +33,7 @@ open_state = { yes_no = { True: "Yes", False: "No", None: "N/A", None: none_val, } ############ Loading @@ -41,7 +43,7 @@ yes_no = { on_off = { True: "On", False: "Off", None: "N/A", None: none_val, } ############ Loading @@ -61,7 +63,7 @@ filter_state = { 0: "Idle", 1: "Moving", 2: "Error", None: "Off", None: none_val, } filter_name = { Loading @@ -74,7 +76,7 @@ filter_name = { 6: "FREE", 7: "SDSS u", 15: "Filter_error", None: "Off", None: none_val, } # Reversing filter_name Loading @@ -85,7 +87,7 @@ camera_state = { 2: "Exposing", 3: "Readout", 5: "Error", None: "Off", None: none_val, } # Reversing camera state Loading
noctua/devices/astelco.py +22 −2 Original line number Diff line number Diff line Loading @@ -160,15 +160,26 @@ class OpenTSI(BaseDevice): str or float or int or None The value returned by the device, or None on error. """ cmd_id = self._get_cmd_id() commands = [(cmd_id, f"GET {message}")] res = self._send(commands) if self.error or not res: return None if res[cmd_id]["status"] != "ERROR": return res[cmd_id]["data"] data = res[cmd_id]["data"] # Catch "FAILED" string returned by OpenTSI despite non-ERROR status if isinstance(data, str) and "FAILED" in data: log.error(f"OpenTSI hardware failure detected on GET {message}: {data}") self.error.append(data) return None return data return None def put(self, key, val): Loading @@ -187,17 +198,26 @@ class OpenTSI(BaseDevice): bool True if the command was completed successfully, False otherwise. """ cmd_id = self._get_cmd_id() commands = [(cmd_id, f"SET {key}={val}")] res = self._send(commands) if self.error or not res: return False if res[cmd_id]["status"] == "COMPLETE": return True # Just in case SET returns a data payload containing FAILED data = res[cmd_id]["data"] if isinstance(data, str) and "FAILED" in data: log.error(f"OpenTSI hardware failure detected on SET {key}={val}: {data}") self.error.append(data) return False return True return False class Telescope(OpenTSI): """ Loading
noctua/web/pages/base.html +8 −0 Original line number Diff line number Diff line Loading @@ -92,6 +92,13 @@ </a> </li> <li> <a class="nav-link {% if request.endpoint == 'web.webcam' %}active{% endif %}" href="{{ url_for('web.webcam') }}"> Webcam </a> </li> </ul> <!-- Logo grande, opzionale, visibile solo su schermi larghi --> Loading Loading @@ -130,6 +137,7 @@ </footer> <!-- ── Vendor scripts ─────────────────────────────────────────────────── --> <script type="module" src="{{ url_for('web.static', filename='js/ui-utils.js') }}"></script> <script src="{{ url_for('web.static', filename='js/vendor/bootstrap.bundle.min.js') }}"></script> <script src="{{ url_for('web.static', filename='js/vendor/ansi_up.js') }}"></script> Loading
noctua/web/pages/subsystem.html +0 −75 Original line number Diff line number Diff line Loading @@ -11,85 +11,10 @@ {% if subsystem == 'telescope' %} <!-- Is Cab Switch On? --> {{ w.widget_toggle({ 'label': "Is Cab Switch On?", 'info': "/telescope/power", 'buttons': [{'label': "Power on/off", 'endpoint': "/telescope/power"}], 'extra_flags': True }) }} <!-- Is Tel Parked? --> {{ w.widget_toggle({ 'label': "Is Tel Parked?", 'info': "/telescope/coordinates/movement/atpark", 'buttons': [ {'label': "Unpark", 'endpoint': "/telescope/coordinates/movement/unpark", 'method': "POST"}, {'label': "Park", 'endpoint': "/telescope/coordinates/movement/park", 'method': "POST"} ], 'extra_flags': True }) }} <!-- Is Tel Tracking? --> {{ w.widget_toggle({ 'label': "Is Tel Tracking?", 'info': "/telescope/coordinates/tracking", 'buttons': [ {'label': "Point webcam", 'endpoint': "/telescope/coordinates/movement/altaz", 'val': [25, 85], 'method': "POST"}, {'label': "Track Polaris", 'endpoint': "/telescope/coordinates/movement/radec", 'val': "Polaris", 'method': "POST"} ], 'extra_flags': True }) }} <!-- Petals --> {{ w.widget_toggle({ 'label': "Petals", 'info': "/telescope/cover", 'buttons': [ {'label': "Open", 'endpoint': "/telescope/cover/movement", 'val': true, 'method': "POST"}, {'label': "Close", 'endpoint': "/telescope/cover/movement", 'val': false, 'method': "POST"} ], 'extra_flags': True }) }} {% elif subsystem == 'dome' %} <!-- Azimuth Control --> {{ w.widget_toggle({ 'label': "Dome Azimuth", 'info': "/dome/position", 'buttons': [ {'label': "Park", 'endpoint': "/dome/position/movement/park", 'method': "POST"}, {'label': "Stop", 'endpoint': "/dome/position/movement", 'method': "DELETE"} ], 'extra_flags': True, 'info_list': [ {'label': 'slaved', 'status': 'dome-position-slaved'}, {'label': 'az', 'status': 'dome-position-azimuth'} ] }) }} <!-- Shutter --> {{ w.widget_toggle({ 'label': "Shutter", 'info': "/dome/shutter", 'buttons': [ {'label': "Open", 'endpoint': "/dome/shutter/movement", 'val': true, 'method': "POST"}, {'label': "Close", 'endpoint': "/dome/shutter/movement", 'val': false, 'method': "POST"} ], 'extra_flags': True }) }} {% elif subsystem == 'camera' %} <!-- Is Cam Switch On? --> {{ w.widget_toggle({ 'label': "Is Cam Switch On?", 'info': "/camera/power", 'buttons': [{'label': "Power", 'endpoint': "/camera/power"}], 'extra_flags': True }) }} {% else %} <!-- Fallback list for generic subsystems --> <div class="alert alert-info">Generic monitor for unknown subsystem.</div> Loading
noctua/web/static/img/synoptic.svg +12 −12 Original line number Diff line number Diff line Loading @@ -23,15 +23,15 @@ inkscape:pageopacity="0.0" inkscape:pagecheckerboard="0" inkscape:deskcolor="#d1d1d1" inkscape:zoom="3.95" inkscape:cx="200.37975" inkscape:cy="213.16456" inkscape:zoom="2.7930718" inkscape:cx="138.37811" inkscape:cy="197.9899" inkscape:window-width="2511" inkscape:window-height="1371" inkscape:window-x="26" inkscape:window-y="23" inkscape:window-maximized="0" inkscape:current-layer="noctua-synoptic" /><defs inkscape:current-layer="beams" /><defs id="defs2"> Loading Loading @@ -658,22 +658,22 @@ inkscape:groupmode="layer" id="beams" inkscape:label="beams"><path id="beam-photometry" id="structure-beam-incoming" style="fill:none;stroke:#37c8ab;stroke-width:1px" d="m 200.55953,215.34038 -60.48559,-62.72949 h -34.3242" sodipodi:nodetypes="ccc" /><path id="structure-beam-photometry" style="fill:none;stroke:#37c8ab;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="m 202.22718,216.19623 43.3783,43.92979 m 23.12946,22.95946 7.91835,9.30074 m 37.69479,10.90406 34.60451,-0.0996 m -75.69139,-15.59218 24.38124,-24.04571 57.62634,0.0633" sodipodi:nodetypes="ccccccccc" /><path id="beam-spectroscopy" id="structure-beam-spectroscopy" style="display:inline;fill:none;stroke:#37c8ab;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="m 200.55953,216.46393 -84.48558,84.72949 h -66.3242 m 103.4728,-37.30999 -45.85232,3e-5 -67.852326,10e-6" sodipodi:nodetypes="cccccc" /><path id="beam-echelle" id="structure-beam-echelle" style="display:inline;fill:none;stroke:#37c8ab;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="m 203.17512,214.14623 84.48557,-84.72949 66.3242,-2e-5 m -103.4728,37.31002 45.85233,-3e-5 47.85234,-1e-5" sodipodi:nodetypes="cccccc" /><path id="beam-incoming" style="fill:none;stroke:#37c8ab;stroke-width:1px" d="m 200.55953,215.34038 -60.48559,-62.72949 h -34.3242" sodipodi:nodetypes="ccc" /></g><path sodipodi:nodetypes="cccccc" /></g><path id="telemetry:dome:light:indicator" style="fill:#008080;fill-opacity:0.298039;stroke:#cccccc;stroke-width:0.999998;stroke-dasharray:none" d="m 197.14131,44.062272 c 0.0241,0.729645 -0.7628,3.424269 -2.9302,3.424269 -2.1674,0 -2.9302,-2.49921 -2.9302,-3.424269 z m 3.90751,-10.42066 c 1e-4,-0.907814 -0.1805,-1.806613 -0.53144,-2.643868 -0.35094,-0.837246 -0.86499,-1.596196 -1.51237,-2.232645 -0.64738,-0.636439 -1.41499,-1.13759 -2.25811,-1.474211 -0.84301,-0.336631 -1.74473,-0.501963 -2.65241,-0.486403 -1.74249,0.05182 -3.40159,0.757963 -4.64688,1.977902 -1.24529,1.219949 -1.98543,2.86419 -2.07305,4.605265 -0.0417,1.161813 0.21363,2.315042 0.74173,3.350769 0.5281,1.035629 1.31158,1.919572 2.27636,2.56822 0.27192,0.176789 0.49553,0.418432 0.6507,0.70315 0.15518,0.284815 0.23703,0.603718 0.23814,0.927993 v 1.494401 h 5.8604 v -1.494401 c 0,-0.323396 0.0804,-0.641713 0.23383,-0.92643 0.15345,-0.284718 0.37517,-0.52685 0.64523,-0.704713 0.93005,-0.624034 1.69268,-1.467052 2.2206,-2.454822 0.52803,-0.987769 0.80522,-2.090207 0.80727,-3.210207 z" /><path Loading