Kstars

manager.h
1/*
2 SPDX-FileCopyrightText: 2012 Jasem Mutlaq <mutlaqja@ikarustech.com>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#pragma once
8
9#ifdef USE_QT5_INDI
10#include <baseclientqt.h>
11#else
12#include <baseclient.h>
13#endif
14
15#include "ui_manager.h"
16
17#include "ekos.h"
18#include "fitsviewer/summaryfitsview.h"
19#include "indi/indistd.h"
20#include "auxiliary/portselector.h"
21#include "ksnotification.h"
22#include "auxiliary/opslogs.h"
23#include "ekos/capture/rotatorsettings.h"
24#include "extensions.h"
25
26#include <QDialog>
27#include <QHash>
28#include <QTimer>
29
30#include <memory>
31
32//! Generic record interfaces and implementations.
33namespace EkosLive
34{
35class Client;
36class Message;
37class Media;
38}
39
40class DriverInfo;
41class ProfileInfo;
42class KPageWidgetItem;
43class OpsEkos;
44
45/**
46 * @class Manager
47 * @short Primary class to handle all Ekos modules.
48 * 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.
49 * \defgroup EkosDBusInterface "Ekos DBus Interface" provides high level functions to control devices and Ekos modules for a total robotic operation:
50 * <ul>
51 * <li>\ref CaptureDBusInterface "Capture Module DBus Interface"</li>
52 * <li>\ref FocusDBusInterface "Focus Module DBus Interface"</li>
53 * <li>\ref MountDBusInterface "Mount Module DBus Interface"</li>
54 * <li>\ref GuideDBusInterface "Guide Module DBus Interface"</li>
55 * <li>\ref AlignDBusInterface "Align Module DBus Interface"</li>
56 * <li>\ref WeatherDBusInterface "Weather DBus Interface"</li>
57 * <li>\ref DustCapDBusInterface "Dust Cap DBus Interface"</li>
58 * </ul>
59 * For low level access to INDI devices, the \ref INDIDBusInterface "INDI Dbus Interface" provides complete access to INDI devices and properties.
60 * Ekos Manager provides a summary of operations progress in the <i>Summary</i> section of the <i>Setup</i> tab.
61 *
62 * @author Jasem Mutlaq
63 * @version 1.8
64 */
65namespace Ekos
66{
67
68class Analyze;
69class Capture;
70class Scheduler;
71class Focus;
72class FocusModule;
73class Align;
74class Guide;
75class Mount;
76class Observatory;
77// class RotatorSettings;
78
79class Manager : public QDialog, public Ui::Manager
80{
82 Q_CLASSINFO("D-Bus Interface", "org.kde.kstars.Ekos")
83
84 Q_SCRIPTABLE Q_PROPERTY(Ekos::CommunicationStatus indiStatus READ indiStatus NOTIFY indiStatusChanged)
85 Q_SCRIPTABLE Q_PROPERTY(Ekos::CommunicationStatus ekosStatus READ ekosStatus NOTIFY ekosStatusChanged)
86 Q_SCRIPTABLE Q_PROPERTY(Ekos::CommunicationStatus settleStatus READ settleStatus NOTIFY settleStatusChanged)
87 Q_SCRIPTABLE Q_PROPERTY(bool ekosLiveStatus READ ekosLiveStatus NOTIFY ekosLiveStatusChanged)
88 Q_SCRIPTABLE Q_PROPERTY(Ekos::ExtensionState extensionStatus READ extensionStatus NOTIFY extensionStatusChanged)
89 Q_SCRIPTABLE Q_PROPERTY(QStringList logText READ logText NOTIFY newLog)
90
91 enum class EkosModule
92 {
93 Setup,
94 Scheduler,
95 Analyze,
96 Capture,
97 Focus,
98 Mount,
99 Align,
100 Guide,
101 Observatory,
102 };
103 public:
104 static Manager *Instance();
105 static void release();
106
107 // No OP
108 void initialize() {}
109
110 void appendLogText(const QString &);
111 void setOptionsWidget(KPageWidgetItem *ops, OpsEkos *opsEkosPtr)
112 {
113 ekosOptionsWidget = ops;
114 opsEkos = opsEkosPtr;
115 }
116 void addObjectToScheduler(SkyObject *object);
117
118 Scheduler *schedulerModule()
119 {
120 return schedulerProcess.get();
121 }
122 Guide *guideModule()
123 {
124 return guideProcess.get();
125 }
126 Align *alignModule()
127 {
128 return alignProcess.get();
129 }
130 Mount *mountModule()
131 {
132 return mountProcess.get();
133 }
134 FocusModule *focusModule()
135 {
136 return focusProcess.get();
137 }
138 Capture *captureModule()
139 {
140 return captureProcess.get();
141 }
142 FITSView *getSummaryPreview()
143 {
144 return m_SummaryView.get();
145 }
146
147 // Filter Manager
148 void createFilterManager(ISD::FilterWheel *device);
149 bool getFilterManager(const QString &name, QSharedPointer<FilterManager> &fm);
150 bool getFilterManager(QSharedPointer<FilterManager> &fm);
151
152 // Rotator Control
153 void createRotatorController(ISD::Rotator *device);
154 bool getRotatorController(const QString &Name, QSharedPointer<RotatorSettings> &rs);
155 bool existRotatorController();
156
157 QString getCurrentJobName();
158 void announceEvent(const QString &message, KSNotification::EventSource source, KSNotification::EventType event);
159
160 extensions m_extensions;
161
162 /**
163 * @brief activateModule Switch tab to specific module name (i.e. CCD) and raise Ekos screen to focus.
164 * @param name module name CCD, Guide, Focus, Mount, Scheduler, or Observatory.
165 * @param popup if True, show Ekos Manager window in the foreground.
166 */
167 void activateModule(const QString &name, bool popup = false);
168
169 /**
170 * @brief addProfile Add a new profile to the database.
171 * @param profileInfo Collection of profile parameters to include the following:
172 * 1. name: Profile name
173 * 2. auto_connect: True of False for Autoconnect?
174 * 3. Mode: "local" or "remote"
175 * 4. remote_host: Optional. remote host (default localhost)
176 * 5. remote_port: Optional. remote port (default 7624)
177 * 6. guiding: 0 for "Internal", 1 for "PHD2", or 2 for "LinGuider"
178 * 7. remote_guiding_host: Optional. remote host for guider application (default localhost)
179 * 8. remote_guide_port: Optional. remote port for guider application.
180 * 9. use_web_manager: True or False?
181 * 10. web_manager_port. Optional. INDI Web Manager port (default 8624)
182 * 12. primary_scope: ID of primary scope to use. This is the ID from OAL::Scope list in the database.
183 * 13. guide_scope: ID of guide scope to use. This is the ID from OAL::Scope list in the database.
184 * 14. mount: Mount driver label (default --).
185 * 15. ccd: CCD driver label (default --).
186 * 16. guider: Guider driver label (default --).
187 * 17. focuser: Focuser driver label (default --).
188 * 18. filter: Filter Wheel driver label (default --).
189 * 19. ao: Adaptive Optics driver label (default --).
190 * 20. dome: Dome driver label (default --).
191 * 21. Weather: Weather station driver label (default --).
192 * 22. aux1: aux1 driver label (default --).
193 * 23. aux2: aux2 driver label (default --).
194 * 24. aux3: aux3 driver label (default --).
195 * 25. aux4: aux4 driver label (default --).
196 */
197 void addNamedProfile(const QJsonObject &profileInfo);
198
199 /** Same as above, except it edits an existing named profile */
200 void editNamedProfile(const QJsonObject &profileInfo);
201
202 /**
203 * @brief deleteProfile Delete existing equipment profile
204 * @param name Name of profile
205 * @warning Ekos must be stopped for this to work. It will fail if Ekos is online.
206 */
207 void deleteNamedProfile(const QString &name);
208
209 /**
210 * @brief getProfile Get a single profile information.
211 * @param name Profile name
212 * @return A JSon object with the detail profile info as described in addProfile function.
213 */
214 QJsonObject getNamedProfile(const QString &name);
215
216 /**
217 * DBus commands to manage equipment profiles.
218 */
219
220 /*@{*/
221
222 /**
223 * DBUS interface function.
224 * set Current device profile.
225 * @param profileName Profile name
226 * @return True if profile is set, false if not found.
227 */
228 Q_SCRIPTABLE bool setProfile(const QString &profileName);
229
230 /**
231 * DBUS interface function
232 * @brief getProfiles Return a list of all device profiles
233 * @return List of device profiles
234 */
235 Q_SCRIPTABLE QStringList getProfiles();
236
237 /** @}*/
238
239
240 /**
241 * Manager interface provides advanced scripting capabilities to establish and shutdown Ekos services.
242 */
243
244 /*@{*/
245
246 /**
247 * DBUS interface function.
248 * @return INDI connection status (0 Idle, 1 Pending, 2 Connected, 3 Error)
249 * @deprecated
250 */
251 Q_SCRIPTABLE unsigned int getINDIConnectionStatus()
252 {
253 return m_indiStatus;
254 }
255
256 Q_SCRIPTABLE Ekos::CommunicationStatus indiStatus()
257 {
258 return m_indiStatus;
259 }
260
261 /**
262 * DBUS interface function.
263 * @return Ekos starting status (0 Idle, 1 Pending, 2 Started, 3 Error)
264 * @deprecated
265 */
266 Q_SCRIPTABLE unsigned int getEkosStartingStatus()
267 {
268 return m_ekosStatus;
269 }
270
271 Q_SCRIPTABLE Ekos::CommunicationStatus ekosStatus()
272 {
273 return m_ekosStatus;
274 }
275
276 /**
277 * DBUS interface function.
278 * @return Settle status (0 Idle, 1 Pending, 2 Started, 3 Error)
279 */
280 Q_SCRIPTABLE Ekos::CommunicationStatus settleStatus()
281 {
282 return m_settleStatus;
283 }
284
285 /**
286 * DBUS interface function. Toggle Ekos logging.
287 * @param name Name of logging to toggle. Available options are:
288 * ** VERBOSE
289 * ** INDI
290 * ** FITS
291 * ** CAPTURE
292 * ** FOCUS
293 * ** GUIDE
294 * ** ALIGNMENT
295 * ** MOUNT
296 * ** SCHEDULER
297 * ** OBSERVATORY
298 * @param enabled True to enable, false otherwise.
299 */
300 Q_SCRIPTABLE Q_NOREPLY void setEkosLoggingEnabled(const QString &name, bool enabled);
301
302 /**
303 * DBUS interface function.
304 * 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,
305 * it establishes connection to the remote INDI server.
306 * @return Returns true if server started successful (local mode) or connection to remote server is successful (remote mode).
307 */
308 Q_SCRIPTABLE void start();
309
310 /**
311 * DBUS interface function.
312 * If connection mode is local, the function terminates the local INDI server and drivers. For remote, it disconnects from the remote INDI server.
313 */
314 Q_SCRIPTABLE void stop();
315
316 Q_SCRIPTABLE QStringList logText()
317 {
318 return m_LogText;
319 }
320
321 Q_SCRIPTABLE bool ekosLiveStatus();
322
323 /**
324 * DBUS interface function.
325 * @return Settle status (0 EXTENSION_START_REQUESTED, 1 EXTENSION_STARTED, 2 EXTENSION_STOP_REQUESTED, 3 EXTENSION_STOPPED)
326 */
327 Q_SCRIPTABLE Ekos::ExtensionState extensionStatus()
328 {
329 return m_extensionStatus;
330 };
331
332 /**
333 * DBUS interface function.
334 * @param enabled Connect to EkosLive if true, otherwise disconnect.
335 */
336 Q_SCRIPTABLE void setEkosLiveConnected(bool enabled);
337
338 /**
339 * @brief setEkosLiveConfig Set EkosLive settings
340 * @param rememberCredentials Remember username and password for next session.
341 * @param autoConnect If true, it will automatically connect to EkosLive service.
342 */
343 Q_SCRIPTABLE void setEkosLiveConfig(bool rememberCredentials, bool autoConnect);
344
345 /**
346 * @brief setEkosLiveUser Save EkosLive username and password
347 * @param username User name
348 * @param password Password
349 */
350 Q_SCRIPTABLE void setEkosLiveUser(const QString &username, const QString &password);
351
352 /**
353 * @brief acceptPortSelection Accept current port selection settings in the Selector Dialog
354 */
355 Q_SCRIPTABLE void acceptPortSelection();
356
357 signals:
358 // Have to use full Ekos::CommunicationStatus for DBus signal to work
359 void ekosStatusChanged(Ekos::CommunicationStatus status);
360 void indiStatusChanged(Ekos::CommunicationStatus status);
361 void settleStatusChanged(Ekos::CommunicationStatus status);
362 void ekosLiveStatusChanged(bool status);
363 void extensionStatusChanged(bool = true);
364
365 void newLog(const QString &text);
366 void newModule(const QString &name);
367 void newDevice(const QString &name, int interface);
368
369 protected:
370 void closeEvent(QCloseEvent *event) override;
371 void hideEvent(QHideEvent *) override;
372 void showEvent(QShowEvent *) override;
373 void resizeEvent(QResizeEvent *) override;
374
375 public slots:
376
377 /**
378 * DBUS interface function.
379 * Connects all the INDI devices started by Ekos.
380 */
381 Q_SCRIPTABLE Q_NOREPLY void connectDevices();
382
383 /**
384 * DBUS interface function.
385 * Disconnects all the INDI devices started by Ekos.
386 */
387 Q_SCRIPTABLE Q_NOREPLY void disconnectDevices();
388
389 /**
390 * DBUS interface function.
391 * Enables loading of preview fits from file rather than Capture data.
392 */
393 Q_SCRIPTABLE Q_NOREPLY void setFITSfromFile(bool previewFromFile);
394
395 /**
396 * DBUS interface function.
397 * Load preview fits from file.
398 */
399 Q_SCRIPTABLE Q_NOREPLY void previewFile(QString filePath);
400
401 /** @}*/
402
403 void processINDI();
404 void cleanDevices(bool stopDrivers = true);
405
406 void processNewDevice(const QSharedPointer<ISD::GenericDevice> &device);
407
408 void processNewProperty(INDI::Property);
409 void processUpdateProperty(INDI::Property);
410 void processDeleteProperty(INDI::Property);
411 void processMessage(int id);
412
413
414 void setDeviceReady();
415
416 void restartDriver(const QString &deviceName);
417
418 private slots:
419
420 void changeAlwaysOnTop(Qt::ApplicationState state);
421
422 void showEkosOptions();
423
424 void updateLog();
425 void clearLog();
426
427 void processTabChange();
428
429 void setServerStarted(const QString &host, int port);
430 void setServerFailed(const QString &host, int port, const QString &message);
431 //void setServerTerminated(const QString &host, int port, const QString &message);
432
433 void setClientStarted(const QString &host, int port);
434 void setClientFailed(const QString &host, int port, const QString &message);
435 void setClientTerminated(const QString &host, int port, const QString &message);
436
437 void removeDevice(const QSharedPointer<ISD::GenericDevice> &device);
438
439 void deviceConnected();
440 void deviceDisconnected();
441
442 //void processINDIModeChange();
443 void checkINDITimeout();
444
445 // Logs
446 void updateDebugInterfaces();
447 void watchDebugProperty(INDI::Property prop);
448
449 void addMount(ISD::Mount *device);
450 void addCamera(ISD::Camera *device);
451 void addFilterWheel(ISD::FilterWheel *device);
452 void addFocuser(ISD::Focuser *device);
453 void addRotator(ISD::Rotator *device);
454 void addDome(ISD::Dome *device);
455 void addWeather(ISD::Weather *device);
456 void addDustCap(ISD::DustCap *device);
457 void addLightBox(ISD::LightBox *device);
458 void addGuider(ISD::Guider *device);
459 void addGPS(ISD::GPS *device);
460
461 /**
462 * @brief syncGenericDevice Check if this device needs to be added to any Ekos module.
463 * @param device pointer to generic device.
464 */
465 void syncGenericDevice(const QSharedPointer<ISD::GenericDevice> &device);
466 void createModules(const QSharedPointer<ISD::GenericDevice> &device);
467
468 // Profiles
469 void addProfile();
470 void editProfile();
471 void deleteProfile();
472 void wizardProfile();
473
474 // Mount Summary
475 void updateMountCoords(const SkyPoint position, ISD::Mount::PierSide pierSide, const dms &ha);
476 void updateMountStatus(ISD::Mount::Status status);
477 void setTarget(const QString &name);
478
479 // Capture Summary
480 void updateCaptureStatus(CaptureState status, const QString &trainname);
481 void updateCaptureProgress(SequenceJob *job, const QSharedPointer<FITSData> &data, const QString &devicename = "");
482 void updateExposureProgress(SequenceJob *job, const QString &trainname);
483 void updateCaptureCountDown();
484
485 // Focus summary
486 void updateFocusStatus(FocusState status);
487 void updateCurrentHFR(double newHFR, int position, bool inAutofocus);
488
489 // Guide Summary
490 void updateGuideStatus(GuideState status);
491 void updateSigmas(double ra, double de);
492
493 private:
494 explicit Manager(QWidget *parent);
495 ~Manager() override;
496
497 void removeTabs();
498 void reset();
499 void initCapture();
500 void initFocus();
501 void initGuide();
502 void initAlign();
503 void initMount();
504 void initObservatory();
505
506 void loadDrivers();
507 void loadProfiles();
508 int addModuleTab(EkosModule module, QWidget *tab, const QIcon &icon);
509
510 /**
511 * @brief isINDIReady Check whether all INDI devices are connected and ready and emit signals accordingly.
512 * @return True if all INDI devices are connected and ready.
513 */
514 bool isINDIReady();
515
516 // Connect Signals/Slots of Ekos modules
517 void connectModules();
518
519 // Check if INDI server is already running
520 bool isRunning(const QString &process);
521
522 bool getCurrentProfile(QSharedPointer<ProfileInfo> &profile) const;
523 void updateProfileLocation(const QSharedPointer<ProfileInfo> &profile);
524 void setProfileMapping(const QJsonObject &payload)
525 {
526 m_ProfileMapping = payload;
527 }
528 // Port Selector Save profile when connect all is pressed
529 void setPortSelectionComplete();
530 // Check if the driver binary must be one only to avoid duplicate instances
531 // Some driver binaries support multiple devices per binary
532 // so we only need to start a single instance to handle them all.
533 bool checkUniqueBinaryDriver(const QSharedPointer<DriverInfo> &primaryDriver,
534 const QSharedPointer<DriverInfo> &secondaryDriver);
535
536 // Containers
537
538 // All Drivers
540
541 // All managed drivers
542 QList<QSharedPointer<DriverInfo>> managedDrivers;
543
544 // Smart pointers for the various Ekos Modules
545 std::unique_ptr<Capture> captureProcess;
546 std::unique_ptr<FocusModule> focusProcess;
547 std::unique_ptr<Guide> guideProcess;
548 std::unique_ptr<Align> alignProcess;
549 std::unique_ptr<Mount> mountProcess;
550 std::unique_ptr<Analyze> analyzeProcess;
551 std::unique_ptr<Scheduler> schedulerProcess;
552 std::unique_ptr<Observatory> observatoryProcess;
553 std::unique_ptr<EkosLive::Client> ekosLiveClient;
554
555 bool m_LocalMode { true };
556 bool m_isStarted { false };
557 bool m_RemoteManagerStart { false };
558
559 int m_DriverDevicesCount { 0 };
560
561 QStringList m_LogText;
562 KPageWidgetItem *ekosOptionsWidget { nullptr };
563 OpsEkos *opsEkos { nullptr };
564
565 CommunicationStatus m_ekosStatus { Ekos::Idle };
566 CommunicationStatus m_indiStatus { Ekos::Idle };
567 // Settle is used to know once all properties from all devices have been defined
568 // There is no way to know this for sure so we use a debounace mechanism.
569 CommunicationStatus m_settleStatus { Ekos::Idle };
570 ExtensionState m_extensionStatus { Ekos::EXTENSION_STOPPED };
571
572 std::unique_ptr<QStandardItemModel> profileModel;
574 QJsonObject m_ProfileMapping;
575
576 // Mount Summary
577 QPointer<QProcess> indiHubAgent;
578 KLed *mountMotionState { nullptr };
579
580
581 // Capture Summary
582 QTimer m_CountdownTimer;
583 QTimer settleTimer;
584 // Preview Frame
586 bool FITSfromFile = false;
587 QTimer extensionTimer;
588 bool extensionAbort = false;
589
590 QSharedPointer<ProfileInfo> m_CurrentProfile;
591 bool profileWizardLaunched { false };
592 QString m_PrimaryCamera, m_GuideCamera;
593
594 // Port Selector
595 std::unique_ptr<Selector::Dialog> m_PortSelector;
596 QTimer m_PortSelectorTimer;
597
600
601 // Logs
602 QPointer<OpsLogs> opsLogs;
603
604 // E.g. Setup, Scheduler, and Analyze.
605 int numPermanentTabs { 0 };
606
607 friend class EkosLive::Client;
608 friend class EkosLive::Message;
609 friend class EkosLive::Media;
610
611 static Manager *_Manager;
612};
613
614}
DriverInfo holds all metadata associated with a particular INDI driver.
Definition driverinfo.h:46
Guide is a special class that handles ST4 commands.
Camera class controls an INDI Camera device.
Definition indicamera.h:45
Class handles control of INDI dome devices.
Definition indidome.h:25
Handles operation of a remotely controlled dust cover cap.
Definition indidustcap.h:25
Focuser class handles control of INDI focuser devices.
Definition indifocuser.h:21
Handles operation of a remotely controlled light box.
device handle controlling Mounts.
Definition indimount.h:29
Rotator class handles control of INDI Rotator devices.
Definition indirotator.h:20
Focuser class handles control of INDI Weather devices.
Definition indiweather.h:24
Primary class to handle all Ekos modules.
Enables the user to set remote connection devices and options in addition to online and offline astro...
Definition opsekos.h:22
Sequence Job is a container for the details required to capture a series of images.
Provides all necessary information about an object in the sky: its coordinates, name(s),...
Definition skyobject.h:42
The sky coordinates of a point in the sky.
Definition skypoint.h:45
An angle, stored as degrees, but expressible in many ways.
Definition dms.h:38
Generic record interfaces and implementations.
Definition cloud.cpp:22
Ekos is an advanced Astrophotography tool for Linux.
Definition align.cpp:83
Q_CLASSINFO(Name, Value)
Q_OBJECTQ_OBJECT
Q_PROPERTY(...)
QObject * parent() const const
T * get() const const
ApplicationState
virtual bool event(QEvent *event) override
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:16:40 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.