File indexing completed on 2024-05-05 07:42:11
0001 /* 0002 SPDX-FileCopyrightText: 2015 Jasem Mutlaq <mutlaqja@ikarustech.com> 0003 0004 DBus calls from GSoC 2015 Ekos Scheduler project: 0005 SPDX-FileCopyrightText: 2015 Daniel Leu <daniel_mihai.leu@cti.pub.ro> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 #pragma once 0011 0012 #include "ui_scheduler.h" 0013 #include "schedulertypes.h" 0014 #include "ekos/align/align.h" 0015 #include "indi/indiweather.h" 0016 #include "schedulerjob.h" 0017 #include "ekos/auxiliary/modulelogger.h" 0018 0019 #include <lilxml.h> 0020 0021 #include <QTime> 0022 #include <QTimer> 0023 #include <QUrl> 0024 #include <QDBusInterface> 0025 0026 #include <cstdint> 0027 0028 class QProgressIndicator; 0029 0030 class GeoLocation; 0031 class SkyObject; 0032 class KConfigDialog; 0033 class TestSchedulerUnit; 0034 class SolverUtils; 0035 class TestEkosSchedulerOps; 0036 0037 namespace Ekos 0038 { 0039 0040 class SequenceJob; 0041 class GreedyScheduler; 0042 class SchedulerProcess; 0043 class SchedulerModuleState; 0044 class SequenceEditor; 0045 0046 /** 0047 * @brief The Ekos scheduler is a simple scheduler class to orchestrate automated multi object observation jobs. 0048 * @author Jasem Mutlaq 0049 * @version 1.2 0050 */ 0051 class Scheduler : public QWidget, public Ui::Scheduler, public ModuleLogger 0052 { 0053 Q_OBJECT 0054 Q_CLASSINFO("D-Bus Interface", "org.kde.kstars.Ekos.Scheduler") 0055 Q_PROPERTY(Ekos::SchedulerState status READ status NOTIFY newStatus) 0056 Q_PROPERTY(QStringList logText READ logText NOTIFY newLog) 0057 Q_PROPERTY(QString profile READ profile WRITE setProfile) 0058 0059 friend class FramingAssistantUI; 0060 0061 public: 0062 0063 /** @brief Columns, in the same order as UI. */ 0064 typedef enum 0065 { 0066 SCHEDCOL_NAME = 0, 0067 SCHEDCOL_STATUS, 0068 SCHEDCOL_CAPTURES, 0069 SCHEDCOL_ALTITUDE, 0070 SCHEDCOL_STARTTIME, 0071 SCHEDCOL_ENDTIME, 0072 } SchedulerColumns; 0073 0074 /** @brief Constructor, the starndard scheduler constructor. */ 0075 Scheduler(); 0076 /** @brief DebugConstructor, a constructor used in testing with a mock ekos. */ 0077 Scheduler(const QString path, const QString interface, 0078 const QString &ekosPathStr, const QString &ekosInterfaceStr); 0079 ~Scheduler() = default; 0080 0081 QString getCurrentJobName(); 0082 0083 // shortcut 0084 SchedulerJob *activeJob(); 0085 0086 void appendLogText(const QString &) override; 0087 QStringList logText() 0088 { 0089 return m_LogText; 0090 } 0091 QString getLogText() 0092 { 0093 return m_LogText.join("\n"); 0094 } 0095 Q_SCRIPTABLE void clearLog(); 0096 void applyConfig(); 0097 0098 void addObject(SkyObject *object); 0099 0100 /** 0101 * @brief importMosaic Import mosaic into planner and generate jobs for the scheduler. 0102 * @param payload metadata for the mosaic information. 0103 * @note Only Telescopius.com mosaic format is now supported. 0104 */ 0105 bool importMosaic(const QJsonObject &payload); 0106 0107 /** @defgroup SchedulerDBusInterface Ekos DBus Interface - Scheduler Module 0108 * Ekos::Align interface provides primary functions to run and stop the scheduler. 0109 */ 0110 0111 /*@{*/ 0112 0113 /** DBUS interface function. 0114 * @brief Start the scheduler main loop and evaluate jobs and execute them accordingly. 0115 */ 0116 Q_SCRIPTABLE Q_NOREPLY void start(); 0117 0118 /** DBUS interface function. 0119 * @brief Stop the scheduler. 0120 */ 0121 Q_SCRIPTABLE Q_NOREPLY void stop(); 0122 0123 /** DBUS interface function. 0124 * @brief Remove all scheduler jobs 0125 */ 0126 Q_SCRIPTABLE Q_NOREPLY void removeAllJobs(); 0127 0128 /** DBUS interface function. 0129 * @brief Loads the Ekos Scheduler List (.esl) file. 0130 * @param fileURL path to a file 0131 * @return true if loading file is successful, false otherwise. 0132 */ 0133 Q_SCRIPTABLE bool loadScheduler(const QString &fileURL); 0134 0135 /** DBUS interface function. 0136 * @brief Set the file URL pointing to the capture sequence file 0137 * @param sequenceFileURL URL of the capture sequence file 0138 */ 0139 Q_SCRIPTABLE void setSequence(const QString &sequenceFileURL); 0140 0141 /** DBUS interface function. 0142 * @brief Resets all jobs to IDLE 0143 */ 0144 Q_SCRIPTABLE void resetAllJobs(); 0145 0146 /** DBUS interface function. 0147 * @brief Resets all jobs to IDLE 0148 */ 0149 Q_SCRIPTABLE void sortJobsPerAltitude(); 0150 0151 Ekos::SchedulerState status(); 0152 0153 void setProfile(const QString &profile) 0154 { 0155 schedulerProfileCombo->setCurrentText(profile); 0156 } 0157 QString profile() 0158 { 0159 return schedulerProfileCombo->currentText(); 0160 } 0161 0162 /** 0163 * @brief retrieve the error handling strategy from the UI 0164 */ 0165 ErrorHandlingStrategy getErrorHandlingStrategy(); 0166 0167 /** 0168 * @brief select the error handling strategy (no restart, restart after all terminated, restart immediately) 0169 */ 0170 void setErrorHandlingStrategy (ErrorHandlingStrategy strategy); 0171 0172 /** @}*/ 0173 0174 // TODO: This section of static public and private methods should someday 0175 // be moved from Scheduler and placed in a separate class, 0176 // e.g. SchedulerPlanner or SchedulerJobEval 0177 /** 0178 * @brief Remove a job from current table row. 0179 * @param index 0180 */ 0181 void removeJob(); 0182 0183 /** 0184 * @brief Remove a job by selecting a table row. 0185 * @param index 0186 */ 0187 void removeOneJob(int index); 0188 0189 /** 0190 * @brief addJob Add a new job from form values 0191 */ 0192 void addJob(SchedulerJob *job = nullptr); 0193 0194 /** 0195 * @brief createJob Create a new job from form values. 0196 * @param job job to be filled from UI values 0197 * @return true iff update was successful 0198 */ 0199 bool fillJobFromUI(SchedulerJob *job); 0200 0201 /** 0202 * @brief addToQueue Construct a SchedulerJob and add it to the queue or save job settings from current form values. 0203 * jobUnderEdit determines whether to add or edit 0204 */ 0205 void saveJob(SchedulerJob *job = nullptr); 0206 0207 void toggleScheduler(); 0208 0209 QJsonObject getSchedulerSettings(); 0210 /** 0211 * @brief createJobSequence Creates a job sequence for the mosaic tool given the prefix and output dir. The currently selected sequence file is modified 0212 * and a new version given the supplied parameters are saved to the output directory 0213 * @param prefix Prefix to set for the job sequence 0214 * @param outputDir Output dir to set for the job sequence 0215 * @return True if new file is saved, false otherwise 0216 */ 0217 bool createJobSequence(XMLEle *root, const QString &prefix, const QString &outputDir); 0218 0219 XMLEle *getSequenceJobRoot(const QString &filename); 0220 0221 /** 0222 * @brief saveScheduler Save scheduler jobs to a file 0223 * @param path path of a file 0224 * @return true on success, false on failure. 0225 */ 0226 Q_SCRIPTABLE bool saveScheduler(const QUrl &fileURL); 0227 0228 // the state machine 0229 QSharedPointer<SchedulerModuleState> moduleState() const 0230 { 0231 return m_moduleState; 0232 } 0233 0234 // Settings 0235 QVariantMap getAllSettings() const; 0236 void setAllSettings(const QVariantMap &settings); 0237 0238 private: 0239 0240 void setAlgorithm(int alg); 0241 0242 friend TestSchedulerUnit; 0243 0244 // TODO: See above TODO. End of static methods that might be moved to 0245 // a separate Scheduler-related class. 0246 0247 /*@{*/ 0248 /** @internal Safeguard flag to avoid registering signals from widgets multiple times. 0249 */ 0250 bool jobChangesAreWatched { false }; 0251 0252 protected: 0253 0254 /** @internal Enables signal watch on SchedulerJob form values in order to apply changes to current job. 0255 * @param enable is the toggle flag, true to watch for changes, false to ignore them. 0256 */ 0257 void watchJobChanges(bool enable); 0258 0259 /** @internal Marks the currently selected SchedulerJob as modified change. 0260 * 0261 * This triggers job re-evaluation. 0262 * Next time save button is invoked, the complete content is written to disk. 0263 */ 0264 void setDirty(); 0265 /** @} */ 0266 0267 /** 0268 * @brief updateJobTable Update the job's row in the job table. If the row does not exist, it will 0269 * be created on the fly. If job is null, update the entire table 0270 * @param job 0271 */ 0272 void updateJobTable(SchedulerJob *job = nullptr); 0273 0274 /** 0275 * @brief insertJobTableRow Insert a new row (empty) into the job table 0276 * @param row row number (starting with 0) 0277 * @param above insert above the given row (=true) or below (=false) 0278 */ 0279 void insertJobTableRow(int row, bool above = true); 0280 0281 /** 0282 * @brief Update the style of a cell, depending on the job's state 0283 */ 0284 void updateCellStyle(SchedulerJob *job, QTableWidgetItem *cell); 0285 0286 protected slots: 0287 0288 /** 0289 * @brief registerNewModule Register an Ekos module as it arrives via DBus 0290 * and create the appropriate DBus interface to communicate with it. 0291 * @param name of module 0292 */ 0293 void registerNewModule(const QString &name); 0294 0295 /** 0296 * @brief registerNewDevice register interfaces associated with devices 0297 * @param name Device name 0298 * @param interface Device driver interface 0299 */ 0300 void registerNewDevice(const QString &name, int interface); 0301 0302 /** 0303 * @brief syncProperties Sync startup properties from the various device to enable/disable features in the scheduler 0304 * like the ability to park/unpark..etc 0305 */ 0306 void syncProperties(); 0307 0308 /** 0309 * @brief checkInterfaceReady Sometimes syncProperties() is not sufficient since the ready signal could have fired already 0310 * and cannot be relied on to know once a module interface is ready. Therefore, we explicitly check if the module interface 0311 * is ready. 0312 * @param iface interface to test for readiness. 0313 */ 0314 void checkInterfaceReady(QDBusInterface *iface); 0315 0316 void setAlignStatus(Ekos::AlignState status); 0317 void setGuideStatus(Ekos::GuideState status); 0318 void setCaptureStatus(Ekos::CaptureState status); 0319 void setFocusStatus(Ekos::FocusState status); 0320 void setMountStatus(ISD::Mount::Status status); 0321 void setWeatherStatus(ISD::Weather::Status status); 0322 0323 /** 0324 * @brief select object from KStars's find dialog. 0325 */ 0326 void selectObject(); 0327 0328 /** 0329 * @brief Selects FITS file for solving. 0330 */ 0331 void selectFITS(); 0332 0333 /** 0334 * @brief Selects sequence queue. 0335 */ 0336 void selectSequence(); 0337 0338 /** 0339 * @brief Selects sequence queue. 0340 */ 0341 void selectStartupScript(); 0342 0343 /** 0344 * @brief Selects sequence queue. 0345 */ 0346 void selectShutdownScript(); 0347 0348 /** 0349 * @brief editJob Edit an observation job 0350 * @param i index model in queue table 0351 */ 0352 void loadJob(QModelIndex i); 0353 0354 /** 0355 * @brief updateSchedulerURL Update scheduler URL after succesful loading a new file. 0356 */ 0357 void updateSchedulerURL(const QString &fileURL); 0358 0359 /** 0360 * @brief setJobAddApply Set first button state to add new job or apply changes. 0361 */ 0362 void setJobAddApply(bool add_mode); 0363 0364 /** 0365 * @brief setJobManipulation Enable or disable job manipulation buttons. 0366 */ 0367 void setJobManipulation(bool can_reorder, bool can_delete); 0368 0369 /** 0370 * @brief set all GUI fields to the values of the given scheduler job 0371 */ 0372 void syncGUIToJob(SchedulerJob *job); 0373 0374 /** 0375 * @brief syncGUIToGeneralSettings set all UI fields that are not job specific 0376 */ 0377 void syncGUIToGeneralSettings(); 0378 0379 /** 0380 * @brief jobSelectionChanged Update UI state when the job list is clicked once. 0381 */ 0382 void clickQueueTable(QModelIndex index); 0383 0384 /** 0385 * @brief Update scheduler parameters to the currently selected scheduler job 0386 * @param selected table position 0387 * @param deselected table position 0388 */ 0389 void queueTableSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected); 0390 0391 /** 0392 * @brief reorderJobs Change the order of jobs in the UI based on a subset of its jobs. 0393 */ 0394 bool reorderJobs(QList<SchedulerJob*> reordered_sublist); 0395 0396 /** 0397 * @brief moveJobUp Move the selected job up in the job list. 0398 */ 0399 void moveJobUp(); 0400 0401 /** 0402 * @brief moveJobDown Move the selected job down in the list. 0403 */ 0404 void moveJobDown(); 0405 0406 /** 0407 * @brief handleSchedulerSleeping Update UI if scheduler is set to sleep 0408 * @param shutdown flag if a preemptive shutdown is executed 0409 * @param sleep flag if the scheduler will sleep 0410 */ 0411 void handleSchedulerSleeping(bool shutdown, bool sleep); 0412 0413 /** 0414 * @brief handleSchedulerStateChanged Update UI when the scheduler state changes 0415 */ 0416 void handleSchedulerStateChanged(SchedulerState newState); 0417 0418 /** 0419 * @brief handleSetPaused Update the UI when {@see #setPaused()} is called. 0420 */ 0421 void handleSetPaused(); 0422 0423 void pause(); 0424 void save(); 0425 void saveAs(); 0426 0427 /** 0428 * @brief load Open a file dialog to select an ESL file, and load its contents. 0429 * @param clearQueue Clear the queue before loading, or append ESL contents to queue. 0430 * @param filename If not empty, this file will be used instead of poping up a dialog. 0431 */ 0432 void load(bool clearQueue, const QString &filename = ""); 0433 0434 void resetJobEdit(); 0435 0436 /** 0437 * @brief updateNightTime update the Twilight restriction with the argument job properties. 0438 * @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. 0439 */ 0440 void updateNightTime(SchedulerJob const * job = nullptr); 0441 0442 /** 0443 * @brief schedulerStopped React when the process engine has stopped the scheduler 0444 */ 0445 void schedulerStopped(); 0446 0447 /** 0448 * @brief resumeCheckStatus If the scheduler primary loop was suspended due to weather or sleep event, resume it again. 0449 */ 0450 void resumeCheckStatus(); 0451 0452 /** 0453 * @brief checkWeather Check weather status and act accordingly depending on the current status of the scheduler and running jobs. 0454 */ 0455 //void checkWeather(); 0456 0457 /** 0458 * @brief startJobEvaluation Start job evaluation only without starting the scheduler process itself. Display the result to the user. 0459 */ 0460 void startJobEvaluation(); 0461 0462 /** 0463 * @brief displayTwilightWarning Display twilight warning to user if it is unchecked. 0464 */ 0465 void checkTwilightWarning(bool enabled); 0466 0467 void setINDICommunicationStatus(Ekos::CommunicationStatus status); 0468 void setEkosCommunicationStatus(Ekos::CommunicationStatus status); 0469 0470 void simClockScaleChanged(float); 0471 void simClockTimeChanged(); 0472 0473 /** 0474 * @brief solverDone Process solver solution after it is done. 0475 * @param timedOut True if the process timed out. 0476 * @param success True if successful, false otherwise. 0477 * @param solution The solver solution if successful. 0478 * @param elapsedSeconds How many seconds elapsed to solve the image. 0479 */ 0480 void solverDone(bool timedOut, bool success, const FITSImage::Solution &solution, double elapsedSeconds); 0481 0482 /** 0483 * @brief setCaptureComplete Handle one sequence image completion. This is used now only to run alignment check 0484 * to ensure it does not deviation from current scheduler job target. 0485 * @param metadata Metadata for image including filename, exposure, filter, hfr..etc. 0486 */ 0487 void setCaptureComplete(const QVariantMap &metadata); 0488 0489 signals: 0490 void newLog(const QString &text); 0491 void newStatus(Ekos::SchedulerState state); 0492 void weatherChanged(ISD::Weather::Status state); 0493 void newTarget(const QString &); 0494 // distance in arc-seconds measured by plate solving the a captured image and 0495 // comparing that position to the target position. 0496 void targetDistance(double distance); 0497 // Below 2 are for the Analyze timeline. 0498 void jobStarted(const QString &jobName); 0499 void jobEnded(const QString &jobName, const QString &endReason); 0500 void jobsUpdated(QJsonArray jobsList); 0501 void settingsUpdated(const QVariantMap &settings); 0502 0503 private: 0504 /** 0505 * @brief handleJobsUpdated Update UI when jobs have been updated 0506 * @param jobsList 0507 */ 0508 void handleJobsUpdated(QJsonArray jobsList); 0509 0510 /** 0511 * @brief handleShutdownStarted Show that the shutdown has been started. 0512 */ 0513 void handleShutdownStarted(); 0514 0515 /** 0516 * @brief processFITSSelection When a FITS file is selected, open it and try to guess 0517 * the object name, and its J2000 RA/DE to fill the UI with such info automatically. 0518 */ 0519 void processFITSSelection(const QUrl &url); 0520 0521 /** 0522 * @brief updateProfiles React upon changed profiles and update the UI 0523 */ 0524 void updateProfiles(); 0525 0526 /** 0527 * @brief updateStageLabel Helper function that updates the stage label. 0528 */ 0529 void updateJobStageUI(SchedulerJobStage stage); 0530 0531 //////////////////////////////////////////////////////////////////// 0532 /// Settings 0533 //////////////////////////////////////////////////////////////////// 0534 0535 /** 0536 * @brief Connect GUI elements to sync settings once updated. 0537 */ 0538 void connectSettings(); 0539 /** 0540 * @brief Stop updating settings when GUI elements are updated. 0541 */ 0542 void disconnectSettings(); 0543 /** 0544 * @brief loadSettings Load setting from Options and set them accordingly. 0545 */ 0546 void loadGlobalSettings(); 0547 0548 /** 0549 * @brief syncSettings When checkboxes, comboboxes, or spin boxes are updated, save their values in the 0550 * global and per-train settings. 0551 */ 0552 void syncSettings(); 0553 0554 /** 0555 * @brief syncControl Sync setting to widget. The value depends on the widget type. 0556 * @param settings Map of all settings 0557 * @param key name of widget to sync 0558 * @param widget pointer of widget to set 0559 * @return True if sync successful, false otherwise 0560 */ 0561 bool syncControl(const QVariantMap &settings, const QString &key, QWidget * widget); 0562 0563 /** 0564 * @brief checkJobInputComplete Check if all inputs are filled such that a new job could be added. 0565 */ 0566 void checkJobInputComplete(); 0567 0568 Ekos::Scheduler *ui { nullptr }; 0569 0570 // Interface strings for the dbus. Changeable for mocks when testing. Private so only tests can change. 0571 QString schedulerPathString { "/KStars/Ekos/Scheduler" }; 0572 QString kstarsInterfaceString { "org.kde.kstars" }; 0573 0574 QString focusInterfaceString { "org.kde.kstars.Ekos.Focus" }; 0575 void setFocusInterfaceString(const QString &interface) 0576 { 0577 focusInterfaceString = interface; 0578 } 0579 QString focusPathString { "/KStars/Ekos/Focus" }; 0580 void setFocusPathString(const QString &interface) 0581 { 0582 focusPathString = interface; 0583 } 0584 0585 // This is only used in the constructor 0586 QString ekosInterfaceString { "org.kde.kstars.Ekos" }; 0587 QString ekosPathString { "/KStars/Ekos" }; 0588 0589 QString mountInterfaceString { "org.kde.kstars.Ekos.Mount" }; 0590 void setMountInterfaceString(const QString &interface) 0591 { 0592 mountInterfaceString = interface; 0593 } 0594 QString mountPathString { "/KStars/Ekos/Mount" }; 0595 void setMountPathString(const QString &interface) 0596 { 0597 mountPathString = interface; 0598 } 0599 0600 QString captureInterfaceString { "org.kde.kstars.Ekos.Capture" }; 0601 void setCaptureInterfaceString(const QString &interface) 0602 { 0603 captureInterfaceString = interface; 0604 } 0605 QString capturePathString { "/KStars/Ekos/Capture" }; 0606 void setCapturePathString(const QString &interface) 0607 { 0608 capturePathString = interface; 0609 } 0610 0611 QString alignInterfaceString { "org.kde.kstars.Ekos.Align" }; 0612 void setAlignInterfaceString(const QString &interface) 0613 { 0614 alignInterfaceString = interface; 0615 } 0616 QString alignPathString { "/KStars/Ekos/Align" }; 0617 void setAlignPathString(const QString &interface) 0618 { 0619 alignPathString = interface; 0620 } 0621 0622 QString guideInterfaceString { "org.kde.kstars.Ekos.Guide" }; 0623 void setGuideInterfaceString(const QString &interface) 0624 { 0625 guideInterfaceString = interface; 0626 } 0627 QString guidePathString { "/KStars/Ekos/Guide" }; 0628 void setGuidePathString(const QString &interface) 0629 { 0630 guidePathString = interface; 0631 } 0632 0633 QString INDIInterfaceString { "org.kde.kstars.INDI" }; 0634 void setINDIInterfaceString(const QString &interface) 0635 { 0636 INDIInterfaceString = interface; 0637 } 0638 0639 QString INDIPathString {"/KStars/INDI"}; 0640 void setINDIPathString(const QString &interface) 0641 { 0642 INDIPathString = interface; 0643 } 0644 0645 QString domeInterfaceString { "org.kde.kstars.INDI.Dome" }; 0646 void setDomeInterfaceString(const QString &interface) 0647 { 0648 domeInterfaceString = interface; 0649 } 0650 0651 QString domePathString; 0652 void setDomePathString(const QString &interface) 0653 { 0654 domePathString = interface; 0655 } 0656 0657 QString weatherInterfaceString { "org.kde.kstars.INDI.Weather" }; 0658 void setWeatherInterfaceString(const QString &interface) 0659 { 0660 weatherInterfaceString = interface; 0661 } 0662 QString weatherPathString; 0663 void setWeatherPathString(const QString &interface) 0664 { 0665 weatherPathString = interface; 0666 } 0667 0668 QString dustCapInterfaceString { "org.kde.kstars.INDI.DustCap" }; 0669 void setDustCapInterfaceString(const QString &interface) 0670 { 0671 dustCapInterfaceString = interface; 0672 } 0673 QString dustCapPathString; 0674 void setDustCapPathString(const QString &interface) 0675 { 0676 dustCapPathString = interface; 0677 } 0678 0679 // the state machine holding all states 0680 QSharedPointer<SchedulerModuleState> m_moduleState; 0681 // process engine implementing all process steps 0682 QSharedPointer<SchedulerProcess> m_process; 0683 QSharedPointer<SchedulerProcess> process() 0684 { 0685 return m_process; 0686 } 0687 0688 // react upon changes of EKOS and INDI state 0689 void ekosStateChanged(EkosState state); 0690 void indiStateChanged(INDIState state); 0691 0692 // react upon state changes 0693 void startupStateChanged(StartupState state); 0694 void shutdownStateChanged(ShutdownState state); 0695 void parkWaitStateChanged(ParkWaitState state); 0696 0697 /// URL to store the scheduler file 0698 QUrl schedulerURL; 0699 /// URL for Ekos Sequence 0700 QUrl sequenceURL; 0701 /// FITS URL to solve 0702 QUrl fitsURL; 0703 /// Store all log strings 0704 QStringList m_LogText; 0705 /// Busy indicator widget 0706 QProgressIndicator *pi { nullptr }; 0707 /// Are we editing a job right now? Job row index 0708 int jobUnderEdit { -1 }; 0709 /// Pointer to Geographic location 0710 GeoLocation *geo { nullptr }; 0711 0712 /// Call checkWeather when weatherTimer time expires. It is equal to the UpdatePeriod time in INDI::Weather device. 0713 //QTimer weatherTimer; 0714 0715 QUrl dirPath; 0716 0717 // update the sleep label and its visibility 0718 void changeSleepLabel(QString text, bool show = true); 0719 // Used by the constructor in testing mainly so a mock ekos could be used. 0720 void setupScheduler(const QString &ekosPathStr, const QString &ekosInterfaceStr); 0721 0722 0723 /// Target coordinates for pointing check 0724 QSharedPointer<SolverUtils> m_Solver; 0725 // Used when solving position every nth capture. 0726 uint32_t m_SolverIteration {0}; 0727 0728 void syncGreedyParams(); 0729 0730 friend TestEkosSchedulerOps; 0731 0732 QSharedPointer<SequenceEditor> m_SequenceEditor; 0733 0734 QVariantMap m_Settings; 0735 QVariantMap m_GlobalSettings; 0736 }; 0737 }