7#include "capturedeviceadaptor.h"
9#include "ksmessagebox.h"
11#include "indi/indistd.h"
12#include "ekos_capture_debug.h"
13#include "sequencejobstate.h"
15#include "indi/indicamera.h"
16#include "indi/indidustcap.h"
17#include "indi/indidome.h"
18#include "indi/indilightbox.h"
19#include "indi/indimount.h"
20#include "indi/indirotator.h"
21#include "ekos/auxiliary/rotatorutils.h"
27void CaptureDeviceAdaptor::connectDome(SequenceJobState *state)
32 connect(state, &SequenceJobState::setDomeParked,
this, &CaptureDeviceAdaptor::setDomeParked);
33 connect(
this, &CaptureDeviceAdaptor::domeStatusChanged, state, &SequenceJobState::domeStatusChanged);
36void CaptureDeviceAdaptor::disconnectDome(SequenceJobState *state)
41 disconnect(state, &SequenceJobState::setDomeParked,
this, &CaptureDeviceAdaptor::setDomeParked);
42 disconnect(
this, &CaptureDeviceAdaptor::domeStatusChanged, state, &SequenceJobState::domeStatusChanged);
48 disconnectDevices(currentSequenceJobState.
data());
50 connectRotator(jobState.data());
51 connectFilterManager(jobState.data());
52 connectActiveCamera(jobState.data());
53 connectMount(jobState.data());
54 connectDome(jobState.data());
55 connectDustCap(jobState.data());
56 currentSequenceJobState = jobState;
60void CaptureDeviceAdaptor::setDustCap(
ISD::DustCap *device)
62 disconnectDustCap(currentSequenceJobState.
data());
63 m_ActiveDustCap = device;
64 connectDustCap(currentSequenceJobState.
data());
67void CaptureDeviceAdaptor::disconnectDevices(SequenceJobState *state)
69 disconnectRotator(state);
70 disconnectFilterManager(state);
71 disconnectActiveCamera(state);
72 disconnectMount(state);
73 disconnectDome(state);
74 disconnectDustCap(state);
81void CaptureDeviceAdaptor::connectDustCap(SequenceJobState *state)
83 if (m_ActiveDustCap !=
nullptr)
84 connect(m_ActiveDustCap, &ISD::DustCap::newStatus,
this, &CaptureDeviceAdaptor::dustCapStatusChanged);
89 connect(state, &SequenceJobState::askManualScopeCover,
this, &CaptureDeviceAdaptor::askManualScopeCover);
90 connect(state, &SequenceJobState::askManualScopeOpen,
this, &CaptureDeviceAdaptor::askManualScopeOpen);
91 connect(state, &SequenceJobState::setLightBoxLight,
this, &CaptureDeviceAdaptor::setLightBoxLight);
92 connect(state, &SequenceJobState::parkDustCap,
this, &CaptureDeviceAdaptor::parkDustCap);
94 connect(
this, &CaptureDeviceAdaptor::manualScopeCoverUpdated, state, &SequenceJobState::updateManualScopeCover);
95 connect(
this, &CaptureDeviceAdaptor::lightBoxLight, state, &SequenceJobState::lightBoxLight);
96 connect(
this, &CaptureDeviceAdaptor::dustCapStatusChanged, state, &SequenceJobState::dustCapStateChanged);
99void CaptureDeviceAdaptor::disconnectDustCap(SequenceJobState *state)
101 if (m_ActiveDustCap !=
nullptr)
102 disconnect(m_ActiveDustCap,
nullptr,
this,
nullptr);
104 if (state ==
nullptr)
107 disconnect(state, &SequenceJobState::askManualScopeCover,
this, &CaptureDeviceAdaptor::askManualScopeCover);
108 disconnect(state, &SequenceJobState::askManualScopeOpen,
this, &CaptureDeviceAdaptor::askManualScopeOpen);
109 disconnect(state, &SequenceJobState::setLightBoxLight,
this, &CaptureDeviceAdaptor::setLightBoxLight);
110 disconnect(state, &SequenceJobState::parkDustCap,
this, &CaptureDeviceAdaptor::parkDustCap);
112 disconnect(
this, &CaptureDeviceAdaptor::manualScopeCoverUpdated, state, &SequenceJobState::updateManualScopeCover);
113 disconnect(
this, &CaptureDeviceAdaptor::lightBoxLight, state, &SequenceJobState::lightBoxLight);
114 disconnect(
this, &CaptureDeviceAdaptor::dustCapStatusChanged, state, &SequenceJobState::dustCapStateChanged);
117void CaptureDeviceAdaptor::setMount(
ISD::Mount *device)
119 if (m_ActiveMount == device)
123 if (m_ActiveMount !=
nullptr)
125 disconnect(m_ActiveMount,
nullptr,
this,
nullptr);
126 disconnectMount(currentSequenceJobState.
data());
129 if (device !=
nullptr)
132 connect(device, &ISD::Mount::pierSideChanged,
this, &CaptureDeviceAdaptor::pierSideChanged);
133 connect(device, &ISD::Mount::newParkStatus,
this, &CaptureDeviceAdaptor::scopeParkStatusChanged);
134 connectMount(currentSequenceJobState.
data());
137 emit pierSideChanged(device->pierSide());
138 emit scopeParkStatusChanged(device->parkStatus());
141 m_ActiveMount = device;
144void CaptureDeviceAdaptor::connectMount(SequenceJobState *state)
146 if (state ==
nullptr)
149 connect(state, &SequenceJobState::slewTelescope,
this, &CaptureDeviceAdaptor::slewTelescope);
150 connect(state, &SequenceJobState::setScopeTracking,
this, &CaptureDeviceAdaptor::setScopeTracking);
151 connect(state, &SequenceJobState::setScopeParked,
this, &CaptureDeviceAdaptor::setScopeParked);
153 connect(
this, &CaptureDeviceAdaptor::scopeStatusChanged, state, &SequenceJobState::scopeStatusChanged);
154 connect(
this, &CaptureDeviceAdaptor::scopeParkStatusChanged, state, &SequenceJobState::scopeParkStatusChanged);
157void CaptureDeviceAdaptor::disconnectMount(SequenceJobState *state)
159 if (state ==
nullptr)
162 disconnect(state, &SequenceJobState::slewTelescope,
this, &CaptureDeviceAdaptor::slewTelescope);
163 disconnect(state, &SequenceJobState::setScopeTracking,
this, &CaptureDeviceAdaptor::setScopeTracking);
164 disconnect(state, &SequenceJobState::setScopeParked,
this, &CaptureDeviceAdaptor::setScopeParked);
166 disconnect(
this, &CaptureDeviceAdaptor::scopeStatusChanged, state, &SequenceJobState::scopeStatusChanged);
167 disconnect(
this, &CaptureDeviceAdaptor::scopeParkStatusChanged, state, &SequenceJobState::scopeParkStatusChanged);
170void CaptureDeviceAdaptor::setDome(
ISD::Dome *device)
172 if (m_ActiveDome == device)
176 if (m_ActiveDome !=
nullptr)
178 disconnect(m_ActiveDome,
nullptr,
this,
nullptr);
179 disconnectDome(currentSequenceJobState.
data());
182 if (device !=
nullptr)
184 connect(device, &ISD::Dome::newStatus,
this, &CaptureDeviceAdaptor::domeStatusChanged);
185 connectDome(currentSequenceJobState.
data());
188 m_ActiveDome = device;
191void CaptureDeviceAdaptor::setRotator(
ISD::Rotator *device)
194 if ((m_ActiveRotator == device) && (device !=
nullptr))
198 if (m_ActiveRotator !=
nullptr)
201 disconnectRotator(currentSequenceJobState.
data());
204 m_ActiveRotator = device;
207 if (m_ActiveRotator !=
nullptr)
209 connect(m_ActiveRotator, &ISD::Rotator::newAbsoluteAngle,
this, &CaptureDeviceAdaptor::newRotatorAngle,
211 connect(m_ActiveRotator, &ISD::Rotator::reverseToggled,
this, &CaptureDeviceAdaptor::rotatorReverseToggled,
213 connectRotator(currentSequenceJobState.
data());
215 emit newRotator(device->getDeviceName());
222void CaptureDeviceAdaptor::connectRotator(SequenceJobState *state)
224 if (state ==
nullptr)
227 connect(
this, &CaptureDeviceAdaptor::newRotatorAngle, state, &SequenceJobState::setCurrentRotatorPositionAngle,
229 connect(state, &SequenceJobState::setRotatorAngle,
this, &CaptureDeviceAdaptor::setRotatorAngle);
232void CaptureDeviceAdaptor::disconnectRotator(SequenceJobState *state)
234 if (state ==
nullptr)
237 disconnect(state, &SequenceJobState::setRotatorAngle,
this, &CaptureDeviceAdaptor::setRotatorAngle);
238 disconnect(
this, &CaptureDeviceAdaptor::newRotatorAngle, state, &SequenceJobState::setCurrentRotatorPositionAngle);
241void CaptureDeviceAdaptor::setRotatorAngle(
double rawAngle)
243 if (m_ActiveRotator !=
nullptr && m_ActiveRotator->setAbsoluteAngle(
rawAngle))
245 RotatorUtils::Instance()->initTimeFrame(
rawAngle);
250 <<
"failed due to missing or unresponsive rotator.";
253double CaptureDeviceAdaptor::getRotatorAngle()
255 if (m_ActiveRotator !=
nullptr)
256 return m_ActiveRotator->absoluteAngle();
261IPState CaptureDeviceAdaptor::getRotatorAngleState()
263 if (m_ActiveRotator !=
nullptr)
264 return m_ActiveRotator->absoluteAngleState();
269void CaptureDeviceAdaptor::reverseRotator(
bool toggled)
271 if (m_ActiveRotator !=
nullptr)
273 m_ActiveRotator->setReversed(toggled);
274 m_ActiveRotator->setConfig(SAVE_CONFIG);
278void CaptureDeviceAdaptor::readRotatorAngle()
280 if (m_ActiveRotator !=
nullptr)
281 emit newRotatorAngle(m_ActiveRotator->absoluteAngle(), m_ActiveRotator->absoluteAngleState());
286void CaptureDeviceAdaptor::setActiveCamera(
ISD::Camera *device)
288 if (m_ActiveCamera == device)
292 if (m_ActiveCamera !=
nullptr)
295 disconnectActiveCamera(currentSequenceJobState.
data());
300 m_ActiveCamera = device;
303 if (m_ActiveCamera !=
nullptr)
306 connect(m_ActiveCamera, &ISD::Camera::newTemperatureValue,
this,
308 connect(m_ActiveCamera, &ISD::ConcreteDevice::Connected,
this, [
this]()
310 emit CameraConnected(
true);
312 connect(m_ActiveCamera, &ISD::ConcreteDevice::Disconnected,
this, [
this]()
314 emit CameraConnected(
false);
317 if (m_ActiveCamera->hasGuideHead())
318 addGuideHead(device);
320 connectActiveCamera(currentSequenceJobState.
data());
323 emit newCamera(device ==
nullptr ?
"" : device->getDeviceName());
326void CaptureDeviceAdaptor::setFilterWheel(ISD::FilterWheel *device)
328 if (m_ActiveFilterWheel == device)
332 if (m_ActiveFilterWheel !=
nullptr)
336 m_ActiveFilterWheel = device;
339 if (m_ActiveFilterWheel !=
nullptr)
341 connect(m_ActiveFilterWheel, &ISD::ConcreteDevice::Connected,
this, [
this]()
343 emit FilterWheelConnected(
true);
345 connect(m_ActiveFilterWheel, &ISD::ConcreteDevice::Disconnected,
this, [
this]()
347 emit FilterWheelConnected(
false);
352 emit newFilterWheel(device ==
nullptr ?
"" : device->getDeviceName());
355void CaptureDeviceAdaptor::connectActiveCamera(SequenceJobState *state)
357 if (state ==
nullptr)
361 connect(state, &SequenceJobState::setCCDTemperature,
this, &CaptureDeviceAdaptor::setCCDTemperature);
362 connect(state, &SequenceJobState::setCCDBatchMode,
this, &CaptureDeviceAdaptor::enableCCDBatchMode);
363 connect(state, &SequenceJobState::queryHasShutter,
this, &CaptureDeviceAdaptor::queryHasShutter);
366 connect(
this, &CaptureDeviceAdaptor::flatSyncFocusChanged, state, &SequenceJobState::flatSyncFocusChanged);
367 connect(
this, &CaptureDeviceAdaptor::hasShutter, state, &SequenceJobState::hasShutter);
368 connect(
this, &CaptureDeviceAdaptor::newCCDTemperatureValue, state, &SequenceJobState::setCurrentCCDTemperature,
372void CaptureDeviceAdaptor::disconnectActiveCamera(SequenceJobState *state)
374 if (state ==
nullptr)
377 disconnect(state, &SequenceJobState::setCCDTemperature,
this, &CaptureDeviceAdaptor::setCCDTemperature);
378 disconnect(state, &SequenceJobState::setCCDBatchMode,
this, &CaptureDeviceAdaptor::enableCCDBatchMode);
379 disconnect(state, &SequenceJobState::queryHasShutter,
this, &CaptureDeviceAdaptor::queryHasShutter);
381 disconnect(
this, &CaptureDeviceAdaptor::flatSyncFocusChanged, state, &SequenceJobState::flatSyncFocusChanged);
382 disconnect(
this, &CaptureDeviceAdaptor::hasShutter, state, &SequenceJobState::hasShutter);
383 disconnect(
this, &CaptureDeviceAdaptor::newCCDTemperatureValue, state, &SequenceJobState::setCurrentCCDTemperature);
386void CaptureDeviceAdaptor::connectFilterManager(SequenceJobState *state)
388 if (state ==
nullptr)
391 connect(state, &SequenceJobState::changeFilterPosition,
this, &CaptureDeviceAdaptor::setFilterPosition);
392 connect(state, &SequenceJobState::readFilterPosition,
this, &CaptureDeviceAdaptor::updateFilterPosition);
393 connect(
this, &CaptureDeviceAdaptor::filterIdChanged, state, &SequenceJobState::setCurrentFilterID);
395 if (m_FilterManager.
isNull() ==
false)
396 connect(m_FilterManager.
get(), &FilterManager::newStatus, state, &SequenceJobState::setFilterStatus);
399void CaptureDeviceAdaptor::disconnectFilterManager(SequenceJobState *state)
401 if (state ==
nullptr)
404 disconnect(state, &SequenceJobState::readFilterPosition,
this, &CaptureDeviceAdaptor::updateFilterPosition);
405 disconnect(state, &SequenceJobState::changeFilterPosition,
this, &CaptureDeviceAdaptor::setFilterPosition);
406 disconnect(
this, &CaptureDeviceAdaptor::filterIdChanged, state, &SequenceJobState::setCurrentFilterID);
408 if (m_FilterManager.
isNull() ==
false)
409 disconnect(m_FilterManager.
get(), &FilterManager::newStatus, state, &SequenceJobState::setFilterStatus);
412void Ekos::CaptureDeviceAdaptor::updateFilterPosition()
414 if (m_FilterManager.isNull())
417 emit filterIdChanged(-1);
420 emit filterIdChanged(m_FilterManager->getFilterPosition());
423void CaptureDeviceAdaptor::readCurrentState(CaptureState state)
428 if (m_ActiveCamera !=
nullptr)
430 double currentTemperature;
431 m_ActiveCamera->getTemperature(¤tTemperature);
432 emit newCCDTemperatureValue(currentTemperature);
448void CaptureDeviceAdaptor::setCCDTemperature(
double temp)
450 if (m_ActiveCamera !=
nullptr)
451 m_ActiveCamera->setTemperature(temp);
454void CaptureDeviceAdaptor::enableCCDBatchMode(
bool enable)
456 if (m_ActiveChip !=
nullptr)
457 m_ActiveChip->setBatchMode(enable);
460void CaptureDeviceAdaptor::abortFastExposure()
462 if (m_ActiveCamera !=
nullptr && m_ActiveChip !=
nullptr && m_ActiveCamera->isFastExposureEnabled())
463 m_ActiveChip->abortExposure();
468 if (getActiveCamera())
472 return propertyMap[
"CCD_GAIN"].value(
"GAIN", -1).toDouble();
473 else if (getActiveCamera()->
getProperty(
"CCD_CONTROLS"))
474 return propertyMap[
"CCD_CONTROLS"].value(
"Gain", -1).toDouble();
479 if (propertyMap.keys().contains(
"CCD_GAIN"))
480 return propertyMap[
"CCD_GAIN"].value(
"GAIN", -1).toDouble();
481 else if(propertyMap.keys().contains(
"CCD_CONTROLS"))
482 return propertyMap[
"CCD_CONTROLS"].value(
"Gain", -1).toDouble();
490double CaptureDeviceAdaptor::cameraGain()
492 double value = INVALID_VALUE;
493 if (getActiveCamera() !=
nullptr)
494 getActiveCamera()->getGain(&value);
501 if (getActiveCamera())
504 return propertyMap[
"CCD_OFFSET"].value(
"OFFSET", -1).toDouble();
505 else if (getActiveCamera()->
getProperty(
"CCD_CONTROLS"))
506 return propertyMap[
"CCD_CONTROLS"].value(
"Offset", -1).toDouble();
511 if (propertyMap.keys().contains(
"CCD_OFFSET"))
512 return propertyMap[
"CCD_OFFSET"].value(
"OFFSET", -1).toDouble();
513 else if(propertyMap.keys().contains(
"CCD_CONTROLS"))
514 return propertyMap[
"CCD_CONTROLS"].value(
"Offset", -1).toDouble();
519double CaptureDeviceAdaptor::cameraOffset()
521 double value = INVALID_VALUE;
522 if (getActiveCamera() !=
nullptr)
523 getActiveCamera()->getOffset(&value);
528double CaptureDeviceAdaptor::cameraTemperature()
530 double value = INVALID_VALUE;
531 if (getActiveCamera() !=
nullptr)
532 getActiveCamera()->getTemperature(&value);
537void CaptureDeviceAdaptor::setFilterPosition(
int targetFilterPosition, FilterManager::FilterPolicy policy)
539 if (m_FilterManager.
isNull() ==
false && m_ActiveFilterWheel !=
nullptr)
540 m_FilterManager->setFilterPosition(targetFilterPosition, policy);
550 if (m_FilterManager == device)
554 if (m_FilterManager.
isNull() ==
false)
556 disconnect(m_FilterManager.
get(), &FilterManager::ready,
this, &CaptureDeviceAdaptor::updateFilterPosition);
557 disconnectFilterManager(currentSequenceJobState.
data());
560 if (device.isNull() ==
false)
562 connect(device.get(), &FilterManager::ready,
this, &CaptureDeviceAdaptor::updateFilterPosition);
563 connectFilterManager(currentSequenceJobState.
data());
566 m_FilterManager = device;
569void CaptureDeviceAdaptor::askManualScopeCover(
QString question,
QString title,
bool light)
572 if (light && m_ManualLightCoveringAsked ==
true)
574 emit manualScopeCoverUpdated(
true,
true,
true);
577 else if (!light && m_ManualDarkCoveringAsked ==
true)
579 emit manualScopeCoverUpdated(
true,
true,
false);
586 emit manualScopeCoverUpdated(
true,
true, light);
587 KSMessageBox::Instance()->disconnect(
this);
588 m_ManualLightCoveringAsked =
false;
589 m_ManualLightOpeningAsked =
false;
590 m_ManualDarkCoveringAsked =
false;
591 m_ManualDarkOpeningAsked =
false;
593 m_ManualLightCoveringAsked =
true;
595 m_ManualDarkCoveringAsked =
true;
602 m_ManualLightCoveringAsked =
false;
604 m_ManualDarkCoveringAsked =
false;
606 emit manualScopeCoverUpdated(
true,
false, light);
607 KSMessageBox::Instance()->disconnect(
this);
610 KSMessageBox::Instance()->warningContinueCancel(question, title, Options::manualCoverTimeout());
614void CaptureDeviceAdaptor::askManualScopeOpen(
bool light)
617 if (light && m_ManualLightOpeningAsked ==
true)
619 emit manualScopeCoverUpdated(
false,
true,
true);
622 else if (!light && m_ManualDarkOpeningAsked ==
true)
624 emit manualScopeCoverUpdated(
false,
true,
false);
631 m_ManualLightCoveringAsked =
false;
632 m_ManualLightOpeningAsked =
false;
633 m_ManualDarkCoveringAsked =
false;
634 m_ManualDarkOpeningAsked =
false;
637 m_ManualLightOpeningAsked =
true;
639 m_ManualDarkOpeningAsked =
true;
641 emit manualScopeCoverUpdated(
false,
true, light);
642 KSMessageBox::Instance()->disconnect(
this);
649 m_ManualLightOpeningAsked =
false;
651 m_ManualDarkOpeningAsked =
false;
652 emit manualScopeCoverUpdated(
false,
false, light);
653 KSMessageBox::Instance()->disconnect(
this);
656 KSMessageBox::Instance()->warningContinueCancel(
i18n(
"Remove cover from the telescope in order to continue."),
657 i18n(
"Telescope Covered"), Options::manualCoverTimeout());
661void CaptureDeviceAdaptor::setLightBoxLight(
bool on)
664 emit lightBoxLight(on);
667void CaptureDeviceAdaptor::parkDustCap(
bool park)
671 if (m_ActiveDustCap->
park())
672 emit dustCapStatusChanged(ISD::DustCap::CAP_PARKING);
674 emit dustCapStatusChanged(ISD::DustCap::CAP_ERROR);
676 else if (m_ActiveDustCap->
unpark())
677 emit dustCapStatusChanged(ISD::DustCap::CAP_UNPARKING);
679 emit dustCapStatusChanged(ISD::DustCap::CAP_ERROR);
682void CaptureDeviceAdaptor::slewTelescope(
SkyPoint &target)
684 if (m_ActiveMount !=
nullptr)
686 m_ActiveMount->Slew(&target);
687 emit scopeStatusChanged(ISD::Mount::MOUNT_SLEWING);
691void CaptureDeviceAdaptor::setScopeTracking(
bool on)
693 if (m_ActiveMount !=
nullptr)
695 m_ActiveMount->setTrackEnabled(on);
696 emit scopeStatusChanged(on ? ISD::Mount::MOUNT_TRACKING :
ISD::Mount::MOUNT_IDLE);
700void CaptureDeviceAdaptor::setScopeParked(
bool parked)
702 if (m_ActiveMount !=
nullptr)
706 if (m_ActiveMount->park())
707 emit scopeStatusChanged(ISD::Mount::MOUNT_PARKING);
709 emit scopeStatusChanged(ISD::Mount::MOUNT_ERROR);
713 if (m_ActiveMount->unpark() ==
false)
714 emit scopeStatusChanged(ISD::Mount::MOUNT_ERROR);
719void CaptureDeviceAdaptor::setDomeParked(
bool parked)
721 if (m_ActiveDome !=
nullptr)
725 if (m_ActiveDome->park())
726 emit domeStatusChanged(ISD::Dome::DOME_PARKING);
728 emit domeStatusChanged(ISD::Dome::DOME_ERROR);
732 if (m_ActiveDome->unpark() ==
false)
733 emit domeStatusChanged(ISD::Dome::DOME_ERROR);
739void CaptureDeviceAdaptor::flatSyncFocus(
int targetFilterID)
741 if (getFilterManager()->syncAbsoluteFocusPosition(targetFilterID - 1))
742 emit flatSyncFocusChanged(
true);
744 emit flatSyncFocusChanged(
false);
747void CaptureDeviceAdaptor::queryHasShutter()
749 if (m_ActiveCamera ==
nullptr)
751 emit hasShutter(
false);
756 QString deviceName = m_ActiveCamera->getDeviceName();
763 emit hasShutter(
true);
765 emit hasShutter(
false);
769 QString deviceName = m_ActiveCamera->getDeviceName();
773 KSMessageBox::Instance()->disconnect(
this);
777 emit hasShutter(
true);
782 KSMessageBox::Instance()->disconnect(
this);
786 emit hasShutter(
false);
789 KSMessageBox::Instance()->questionYesNo(
i18n(
"Does %1 have a shutter?", deviceName),
790 i18n(
"Dark Exposure"));
Camera class controls an INDI Camera device.
Class handles control of INDI dome devices.
Handles operation of a remotely controlled dust cover cap.
Q_SCRIPTABLE bool unpark()
UnPark Open dust cap.
Q_SCRIPTABLE bool park()
Park Close dust cap.
Q_SCRIPTABLE bool setLightEnabled(bool enable)
SetLightEnabled Turn on/off light.
device handle controlling Mounts.
void newStatus(ISD::Mount::Status status)
Change in the mount status.
Rotator class handles control of INDI Rotator devices.
The sky coordinates of a point in the sky.
QString i18n(const char *text, const TYPE &arg...)
Ekos is an advanced Astrophotography tool for Linux.
@ CAPTURE_SETTING_ROTATOR
@ CAPTURE_SETTING_TEMPERATURE
ISD is a collection of INDI Standard Devices.
QCA_EXPORT QVariant getProperty(const QString &name)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool disconnect(const QMetaObject::Connection &connection)
bool isNull() const const