11#include "clientmanager.h"
12#include "driverinfo.h"
13#include "deviceinfo.h"
14#include "imageviewer.h"
15#include "indi_debug.h"
17#include "kstarsdata.h"
21#include "indilistener.h"
23#include "indicamera.h"
24#include "indiguider.h"
25#include "indifocuser.h"
26#include "indifilterwheel.h"
29#include "indiweather.h"
30#include "indiadaptiveoptics.h"
31#include "indidustcap.h"
32#include "indilightbox.h"
33#include "indidetector.h"
34#include "indirotator.h"
35#include "indispectrograph.h"
36#include "indicorrelator.h"
37#include "indiauxiliary.h"
39#include "genericdeviceadaptor.h"
41#include <QImageReader>
47GDSetCommand::GDSetCommand(INDI_PROPERTY_TYPE inPropertyType,
const QString &inProperty,
const QString &inElement,
49 :
QObject(parent), propType(inPropertyType), indiProperty((inProperty)), indiElement(inElement), elementValue(qValue)
53uint8_t GenericDevice::m_ID = 1;
57 new GenericDeviceAdaptor(
this);
61 m_DriverInfo = idv.getDriverInfo();
62 m_BaseDevice = idv.getBaseDevice();
65 Q_ASSERT_X(m_BaseDevice, __FUNCTION__,
"Base device is invalid.");
66 Q_ASSERT_X(m_ClientManager, __FUNCTION__,
"Client manager is invalid.");
68 m_Name = m_BaseDevice.getDeviceName();
70 setObjectName(m_Name);
72 m_DriverInterface = m_BaseDevice.getDriverInterface();
73 m_DriverVersion = m_BaseDevice.getDriverVersion();
80 if (Options::useTimeUpdate() && Options::timeSource() ==
"KStars")
84 auto tvp = m_BaseDevice.getText(
"TIME_UTC");
85 if (tvp && tvp.getPermission() != IP_RO)
91 m_ReadyTimer =
new QTimer(
this);
92 m_ReadyTimer->setInterval(250);
93 m_ReadyTimer->setSingleShot(
true);
96 m_TimeUpdateTimer =
new QTimer(
this);
97 m_TimeUpdateTimer->setInterval(5000);
98 m_TimeUpdateTimer->setSingleShot(
true);
101 m_LocationUpdateTimer =
new QTimer(
this);
102 m_LocationUpdateTimer->setInterval(5000);
103 m_LocationUpdateTimer->setSingleShot(
true);
108GenericDevice::~GenericDevice()
110 for (
auto &metadata : streamFileMetadata)
111 metadata.file->close();
114void GenericDevice::handleTimeout()
127void GenericDevice::checkTimeUpdate()
132 auto timeTP = tvp.getText();
134 if (timeTP && timeTP->getPermission() != IP_RO && timeTP->getState() == IPS_IDLE)
140void GenericDevice::checkLocationUpdate()
145 auto locationNP = nvp.getNumber();
147 if (locationNP && locationNP->getPermission() != IP_RO && locationNP->getState() == IPS_IDLE)
152void GenericDevice::registerDBusType()
155 static bool isRegistered =
false;
157 if (isRegistered ==
false)
159 qRegisterMetaType<ISD::ParkStatus>(
"ISD::ParkStatus");
160 qDBusRegisterMetaType<ISD::ParkStatus>();
166const QString &GenericDevice::getDeviceName()
const
171void GenericDevice::registerProperty(INDI::Property prop)
173 if (!prop.getRegistered())
176 m_ReadyTimer->start();
181 if (name ==
"CONNECTION")
183 auto svp = prop.getSwitch();
186 if (!svp || svp->getState() == IPS_BUSY)
189 auto conSP = svp->findWidgetByName(
"CONNECT");
194 if (m_Connected ==
false && svp->getState() == IPS_OK && conSP->getState() == ISS_ON)
200 else if (m_Connected && conSP->getState() == ISS_OFF)
206 m_Ready = (svp->s == IPS_OK && conSP->s == ISS_ON);
208 else if (name ==
"DRIVER_INFO")
210 auto tvp = prop.getText();
213 auto tp = tvp->findWidgetByName(
"DRIVER_INTERFACE");
216 m_DriverInterface =
static_cast<uint32_t
>(atoi(tp->getText()));
217 emit interfaceDefined();
220 tp = tvp->findWidgetByName(
"DRIVER_VERSION");
223 m_DriverVersion =
QString(tp->getText());
227 else if (name ==
"SYSTEM_PORTS")
231 auto svp = prop.getSwitch();
232 auto port = m_BaseDevice.getText(
"DEVICE_PORT");
235 for (
const auto &it : *svp)
237 if (it.isNameMatch(port.at(0)->getText()))
239 emit systemPortDetected();
245 else if (name ==
"TIME_UTC" && Options::useTimeUpdate())
247 const auto &tvp = prop.getText();
251 if (Options::timeSource() ==
"KStars" && tvp->getPermission() != IP_RO)
254 m_TimeUpdateTimer->start();
257 else if (name ==
"GEOGRAPHIC_COORD" && Options::useGeographicUpdate())
259 if (Options::locationSource() ==
"KStars" && prop.getPermission() != IP_RO)
262 m_LocationUpdateTimer->start();
264 else if (name ==
"WATCHDOG_HEARTBEAT")
266 if (watchDogTimer ==
nullptr)
268 watchDogTimer =
new QTimer(
this);
269 connect(watchDogTimer, SIGNAL(timeout()),
this, SLOT(resetWatchdog()));
272 if (m_Connected && prop.getNumber()->at(0)->getValue() > 0)
275 m_ClientManager->sendNewProperty(prop);
279 emit propertyDefined(prop);
282void GenericDevice::updateProperty(INDI::Property prop)
284 switch (prop.getType())
306void GenericDevice::removeProperty(INDI::Property prop)
308 emit propertyDeleted(prop);
311void GenericDevice::processSwitch(INDI::Property prop)
313 if (prop.isNameMatch(
"CONNECTION"))
316 if (prop.getState() == IPS_BUSY)
319 auto connectionOn = prop.getSwitch()->findWidgetByName(
"CONNECT");
320 if (m_Connected ==
false && prop.getState() == IPS_OK && connectionOn->getState() == ISS_ON)
329 if (watchDogTimer !=
nullptr)
331 auto nvp = m_BaseDevice.getNumber(
"WATCHDOG_HEARTBEAT");
332 if (nvp && nvp.at(0)->getValue() > 0)
335 m_ClientManager->sendNewProperty(nvp);
339 m_ReadyTimer->start();
341 else if (m_Connected && connectionOn->getState() == ISS_OFF)
343 disconnect(m_ReadyTimer, &
QTimer::timeout,
this, &GenericDevice::handleTimeout);
349 m_Ready = (prop.getState() == IPS_OK && connectionOn->getState() == ISS_ON);
352 emit propertyUpdated(prop);
355void GenericDevice::processNumber(INDI::Property prop)
357 QString deviceName = getDeviceName();
358 auto nvp = prop.getNumber();
360 if (prop.isNameMatch(
"GEOGRAPHIC_COORD") && prop.getState() == IPS_OK && Options::locationSource() == deviceName)
366 auto np = nvp->findWidgetByName(
"LONG");
374 lng.
setD(np->value - 360.0);
376 np = nvp->findWidgetByName(
"LAT");
385 qCWarning(KSTARS_INDI) <<
"Ignoring invalid device coordinates.";
389 np = nvp->findWidgetByName(
"ELEV");
394 for (
auto &oneDevice : INDIListener::devices())
397 if (oneDevice->getDeviceName() == getDeviceName())
404 std::unique_ptr<GeoLocation> tempGeo;
407 if (getDriverInterface() & INDI::BaseDevice::GPS_INTERFACE)
408 newLocationName =
i18n(
"GPS Location");
410 newLocationName =
i18n(
"Mount Location");
412 if (
geo->name() != newLocationName)
414 double TZ0 =
geo->TZ0();
416 tempGeo.reset(
new GeoLocation(lng, lat, newLocationName,
"",
"", TZ0, rule, elev));
425 qCInfo(KSTARS_INDI) <<
"Setting location from device:" << deviceName <<
"Longitude:" << lng.
toDMSString() <<
"Latitude:" <<
430 else if (nvp->isNameMatch(
"WATCHDOG_HEARTBEAT"))
432 if (watchDogTimer ==
nullptr)
434 watchDogTimer =
new QTimer(
this);
438 auto value = nvp->at(0)->getValue();
439 if (m_Connected && value > 0)
443 double nextMS = qMax(100.0, (value - 5) * 1000);
444 watchDogTimer->start(nextMS);
447 watchDogTimer->stop();
450 emit propertyUpdated(prop);
453void GenericDevice::processText(INDI::Property prop)
455 auto tvp = prop.getText();
457 if (tvp->isNameMatch(
"DRIVER_INFO"))
459 auto tp = tvp->findWidgetByName(
"DRIVER_INTERFACE");
462 m_DriverInterface =
static_cast<uint32_t
>(atoi(tp->getText()));
463 emit interfaceDefined();
467 if (m_ConcreteDevices.isEmpty() ==
false)
470 if (generateDevices())
475 tp = tvp->findWidgetByName(
"DRIVER_VERSION");
478 m_DriverVersion =
QString(tp->text);
483 else if (tvp->isNameMatch(
"TIME_UTC") && tvp->s == IPS_OK && Options::timeSource() == getDeviceName())
485 int d, m, y, min, sec, hour;
490 auto tp = tvp->findWidgetByName(
"UTC");
494 qCWarning(KSTARS_INDI) <<
"UTC property missing from TIME_UTC";
498 sscanf(tp->getText(),
"%d%*[^0-9]%d%*[^0-9]%dT%d%*[^0-9]%d%*[^0-9]%d", &y, &m, &d, &hour, &min, &sec);
500 indiTime.
setHMS(hour, min, sec);
504 tp = tvp->findWidgetByName(
"OFFSET");
508 qCWarning(KSTARS_INDI) <<
"Offset property missing from TIME_UTC";
512 sscanf(tp->getText(),
"%f", &utcOffset);
515 for (
auto &oneDevice : INDIListener::devices())
518 if (oneDevice->getDeviceName() == getDeviceName())
521 oneDevice->updateTime(tvp->tp[0].text, tvp->tp[1].text);
524 qCInfo(KSTARS_INDI) <<
"Setting UTC time from device:" << getDeviceName() << indiDateTime.toString();
531 utcOffset -=
geo->tzrule()->deltaTZ();
535 geo->setTZ0(utcOffset);
538 emit propertyUpdated(prop);
541void GenericDevice::processLight(INDI::Property prop)
543 emit propertyUpdated(prop);
546void GenericDevice::processMessage(
int messageID)
548 emit messageUpdated(messageID);
551bool GenericDevice::processBLOB(INDI::Property prop)
554 if (prop.getPermission() == IP_WO)
557 auto bvp = prop.getBLOB();
558 auto bp = bvp->at(0);
561 for (
auto &oneConcreteDevice : m_ConcreteDevices)
563 if (!oneConcreteDevice.isNull() && oneConcreteDevice->processBLOB(prop))
567 INDIDataTypes dataType;
569 if (!strcmp(bp->getFormat(),
".ascii"))
570 dataType = DATA_ASCII;
572 dataType = DATA_OTHER;
574 QString currentDir = Options::fitsDir();
578 currentDir.
truncate(
sizeof(currentDir) - 1);
580 QString filename(currentDir +
'/');
587 if (dataType == DATA_ASCII)
591 auto it = std::find_if(streamFileMetadata.begin(), streamFileMetadata.end(), [bvp, bp](
const StreamFileMetadata & data)
593 return (bvp->getDeviceName() == data.device && bvp->getName() == data.property && bp->getName() == data.element);
596 QFile *streamDatafile =
nullptr;
599 if (it == streamFileMetadata.end())
601 StreamFileMetadata metadata;
602 metadata.device = bvp->getDeviceName();
603 metadata.property = bvp->getName();
604 metadata.element = bp->getName();
608 streamDatafile =
new QFile(
this);
609 metadata.file = streamDatafile;
611 streamFileMetadata.append(metadata);
614 streamDatafile = (*it).file;
619 for (nr = 0; nr < bp->getSize(); nr += n)
620 n = out.
writeRawData(
static_cast<char *
>(bp->getBlob()) + nr, bp->getSize() - nr);
623 streamDatafile->
flush();
628 QFile fits_temp_file(filename);
631 qCCritical(KSTARS_INDI) <<
"GenericDevice Error: Unable to open " << fits_temp_file.
fileName();
637 for (nr = 0; nr < bp->getSize(); nr += n)
638 n = out.
writeRawData(
static_cast<char *
>(bp->getBlob()) + nr, bp->getSize() - nr);
640 fits_temp_file.
flush();
641 fits_temp_file.
close();
654 if (dataType == DATA_OTHER)
657 emit propertyUpdated(prop);
661bool GenericDevice::setConfig(INDIConfig tConfig)
663 auto svp = m_BaseDevice.getSwitch(
"CONFIG_PROCESS");
668 const char *strConfig =
nullptr;
672 case LOAD_LAST_CONFIG:
673 strConfig =
"CONFIG_LOAD";
677 strConfig =
"CONFIG_SAVE";
680 case LOAD_DEFAULT_CONFIG:
681 strConfig =
"CONFIG_DEFAULT";
685 strConfig =
"CONFIG_PURGE";
692 auto sp = svp.findWidgetByName(strConfig);
695 sp->setState(ISS_ON);
698 m_ClientManager->sendNewProperty(svp);
703void GenericDevice::createDeviceInit()
705 if (Options::showINDIMessages())
714void GenericDevice::updateTime(
const QString &iso8601,
const QString &utcOffset)
717 auto timeUTC = m_BaseDevice.getText(
"TIME_UTC");
734 auto timeEle = timeUTC.findWidgetByName(
"UTC");
738 auto offsetEle = timeUTC.findWidgetByName(
"OFFSET");
742 if (timeEle && offsetEle)
744 qCInfo(KSTARS_INDI) <<
"Updating" << getDeviceName() <<
"Time UTC:" << isoTS <<
"Offset:" << offset;
745 m_ClientManager->sendNewProperty(timeUTC);
752void GenericDevice::updateLocation(
double longitude,
double latitude,
double elevation)
754 auto nvp = m_BaseDevice.getNumber(
"GEOGRAPHIC_COORD");
761 double longitude_degrees, latitude_degrees, elevation_meters;
763 if (longitude == -1 && latitude == -1 && elevation == -1)
765 longitude_degrees =
geo->lng()->Degrees();
766 latitude_degrees =
geo->lat()->Degrees();
767 elevation_meters =
geo->elevation();
771 longitude_degrees = longitude;
772 latitude_degrees = latitude;
773 elevation_meters = elevation;
776 if (longitude_degrees < 0)
777 longitude_degrees =
dms(longitude_degrees + 360.0).
Degrees();
779 auto np = nvp.findWidgetByName(
"LONG");
784 np->setValue(longitude_degrees);
786 np = nvp.findWidgetByName(
"LAT");
790 np->setValue(latitude_degrees);
792 np = nvp.findWidgetByName(
"ELEV");
796 np->setValue(elevation_meters);
798 qCInfo(KSTARS_INDI) <<
"Updating" << getDeviceName() <<
"Location Longitude:" << longitude_degrees <<
"Latitude:" <<
799 latitude_degrees <<
"Elevation:" << elevation_meters;
801 m_ClientManager->sendNewProperty(nvp);
804void GenericDevice::Connect()
806 m_ClientManager->connectDevice(m_Name.toLatin1().constData());
809void GenericDevice::Disconnect()
811 m_ClientManager->disconnectDevice(m_Name.toLatin1().constData());
814bool GenericDevice::setProperty(
QObject *setPropCommand)
816 GDSetCommand *indiCommand =
static_cast<GDSetCommand *
>(setPropCommand);
820 auto prop = m_BaseDevice.getProperty(indiCommand->indiProperty.toLatin1().constData());
825 switch (indiCommand->propType)
829 auto svp = prop.getSwitch();
834 auto sp = svp->findWidgetByName(indiCommand->indiElement.toLatin1().constData());
839 if (svp->getRule() == ISR_1OFMANY || svp->getRule() == ISR_ATMOST1)
842 sp->setState(indiCommand->elementValue.toInt() == 0 ? ISS_OFF : ISS_ON);
845 m_ClientManager->sendNewProperty(svp);
852 auto nvp = prop.getNumber();
857 auto np = nvp->findWidgetByName(indiCommand->indiElement.toLatin1().constData());
862 double value = indiCommand->elementValue.toDouble();
864 if (value == np->getValue())
870 m_ClientManager->sendNewProperty(nvp);
881bool GenericDevice::getMinMaxStep(
const QString &propName,
const QString &elementName,
double *min,
double *max,
884 auto nvp = m_BaseDevice.getNumber(propName.
toLatin1());
889 auto np = nvp.findWidgetByName(elementName.
toLatin1());
896 *step = np->getStep();
901IPState GenericDevice::getState(
const QString &propName)
906IPerm GenericDevice::getPermission(
const QString &propName)
911INDI::Property GenericDevice::getProperty(
const QString &propName)
916bool GenericDevice::setJSONProperty(
const QString &propName,
const QJsonArray &propElements)
918 for (
auto &oneProp : * (m_BaseDevice.getProperties()))
920 if (propName ==
QString(oneProp.getName()))
922 switch (oneProp.getType())
926 auto svp = oneProp.getSwitch();
927 if (svp->getRule() == ISR_1OFMANY || svp->getRule() == ISR_ATMOST1)
930 for (
auto oneElement : propElements)
932 QJsonObject oneElementObject = oneElement.toObject();
933 auto sp = svp->findWidgetByName(oneElementObject[
"name"].
toString().toLatin1().constData());
936 sp->setState(
static_cast<ISState
>(oneElementObject[
"state"].toInt()));
940 m_ClientManager->sendNewProperty(svp);
946 auto nvp = oneProp.getNumber();
947 for (
const auto &oneElement : propElements)
949 QJsonObject oneElementObject = oneElement.toObject();
950 auto np = nvp->findWidgetByName(oneElementObject[
"name"].
toString().toLatin1().constData());
953 double newValue = oneElementObject[
"value"].toDouble(std::numeric_limits<double>::quiet_NaN());
954 if (std::isnan(newValue))
956 f_scansexa(oneElementObject[
"value"].
toString().toLatin1().constData(), &newValue);
958 np->setValue(newValue);
962 m_ClientManager->sendNewProperty(nvp);
968 auto tvp = oneProp.getText();
969 for (
const auto &oneElement : propElements)
971 QJsonObject oneElementObject = oneElement.toObject();
972 auto tp = tvp->findWidgetByName(oneElementObject[
"name"].
toString().toLatin1().constData());
974 tp->setText(oneElementObject[
"text"].
toString().toLatin1().constData());
977 m_ClientManager->sendNewProperty(tvp);
994bool GenericDevice::getJSONProperty(
const QString &propName,
QJsonObject &propObject,
bool compact)
996 for (
auto oneProp : m_BaseDevice.getProperties())
998 if (propName == oneProp.getName())
1000 switch (oneProp.getType())
1003 switchToJson(oneProp, propObject, compact);
1007 numberToJson(oneProp, propObject, compact);
1011 textToJson(oneProp, propObject, compact);
1015 lightToJson(oneProp, propObject, compact);
1034 if (!blobProperty.isValid())
1037 auto oneBLOB = blobProperty.getBLOB()->findWidgetByName(elementName.
toLatin1().
constData());
1045 blobObject.
insert(
"property", propName);
1046 blobObject.
insert(
"element", elementName);
1048 blobObject.
insert(
"data", encoded);
1053void GenericDevice::resetWatchdog()
1055 auto nvp = m_BaseDevice.getNumber(
"WATCHDOG_HEARTBEAT");
1059 m_ClientManager->sendNewProperty(nvp);
1064 if (m_ConcreteDevices.contains(interface))
1066 device = m_ConcreteDevices[interface];
1074 if (m_ConcreteDevices.contains(INDI::BaseDevice::TELESCOPE_INTERFACE))
1075 return dynamic_cast<ISD::Mount*
>(m_ConcreteDevices[INDI::BaseDevice::TELESCOPE_INTERFACE].get());
1081 if (m_ConcreteDevices.contains(INDI::BaseDevice::CCD_INTERFACE))
1082 return dynamic_cast<ISD::Camera*
>(m_ConcreteDevices[INDI::BaseDevice::CCD_INTERFACE].get());
1086ISD::Guider *GenericDevice::getGuider()
1088 if (m_ConcreteDevices.contains(INDI::BaseDevice::GUIDER_INTERFACE))
1089 return dynamic_cast<ISD::Guider*
>(m_ConcreteDevices[INDI::BaseDevice::GUIDER_INTERFACE].get());
1095 if (m_ConcreteDevices.contains(INDI::BaseDevice::FOCUSER_INTERFACE))
1096 return dynamic_cast<ISD::Focuser*
>(m_ConcreteDevices[INDI::BaseDevice::FOCUSER_INTERFACE].get());
1100ISD::FilterWheel *GenericDevice::getFilterWheel()
1102 if (m_ConcreteDevices.contains(INDI::BaseDevice::FILTER_INTERFACE))
1103 return dynamic_cast<ISD::FilterWheel*
>(m_ConcreteDevices[INDI::BaseDevice::FILTER_INTERFACE].get());
1109 if (m_ConcreteDevices.contains(INDI::BaseDevice::DOME_INTERFACE))
1110 return dynamic_cast<ISD::Dome*
>(m_ConcreteDevices[INDI::BaseDevice::DOME_INTERFACE].get());
1114ISD::GPS *GenericDevice::getGPS()
1116 if (m_ConcreteDevices.contains(INDI::BaseDevice::GPS_INTERFACE))
1117 return dynamic_cast<ISD::GPS*
>(m_ConcreteDevices[INDI::BaseDevice::GPS_INTERFACE].get());
1123 if (m_ConcreteDevices.contains(INDI::BaseDevice::WEATHER_INTERFACE))
1124 return dynamic_cast<ISD::Weather*
>(m_ConcreteDevices[INDI::BaseDevice::WEATHER_INTERFACE].get());
1130 if (m_ConcreteDevices.contains(INDI::BaseDevice::AO_INTERFACE))
1131 return dynamic_cast<ISD::AdaptiveOptics*
>(m_ConcreteDevices[INDI::BaseDevice::AO_INTERFACE].get());
1137 if (m_ConcreteDevices.contains(INDI::BaseDevice::DUSTCAP_INTERFACE))
1138 return dynamic_cast<ISD::DustCap*
>(m_ConcreteDevices[INDI::BaseDevice::DUSTCAP_INTERFACE].get());
1144 if (m_ConcreteDevices.contains(INDI::BaseDevice::LIGHTBOX_INTERFACE))
1145 return dynamic_cast<ISD::LightBox*
>(m_ConcreteDevices[INDI::BaseDevice::LIGHTBOX_INTERFACE].get());
1151 if (m_ConcreteDevices.contains(INDI::BaseDevice::DETECTOR_INTERFACE))
1152 return dynamic_cast<ISD::Detector*
>(m_ConcreteDevices[INDI::BaseDevice::DETECTOR_INTERFACE].get());
1158 if (m_ConcreteDevices.contains(INDI::BaseDevice::ROTATOR_INTERFACE))
1159 return dynamic_cast<ISD::Rotator*
>(m_ConcreteDevices[INDI::BaseDevice::ROTATOR_INTERFACE].get());
1165 if (m_ConcreteDevices.contains(INDI::BaseDevice::SPECTROGRAPH_INTERFACE))
1166 return dynamic_cast<ISD::Spectrograph*
>(m_ConcreteDevices[INDI::BaseDevice::SPECTROGRAPH_INTERFACE].get());
1172 if (m_ConcreteDevices.contains(INDI::BaseDevice::CORRELATOR_INTERFACE))
1173 return dynamic_cast<ISD::Correlator*
>(m_ConcreteDevices[INDI::BaseDevice::CORRELATOR_INTERFACE].get());
1179 if (m_ConcreteDevices.contains(INDI::BaseDevice::AUX_INTERFACE))
1180 return dynamic_cast<ISD::Auxiliary*
>(m_ConcreteDevices[INDI::BaseDevice::AUX_INTERFACE].get());
1184bool GenericDevice::generateDevices()
1186 auto generated =
false;
1188 if (m_DriverInterface & INDI::BaseDevice::TELESCOPE_INTERFACE &&
1189 m_ConcreteDevices[INDI::BaseDevice::TELESCOPE_INTERFACE].isNull())
1194 m_ConcreteDevices[INDI::BaseDevice::TELESCOPE_INTERFACE].reset(mount);
1195 mount->registeProperties();
1198 mount->processProperties();
1199 emit newMount(mount);
1203 connect(mount, &ISD::ConcreteDevice::ready,
this, [
this, mount]()
1205 emit newMount(mount);
1211 if (m_DriverInterface & INDI::BaseDevice::CCD_INTERFACE &&
1212 m_ConcreteDevices[INDI::BaseDevice::CCD_INTERFACE].isNull())
1215 camera->setObjectName(
"Camera:" + objectName());
1217 m_ConcreteDevices[INDI::BaseDevice::CCD_INTERFACE].reset(camera);
1218 camera->registeProperties();
1221 camera->processProperties();
1222 emit newCamera(camera);
1227 connect(camera, &ISD::ConcreteDevice::ready,
this, [
this, camera]()
1229 emit newCamera(camera);
1235 if (m_DriverInterface & INDI::BaseDevice::GUIDER_INTERFACE &&
1236 m_ConcreteDevices[INDI::BaseDevice::GUIDER_INTERFACE].isNull())
1238 auto guider =
new ISD::Guider(
this);
1239 guider->setObjectName(
"Guider:" + objectName());
1241 m_ConcreteDevices[INDI::BaseDevice::GUIDER_INTERFACE].reset(guider);
1242 guider->registeProperties();
1245 guider->processProperties();
1246 emit newGuider(guider);
1250 connect(guider, &ISD::ConcreteDevice::ready,
this, [
this, guider]()
1252 emit newGuider(guider);
1258 if (m_DriverInterface & INDI::BaseDevice::FOCUSER_INTERFACE &&
1259 m_ConcreteDevices[INDI::BaseDevice::FOCUSER_INTERFACE].isNull())
1262 focuser->setObjectName(
"Focuser:" + objectName());
1264 m_ConcreteDevices[INDI::BaseDevice::FOCUSER_INTERFACE].reset(focuser);
1265 focuser->registeProperties();
1268 focuser->processProperties();
1269 emit newFocuser(focuser);
1273 connect(focuser, &ISD::ConcreteDevice::ready,
this, [
this, focuser]()
1275 emit newFocuser(focuser);
1281 if (m_DriverInterface & INDI::BaseDevice::FILTER_INTERFACE &&
1282 m_ConcreteDevices[INDI::BaseDevice::FILTER_INTERFACE].isNull())
1284 auto filterWheel =
new ISD::FilterWheel(
this);
1285 filterWheel->setObjectName(
"FilterWheel:" + objectName());
1287 m_ConcreteDevices[INDI::BaseDevice::FILTER_INTERFACE].reset(filterWheel);
1288 filterWheel->registeProperties();
1291 filterWheel->processProperties();
1292 emit newFilterWheel(filterWheel);
1296 connect(filterWheel, &ISD::ConcreteDevice::ready,
this, [
this, filterWheel]()
1298 emit newFilterWheel(filterWheel);
1304 if (m_DriverInterface & INDI::BaseDevice::DOME_INTERFACE &&
1305 m_ConcreteDevices[INDI::BaseDevice::DOME_INTERFACE].isNull())
1308 dome->setObjectName(
"Dome:" + objectName());
1310 m_ConcreteDevices[INDI::BaseDevice::DOME_INTERFACE].reset(dome);
1311 dome->registeProperties();
1314 dome->processProperties();
1319 connect(dome, &ISD::ConcreteDevice::ready,
this, [
this, dome]()
1327 if (m_DriverInterface & INDI::BaseDevice::GPS_INTERFACE &&
1328 m_ConcreteDevices[INDI::BaseDevice::GPS_INTERFACE].isNull())
1330 auto gps =
new ISD::GPS(
this);
1331 gps->setObjectName(
"GPS:" + objectName());
1333 m_ConcreteDevices[INDI::BaseDevice::GPS_INTERFACE].reset(gps);
1334 gps->registeProperties();
1337 gps->processProperties();
1342 connect(gps, &ISD::ConcreteDevice::ready,
this, [
this, gps]()
1350 if (m_DriverInterface & INDI::BaseDevice::WEATHER_INTERFACE &&
1351 m_ConcreteDevices[INDI::BaseDevice::WEATHER_INTERFACE].isNull())
1354 weather->setObjectName(
"Weather:" + objectName());
1356 m_ConcreteDevices[INDI::BaseDevice::WEATHER_INTERFACE].reset(weather);
1357 weather->registeProperties();
1360 weather->processProperties();
1361 emit newWeather(weather);
1365 connect(weather, &ISD::ConcreteDevice::ready,
this, [
this, weather]()
1367 emit newWeather(weather);
1373 if (m_DriverInterface & INDI::BaseDevice::AO_INTERFACE &&
1374 m_ConcreteDevices[INDI::BaseDevice::AO_INTERFACE].isNull())
1377 ao->setObjectName(
"AdaptiveOptics:" + objectName());
1379 m_ConcreteDevices[INDI::BaseDevice::AO_INTERFACE].reset(ao);
1380 ao->registeProperties();
1383 ao->processProperties();
1384 emit newAdaptiveOptics(ao);
1388 connect(ao, &ISD::ConcreteDevice::ready,
this, [
this, ao]()
1390 emit newAdaptiveOptics(ao);
1396 if (m_DriverInterface & INDI::BaseDevice::DUSTCAP_INTERFACE &&
1397 m_ConcreteDevices[INDI::BaseDevice::DUSTCAP_INTERFACE].isNull())
1400 dustCap->setObjectName(
"DustCap:" + objectName());
1402 m_ConcreteDevices[INDI::BaseDevice::DUSTCAP_INTERFACE].reset(dustCap);
1403 dustCap->registeProperties();
1406 dustCap->processProperties();
1407 emit newDustCap(dustCap);
1411 connect(dustCap, &ISD::ConcreteDevice::ready,
this, [
this, dustCap]()
1413 emit newDustCap(dustCap);
1419 if (m_DriverInterface & INDI::BaseDevice::LIGHTBOX_INTERFACE &&
1420 m_ConcreteDevices[INDI::BaseDevice::LIGHTBOX_INTERFACE].isNull())
1423 lightBox->setObjectName(
"LightBox:" + objectName());
1425 m_ConcreteDevices[INDI::BaseDevice::LIGHTBOX_INTERFACE].reset(lightBox);
1426 lightBox->registeProperties();
1429 lightBox->processProperties();
1430 emit newLightBox(lightBox);
1434 connect(lightBox, &ISD::ConcreteDevice::ready,
this, [
this, lightBox]()
1436 emit newLightBox(lightBox);
1442 if (m_DriverInterface & INDI::BaseDevice::ROTATOR_INTERFACE &&
1443 m_ConcreteDevices[INDI::BaseDevice::ROTATOR_INTERFACE].isNull())
1446 rotator->setObjectName(
"Rotator:" + objectName());
1448 m_ConcreteDevices[INDI::BaseDevice::ROTATOR_INTERFACE].reset(rotator);
1449 rotator->registeProperties();
1452 rotator->processProperties();
1453 emit newRotator(rotator);
1457 connect(rotator, &ISD::ConcreteDevice::ready,
this, [
this, rotator]()
1459 emit newRotator(rotator);
1465 if (m_DriverInterface & INDI::BaseDevice::DETECTOR_INTERFACE &&
1466 m_ConcreteDevices[INDI::BaseDevice::DETECTOR_INTERFACE].isNull())
1469 detector->setObjectName(
"Detector:" + objectName());
1471 m_ConcreteDevices[INDI::BaseDevice::DETECTOR_INTERFACE].reset(detector);
1472 detector->registeProperties();
1475 detector->processProperties();
1476 emit newDetector(detector);
1480 connect(detector, &ISD::ConcreteDevice::ready,
this, [
this, detector]()
1482 emit newDetector(detector);
1488 if (m_DriverInterface & INDI::BaseDevice::SPECTROGRAPH_INTERFACE &&
1489 m_ConcreteDevices[INDI::BaseDevice::SPECTROGRAPH_INTERFACE].isNull())
1492 spectrograph->setObjectName(
"Spectrograph:" + objectName());
1494 m_ConcreteDevices[INDI::BaseDevice::SPECTROGRAPH_INTERFACE].reset(spectrograph);
1495 spectrograph->registeProperties();
1498 spectrograph->processProperties();
1499 emit newSpectrograph(spectrograph);
1503 connect(spectrograph, &ISD::ConcreteDevice::ready,
this, [
this, spectrograph]()
1505 emit newSpectrograph(spectrograph);
1511 if (m_DriverInterface & INDI::BaseDevice::CORRELATOR_INTERFACE &&
1512 m_ConcreteDevices[INDI::BaseDevice::CORRELATOR_INTERFACE].isNull())
1515 correlator->setObjectName(
"Correlator:" + objectName());
1517 m_ConcreteDevices[INDI::BaseDevice::CORRELATOR_INTERFACE].reset(correlator);
1518 correlator->registeProperties();
1521 correlator->processProperties();
1522 emit newCorrelator(correlator);
1526 connect(correlator, &ISD::ConcreteDevice::ready,
this, [
this, correlator]()
1528 emit newCorrelator(correlator);
1534 if (m_DriverInterface & INDI::BaseDevice::AUX_INTERFACE &&
1535 m_ConcreteDevices[INDI::BaseDevice::AUX_INTERFACE].isNull())
1538 aux->setObjectName(
"Auxiliary:" + objectName());
1540 m_ConcreteDevices[INDI::BaseDevice::AUX_INTERFACE].reset(aux);
1541 aux->registeProperties();
1544 aux->processProperties();
1545 emit newAuxiliary(aux);
1549 connect(aux, &ISD::ConcreteDevice::ready,
this, [
this, aux]()
1551 emit newAuxiliary(aux);
1559void GenericDevice::sendNewProperty(INDI::Property prop)
1564void switchToJson(INDI::Property prop,
QJsonObject &propObject,
bool compact)
1566 auto svp = prop.getSwitch();
1568 for (
int i = 0; i < svp->count(); i++)
1570 QJsonObject oneSwitch = {{
"name", svp->at(i)->getName()}, {
"state", svp->at(i)->getState()}};
1572 oneSwitch.
insert(
"label", svp->at(i)->getLabel());
1573 switches.
append(oneSwitch);
1576 propObject = {{
"device", svp->getDeviceName()}, {
"name", svp->getName()}, {
"state", svp->getState()}, {
"switches", switches}};
1579 propObject.
insert(
"label", svp->getLabel());
1580 propObject.
insert(
"group", svp->getGroupName());
1581 propObject.
insert(
"perm", svp->getPermission());
1582 propObject.
insert(
"rule", svp->getRule());
1586void numberToJson(INDI::Property prop,
QJsonObject &propObject,
bool compact)
1588 auto nvp = prop.getNumber();
1590 for (
int i = 0; i < nvp->count(); i++)
1592 QJsonObject oneNumber = {{
"name", nvp->at(i)->getName()}, {
"value", nvp->at(i)->getValue()}};
1595 oneNumber.
insert(
"label", nvp->at(i)->getLabel());
1596 oneNumber.
insert(
"min", nvp->at(i)->getMin());
1597 oneNumber.
insert(
"max", nvp->at(i)->getMax());
1598 oneNumber.
insert(
"step", nvp->at(i)->getStep());
1599 oneNumber.
insert(
"format", nvp->at(i)->getFormat());
1601 numbers.
append(oneNumber);
1604 propObject = {{
"device", nvp->getDeviceName()}, {
"name", nvp->getName()}, {
"state", nvp->getState()}, {
"numbers", numbers}};
1607 propObject.
insert(
"label", nvp->getLabel());
1608 propObject.
insert(
"group", nvp->getGroupName());
1609 propObject.
insert(
"perm", nvp->getPermission());
1613void textToJson(INDI::Property prop,
QJsonObject &propObject,
bool compact)
1615 auto tvp = prop.getText();
1617 for (
int i = 0; i < tvp->count(); i++)
1619 QJsonObject oneText = {{
"name", tvp->at(i)->getName()}, {
"text", tvp->at(i)->getText()}};
1622 oneText.
insert(
"label", tvp->at(i)->getLabel());
1627 propObject = {{
"device", tvp->getDeviceName()}, {
"name", tvp->getName()}, {
"state", tvp->getState()}, {
"texts", Texts}};
1630 propObject.
insert(
"label", tvp->getLabel());
1631 propObject.
insert(
"group", tvp->getGroupName());
1632 propObject.
insert(
"perm", tvp->getPermission());
1636void lightToJson(INDI::Property prop,
QJsonObject &propObject,
bool compact)
1638 auto lvp = prop.getLight();
1640 for (
int i = 0; i < lvp->count(); i++)
1642 QJsonObject oneLight = {{
"name", lvp->at(i)->getName()}, {
"state", lvp->at(i)->getState()}};
1645 oneLight.
insert(
"label", lvp->at(i)->getLabel());
1650 propObject = {{
"device", lvp->getDeviceName()}, {
"name", lvp->getName()}, {
"state", lvp->getState()}, {
"lights", Lights}};
1653 propObject.
insert(
"label", lvp->getLabel());
1654 propObject.
insert(
"group", lvp->getGroupName());
1658void propertyToJson(INDI::Property prop,
QJsonObject &propObject,
bool compact)
1660 switch (prop.getType())
1663 switchToJson(prop, propObject, compact);
1666 textToJson(prop, propObject, compact);
1669 numberToJson(prop, propObject, compact);
1672 lightToJson(prop, propObject, compact);
1684 argument << static_cast<int>(source);
1695 dest =
static_cast<ISD::ParkStatus
>(a);
ClientManager manages connection to INDI server, creation of devices, and receiving/sending propertie...
DeviceInfo is simple class to hold DriverInfo and INDI::BaseDevice associated with a particular devic...
Contains all relevant information for specifying a location on Earth: City Name, State/Province name,...
AdaptiveOptics class handles control of INDI AdaptiveOptics devices.
Auxiliary class handles control of INDI Auxiliary devices.
Camera class controls an INDI Camera device.
void sendNewProperty(INDI::Property prop)
Send new property command to server.
Correlator class handles control of INDI Correlator devices.
Detector class handles control of INDI Detector devices.
Class handles control of INDI dome devices.
Handles operation of a remotely controlled dust cover cap.
Focuser class handles control of INDI focuser devices.
Handles operation of a remotely controlled light box.
device handle controlling Mounts.
Rotator class handles control of INDI Rotator devices.
Spectrograph class handles control of INDI Spectrograph devices.
Focuser class handles control of INDI Weather devices.
void setLocation(const GeoLocation &l)
Set the GeoLocation according to the argument.
void changeDateTime(const KStarsDateTime &newDate)
Change the current simulation date/time to the KStarsDateTime argument.
void syncLST()
Sync the LST with the simulation clock.
const KStarsDateTime & ut() const
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
static KStars * Instance()
KStarsData * data() const
void timeChanged()
The time has changed (emitted by setUTC() )
void forceUpdateNow()
Convenience function; simply calls forceUpdate(true).
This class provides the information needed to determine whether Daylight Savings Time (DST; a....
An angle, stored as degrees, but expressible in many ways.
const QString toDMSString(const bool forceSign=false, const bool machineReadable=false, const bool highPrecision=false) const
virtual void setD(const double &x)
Sets floating-point value of angle, in degrees.
const double & Degrees() const
QString i18n(const char *text, const TYPE &arg...)
char * toString(const EngineQuery &query)
ISD is a collection of INDI Standard Devices.
KCALENDARCORE_EXPORT QDataStream & operator>>(QDataStream &in, const KCalendarCore::Alarm::Ptr &)
GeoCoordinates geo(const QVariant &location)
QString name(StandardAction id)
KTEXTEDITOR_EXPORT QDebug operator<<(QDebug s, const MovingCursor &cursor)
QCA_EXPORT QVariant getProperty(const QString &name)
const char * constData() const const
QByteArray fromRawData(const char *data, qsizetype size)
QByteArray toBase64(Base64Options options) const const
int writeRawData(const char *s, int len)
bool setDate(int year, int month, int day)
QDateTime currentDateTime()
QString toString(QStringView format, QCalendar cal) const const
bool registerObject(const QString &path, QObject *object, RegisterOptions options)
QDBusConnection sessionBus()
virtual QString fileName() const const override
bool open(FILE *fh, OpenMode mode, FileHandleFlags handleFlags)
virtual void close() override
void append(const QJsonValue &value)
iterator insert(QLatin1StringView key, const QJsonValue &value)
QStatusBar * statusBar() const const
void setObjectName(QAnyStringView name)
void showMessage(const QString &message, int timeout)
QString arg(Args &&... args) const const
bool endsWith(QChar c, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
QString & remove(QChar ch, Qt::CaseSensitivity cs)
QString & setNum(double n, char format, int precision)
qsizetype size() const const
QByteArray toLatin1() const const
QString toLower() const const
QByteArray toUtf8() const const
QString trimmed() const const
void truncate(qsizetype position)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
bool setHMS(int h, int m, int s, int ms)
void setScheme(const QString &scheme)