1818
1919#include " ASCOMDevice.hpp"
2020#include < comdef.h>
21+ #include < QTimer>
22+ // #include <qwaitcondition.h>
23+ #include < QMessageBox>
24+ #include " StelTranslator.hpp"
2125
2226ASCOMDevice::ASCOMDevice (QObject* parent, QString ascomDeviceId) : QObject(parent),
23- mAscomDeviceId(ascomDeviceId)
24- {}
27+ mAscomDeviceId(ascomDeviceId),
28+ connectionRetries(0 )
29+ {
30+ }
2531
26- bool ASCOMDevice::connect ()
32+ // FIXME! ASCOM7 deprecates writing to the LConnected property. One shall use methods Connect()/Disconnect() instead,
33+ // and detect the state per "Connecting" property.
34+ void ASCOMDevice::connect ()
2735{
28- if (mConnected ) return true ;
36+ if (mConnected ) return ; // true;
2937
3038 BOOL initResult = OleInit (COINIT_APARTMENTTHREADED);
3139 HRESULT hResult = OleCreateInstance (reinterpret_cast <const wchar_t *>(mAscomDeviceId .toStdWString ().c_str ()), &pTelescopeDispatch);
3240
3341 if (!initResult || FAILED (hResult))
3442 {
35- qDebug () << " Initialization failed for device: " << mAscomDeviceId ;
36- return false ;
43+ qCritical () << " Initialization failed for device: " << mAscomDeviceId ;
44+ QMessageBox::critical (nullptr , q_ (" ERROR!" ), q_ (" Initialization failed for device: " )+mAscomDeviceId );
45+
46+ return ;
3747 }
3848
39- VARIANT v1 = OleBoolToVariant (TRUE );
49+ // Initiate asynchronous Connect() according to ASCOM7
50+ hResult = OleMethodCall (pTelescopeDispatch, nullptr , const_cast <wchar_t *>(LConnect), 0 );
51+ if (FAILED (hResult))
52+ {
53+ qCritical () << " Could not send Connect signal to device: " << mAscomDeviceId ;
54+ QMessageBox::critical (nullptr , q_ (" ERROR!" ), q_ (" Could not send Connect signal to device: " )+mAscomDeviceId );
55+ return ;
56+ }
57+ connectionRetries=10 ;
58+ QObject::connect (&connectionTimer, &QTimer::timeout, this , &ASCOMDevice::tryFinishConnect);
59+ connectionTimer.start (250 ); // 1/4 s interval
60+ }
4061
41- hResult = OlePropertyPut (pTelescopeDispatch, nullptr , const_cast <wchar_t *>(LConnected), 1 , v1);
62+ void ASCOMDevice::tryFinishConnect ()
63+ {
64+ qDebug () << " ASCOMDevice::tryFinishConnect()" ;
4265
43- if (FAILED (hResult ))
66+ if (isConnecting ( ))
4467 {
45- qDebug () << " Could not connect to device: " << mAscomDeviceId ;
46- return false ;
68+ if (--connectionRetries <= 0 )
69+ {
70+ // Give up connecting!
71+ connectionTimer.stop ();
72+ QObject::disconnect (&connectionTimer, &QTimer::timeout, this , &ASCOMDevice::tryFinishConnect);
73+ qCritical () << " Could not establish connection to device: " << mAscomDeviceId ;
74+ QMessageBox::critical (nullptr , q_ (" ERROR!" ), q_ (" Could not establish connection to device: " )+mAscomDeviceId );
75+ }
76+ }
77+ else // connection has probably been established. Read value for certainty.
78+ {
79+ connectionTimer.stop ();
80+ QObject::disconnect (&connectionTimer, &QTimer::timeout, this , &ASCOMDevice::tryFinishConnect);
81+ mConnected =isDeviceConnected ();
4782 }
48-
49- mConnected = true ;
50- return true ;
5183}
5284
53- bool ASCOMDevice::disconnect ()
85+ void ASCOMDevice::tryFinishDisconnect ()
5486{
55- if (!mConnected ) return true ;
87+ qDebug () << " ASCOMDevice::tryFinishDisconnect()" ;
88+ if (isConnecting ())
89+ {
90+ if (--connectionRetries <= 0 )
91+ {
92+ // Give up disconnecting! Is that at all useful?
93+ connectionTimer.stop ();
94+ QObject::disconnect (&connectionTimer, &QTimer::timeout, this , &ASCOMDevice::tryFinishDisconnect);
95+ qCritical () << " Could not send Disconnect signal to device: " << mAscomDeviceId ;
96+ // TODO: Show a screen panel?
97+ QMessageBox::critical (nullptr , q_ (" ERROR!" ), q_ (" Could not cleanly disconnect from device: " )+mAscomDeviceId );
98+ }
99+ }
100+ else // disconnection has been successful. Read value for certainty.
101+ {
102+ connectionTimer.stop ();
103+ QObject::disconnect (&connectionTimer, &QTimer::timeout, this , &ASCOMDevice::tryFinishDisconnect);
104+ mConnected =false ;
105+ pTelescopeDispatch->Release ();
106+ }
107+ }
108+
56109
57- VARIANT v1 = OleBoolToVariant (FALSE );
58- HRESULT hResult = OlePropertyPut (pTelescopeDispatch, nullptr , const_cast <wchar_t *>(LConnected), 1 , v1);
59110
111+ // void ASCOMDevice::disconnect()
112+ // {
113+ // if (!mConnected) return; // true;
114+ //
115+ // VARIANT v1 = OleBoolToVariant(FALSE);
116+ // HRESULT hResult = OlePropertyPut(pTelescopeDispatch, nullptr, const_cast<wchar_t*>(LConnected), 1, v1);
117+ //
118+ // if (FAILED(hResult))
119+ // {
120+ // qDebug() << "Could not disconnect device: " << mAscomDeviceId;
121+ // return; // false;
122+ // }
123+ //
124+ // pTelescopeDispatch->Release(); // TODO: Move that to tryFinishDisconnect
125+ //
126+ // mConnected = false;
127+ // return; // true;
128+ // }
129+
130+
131+ void ASCOMDevice::disconnect ()
132+ {
133+ if (mConnected ) return ; // true;
134+
135+
136+ // Initiate asynchronous Disconnect() according to ASCOM7
137+ HRESULT hResult = OleMethodCall (pTelescopeDispatch, nullptr , const_cast <wchar_t *>(LDisconnect), 0 );
60138 if (FAILED (hResult))
61139 {
62- qDebug () << " Could not disconnect device: " << mAscomDeviceId ;
63- return false ;
140+ qCritical () << " Could not send Disconnect signal to device: " << mAscomDeviceId ;
141+ // TODO: Show a screen panel?
142+ return ;
64143 }
65-
66- pTelescopeDispatch->Release ();
67-
68- mConnected = false ;
69- return true ;
144+ connectionRetries=10 ;
145+ QObject::connect (&connectionTimer, &QTimer::timeout, this , &ASCOMDevice::tryFinishDisconnect);
146+ connectionTimer.start (250 ); // 1/4 s interval
70147}
71148
149+
72150ASCOMDevice::ASCOMCoordinates ASCOMDevice::position () const
73151{
74152 return mCoordinates ;
@@ -114,6 +192,11 @@ void ASCOMDevice::abortSlew()
114192 }
115193}
116194
195+ bool ASCOMDevice::isConnected () const
196+ {
197+ return mConnected ;
198+ }
199+
117200bool ASCOMDevice::isDeviceConnected () const
118201{
119202 if (!mConnected ) return false ;
@@ -127,7 +210,21 @@ bool ASCOMDevice::isDeviceConnected() const
127210 return false ;
128211 }
129212
130- return v1.boolVal == -1 ;
213+ return v1.boolVal == VARIANT_TRUE;
214+ }
215+
216+ bool ASCOMDevice::isConnecting () const
217+ {
218+ VARIANT v1;
219+ HRESULT hResult = OlePropertyGet (pTelescopeDispatch, &v1, const_cast <wchar_t *>(LConnecting));
220+
221+ if (FAILED (hResult))
222+ {
223+ qDebug () << " Could not get connecting state for device: " << mAscomDeviceId ;
224+ return false ;
225+ }
226+
227+ return v1.boolVal == VARIANT_TRUE;
131228}
132229
133230bool ASCOMDevice::isParked () const
@@ -143,7 +240,7 @@ bool ASCOMDevice::isParked() const
143240 return false ;
144241 }
145242
146- return v1.boolVal == - 1 ;
243+ return v1.boolVal == VARIANT_TRUE ;
147244}
148245
149246
@@ -176,7 +273,7 @@ bool ASCOMDevice::doesRefraction()
176273 return false ;
177274 }
178275
179- return v1.boolVal == - 1 ;
276+ return v1.boolVal == VARIANT_TRUE ;
180277}
181278
182279
@@ -228,9 +325,12 @@ QString ASCOMDevice::showDeviceChooser(QString previousDeviceId)
228325
229326const wchar_t * ASCOMDevice::LSlewToCoordinatesAsync = L" SlewToCoordinatesAsync" ;
230327const wchar_t * ASCOMDevice::LSyncToCoordinates = L" SyncToCoordinates" ;
231- const wchar_t * ASCOMDevice::LAbortSlew = L" AbortSlew" ;
232- const wchar_t * ASCOMDevice::LConnected = L" Connected" ;
233- const wchar_t * ASCOMDevice::LAtPark = L" AtPark" ;
328+ const wchar_t * ASCOMDevice::LAbortSlew = L" AbortSlew" ;
329+ const wchar_t * ASCOMDevice::LConnected = L" Connected" ;
330+ const wchar_t * ASCOMDevice::LConnecting = L" Connecting" ;
331+ const wchar_t * ASCOMDevice::LConnect = L" Connect" ;
332+ const wchar_t * ASCOMDevice::LDisconnect = L" Disconnect" ;
333+ const wchar_t * ASCOMDevice::LAtPark = L" AtPark" ;
234334const wchar_t * ASCOMDevice::LEquatorialSystem = L" EquatorialSystem" ;
235335const wchar_t * ASCOMDevice::LDoesRefraction = L" DoesRefraction" ;
236336const wchar_t * ASCOMDevice::LRightAscension = L" RightAscension" ;
0 commit comments