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

KDE's Doxygen guidelines are available online.