1 /*  mock ekos modules
2     SPDX-FileCopyrightText: 2021 Hy Murveit <hy@murveit.com>
3 
4     SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #ifndef MOCKMODULES_H
8 #define MOCKMODULES_H
9 
10 #include <QString>
11 #include <QList>
12 #include <QStringList>
13 #include <QtDBus/QtDBus>
14 #include "ekos/ekos.h"
15 #include "indi/inditelescope.h"
16 
17 // These classes mock Ekos modules for use in testing the scheduler
18 // in test_ekos_scheduler_ops.cpp.  They perform minimal functions
19 // and are only partially implemented--that is, they only have methods
20 // that are actually called by the scheduler. If scheduler functionality
21 // is added, then more mock methods may need to be created, or methods extended.
22 // They communicate with the scheduler with the same dbus calls as the real modules.
23 //
24 // Note that MockEkos uses a different path and interface than the actual
25 // scheduler (to avoid name conflicts with the adaptor class) so it use it
26 // the scheduler contstructor that takes path and interface needs to be used.
27 // Scheduler scheduler("/KStars/MockEkos", "org.kde.kstars.MockEkos");
28 
29 namespace Ekos
30 {
31 
32 // MockFocus returns status of either FOCUS_PROGRESS or FOCUS_IDLE
33 // or whatever is passed to setStatus(). It is commanded by the status call.
34 // It signals newStatus() if the status is changed.
35 // Status can be changed via start(), abort(), or setStatus(status).
36 class MockFocus : public QObject
37 {
38         Q_OBJECT
39         Q_CLASSINFO("D-Bus Interface", "org.kde.kstars.MockEkos.MockFocus")
40         Q_PROPERTY(Ekos::FocusState status READ status NOTIFY newStatus)
41     public:
42         MockFocus();
43 
start()44         Q_SCRIPTABLE Q_NOREPLY void start()
45         {
46             fprintf(stderr, "MockFocus::start called\n");
47             setStatus(Ekos::FOCUS_PROGRESS);
48         }
abort()49         Q_SCRIPTABLE Q_NOREPLY void abort()
50         {
51             fprintf(stderr, "MockFocus::abort called\n");
52             setStatus(Ekos::FOCUS_IDLE);
53         }
canAutoFocus()54         Q_SCRIPTABLE Q_NOREPLY bool canAutoFocus()
55         {
56             fprintf(stderr, "MockFocus::canAutoFocus called\n");
57             return true;
58         }
59 
60         // Seems like the calibrationAutoStar is the one that's used!
setAutoStarEnabled(bool enable)61         Q_SCRIPTABLE Q_NOREPLY void setAutoStarEnabled(bool enable)
62         {
63             Q_UNUSED(enable);
64             fprintf(stderr, "MockFocus::setAutoStarEnabled called\n");
65         }
66 
resetFrame()67         Q_SCRIPTABLE Q_NOREPLY void resetFrame()
68         {
69             fprintf(stderr, "MockFocus::ResetFrame called\n");
70             isReset = true;
71         }
72 
73         bool isReset = false;
74 
status()75         Q_SCRIPTABLE Ekos::FocusState status()
76         {
77             return m_Status;
78         }
79 
setStatus(Ekos::FocusState status)80         void setStatus(Ekos::FocusState status)
81         {
82             m_Status = status;
83             emit newStatus(m_Status);
84         }
85 
86         static const QString mockPath;
87 
88     public slots:
89 
90     signals:
91         void newStatus(Ekos::FocusState state);
92     private:
93         Ekos::FocusState m_Status = Ekos::FOCUS_IDLE;
94 };
95 
96 // MockMount returns status() of either MOUNT_SLEWING, MOUNT_IDLE
97 // or whatever is passed to setStatus().
98 // They are commanded by slew(), abort() & setStatus() and signaled by newStatus().
99 // It also returns parkStatus() of either PARK_PARKED or PARK_UNPARKED
100 // or whatever is passed to setParkStatus().
101 // Commanded by park(), unpark(), setParkStatus() & signaled by newParkStatus().
102 // It can also signal ready() when sendRead() is called.
103 class MockMount : public QObject
104 {
105         Q_OBJECT
106         Q_CLASSINFO("D-Bus Interface", "org.kde.kstars.MockEkos.MockMount")
107         Q_PROPERTY(ISD::Telescope::Status status READ status NOTIFY newStatus)
108         Q_PROPERTY(ISD::ParkStatus parkStatus READ parkStatus NOTIFY newParkStatus)
109         Q_PROPERTY(bool canPark READ canPark)
110     public:
111         MockMount();
112 
status()113         ISD::Telescope::Status status() const
114         {
115             return m_Status;
116         }
parkStatus()117         Q_INVOKABLE Q_SCRIPTABLE ISD::ParkStatus parkStatus() const
118         {
119             return m_ParkStatus;
120         }
slew(double RaHours,double DecDegrees)121         Q_INVOKABLE Q_SCRIPTABLE bool slew(double RaHours, double DecDegrees)
122         {
123             fprintf(stderr, "%d @@@MockMount::slew(%f,%f)\n", __LINE__, RaHours, DecDegrees);
124             setStatus(ISD::Telescope::MOUNT_SLEWING);
125             lastRaHoursSlew = RaHours;
126             lastDecDegreesSlew = DecDegrees;
127             return true;
128         }
abort()129         Q_INVOKABLE Q_SCRIPTABLE bool abort()
130         {
131             fprintf(stderr, "%d @@@MockMount::abort()\n", __LINE__);
132             setStatus(ISD::Telescope::MOUNT_IDLE);
133             return true;
134         }
resetModel()135         Q_INVOKABLE Q_SCRIPTABLE bool resetModel()
136         {
137             return true;
138         }
canPark()139         Q_INVOKABLE Q_SCRIPTABLE bool canPark()
140         {
141             return true;
142         }
park()143         Q_INVOKABLE Q_SCRIPTABLE bool park()
144         {
145             fprintf(stderr, "%d @@@MockMount::park\n", __LINE__);
146             setParkStatus(ISD::PARK_PARKED);
147             return true;
148         }
unpark()149         Q_INVOKABLE Q_SCRIPTABLE bool unpark()
150         {
151             fprintf(stderr, "%d @@@MockMount::park\n", __LINE__);
152             setParkStatus(ISD::PARK_UNPARKED);
153             return true;
154         }
155 
sendReady()156         void sendReady()
157         {
158             emit ready();
159         }
setStatus(ISD::Telescope::Status status)160         void setStatus(ISD::Telescope::Status status)
161         {
162             m_Status = status;
163             emit newStatus(m_Status);
164         }
setParkStatus(ISD::ParkStatus parkStatus)165         void setParkStatus(ISD::ParkStatus parkStatus)
166         {
167             m_ParkStatus = parkStatus;
168             emit newParkStatus(parkStatus);
169         }
170 
171         double lastRaHoursSlew = 0;
172         double lastDecDegreesSlew = 0;
173         static const QString mockPath;
174 
175     signals:
176         void newStatus(ISD::Telescope::Status status);
177         void ready();
178         void newParkStatus(ISD::ParkStatus status);
179 
180     public slots:
setMeridianFlipValues(bool activate,double hours)181         void setMeridianFlipValues(bool activate, double hours)
182         {
183             Q_UNUSED(activate);
184             Q_UNUSED(hours);
185         }
186     private:
187         ISD::Telescope::Status m_Status = ISD::Telescope::MOUNT_IDLE;
188         ISD::ParkStatus m_ParkStatus = ISD::PARK_UNPARKED;
189 };
190 
191 // MockCapture returns status() of CAPTURE_CAPTURING, CAPTURE_ABORTED, CAPTURE_IDLE
192 // or whatever is passed to setStatus().
193 // They are commanded by start(), abort() & setStatus() and signaled by newStatus().
194 // It also has a coolerControl and targetName property.
195 class MockCapture : public QObject
196 {
197         Q_OBJECT
198         Q_CLASSINFO("D-Bus Interface", "org.kde.kstars.MockEkos.MockCapture")
199         Q_PROPERTY(Ekos::CaptureState status READ status NOTIFY newStatus)
200         Q_PROPERTY(QString targetName MEMBER m_TargetName)
201         Q_PROPERTY(bool coolerControl READ hasCoolerControl WRITE setCoolerControl)
202 
203 
204     public:
205         MockCapture();
clearAutoFocusHFR()206         Q_SCRIPTABLE Q_NOREPLY void clearAutoFocusHFR() {}
loadSequenceQueue(const QString & fileURL)207         Q_SCRIPTABLE bool loadSequenceQueue(const QString &fileURL)
208         {
209             fprintf(stderr, "%d @@@MockCapture::loadSequenceQueue(%s)\n", __LINE__, fileURL.toLatin1().data());
210             m_fileURL = fileURL;
211             return true;
212         }
setCapturedFramesMap(const QString & signature,int count)213         Q_SCRIPTABLE Q_NOREPLY void setCapturedFramesMap(const QString &signature, int count)
214         {
215             Q_UNUSED(signature);
216             Q_UNUSED(count);
217             fprintf(stderr, "%d @@@MockCapture::setCapturedFramesMap(%s,%d)\n", __LINE__, signature.toLatin1().data(), count);
218         }
status()219         Q_SCRIPTABLE Ekos::CaptureState status()
220         {
221             return m_Status;
222         }
223 
hasCoolerControl()224         Q_SCRIPTABLE bool hasCoolerControl()
225         {
226             return m_CoolerControl;
227         }
setCoolerControl(bool value)228         Q_SCRIPTABLE bool setCoolerControl(bool value)
229         {
230             m_CoolerControl = value;
231             return true;
232         }
233 
sendReady()234         void sendReady()
235         {
236             emit ready();
237         }
setStatus(Ekos::CaptureState status)238         void setStatus(Ekos::CaptureState status)
239         {
240             m_Status = status;
241             emit newStatus(m_Status);
242         }
243         QString m_fileURL;
244 
245         static const QString mockPath;
246 
247     public slots:
248 
abort()249         Q_SCRIPTABLE Q_NOREPLY void abort()
250         {
251             fprintf(stderr, "%d @@@MockCapture::abort()\n", __LINE__);
252             setStatus(CAPTURE_ABORTED);
253         }
start()254         Q_SCRIPTABLE Q_NOREPLY void start()
255         {
256             fprintf(stderr, "%d @@@MockCapture::start()\n", __LINE__);
257             setStatus(CAPTURE_CAPTURING);
258         }
259 
260     signals:
261         Q_SCRIPTABLE void newStatus(Ekos::CaptureState status);
262         void ready();
263 
264     private:
265         QString m_TargetName;
266         Ekos::CaptureState m_Status { CAPTURE_IDLE };
267         bool m_CoolerControl { false };
268 };
269 
270 // MockAlign returns status() of ALIGN_PROGRESS or whatever is passed to setStatus().
271 // They are commanded by captureAndSolve(), loadAndSlew(), abort() & setStatus().
272 // It is signaled by newStatus().
273 class MockAlign : public QObject
274 {
275         Q_OBJECT
276         Q_CLASSINFO("D-Bus Interface", "org.kde.kstars.MockEkos.MockAlign")
277         Q_PROPERTY(Ekos::AlignState status READ status NOTIFY newStatus)
278 
279     public:
280         MockAlign();
281 
status()282         Q_SCRIPTABLE Ekos::AlignState status()
283         {
284             return m_Status;
285         }
setSolverAction(int action)286         Q_SCRIPTABLE Q_NOREPLY void setSolverAction(int action)
287         {
288             fprintf(stderr, "%d @@@MockAlign::setSolverAction(%d)\n", __LINE__, action);
289         }
setStatus(Ekos::AlignState status)290         void setStatus(Ekos::AlignState status)
291         {
292             m_Status = status;
293             emit newStatus(m_Status);
294         }
295 
296         static const QString mockPath;
297 
298     public slots:
abort()299         Q_SCRIPTABLE Q_NOREPLY void abort()
300         {
301             fprintf(stderr, "%d @@@MockAlign::abort()\n", __LINE__);
302             setStatus(ALIGN_IDLE);
303         }
captureAndSolve()304         Q_SCRIPTABLE bool captureAndSolve()
305         {
306             fprintf(stderr, "%d @@@MockAlign::captureAndSolve()\n", __LINE__);
307             setStatus(ALIGN_PROGRESS);
308             return true;
309         }
310         Q_SCRIPTABLE bool loadAndSlew(QString fileURL = QString())
311         {
312             Q_UNUSED(fileURL);
313             fprintf(stderr, "%d @@@MockAlign::loadAndSlew(fileURL)\n", __LINE__);
314             setStatus(ALIGN_PROGRESS);
315             return true;
316         }
setTargetCoords(double ra,double dec)317         Q_SCRIPTABLE Q_NOREPLY void setTargetCoords(double ra, double dec)
318         {
319             fprintf(stderr, "%d @@@MockAlign::setTargetCoords(%f,%f)\n", __LINE__, ra, dec);
320             targetRa = ra;
321             targetDec = dec;
322         }
setTargetRotation(double rotation)323         Q_SCRIPTABLE Q_NOREPLY void setTargetRotation(double rotation)
324         {
325             fprintf(stderr, "%d @@@MockAlign::setTargetRotation(%f)\n", __LINE__, rotation);
326             targetRotation = rotation;
327             Q_UNUSED(rotation);
328         }
loadAndSlew(const QByteArray & image,const QString & extension)329         bool loadAndSlew(const QByteArray &image, const QString &extension)
330         {
331             Q_UNUSED(image);
332             Q_UNUSED(extension);
333             fprintf(stderr, "%d @@@MockAlign::loadAndSlew(image,extension)\n", __LINE__);
334             setStatus(ALIGN_PROGRESS);
335             return true;
336         }
337 
338     signals:
339         void newStatus(Ekos::AlignState state);
340 
341     private:
342         Ekos::AlignState m_Status {ALIGN_IDLE};
343         int action { 0 };
344         double targetRa { 0 };
345         double targetDec { 0 };
346         double targetRotation { 0 };
347 };
348 
349 // MockGuide returns status() of GUIDE_GUIDING, GUIDE_ABORTED, or GUIDE_IDLE
350 // or whatever is passed to setStatus().
351 // They are commanded by guide(), abort() & setStatus() and  signaled by newStatus().
352 class MockGuide : public QObject
353 {
354         Q_OBJECT
355         Q_CLASSINFO("D-Bus Interface", "org.kde.kstars.MockEkos.MockGuide")
356         Q_PROPERTY(Ekos::GuideState status READ status NOTIFY newStatus)
357 
358     public:
359         MockGuide();
360 
connectGuider()361         Q_SCRIPTABLE bool connectGuider()
362         {
363             fprintf(stderr, "%d @@@MockGuide::connectGuider()\n", __LINE__);
364             connected = true;
365             return true;
366         }
setCalibrationAutoStar(bool enable)367         Q_SCRIPTABLE Q_NOREPLY void setCalibrationAutoStar(bool enable)
368         {
369             fprintf(stderr, "%d @@@MockGuide::setCalibrationAutoStar()\n", __LINE__);
370             calAutoStar = enable;
371             Q_UNUSED(enable);
372         }
status()373         Q_SCRIPTABLE Ekos::GuideState status()
374         {
375             return m_Status;
376         }
setStatus(Ekos::GuideState status)377         void setStatus(Ekos::GuideState status)
378         {
379             m_Status = status;
380             emit newStatus(m_Status);
381         }
382         bool connected { false };
383 
384         // I believe this is really autoStar in general!
385         bool calAutoStar { false };
386 
387         static const QString mockPath;
388 
389     public slots:
clearCalibration()390         Q_SCRIPTABLE Q_NOREPLY void clearCalibration() {}
guide()391         Q_SCRIPTABLE bool guide()
392         {
393             fprintf(stderr, "%d @@@MockGuide::guide()\n", __LINE__);
394             setStatus(Ekos::GUIDE_GUIDING);
395             return true;
396         }
abort()397         Q_SCRIPTABLE bool abort()
398         {
399             setStatus(Ekos::GUIDE_ABORTED);
400             return true;
401         }
402 
403     signals:
404         void newStatus(Ekos::GuideState status);
405 
406     private:
407         Ekos::GuideState m_Status {GUIDE_IDLE};
408 };
409 
410 // MockEkos has 2 different statuses.
411 // ekosStatus is commanded by start() --> Success, and stop() --> Idle and
412 // setEkosStatus(). It signals ekosStatusChanged.
413 // indiStatus is commanded by connectDevices() --> Success, and
414 // disconnectDevives() --> Idle and setIndiStatus().
415 // It signals indiStatusChanged.
416 // It also has an addModule() method which signals newModule().
417 // A scheduler using this mock should be constructed as:
418 // Scheduler scheduler("/KStars/MockEkos", "org.kde.kstars.MockEkos");
419 class MockEkos : public QObject
420 {
421         Q_OBJECT
422         Q_CLASSINFO("D-Bus Interface", "org.kde.kstars.MockEkos")
423         Q_PROPERTY(Ekos::CommunicationStatus indiStatus READ indiStatus NOTIFY indiStatusChanged)
424         Q_PROPERTY(Ekos::CommunicationStatus ekosStatus READ ekosStatus NOTIFY ekosStatusChanged)
425 
426     public:
427         MockEkos();
start()428         Q_SCRIPTABLE void start()
429         {
430             fprintf(stderr, "%d @@@MockEkos::start()\n", __LINE__);
431             setEkosStatus(Ekos::Success);
432         }
stop()433         Q_SCRIPTABLE void stop()
434         {
435             fprintf(stderr, "%d @@@MockEkos::stop()\n", __LINE__);
436             setEkosStatus(Ekos::Idle);
437         }
getProfiles()438         Q_SCRIPTABLE QStringList getProfiles()
439         {
440             fprintf(stderr, "%d @@@MockEkos::getProfiles()\n", __LINE__);
441             return QStringList();
442         }
setProfile(const QString & profileName)443         Q_SCRIPTABLE bool setProfile(const QString &profileName)
444         {
445             Q_UNUSED(profileName);
446             fprintf(stderr, "%d @@@MockEkos::setProfile()\n", __LINE__);
447             return true;
448         }
indiStatus()449         Q_SCRIPTABLE CommunicationStatus indiStatus()
450         {
451             fprintf(stderr, "%d @@@MockEkos::indiStatus\n", __LINE__);
452             return m_INDIStatus;
453         }
ekosStatus()454         Q_SCRIPTABLE CommunicationStatus ekosStatus()
455         {
456             fprintf(stderr, "%d @@@MockEkos::ekosStatus\n", __LINE__);
457             return m_EkosStatus;
458         }
setEkosStatus(Ekos::CommunicationStatus status)459         void setEkosStatus(Ekos::CommunicationStatus status)
460         {
461             m_EkosStatus = status;
462             emit ekosStatusChanged(status);
463         }
setIndiStatus(Ekos::CommunicationStatus status)464         void setIndiStatus(Ekos::CommunicationStatus status)
465         {
466             m_INDIStatus = status;
467             emit indiStatusChanged(status);
468         }
addModule(const QString & name)469         void addModule(const QString &name)
470         {
471             emit newModule(name);
472         }
473 
474         static const QString mockPath;
475 
476     signals:
477         void ekosStatusChanged(Ekos::CommunicationStatus status);
478         void indiStatusChanged(Ekos::CommunicationStatus status);
479         void newModule(const QString &name);
480 
481     protected:
482     public slots:
connectDevices()483         Q_SCRIPTABLE Q_NOREPLY void connectDevices()
484         {
485             fprintf(stderr, "%d @@@MockEkos::connectDevices\n", __LINE__);
486             setIndiStatus(Ekos::Success);
487         }
disconnectDevices()488         Q_SCRIPTABLE Q_NOREPLY void disconnectDevices()
489         {
490             fprintf(stderr, "%d @@@MockEkos::disconnectDevices\n", __LINE__);
491             setIndiStatus(Ekos::Idle);
492         }
493     private slots:
494     private:
495         Ekos::CommunicationStatus m_EkosStatus {Ekos::Idle};
496         Ekos::CommunicationStatus m_INDIStatus {Ekos::Idle};
497 };
498 
499 }  // namespace Ekos
500 
501 #endif // MOCKMODULES_H
502