Kstars

indidome.cpp
1 /*
2  SPDX-FileCopyrightText: 2015 Jasem Mutlaq <[email protected]>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include <basedevice.h>
8 #include <KActionCollection>
9 #include <KNotification>
10 #include <QAction>
11 #include <QtDBus/qdbusmetatype.h>
12 
13 #include "indidome.h"
14 #include "kstars.h"
15 #include "clientmanager.h"
16 #include "domeadaptor.h"
17 
18 namespace ISD
19 {
20 
21 const QList<const char *> Dome::domeStates = { I18N_NOOP("Idle"), I18N_NOOP("Moving clockwise"), I18N_NOOP("Moving counter clockwise"),
22  I18N_NOOP("Tracking"), I18N_NOOP("Parking"), I18N_NOOP("UnParking"), I18N_NOOP("Parked"),
23  I18N_NOOP("Error")
24  };
25 
26 uint8_t Dome::m_ID = 1;
27 
28 Dome::Dome(GenericDevice *parent) : ConcreteDevice(parent)
29 {
30  qRegisterMetaType<ISD::Dome::Status>("ISD::Dome::Status");
31  qDBusRegisterMetaType<ISD::Dome::Status>();
32 
33  qRegisterMetaType<ISD::Dome::ShutterStatus>("ISD::Dome::ShutterStatus");
34  qDBusRegisterMetaType<ISD::Dome::ShutterStatus>();
35 
36  new DomeAdaptor(this);
37  QDBusConnection::sessionBus().registerObject(QString("/KStars/INDI/Dome/%1").arg(getID()), this);
38 }
39 
40 void Dome::registerProperty(INDI::Property prop)
41 {
42  if (!prop->getRegistered())
43  return;
44 
45  if (prop->isNameMatch("ABS_DOME_POSITION"))
46  {
47  m_CanAbsMove = true;
48  }
49  else if (prop->isNameMatch("REL_DOME_POSITION"))
50  {
51  m_CanRelMove = true;
52  }
53  else if (prop->isNameMatch("DOME_ABORT_MOTION"))
54  {
55  m_CanAbort = true;
56  }
57  else if (prop->isNameMatch("DOME_SHUTTER"))
58  {
59  m_HasShutter = true;
60  }
61 
62  ConcreteDevice::registerProperty(prop);
63 }
64 
65 void Dome::processNumber(INumberVectorProperty *nvp)
66 {
67  if (!strcmp(nvp->name, "ABS_DOME_POSITION"))
68  {
69  emit positionChanged(nvp->np[0].value);
70  }
71 }
72 
73 void Dome::processSwitch(ISwitchVectorProperty *svp)
74 {
75  if (!strcmp(svp->name, "CONNECTION"))
76  {
77  ISwitch *conSP = IUFindSwitch(svp, "CONNECT");
78  if (conSP)
79  {
80  if (conSP->s == ISS_ON)
82  else
83  {
85 
86  m_CanAbsMove = false;
87  m_CanPark = false;
88  }
89  }
90  }
91  else if (!strcmp(svp->name, "DOME_PARK"))
92  {
93  m_CanPark = true;
94 
95  ISwitch *sp = IUFindSwitch(svp, "PARK");
96  if (sp)
97  {
98  if (svp->s == IPS_ALERT)
99  {
100  m_ParkStatus = PARK_ERROR;
101  emit newParkStatus(PARK_ERROR);
102 
103  // If alert, set park status to whatever it was opposite to. That is, if it was parking and failed
104  // then we set status to unparked since it did not successfully complete parking.
105  // if (m_ParkStatus == PARK_PARKING)
106  // m_ParkStatus = PARK_UNPARKED;
107  // else if (m_ParkStatus == PARK_UNPARKING)
108  // m_ParkStatus = PARK_PARKED;
109 
110  // emit newParkStatus(m_ParkStatus);
111 
112  }
113  else if (svp->s == IPS_BUSY && sp->s == ISS_ON && m_ParkStatus != PARK_PARKING)
114  {
115  m_ParkStatus = PARK_PARKING;
116  KNotification::event(QLatin1String("DomeParking"), i18n("Dome parking is in progress"));
117  emit newParkStatus(m_ParkStatus);
118 
119  if (m_Status != DOME_PARKING)
120  {
121  m_Status = DOME_PARKING;
122  emit newStatus(m_Status);
123  }
124  }
125  else if (svp->s == IPS_BUSY && sp->s == ISS_OFF && m_ParkStatus != PARK_UNPARKING)
126  {
127  m_ParkStatus = PARK_UNPARKING;
128  KNotification::event(QLatin1String("DomeUnparking"), i18n("Dome unparking is in progress"));
129  emit newParkStatus(m_ParkStatus);
130 
131  if (m_Status != DOME_UNPARKING)
132  {
133  m_Status = DOME_UNPARKING;
134  emit newStatus(m_Status);
135  }
136  }
137  else if (svp->s == IPS_OK && sp->s == ISS_ON && m_ParkStatus != PARK_PARKED)
138  {
139  m_ParkStatus = PARK_PARKED;
140  KNotification::event(QLatin1String("DomeParked"), i18n("Dome parked"));
141  emit newParkStatus(m_ParkStatus);
142 
143  QAction *parkAction = KStars::Instance()->actionCollection()->action("dome_park");
144  if (parkAction)
145  parkAction->setEnabled(false);
146  QAction *unParkAction = KStars::Instance()->actionCollection()->action("dome_unpark");
147  if (unParkAction)
148  unParkAction->setEnabled(true);
149 
150  if (m_Status != DOME_PARKED)
151  {
152  m_Status = DOME_PARKED;
153  emit newStatus(m_Status);
154  }
155 
156  }
157  else if ( (svp->s == IPS_OK || svp->s == IPS_IDLE) && sp->s == ISS_OFF && m_ParkStatus != PARK_UNPARKED)
158  {
159  m_ParkStatus = PARK_UNPARKED;
160  KNotification::event(QLatin1String("DomeUnparked"), i18n("Dome unparked"));
161 
162  QAction *parkAction = KStars::Instance()->actionCollection()->action("dome_park");
163  if (parkAction)
164  parkAction->setEnabled(true);
165  QAction *unParkAction = KStars::Instance()->actionCollection()->action("dome_unpark");
166  if (unParkAction)
167  unParkAction->setEnabled(false);
168 
169  emit newParkStatus(m_ParkStatus);
170 
171  if (m_Status != DOME_IDLE)
172  {
173  m_Status = DOME_IDLE;
174  emit newStatus(m_Status);
175  }
176  }
177  }
178  }
179  else if (!strcmp(svp->name, "DOME_MOTION"))
180  {
181  Status lastStatus = m_Status;
182 
183  if (svp->s == IPS_BUSY && lastStatus != DOME_MOVING_CW && lastStatus != DOME_MOVING_CCW && lastStatus != DOME_PARKING
184  && lastStatus != DOME_UNPARKING)
185  {
186  m_Status = svp->sp->s == ISS_ON ? DOME_MOVING_CW : DOME_MOVING_CCW;
187  emit newStatus(m_Status);
188 
189  // rolloff roofs: cw = opening = unparking, ccw = closing = parking
190  if (!canAbsMove() && !canRelMove())
191  {
192  m_ParkStatus = (m_Status == DOME_MOVING_CW) ? PARK_UNPARKING : PARK_PARKING;
193  emit newParkStatus(m_ParkStatus);
194  }
195  }
196  else if (svp->s == IPS_OK && (lastStatus == DOME_MOVING_CW || lastStatus == DOME_MOVING_CCW))
197  {
198  m_Status = DOME_TRACKING;
199  emit newStatus(m_Status);
200  }
201  else if (svp->s == IPS_IDLE && lastStatus != DOME_IDLE)
202  {
203  m_Status = DOME_IDLE;
204  emit newStatus(m_Status);
205  }
206  else if (svp->s == IPS_ALERT)
207  {
208  m_Status = DOME_ERROR;
209  emit newStatus(m_Status);
210  }
211  }
212  else if (!strcmp(svp->name, "DOME_SHUTTER"))
213  {
214  if (svp->s == IPS_ALERT)
215  {
216  emit newShutterStatus(SHUTTER_ERROR);
217 
218  // If alert, set shutter status to whatever it was opposite to. That is, if it was opening and failed
219  // then we set status to closed since it did not successfully complete opening.
220  if (m_ShutterStatus == SHUTTER_CLOSING)
221  m_ShutterStatus = SHUTTER_OPEN;
222  else
223  m_ShutterStatus = SHUTTER_CLOSED;
224 
225  emit newShutterStatus(m_ShutterStatus);
226  }
227 
228  ShutterStatus status = parseShutterStatus(svp);
229 
230  switch (status)
231  {
232  case SHUTTER_CLOSING:
233  if (m_ShutterStatus != SHUTTER_CLOSING)
234  {
235  m_ShutterStatus = SHUTTER_CLOSING;
236  KNotification::event(QLatin1String("ShutterClosing"), i18n("Shutter closing is in progress"));
237  emit newShutterStatus(m_ShutterStatus);
238  }
239  break;
240  case SHUTTER_OPENING:
241  if (m_ShutterStatus != SHUTTER_OPENING)
242  {
243  m_ShutterStatus = SHUTTER_OPENING;
244  KNotification::event(QLatin1String("ShutterOpening"), i18n("Shutter opening is in progress"));
245  emit newShutterStatus(m_ShutterStatus);
246  }
247  break;
248  case SHUTTER_CLOSED:
249  if (m_ShutterStatus != SHUTTER_CLOSED)
250  {
251  m_ShutterStatus = SHUTTER_CLOSED;
252  KNotification::event(QLatin1String("ShutterClosed"), i18n("Shutter closed"));
253  emit newShutterStatus(m_ShutterStatus);
254  }
255  break;
256  case SHUTTER_OPEN:
257  if (m_ShutterStatus != SHUTTER_OPEN)
258  {
259  m_ShutterStatus = SHUTTER_OPEN;
260  KNotification::event(QLatin1String("ShutterOpened"), i18n("Shutter opened"));
261  emit newShutterStatus(m_ShutterStatus);
262  }
263  break;
264  default:
265  break;
266  }
267 
268  return;
269 
270  }
271  else if (!strcmp(svp->name, "DOME_AUTOSYNC"))
272  {
273  ISwitch *sp = IUFindSwitch(svp, "DOME_AUTOSYNC_ENABLE");
274  if (sp != nullptr)
275  emit newAutoSyncStatus(sp->s == ISS_ON);
276  }
277 }
278 
279 bool Dome::abort()
280 {
281  if (m_CanAbort == false)
282  return false;
283 
284  auto motionSP = getSwitch("DOME_ABORT_MOTION");
285 
286  if (!motionSP)
287  return false;
288 
289  auto abortSW = motionSP->findWidgetByName("ABORT");
290 
291  if (!abortSW)
292  return false;
293 
294  abortSW->setState(ISS_ON);
295  sendNewSwitch(motionSP);
296 
297  return true;
298 }
299 
300 bool Dome::park()
301 {
302  auto parkSP = getSwitch("DOME_PARK");
303 
304  if (!parkSP)
305  return false;
306 
307  auto parkSW = parkSP->findWidgetByName("PARK");
308 
309  if (!parkSW)
310  return false;
311 
312  parkSP->reset();
313  parkSW->setState(ISS_ON);
314  sendNewSwitch(parkSP);
315 
316  return true;
317 }
318 
319 bool Dome::unPark()
320 {
321  auto parkSP = getSwitch("DOME_PARK");
322 
323  if (!parkSP)
324  return false;
325 
326  auto parkSW = parkSP->findWidgetByName("UNPARK");
327 
328  if (!parkSW)
329  return false;
330 
331  parkSP->reset();
332  parkSW->setState(ISS_ON);
333  sendNewSwitch(parkSP);
334 
335  return true;
336 }
337 
338 bool Dome::isMoving() const
339 {
340  auto motionSP = getSwitch("DOME_MOTION");
341 
342  if (motionSP && motionSP->getState() == IPS_BUSY)
343  return true;
344 
345  return false;
346 }
347 
348 double Dome::position() const
349 {
350  auto az = getNumber("ABS_DOME_POSITION");
351 
352  if (!az)
353  return -1;
354  else
355  return az->at(0)->getValue();
356 }
357 
358 bool Dome::setPosition(double position)
359 {
360  auto az = getNumber("ABS_DOME_POSITION");
361 
362  if (!az)
363  return false;
364 
365  az->at(0)->setValue(position);
366  sendNewNumber(az);
367  return true;
368 }
369 
370 bool Dome::setRelativePosition(double position)
371 {
372  auto azDiff = getNumber("REL_DOME_POSITION");
373  if (!azDiff)
374  return false;
375 
376  azDiff->at(0)->setValue(position);
377  sendNewNumber(azDiff);
378  return true;
379 }
380 
381 bool Dome::isAutoSync()
382 {
383  auto autosync = getSwitch("DOME_AUTOSYNC");
384  if (!autosync)
385  return false;
386 
387  auto autosyncSW = autosync->findWidgetByName("DOME_AUTOSYNC_ENABLE");
388  if (!autosyncSW)
389  return false;
390  else
391  return (autosyncSW->s == ISS_ON);
392 }
393 
394 bool Dome::setAutoSync(bool activate)
395 {
396  auto autosync = getSwitch("DOME_AUTOSYNC");
397  if (!autosync)
398  return false;
399 
400  auto autosyncSW = autosync->findWidgetByName(activate ? "DOME_AUTOSYNC_ENABLE" : "DOME_AUTOSYNC_DISABLE");
401  if (!autosyncSW)
402  return false;
403 
404  autosync->reset();
405  autosyncSW->setState(ISS_ON);
406  sendNewSwitch(autosync);
407 
408  return true;
409 }
410 
411 bool Dome::moveDome(DomeDirection dir, DomeMotionCommand operation)
412 {
413  auto domeMotion = getSwitch("DOME_MOTION");
414  if (!domeMotion)
415  return false;
416 
417  auto opSwitch = domeMotion->findWidgetByName(dir == DomeDirection::DOME_CW ? "DOME_CW" : "DOME_CCW");
418  if (!opSwitch)
419  return false;
420 
421  domeMotion->reset();
422  opSwitch->setState(operation == DomeMotionCommand::MOTION_START ? ISS_ON : ISS_OFF);
423  sendNewSwitch(domeMotion);
424  return true;
425 }
426 
427 bool Dome::controlShutter(bool open)
428 {
429  auto shutterSP = getSwitch("DOME_SHUTTER");
430  if (!shutterSP)
431  return false;
432 
433  auto shutterSW = shutterSP->findWidgetByName(open ? "SHUTTER_OPEN" : "SHUTTER_CLOSE");
434  if (!shutterSW)
435  return false;
436 
437  shutterSP->reset();
438  shutterSW->setState(ISS_ON);
439  sendNewSwitch(shutterSP);
440 
441  return true;
442 }
443 
444 Dome::ShutterStatus Dome::shutterStatus()
445 {
446  auto shutterSP = getSwitch("DOME_SHUTTER");
447 
448  return parseShutterStatus(shutterSP);
449 }
450 
451 Dome::ShutterStatus Dome::parseShutterStatus(ISwitchVectorProperty *svp)
452 {
453  if (svp == nullptr)
454  return SHUTTER_UNKNOWN;
455 
456  ISwitch *sp = IUFindSwitch(svp, "SHUTTER_OPEN");
457  if (sp == nullptr)
458  return SHUTTER_UNKNOWN;
459 
460  if (svp->s == IPS_ALERT)
461  return SHUTTER_ERROR;
462  else if (svp->s == IPS_BUSY)
463  return (sp->s == ISS_ON) ? SHUTTER_OPENING : SHUTTER_CLOSING;
464  else if (svp->s == IPS_OK)
465  return (sp->s == ISS_ON) ? SHUTTER_OPEN : SHUTTER_CLOSED;
466 
467  // this should not happen
468  return SHUTTER_UNKNOWN;
469 }
470 
471 const QString Dome::getStatusString(Dome::Status status, bool translated)
472 {
473  return translated ? i18n(domeStates[status]) : domeStates[status];
474 }
475 
476 }
477 
478 QDBusArgument &operator<<(QDBusArgument &argument, const ISD::Dome::Status &source)
479 {
480  argument.beginStructure();
481  argument << static_cast<int>(source);
482  argument.endStructure();
483  return argument;
484 }
485 
486 const QDBusArgument &operator>>(const QDBusArgument &argument, ISD::Dome::Status &dest)
487 {
488  int a;
489  argument.beginStructure();
490  argument >> a;
491  argument.endStructure();
492  dest = static_cast<ISD::Dome::Status>(a);
493  return argument;
494 }
495 
496 QDBusArgument &operator<<(QDBusArgument &argument, const ISD::Dome::ShutterStatus &source)
497 {
498  argument.beginStructure();
499  argument << static_cast<int>(source);
500  argument.endStructure();
501  return argument;
502 }
503 
504 const QDBusArgument &operator>>(const QDBusArgument &argument, ISD::Dome::ShutterStatus &dest)
505 {
506  int a;
507  argument.beginStructure();
508  argument >> a;
509  argument.endStructure();
510  dest = static_cast<ISD::Dome::ShutterStatus>(a);
511  return argument;
512 }
513 
QAction * action(const QString &name) const
void slotSetDomeEnabled(bool enable)
slotSetDomeEnabled call when dome comes online or goes offline.
bool registerObject(const QString &path, QObject *object, QDBusConnection::RegisterOptions options)
static KStars * Instance()
Definition: kstars.h:125
QString i18n(const char *text, const TYPE &arg...)
QDBusConnection sessionBus()
NETWORKMANAGERQT_EXPORT NetworkManager::Status status()
virtual KActionCollection * actionCollection() const
void setEnabled(bool)
QDebug operator<<(QDebug d, const QCPVector2D &vec)
Definition: qcustomplot.h:450
void beginStructure()
void endStructure()
#define I18N_NOOP(text)
QDataStream & operator>>(QDataStream &in, KDateTime &dateTime)
static KNotification * event(const QString &eventId, const QString &text=QString(), const QPixmap &pixmap=QPixmap(), QWidget *widget=nullptr, const NotificationFlags &flags=CloseOnTimeout, const QString &componentName=QString())
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Fri Aug 19 2022 03:57:51 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.