Kstars

schedulerprocess.h
1/*
2 SPDX-FileCopyrightText: 2023 Wolfgang Reissenberger <sterne-jaeger@openfuture.de>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#pragma once
8
9#include "schedulertypes.h"
10#include "schedulerjob.h"
11#include "ekos/auxiliary/modulelogger.h"
12#include "ekos/align/align.h"
13#include "ekos/auxiliary/solverutils.h"
14#include "indi/indiweather.h"
15#include "dms.h"
16
17#include <QObject>
18#include <QPointer>
19#include <QtDBus/QDBusInterface>
20#include <QProcess>
21
22namespace Ekos
23{
24
25class GreedyScheduler;
26class SchedulerModuleState;
27
28/**
29 * @class SchedulerProcess
30 * @brief The SchedulerProcess class holds the entire business logic for controlling the
31 * execution of the EKOS scheduler.
32 */
33class SchedulerProcess : public QObject, public ModuleLogger
34{
36 Q_CLASSINFO("D-Bus Interface", "org.kde.kstars.Ekos.Scheduler")
37 Q_PROPERTY(Ekos::SchedulerState status READ status NOTIFY newStatus)
38 Q_PROPERTY(QString profile READ profile WRITE setProfile)
39 Q_PROPERTY(QString currentJobName READ currentJobName)
40 Q_PROPERTY(QString currentJobJson READ currentJobJson)
41 Q_PROPERTY(QString jsonJobs READ jsonJobs)
42 Q_PROPERTY(QStringList logText READ logText NOTIFY newLog)
43
44public:
45 SchedulerProcess(QSharedPointer<SchedulerModuleState> state, const QString &ekosPathStr, const QString &ekosInterfaceStr);
46
47
48 // ////////////////////////////////////////////////////////////////////
49 // external DBUS interface
50 // ////////////////////////////////////////////////////////////////////
51
52 SchedulerState status();
53
54 // ////////////////////////////////////////////////////////////////////
55 // process steps
56 // ////////////////////////////////////////////////////////////////////
57
58 /**
59 * @brief execute Execute the schedule, start if idle or paused.
60 */
61 Q_SCRIPTABLE void execute();
62
63 /**
64 * @brief findNextJob Check if the job met the completion criteria, and if it did, then it search for next job candidate.
65 * If no jobs are found, it starts the shutdown stage.
66 */
67 void findNextJob();
68
69 /**
70 * @brief stopCurrentJobAction Stop whatever action taking place in the current job (eg. capture, guiding...etc).
71 */
72 Q_SCRIPTABLE void stopCurrentJobAction();
73
74 /**
75 * @brief executeJob After the best job is selected, we call this in order to start the process that will execute the job.
76 * checkJobStatus slot will be connected in order to figure the exact state of the current job each second
77 * @return True if job is accepted and can be executed, false otherwise.
78 */
79 bool executeJob(SchedulerJob *job);
80
81 /**
82 * @brief wakeUpScheduler Wake up scheduler from sleep state
83 */
84 Q_SCRIPTABLE void wakeUpScheduler();
85
86 /** DBUS interface function.
87 * @brief Setup the main loop and start.
88 */
89 Q_SCRIPTABLE Q_NOREPLY void start();
90
91 /** DBUS interface function.
92 * @brief stop Stop the scheduler execution. If stopping succeeded,
93 * a {@see #schedulerStopped()} signal is emitted
94 */
95 Q_SCRIPTABLE Q_NOREPLY void stop();
96
97 /** DBUS interface function.
98 * @brief Remove all scheduler jobs
99 */
100 Q_SCRIPTABLE Q_NOREPLY void removeAllJobs();
101
102 /** DBUS interface function.
103 * @brief Loads the Ekos Scheduler List (.esl) file.
104 * @param fileURL path to a file
105 * @return true if loading file is successful, false otherwise.
106 */
107 Q_SCRIPTABLE bool loadScheduler(const QString &fileURL);
108
109 /** DBUS interface function.
110 * @brief Set the file URL pointing to the capture sequence file
111 * @param sequenceFileURL URL of the capture sequence file
112 */
113 Q_SCRIPTABLE Q_NOREPLY void setSequence(const QString &sequenceFileURL);
114
115 /** DBUS interface function.
116 * @brief Resets all jobs to IDLE
117 */
118 Q_SCRIPTABLE Q_NOREPLY void resetAllJobs();
119
120 /**
121 * @brief shouldSchedulerSleep Check if the scheduler needs to sleep until the job is ready
122 * @param job Job to check
123 * @return True if we set the scheduler to sleep mode. False, if not required and we need to execute now
124 */
125 bool shouldSchedulerSleep(SchedulerJob *job);
126
127 /**
128 * @brief mountCoords read the equatorial coordinates from the mount
129 * @return {RA, DEC}
130 */
132
133 /**
134 * @brief startSlew DBus call for initiating slew
135 */
136 Q_SCRIPTABLE Q_NOREPLY void startSlew();
137
138 /**
139 * @brief startFocusing DBus call for feeding ekos the specified settings and initiating focus operation
140 */
141 Q_SCRIPTABLE Q_NOREPLY void startFocusing();
142
143 /**
144 * @brief startAstrometry initiation of the capture and solve operation. We change the job state
145 * after solver is started
146 */
147 Q_SCRIPTABLE Q_NOREPLY void startAstrometry();
148
149 /**
150 * @brief startGuiding After ekos is fed the calibration options, we start the guiding process
151 * @param resetCalibration By default calibration is not reset until it is explicitly requested
152 */
153 Q_SCRIPTABLE Q_NOREPLY void startGuiding(bool resetCalibration = false);
154
155 /**
156 * @brief stopGuiding After guiding is done we need to stop the process
157 */
158 Q_SCRIPTABLE Q_NOREPLY void stopGuiding();
159
160 /**
161 * @brief processGuidingTimer Check the guiding timer, and possibly restart guiding.
162 */
163 void processGuidingTimer();
164
165 /**
166 * @brief startCapture The current job file name is solved to an url which is fed to ekos. We then start the capture process
167 * @param restart Set to true if the goal to restart an existing sequence. The only difference is that when a sequence is restarted, sequence file
168 * is not loaded from disk again since that results in erasing all the history of the capture process.
169 */
170 Q_SCRIPTABLE Q_NOREPLY void startCapture(bool restart = false);
171
172 void startSingleCapture(SchedulerJob *job, bool restart = false);
173
174 /**
175 * @brief updateCompletedJobsCount For each scheduler job, examine sequence job storage and count captures.
176 * @param forced forces recounting captures unconditionally if true, else only IDLE, EVALUATION or new jobs are examined.
177 */
178 void updateCompletedJobsCount(bool forced = false);
179
180 /**
181 * @brief setSolverAction set the GOTO mode for the solver
182 * @param mode 0 For Sync, 1 for SlewToTarget, 2 for Nothing
183 */
184 void setSolverAction(Align::GotoMode mode);
185
186 /**
187 * @brief loadProfiles Load the existing EKOS profiles
188 */
189 void loadProfiles();
190
191 /**
192 * @brief checkEkosState Check ekos startup stages and take whatever action necessary to get Ekos up and running
193 * @return True if Ekos is running, false if Ekos start up is in progress.
194 */
195 bool checkEkosState();
196
197 /**
198 * @brief checkINDIState Check INDI startup stages and take whatever action necessary to get INDI devices connected.
199 * @return True if INDI devices are connected, false if it is under progress.
200 */
201 bool checkINDIState();
202
203 /**
204 * @brief completeShutdown Try to complete the scheduler shutdown
205 * @return false iff some further action is required
206 */
207 Q_SCRIPTABLE bool completeShutdown();
208
209 /**
210 * @brief disconnectINDI disconnect all INDI devices from server.
211 */
212 Q_SCRIPTABLE Q_NOREPLY void disconnectINDI();
213
214 /**
215 * @brief manageConnectionLoss Mitigate loss of connection with the INDI server.
216 * @return true if connection to Ekos/INDI should be attempted again, false if not mitigation is available or needed.
217 */
219
220 /**
221 * @brief checkDomeParkingStatus check dome parking status and updating corresponding states accordingly.
222 */
224
225 /**
226 * @brief checkStartupState Check startup procedure stages and make sure all stages are complete.
227 * @return True if startup is complete, false otherwise.
228 */
229 bool checkStartupState();
230 /**
231 * @brief checkShutdownState Check shutdown procedure stages and make sure all stages are complete.
232 * @return
233 */
234 bool checkShutdownState();
235
236 /**
237 * @brief checkParkWaitState Check park wait state.
238 * @return If parking/unparking in progress, return false. If parking/unparking complete, return true.
239 */
240 Q_SCRIPTABLE bool checkParkWaitState();
241
242 /**
243 * @brief runStartupProcedure Execute the startup of the scheduler itself to be prepared
244 * for running scheduler jobs.
245 */
246 Q_SCRIPTABLE Q_NOREPLY void runStartupProcedure();
247
248 /**
249 * @brief runShutdownProcedure Shutdown the scheduler itself and EKOS (if configured to do so).
250 */
251 Q_SCRIPTABLE Q_NOREPLY void runShutdownProcedure();
252
253 /**
254 * @brief setPaused pausing the scheduler
255 */
256 Q_SCRIPTABLE Q_NOREPLY void setPaused();
257
258 /**
259 * @brief resetJobs Reset all jobs counters
260 */
261 Q_SCRIPTABLE Q_NOREPLY void resetJobs();
262
263 /**
264 * @brief selectActiveJob Select the job that should be executed
265 */
266 void selectActiveJob(const QList<SchedulerJob *> &jobs);
267
268 /**
269 * @brief startJobEvaluation Start job evaluation only without starting the scheduler process itself. Display the result to the user.
270 */
271 Q_SCRIPTABLE Q_NOREPLY void startJobEvaluation();
272
273 /**
274 * @brief evaluateJobs evaluates the current state of each objects and gives each one a score based on the constraints.
275 * Given that score, the scheduler will decide which is the best job that needs to be executed.
276 */
277 Q_SCRIPTABLE Q_NOREPLY void evaluateJobs(bool evaluateOnly);
278
279 /**
280 * @brief checkJobStatus Check the overall state of the scheduler, Ekos, and INDI. When all is OK, it calls evaluateJobs() when no job is current or executeJob() if a job is selected.
281 * @return False if this function needs to be called again later, true if situation is stable and operations may continue.
282 */
283 bool checkStatus();
284
285 /**
286 * @brief getNextAction Checking for the next appropriate action regarding the current state of the scheduler and execute it
287 */
288 void getNextAction();
289
290 /**
291 * @brief Repeatedly runs a scheduler iteration and then sleeps timerInterval millisconds
292 * and run the next iteration. This continues until the sleep time is negative.
293 */
294 void iterate();
295
296 /**
297 * @brief Run a single scheduler iteration.
298 */
300
301 /**
302 * @brief checkJobStage Check the progress of the job states and make DBUS calls to start the next stage until the job is complete.
303 */
304 void checkJobStage();
305 void checkJobStageEpilogue();
306
307 /**
308 * @brief applyConfig Apply configuration changes from the global configuration dialog.
309 */
310 void applyConfig();
311
312 /**
313 * @brief saveScheduler Save scheduler jobs to a file
314 * @param path path of a file
315 * @return true on success, false on failure.
316 */
317 Q_SCRIPTABLE bool saveScheduler(const QUrl &fileURL);
318
319 /**
320 * @brief appendEkosScheduleList Append the contents of an ESL file to the queue.
321 * @param fileURL File URL to load contents from.
322 * @return True if contents were loaded successfully, else false.
323 */
324 Q_SCRIPTABLE bool appendEkosScheduleList(const QString &fileURL);
325
326 /**
327 * @brief appendLogText Append a new line to the logging.
328 */
329 Q_SCRIPTABLE Q_NOREPLY void appendLogText(const QString &logentry) override;
330
331 /**
332 * @brief clearLog Clear log entry
333 */
334 Q_SCRIPTABLE void clearLog();
335
336 /**
337 * @return True if mount is parked
338 */
339 Q_SCRIPTABLE bool isMountParked();
340 /**
341 * @return True if dome is parked
342 */
343 Q_SCRIPTABLE bool isDomeParked();
344
345 void simClockScaleChanged(float);
346 void simClockTimeChanged();
347
348 // ////////////////////////////////////////////////////////////////////
349 // state machine and scheduler
350 // ////////////////////////////////////////////////////////////////////
352 QSharedPointer<SchedulerModuleState> moduleState() const
353 {
354 return m_moduleState;
355 }
356
357 QPointer<Ekos::GreedyScheduler> m_GreedyScheduler;
358 QPointer<GreedyScheduler> &getGreedyScheduler()
359 {
360 return m_GreedyScheduler;
361 }
362
363 // ////////////////////////////////////////////////////////////////////
364 // DBUS interfaces to devices
365 // ////////////////////////////////////////////////////////////////////
366
367 QString focusInterfaceString { "org.kde.kstars.Ekos.Focus" };
368 void setFocusInterfaceString(const QString &interface)
369 {
370 focusInterfaceString = interface;
371 }
372 QString focusPathString { "/KStars/Ekos/Focus" };
373 void setFocusPathString(const QString &interface)
374 {
375 focusPathString = interface;
376 }
377
378 QString mountInterfaceString { "org.kde.kstars.Ekos.Mount" };
379 void setMountInterfaceString(const QString &interface)
380 {
381 mountInterfaceString = interface;
382 }
383 QString mountPathString { "/KStars/Ekos/Mount" };
384 void setMountPathString(const QString &interface)
385 {
386 mountPathString = interface;
387 }
388
389 QString captureInterfaceString { "org.kde.kstars.Ekos.Capture" };
390 void setCaptureInterfaceString(const QString &interface)
391 {
392 captureInterfaceString = interface;
393 }
394 QString capturePathString { "/KStars/Ekos/Capture" };
395 void setCapturePathString(const QString &interface)
396 {
397 capturePathString = interface;
398 }
399
400 QString alignInterfaceString { "org.kde.kstars.Ekos.Align" };
401 void setAlignInterfaceString(const QString &interface)
402 {
403 alignInterfaceString = interface;
404 }
405 QString alignPathString { "/KStars/Ekos/Align" };
406 void setAlignPathString(const QString &interface)
407 {
408 alignPathString = interface;
409 }
410
411 QString guideInterfaceString { "org.kde.kstars.Ekos.Guide" };
412 void setGuideInterfaceString(const QString &interface)
413 {
414 guideInterfaceString = interface;
415 }
416 QString guidePathString { "/KStars/Ekos/Guide" };
417 void setGuidePathString(const QString &interface)
418 {
419 guidePathString = interface;
420 }
421
422 QString observatoryInterfaceString { "org.kde.kstars.Ekos.Observatory" };
423 void setObservatoryInterfaceString(const QString &interface)
424 {
425 observatoryInterfaceString = interface;
426 }
427 QString observatoryPathString { "/KStars/Ekos/Observatory" };
428 void setObservatoryPathString(const QString &interface)
429 {
430 observatoryPathString = interface;
431 }
432
433 QString domeInterfaceString { "org.kde.kstars.INDI.Dome" };
434 void setDomeInterfaceString(const QString &interface)
435 {
436 domeInterfaceString = interface;
437 }
438
439 QString domePathString;
440 void setDomePathString(const QString &interface)
441 {
442 domePathString = interface;
443 }
444
445 QString weatherInterfaceString { "org.kde.kstars.INDI.Weather" };
446 void setWeatherInterfaceString(const QString &interface)
447 {
448 weatherInterfaceString = interface;
449 }
450 QString weatherPathString;
451 void setWeatherPathString(const QString &interface)
452 {
453 weatherPathString = interface;
454 }
455
456 QString dustCapInterfaceString { "org.kde.kstars.INDI.DustCap" };
457 void setDustCapInterfaceString(const QString &interface)
458 {
459 dustCapInterfaceString = interface;
460 }
461 QString dustCapPathString;
462 void setDustCapPathString(const QString &interface)
463 {
464 dustCapPathString = interface;
465 }
466
467 QPointer<QDBusInterface> ekosInterface() const
468 {
469 return m_ekosInterface;
470 }
471 void setEkosInterface(QPointer<QDBusInterface> newInterface)
472 {
473 m_ekosInterface = newInterface;
474 }
475 QPointer<QDBusInterface> indiInterface() const
476 {
477 return m_indiInterface;
478 }
479 void setIndiInterface(QPointer<QDBusInterface> newInterface)
480 {
481 m_indiInterface = newInterface;
482 }
483 QPointer<QDBusInterface> focusInterface() const
484 {
485 return m_focusInterface;
486 }
487 void setFocusInterface(QPointer<QDBusInterface> newInterface)
488 {
489 m_focusInterface = newInterface;
490 }
491 QPointer<QDBusInterface> captureInterface() const
492 {
493 return m_captureInterface;
494 }
495 void setCaptureInterface(QPointer<QDBusInterface> newInterface)
496 {
497 m_captureInterface = newInterface;
498 }
499 QPointer<QDBusInterface> mountInterface() const
500 {
501 return m_mountInterface;
502 }
503 void setMountInterface(QPointer<QDBusInterface> newInterface)
504 {
505 m_mountInterface = newInterface;
506 }
507 QPointer<QDBusInterface> alignInterface() const
508 {
509 return m_alignInterface;
510 }
511 void setAlignInterface(QPointer<QDBusInterface> newInterface)
512 {
513 m_alignInterface = newInterface;
514 }
515 QPointer<QDBusInterface> guideInterface() const
516 {
517 return m_guideInterface;
518 }
519 void setGuideInterface(QPointer<QDBusInterface> newInterface)
520 {
521 m_guideInterface = newInterface;
522 }
523 QPointer<QDBusInterface> observatoryInterface() const
524 {
525 return m_observatoryInterface;
526 }
527 void setObservatoryInterface(QPointer<QDBusInterface> newInterface)
528 {
529 m_observatoryInterface = newInterface;
530 }
531 QPointer<QDBusInterface> domeInterface() const
532 {
533 return m_domeInterface;
534 }
535 void setDomeInterface(QPointer<QDBusInterface> newInterface)
536 {
537 m_domeInterface = newInterface;
538 }
539 QPointer<QDBusInterface> weatherInterface() const
540 {
541 return m_weatherInterface;
542 }
543 void setWeatherInterface(QPointer<QDBusInterface> newInterface)
544 {
545 m_weatherInterface = newInterface;
546 }
547 QPointer<QDBusInterface> capInterface() const
548 {
549 return m_capInterface;
550 }
551 void setCapInterface(QPointer<QDBusInterface> newInterface)
552 {
553 m_capInterface = newInterface;
554 }
555
556 /**
557 * @brief createJobSequence Creates a job sequence for the mosaic tool given the prefix and output dir. The currently selected sequence file is modified
558 * and a new version given the supplied parameters are saved to the output directory
559 * @param prefix Prefix to set for the job sequence
560 * @param outputDir Output dir to set for the job sequence
561 * @return True if new file is saved, false otherwise
562 */
563 bool createJobSequence(XMLEle *root, const QString &prefix, const QString &outputDir);
564
565 /**
566 * @brief getSequenceJobRoot Read XML data from capture sequence job
567 * @param filename
568 * @return
569 */
570 XMLEle *getSequenceJobRoot(const QString &filename) const;
571
572 /**
573 * @brief getGuidingStatus Retrieve the guiding status.
574 */
575 GuideState getGuidingStatus();
576
577 QProcess &scriptProcess()
578 {
579 return m_scriptProcess;
580 }
581
582 const QString &profile() const;
583 void setProfile(const QString &newProfile);
584
585 QString currentJobName();
586 QString currentJobJson();
587 QString jsonJobs();
588
589 QStringList logText();
590
591signals:
592 // new log text for the module log window
593 void newLog(const QString &text);
594 // status updates
595 void newStatus(SchedulerState state);
596 void newWeatherStatus(ISD::Weather::Status state);
597 void schedulerStopped();
598 void shutdownStarted();
599 void schedulerSleeping(bool shutdown, bool sleep);
600 void schedulerPaused();
601 void changeSleepLabel(QString text, bool show = true);
602 // state changes
603 void jobsUpdated(QJsonArray jobsList);
604 void updateJobTable(SchedulerJob *job = nullptr);
605 void clearJobTable();
606 void changeCurrentSequence(const QString &sequenceFileURL);
607 void interfaceReady(QDBusInterface *iface);
608 // loading jobs
609 void addJob(SchedulerJob *job);
610 void syncGreedyParams();
611 void syncGUIToGeneralSettings();
612 void updateSchedulerURL(const QString &fileURL);
613 // distance in arc-seconds measured by plate solving the a captured image and
614 // comparing that position to the target position.
615 void targetDistance(double distance);
616 // required for Analyze timeline
617 void jobStarted(const QString &jobName);
618 void jobEnded(const QString &jobName, const QString &endReason);
619
620
621private slots:
622 void setINDICommunicationStatus(Ekos::CommunicationStatus status);
623 void setEkosCommunicationStatus(Ekos::CommunicationStatus status);
624
625 /**
626 * @brief syncProperties Sync startup properties from the various device to enable/disable features in the scheduler
627 * like the ability to park/unpark..etc
628 */
629 void syncProperties()
630 {
631 checkInterfaceReady(qobject_cast<QDBusInterface*>(sender()));
632 }
633
634 // ////////////////////////////////////////////////////////////////////
635 // alignment checks
636 // ////////////////////////////////////////////////////////////////////
637
638 /**
639 * @brief checkAlignment Handle one sequence image completion. This is used now only to run alignment check
640 * to ensure it does not deviation from current scheduler job target.
641 * @param metadata Metadata for image including filename, exposure, filter, hfr..etc.
642 * @param trainname name of the optical train that has captured the image
643 */
644 void checkAlignment(const QVariantMap &metadata, const QString &trainname);
645
646 /**
647 * @brief solverDone Process solver solution after it is done.
648 * @param timedOut True if the process timed out.
649 * @param success True if successful, false otherwise.
650 * @param solution The solver solution if successful.
651 * @param elapsedSeconds How many seconds elapsed to solve the image.
652 */
653 void solverDone(bool timedOut, bool success, const FITSImage::Solution &solution, double elapsedSeconds);
654
655 /**
656 * @brief checkInterfaceReady Sometimes syncProperties() is not sufficient since the ready signal could have fired already
657 * and cannot be relied on to know once a module interface is ready. Therefore, we explicitly check if the module interface
658 * is ready.
659 * @param iface interface to test for readiness.
660 */
661 void checkInterfaceReady(QDBusInterface *iface);
662
663 /**
664 * @brief registerNewModule Register an Ekos module as it arrives via DBus
665 * and create the appropriate DBus interface to communicate with it.
666 * @param name of module
667 */
668 void registerNewModule(const QString &name);
669
670 /**
671 * @brief registerNewDevice register interfaces associated with devices
672 * @param name Device name
673 * @param interface Device driver interface
674 */
675 void registerNewDevice(const QString &name, int interface);
676
677 // ////////////////////////////////////////////////////////////////////
678 // device handling
679 // ////////////////////////////////////////////////////////////////////
680 void setAlignStatus(Ekos::AlignState status);
681 void setGuideStatus(Ekos::GuideState status);
682 void setCaptureStatus(Ekos::CaptureState status, const QString &trainname);
683 void setFocusStatus(Ekos::FocusState status, const QString &trainname);
684 void setMountStatus(ISD::Mount::Status status);
685 void setWeatherStatus(ISD::Weather::Status status);
686
687private:
688 // When a module is commanded to perform an action, wait this many milliseconds
689 // before check its state again. If State is still IDLE, then it either didn't received the command
690 // or there is another problem.
691 static const uint32_t ALIGN_INACTIVITY_TIMEOUT = 120000;
692 static const uint32_t FOCUS_INACTIVITY_TIMEOUT = 120000;
693 static const uint32_t CAPTURE_INACTIVITY_TIMEOUT = 120000;
694 static const uint16_t GUIDE_INACTIVITY_TIMEOUT = 60000;
695 /// Counter to keep debug logging in check
696 uint8_t checkJobStageCounter { 0 };
697
698 // Startup and Shutdown scripts process
699 QProcess m_scriptProcess;
700 // solver for alignment checks
702
703 // mapping train name --> scheduler job
704 QMap<QString, SchedulerJob*> m_activeJobs;
705
706 // ////////////////////////////////////////////////////////////////////
707 // DBUS interfaces
708 // ////////////////////////////////////////////////////////////////////
709 // Interface strings for the dbus. Changeable for mocks when testing. Private so only tests can change.
710 QString schedulerProcessPathString { "/KStars/Ekos/Scheduler" };
711 QString kstarsInterfaceString { "org.kde.kstars" };
712 // This is only used in the constructor
713 QString ekosInterfaceString { "org.kde.kstars.Ekos" };
714 QString ekosPathString { "/KStars/Ekos" };
715 QString INDIInterfaceString { "org.kde.kstars.INDI" };
716 QString INDIPathString {"/KStars/INDI"};
717 // DBus interfaces to devices
718 QPointer<QDBusInterface> m_ekosInterface { nullptr };
719 QPointer<QDBusInterface> m_indiInterface { nullptr };
720 QPointer<QDBusInterface> m_focusInterface { nullptr };
721 QPointer<QDBusInterface> m_captureInterface { nullptr };
722 QPointer<QDBusInterface> m_mountInterface { nullptr };
723 QPointer<QDBusInterface> m_alignInterface { nullptr };
724 QPointer<QDBusInterface> m_guideInterface { nullptr };
725 QPointer<QDBusInterface> m_observatoryInterface { nullptr };
726 QPointer<QDBusInterface> m_domeInterface { nullptr };
727 QPointer<QDBusInterface> m_weatherInterface { nullptr };
728 QPointer<QDBusInterface> m_capInterface { nullptr };
729 // ////////////////////////////////////////////////////////////////////
730 // process steps
731 // ////////////////////////////////////////////////////////////////////
732
733 /**
734 * @brief executeScript Execute pre- or post job script
735 */
736 void executeScript(const QString &filename);
737
738 /**
739 * @brief stopEkos shutdown Ekos completely
740 */
741 void stopEkos();
742
743 /**
744 * @brief checkMountParkingStatus check mount parking status and updating corresponding states accordingly.
745 */
746 void checkMountParkingStatus();
747
748 /**
749 * @brief checkDomeParkingStatus check dome parking status and updating corresponding states accordingly.
750 */
751 void checkDomeParkingStatus();
752
753 /**
754 * @brief startFocusing Start focusing on the job
755 */
756 void startFocusing(SchedulerJob *job);
757 // ////////////////////////////////////////////////////////////////////
758 // device handling
759 // ////////////////////////////////////////////////////////////////////
760 /**
761 * @brief parkCap Close dust cover
762 */
763 void parkCap();
764
765 /**
766 * @brief unCap Open dust cover
767 */
768 void unParkCap();
769
770 /**
771 * @brief parkMount Park mount
772 */
773 void parkMount();
774
775 /**
776 * @brief unParkMount Unpark mount
777 */
778 void unParkMount();
779
780 /**
781 * @brief parkDome Park dome
782 */
783 void parkDome();
784
785 /**
786 * @brief unParkDome Unpark dome
787 */
788 void unParkDome();
789
790 // ////////////////////////////////////////////////////////////////////
791 // helper functions
792 // ////////////////////////////////////////////////////////////////////
793
794 /**
795 * @brief checkStartupProcedure restart regularly {@see #checkStartupState()} until completed
796 */
797 void checkStartupProcedure();
798
799 /**
800 * @brief checkShutdownProcedure Check regularly if the shutdown has completed (see
801 * {@see #checkShutdownState()}) and stop EKOS if the corresponding configuration flag is set.
802 */
803 void checkShutdownProcedure();
804
805 /**
806 * @brief checkProcessExit Check script process exist status. This is called when the process exists either normally or abnormally.
807 * @param exitCode exit code from the script process. Depending on the exist code, the status of startup/shutdown procedure is set accordingly.
808 */
809 void checkProcessExit(int exitCode);
810
811 /**
812 * @brief readProcessOutput read running script process output and display it in Ekos
813 */
814 void readProcessOutput();
815
816 /**
817 * @brief Returns true if the job is storing its captures on the same machine as the scheduler.
818 */
819 bool canCountCaptures(const SchedulerJob &job);
820
821 /**
822 * @brief activeJob Shortcut to the active job held in the state machine
823 */
824 SchedulerJob *activeJob();
825
826 // Prints all the relative state variables set during an iteration. For debugging.
827 void printStates(const QString &label);
828
829 /**
830 * @brief Abort capturing
831 * @param train train name, if empty abort the master job, otherwise abort this job's capture
832 * @param followersOnly if true and train name is empty, do not abort the lead, but all its followers
833 */
834 void stopCapturing(QString train = "", bool followersOnly = false);
835};
836} // Ekos namespace
Q_SCRIPTABLE Q_NOREPLY void startAstrometry()
startAstrometry initiation of the capture and solve operation.
bool shouldSchedulerSleep(SchedulerJob *job)
shouldSchedulerSleep Check if the scheduler needs to sleep until the job is ready
Q_SCRIPTABLE Q_NOREPLY void startCapture(bool restart=false)
startCapture The current job file name is solved to an url which is fed to ekos.
void loadProfiles()
loadProfiles Load the existing EKOS profiles
Q_SCRIPTABLE Q_NOREPLY void runStartupProcedure()
runStartupProcedure Execute the startup of the scheduler itself to be prepared for running scheduler ...
void checkCapParkingStatus()
checkDomeParkingStatus check dome parking status and updating corresponding states accordingly.
void getNextAction()
getNextAction Checking for the next appropriate action regarding the current state of the scheduler a...
Q_SCRIPTABLE bool isMountParked()
Q_SCRIPTABLE Q_NOREPLY void startJobEvaluation()
startJobEvaluation Start job evaluation only without starting the scheduler process itself.
Q_SCRIPTABLE Q_NOREPLY void resetJobs()
resetJobs Reset all jobs counters
void selectActiveJob(const QList< SchedulerJob * > &jobs)
selectActiveJob Select the job that should be executed
Q_SCRIPTABLE void wakeUpScheduler()
wakeUpScheduler Wake up scheduler from sleep state
Q_SCRIPTABLE Q_NOREPLY void setPaused()
setPaused pausing the scheduler
Q_SCRIPTABLE bool checkParkWaitState()
checkParkWaitState Check park wait state.
bool executeJob(SchedulerJob *job)
executeJob After the best job is selected, we call this in order to start the process that will execu...
bool createJobSequence(XMLEle *root, const QString &prefix, const QString &outputDir)
createJobSequence Creates a job sequence for the mosaic tool given the prefix and output dir.
void iterate()
Repeatedly runs a scheduler iteration and then sleeps timerInterval millisconds and run the next iter...
Q_SCRIPTABLE Q_NOREPLY void startGuiding(bool resetCalibration=false)
startGuiding After ekos is fed the calibration options, we start the guiding process
void findNextJob()
findNextJob Check if the job met the completion criteria, and if it did, then it search for next job ...
Q_SCRIPTABLE bool appendEkosScheduleList(const QString &fileURL)
appendEkosScheduleList Append the contents of an ESL file to the queue.
Q_SCRIPTABLE void execute()
execute Execute the schedule, start if idle or paused.
Q_SCRIPTABLE bool isDomeParked()
Q_SCRIPTABLE bool saveScheduler(const QUrl &fileURL)
saveScheduler Save scheduler jobs to a file
Q_SCRIPTABLE Q_NOREPLY void appendLogText(const QString &logentry) override
appendLogText Append a new line to the logging.
Q_SCRIPTABLE Q_NOREPLY void start()
DBUS interface function.
Q_SCRIPTABLE Q_NOREPLY void removeAllJobs()
DBUS interface function.
Q_SCRIPTABLE void stopCurrentJobAction()
stopCurrentJobAction Stop whatever action taking place in the current job (eg.
Q_SCRIPTABLE Q_NOREPLY void stopGuiding()
stopGuiding After guiding is done we need to stop the process
bool checkShutdownState()
checkShutdownState Check shutdown procedure stages and make sure all stages are complete.
Q_SCRIPTABLE Q_NOREPLY void startSlew()
startSlew DBus call for initiating slew
bool checkEkosState()
checkEkosState Check ekos startup stages and take whatever action necessary to get Ekos up and runnin...
bool checkStatus()
checkJobStatus Check the overall state of the scheduler, Ekos, and INDI.
bool checkINDIState()
checkINDIState Check INDI startup stages and take whatever action necessary to get INDI devices conne...
XMLEle * getSequenceJobRoot(const QString &filename) const
getSequenceJobRoot Read XML data from capture sequence job
Q_SCRIPTABLE Q_NOREPLY void runShutdownProcedure()
runShutdownProcedure Shutdown the scheduler itself and EKOS (if configured to do so).
Q_SCRIPTABLE Q_NOREPLY void setSequence(const QString &sequenceFileURL)
DBUS interface function.
Q_SCRIPTABLE bool loadScheduler(const QString &fileURL)
DBUS interface function.
Q_SCRIPTABLE Q_NOREPLY void startFocusing()
startFocusing DBus call for feeding ekos the specified settings and initiating focus operation
void checkJobStage()
checkJobStage Check the progress of the job states and make DBUS calls to start the next stage until ...
bool checkStartupState()
checkStartupState Check startup procedure stages and make sure all stages are complete.
void processGuidingTimer()
processGuidingTimer Check the guiding timer, and possibly restart guiding.
SkyPoint mountCoords()
mountCoords read the equatorial coordinates from the mount
GuideState getGuidingStatus()
getGuidingStatus Retrieve the guiding status.
Q_SCRIPTABLE Q_NOREPLY void resetAllJobs()
DBUS interface function.
void applyConfig()
applyConfig Apply configuration changes from the global configuration dialog.
Q_SCRIPTABLE void clearLog()
clearLog Clear log entry
Q_SCRIPTABLE Q_NOREPLY void disconnectINDI()
disconnectINDI disconnect all INDI devices from server.
Q_SCRIPTABLE Q_NOREPLY void stop()
DBUS interface function.
bool manageConnectionLoss()
manageConnectionLoss Mitigate loss of connection with the INDI server.
void updateCompletedJobsCount(bool forced=false)
updateCompletedJobsCount For each scheduler job, examine sequence job storage and count captures.
Q_SCRIPTABLE Q_NOREPLY void evaluateJobs(bool evaluateOnly)
evaluateJobs evaluates the current state of each objects and gives each one a score based on the cons...
int runSchedulerIteration()
Run a single scheduler iteration.
void setSolverAction(Align::GotoMode mode)
setSolverAction set the GOTO mode for the solver
Q_SCRIPTABLE bool completeShutdown()
completeShutdown Try to complete the scheduler shutdown
The sky coordinates of a point in the sky.
Definition skypoint.h:45
Ekos is an advanced Astrophotography tool for Linux.
Definition align.cpp:83
AlignState
Definition ekos.h:145
CaptureState
Capture states.
Definition ekos.h:92
QObject(QObject *parent)
Q_CLASSINFO(Name, Value)
Q_OBJECTQ_OBJECT
Q_PROPERTY(...)
T qobject_cast(QObject *object)
QObject * sender() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Feb 28 2025 11:56:01 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.