12#include "profileinfo.h"
13#include "indi/drivermanager.h"
14#include "indi/indilistener.h"
15#include "auxiliary/ksmessagebox.h"
16#include "ekos/auxiliary/filtermanager.h"
17#include "ekos/auxiliary/opticaltrainmanager.h"
18#include "ekos/auxiliary/profilesettings.h"
19#include "ekos/capture/capture.h"
20#include "ekos/guide/guide.h"
21#include "ekos/mount/mount.h"
22#include "ekos/scheduler/scheduler.h"
23#include "ekos/scheduler/schedulermodulestate.h"
25#include "kstarsdata.h"
26#include "ekos_debug.h"
28#include "skymapcomposite.h"
29#include "catalogobject.h"
30#include "fitsviewer/fitsviewer.h"
31#include "fitsviewer/fitstab.h"
32#include "ekos/auxiliary/darklibrary.h"
37#include <KActionCollection>
38#include <basedevice.h>
44 m_Manager(manager), m_NodeManagers(nodeManagers), m_DSOManager(CatalogsDB::dso_db_path())
46 for (
auto &nodeManager : m_NodeManagers)
48 connect(nodeManager->message(), &Node::connected,
this, &Message::onConnected);
49 connect(nodeManager->message(), &Node::disconnected,
this, &Message::onDisconnected);
50 connect(nodeManager->message(), &Node::onTextReceived,
this, &Message::onTextReceived);
53 connect(manager, &Ekos::Manager::newModule,
this, &Message::sendModuleState);
57 m_PendingPropertiesTimer.setInterval(500);
60 m_DebouncedSend.setInterval(500);
67void Message::onConnected()
69 auto node = qobject_cast<Node*>(sender());
73 qCInfo(KSTARS_EKOS) <<
"Connected to Message Websocket server at" << node->url().toDisplayString();
75 m_PendingPropertiesTimer.start();
84void Message::onDisconnected()
86 auto node = qobject_cast<Node*>(sender());
90 qCInfo(KSTARS_EKOS) <<
"Disconnected from Message Websocket server at" << node->url().toDisplayString();
92 if (isConnected() ==
false)
94 m_PendingPropertiesTimer.stop();
102void Message::onTextReceived(
const QString &message)
104 auto node = qobject_cast<Node*>(sender());
105 if (!node || message.
isEmpty())
108 qCInfo(KSTARS_EKOS) <<
"Websocket Message" << message;
113 qCWarning(KSTARS_EKOS) <<
"Ekos Live Parsing Error" <<
error.errorString();
118 const QString command = msgObj[
"type"].toString();
119 const QJsonObject payload = msgObj[
"payload"].toObject();
121 if (command == commands[GET_CONNECTION])
125 else if (command == commands[LOGOUT])
127 emit expired(node->url());
130 else if (command == commands[SET_CLIENT_STATE])
133 if (payload[
"state"].toBool(
false))
135 qCInfo(KSTARS_EKOS) <<
"EkosLive client is connected.";
138 if (KStarsData::Instance()->clock()->isActive() ==
false)
140 qCInfo(KSTARS_EKOS) <<
"Resuming and syncing clock.";
151 qCInfo(KSTARS_EKOS) <<
"EkosLive client is disconnected.";
153 if (
KStars::Instance()->isStartedWithClockRunning() ==
false && m_Manager->ekosStatus() == Ekos::CommunicationStatus::Idle)
155 qCInfo(KSTARS_EKOS) <<
"Stopping the clock.";
160 else if (command == commands[GET_DRIVERS])
162 else if (command == commands[GET_PROFILES])
164 else if (command == commands[GET_SCOPES])
166 else if (command == commands[GET_DSLR_LENSES])
168 else if(command == commands[INVOKE_METHOD])
170 auto object = findObject(payload[
"object"].
toString());
172 invokeMethod(
object, payload);
174 else if(command == commands[SET_PROPERTY])
176 auto object = findObject(payload[
"object"].
toString());
178 object->setProperty(payload[
"name"].
toString().toLatin1().constData(), payload[
"value"].toVariant());
180 else if(command == commands[GET_PROPERTY])
182 auto map = QVariantMap();
183 map[
"result"] =
false;
184 auto object = findObject(payload[
"object"].
toString());
187 auto value =
object->property(payload[
"name"].
toString().toLatin1().constData());
190 map[
"result"] =
true;
191 map[
"value"] = value;
197 processScopeCommands(command, payload);
199 processProfileCommands(command, payload);
201 processAstronomyCommands(command, payload);
202 else if (command == commands[DIALOG_GET_RESPONSE])
203 processDialogResponse(payload);
205 processOptionsCommands(command, payload);
207 processSchedulerCommands(command, payload);
209 processDSLRCommands(command, payload);
211 if (m_Manager->getEkosStartingStatus() != Ekos::Success)
214 if (command == commands[GET_STATES])
216 else if (command == commands[GET_STELLARSOLVER_PROFILES])
217 sendStellarSolverProfiles();
218 else if (command == commands[GET_DEVICES])
221 processCaptureCommands(command, payload);
223 processMountCommands(command, payload);
225 processFocusCommands(command, payload);
227 processGuideCommands(command, payload);
229 processAlignCommands(command, payload);
231 processPolarCommands(command, payload);
233 processTrainCommands(command, payload);
235 processFilterManagerCommands(command, payload);
237 processDarkLibraryCommands(command, payload);
239 processDeviceCommands(command, payload);
246bool Message::isConnected()
const
248 return std::any_of(m_NodeManagers.begin(), m_NodeManagers.end(), [](
auto & nodeManager)
250 return nodeManager->message()->isConnected();
257void Message::sendStellarSolverProfiles()
259 if (m_Manager->getEkosStartingStatus() != Ekos::Success)
264 if (m_Manager->focusModule())
269 if (m_Manager->alignModule())
273 sendResponse(commands[GET_STELLARSOLVER_PROFILES], profiles);
279void Message::sendDrivers()
281 sendResponse(commands[GET_DRIVERS], DriverManager::Instance()->getDriverList());
287void Message::sendDevices()
289 if (m_Manager->getEkosStartingStatus() != Ekos::Success)
298 {
"name", gd->getDeviceName()},
299 {
"connected", gd->isConnected()},
300 {
"version", gd->getDriverVersion()},
301 {
"interface",
static_cast<int>(gd->getDriverInterface())},
304 deviceList.
append(oneDevice);
307 sendResponse(commands[GET_DEVICES], deviceList);
313void Message::sendTrains()
315 if (m_Manager->getEkosStartingStatus() != Ekos::Success)
320 for(
auto &train :
Ekos::OpticalTrainManager::Instance()->getOpticalTrains())
323 sendResponse(commands[TRAIN_GET_ALL], trains);
329void Message::sendTrainProfiles()
331 if (m_Manager->getEkosStartingStatus() != Ekos::Success)
334 auto profiles = Ekos::ProfileSettings::Instance()->getSettings();
342void Message::requestOpticalTrains(
bool show)
344 sendResponse(commands[TRAIN_CONFIGURATION_REQUESTED], show);
350void Message::sendScopes()
357 for (
auto &scope : allScopes)
358 scopeList.append(scope->toJson());
360 sendResponse(commands[GET_SCOPES], scopeList);
366void Message::sendDSLRLenses()
373 for (
auto &dslrLens : allDslrLens)
374 dslrList.append(dslrLens->toJson());
376 sendResponse(commands[GET_DSLR_LENSES], dslrList);
382void Message::sendTemperature(
double value)
390 {
"name", oneCCD->getDeviceName()},
391 {
"temperature", value}
394 sendResponse(commands[NEW_CAMERA_STATE], temperature);
401void Message::processCaptureCommands(
const QString &command,
const QJsonObject &payload)
405 if (capture ==
nullptr)
407 qCWarning(KSTARS_EKOS) <<
"Ignoring command" << command <<
"as capture module is not available";
411 if (command == commands[CAPTURE_PREVIEW])
413 capture->mainCamera()->capturePreview();
415 else if (command == commands[CAPTURE_TOGGLE_VIDEO])
417 capture->
setVideoLimits(payload[
"maxBufferSize"].toInt(512), payload[
"maxPreviewFPS"].toInt(10));
420 else if (command == commands[CAPTURE_START])
422 else if (command == commands[CAPTURE_STOP])
424 else if (command == commands[CAPTURE_LOOP])
426 capture->mainCamera()->startFraming();
428 else if (command == commands[CAPTURE_GET_SEQUENCES])
432 else if (command == commands[CAPTURE_ADD_SEQUENCE])
435 capture->mainCamera()->createJob();
437 else if (command == commands[CAPTURE_REMOVE_SEQUENCE])
439 if (capture->mainCamera()->removeJob(payload[
"index"].toInt()) ==
false)
442 else if (command == commands[CAPTURE_CLEAR_SEQUENCES])
446 else if (command == commands[CAPTURE_SAVE_SEQUENCE_FILE])
451 else if (command == commands[CAPTURE_LOAD_SEQUENCE_FILE])
466 path = payload[
"filepath"].toString();
476 sendResponse(commands[CAPTURE_LOAD_SEQUENCE_FILE], response);
479 else if (command == commands[CAPTURE_GET_ALL_SETTINGS])
481 sendCaptureSettings(capture->mainCamera()->getAllSettings());
483 else if (command == commands[CAPTURE_SET_ALL_SETTINGS])
486 capture->mainCamera()->setAllSettings(settings);
487 KSUtils::setGlobalSettings(settings);
489 else if (command == commands[CAPTURE_GENERATE_DARK_FLATS])
491 capture->mainCamera()->generateDarkFlats();
498void Message::sendCaptureSequence(
const QJsonArray &sequenceArray)
500 sendResponse(commands[CAPTURE_GET_SEQUENCES], sequenceArray);
503void Message::sendPreviewLabel(
const QString &preview)
509 sendResponse(commands[CAPTURE_GET_PREVIEW_LABEL], payload);
515void Message::sendCaptureSettings(
const QVariantMap &settings)
517 m_DebouncedSend.start();
518 m_DebouncedMap[commands[CAPTURE_GET_ALL_SETTINGS]] = settings;
524void Message::sendAlignSettings(
const QVariantMap &settings)
526 m_DebouncedSend.start();
527 m_DebouncedMap[commands[ALIGN_GET_ALL_SETTINGS]] = settings;
533void Message::sendGuideSettings(
const QVariantMap &settings)
535 m_DebouncedSend.start();
536 m_DebouncedMap[commands[GUIDE_GET_ALL_SETTINGS]] = settings;
543void Message::sendFocusSettings(
const QVariantMap &settings)
545 m_DebouncedSend.start();
546 m_DebouncedMap[commands[FOCUS_GET_ALL_SETTINGS]] = settings;
552void Message::sendMountSettings(
const QVariantMap &settings)
554 m_DebouncedSend.start();
555 m_DebouncedMap[commands[MOUNT_GET_ALL_SETTINGS]] = settings;
561void Message::sendDarkLibrarySettings(
const QVariantMap &settings)
563 m_DebouncedSend.start();
564 m_DebouncedMap[commands[DARK_LIBRARY_GET_ALL_SETTINGS]] = settings;
571void Message::sendSchedulerSettings(
const QVariantMap &settings)
573 m_DebouncedSend.start();
574 m_DebouncedMap[commands[SCHEDULER_GET_ALL_SETTINGS]] = settings;
580void Message::dispatchDebounceQueue()
588 m_DebouncedMap.clear();
591 Options::self()->save();
601 if (guide ==
nullptr)
603 qCWarning(KSTARS_EKOS) <<
"Ignoring command" << command <<
"as guide module is not available";
607 if (command == commands[GUIDE_START])
611 else if (command == commands[GUIDE_CAPTURE])
613 else if (command == commands[GUIDE_LOOP])
615 else if (command == commands[GUIDE_STOP])
617 else if (command == commands[GUIDE_CLEAR])
619 else if (command == commands[GUIDE_SET_ALL_SETTINGS])
622 guide->setAllSettings(settings);
623 KSUtils::setGlobalSettings(settings);
625 else if (command == commands[GUIDE_GET_ALL_SETTINGS])
626 sendGuideSettings(guide->getAllSettings());
627 else if(command == commands[GUIDE_SET_CALIBRATION_SETTINGS])
630 Options::setCalibrationPulseDuration(payload[
"pulse"].toInt());
631 Options::setGuideCalibrationBacklash(payload[
"max_move"].toInt());
632 Options::setTwoAxisEnabled(payload[
"two_axis"].toBool());
633 Options::setGuideAutoSquareSizeEnabled(payload[
"square_size"].toBool());
634 Options::setGuideCalibrationBacklash(payload[
"calibrationBacklash"].toBool());
635 Options::setResetGuideCalibration(payload[
"resetCalibration"].toBool());
636 Options::setReuseGuideCalibration(payload[
"reuseCalibration"].toBool());
637 Options::setReverseDecOnPierSideChange(payload[
"reverseCalibration"].toBool());
638 sendGuideSettings(m_Manager->guideModule()->getAllSettings());
649 if (focus ==
nullptr)
651 qCWarning(KSTARS_EKOS) <<
"Ignoring command" << command <<
"as focus module is not available";
655 if (command == commands[FOCUS_START])
657 else if (command == commands[FOCUS_CAPTURE])
662 else if (command == commands[FOCUS_STOP])
664 else if (command == commands[FOCUS_RESET])
666 else if (command == commands[FOCUS_IN])
667 focus->
focusIn(payload[
"steps"].toInt());
668 else if (command == commands[FOCUS_OUT])
669 focus->
focusOut(payload[
"steps"].toInt());
670 else if (command == commands[FOCUS_LOOP])
672 else if (command == commands[FOCUS_SET_ALL_SETTINGS])
675 focus->setAllSettings(settings);
676 KSUtils::setGlobalSettings(settings);
679 else if (command == commands[FOCUS_GET_ALL_SETTINGS])
680 sendFocusSettings(focus->getAllSettings());
681 else if (command == commands[FOCUS_SET_CROSSHAIR])
683 double x = payload[
"x"].toDouble();
684 double y = payload[
"y"].toDouble();
696 if (mount ==
nullptr)
698 qCWarning(KSTARS_EKOS) <<
"Ignoring command" << command <<
"as mount module is not available";
702 if (command == commands[MOUNT_ABORT])
704 else if (command == commands[MOUNT_PARK])
706 else if (command == commands[MOUNT_UNPARK])
708 else if (command == commands[MOUNT_SET_TRACKING])
709 mount->setTrackEnabled(payload[
"enabled"].toBool());
710 else if (command == commands[MOUNT_SYNC_RADE])
712 mount->setJ2000Enabled(payload[
"isJ2000"].toBool());
715 mount->sync(ra.Hours(), de.Degrees());
717 else if (command == commands[MOUNT_SYNC_TARGET])
721 else if (command == commands[MOUNT_GOTO_RADE])
723 mount->setJ2000Enabled(payload[
"isJ2000"].toBool());
726 mount->slew(ra.Hours(), de.Degrees());
728 else if (command == commands[MOUNT_GOTO_TARGET])
732 else if (command == commands[MOUNT_SET_SLEW_RATE])
734 int rate = payload[
"rate"].toInt(-1);
736 mount->setSlewRate(rate);
738 else if (command == commands[MOUNT_SET_ALL_SETTINGS])
741 mount->setAllSettings(settings);
742 KSUtils::setGlobalSettings(settings);
744 else if (command == commands[MOUNT_GET_ALL_SETTINGS])
745 sendMountSettings(
mount->getAllSettings());
746 else if (command == commands[MOUNT_SET_MOTION])
748 QString direction = payload[
"direction"].toString();
749 ISD::Mount::MotionCommand action = payload[
"action"].toBool(
false) ?
750 ISD::Mount::MOTION_START : ISD::Mount::MOTION_STOP;
752 if (direction ==
"N")
753 mount->motionCommand(action, ISD::Mount::MOTION_NORTH, -1);
754 else if (direction ==
"S")
755 mount->motionCommand(action, ISD::Mount::MOTION_SOUTH, -1);
756 else if (direction ==
"E")
757 mount->motionCommand(action, -1, ISD::Mount::MOTION_EAST);
758 else if (direction ==
"W")
759 mount->motionCommand(action, -1, ISD::Mount::MOTION_WEST);
761 else if (command == commands[MOUNT_GOTO_PIXEL])
763 const auto name = payload[
"camera"].toString();
764 const auto xFactor = payload[
"x"].toDouble();
765 const auto yFactor = payload[
"y"].toDouble();
769 auto camera = oneDevice->getCamera();
770 if (!camera || camera->getDeviceName() != name)
773 auto primaryChip = camera->getChip(ISD::CameraChip::PRIMARY_CCD);
778 auto imageData = primaryChip->getImageData();
779 if (!imageData || imageData->hasWCS() ==
false)
782 auto x = xFactor * imageData->width();
783 auto y = yFactor * imageData->height();
787 if (imageData->pixelToWCS(point, coord))
791 mount->gotoTarget(coord);
796 else if (command == commands[MOUNT_TOGGLE_AUTOPARK])
797 mount->setAutoParkEnabled(payload[
"toggled"].toBool());
807 if (align ==
nullptr)
809 qCWarning(KSTARS_EKOS) <<
"Ignoring command" << command <<
"as align module is not available";
813 if (command == commands[ALIGN_SOLVE])
817 else if (command == commands[ALIGN_SET_ALL_SETTINGS])
820 align->setAllSettings(settings);
821 KSUtils::setGlobalSettings(settings);
823 else if (command == commands[ALIGN_GET_ALL_SETTINGS])
824 sendAlignSettings(align->getAllSettings());
825 else if(command == commands[ALIGN_SET_ASTROMETRY_SETTINGS])
827 Options::setAstrometryRotatorThreshold(payload[
"threshold"].toInt());
828 Options::setAstrometryUseRotator(payload[
"rotator_control"].toBool());
829 Options::setAstrometryUseImageScale(payload[
"scale"].toBool());
830 Options::setAstrometryUsePosition(payload[
"position"].toBool());
832 else if (command == commands[ALIGN_STOP])
834 else if (command == commands[ALIGN_LOAD_AND_SLEW])
853 else if (command == commands[ALIGN_MANUAL_ROTATOR_TOGGLE])
855 align->toggleManualRotator(payload[
"toggled"].toBool());
864 if (m_Manager->getEkosStartingStatus() != Ekos::Success)
872 sendResponse(commands[NEW_ALIGN_STATE], alignState);
878void Message::setAlignSolution(
const QVariantMap &solution)
880 if (m_Manager->getEkosStartingStatus() != Ekos::Success)
888 sendResponse(commands[NEW_ALIGN_STATE], alignState);
894void Message::processSchedulerCommands(
const QString &command,
const QJsonObject &payload)
898 if (command == commands[SCHEDULER_GET_JOBS])
902 else if (command == commands[SCHEDULER_ADD_JOBS])
906 else if(command == commands[SCHEDULER_REMOVE_JOBS])
908 int index = payload[
"index"].toInt();
911 else if(command == commands[SCHEDULER_GET_ALL_SETTINGS])
913 sendSchedulerSettings(scheduler->getAllSettings());
915 else if(command == commands[SCHEDULER_SET_ALL_SETTINGS])
918 scheduler->setAllSettings(settings);
919 KSUtils::setGlobalSettings(settings);
921 else if (command == commands[SCHEDULER_SAVE_FILE])
926 else if (command == commands[SCHEDULER_LOAD_FILE])
941 path = payload[
"filepath"].toString();
951 sendResponse(commands[SCHEDULER_LOAD_FILE], response);
954 else if(command == commands[SCHEDULER_START_JOB])
956 scheduler->toggleScheduler();
958 else if(command == commands[SCHEDULER_IMPORT_MOSAIC])
963 sendEvent(
i18n(
"Mosaic import failed."), KSNotification::Scheduler, KSNotification::Alert);
978 if (command == commands[PAH_START])
980 paa->startPAHProcess();
982 if (command == commands[PAH_STOP])
984 paa->stopPAHProcess();
986 else if (command == commands[PAH_REFRESH])
988 paa->setPAHRefreshDuration(payload[
"value"].toDouble(1));
989 paa->startPAHRefreshProcess();
991 else if (command == commands[PAH_SET_ALGORITHM])
995 algorithmCombo->
setCurrentIndex(
static_cast<Ekos::PolarAlignmentAssistant::RefreshAlgorithm
>(payload[
"value"].toInt(1)));
997 else if (command == commands[PAH_RESET_VIEW])
999 emit resetPolarView();
1001 else if (command == commands[PAH_SET_CROSSHAIR])
1003 double x = payload[
"x"].toDouble();
1004 double y = payload[
"y"].toDouble();
1006 if (m_BoundingRect.isNull() ==
false)
1010 double boundX = x * m_BoundingRect.width();
1011 double boundY = y * m_BoundingRect.height();
1016 x = ((boundX + m_BoundingRect.x()) / (m_CurrentZoom / 100)) / m_ViewSize.width();
1017 y = ((boundY + m_BoundingRect.y()) / (m_CurrentZoom / 100)) / m_ViewSize.height();
1021 paa->setPAHCorrectionOffsetPercentage(x, y);
1023 else if (command == commands[PAH_SELECT_STAR_DONE])
1029 else if (command == commands[PAH_REFRESHING_DONE])
1031 paa->stopPAHProcess();
1033 else if (command == commands[PAH_SLEW_DONE])
1035 paa->setPAHSlewDone();
1037 else if (command == commands[PAH_PAH_SET_ZOOM])
1039 double scale = payload[
"scale"].toDouble();
1040 align->setAlignZoom(scale);
1048void Message::setPAHStage(Ekos::PolarAlignmentAssistant::Stage stage)
1050 if (isConnected() ==
false || m_Manager->getEkosStartingStatus() != Ekos::Success)
1063 {
"stage", paa->getPAHStageString(
false)}
1068 if (stage == Ekos::PolarAlignmentAssistant::PAH_STAR_SELECT)
1069 align->zoomAlignView();
1071 sendResponse(commands[NEW_POLAR_STATE], polarState);
1077void Message::setPAHMessage(
const QString &message)
1079 if (isConnected() ==
false || m_Manager->getEkosStartingStatus() != Ekos::Success)
1089 sendResponse(commands[NEW_POLAR_STATE], polarState);
1095void Message::setPolarResults(
QLineF correctionVector,
double polarError,
double azError,
double altError)
1097 if (isConnected() ==
false || m_Manager->getEkosStartingStatus() != Ekos::Success)
1100 this->correctionVector = correctionVector;
1105 {
"center_x",
center.x()},
1106 {
"center_y",
center.y()},
1107 {
"mag", correctionVector.
length()},
1108 {
"pa", correctionVector.
angle()},
1109 {
"error", polarError},
1110 {
"azError", azError},
1111 {
"altError", altError}
1119 sendResponse(commands[NEW_POLAR_STATE], polarState);
1125void Message::setUpdatedErrors(
double total,
double az,
double alt)
1127 if (isConnected() ==
false || m_Manager->getEkosStartingStatus() != Ekos::Success)
1132 {
"updatedError", total},
1133 {
"updatedAZError", az},
1134 {
"updatedALTError", alt}
1137 sendResponse(commands[NEW_POLAR_STATE], error);
1143void Message::setPAHEnabled(
bool enabled)
1145 if (m_Manager->getEkosStartingStatus() != Ekos::Success)
1150 {
"enabled", enabled}
1153 sendResponse(commands[NEW_POLAR_STATE], polarState);
1159void Message::processProfileCommands(
const QString &command,
const QJsonObject &payload)
1161 if (command == commands[START_PROFILE])
1163 if (m_Manager->getEkosStartingStatus() != Ekos::Idle)
1166 m_Manager->setProfile(payload[
"name"].
toString());
1171 else if (command == commands[STOP_PROFILE])
1178 m_PropertySubscriptions.clear();
1180 else if (command == commands[ADD_PROFILE])
1182 m_Manager->addNamedProfile(payload);
1185 else if (command == commands[UPDATE_PROFILE])
1187 m_Manager->editNamedProfile(payload);
1190 else if (command == commands[GET_PROFILE])
1192 m_Manager->getNamedProfile(payload[
"name"].
toString());
1194 else if (command == commands[DELETE_PROFILE])
1196 m_Manager->deleteNamedProfile(payload[
"name"].
toString());
1199 else if (command == commands[SET_PROFILE_MAPPING])
1201 m_Manager->setProfileMapping(payload);
1203 else if (command == commands[SET_PROFILE_PORT_SELECTION])
1205 requestPortSelection(
false);
1206 m_Manager->acceptPortSelection();
1213void Message::sendProfiles()
1218 if (!m_Manager->getCurrentProfile(profile))
1221 for (
auto &oneProfile : m_Manager->profiles)
1222 profileArray.append(oneProfile->toJson());
1226 {
"selectedProfile", profile->name},
1227 {
"profiles", profileArray}
1229 sendResponse(commands[GET_PROFILES], profiles);
1235void Message::sendSchedulerJobs()
1239 {
"jobs", m_Manager->schedulerModule()->moduleState()->getJSONJobs()}
1241 sendResponse(commands[SCHEDULER_GET_JOBS], jobs);
1247void Message::sendSchedulerJobList(
QJsonArray jobsList)
1253 sendResponse(commands[SCHEDULER_GET_JOBS], jobs);
1259void Message::sendSchedulerStatus(
const QJsonObject &status)
1261 sendResponse(commands[NEW_SCHEDULER_STATE], status);
1268void Message::setEkosStatingStatus(Ekos::CommunicationStatus status)
1270 if (status == Ekos::Pending)
1275 {
"connected",
true},
1276 {
"online",
status == Ekos::Success}
1278 sendResponse(commands[NEW_CONNECTION_STATE], connectionState);
1284void Message::setINDIStatus(Ekos::CommunicationStatus status)
1291 sendResponse(commands[NEW_INDI_STATE], connectionState);
1297void Message::processOptionsCommands(
const QString &command,
const QJsonObject &payload)
1299 if (command == commands[OPTION_SET])
1301 const QJsonArray options = payload[
"options"].toArray();
1302 for (
const auto &oneOption : options)
1303 Options::self()->
setProperty(oneOption[
"name"].
toString().toLatin1(), oneOption[
"value"].toVariant());
1305 Options::self()->save();
1306 emit optionsUpdated();
1308 else if (command == commands[OPTION_GET])
1310 const QJsonArray options = payload[
"options"].toArray();
1312 for (
const auto &oneOption : options)
1314 const auto name = oneOption[
"name"].toString();
1318 map[
"value"] = value;
1321 sendResponse(commands[OPTION_GET], result);
1328void Message::processScopeCommands(
const QString &command,
const QJsonObject &payload)
1330 if (command == commands[ADD_SCOPE])
1333 payload[
"type"].
toString(), payload[
"aperture"].toDouble(), payload[
"focal_length"].toDouble());
1335 else if (command == commands[UPDATE_SCOPE])
1338 payload[
"type"].
toString(), payload[
"aperture"].toDouble(), payload[
"focal_length"].toDouble(), payload[
"id"].
toString());
1340 else if (command == commands[DELETE_SCOPE])
1353 if (command == commands[DSLR_SET_INFO])
1355 if (m_Manager->captureModule())
1356 m_Manager->captureModule()->mainCamera()->addDSLRInfo(
1358 payload[
"width"].toInt(),
1359 payload[
"height"].toInt(),
1360 payload[
"pixelw"].toDouble(),
1361 payload[
"pixelh"].toDouble());
1364 else if(command == commands[DSLR_ADD_LENS])
1367 payload[
"focal_length"].toDouble(), payload[
"focal_ratio"].toDouble());
1369 else if (command == commands[DSLR_DELETE_LENS])
1373 else if (command == commands[DSLR_UPDATE_LENS])
1376 payload[
"focal_length"].toDouble(), payload[
"focal_ratio"].toDouble(), payload[
"id"].
toString());
1385void Message::processTrainCommands(
const QString &command,
const QJsonObject &payload)
1387 if (command == commands[TRAIN_GET_ALL])
1389 else if (command == commands[TRAIN_GET_PROFILES])
1390 sendTrainProfiles();
1391 else if (command == commands[TRAIN_SET])
1393 auto module = payload["module"].toString();
1394 auto name = payload[
"name"].toString();
1396 if (module ==
"capture")
1398 if (m_Manager->captureModule())
1399 m_Manager->captureModule()->setOpticalTrain(name);
1401 else if (module ==
"focus")
1403 if (m_Manager->focusModule())
1404 m_Manager->focusModule()->setOpticalTrain(name);
1406 else if (module ==
"guide")
1408 if (m_Manager->guideModule())
1409 m_Manager->guideModule()->setOpticalTrain(name);
1411 else if (module ==
"align")
1413 if (m_Manager->alignModule())
1414 m_Manager->alignModule()->setOpticalTrain(name);
1416 else if (module ==
"mount")
1418 if (m_Manager->mountModule())
1419 m_Manager->mountModule()->setOpticalTrain(name);
1421 else if (module ==
"darklibrary")
1423 Ekos::DarkLibrary::Instance()->setOpticalTrain(name);
1426 else if (command == commands[TRAIN_ADD])
1428 Ekos::OpticalTrainManager::Instance()->addOpticalTrain(payload);
1430 else if (command == commands[TRAIN_UPDATE])
1432 Ekos::OpticalTrainManager::Instance()->setOpticalTrain(payload);
1434 else if (command == commands[TRAIN_DELETE])
1436 Ekos::OpticalTrainManager::Instance()->removeOpticalTrain(payload[
"name"].
toString());
1438 else if (command == commands[TRAIN_RESET])
1440 Ekos::OpticalTrainManager::Instance()->reset();
1442 else if (command == commands[TRAIN_ACCEPT])
1444 requestOpticalTrains(
false);
1445 Ekos::OpticalTrainManager::Instance()->
accept();
1453void Message::processFilterManagerCommands(
const QString &command,
const QJsonObject &payload)
1456 if (m_Manager->captureModule())
1457 manager = m_Manager->captureModule()->mainCamera()->filterManager();
1462 if (command == commands[FM_GET_DATA])
1465 sendResponse(commands[FM_GET_DATA], data);
1467 else if (command == commands[FM_SET_DATA])
1469 manager->setFilterData(payload);
1476void Message::processDarkLibraryCommands(
const QString &command,
const QJsonObject &payload)
1478 if (command == commands[DARK_LIBRARY_START])
1479 Ekos::DarkLibrary::Instance()->start();
1480 else if(command == commands[DARK_LIBRARY_SET_ALL_SETTINGS])
1483 Ekos::DarkLibrary::Instance()->setAllSettings(settings);
1484 KSUtils::setGlobalSettings(settings);
1486 else if(command == commands[DARK_LIBRARY_GET_ALL_SETTINGS])
1487 sendDarkLibrarySettings(Ekos::DarkLibrary::Instance()->getAllSettings());
1488 else if(command == commands[DARK_LIBRARY_GET_DEFECT_SETTINGS])
1489 sendResponse(commands[DARK_LIBRARY_GET_DEFECT_SETTINGS], Ekos::DarkLibrary::Instance()->getDefectSettings());
1490 else if(command == commands[DARK_LIBRARY_SET_CAMERA_PRESETS])
1492 Ekos::DarkLibrary::Instance()->setCameraPresets(payload);
1494 else if (command == commands[DARK_LIBRARY_STOP])
1496 Ekos::DarkLibrary::Instance()->
stop();
1498 else if (command == commands[DARK_LIBRARY_GET_MASTERS_IMAGE])
1500 const int row = payload[
"row"].toInt();
1501 Ekos::DarkLibrary::Instance()->loadIndexInView(row);
1503 else if (command == commands[DARK_LIBRARY_GET_CAMERA_PRESETS])
1505 sendResponse(commands[DARK_LIBRARY_GET_CAMERA_PRESETS], Ekos::DarkLibrary::Instance()->getCameraPresets());
1507 else if (command == commands[DARK_LIBRARY_SET_DEFECT_PIXELS])
1509 Ekos::DarkLibrary::Instance()->setDefectPixels(payload);
1511 else if (command == commands[DARK_LIBRARY_SAVE_MAP])
1513 Ekos::DarkLibrary::Instance()->saveMapB->click();
1515 else if (command == commands[DARK_LIBRARY_SET_DEFECT_FRAME])
1517 Ekos::DarkLibrary::Instance()->setDefectMapEnabled(
false);
1519 else if (command == commands[DARK_LIBRARY_GET_VIEW_MASTERS])
1521 sendResponse(commands[DARK_LIBRARY_GET_VIEW_MASTERS], Ekos::DarkLibrary::Instance()->getViewMasters());
1523 else if (command == commands[DARK_LIBRARY_CLEAR_MASTERS_ROW])
1525 const int rowIndex = payload[
"row"].toInt();
1526 Ekos::DarkLibrary::Instance()->clearRow(rowIndex);
1533void Message::processDeviceCommands(
const QString &command,
const QJsonObject &payload)
1535 QString device = payload[
"device"].toString();
1538 if (device.
isEmpty() && command == commands[DEVICE_PROPERTY_UNSUBSCRIBE])
1540 m_PropertySubscriptions.clear();
1545 if (!INDIListener::findDevice(device, oneDevice))
1549 if (command == commands[DEVICE_PROPERTY_GET])
1552 if (oneDevice->getJSONProperty(payload[
"property"].toString(), propObject, payload[
"compact"].toBool(
true)))
1553 sendResponse(commands[DEVICE_PROPERTY_GET], propObject);
1556 else if (command == commands[DEVICE_PROPERTY_SET])
1558 oneDevice->setJSONProperty(payload[
"property"].
toString(), payload[
"elements"].toArray());
1561 else if (command == commands[DEVICE_GET])
1567 if (oneDevice->getJSONProperty(oneProp.getName(), singleProp, payload[
"compact"].toBool(
false)))
1577 sendResponse(commands[DEVICE_GET], response);
1581 else if (command == commands[DEVICE_PROPERTY_SUBSCRIBE])
1584 const QJsonArray groups = payload[
"groups"].toArray();
1588 if (m_PropertySubscriptions.contains(device))
1589 props = m_PropertySubscriptions[device];
1598 else if (groups.
isEmpty() ==
false)
1603 if (indiGroups.contains(oneProp.getGroupName()))
1604 props.
insert(oneProp.getName());
1611 props.
insert(oneProp.getName());
1614 m_PropertySubscriptions[device] = props;
1616 else if (command == commands[DEVICE_PROPERTY_UNSUBSCRIBE])
1619 const QJsonArray groups = payload[
"groups"].toArray();
1623 if (m_PropertySubscriptions.contains(device))
1624 props = m_PropertySubscriptions[device];
1634 else if (groups.
isEmpty() ==
false)
1639 if (indiGroups.contains(oneProp.getGroupName()))
1640 props.
remove(oneProp.getName());
1647 props.
remove(oneProp.getName());
1650 m_PropertySubscriptions[device] = props;
1657void Message::processAstronomyCommands(
const QString &command,
const QJsonObject &payload)
1659 if (command == commands[ASTRO_GET_ALMANC])
1666 KSAlmanac almanac(midnight, KStarsData::Instance()->
geo());
1670 {
"SunRise", almanac.getSunRise()},
1671 {
"SunSet", almanac.getSunSet()},
1672 {
"SunMaxAlt", almanac.getSunMaxAlt()},
1673 {
"SunMinAlt", almanac.getSunMinAlt()},
1674 {
"MoonRise", almanac.getMoonRise()},
1675 {
"MoonSet", almanac.getMoonSet()},
1676 {
"MoonPhase", almanac.getMoonPhase()},
1677 {
"MoonIllum", almanac.getMoonIllum()},
1678 {
"Dawn", almanac.getDawnAstronomicalTwilight()},
1679 {
"Dusk", almanac.getDuskAstronomicalTwilight()},
1683 sendResponse(commands[ASTRO_GET_ALMANC], response);
1685 else if (command == commands[ASTRO_GET_NAMES])
1687 auto composite = KStarsData::Instance()->
skyComposite();
1690 CatalogsDB::CatalogObjectList dsoObjects;
1692 allObjects.
append(composite->objectLists(SkyObject::STAR));
1693 allObjects.
append(composite->objectLists(SkyObject::CATALOG_STAR));
1694 allObjects.
append(composite->objectLists(SkyObject::PLANET));
1695 allObjects.
append(composite->objectLists(SkyObject::MOON));
1696 allObjects.
append(composite->objectLists(SkyObject::COMET));
1697 allObjects.
append(composite->objectLists(SkyObject::ASTEROID));
1698 allObjects.
append(composite->objectLists(SkyObject::SUPERNOVA));
1699 allObjects.
append(composite->objectLists(SkyObject::SATELLITE));
1700 dsoObjects = m_DSOManager.get_objects_all();
1702 for (
auto &oneObject : allObjects)
1703 all << oneObject.second->
name() << oneObject.second->longname().split(
", ");
1705 for (
auto &oneObject : dsoObjects)
1706 all << oneObject.
name() << oneObject.longname().split(
", ");
1712 else if (command == commands[ASTRO_GET_DESIGNATIONS])
1716 for (
auto &oneObject : m_DSOManager.get_objects_all())
1720 {
"primary", oneObject.name()},
1724 designations.
append(oneDesignation);
1727 sendResponse(commands[ASTRO_GET_DESIGNATIONS], designations);
1729 else if (command == commands[ASTRO_GET_LOCATION])
1731 auto geo = KStarsData::Instance()->
geo();
1734 {
"name",
geo->name()},
1735 {
"longitude",
geo->lng()->Degrees()},
1736 {
"latitude",
geo->lat()->Degrees()},
1737 {
"elevation",
geo->elevation()},
1742 sendResponse(commands[ASTRO_GET_LOCATION], location);
1745 else if (command == commands[ASTRO_SEARCH_OBJECTS])
1756 auto objectType =
static_cast<SkyObject::TYPE>(payload[
"type"].toInt(SkyObject::GALAXY));
1758 auto objectDirection =
static_cast<Direction
>(payload[
"direction"].toInt(All));
1760 auto objectMaxMagnitude = payload[
"maxMagnitude"].toDouble(10);
1762 auto objectMinAlt = payload[
"minAlt"].toDouble(15);
1764 auto objectMinDuration = payload[
"minDuration"].toInt(3600);
1766 auto objectMinFOV = payload[
"minFOV"].toDouble(0);
1768 auto *data = KStarsData::Instance();
1770 auto *
geo = KStarsData::Instance()->
geo();
1773 auto start = KStarsData::Instance()->
lt();
1774 auto end = getNextDawn();
1780 CatalogsDB::CatalogObjectList dsoObjects;
1786 case SkyObject::STAR:
1787 case SkyObject::CATALOG_STAR:
1788 allObjects.
append(data->skyComposite()->objectLists(SkyObject::STAR));
1789 allObjects.
append(data->skyComposite()->objectLists(SkyObject::CATALOG_STAR));
1792 case SkyObject::PLANET:
1793 case SkyObject::MOON:
1794 allObjects.
append(data->skyComposite()->objectLists(SkyObject::PLANET));
1795 allObjects.
append(data->skyComposite()->objectLists(SkyObject::MOON));
1798 case SkyObject::COMET:
1799 allObjects.
append(data->skyComposite()->objectLists(SkyObject::COMET));
1801 case SkyObject::ASTEROID:
1802 allObjects.
append(data->skyComposite()->objectLists(SkyObject::ASTEROID));
1805 case SkyObject::OPEN_CLUSTER:
1806 dsoObjects.splice(dsoObjects.end(), m_DSOManager.get_objects(SkyObject::OPEN_CLUSTER, objectMaxMagnitude));
1809 case SkyObject::GLOBULAR_CLUSTER:
1810 dsoObjects.splice(dsoObjects.end(), m_DSOManager.get_objects(SkyObject::GLOBULAR_CLUSTER, objectMaxMagnitude));
1814 case SkyObject::GASEOUS_NEBULA:
1815 dsoObjects.splice(dsoObjects.end(), m_DSOManager.get_objects(SkyObject::GASEOUS_NEBULA, objectMaxMagnitude));
1818 case SkyObject::PLANETARY_NEBULA:
1819 dsoObjects.splice(dsoObjects.end(), m_DSOManager.get_objects(SkyObject::PLANETARY_NEBULA, objectMaxMagnitude));
1822 case SkyObject::GALAXY:
1823 dsoObjects.splice(dsoObjects.end(), m_DSOManager.get_objects(SkyObject::GALAXY, objectMaxMagnitude));
1826 case SkyObject::SUPERNOVA:
1828 if (!Options::showSupernovae())
1830 Options::setShowSupernovae(
true);
1831 data->setFullTimeUpdate();
1834 allObjects.
append(data->skyComposite()->objectLists(SkyObject::SUPERNOVA));
1837 case SkyObject::SATELLITE:
1839 if (!Options::showSatellites())
1841 Options::setShowSatellites(
true);
1842 data->setFullTimeUpdate();
1845 allObjects.
append(data->skyComposite()->objectLists(SkyObject::SATELLITE));
1853 std::sort(allObjects.
begin(), allObjects.
end(), [](
const auto & a,
const auto & b)
1855 return a.second->mag() < b.second->mag();
1858 QMutableVectorIterator<QPair<QString, const SkyObject *>> objectIterator(allObjects);
1861 if (objectDirection != All)
1863 QPair<int, int> Quardent1(270, 360), Quardent2(0, 90), Quardent3(90, 180), Quardent4(180, 270);
1864 QPair<int, int> minAZ, maxAZ;
1865 switch (objectDirection)
1889 CatalogsDB::CatalogObjectList::iterator dsoIterator = dsoObjects.begin();
1890 while (dsoIterator != dsoObjects.end())
1893 const double az = (*dsoIterator).recomputeHorizontalCoords(start, geo).az().Degrees();
1894 if (! ((minAZ.first <= az && az <= minAZ.second) || (maxAZ.first <= az && az <= maxAZ.second)))
1895 dsoIterator = dsoObjects.erase(dsoIterator);
1902 while (objectIterator.hasNext())
1904 const auto az = objectIterator.next().second->recomputeHorizontalCoords(start, geo).az().Degrees();
1905 if (! ((minAZ.first <= az && az <= minAZ.second) || (maxAZ.first <= az && az <= maxAZ.second)))
1906 objectIterator.remove();
1914 objectIterator.toFront();
1915 while (objectIterator.hasNext())
1917 auto magnitude = objectIterator.next().second->mag();
1919 if (magnitude != NaN::f && magnitude > objectMaxMagnitude)
1920 objectIterator.remove();
1927 CatalogsDB::CatalogObjectList::iterator dsoIterator = dsoObjects.begin();
1928 while (dsoIterator != dsoObjects.end())
1930 double duration = 0;
1933 dms LST =
geo->GSTtoLST(t.gst());
1934 (*dsoIterator).EquatorialToHorizontal(&LST,
geo->lat());
1935 if ((*dsoIterator).alt().Degrees() >= objectMinAlt)
1939 if (duration < objectMinDuration)
1940 dsoIterator = dsoObjects.erase(dsoIterator);
1947 objectIterator.toFront();
1948 while (objectIterator.hasNext())
1950 auto oneObject = objectIterator.next().second;
1951 double duration = 0;
1955 auto LST =
geo->GSTtoLST(t.gst());
1956 const_cast<SkyObject *
>(oneObject)->EquatorialToHorizontal(&LST,
geo->lat());
1957 if (oneObject->alt().Degrees() >= objectMinAlt)
1961 if (duration < objectMinDuration)
1962 objectIterator.remove();
1967 if (isDSO && objectMinFOV > 0)
1969 CatalogsDB::CatalogObjectList::iterator dsoIterator = dsoObjects.begin();
1970 while (dsoIterator != dsoObjects.end())
1972 if ((*dsoIterator).a() < objectMinFOV)
1973 dsoIterator = dsoObjects.erase(dsoIterator);
1980 for (
auto &oneObject : allObjects)
1981 searchObjects.append(oneObject.second->
name());
1982 for (
auto &oneObject : dsoObjects)
1983 searchObjects.append(oneObject.
name());
1988 sendResponse(commands[ASTRO_SEARCH_OBJECTS], response);
1990 else if(command == commands[ASTRO_GET_OBJECT_INFO])
1992 const auto name = payload[
"object"].toString();
1993 bool exact = payload[
"exact"].toBool(
false);
2000 {
"name", exact ?
name : oneObject->
name()},
2002 {
"magnitude", oneObject->
mag()},
2005 {
"ra", oneObject->
ra().
Hours()},
2009 sendResponse(commands[ASTRO_GET_OBJECT_INFO], info);
2018 sendResponse(commands[ASTRO_GET_OBJECT_INFO], info );
2023 else if (command == commands[ASTRO_GET_OBJECTS_INFO])
2033 bool exact = payload[
"exact"].toBool(
false);
2034 QVariantList objectNames = payload[
"names"].toArray().toVariantList();
2037 for (
auto &oneName : objectNames)
2045 {
"name", exact ?
name : oneObject->
name()},
2047 {
"magnitude", oneObject->
mag()},
2050 {
"ra", oneObject->
ra().
Hours()},
2058 info[
"a"] = dsoObject->
a();
2059 info[
"b"] = dsoObject->
b();
2060 info[
"pa"] = dsoObject->
pa();
2063 objectsArray.
append(info);
2067 sendResponse(commands[ASTRO_GET_OBJECTS_INFO], objectsArray);
2070 else if (command == commands[ASTRO_GET_OBJECTS_OBSERVABILITY])
2080 QVariantList objectNames = payload[
"names"].toArray().toVariantList();
2083 bool exact = payload[
"exact"].toBool(
false);
2085 auto *data = KStarsData::Instance();
2087 auto *
geo = KStarsData::Instance()->
geo();
2089 auto ut = data->ut();
2091 for (
auto &oneName : objectNames)
2094 SkyObject *oneObject = data->skyComposite()->findByName(name, exact);
2098 dms ha(data->lst()->Degrees() - oneObject->
ra().
Degrees());
2101 {
"name", exact ?
name : oneObject->
name()},
2107 objectsArray.
append(info);
2111 sendResponse(commands[ASTRO_GET_OBJECTS_OBSERVABILITY], objectsArray);
2113 else if (command == commands[ASTRO_GET_OBJECTS_RISESET])
2123 QVariantList objectNames = payload[
"names"].toArray().toVariantList();
2126 bool exact = payload[
"exact"].toBool(
false);
2128 auto *data = KStarsData::Instance();
2130 auto *
geo = KStarsData::Instance()->
geo();
2136 if (data->lt().time().hour() > 12)
2139 for (
auto &oneName : objectNames)
2142 SkyObject *oneObject = data->skyComposite()->findByName(name, exact);
2152 if (transitTime < riseTime)
2159 if (setTime < riseTime)
2162 info[
"name"] = exact ?
name : oneObject->
name();
2172 info[
"rise"] =
"Circumpolar";
2173 info[
"set"] =
"Circumpolar";
2177 info[
"rise"] =
"Never rises";
2178 info[
"set"] =
"Never rises";
2185 for (
double h = -12.0; h <= 12.0; h += 0.5)
2187 double hour = h + (24.0 * DayOffset);
2194 info[
"altitudes"] = altitudes;
2196 objectsArray.
append(info);
2200 sendResponse(commands[ASTRO_GET_OBJECTS_RISESET], objectsArray);
2214 KSAlmanac almanac(midnight, KStarsData::Instance()->
geo());
2218 if (nextDawn < localTime)
2227void Message::requestDSLRInfo(
const QString &cameraName)
2229 sendResponse(commands[DSLR_GET_INFO], cameraName);
2235void Message::requestPortSelection(
bool show)
2237 sendResponse(commands[GET_PROFILE_PORT_SELECTION], show);
2243void Message::sendDialog(
const QJsonObject &message)
2245 sendResponse(commands[DIALOG_GET_INFO], message);
2253 for (
auto &nodeManager : m_NodeManagers)
2255 nodeManager->message()->sendResponse(command, payload);
2264 for (
auto &nodeManager : m_NodeManagers)
2266 nodeManager->message()->sendResponse(command, payload);
2273void Message::sendResponse(
const QString &command,
const QString &payload)
2275 for (
auto &nodeManager : m_NodeManagers)
2277 nodeManager->message()->sendResponse(command, payload);
2284void Message::sendResponse(
const QString &command,
bool payload)
2286 for (
auto &nodeManager : m_NodeManagers)
2288 nodeManager->message()->sendResponse(command, payload);
2295void Message::autofocusAborted()
2299 {
"status",
"Aborted"}
2301 sendResponse(commands[NEW_FOCUS_STATE], cStatus);
2307void Message::updateMountStatus(
const QJsonObject &status,
bool throttle)
2312 if (m_ThrottleTS.msecsTo(now) >= THROTTLE_INTERVAL)
2315 sendResponse(commands[NEW_MOUNT_STATE], status);
2319 sendResponse(commands[NEW_MOUNT_STATE], status);
2325void Message::updateCaptureStatus(
const QJsonObject &status)
2327 sendResponse(commands[NEW_CAPTURE_STATE], status);
2333void Message::updateFocusStatus(
const QJsonObject &status)
2335 sendResponse(commands[NEW_FOCUS_STATE], status);
2341void Message::updateGuideStatus(
const QJsonObject &status)
2343 sendResponse(commands[NEW_GUIDE_STATE], status);
2349void Message::updateDomeStatus(
const QJsonObject &status)
2351 sendResponse(commands[NEW_DOME_STATE], status);
2357void Message::updateCapStatus(
const QJsonObject &status)
2359 sendResponse(commands[NEW_CAP_STATE], status);
2365void Message::updateAlignStatus(
const QJsonObject &status)
2367 sendResponse(commands[NEW_ALIGN_STATE], status);
2373void Message::sendConnection()
2377 {
"connected",
true},
2378 {
"online", m_Manager->getEkosStartingStatus() == Ekos::Success}
2381 sendResponse(commands[NEW_CONNECTION_STATE], connectionState);
2387void Message::sendStates()
2390 if (m_Manager->captureModule())
2392 QJsonObject captureState = {{
"status", getCaptureStatusString(m_Manager->captureModule()->status(),
false)}};
2393 sendResponse(commands[NEW_CAPTURE_STATE], captureState);
2394 sendCaptureSequence(m_Manager->captureModule()->getSequence());
2397 if (m_Manager->mountModule())
2401 {
"status", m_Manager->mountModule()->statusString(
false)},
2402 {
"target", m_Manager->capturePreview->mountTarget->text()},
2403 {
"slewRate", m_Manager->mountModule()->slewRate()},
2404 {
"pierSide", m_Manager->mountModule()->pierSide()}
2407 sendResponse(commands[NEW_MOUNT_STATE], mountState);
2410 if (m_Manager->focusModule())
2412 QJsonObject focusState = {{
"status", getFocusStatusString(m_Manager->focusModule()->status(),
false)}};
2413 sendResponse(commands[NEW_FOCUS_STATE], focusState);
2416 if (m_Manager->guideModule())
2418 QJsonObject guideState = {{
"status", getGuideStatusString(m_Manager->guideModule()->status(),
false)}};
2419 sendResponse(commands[NEW_GUIDE_STATE], guideState);
2422 if (m_Manager->alignModule())
2427 {
"status", getAlignStatusString(m_Manager->alignModule()->status(),
false)}
2429 sendResponse(commands[NEW_ALIGN_STATE], alignState);
2432 sendAlignSettings(m_Manager->alignModule()->getAllSettings());
2439 doc.
setHtml(paa->getPAHMessage());
2442 {
"stage", paa->getPAHStageString(
false)},
2446 sendResponse(commands[NEW_POLAR_STATE], polarState);
2454void Message::sendEvent(
const QString &message, KSNotification::EventSource source, KSNotification::EventType event)
2456 if (Options::ekosLiveNotifications() ==
false)
2462 {
"severity",
event},
2463 {
"message", message},
2467 sendResponse(commands[NEW_NOTIFICATION], newEvent);
2473void Message::sendManualRotatorStatus(
double currentPA,
double targetPA,
double threshold)
2475 QJsonObject request = {{
"currentPA", currentPA}, {
"targetPA", targetPA}, {
"threshold", threshold}};
2476 sendResponse(commands[ALIGN_MANUAL_ROTATOR_STATUS], request);
2482void Message::setBoundingRect(
QRect rect,
QSize view,
double currentZoom)
2484 m_BoundingRect = rect;
2486 m_CurrentZoom = currentZoom;
2492void Message::processDialogResponse(
const QJsonObject &payload)
2500void Message::processNewProperty(INDI::Property prop)
2505 if (m_Manager->settleStatus() != Ekos::CommunicationStatus::Success)
2509 ISD::propertyToJson(prop, propObject,
false);
2510 sendResponse(commands[DEVICE_PROPERTY_ADD], propObject);
2516void Message::processDeleteProperty(INDI::Property prop)
2520 {
"device", prop.getDeviceName()},
2521 {
"name", prop.getName()}
2524 sendResponse(commands[DEVICE_PROPERTY_REMOVE], payload);
2532 if (Options::ekosLiveNotifications() ==
false)
2538 {
"device", device->getDeviceName()},
2539 {
"message", message}
2542 sendResponse(commands[DEVICE_MESSAGE], payload);
2548void Message::processUpdateProperty(INDI::Property prop)
2550 if (m_PropertySubscriptions.contains(prop.getDeviceName()))
2552 QSet<QString> subProps = m_PropertySubscriptions[prop.getDeviceName()];
2553 if (subProps.
contains(prop.getName()))
2555 m_PendingProperties.
remove(prop);
2556 m_PendingProperties.insert(prop);
2564void Message::setPendingPropertiesEnabled(
bool enabled)
2567 m_PendingPropertiesTimer.start();
2570 m_PendingPropertiesTimer.stop();
2571 m_PendingProperties.clear();
2578void Message::sendPendingProperties()
2580 for (
auto &prop : m_PendingProperties)
2582 if (prop->isValid())
2585 ISD::propertyToJson(*prop, propObject);
2586 sendResponse(commands[DEVICE_PROPERTY_GET], propObject);
2590 m_PendingProperties.clear();
2596void Message::sendModuleState(
const QString &name)
2598 if (name ==
"Capture")
2600 QJsonObject captureState = {{
"status", getCaptureStatusString(m_Manager->captureModule()->status(),
false)}};
2601 sendResponse(commands[NEW_CAPTURE_STATE], captureState);
2602 sendCaptureSequence(m_Manager->captureModule()->getSequence());
2604 else if (name ==
"Mount")
2608 {
"status", m_Manager->mountStatus->getStatusText()},
2609 {
"target", m_Manager->capturePreview->mountTarget->text()},
2610 {
"slewRate", m_Manager->mountModule()->slewRate()},
2611 {
"pierSide", m_Manager->mountModule()->pierSide()}
2614 sendResponse(commands[NEW_MOUNT_STATE], mountState);
2616 else if (name ==
"Focus")
2618 QJsonObject focusState = {{
"status", getFocusStatusString(m_Manager->focusModule()->status(),
false)}};
2619 sendResponse(commands[NEW_FOCUS_STATE], focusState);
2621 else if (name ==
"Guide")
2623 QJsonObject guideState = {{
"status", getGuideStatusString(m_Manager->guideModule()->status(),
false)}};
2624 sendResponse(commands[NEW_GUIDE_STATE], guideState);
2626 else if (name ==
"Align")
2631 {
"status", getAlignStatusString(m_Manager->alignModule()->status(),
false)}
2633 sendResponse(commands[NEW_ALIGN_STATE], alignState);
2636 sendAlignSettings(m_Manager->alignModule()->getAllSettings());
2643 doc.
setHtml(paa->getPAHMessage());
2646 {
"stage", paa->getPAHStageString(
false)},
2650 sendResponse(commands[NEW_POLAR_STATE], polarState);
2662 if (name ==
"Manager")
2674 for (
auto &viewer :
KStars::Instance()->getFITSViewers())
2676 for (
auto &tab : viewer->tabs())
2678 if (tab->getView()->objectName() == name)
2679 return tab->getView().get();
2698 case QVariant::Type::Int:
2699 types.number_integer = arg.
toInt();
2700 genericArg = Q_ARG(
int, types.number_integer);
2702 case QVariant::Type::UInt:
2703 types.number_unsigned_integer = arg.
toUInt();
2704 genericArg = Q_ARG(uint, types.number_unsigned_integer);
2706 case QVariant::Type::LongLong:
2708 genericArg = Q_ARG(
int, types.number_integer);
2710 case QVariant::Type::ULongLong:
2711 types.number_unsigned_integer = arg.
toULongLong();
2712 genericArg = Q_ARG(uint, types.number_unsigned_integer);
2714 case QVariant::Type::Double:
2715 types.number_double = arg.
toDouble();
2716 genericArg = Q_ARG(
double, types.number_double);
2718 case QVariant::Type::Bool:
2719 types.boolean = arg.
toBool();
2720 genericArg = Q_ARG(
bool, types.boolean);
2722 case QVariant::Type::String:
2724 genericArg = Q_ARG(
QString, types.text);
2726 case QVariant::Type::Url:
2727 types.url = arg.
toUrl();
2728 genericArg = Q_ARG(
QUrl, types.
url);
2745 auto name = payload[
"name"].toString().toLatin1();
2751 for (
auto oneArg : args)
2753 auto argObject = oneArg.toObject();
2755 SimpleTypes genericType;
2756 argsList.
append(genericArgument);
2757 typesList.
append(genericType);
2758 if (parseArgument(
static_cast<QVariant::Type>(argObject[
"type"].toInt()), argObject[
"value"].toVariant(), argsList.
back(),
2759 typesList.
last()) ==
false)
2766 switch (argsList.
size())
a dms subclass that caches its sine and cosine values every time the angle is changed.
A simple container object to hold the minimum information for a Deep Sky Object to be drawn on the sk...
double pa() const override
Align class handles plate-solving and polar alignment measurement and correction using astrometry....
bool loadAndSlew(const QByteArray &image, const QString &extension)
DBUS interface function.
Captures single or sequence of images from a CCD.
bool setVideoLimits(uint16_t maxBufferSize, uint16_t maxPreviewFPS)
setVideoLimits sets the buffer size and max preview fps for live preview
const QJsonArray & getSequence() const
getSequence Return the JSON representation of the current sequeue queue
void stop()
stop Abort all dark job captures.
Supports manual focusing and auto focusing using relative and absolute INDI focusers.
void startFraming()
startFraming Begins continuous capture of the CCD and calculates HFR every frame.
void selectFocusStarFraction(double x, double y)
selectFocusStarFraction Select the focus star based by fraction of the overall size.
Q_SCRIPTABLE Q_NOREPLY void resetFrame()
DBUS interface function.
Performs calibration and autoguiding using an ST4 port or directly via the INDI driver.
Q_SCRIPTABLE bool capture()
DBUS interface function.
Q_SCRIPTABLE Q_NOREPLY void clearCalibration()
DBUS interface function.
Q_SCRIPTABLE bool abort()
DBUS interface function.
Q_SCRIPTABLE Q_NOREPLY void loop()
DBUS interface function.
Q_SCRIPTABLE bool guide()
DBUS interface function.
Supports controlling INDI telescope devices including setting/retrieving mount properties,...
The PolarAlignmentAssistant class.
The Ekos scheduler is a simple scheduler class to orchestrate automated multi object observation jobs...
void addJob(SchedulerJob *job=nullptr)
addJob Add a new job from form values
bool importMosaic(const QJsonObject &payload)
importMosaic Import mosaic into planner and generate jobs for the scheduler.
bool loadFile(const QUrl &path)
loadFile Load scheduler jobs from disk
bool saveFile(const QUrl &path)
saveFile Save scheduler jobs to disk
void removeOneJob(int index)
Remove a job by selecting a table row.
INDIListener is responsible for creating ISD::GDInterface generic devices as new devices arrive from ...
Camera class controls an INDI Camera device.
Q_INVOKABLE QAction * action(const QString &name) const
A class that implements methods to find sun rise, sun set, twilight begin / end times,...
bool selectResponse(const QString &button)
selectResponse Programatically select one the buttons in the dialog.
bool GetAllScopes(QList< OAL::Scope * > &m_scopeList)
updates the scope list with all scopes from database List is cleared and then filled with content.
bool AddDSLRLens(const QString &model, const QString &vendor, const double focalLength, const double focalRatio)
Appends the DSLR lens with given details in the database.
bool AddScope(const QString &model, const QString &vendor, const QString &type, const double &aperture, const double &focalLength)
Appends the scope with given details in the database.
bool DeleteEquipment(const QString &type, const QString &id)
Erase the equipment with given type and unique id Valid equipment types: "telescope",...
bool GetAllDSLRLenses(QList< OAL::DSLRLens * > &dslrlens_list)
updates the dslr list with all DSLR lenses from database List is cleared and then filled with content...
const KStarsDateTime & lt() const
void changeDateTime(const KStarsDateTime &newDate)
Change the current simulation date/time to the KStarsDateTime argument.
Q_INVOKABLE SimClock * clock()
SkyMapComposite * skyComposite()
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
KStarsDateTime addDays(int nd) const
Modify the Date/Time by adding a number of days.
KStarsDateTime addSecs(double s) const
static KStarsDateTime currentDateTimeUtc()
This is the main window for KStars.
static KStars * Instance()
virtual KActionCollection * actionCollection() const
Q_SCRIPTABLE Q_NOREPLY void start()
DBUS function to start the SimClock.
Q_SCRIPTABLE Q_NOREPLY void setUTC(const KStarsDateTime &newtime)
DBUS function to set the time of the SimClock.
Q_SCRIPTABLE Q_NOREPLY void stop()
DBUS function to stop the SimClock.
SkyObject * findByName(const QString &name, bool exact=true) override
Search the children of this SkyMapComposite for a SkyObject whose name matches the argument.
void forceUpdate(bool now=false)
Recalculates the positions of objects in the sky, and then repaints the sky map.
Provides all necessary information about an object in the sky: its coordinates, name(s),...
virtual QString name(void) const
virtual QString longname(void) const
QTime transitTime(const KStarsDateTime &dt, const GeoLocation *geo) const
The same iteration technique described in riseSetTime() is used here.
QTime riseSetTime(const KStarsDateTime &dt, const GeoLocation *geo, bool rst, bool exact=true) const
Determine the time at which the point will rise or set.
TYPE
The type classification of the SkyObject.
The sky coordinates of a point in the sky.
void apparentCoord(long double jd0, long double jdf)
Computes the apparent coordinates for this SkyPoint for any epoch, accounting for the effects of prec...
const CachingDms & dec() const
const CachingDms & ra0() const
const CachingDms & ra() const
void EquatorialToHorizontal(const CachingDms *LST, const CachingDms *lat)
Determine the (Altitude, Azimuth) coordinates of the SkyPoint from its (RA, Dec) coordinates,...
const CachingDms & dec0() const
An angle, stored as degrees, but expressible in many ways.
static dms fromString(const QString &s, bool deg)
Static function to create a DMS object from a QString.
const double & Degrees() const
Q_SCRIPTABLE bool captureAndSolve(bool initialCall=true)
DBUS interface function.
Q_SCRIPTABLE Q_NOREPLY void abort()
DBUS interface function.
Q_SCRIPTABLE Q_NOREPLY void toggleVideo(bool enabled)
DBUS interface function.
Q_SCRIPTABLE Q_NOREPLY void stop(CaptureState targetState=CAPTURE_IDLE)
DBUS interface function.
Q_SCRIPTABLE Q_NOREPLY void start()
DBUS interface function.
Q_SCRIPTABLE bool saveSequenceQueue(const QString &path)
DBUS interface function.
Q_SCRIPTABLE bool loadSequenceQueue(const QString &fileURL, QString targetName="")
DBUS interface function.
Q_SCRIPTABLE Q_NOREPLY void clearSequenceQueue()
DBUS interface function.
Q_SCRIPTABLE Q_NOREPLY void capture(double settleTime=0.0)
DBUS interface function.
Q_SCRIPTABLE bool focusOut(int ms=-1)
DBUS interface function.
Q_SCRIPTABLE Q_NOREPLY void start()
DBUS interface function.
Q_SCRIPTABLE Q_NOREPLY void abort()
DBUS interface function.
Q_SCRIPTABLE bool focusIn(int ms=-1)
DBUS interface function.
KLocalizedString KI18N_EXPORT ki18n(const char *text)
QString i18n(const char *text, const TYPE &arg...)
char * toString(const EngineQuery &query)
Generic record interfaces and implementations.
Ekos is an advanced Astrophotography tool for Linux.
KDB_EXPORT void getProperties(const KDbLookupFieldSchema *lookup, QMap< QByteArray, QVariant > *values)
QString name(GameStandardAction id)
QAction * end(const QObject *recvr, const char *slot, QObject *parent)
KIOCORE_EXPORT SimpleJob * mount(bool ro, const QByteArray &fstype, const QString &dev, const QString &point, JobFlags flags=DefaultFlags)
GeoCoordinates geo(const QVariant &location)
QVariant location(const QVariant &res)
QString path(const QString &relativePath)
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
NETWORKMANAGERQT_EXPORT NetworkManager::Status status()
QCA_EXPORT void setProperty(const QString &name, const QVariant &value)
QByteArray fromBase64(const QByteArray &base64, Base64Options options)
void setCurrentIndex(int index)
QDateTime currentDateTime()
virtual void close() override
qint64 write(const QByteArray &data)
void append(const QJsonValue &value)
QJsonArray fromStringList(const QStringList &list)
bool isEmpty() const const
QVariantList toVariantList() const const
QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error)
bool contains(QLatin1StringView key) const const
QJsonObject fromVariantMap(const QVariantMap &map)
iterator insert(QLatin1StringView key, const QJsonValue &value)
QVariantMap toVariantMap() const const
qreal angle() const const
qreal length() const const
void append(QList< T > &&value)
qsizetype size() const const
T findChild(const QString &name, Qt::FindChildOptions options) const const
bool contains(const QSet< T > &other) const const
iterator insert(const T &value)
bool remove(const T &value)
bool isNull() const const
QString arg(Args &&... args) const const
QString asprintf(const char *cformat,...)
QString fromLatin1(QByteArrayView str)
QString fromStdString(const std::string &str)
QString fromUtf8(QByteArrayView str)
bool isEmpty() const const
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QByteArray toLatin1() const const
QByteArray toUtf8() const const
qsizetype removeDuplicates()
void sort(Qt::CaseSensitivity cs)
QTextStream & center(QTextStream &stream)
QFuture< void > map(Iterator begin, Iterator end, MapFunctor &&function)
virtual QString fileName() const const override
void setAutoRemove(bool b)
void setHtml(const QString &html)
QString toPlainText() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
bool isValid(int h, int m, int s, int ms)
QUrl fromLocalFile(const QString &localFile)
QString url(FormattingOptions options) const const
QString toString(StringFormat mode) const const
bool toBool() const const
double toDouble(bool *ok) const const
int toInt(bool *ok) const const
qlonglong toLongLong(bool *ok) const const
QString toString() const const
uint toUInt(bool *ok) const const
qulonglong toULongLong(bool *ok) const const