File indexing completed on 2024-03-24 15:18:39

0001 /*
0002     Helper class of KStars UI scheduler tests
0003 
0004     SPDX-FileCopyrightText: 2021 Wolfgang Reissenberger <sterne-jaeger@openfuture.de>
0005 
0006     SPDX-License-Identifier: GPL-2.0-or-later
0007 */
0008 #include "test_ekos_scheduler_helper.h"
0009 #include "skyobject.h"
0010 
0011 TestEkosSchedulerHelper::TestEkosSchedulerHelper(): TestEkosHelper() {}
0012 
0013 // Simple write-string-to-file utility.
0014 bool TestEkosSchedulerHelper::writeFile(const QString &filename, const QString &contents)
0015 {
0016     QFile qFile(filename);
0017     if (qFile.open(QIODevice::WriteOnly | QIODevice::Text))
0018     {
0019         QTextStream out(&qFile);
0020         out << contents;
0021         qFile.close();
0022         return true;
0023     }
0024     return false;
0025 }
0026 
0027 QString TestEkosSchedulerHelper::getSchedulerFile(const SkyObject *targetObject, const StartupCondition &startupCondition,
0028         const CompletionCondition &completionCondition,
0029         ScheduleSteps steps, bool enforceTwilight, bool enforceArtificialHorizon,
0030         int minAltitude, QString fitsFile, ShutdownProcedure shutdownProcedure, int errorDelay)
0031 {
0032     QString target = QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><SchedulerList version='1.4'><Profile>Default</Profile>"
0033                              "<Job><Name>%1</Name><Priority>10</Priority><Coordinates><J2000RA>%2</J2000RA>"
0034                              "<J2000DE>%3</J2000DE></Coordinates><Rotation>0</Rotation>")
0035                      .arg(targetObject->name()).arg(targetObject->ra0().Hours()).arg(targetObject->dec0().Degrees());
0036 
0037     if (fitsFile != nullptr)
0038         target += QString("<FITS>%1</FITS>").arg(fitsFile);
0039 
0040     QString sequence = QString("<Sequence>%1</Sequence>");
0041 
0042     QString startupConditionStr;
0043     if (startupCondition.type == Ekos::START_ASAP)
0044         startupConditionStr = QString("<Condition>ASAP</Condition>");
0045     else if (startupCondition.type == Ekos::START_AT)
0046         startupConditionStr = QString("<Condition value='%1'>At</Condition>").arg(
0047                                   startupCondition.atLocalDateTime.toString(Qt::ISODate));
0048 
0049     QString completionConditionStr;
0050     if (completionCondition.type == Ekos::FINISH_SEQUENCE)
0051         completionConditionStr = QString("<Condition>Sequence</Condition>");
0052     else if (completionCondition.type == Ekos::FINISH_REPEAT)
0053         completionConditionStr = QString("<Condition value='%1'>Repeat</Condition>").arg(completionCondition.repeat);
0054     else if (completionCondition.type == Ekos::FINISH_LOOP)
0055         completionConditionStr = QString("<Condition>Loop</Condition>");
0056     else if (completionCondition.type == Ekos::FINISH_AT)
0057         completionConditionStr = QString("<Condition value='%1'>At</Condition>").arg(
0058                                      completionCondition.atLocalDateTime.toString(Qt::ISODate));
0059 
0060     QString parameters = QString("<StartupCondition>%1</StartupCondition>"
0061                                  "<Constraints><Constraint value='%4'>MinimumAltitude</Constraint>%2%3"
0062                                  "</Constraints><CompletionCondition>%9</CompletionCondition>"
0063                                  "%5%6%7%8</Steps></Job>"
0064                                  "<ErrorHandlingStrategy value='1'><delay>%10</delay></ErrorHandlingStrategy><StartupProcedure>"
0065                                  "<Procedure>UnparkMount</Procedure></StartupProcedure>")
0066                          .arg(startupConditionStr)
0067                          .arg(enforceTwilight ? "<Constraint>EnforceTwilight</Constraint>" : "")
0068                          .arg(enforceArtificialHorizon ? "<Constraint>EnforceArtificialHorizon</Constraint>" : "")
0069                          .arg(minAltitude)
0070                          .arg(steps.track ? "<Steps><Step>Track</Step>" : "")
0071                          .arg(steps.focus ? "<Step>Focus</Step>" : "")
0072                          .arg(steps.align ? "<Step>Align</Step>" : "")
0073                          .arg(steps.guide ? "<Step>Guide</Step>" : "")
0074                          .arg(completionConditionStr).arg(errorDelay);
0075 
0076     QString shutdown = QString("<ShutdownProcedure>%1%2%3%4</ShutdownProcedure></SchedulerList>")
0077                        .arg(shutdownProcedure.warm_ccd ? "<Procedure>WarmCCD</Procedure>" : "")
0078                        .arg(shutdownProcedure.close_cap ? "<Procedure>ParkCap</Procedure>" : "")
0079                        .arg(shutdownProcedure.park_mount ? "<Procedure>ParkMount</Procedure>" : "")
0080                        .arg(shutdownProcedure.park_dome ? "<Procedure>ParkDome</Procedure>" : "");
0081 
0082     return (target + sequence + parameters + shutdown);
0083 }
0084 
0085 QString TestEkosSchedulerHelper::getEsqContent(QVector<TestEkosSchedulerHelper::CaptureJob> jobs)
0086 {
0087     QString result = QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><SequenceQueue version='2.1'><CCD>CCD Simulator</CCD>"
0088                              "<FilterWheel>CCD Simulator</FilterWheel><GuideDeviation enabled='false'>2</GuideDeviation>"
0089                              "<GuideStartDeviation enabled='false'>2</GuideStartDeviation><Autofocus enabled='false'>0</Autofocus>"
0090                              "<RefocusOnTemperatureDelta enabled='false'>1</RefocusOnTemperatureDelta>"
0091                              "<RefocusEveryN enabled='false'>60</RefocusEveryN>");
0092 
0093     for (QVector<CaptureJob>::iterator job_iter = jobs.begin(); job_iter !=  jobs.end(); job_iter++)
0094     {
0095         result += QString("<Job><Exposure>%1</Exposure><Binning><X>1</X><Y>1</Y>"
0096                           "</Binning><Frame><X>0</X><Y>0</Y><W>1280</W><H>1024</H></Frame><Temperature force='false'>0</Temperature>"
0097                           "<Filter>%3</Filter><Type>Light</Type><Prefix><RawPrefix></RawPrefix><FilterEnabled>1</FilterEnabled>"
0098                           "<ExpEnabled>0</ExpEnabled><TimeStampEnabled>0</TimeStampEnabled></Prefix>"
0099                           "<Count>%2</Count><Delay>0</Delay><FITSDirectory>%4</FITSDirectory><UploadMode>0</UploadMode>"
0100                           "<Encoding>FITS</Encoding><Properties></Properties><Calibration><FlatSource><Type>Manual</Type>"
0101                           "</FlatSource><FlatDuration><Type>ADU</Type><Value>15000</Value><Tolerance>1000</Tolerance></FlatDuration>"
0102                           "<PreMountPark>False</PreMountPark><PreDomePark>False</PreDomePark></Calibration></Job>")
0103                   .arg(job_iter->exposureTime).arg(job_iter->count).arg(job_iter->filterName).arg(job_iter->fitsDirectory);
0104     }
0105 
0106     result += "</SequenceQueue>";
0107     return result;
0108 }
0109 
0110 // TODO: make a method that creates the below strings depending of a few
0111 // scheduler paramters we want to vary.
0112 
0113 bool TestEkosSchedulerHelper::writeSimpleSequenceFiles(const QString &eslContents, const QString &eslFile,
0114         const QString &esqContents,
0115         const QString &esqFile)
0116 {
0117     return writeFile(eslFile, eslContents.arg(QString("file:%1").arg(esqFile))) && writeFile(esqFile, esqContents);
0118 }