Kstars

scheduler.h
1/*
2 SPDX-FileCopyrightText: 2015 Jasem Mutlaq <mutlaqja@ikarustech.com>
3
4 DBus calls from GSoC 2015 Ekos Scheduler project:
5 SPDX-FileCopyrightText: 2015 Daniel Leu <daniel_mihai.leu@cti.pub.ro>
6
7 SPDX-License-Identifier: GPL-2.0-or-later
8*/
9
10#pragma once
11
12#include "ui_scheduler.h"
13#include "schedulertypes.h"
14#include "ekos/align/align.h"
15#include "indi/indiweather.h"
16#include "schedulerjob.h"
17
18#include <lilxml.h>
19
20#include <QTime>
21#include <QTimer>
22#include <QUrl>
23#include <QDBusInterface>
24
25#include <cstdint>
26
28
29class GeoLocation;
30class SkyObject;
31class KConfigDialog;
32class TestSchedulerUnit;
33class SolverUtils;
34class TestEkosSchedulerOps;
35
36namespace Ekos
37{
38
39class SequenceJob;
40class GreedyScheduler;
41class SchedulerProcess;
42class SchedulerModuleState;
43class SequenceEditor;
44
45/**
46 * @brief The Ekos scheduler is a simple scheduler class to orchestrate automated multi object observation jobs.
47 * @author Jasem Mutlaq
48 * @version 1.2
49 */
50class Scheduler : public QWidget, public Ui::Scheduler
51{
53
54 friend class FramingAssistantUI;
55
56public:
57
58 /** @brief Columns, in the same order as UI. */
59 typedef enum
60 {
61 SCHEDCOL_NAME = 0,
62 SCHEDCOL_STATUS,
63 SCHEDCOL_CAPTURES,
64 SCHEDCOL_ALTITUDE,
65 SCHEDCOL_STARTTIME,
66 SCHEDCOL_ENDTIME,
68
69 /** @brief Constructor, the starndard scheduler constructor. */
70 Scheduler();
71 /** @brief DebugConstructor, a constructor used in testing with a mock ekos. */
72 Scheduler(const QString path, const QString interface,
74 ~Scheduler() = default;
75
76 QString getCurrentJobName();
77
78 // shortcut
79 SchedulerJob *activeJob();
80
81 /**
82 * @brief handleConfigChanged Update UI after changes to the global configuration
83 */
85
86 void addObject(SkyObject *object);
87
88 /**
89 * @brief importMosaic Import mosaic into planner and generate jobs for the scheduler.
90 * @param payload metadata for the mosaic information.
91 * @note Only Telescopius.com mosaic format is now supported.
92 */
93 bool importMosaic(const QJsonObject &payload);
94
95 /** @defgroup SchedulerDBusInterface Ekos DBus Interface - Scheduler Module
96 * Ekos::Align interface provides primary functions to run and stop the scheduler.
97 */
98
99 /*@{*/
100
101 /**
102 * @brief Set the file URL pointing to the capture sequence file
103 * @param sequenceFileURL URL of the capture sequence file
104 */
106
107 /** DBUS interface function.
108 * @brief Resets all jobs to IDLE
109 */
111
112 void setProfile(const QString &profile)
113 {
114 schedulerProfileCombo->setCurrentText(profile);
115 }
116 QString profile()
117 {
118 return schedulerProfileCombo->currentText();
119 }
120
121 /**
122 * @brief retrieve the error handling strategy from the UI
123 */
125
126 /**
127 * @brief select the error handling strategy (no restart, restart after all terminated, restart immediately)
128 */
130
131 /** @}*/
132
133 // TODO: This section of static public and private methods should someday
134 // be moved from Scheduler and placed in a separate class,
135 // e.g. SchedulerPlanner or SchedulerJobEval
136 /**
137 * @brief Remove a job from current table row.
138 * @param index
139 */
140 void removeJob();
141
142 /**
143 * @brief Remove a job by selecting a table row.
144 * @param index
145 */
146 void removeOneJob(int index);
147
148 /**
149 * @brief addJob Add a new job from form values
150 */
151 void addJob(SchedulerJob *job = nullptr);
152
153 /**
154 * @brief createJob Create a new job from form values.
155 * @param job job to be filled from UI values
156 * @return true iff update was successful
157 */
158 bool fillJobFromUI(SchedulerJob *job);
159
160 /**
161 * @brief addToQueue Construct a SchedulerJob and add it to the queue or save job settings from current form values.
162 * jobUnderEdit determines whether to add or edit
163 */
164 void saveJob(SchedulerJob *job = nullptr);
165
166 void toggleScheduler();
167
168 QJsonObject getSchedulerSettings();
169
170 // the state machine
171 QSharedPointer<SchedulerModuleState> moduleState() const
172 {
173 return m_moduleState;
174 }
175 // the process engine
177 {
178 return m_process;
179 }
180
181 /**
182 * @brief saveFile Save scheduler jobs to disk
183 * @param path Path to esl file to save jobs to
184 * @return True if successful, false otherwise
185 */
186 bool saveFile(const QUrl &path);
187
188 /**
189 * @brief loadFile Load scheduler jobs from disk
190 * @param path Oath to esl file to load jobs from
191 * @return True if successful, false otherwise
192 */
193 bool loadFile(const QUrl &path);
194
195 // Settings
196 QVariantMap getAllSettings() const;
197 void setAllSettings(const QVariantMap &settings);
198
199private:
200
201 void setAlgorithm(int alg);
202
203 friend TestSchedulerUnit;
204
205 // TODO: See above TODO. End of static methods that might be moved to
206 // a separate Scheduler-related class.
207
208 /*@{*/
209 /** @internal Safeguard flag to avoid registering signals from widgets multiple times.
210 */
211 bool jobChangesAreWatched { false };
212
213protected:
214
215 /** @internal Enables signal watch on SchedulerJob form values in order to apply changes to current job.
216 * @param enable is the toggle flag, true to watch for changes, false to ignore them.
217 */
218 void watchJobChanges(bool enable);
219
220 /** @internal Marks the currently selected SchedulerJob as modified change.
221 *
222 * This triggers job re-evaluation.
223 * Next time save button is invoked, the complete content is written to disk.
224 */
225 void setDirty();
226 /** @} */
227
228 /**
229 * @brief updateJobTable Update the job's row in the job table. If the row does not exist, it will
230 * be created on the fly. If job is null, update the entire table
231 * @param job
232 */
233 void updateJobTable(SchedulerJob *job = nullptr);
234
235 /**
236 * @brief insertJobTableRow Insert a new row (empty) into the job table
237 * @param row row number (starting with 0)
238 * @param above insert above the given row (=true) or below (=false)
239 */
240 void insertJobTableRow(int row, bool above = true);
241
242 /**
243 * @brief Update the style of a cell, depending on the job's state
244 */
245 void updateCellStyle(SchedulerJob *job, QTableWidgetItem *cell);
246
247protected slots:
248
249 /**
250 * @brief checkInterfaceReady Sometimes syncProperties() is not sufficient since the ready signal could have fired already
251 * and cannot be relied on to know once a module interface is ready. Therefore, we explicitly check if the module interface
252 * is ready.
253 * @param iface interface to test for readiness.
254 */
256
257 void setWeatherStatus(ISD::Weather::Status status);
258
259 /**
260 * @brief select object from KStars's find dialog.
261 */
262 void selectObject();
263
264 /**
265 * @brief Selects FITS file for solving.
266 */
267 void selectFITS();
268
269 /**
270 * @brief Selects sequence queue.
271 */
272 void selectSequence();
273
274 /**
275 * @brief Selects sequence queue.
276 */
277 void selectStartupScript();
278
279 /**
280 * @brief Selects sequence queue.
281 */
283
284 /**
285 * @brief editJob Edit an observation job
286 * @param i index model in queue table
287 */
288 void loadJob(QModelIndex i);
289
290 /**
291 * @brief updateSchedulerURL Update scheduler URL after succesful loading a new file.
292 */
294
295 /**
296 * @brief setJobAddApply Set first button state to add new job or apply changes.
297 */
298 void setJobAddApply(bool add_mode);
299
300 /**
301 * @brief setJobManipulation Enable or disable job manipulation buttons.
302 */
304
305 /**
306 * @brief set all GUI fields to the values of the given scheduler job
307 */
308 void syncGUIToJob(SchedulerJob *job);
309
310 /**
311 * @brief syncGUIToGeneralSettings set all UI fields that are not job specific
312 */
314
315 /**
316 * @brief jobSelectionChanged Update UI state when the job list is clicked once.
317 */
318 void clickQueueTable(QModelIndex index);
319
320 /**
321 * @brief clearJobTable delete all rows in the job table
322 */
323 void clearJobTable();
324
325 /**
326 * @brief clearLog Clears log entry
327 */
328 Q_INVOKABLE void clearLog();
329
330 /**
331 * @brief Update scheduler parameters to the currently selected scheduler job
332 * @param selected table position
333 * @param deselected table position
334 */
336
337 /**
338 * @brief reorderJobs Change the order of jobs in the UI based on a subset of its jobs.
339 */
341
342 /**
343 * @brief moveJobUp Move the selected job up in the job list.
344 */
345 void moveJobUp();
346
347 /**
348 * @brief moveJobDown Move the selected job down in the list.
349 */
350 void moveJobDown();
351
352 /**
353 * @brief handleSchedulerSleeping Update UI if scheduler is set to sleep
354 * @param shutdown flag if a preemptive shutdown is executed
355 * @param sleep flag if the scheduler will sleep
356 */
357 void handleSchedulerSleeping(bool shutdown, bool sleep);
358
359 /**
360 * @brief handleSchedulerStateChanged Update UI when the scheduler state changes
361 */
363
364 /**
365 * @brief handleSetPaused Update the UI when {@see #setPaused()} is called.
366 */
367 void handleSetPaused();
368
369 void pause();
370 bool save();
371 void saveAs();
372
373 /**
374 * @brief load Open a file dialog to select an ESL file, and load its contents.
375 * @param clearQueue Clear the queue before loading, or append ESL contents to queue.
376 * @param filename If not empty, this file will be used instead of poping up a dialog.
377 */
378 bool load(bool clearQueue, const QString &filename = QString());
379
380 void resetJobEdit();
381
382 /**
383 * @brief updateNightTime update the Twilight restriction with the argument job properties.
384 * @param job SchedulerJob for which to display the next dawn and dusk, or the job currently selected if null, or today's next dawn and dusk if no job is selected.
385 */
386 void updateNightTime(SchedulerJob const * job = nullptr);
387
388 /**
389 * @brief schedulerStopped React when the process engine has stopped the scheduler
390 */
391 void schedulerStopped();
392
393 /**
394 * @brief resumeCheckStatus If the scheduler primary loop was suspended due to weather or sleep event, resume it again.
395 */
396 void resumeCheckStatus();
397
398 /**
399 * @brief checkWeather Check weather status and act accordingly depending on the current status of the scheduler and running jobs.
400 */
401 //void checkWeather();
402
403 /**
404 * @brief displayTwilightWarning Display twilight warning to user if it is unchecked.
405 */
406 void checkTwilightWarning(bool enabled);
407
408signals:
409 void newStatus(Ekos::SchedulerState state);
410 void weatherChanged(ISD::Weather::Status state);
411 void newTarget(const QString &);
412 // distance in arc-seconds measured by plate solving the a captured image and
413 // comparing that position to the target position.
414 void targetDistance(double distance);
415 // Below 2 are for the Analyze timeline.
416 void jobStarted(const QString &jobName);
417 void jobEnded(const QString &jobName, const QString &endReason);
418 void jobsUpdated(QJsonArray jobsList);
419 void settingsUpdated(const QVariantMap &settings);
420
421private:
422 /**
423 * @brief handleJobsUpdated Update UI when jobs have been updated
424 * @param jobsList
425 */
426 void handleJobsUpdated(QJsonArray jobsList);
427
428 /**
429 * @brief handleShutdownStarted Show that the shutdown has been started.
430 */
431 void handleShutdownStarted();
432
433 /**
434 * @brief processFITSSelection When a FITS file is selected, open it and try to guess
435 * the object name, and its J2000 RA/DE to fill the UI with such info automatically.
436 */
437 void processFITSSelection(const QUrl &url);
438
439 /**
440 * @brief updateProfiles React upon changed profiles and update the UI
441 */
442 void updateProfiles();
443
444 /**
445 * @brief updateStageLabel Helper function that updates the stage label.
446 */
447 void updateJobStageUI(SchedulerJobStage stage);
448
449 ////////////////////////////////////////////////////////////////////
450 /// Settings
451 ////////////////////////////////////////////////////////////////////
452
453 /**
454 * @brief Connect GUI elements to sync settings once updated.
455 */
456 void connectSettings();
457 /**
458 * @brief Stop updating settings when GUI elements are updated.
459 */
460 void disconnectSettings();
461 /**
462 * @brief loadSettings Load setting from Options and set them accordingly.
463 */
464 void loadGlobalSettings();
465
466 /**
467 * @brief syncSettings When checkboxes, comboboxes, or spin boxes are updated, save their values in the
468 * global and per-train settings.
469 */
470 void syncSettings();
471
472 /**
473 * @brief syncControl Sync setting to widget. The value depends on the widget type.
474 * @param settings Map of all settings
475 * @param key name of widget to sync
476 * @param widget pointer of widget to set
477 * @return True if sync successful, false otherwise
478 */
479 bool syncControl(const QVariantMap &settings, const QString &key, QWidget * widget);
480
481 /**
482 * @brief checkJobInputComplete Check if all inputs are filled such that a new job could be added.
483 */
484 void checkJobInputComplete();
485
486 Ekos::Scheduler *ui { nullptr };
487
488 // Interface strings for the dbus. Changeable for mocks when testing. Private so only tests can change.
489 QString schedulerPathString { "/KStars/Ekos/Scheduler" };
490 QString kstarsInterfaceString { "org.kde.kstars" };
491 // This is only used in the constructor
492 QString ekosInterfaceString { "org.kde.kstars.Ekos" };
493 QString ekosPathString { "/KStars/Ekos" };
494
495 // the state machine holding all states
497 // process engine implementing all process steps
499
500 // react upon changes of EKOS and INDI state
501 void ekosStateChanged(EkosState state);
502 void indiStateChanged(INDIState state);
503
504 // react upon state changes
505 void startupStateChanged(StartupState state);
506 void shutdownStateChanged(ShutdownState state);
507 void parkWaitStateChanged(ParkWaitState state);
508
509 /// URL to store the scheduler file
510 QUrl schedulerURL;
511 /// URL for Ekos Sequence
512 QUrl sequenceURL;
513 /// FITS URL to solve
514 QUrl fitsURL;
515 /// Busy indicator widget
516 QProgressIndicator *pi { nullptr };
517 /// Are we editing a job right now? Job row index
518 int jobUnderEdit { -1 };
519 /// Pointer to Geographic location
520 GeoLocation *geo { nullptr };
521
522 /// Call checkWeather when weatherTimer time expires. It is equal to the UpdatePeriod time in INDI::Weather device.
523 //QTimer weatherTimer;
524
525 QUrl dirPath;
526
527 // update the sleep label and its visibility
528 void changeSleepLabel(QString text, bool show = true);
529 // Used by the constructor in testing mainly so a mock ekos could be used.
530 void setupScheduler(const QString &ekosPathStr, const QString &ekosInterfaceStr);
531
532
533 /// Target coordinates for pointing check
535
536 void syncGreedyParams();
537
538 friend TestEkosSchedulerOps;
539
540 QSharedPointer<SequenceEditor> m_SequenceEditor;
541
542 QTimer m_JobUpdateDebounce;
543 QVariantMap m_Settings;
544 QVariantMap m_GlobalSettings;
545};
546}
The Ekos scheduler is a simple scheduler class to orchestrate automated multi object observation jobs...
Definition scheduler.h:51
ErrorHandlingStrategy getErrorHandlingStrategy()
retrieve the error handling strategy from the UI
void moveJobUp()
moveJobUp Move the selected job up in the job list.
void watchJobChanges(bool enable)
Q_INVOKABLE void clearLog()
clearLog Clears log entry
void checkTwilightWarning(bool enabled)
checkWeather Check weather status and act accordingly depending on the current status of the schedule...
void saveJob(SchedulerJob *job=nullptr)
addToQueue Construct a SchedulerJob and add it to the queue or save job settings from current form va...
void updateSchedulerURL(const QString &fileURL)
updateSchedulerURL Update scheduler URL after succesful loading a new file.
void addJob(SchedulerJob *job=nullptr)
addJob Add a new job from form values
void selectSequence()
Selects sequence queue.
void insertJobTableRow(int row, bool above=true)
insertJobTableRow Insert a new row (empty) into the job table
bool load(bool clearQueue, const QString &filename=QString())
load Open a file dialog to select an ESL file, and load its contents.
void resumeCheckStatus()
resumeCheckStatus If the scheduler primary loop was suspended due to weather or sleep event,...
void handleSchedulerSleeping(bool shutdown, bool sleep)
handleSchedulerSleeping Update UI if scheduler is set to sleep
void setJobManipulation(bool can_reorder, bool can_delete)
setJobManipulation Enable or disable job manipulation buttons.
void moveJobDown()
moveJobDown Move the selected job down in the list.
bool importMosaic(const QJsonObject &payload)
importMosaic Import mosaic into planner and generate jobs for the scheduler.
void handleSetPaused()
handleSetPaused Update the UI when {
bool reorderJobs(QList< SchedulerJob * > reordered_sublist)
reorderJobs Change the order of jobs in the UI based on a subset of its jobs.
void syncGUIToGeneralSettings()
syncGUIToGeneralSettings set all UI fields that are not job specific
void updateNightTime(SchedulerJob const *job=nullptr)
updateNightTime update the Twilight restriction with the argument job properties.
bool loadFile(const QUrl &path)
loadFile Load scheduler jobs from disk
void handleSchedulerStateChanged(SchedulerState newState)
handleSchedulerStateChanged Update UI when the scheduler state changes
bool fillJobFromUI(SchedulerJob *job)
createJob Create a new job from form values.
void loadJob(QModelIndex i)
editJob Edit an observation job
void setSequence(const QString &sequenceFileURL)
Set the file URL pointing to the capture sequence file.
void selectStartupScript()
Selects sequence queue.
void syncGUIToJob(SchedulerJob *job)
set all GUI fields to the values of the given scheduler job
void schedulerStopped()
schedulerStopped React when the process engine has stopped the scheduler
void selectObject()
select object from KStars's find dialog.
void updateCellStyle(SchedulerJob *job, QTableWidgetItem *cell)
Update the style of a cell, depending on the job's state.
void clearJobTable()
clearJobTable delete all rows in the job table
void setJobAddApply(bool add_mode)
setJobAddApply Set first button state to add new job or apply changes.
void handleConfigChanged()
handleConfigChanged Update UI after changes to the global configuration
bool saveFile(const QUrl &path)
saveFile Save scheduler jobs to disk
Q_SCRIPTABLE void sortJobsPerAltitude()
DBUS interface function.
void setErrorHandlingStrategy(ErrorHandlingStrategy strategy)
select the error handling strategy (no restart, restart after all terminated, restart immediately)
void clickQueueTable(QModelIndex index)
jobSelectionChanged Update UI state when the job list is clicked once.
void updateJobTable(SchedulerJob *job=nullptr)
updateJobTable Update the job's row in the job table.
void removeJob()
Remove a job from current table row.
void removeOneJob(int index)
Remove a job by selecting a table row.
void selectFITS()
Selects FITS file for solving.
Scheduler()
Constructor, the starndard scheduler constructor.
Definition scheduler.cpp:80
void interfaceReady(QDBusInterface *iface)
checkInterfaceReady Sometimes syncProperties() is not sufficient since the ready signal could have fi...
SchedulerColumns
Columns, in the same order as UI.
Definition scheduler.h:60
void queueTableSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
Update scheduler parameters to the currently selected scheduler job.
void selectShutdownScript()
Selects sequence queue.
Contains all relevant information for specifying a location on Earth: City Name, State/Province name,...
Definition geolocation.h:28
The QProgressIndicator class lets an application display a progress indicator to show that a long tas...
The SchedulerState class holds all attributes defining the scheduler's state.
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
Ekos is an advanced Astrophotography tool for Linux.
Definition align.cpp:79
ErrorHandlingStrategy
options what should happen if an error or abort occurs
Q_INVOKABLEQ_INVOKABLE
Q_OBJECTQ_OBJECT
void show()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 17 2024 11:48:26 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.