File indexing completed on 2024-07-07 07:08:24

0001 /*
0002     SPDX-FileCopyrightText: 2016 Artem Fedoskin <afedoskin3@gmail.com>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #pragma once
0007 
0008 #include "baseclientqt.h"
0009 #include "indicommon.h"
0010 #include "indistd.h"
0011 
0012 #include <QImage>
0013 #include <QNetworkAccessManager>
0014 #include <QNetworkReply>
0015 
0016 #include <memory>
0017 
0018 class QFileDialog;
0019 class QQmlContext;
0020 
0021 using namespace INDI;
0022 class TelescopeLite;
0023 
0024 struct DeviceInfoLite
0025 {
0026     explicit DeviceInfoLite(INDI::BaseDevice *dev);
0027     ~DeviceInfoLite();
0028 
0029     INDI::BaseDevice *device { nullptr };
0030     /// Motion control
0031     std::unique_ptr<TelescopeLite> telescope;
0032 };
0033 
0034 /**
0035  * @class ClientManagerLite
0036  *
0037  * @author Artem Fedoskin
0038  * @version 1.0
0039  */
0040 class ClientManagerLite : public INDI::BaseClientQt
0041 {
0042         Q_OBJECT
0043         Q_PROPERTY(QString connectedHost READ connectedHost WRITE setConnectedHost NOTIFY connectedHostChanged)
0044         Q_PROPERTY(bool connected READ isConnected WRITE setConnected NOTIFY connectedChanged)
0045 
0046         /**
0047          * A wrapper for Options::lastServer(). Used to store last used server if user successfully
0048          * connected to some server at least once.
0049          **/
0050         Q_PROPERTY(QString lastUsedServer READ getLastUsedServer WRITE setLastUsedServer NOTIFY lastUsedServerChanged)
0051 
0052         /**
0053          * A wrapper for Options::lastServer(). Used to store last used port if user successfully
0054          * connected to some server at least once.
0055          **/
0056         Q_PROPERTY(int lastUsedPort READ getLastUsedPort WRITE setLastUsedPort NOTIFY lastUsedPortChanged)
0057 
0058         /**
0059          * A wrapper for Options::lastServer(). Used to store last Web Manager used port if user successfully
0060          * connected at least once.
0061          **/
0062         Q_PROPERTY(int lastUsedWebManagerPort READ getLastUsedWebManagerPort WRITE setLastUsedWebManagerPort
0063                    NOTIFY lastUsedWebManagerPortChanged)
0064     public:
0065         typedef enum { UPLOAD_CLIENT, UPLOAD_LOCAL, UPLOAD_BOTH } UploadMode;
0066 
0067         explicit ClientManagerLite(QQmlContext &main_context);
0068         virtual ~ClientManagerLite();
0069 
0070         Q_INVOKABLE bool setHost(const QString &ip, unsigned int port);
0071         Q_INVOKABLE void disconnectHost();
0072 
0073         /**
0074          * Get the profiles from Web Manager
0075          *
0076          * @param ip IP address
0077          * @param port Port number
0078          *
0079          * The process is async and the results are stored in @a webMProfiles. Once this
0080          * request finishes, the server status is queried from the server.
0081          */
0082         Q_INVOKABLE void getWebManagerProfiles(const QString &ip, unsigned int port);
0083 
0084         /**
0085          * Start an INDI server with a Web Manager profile
0086          *
0087          * @param profile Profile name
0088          */
0089         Q_INVOKABLE void startWebManagerProfile(const QString &profile);
0090 
0091         /** Stop the INDI server with an active Web Manager profile */
0092         Q_INVOKABLE void stopWebManagerProfile();
0093 
0094         /** Handle the errors of the async Web Manager requests */
0095         Q_INVOKABLE void webManagerReplyError(QNetworkReply::NetworkError code);
0096 
0097         /** Do actions when async Web Manager requests are finished */
0098         Q_INVOKABLE void webManagerReplyFinished();
0099 
0100         Q_INVOKABLE TelescopeLite *getTelescope();
0101 
0102         QString connectedHost()
0103         {
0104             return m_connectedHost;
0105         }
0106         void setConnectedHost(const QString &connectedHost);
0107         void setConnected(bool connected);
0108 
0109         /**
0110          * Set the INDI Control Page
0111          *
0112          * @param page Reference to the QML page
0113          */
0114         void setIndiControlPage(QObject &page)
0115         {
0116             indiControlPage = &page;
0117         };
0118 
0119         /**
0120          * @brief syncLED
0121          * @param device device name
0122          * @param property property name
0123          * @param name of Light which LED needs to be synced
0124          * @return color of state
0125          */
0126         Q_INVOKABLE QString syncLED(const QString &device, const QString &property, const QString &name = "");
0127 
0128         void buildTextGUI(INDI::Property property);
0129         void buildNumberGUI(INDI::Property property);
0130         void buildMenuGUI(INDI::Property property);
0131         void buildSwitchGUI(INDI::Property property, PGui guiType);
0132         void buildSwitch(bool buttonGroup, ISwitch *sw, INDI::Property property, bool exclusive = false,
0133                          PGui guiType = PG_BUTTONS);
0134         void buildLightGUI(INDI::Property property);
0135         //void buildBLOBGUI(INDI::Property property);
0136 
0137         Q_INVOKABLE void sendNewINDISwitch(const QString &deviceName, const QString &propName, const QString &name);
0138         Q_INVOKABLE void sendNewINDISwitch(const QString &deviceName, const QString &propName, int index);
0139 
0140         Q_INVOKABLE void sendNewINDINumber(const QString &deviceName, const QString &propName, const QString &numberName,
0141                                            double value);
0142         Q_INVOKABLE void sendNewINDIText(const QString &deviceName, const QString &propName, const QString &fieldName,
0143                                          const QString &text);
0144 
0145         bool isConnected()
0146         {
0147             return m_connected;
0148         }
0149         Q_INVOKABLE bool isDeviceConnected(const QString &deviceName);
0150 
0151         QList<DeviceInfoLite *> getDevices()
0152         {
0153             return m_devices;
0154         }
0155 
0156         Q_INVOKABLE QString getLastUsedServer();
0157         Q_INVOKABLE void setLastUsedServer(const QString &server);
0158 
0159         Q_INVOKABLE int getLastUsedPort();
0160         Q_INVOKABLE void setLastUsedPort(int port);
0161 
0162         Q_INVOKABLE int getLastUsedWebManagerPort();
0163         Q_INVOKABLE void setLastUsedWebManagerPort(int port);
0164 
0165         /**
0166          * @brief saveDisplayImage
0167          * @return true if image was saved false otherwise
0168          */
0169         Q_INVOKABLE bool saveDisplayImage();
0170 
0171         void clearDevices();
0172 
0173     private slots:
0174 
0175         void connectNewDevice(const QString &device_name);
0176 
0177     protected:
0178         virtual void newDevice(INDI::BaseDevice *dp) override;
0179         virtual void removeDevice(INDI::BaseDevice *dp) override;
0180         virtual void newProperty(INDI::Property property) override;
0181         virtual void removeProperty(INDI::Property property) override;
0182         virtual void newBLOB(IBLOB *bp) override;
0183         virtual void newSwitch(ISwitchVectorProperty *svp) override;
0184         virtual void newNumber(INumberVectorProperty *nvp) override;
0185         virtual void newMessage(INDI::BaseDevice *dp, int messageID) override;
0186         virtual void newText(ITextVectorProperty *tvp) override;
0187         virtual void newLight(ILightVectorProperty *lvp) override;
0188         virtual void serverConnected() override {}
0189         virtual void serverDisconnected(int exit_code) override;
0190     signals:
0191         //Device
0192         void newINDIDevice(QString deviceName);
0193         void removeINDIDevice(QString deviceName);
0194         void deviceConnected(QString deviceName, bool isConnected);
0195 
0196         void newINDIProperty(QString deviceName, QString propName, QString groupName, QString type, QString label);
0197 
0198         void createINDIText(QString deviceName, QString propName, QString propLabel, QString fieldName, QString propText,
0199                             bool read, bool write);
0200 
0201         void createINDINumber(QString deviceName, QString propName, QString propLabel, QString numberName, QString propText,
0202                               bool read, bool write, bool scale);
0203 
0204         void createINDIButton(QString deviceName, QString propName, QString propText, QString switchName, bool read,
0205                               bool write, bool exclusive, bool checked, bool checkable);
0206         void createINDIRadio(QString deviceName, QString propName, QString propText, QString switchName, bool read,
0207                              bool write, bool exclusive, bool checked, bool enabled);
0208 
0209         void createINDIMenu(QString deviceName, QString propName, QString switchLabel, QString switchName, bool isSelected);
0210 
0211         void createINDILight(QString deviceName, QString propName, QString label, QString lightName);
0212 
0213         void removeINDIProperty(QString deviceName, QString groupName, QString propName);
0214 
0215         //Update signals
0216         void newINDISwitch(QString deviceName, QString propName, QString switchName, bool isOn);
0217         void newINDINumber(QString deviceName, QString propName, QString numberName, QString value);
0218         void newINDIText(QString deviceName, QString propName, QString fieldName, QString text);
0219         void newINDIMessage(QString message);
0220         void newINDILight(QString deviceName, QString propName);
0221         void newINDIBLOBImage(QString deviceName, bool isLoaded);
0222         void newLEDState(QString deviceName, QString propName); // to sync LED for properties
0223 
0224         void connectedHostChanged(QString);
0225         void connectedChanged(bool);
0226         void telescopeAdded(TelescopeLite *newTelescope);
0227         void telescopeRemoved(TelescopeLite *delTelescope);
0228         void telescopeConnected(TelescopeLite *telescope);
0229         void telescopeDisconnected();
0230 
0231         void lastUsedServerChanged();
0232         void lastUsedPortChanged();
0233         void lastUsedWebManagerPortChanged();
0234 
0235     private:
0236         bool processBLOBasCCD(IBLOB *bp);
0237 
0238         /// Qml context
0239         QQmlContext &context;
0240         QList<DeviceInfoLite *> m_devices;
0241         QString m_connectedHost;
0242         bool m_connected { false };
0243         char BLOBFilename[MAXINDIFILENAME];
0244         QImage displayImage;
0245         /// INDI Control Page
0246         QObject* indiControlPage;
0247         /// Manager for the JSON requests to the Web Manager
0248         QNetworkAccessManager manager;
0249         /// Network reply for querying profiles from the Web Manager
0250         std::unique_ptr<QNetworkReply> webMProfilesReply;
0251         /// Network reply for Web Manager status
0252         std::unique_ptr<QNetworkReply> webMStatusReply;
0253         /// Network reply to stop the active profile in the Web Manager
0254         std::unique_ptr<QNetworkReply> webMStopProfileReply;
0255         /// Network reply to start a profile in the Web Manager
0256         std::unique_ptr<QNetworkReply> webMStartProfileReply;
0257         /// Web Manager profiles
0258         QStringList webMProfiles;
0259         TelescopeLite *m_telescope { nullptr };
0260 #ifdef ANDROID
0261         QString defaultImageType;
0262         QString defaultImagesLocation;
0263 #endif
0264 };