Kstars

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

KDE's Doxygen guidelines are available online.