Warning, file /education/kstars/kstars/ekos/manager.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2012 Jasem Mutlaq <mutlaqja@ikarustech.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #ifdef USE_QT5_INDI 0010 #include <baseclientqt.h> 0011 #else 0012 #include <baseclient.h> 0013 #endif 0014 0015 #include "ui_manager.h" 0016 0017 #include "ekos.h" 0018 #include "fitsviewer/summaryfitsview.h" 0019 #include "indi/indistd.h" 0020 #include "auxiliary/portselector.h" 0021 #include "ksnotification.h" 0022 #include "auxiliary/opslogs.h" 0023 0024 #include <QDialog> 0025 #include <QHash> 0026 #include <QtDBus/QtDBus> 0027 0028 #include <memory> 0029 0030 //! Generic record interfaces and implementations. 0031 namespace EkosLive 0032 { 0033 class Client; 0034 class Message; 0035 class Media; 0036 } 0037 0038 class DriverInfo; 0039 class ProfileInfo; 0040 class KPageWidgetItem; 0041 class OpsEkos; 0042 0043 /** 0044 * @class Manager 0045 * @short Primary class to handle all Ekos modules. 0046 * The Ekos Manager class manages startup and shutdown of INDI devices and registeration of devices within Ekos Modules. Ekos module consist of \ref Ekos::Mount, \ref Ekos::Capture, \ref Ekos::Focus, \ref Ekos::Guide, and \ref Ekos::Align modules. 0047 * \defgroup EkosDBusInterface "Ekos DBus Interface" provides high level functions to control devices and Ekos modules for a total robotic operation: 0048 * <ul> 0049 * <li>\ref CaptureDBusInterface "Capture Module DBus Interface"</li> 0050 * <li>\ref FocusDBusInterface "Focus Module DBus Interface"</li> 0051 * <li>\ref MountDBusInterface "Mount Module DBus Interface"</li> 0052 * <li>\ref GuideDBusInterface "Guide Module DBus Interface"</li> 0053 * <li>\ref AlignDBusInterface "Align Module DBus Interface"</li> 0054 * <li>\ref WeatherDBusInterface "Weather DBus Interface"</li> 0055 * <li>\ref DustCapDBusInterface "Dust Cap DBus Interface"</li> 0056 * </ul> 0057 * For low level access to INDI devices, the \ref INDIDBusInterface "INDI Dbus Interface" provides complete access to INDI devices and properties. 0058 * Ekos Manager provides a summary of operations progress in the <i>Summary</i> section of the <i>Setup</i> tab. 0059 * 0060 * @author Jasem Mutlaq 0061 * @version 1.8 0062 */ 0063 namespace Ekos 0064 { 0065 0066 class Analyze; 0067 class Capture; 0068 class Scheduler; 0069 class Focus; 0070 class Align; 0071 class Guide; 0072 class Mount; 0073 class Observatory; 0074 0075 class Manager : public QDialog, public Ui::Manager 0076 { 0077 Q_OBJECT 0078 Q_CLASSINFO("D-Bus Interface", "org.kde.kstars.Ekos") 0079 0080 Q_SCRIPTABLE Q_PROPERTY(Ekos::CommunicationStatus indiStatus READ indiStatus NOTIFY indiStatusChanged) 0081 Q_SCRIPTABLE Q_PROPERTY(Ekos::CommunicationStatus ekosStatus READ ekosStatus NOTIFY ekosStatusChanged) 0082 Q_SCRIPTABLE Q_PROPERTY(Ekos::CommunicationStatus settleStatus READ settleStatus NOTIFY settleStatusChanged) 0083 Q_SCRIPTABLE Q_PROPERTY(bool ekosLiveStatus READ ekosLiveStatus NOTIFY ekosLiveStatusChanged) 0084 Q_SCRIPTABLE Q_PROPERTY(QStringList logText READ logText NOTIFY newLog) 0085 0086 enum class EkosModule 0087 { 0088 Setup, 0089 Scheduler, 0090 Analyze, 0091 Capture, 0092 Focus, 0093 Mount, 0094 Align, 0095 Guide, 0096 Observatory, 0097 }; 0098 public: 0099 static Manager *Instance(); 0100 static void release(); 0101 0102 // No OP 0103 void initialize() {} 0104 0105 void appendLogText(const QString &); 0106 void setOptionsWidget(KPageWidgetItem *ops, OpsEkos *opsEkosPtr) 0107 { 0108 ekosOptionsWidget = ops; 0109 opsEkos = opsEkosPtr; 0110 } 0111 void addObjectToScheduler(SkyObject *object); 0112 0113 Scheduler *schedulerModule() 0114 { 0115 return schedulerProcess.get(); 0116 } 0117 Guide *guideModule() 0118 { 0119 return guideProcess.get(); 0120 } 0121 Align *alignModule() 0122 { 0123 return alignProcess.get(); 0124 } 0125 Mount *mountModule() 0126 { 0127 return mountProcess.get(); 0128 } 0129 Focus *focusModule() 0130 { 0131 return focusProcess.get(); 0132 } 0133 Capture *captureModule() 0134 { 0135 return captureProcess.get(); 0136 } 0137 FITSView *getSummaryPreview() 0138 { 0139 return m_SummaryView.get(); 0140 } 0141 0142 // Filter Manager 0143 void createFilterManager(ISD::FilterWheel *device); 0144 bool getFilterManager(const QString &name, QSharedPointer<FilterManager> &fm); 0145 0146 QString getCurrentJobName(); 0147 void announceEvent(const QString &message, KSNotification::EventSource source, KSNotification::EventType event); 0148 0149 /** 0150 * @brief activateModule Switch tab to specific module name (i.e. CCD) and raise Ekos screen to focus. 0151 * @param name module name CCD, Guide, Focus, Mount, Scheduler, or Observatory. 0152 * @param popup if True, show Ekos Manager window in the foreground. 0153 */ 0154 void activateModule(const QString &name, bool popup = false); 0155 0156 /** 0157 * @brief addProfile Add a new profile to the database. 0158 * @param profileInfo Collection of profile parameters to include the following: 0159 * 1. name: Profile name 0160 * 2. auto_connect: True of False for Autoconnect? 0161 * 3. Mode: "local" or "remote" 0162 * 4. remote_host: Optional. remote host (default localhost) 0163 * 5. remote_port: Optional. remote port (default 7624) 0164 * 6. guiding: 0 for "Internal", 1 for "PHD2", or 2 for "LinGuider" 0165 * 7. remote_guiding_host: Optional. remote host for guider application (default localhost) 0166 * 8. remote_guide_port: Optional. remote port for guider application. 0167 * 9. use_web_manager: True or False? 0168 * 10. web_manager_port. Optional. INDI Web Manager port (default 8624) 0169 * 12. primary_scope: ID of primary scope to use. This is the ID from OAL::Scope list in the database. 0170 * 13. guide_scope: ID of guide scope to use. This is the ID from OAL::Scope list in the database. 0171 * 14. mount: Mount driver label (default --). 0172 * 15. ccd: CCD driver label (default --). 0173 * 16. guider: Guider driver label (default --). 0174 * 17. focuser: Focuser driver label (default --). 0175 * 18. filter: Filter Wheel driver label (default --). 0176 * 19. ao: Adaptive Optics driver label (default --). 0177 * 20. dome: Dome driver label (default --). 0178 * 21. Weather: Weather station driver label (default --). 0179 * 22. aux1: aux1 driver label (default --). 0180 * 23. aux2: aux2 driver label (default --). 0181 * 24. aux3: aux3 driver label (default --). 0182 * 25. aux4: aux4 driver label (default --). 0183 */ 0184 void addNamedProfile(const QJsonObject &profileInfo); 0185 0186 /** Same as above, except it edits an existing named profile */ 0187 void editNamedProfile(const QJsonObject &profileInfo); 0188 0189 /** 0190 * @brief deleteProfile Delete existing equipment profile 0191 * @param name Name of profile 0192 * @warning Ekos must be stopped for this to work. It will fail if Ekos is online. 0193 */ 0194 void deleteNamedProfile(const QString &name); 0195 0196 /** 0197 * @brief getProfile Get a single profile information. 0198 * @param name Profile name 0199 * @return A JSon object with the detail profile info as described in addProfile function. 0200 */ 0201 QJsonObject getNamedProfile(const QString &name); 0202 0203 /** 0204 * DBus commands to manage equipment profiles. 0205 */ 0206 0207 /*@{*/ 0208 0209 /** 0210 * DBUS interface function. 0211 * set Current device profile. 0212 * @param profileName Profile name 0213 * @return True if profile is set, false if not found. 0214 */ 0215 Q_SCRIPTABLE bool setProfile(const QString &profileName); 0216 0217 /** 0218 * DBUS interface function 0219 * @brief getProfiles Return a list of all device profiles 0220 * @return List of device profiles 0221 */ 0222 Q_SCRIPTABLE QStringList getProfiles(); 0223 0224 /** @}*/ 0225 0226 0227 /** 0228 * Manager interface provides advanced scripting capabilities to establish and shutdown Ekos services. 0229 */ 0230 0231 /*@{*/ 0232 0233 /** 0234 * DBUS interface function. 0235 * @return INDI connection status (0 Idle, 1 Pending, 2 Connected, 3 Error) 0236 * @deprecated 0237 */ 0238 Q_SCRIPTABLE unsigned int getINDIConnectionStatus() 0239 { 0240 return m_indiStatus; 0241 } 0242 0243 Q_SCRIPTABLE Ekos::CommunicationStatus indiStatus() 0244 { 0245 return m_indiStatus; 0246 } 0247 0248 /** 0249 * DBUS interface function. 0250 * @return Ekos starting status (0 Idle, 1 Pending, 2 Started, 3 Error) 0251 * @deprecated 0252 */ 0253 Q_SCRIPTABLE unsigned int getEkosStartingStatus() 0254 { 0255 return m_ekosStatus; 0256 } 0257 0258 Q_SCRIPTABLE Ekos::CommunicationStatus ekosStatus() 0259 { 0260 return m_ekosStatus; 0261 } 0262 0263 /** 0264 * DBUS interface function. 0265 * @return Settle status (0 Idle, 1 Pending, 2 Started, 3 Error) 0266 */ 0267 Q_SCRIPTABLE Ekos::CommunicationStatus settleStatus() 0268 { 0269 return m_settleStatus; 0270 } 0271 0272 /** 0273 * DBUS interface function. Toggle Ekos logging. 0274 * @param name Name of logging to toggle. Available options are: 0275 * ** VERBOSE 0276 * ** INDI 0277 * ** FITS 0278 * ** CAPTURE 0279 * ** FOCUS 0280 * ** GUIDE 0281 * ** ALIGNMENT 0282 * ** MOUNT 0283 * ** SCHEDULER 0284 * ** OBSERVATORY 0285 * @param enabled True to enable, false otherwise. 0286 */ 0287 Q_SCRIPTABLE Q_NOREPLY void setEkosLoggingEnabled(const QString &name, bool enabled); 0288 0289 /** 0290 * DBUS interface function. 0291 * If connection mode is local, the function first establishes an INDI server with all the specified drivers in Ekos options or as set by the user. For remote connection, 0292 * it establishes connection to the remote INDI server. 0293 * @return Returns true if server started successful (local mode) or connection to remote server is successful (remote mode). 0294 */ 0295 Q_SCRIPTABLE void start(); 0296 0297 /** 0298 * DBUS interface function. 0299 * If connection mode is local, the function terminates the local INDI server and drivers. For remote, it disconnects from the remote INDI server. 0300 */ 0301 Q_SCRIPTABLE void stop(); 0302 0303 Q_SCRIPTABLE QStringList logText() 0304 { 0305 return m_LogText; 0306 } 0307 0308 Q_SCRIPTABLE bool ekosLiveStatus(); 0309 0310 /** 0311 * DBUS interface function. 0312 * @param enabled Connect to EkosLive if true, otherwise disconnect. 0313 */ 0314 Q_SCRIPTABLE void setEkosLiveConnected(bool enabled); 0315 0316 /** 0317 * @brief setEkosLiveConfig Set EkosLive settings 0318 * @param onlineService If true, connect to EkosLive Online Service. Otherwise, EkosLive offline service. 0319 * @param rememberCredentials Remember username and password for next session. 0320 * @param autoConnect If true, it will automatically connect to EkosLive service. 0321 */ 0322 Q_SCRIPTABLE void setEkosLiveConfig(bool onlineService, bool rememberCredentials, bool autoConnect); 0323 0324 /** 0325 * @brief setEkosLiveUser Save EkosLive username and password 0326 * @param username User name 0327 * @param password Password 0328 */ 0329 Q_SCRIPTABLE void setEkosLiveUser(const QString &username, const QString &password); 0330 0331 /** 0332 * @brief acceptPortSelection Accept current port selection settings in the Selector Dialog 0333 */ 0334 Q_SCRIPTABLE void acceptPortSelection(); 0335 0336 signals: 0337 // Have to use full Ekos::CommunicationStatus for DBus signal to work 0338 void ekosStatusChanged(Ekos::CommunicationStatus status); 0339 void indiStatusChanged(Ekos::CommunicationStatus status); 0340 void settleStatusChanged(Ekos::CommunicationStatus status); 0341 void ekosLiveStatusChanged(bool status); 0342 0343 void newLog(const QString &text); 0344 void newModule(const QString &name); 0345 void newDevice(const QString &name, int interface); 0346 0347 protected: 0348 void closeEvent(QCloseEvent *event) override; 0349 void hideEvent(QHideEvent *) override; 0350 void showEvent(QShowEvent *) override; 0351 void resizeEvent(QResizeEvent *) override; 0352 0353 public slots: 0354 0355 /** 0356 * DBUS interface function. 0357 * Connects all the INDI devices started by Ekos. 0358 */ 0359 Q_SCRIPTABLE Q_NOREPLY void connectDevices(); 0360 0361 /** 0362 * DBUS interface function. 0363 * Disconnects all the INDI devices started by Ekos. 0364 */ 0365 Q_SCRIPTABLE Q_NOREPLY void disconnectDevices(); 0366 0367 /** @}*/ 0368 0369 void processINDI(); 0370 void cleanDevices(bool stopDrivers = true); 0371 0372 void processNewDevice(const QSharedPointer<ISD::GenericDevice> &device); 0373 0374 void processNewProperty(INDI::Property); 0375 void processUpdateProperty(INDI::Property); 0376 void processDeleteProperty(INDI::Property); 0377 0378 void setDeviceReady(); 0379 0380 void restartDriver(const QString &deviceName); 0381 0382 private slots: 0383 0384 void changeAlwaysOnTop(Qt::ApplicationState state); 0385 0386 void showEkosOptions(); 0387 0388 void updateLog(); 0389 void clearLog(); 0390 0391 void processTabChange(); 0392 0393 void setServerStarted(const QString &host, int port); 0394 void setServerFailed(const QString &host, int port, const QString &message); 0395 //void setServerTerminated(const QString &host, int port, const QString &message); 0396 0397 void setClientStarted(const QString &host, int port); 0398 void setClientFailed(const QString &host, int port, const QString &message); 0399 void setClientTerminated(const QString &host, int port, const QString &message); 0400 0401 void removeDevice(const QSharedPointer<ISD::GenericDevice> &device); 0402 0403 void deviceConnected(); 0404 void deviceDisconnected(); 0405 0406 //void processINDIModeChange(); 0407 void checkINDITimeout(); 0408 0409 // Logs 0410 void updateDebugInterfaces(); 0411 void watchDebugProperty(INDI::Property prop); 0412 0413 void addMount(ISD::Mount *device); 0414 void addCamera(ISD::Camera *device); 0415 void addFilterWheel(ISD::FilterWheel *device); 0416 void addFocuser(ISD::Focuser *device); 0417 void addRotator(ISD::Rotator *device); 0418 void addDome(ISD::Dome *device); 0419 void addWeather(ISD::Weather *device); 0420 void addDustCap(ISD::DustCap *device); 0421 void addLightBox(ISD::LightBox *device); 0422 void addGuider(ISD::Guider *device); 0423 void addGPS(ISD::GPS *device); 0424 0425 /** 0426 * @brief syncGenericDevice Check if this device needs to be added to any Ekos module. 0427 * @param device pointer to generic device. 0428 */ 0429 void syncGenericDevice(const QSharedPointer<ISD::GenericDevice> &device); 0430 void createModules(const QSharedPointer<ISD::GenericDevice> &device); 0431 0432 // Profiles 0433 void addProfile(); 0434 void editProfile(); 0435 void deleteProfile(); 0436 void wizardProfile(); 0437 0438 // Mount Summary 0439 void updateMountCoords(const SkyPoint position, ISD::Mount::PierSide pierSide, const dms &ha); 0440 void updateMountStatus(ISD::Mount::Status status); 0441 void setTarget(const QString &name); 0442 0443 // Capture Summary 0444 void updateCaptureStatus(CaptureState status); 0445 void updateCaptureProgress(SequenceJob *job, const QSharedPointer<FITSData> &data); 0446 void updateExposureProgress(SequenceJob *job); 0447 void updateCaptureCountDown(); 0448 0449 // Focus summary 0450 void updateFocusStatus(FocusState status); 0451 void updateCurrentHFR(double newHFR, int position); 0452 0453 // Guide Summary 0454 void updateGuideStatus(GuideState status); 0455 void updateSigmas(double ra, double de); 0456 0457 private: 0458 explicit Manager(QWidget *parent); 0459 ~Manager() override; 0460 0461 void removeTabs(); 0462 void reset(); 0463 void initCapture(); 0464 void initFocus(); 0465 void initGuide(); 0466 void initAlign(); 0467 void initMount(); 0468 void initObservatory(); 0469 0470 void loadDrivers(); 0471 void loadProfiles(); 0472 int addModuleTab(EkosModule module, QWidget *tab, const QIcon &icon); 0473 0474 /** 0475 * @brief syncActiveDevices Syncs ACTIVE_DEVICES such as ACTIVE_TELESCOPE and ACTIVE_CCD 0476 * to the currently detected devices. 0477 */ 0478 void syncActiveDevices(); 0479 0480 /** 0481 * @brief isINDIReady Check whether all INDI devices are connected and ready and emit signals accordingly. 0482 * @return True if all INDI devices are connected and ready. 0483 */ 0484 bool isINDIReady(); 0485 0486 // Connect Signals/Slots of Ekos modules 0487 void connectModules(); 0488 0489 // Check if INDI server is already running 0490 bool isRunning(const QString &process); 0491 0492 bool getCurrentProfile(QSharedPointer<ProfileInfo> &profile) const; 0493 void updateProfileLocation(const QSharedPointer<ProfileInfo> &profile); 0494 void setProfileMapping(const QJsonObject &payload) 0495 { 0496 m_ProfileMapping = payload; 0497 } 0498 // Port Selector Save profile when connect all is pressed 0499 void setPortSelectionComplete(); 0500 // Check if the driver binary must be one only to avoid duplicate instances 0501 // Some driver binaries support multiple devices per binary 0502 // so we only need to start a single instance to handle them all. 0503 bool checkUniqueBinaryDriver(DriverInfo * primaryDriver, DriverInfo * secondaryDriver); 0504 0505 // Containers 0506 0507 // All Drivers 0508 QHash<QString, DriverInfo *> driversList; 0509 0510 // All managed drivers 0511 QList<DriverInfo *> managedDrivers; 0512 0513 // Smart pointers for the various Ekos Modules 0514 std::unique_ptr<Capture> captureProcess; 0515 std::unique_ptr<Focus> focusProcess; 0516 std::unique_ptr<Guide> guideProcess; 0517 std::unique_ptr<Align> alignProcess; 0518 std::unique_ptr<Mount> mountProcess; 0519 std::unique_ptr<Analyze> analyzeProcess; 0520 std::unique_ptr<Scheduler> schedulerProcess; 0521 std::unique_ptr<Observatory> observatoryProcess; 0522 std::unique_ptr<EkosLive::Client> ekosLiveClient; 0523 0524 bool m_LocalMode { true }; 0525 bool m_isStarted { false }; 0526 bool m_RemoteManagerStart { false }; 0527 0528 int m_DriverDevicesCount { 0 }; 0529 0530 QStringList m_LogText; 0531 KPageWidgetItem *ekosOptionsWidget { nullptr }; 0532 OpsEkos *opsEkos { nullptr }; 0533 0534 CommunicationStatus m_ekosStatus { Ekos::Idle }; 0535 CommunicationStatus m_indiStatus { Ekos::Idle }; 0536 // Settle is used to know once all properties from all devices have been defined 0537 // There is no way to know this for sure so we use a debounace mechanism. 0538 CommunicationStatus m_settleStatus { Ekos::Idle }; 0539 0540 std::unique_ptr<QStandardItemModel> profileModel; 0541 QList<QSharedPointer<ProfileInfo>> profiles; 0542 QJsonObject m_ProfileMapping; 0543 0544 // Mount Summary 0545 QPointer<QProcess> indiHubAgent; 0546 KLed *mountMotionState { nullptr }; 0547 0548 0549 // Capture Summary 0550 QTimer m_CountdownTimer; 0551 QTimer settleTimer; 0552 // Preview Frame 0553 QSharedPointer<SummaryFITSView> m_SummaryView; 0554 0555 QSharedPointer<ProfileInfo> m_CurrentProfile; 0556 bool profileWizardLaunched { false }; 0557 QString m_PrimaryCamera, m_GuideCamera; 0558 0559 // Port Selector 0560 std::unique_ptr<Selector::Dialog> m_PortSelector; 0561 QTimer m_PortSelectorTimer; 0562 0563 QMap<QString, QSharedPointer<FilterManager>> m_FilterManagers; 0564 0565 // Logs 0566 QPointer<OpsLogs> opsLogs; 0567 0568 // E.g. Setup, Scheduler, and Analyze. 0569 int numPermanentTabs { 0 }; 0570 0571 friend class EkosLive::Client; 0572 friend class EkosLive::Message; 0573 friend class EkosLive::Media; 0574 0575 static Manager *_Manager; 0576 }; 0577 0578 }