File indexing completed on 2024-03-24 03:46:56
0001 /* 0002 SPDX-FileCopyrightText: 2012 Jasem Mutlaq <mutlaqja@ikarustech.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 0006 Handle INDI Standard properties. 0007 */ 0008 0009 #pragma once 0010 0011 #include "indicommon.h" 0012 0013 #include <indiproperty.h> 0014 #include <basedevice.h> 0015 0016 #include <QObject> 0017 #include <QVariant> 0018 #include <QJsonArray> 0019 0020 #ifndef KSTARS_LITE 0021 #include <QDBusArgument> 0022 #endif 0023 0024 #define MAXINDIFILENAME 512 0025 0026 class ClientManager; 0027 class DriverInfo; 0028 class DeviceInfo; 0029 class QTimer; 0030 class QFile; 0031 0032 using Properties = INDI::BaseDevice::Properties; 0033 0034 // INDI Standard Device Namespace 0035 namespace ISD 0036 { 0037 0038 typedef enum { PARK_UNKNOWN, PARK_PARKED, PARK_PARKING, PARK_UNPARKING, PARK_UNPARKED, PARK_ERROR } ParkStatus; 0039 0040 // Create instances as per driver interface. 0041 class ConcreteDevice; 0042 class Mount; 0043 class Camera; 0044 class Guider; 0045 class Focuser; 0046 class FilterWheel; 0047 class Dome; 0048 class GPS; 0049 class Weather; 0050 class AdaptiveOptics; 0051 class DustCap; 0052 class LightBox; 0053 class Detector; 0054 class Rotator; 0055 class Spectrograph; 0056 class Correlator; 0057 class Auxiliary; 0058 0059 class GDSetCommand : public QObject 0060 { 0061 Q_OBJECT 0062 0063 public: 0064 GDSetCommand(INDI_PROPERTY_TYPE inPropertyType, const QString &inProperty, const QString &inElement, 0065 QVariant qValue, QObject *parent); 0066 INDI_PROPERTY_TYPE propType; 0067 0068 QString indiProperty; 0069 QString indiElement; 0070 QVariant elementValue; 0071 }; 0072 0073 /** 0074 * @class GDInterface 0075 * GDInterface is the Generic Device <i>Interface</i> for INDI devices. It is used as part of the Decorator Pattern when initially a new INDI device is created as a 0076 * Generic Device in INDIListener. If the device registers an INDI Standard Property belonging to one specific device type (e.g. Telescope), then the device functionality 0077 * is extended to the particular device type. 0078 * 0079 * DeviceDecorator subclasses GDInterface and calls concrete decorators methods. 0080 * 0081 * @author Jasem Mutlaq 0082 */ 0083 class GDInterface : public QObject 0084 { 0085 Q_OBJECT 0086 0087 public: 0088 explicit GDInterface(QObject *parent) : QObject(parent) {} 0089 0090 // Property registration 0091 virtual void registerProperty(INDI::Property prop) = 0; 0092 virtual void removeProperty(INDI::Property prop) = 0; 0093 virtual void updateProperty(INDI::Property prop) = 0; 0094 0095 // Property updates 0096 virtual void processSwitch(INDI::Property prop) = 0; 0097 virtual void processText(INDI::Property prop) = 0; 0098 virtual void processNumber(INDI::Property prop) = 0; 0099 virtual void processLight(INDI::Property prop) = 0; 0100 virtual bool processBLOB(INDI::Property prop) = 0; 0101 0102 // Messages 0103 virtual void processMessage(int messageID) = 0; 0104 }; 0105 0106 /** 0107 * @class GenericDevice 0108 * GenericDevice is the Generic Device for INDI devices. When a new INDI device is created in INDIListener, it gets created as a GenericDevice initially. If the device 0109 * registers a standard property that is a key property to a device type family (e.g. Number property EQUATORIAL_EOD_COORD signifies a Telescope device), then the specialized version of 0110 * the device is extended via the Decorator Pattern. 0111 * 0112 * GenericDevice handles common functions shared across many devices such as time and location handling, configuration processing, retrieving information about properties, driver info..etc. 0113 * 0114 * @author Jasem Mutlaq 0115 */ 0116 class GenericDevice : public GDInterface 0117 { 0118 Q_OBJECT 0119 Q_CLASSINFO("D-Bus Interface", "org.kde.kstars.INDI.GenericDevice") 0120 Q_PROPERTY(QString name READ getDeviceName) 0121 Q_PROPERTY(uint32_t driverInterface READ getDriverInterface) 0122 Q_PROPERTY(QString driverVersion READ getDriverVersion) 0123 Q_PROPERTY(bool connected READ isConnected) 0124 0125 public: 0126 explicit GenericDevice(DeviceInfo &idv, ClientManager *cm, QObject *parent = nullptr); 0127 virtual ~GenericDevice() override; 0128 0129 virtual void registerProperty(INDI::Property prop) override; 0130 virtual void removeProperty(INDI::Property prop) override; 0131 virtual void updateProperty(INDI::Property prop) override; 0132 0133 virtual void processSwitch(INDI::Property prop) override; 0134 virtual void processText(INDI::Property prop) override; 0135 virtual void processNumber(INDI::Property prop) override; 0136 virtual void processLight(INDI::Property prop) override; 0137 0138 /** 0139 * @brief processBLOB Process Binary BLOB 0140 * @param bp pointer to binary blob. 0141 * @return Return true of BLOB was successfully processed. If a concrete device does not process the blob, it should 0142 * return false to allow sibling or parent devices to process the blob. 0143 */ 0144 virtual bool processBLOB(INDI::Property prop) override; 0145 virtual void processMessage(int messageID) override; 0146 0147 virtual const QString &getDeviceName() const; 0148 virtual const QSharedPointer<DriverInfo> &getDriverInfo() const 0149 { 0150 return m_DriverInfo; 0151 } 0152 virtual DeviceInfo *getDeviceInfo() const 0153 { 0154 return m_DeviceInfo; 0155 } 0156 virtual Properties getProperties() 0157 { 0158 return m_BaseDevice.getProperties(); 0159 } 0160 virtual uint32_t getDriverInterface() 0161 { 0162 return m_DriverInterface; 0163 } 0164 virtual QString getDriverVersion() 0165 { 0166 return m_DriverVersion; 0167 } 0168 0169 virtual bool setConfig(INDIConfig tConfig); 0170 virtual bool isConnected() const 0171 { 0172 return m_Connected; 0173 } 0174 virtual bool isReady() const 0175 { 0176 return m_Ready; 0177 } 0178 virtual INDI::BaseDevice getBaseDevice() const 0179 { 0180 return m_BaseDevice; 0181 } 0182 ClientManager *getClientManager() const 0183 { 0184 return m_ClientManager; 0185 } 0186 virtual bool getMinMaxStep(const QString &propName, const QString &elementName, double *min, double *max, 0187 double *step); 0188 virtual IPState getState(const QString &propName); 0189 virtual IPerm getPermission(const QString &propName); 0190 virtual INDI::Property getProperty(const QString &propName); 0191 virtual bool getJSONProperty(const QString &propName, QJsonObject &propObject, bool compact); 0192 virtual bool getJSONBLOB(const QString &propName, const QString &elementName, QJsonObject &blobObject); 0193 virtual bool setJSONProperty(const QString &propName, const QJsonArray &propElements); 0194 0195 bool findConcreteDevice(uint32_t interface, QSharedPointer<ConcreteDevice> &device); 0196 0197 void sendNewProperty(INDI::Property prop); 0198 /** @brief Send new Text command to server */ 0199 void sendNewText(INDI::Property prop); 0200 /** @brief Send new Number command to server */ 0201 void sendNewNumber(INDI::Property prop); 0202 /** @brief Send new Switch command to server */ 0203 void sendNewSwitch(INDI::Property prop); 0204 0205 // Convinence functions 0206 ISD::Mount *getMount(); 0207 ISD::Camera *getCamera(); 0208 ISD::Guider *getGuider(); 0209 ISD::Focuser *getFocuser(); 0210 ISD::FilterWheel *getFilterWheel(); 0211 ISD::Dome *getDome(); 0212 ISD::GPS *getGPS(); 0213 ISD::Weather *getWeather(); 0214 ISD::AdaptiveOptics *getAdaptiveOptics(); 0215 ISD::DustCap *getDustCap(); 0216 ISD::LightBox *getLightBox(); 0217 ISD::Detector *getDetector(); 0218 ISD::Rotator *getRotator(); 0219 ISD::Spectrograph *getSpectrograph(); 0220 ISD::Correlator *getCorrelator(); 0221 ISD::Auxiliary *getAuxiliary(); 0222 0223 Q_SCRIPTABLE Q_NOREPLY void Connect(); 0224 Q_SCRIPTABLE Q_NOREPLY void Disconnect(); 0225 bool setProperty(QObject *); 0226 0227 protected slots: 0228 virtual void resetWatchdog(); 0229 0230 protected: 0231 void createDeviceInit(); 0232 void updateTime(); 0233 void updateLocation(); 0234 /** 0235 * @brief generateDevices Generate concrete devices based on DRIVER_INTERFACE 0236 * @return True if at least one device is generated, false otherwise. 0237 */ 0238 bool generateDevices(); 0239 void handleTimeout(); 0240 void checkTimeUpdate(); 0241 void checkLocationUpdate(); 0242 0243 protected: 0244 uint32_t m_DriverInterface { 0 }; 0245 QString m_DriverVersion; 0246 QMap<uint32_t, QSharedPointer<ConcreteDevice>> m_ConcreteDevices; 0247 0248 signals: 0249 void Connected(); 0250 void Disconnected(); 0251 0252 void propertyUpdated(INDI::Property prop); 0253 void messageUpdated(int messageID); 0254 0255 void interfaceDefined(); 0256 void systemPortDetected(); 0257 void propertyDefined(INDI::Property prop); 0258 void propertyDeleted(INDI::Property prop); 0259 void ready(); 0260 0261 // These are emitted as soon as the driver interface defines them 0262 void newMount(Mount *device); 0263 void newCamera(Camera *device); 0264 void newGuider(Guider *device); 0265 void newFocuser(Focuser *device); 0266 void newFilterWheel(FilterWheel *device); 0267 void newDome(Dome *device); 0268 void newGPS(GPS *device); 0269 void newWeather(Weather *device); 0270 void newAdaptiveOptics(AdaptiveOptics *device); 0271 void newDustCap(DustCap *device); 0272 void newLightBox(LightBox *device); 0273 void newDetector(Detector *device); 0274 void newRotator(Rotator *device); 0275 void newSpectrograph(Spectrograph *device); 0276 void newCorrelator(Correlator *device); 0277 void newAuxiliary(Auxiliary *device); 0278 0279 private: 0280 0281 class StreamFileMetadata 0282 { 0283 public: 0284 QString device; 0285 QString property; 0286 QString element; 0287 QFile *file { nullptr}; 0288 }; 0289 0290 static void registerDBusType(); 0291 bool m_Connected { false }; 0292 bool m_Ready {false}; 0293 QString m_Name; 0294 QSharedPointer<DriverInfo> m_DriverInfo; 0295 DeviceInfo *m_DeviceInfo { nullptr }; 0296 INDI::BaseDevice m_BaseDevice; 0297 ClientManager *m_ClientManager { nullptr }; 0298 QTimer *watchDogTimer { nullptr }; 0299 QTimer *m_ReadyTimer {nullptr}; 0300 QTimer *m_TimeUpdateTimer {nullptr}; 0301 QTimer *m_LocationUpdateTimer {nullptr}; 0302 QList<StreamFileMetadata> streamFileMetadata; 0303 0304 static uint8_t getID() 0305 { 0306 return m_ID++; 0307 } 0308 static uint8_t m_ID; 0309 }; 0310 0311 void switchToJson(INDI::Property prop, QJsonObject &propObject, bool compact = true); 0312 void textToJson(INDI::Property prop, QJsonObject &propObject, bool compact = true); 0313 void numberToJson(INDI::Property prop, QJsonObject &propObject, bool compact = true); 0314 void lightToJson(INDI::Property prop, QJsonObject &propObject, bool compact = true); 0315 void propertyToJson(INDI::Property prop, QJsonObject &propObject, bool compact = true); 0316 0317 } 0318 0319 0320 #ifndef KSTARS_LITE 0321 Q_DECLARE_METATYPE(ISD::ParkStatus) 0322 QDBusArgument &operator<<(QDBusArgument &argument, const ISD::ParkStatus &source); 0323 const QDBusArgument &operator>>(const QDBusArgument &argument, ISD::ParkStatus &dest); 0324 #endif