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