File indexing completed on 2024-04-28 03:43:40

0001 /*  Ekos Observatory Module
0002     SPDX-FileCopyrightText: Wolfgang Reissenberger <sterne-jaeger@t-online.de>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include "ui_observatory.h"
0010 
0011 #include "indi/indidome.h"
0012 #include "indi/indiweather.h"
0013 
0014 #include <QWidget>
0015 #include <QLineEdit>
0016 #include <KLocalizedString>
0017 
0018 namespace Ekos
0019 {
0020 
0021 struct ObservatoryStatusControl
0022 {
0023     bool useDome, useShutter, useWeather;
0024 };
0025 
0026 struct WeatherActions
0027 {
0028     bool parkDome, closeShutter, stopScheduler;
0029     uint delay;
0030 };
0031 
0032 
0033 class Observatory : public QWidget, public Ui::Observatory
0034 {
0035         Q_OBJECT
0036         Q_CLASSINFO("D-Bus Interface", "org.kde.kstars.Ekos.Observatory")
0037         Q_PROPERTY(QStringList logText READ logText NOTIFY newLog)
0038 
0039     public:
0040         Observatory();
0041 
0042         bool setDome(ISD::Dome *device);
0043         bool addWeatherSource(ISD::Weather *device);
0044 
0045         // Logging
0046         QStringList logText()
0047         {
0048             return m_LogText;
0049         }
0050         QString getLogText()
0051         {
0052             return m_LogText.join("\n");
0053         }
0054 
0055         void clearLog();
0056 
0057         /**
0058          * @brief Retrieve the settings that define, from which states the
0059          * "ready" state of the observatory is derived from.
0060          */
0061         ObservatoryStatusControl statusControl()
0062         {
0063             return m_StatusControl;
0064         }
0065         void setStatusControl(ObservatoryStatusControl control);
0066         void removeDevice(const QSharedPointer<ISD::GenericDevice> &deviceRemoved);
0067         void setWeatherSource(const QString &name);
0068 
0069 
0070     signals:
0071         Q_SCRIPTABLE void newLog(const QString &text);
0072 
0073         void newWeatherData(const QJsonArray &data);
0074 
0075     private:
0076         // motion control
0077         void enableMotionControl(bool enabled);
0078 
0079         // slaving control
0080         void enableAutoSync(bool enabled);
0081         void showAutoSync(bool enabled);
0082 
0083         // Logging
0084         QStringList m_LogText;
0085         void appendLogText(const QString &);
0086 
0087         // timer for refreshing the observatory status
0088         QTimer weatherStatusTimer;
0089 
0090         // reacting on weather changes
0091         void setWarningActions(WeatherActions actions);
0092         void setAlertActions(WeatherActions actions);
0093 
0094         // button handling
0095         void toggleButtons(QPushButton *buttonPressed, QString titlePressed, QPushButton *buttonCounterpart,
0096                            QString titleCounterpart);
0097         void activateButton(QPushButton *button, QString title);
0098         void buttonPressed(QPushButton *button, QString title);
0099 
0100         // weather sensor data
0101         QGridLayout* sensorDataBoxLayout;
0102         // map id -> (label, widget)
0103         std::map<QString, QPair<QAbstractButton*, QLineEdit*>*> sensorDataWidgets = {};
0104         // map id -> graph key x value vector
0105         std::map<QString, QVector<QCPGraphData>*> sensorGraphData = {};
0106 
0107         // map id -> range (+1: values only > 0, 0: values > 0 and < 0; -1: values < 0)
0108         std::map<QString, int> sensorRanges = {};
0109 
0110         // selected sensor for graph display
0111         QString selectedSensorID;
0112 
0113         // button group for sensor names to ensure, that only one button is pressed
0114         QButtonGroup *sensorDataNamesGroup {nullptr};
0115 
0116         ISD::Weather::Status m_WeatherStatus { ISD::Weather::WEATHER_IDLE };
0117 
0118         // Initialize the UI controls that configure reactions upon weather events
0119         void initWeatherActions(bool enabled);
0120 
0121         void initSensorGraphs();
0122         void updateSensorData(const QJsonArray &data);
0123         void updateSensorGraph(const QString &sensor_label, QDateTime now, double value);
0124 
0125         // hold all sensor data received from the weather station
0126         QJsonArray m_WeatherData;
0127         void weatherChanged(ISD::Weather::Status status);
0128 
0129         /**
0130          * @brief Activate or deactivate the weather warning actions
0131          */
0132         void setWarningActionsActive(bool active);
0133         /**
0134          * @brief Activate or deactivate the weather alert actions
0135          */
0136         void setAlertActionsActive(bool active);
0137 
0138         /**
0139          * @brief Flag whether the X axis should be visible in the sensor graph
0140          */
0141         bool autoScaleValues()
0142         {
0143             return m_autoScaleValues;
0144         }
0145         void setAutoScaleValues(bool show);
0146 
0147     private:
0148         // observatory status handling
0149         //void setObseratoryStatusControl(ObservatoryStatusControl control);
0150         void statusControlSettingsChanged();
0151 
0152         void initWeather();
0153         void enableWeather(bool enable);
0154         void clearSensorDataHistory();
0155         void shutdownWeather();
0156         void setWeatherStatus(ISD::Weather::Status status);
0157 
0158         // sensor data graphs
0159         void mouseOverLine(QMouseEvent *event);
0160         void refreshSensorGraph();
0161 
0162         void execute(WeatherActions actions);
0163 
0164         // reacting on weather changes
0165         void weatherWarningSettingsChanged();
0166         void weatherAlertSettingsChanged();
0167 
0168         // reacting on sensor selection change
0169         void selectedSensorChanged(QString id);
0170 
0171         // reacting on observatory status changes
0172         void observatoryStatusChanged(bool ready);
0173         void domeAzimuthChanged(double position);
0174 
0175         void shutdownDome();
0176 
0177         void setDomeStatus(ISD::Dome::Status status);
0178         void setDomeParkStatus(ISD::ParkStatus status);
0179         void setShutterStatus(ISD::Dome::ShutterStatus status);
0180 
0181         /**
0182          * @brief Actions to be taken when a weather warning occurs
0183          */
0184         WeatherActions getWarningActions()
0185         {
0186             return m_WarningActions;
0187         }
0188         QString getWarningActionsStatus();
0189         bool getWarningActionsActive()
0190         {
0191             return warningActionsActive;
0192         }
0193 
0194         /**
0195          * @brief Actions to be taken when a weather alert occurs
0196          */
0197         WeatherActions getAlertActions()
0198         {
0199             return m_AlertActions;
0200         }
0201         QString getAlertActionsStatus();
0202         bool getAlertActionsActive()
0203         {
0204             return alertActionsActive;
0205         }
0206 
0207     private:
0208         ISD::Dome *m_Dome {nullptr};
0209         ISD::Weather *m_WeatherSource {nullptr};
0210         QList<ISD::Weather *> m_WeatherSources;
0211 
0212         ObservatoryStatusControl m_StatusControl;
0213 
0214         QTimer warningTimer, alertTimer;
0215         struct WeatherActions m_WarningActions, m_AlertActions;
0216         bool warningActionsActive, alertActionsActive, m_autoScaleValues;
0217         void startAlertTimer();
0218         void startWarningTimer();
0219 };
0220 }