File indexing completed on 2024-04-28 03:43:14
0001 /* Ekos commands for the capture module 0002 SPDX-FileCopyrightText: Wolfgang Reissenberger <sterne-jaeger@openfuture.de> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "capturedeviceadaptor.h" 0008 0009 #include "ksmessagebox.h" 0010 #include "Options.h" 0011 #include "indi/indistd.h" 0012 #include "ekos_capture_debug.h" 0013 #include "sequencejobstate.h" 0014 0015 #include "indi/indicamera.h" 0016 #include "indi/indidustcap.h" 0017 #include "indi/indidome.h" 0018 #include "indi/indilightbox.h" 0019 #include "indi/indimount.h" 0020 #include "indi/indirotator.h" 0021 #include "ekos/auxiliary/rotatorutils.h" 0022 0023 namespace Ekos 0024 { 0025 0026 0027 void CaptureDeviceAdaptor::connectDome(SequenceJobState *state) 0028 { 0029 if (state == nullptr) 0030 return; 0031 0032 connect(state, &SequenceJobState::setDomeParked, this, &CaptureDeviceAdaptor::setDomeParked); 0033 connect(this, &CaptureDeviceAdaptor::domeStatusChanged, state, &SequenceJobState::domeStatusChanged); 0034 } 0035 0036 void CaptureDeviceAdaptor::disconnectDome(SequenceJobState *state) 0037 { 0038 if (state == nullptr) 0039 return; 0040 0041 disconnect(state, &SequenceJobState::setDomeParked, this, &CaptureDeviceAdaptor::setDomeParked); 0042 disconnect(this, &CaptureDeviceAdaptor::domeStatusChanged, state, &SequenceJobState::domeStatusChanged); 0043 } 0044 0045 void CaptureDeviceAdaptor::setCurrentSequenceJobState(QSharedPointer<SequenceJobState> jobState) 0046 { 0047 // clear old connections 0048 disconnectDevices(currentSequenceJobState.data()); 0049 // add new connections 0050 connectRotator(jobState.data()); 0051 connectFilterManager(jobState.data()); 0052 connectActiveCamera(jobState.data()); 0053 connectMount(jobState.data()); 0054 connectDome(jobState.data()); 0055 connectDustCap(jobState.data()); 0056 currentSequenceJobState = jobState; 0057 0058 } 0059 0060 void CaptureDeviceAdaptor::setDustCap(ISD::DustCap *device) 0061 { 0062 disconnectDustCap(currentSequenceJobState.data()); 0063 m_ActiveDustCap = device; 0064 connectDustCap(currentSequenceJobState.data()); 0065 } 0066 0067 void CaptureDeviceAdaptor::disconnectDevices(SequenceJobState *state) 0068 { 0069 disconnectRotator(state); 0070 disconnectFilterManager(state); 0071 disconnectActiveCamera(state); 0072 disconnectMount(state); 0073 disconnectDome(state); 0074 disconnectDustCap(state); 0075 } 0076 0077 0078 0079 0080 0081 void CaptureDeviceAdaptor::connectDustCap(SequenceJobState *state) 0082 { 0083 if (m_ActiveDustCap != nullptr) 0084 connect(m_ActiveDustCap, &ISD::DustCap::newStatus, this, &CaptureDeviceAdaptor::dustCapStatusChanged); 0085 0086 if (state == nullptr) 0087 return; 0088 0089 connect(state, &SequenceJobState::askManualScopeCover, this, &CaptureDeviceAdaptor::askManualScopeCover); 0090 connect(state, &SequenceJobState::askManualScopeOpen, this, &CaptureDeviceAdaptor::askManualScopeOpen); 0091 connect(state, &SequenceJobState::setLightBoxLight, this, &CaptureDeviceAdaptor::setLightBoxLight); 0092 connect(state, &SequenceJobState::parkDustCap, this, &CaptureDeviceAdaptor::parkDustCap); 0093 0094 connect(this, &CaptureDeviceAdaptor::manualScopeCoverUpdated, state, &SequenceJobState::updateManualScopeCover); 0095 connect(this, &CaptureDeviceAdaptor::lightBoxLight, state, &SequenceJobState::lightBoxLight); 0096 connect(this, &CaptureDeviceAdaptor::dustCapStatusChanged, state, &SequenceJobState::dustCapStateChanged); 0097 } 0098 0099 void CaptureDeviceAdaptor::disconnectDustCap(SequenceJobState *state) 0100 { 0101 if (m_ActiveDustCap != nullptr) 0102 disconnect(m_ActiveDustCap, nullptr, this, nullptr); 0103 0104 if (state == nullptr) 0105 return; 0106 0107 disconnect(state, &SequenceJobState::askManualScopeCover, this, &CaptureDeviceAdaptor::askManualScopeCover); 0108 disconnect(state, &SequenceJobState::askManualScopeOpen, this, &CaptureDeviceAdaptor::askManualScopeOpen); 0109 disconnect(state, &SequenceJobState::setLightBoxLight, this, &CaptureDeviceAdaptor::setLightBoxLight); 0110 disconnect(state, &SequenceJobState::parkDustCap, this, &CaptureDeviceAdaptor::parkDustCap); 0111 0112 disconnect(this, &CaptureDeviceAdaptor::manualScopeCoverUpdated, state, &SequenceJobState::updateManualScopeCover); 0113 disconnect(this, &CaptureDeviceAdaptor::lightBoxLight, state, &SequenceJobState::lightBoxLight); 0114 disconnect(this, &CaptureDeviceAdaptor::dustCapStatusChanged, state, &SequenceJobState::dustCapStateChanged); 0115 } 0116 0117 void CaptureDeviceAdaptor::setMount(ISD::Mount *device) 0118 { 0119 if (m_ActiveMount == device) 0120 return; 0121 0122 // clean up old connections 0123 if (m_ActiveMount != nullptr) 0124 { 0125 disconnect(m_ActiveMount, nullptr, this, nullptr); 0126 disconnectMount(currentSequenceJobState.data()); 0127 } 0128 // connect new device 0129 if (device != nullptr) 0130 { 0131 connect(device, &ISD::Mount::newStatus, this, &CaptureDeviceAdaptor::scopeStatusChanged); 0132 connect(device, &ISD::Mount::pierSideChanged, this, &CaptureDeviceAdaptor::pierSideChanged); 0133 connect(device, &ISD::Mount::newParkStatus, this, &CaptureDeviceAdaptor::scopeParkStatusChanged); 0134 connectMount(currentSequenceJobState.data()); 0135 0136 // update mount states 0137 emit pierSideChanged(device->pierSide()); 0138 emit scopeParkStatusChanged(device->parkStatus()); 0139 } 0140 0141 m_ActiveMount = device; 0142 } 0143 0144 void CaptureDeviceAdaptor::connectMount(SequenceJobState *state) 0145 { 0146 if (state == nullptr) 0147 return; 0148 0149 connect(state, &SequenceJobState::slewTelescope, this, &CaptureDeviceAdaptor::slewTelescope); 0150 connect(state, &SequenceJobState::setScopeTracking, this, &CaptureDeviceAdaptor::setScopeTracking); 0151 connect(state, &SequenceJobState::setScopeParked, this, &CaptureDeviceAdaptor::setScopeParked); 0152 0153 connect(this, &CaptureDeviceAdaptor::scopeStatusChanged, state, &SequenceJobState::scopeStatusChanged); 0154 connect(this, &CaptureDeviceAdaptor::scopeParkStatusChanged, state, &SequenceJobState::scopeParkStatusChanged); 0155 } 0156 0157 void CaptureDeviceAdaptor::disconnectMount(SequenceJobState *state) 0158 { 0159 if (state == nullptr) 0160 return; 0161 0162 disconnect(state, &SequenceJobState::slewTelescope, this, &CaptureDeviceAdaptor::slewTelescope); 0163 disconnect(state, &SequenceJobState::setScopeTracking, this, &CaptureDeviceAdaptor::setScopeTracking); 0164 disconnect(state, &SequenceJobState::setScopeParked, this, &CaptureDeviceAdaptor::setScopeParked); 0165 0166 disconnect(this, &CaptureDeviceAdaptor::scopeStatusChanged, state, &SequenceJobState::scopeStatusChanged); 0167 disconnect(this, &CaptureDeviceAdaptor::scopeParkStatusChanged, state, &SequenceJobState::scopeParkStatusChanged); 0168 } 0169 0170 void CaptureDeviceAdaptor::setDome(ISD::Dome *device) 0171 { 0172 if (m_ActiveDome == device) 0173 return; 0174 0175 // clean up old connections 0176 if (m_ActiveDome != nullptr) 0177 { 0178 disconnect(m_ActiveDome, nullptr, this, nullptr); 0179 disconnectDome(currentSequenceJobState.data()); 0180 } 0181 // connect new device 0182 if (device != nullptr) 0183 { 0184 connect(device, &ISD::Dome::newStatus, this, &CaptureDeviceAdaptor::domeStatusChanged); 0185 connectDome(currentSequenceJobState.data()); 0186 } 0187 0188 m_ActiveDome = device; 0189 } 0190 0191 void CaptureDeviceAdaptor::setRotator(ISD::Rotator *device) 0192 { 0193 // do nothing if *real* rotator is already connected 0194 if ((m_ActiveRotator == device) && (device != nullptr)) 0195 return; 0196 0197 // clean up old connections 0198 if (m_ActiveRotator != nullptr) 0199 { 0200 m_ActiveRotator->disconnect(this); 0201 disconnectRotator(currentSequenceJobState.data()); 0202 } 0203 0204 m_ActiveRotator = device; 0205 0206 // connect new device 0207 if (m_ActiveRotator != nullptr) 0208 { 0209 connect(m_ActiveRotator, &ISD::Rotator::newAbsoluteAngle, this, &CaptureDeviceAdaptor::newRotatorAngle, 0210 Qt::UniqueConnection); 0211 connect(m_ActiveRotator, &ISD::Rotator::reverseToggled, this, &CaptureDeviceAdaptor::rotatorReverseToggled, 0212 Qt::UniqueConnection); 0213 connectRotator(currentSequenceJobState.data()); 0214 0215 emit newRotator(device->getDeviceName()); 0216 } 0217 else 0218 emit newRotator(""); // no real rotator present, so check if user wants to use "manual rotator" 0219 0220 } 0221 0222 void CaptureDeviceAdaptor::connectRotator(SequenceJobState *state) 0223 { 0224 if (state == nullptr) 0225 return; 0226 0227 connect(this, &CaptureDeviceAdaptor::newRotatorAngle, state, &SequenceJobState::setCurrentRotatorPositionAngle, 0228 Qt::UniqueConnection); 0229 connect(state, &SequenceJobState::setRotatorAngle, this, &CaptureDeviceAdaptor::setRotatorAngle); 0230 } 0231 0232 void CaptureDeviceAdaptor::disconnectRotator(SequenceJobState *state) 0233 { 0234 if (state == nullptr) 0235 return; 0236 0237 disconnect(state, &SequenceJobState::setRotatorAngle, this, &CaptureDeviceAdaptor::setRotatorAngle); 0238 disconnect(this, &CaptureDeviceAdaptor::newRotatorAngle, state, &SequenceJobState::setCurrentRotatorPositionAngle); 0239 } 0240 0241 void CaptureDeviceAdaptor::setRotatorAngle(double rawAngle) 0242 { 0243 if (m_ActiveRotator != nullptr && m_ActiveRotator->setAbsoluteAngle(rawAngle)) 0244 { 0245 RotatorUtils::Instance()->initTimeFrame(rawAngle); 0246 qCInfo(KSTARS_EKOS_CAPTURE) << "Setting rotator angle to" << rawAngle << "degrees."; 0247 } 0248 else 0249 qCWarning(KSTARS_EKOS_CAPTURE) << "Setting rotator angle to " << rawAngle 0250 << "failed due to missing or unresponsive rotator."; 0251 } 0252 0253 double CaptureDeviceAdaptor::getRotatorAngle() 0254 { 0255 if (m_ActiveRotator != nullptr) 0256 return m_ActiveRotator->absoluteAngle(); 0257 else 0258 return 0; 0259 } 0260 0261 IPState CaptureDeviceAdaptor::getRotatorAngleState() 0262 { 0263 if (m_ActiveRotator != nullptr) 0264 return m_ActiveRotator->absoluteAngleState(); 0265 else 0266 return IPS_ALERT; 0267 } 0268 0269 void CaptureDeviceAdaptor::reverseRotator(bool toggled) 0270 { 0271 if (m_ActiveRotator != nullptr) 0272 { 0273 m_ActiveRotator->setReversed(toggled); 0274 m_ActiveRotator->setConfig(SAVE_CONFIG); 0275 } 0276 } 0277 0278 void CaptureDeviceAdaptor::readRotatorAngle() 0279 { 0280 if (m_ActiveRotator != nullptr) 0281 emit newRotatorAngle(m_ActiveRotator->absoluteAngle(), m_ActiveRotator->absoluteAngleState()); 0282 } 0283 0284 0285 0286 void CaptureDeviceAdaptor::setActiveCamera(ISD::Camera *device) 0287 { 0288 if (m_ActiveCamera == device) 0289 return; 0290 0291 // disconnect device events if the new device is not empty 0292 if (m_ActiveCamera != nullptr) 0293 { 0294 m_ActiveCamera->disconnect(this); 0295 disconnectActiveCamera(currentSequenceJobState.data()); 0296 0297 } 0298 0299 // store the link to the new device 0300 m_ActiveCamera = device; 0301 0302 // connect device events if the new device is not empty 0303 if (m_ActiveCamera != nullptr) 0304 { 0305 // publish device events 0306 connect(m_ActiveCamera, &ISD::Camera::newTemperatureValue, this, 0307 &CaptureDeviceAdaptor::newCCDTemperatureValue, Qt::UniqueConnection); 0308 connect(m_ActiveCamera, &ISD::ConcreteDevice::Connected, this, [this]() 0309 { 0310 emit CameraConnected(true); 0311 }); 0312 connect(m_ActiveCamera, &ISD::ConcreteDevice::Disconnected, this, [this]() 0313 { 0314 emit CameraConnected(false); 0315 }); 0316 0317 if (m_ActiveCamera->hasGuideHead()) 0318 addGuideHead(device); 0319 } 0320 connectActiveCamera(currentSequenceJobState.data()); 0321 0322 // communicate new camera 0323 emit newCamera(device == nullptr ? "" : device->getDeviceName()); 0324 } 0325 0326 void CaptureDeviceAdaptor::setFilterWheel(ISD::FilterWheel *device) 0327 { 0328 if (m_ActiveFilterWheel == device) 0329 return; 0330 0331 // disconnect device events if the new device is not empty 0332 if (m_ActiveFilterWheel != nullptr) 0333 m_ActiveFilterWheel->disconnect(this); 0334 0335 // store the link to the new device 0336 m_ActiveFilterWheel = device; 0337 0338 // connect device events if the new device is not empty 0339 if (m_ActiveFilterWheel != nullptr) 0340 { 0341 connect(m_ActiveFilterWheel, &ISD::ConcreteDevice::Connected, this, [this]() 0342 { 0343 emit FilterWheelConnected(true); 0344 }); 0345 connect(m_ActiveFilterWheel, &ISD::ConcreteDevice::Disconnected, this, [this]() 0346 { 0347 emit FilterWheelConnected(false); 0348 }); 0349 } 0350 0351 // communicate new device 0352 emit newFilterWheel(device == nullptr ? "" : device->getDeviceName()); 0353 } 0354 0355 void CaptureDeviceAdaptor::connectActiveCamera(SequenceJobState *state) 0356 { 0357 if (state == nullptr) 0358 return; 0359 0360 //connect state machine to device adaptor 0361 connect(state, &SequenceJobState::setCCDTemperature, this, &CaptureDeviceAdaptor::setCCDTemperature); 0362 connect(state, &SequenceJobState::setCCDBatchMode, this, &CaptureDeviceAdaptor::enableCCDBatchMode); 0363 connect(state, &SequenceJobState::queryHasShutter, this, &CaptureDeviceAdaptor::queryHasShutter); 0364 0365 // forward own events to the state machine 0366 connect(this, &CaptureDeviceAdaptor::flatSyncFocusChanged, state, &SequenceJobState::flatSyncFocusChanged); 0367 connect(this, &CaptureDeviceAdaptor::hasShutter, state, &SequenceJobState::hasShutter); 0368 connect(this, &CaptureDeviceAdaptor::newCCDTemperatureValue, state, &SequenceJobState::setCurrentCCDTemperature, 0369 Qt::UniqueConnection); 0370 } 0371 0372 void CaptureDeviceAdaptor::disconnectActiveCamera(SequenceJobState *state) 0373 { 0374 if (state == nullptr) 0375 return; 0376 0377 disconnect(state, &SequenceJobState::setCCDTemperature, this, &CaptureDeviceAdaptor::setCCDTemperature); 0378 disconnect(state, &SequenceJobState::setCCDBatchMode, this, &CaptureDeviceAdaptor::enableCCDBatchMode); 0379 disconnect(state, &SequenceJobState::queryHasShutter, this, &CaptureDeviceAdaptor::queryHasShutter); 0380 0381 disconnect(this, &CaptureDeviceAdaptor::flatSyncFocusChanged, state, &SequenceJobState::flatSyncFocusChanged); 0382 disconnect(this, &CaptureDeviceAdaptor::hasShutter, state, &SequenceJobState::hasShutter); 0383 disconnect(this, &CaptureDeviceAdaptor::newCCDTemperatureValue, state, &SequenceJobState::setCurrentCCDTemperature); 0384 } 0385 0386 void CaptureDeviceAdaptor::connectFilterManager(SequenceJobState *state) 0387 { 0388 if (state == nullptr) 0389 return; 0390 0391 connect(state, &SequenceJobState::changeFilterPosition, this, &CaptureDeviceAdaptor::setFilterPosition); 0392 connect(state, &SequenceJobState::readFilterPosition, this, &CaptureDeviceAdaptor::updateFilterPosition); 0393 connect(this, &CaptureDeviceAdaptor::filterIdChanged, state, &SequenceJobState::setCurrentFilterID); 0394 0395 if (m_FilterManager.isNull() == false) 0396 connect(m_FilterManager.get(), &FilterManager::newStatus, state, &SequenceJobState::setFilterStatus); 0397 } 0398 0399 void CaptureDeviceAdaptor::disconnectFilterManager(SequenceJobState *state) 0400 { 0401 if (state == nullptr) 0402 return; 0403 0404 disconnect(state, &SequenceJobState::readFilterPosition, this, &CaptureDeviceAdaptor::updateFilterPosition); 0405 disconnect(state, &SequenceJobState::changeFilterPosition, this, &CaptureDeviceAdaptor::setFilterPosition); 0406 disconnect(this, &CaptureDeviceAdaptor::filterIdChanged, state, &SequenceJobState::setCurrentFilterID); 0407 0408 if (m_FilterManager.isNull() == false) 0409 disconnect(m_FilterManager.get(), &FilterManager::newStatus, state, &SequenceJobState::setFilterStatus); 0410 } 0411 0412 void Ekos::CaptureDeviceAdaptor::updateFilterPosition() 0413 { 0414 if (m_FilterManager.isNull()) 0415 { 0416 qCritical(KSTARS_EKOS_CAPTURE) << "Filter manager is not initilized yet. Filter wheel missing from train?"; 0417 emit filterIdChanged(-1); 0418 } 0419 else 0420 emit filterIdChanged(m_FilterManager->getFilterPosition()); 0421 } 0422 0423 void CaptureDeviceAdaptor::readCurrentState(CaptureState state) 0424 { 0425 switch(state) 0426 { 0427 case CAPTURE_SETTING_TEMPERATURE: 0428 if (m_ActiveCamera != nullptr) 0429 { 0430 double currentTemperature; 0431 m_ActiveCamera->getTemperature(¤tTemperature); 0432 emit newCCDTemperatureValue(currentTemperature); 0433 } 0434 break; 0435 case CAPTURE_SETTING_ROTATOR: 0436 readRotatorAngle(); 0437 break; 0438 case CAPTURE_GUIDER_DRIFT: 0439 // intentionally left empty since the guider regularly updates the drift 0440 break; 0441 default: 0442 // this should not happen! 0443 qWarning(KSTARS_EKOS_CAPTURE) << "Reading device state " << state << " not implemented!"; 0444 break; 0445 } 0446 } 0447 0448 void CaptureDeviceAdaptor::setCCDTemperature(double temp) 0449 { 0450 if (m_ActiveCamera != nullptr) 0451 m_ActiveCamera->setTemperature(temp); 0452 } 0453 0454 void CaptureDeviceAdaptor::enableCCDBatchMode(bool enable) 0455 { 0456 if (m_ActiveChip != nullptr) 0457 m_ActiveChip->setBatchMode(enable); 0458 } 0459 0460 void CaptureDeviceAdaptor::abortFastExposure() 0461 { 0462 if (m_ActiveCamera != nullptr && m_ActiveChip != nullptr && m_ActiveCamera->isFastExposureEnabled()) 0463 m_ActiveChip->abortExposure(); 0464 } 0465 0466 double CaptureDeviceAdaptor::cameraGain(QMap<QString, QMap<QString, QVariant> > propertyMap) 0467 { 0468 if (getActiveCamera()) 0469 { 0470 // derive attributes from active camera 0471 if (getActiveCamera()->getProperty("CCD_GAIN")) 0472 return propertyMap["CCD_GAIN"].value("GAIN", -1).toDouble(); 0473 else if (getActiveCamera()->getProperty("CCD_CONTROLS")) 0474 return propertyMap["CCD_CONTROLS"].value("Gain", -1).toDouble(); 0475 } 0476 else // no active camera set, e.g. whien used from the scheduler 0477 { 0478 // if camera is unknown, use the custom property that is set 0479 if (propertyMap.keys().contains("CCD_GAIN")) 0480 return propertyMap["CCD_GAIN"].value("GAIN", -1).toDouble(); 0481 else if(propertyMap.keys().contains("CCD_CONTROLS")) 0482 return propertyMap["CCD_CONTROLS"].value("Gain", -1).toDouble(); 0483 } 0484 0485 // none found 0486 return -1; 0487 0488 } 0489 0490 double CaptureDeviceAdaptor::cameraGain() 0491 { 0492 double value = INVALID_VALUE; 0493 if (getActiveCamera() != nullptr) 0494 getActiveCamera()->getGain(&value); 0495 0496 return value; 0497 } 0498 0499 double CaptureDeviceAdaptor::cameraOffset(QMap<QString, QMap<QString, QVariant> > propertyMap) 0500 { 0501 if (getActiveCamera()) 0502 { 0503 if (getActiveCamera()->getProperty("CCD_OFFSET")) 0504 return propertyMap["CCD_OFFSET"].value("OFFSET", -1).toDouble(); 0505 else if (getActiveCamera()->getProperty("CCD_CONTROLS")) 0506 return propertyMap["CCD_CONTROLS"].value("Offset", -1).toDouble(); 0507 } 0508 else 0509 { 0510 // if camera is unknown, use the custom property that is set 0511 if (propertyMap.keys().contains("CCD_OFFSET")) 0512 return propertyMap["CCD_OFFSET"].value("OFFSET", -1).toDouble(); 0513 else if(propertyMap.keys().contains("CCD_CONTROLS")) 0514 return propertyMap["CCD_CONTROLS"].value("Offset", -1).toDouble(); 0515 } 0516 return -1; 0517 } 0518 0519 double CaptureDeviceAdaptor::cameraOffset() 0520 { 0521 double value = INVALID_VALUE; 0522 if (getActiveCamera() != nullptr) 0523 getActiveCamera()->getOffset(&value); 0524 0525 return value; 0526 } 0527 0528 double CaptureDeviceAdaptor::cameraTemperature() 0529 { 0530 double value = INVALID_VALUE; 0531 if (getActiveCamera() != nullptr) 0532 getActiveCamera()->getTemperature(&value); 0533 0534 return value; 0535 } 0536 0537 void CaptureDeviceAdaptor::setFilterPosition(int targetFilterPosition, FilterManager::FilterPolicy policy) 0538 { 0539 if (m_FilterManager.isNull() == false && m_ActiveFilterWheel != nullptr) 0540 m_FilterManager->setFilterPosition(targetFilterPosition, policy); 0541 } 0542 0543 0544 0545 0546 0547 void CaptureDeviceAdaptor::setFilterManager(QSharedPointer<FilterManager> device) 0548 { 0549 // avoid doubled definition 0550 if (m_FilterManager == device) 0551 return; 0552 0553 // disconnect old filter manager 0554 if (m_FilterManager.isNull() == false) 0555 { 0556 disconnect(m_FilterManager.get(), &FilterManager::ready, this, &CaptureDeviceAdaptor::updateFilterPosition); 0557 disconnectFilterManager(currentSequenceJobState.data()); 0558 } 0559 //connect new filter manager 0560 if (device.isNull() == false) 0561 { 0562 connect(device.get(), &FilterManager::ready, this, &CaptureDeviceAdaptor::updateFilterPosition); 0563 connectFilterManager(currentSequenceJobState.data()); 0564 } 0565 0566 m_FilterManager = device; 0567 } 0568 0569 void CaptureDeviceAdaptor::askManualScopeCover(QString question, QString title, bool light) 0570 { 0571 // do not ask again 0572 if (light && m_ManualLightCoveringAsked == true) 0573 { 0574 emit manualScopeCoverUpdated(true, true, true); 0575 return; 0576 } 0577 else if (!light && m_ManualDarkCoveringAsked == true) 0578 { 0579 emit manualScopeCoverUpdated(true, true, false); 0580 return; 0581 } 0582 0583 // Continue 0584 connect(KSMessageBox::Instance(), &KSMessageBox::accepted, this, [this, light]() 0585 { 0586 emit manualScopeCoverUpdated(true, true, light); 0587 KSMessageBox::Instance()->disconnect(this); 0588 m_ManualLightCoveringAsked = false; 0589 m_ManualLightOpeningAsked = false; 0590 m_ManualDarkCoveringAsked = false; 0591 m_ManualDarkOpeningAsked = false; 0592 if (light) 0593 m_ManualLightCoveringAsked = true; 0594 else 0595 m_ManualDarkCoveringAsked = true; 0596 }); 0597 0598 // Cancel 0599 connect(KSMessageBox::Instance(), &KSMessageBox::rejected, this, [this, light]() 0600 { 0601 if (light) 0602 m_ManualLightCoveringAsked = false; 0603 else 0604 m_ManualDarkCoveringAsked = false; 0605 0606 emit manualScopeCoverUpdated(true, false, light); 0607 KSMessageBox::Instance()->disconnect(this); 0608 }); 0609 0610 KSMessageBox::Instance()->warningContinueCancel(question, title, Options::manualCoverTimeout()); 0611 0612 } 0613 0614 void CaptureDeviceAdaptor::askManualScopeOpen(bool light) 0615 { 0616 // do not ask again 0617 if (light && m_ManualLightOpeningAsked == true) 0618 { 0619 emit manualScopeCoverUpdated(false, true, true); 0620 return; 0621 } 0622 else if (!light && m_ManualDarkOpeningAsked == true) 0623 { 0624 emit manualScopeCoverUpdated(false, true, false); 0625 return; 0626 } 0627 0628 // Continue 0629 connect(KSMessageBox::Instance(), &KSMessageBox::accepted, this, [this, light]() 0630 { 0631 m_ManualLightCoveringAsked = false; 0632 m_ManualLightOpeningAsked = false; 0633 m_ManualDarkCoveringAsked = false; 0634 m_ManualDarkOpeningAsked = false; 0635 0636 if (light) 0637 m_ManualLightOpeningAsked = true; 0638 else 0639 m_ManualDarkOpeningAsked = true; 0640 0641 emit manualScopeCoverUpdated(false, true, light); 0642 KSMessageBox::Instance()->disconnect(this); 0643 }); 0644 0645 // Cancel 0646 connect(KSMessageBox::Instance(), &KSMessageBox::rejected, this, [this, light]() 0647 { 0648 if (light) 0649 m_ManualLightOpeningAsked = false; 0650 else 0651 m_ManualDarkOpeningAsked = false; 0652 emit manualScopeCoverUpdated(false, false, light); 0653 KSMessageBox::Instance()->disconnect(this); 0654 }); 0655 0656 KSMessageBox::Instance()->warningContinueCancel(i18n("Remove cover from the telescope in order to continue."), 0657 i18n("Telescope Covered"), Options::manualCoverTimeout()); 0658 0659 } 0660 0661 void CaptureDeviceAdaptor::setLightBoxLight(bool on) 0662 { 0663 m_ActiveLightBox->setLightEnabled(on); 0664 emit lightBoxLight(on); 0665 } 0666 0667 void CaptureDeviceAdaptor::parkDustCap(bool park) 0668 { 0669 // park 0670 if (park == true) 0671 if (m_ActiveDustCap->park()) 0672 emit dustCapStatusChanged(ISD::DustCap::CAP_PARKING); 0673 else 0674 emit dustCapStatusChanged(ISD::DustCap::CAP_ERROR); 0675 // unpark 0676 else if (m_ActiveDustCap->unpark()) 0677 emit dustCapStatusChanged(ISD::DustCap::CAP_UNPARKING); 0678 else 0679 emit dustCapStatusChanged(ISD::DustCap::CAP_ERROR); 0680 } 0681 0682 void CaptureDeviceAdaptor::slewTelescope(SkyPoint &target) 0683 { 0684 if (m_ActiveMount != nullptr) 0685 { 0686 m_ActiveMount->Slew(&target); 0687 emit scopeStatusChanged(ISD::Mount::MOUNT_SLEWING); 0688 } 0689 } 0690 0691 void CaptureDeviceAdaptor::setScopeTracking(bool on) 0692 { 0693 if (m_ActiveMount != nullptr) 0694 { 0695 m_ActiveMount->setTrackEnabled(on); 0696 emit scopeStatusChanged(on ? ISD::Mount::MOUNT_TRACKING : ISD::Mount::MOUNT_IDLE); 0697 } 0698 } 0699 0700 void CaptureDeviceAdaptor::setScopeParked(bool parked) 0701 { 0702 if (m_ActiveMount != nullptr) 0703 { 0704 if (parked == true) 0705 { 0706 if (m_ActiveMount->park()) 0707 emit scopeStatusChanged(ISD::Mount::MOUNT_PARKING); 0708 else 0709 emit scopeStatusChanged(ISD::Mount::MOUNT_ERROR); 0710 } 0711 else 0712 { 0713 if (m_ActiveMount->unpark() == false) 0714 emit scopeStatusChanged(ISD::Mount::MOUNT_ERROR); 0715 } 0716 } 0717 } 0718 0719 void CaptureDeviceAdaptor::setDomeParked(bool parked) 0720 { 0721 if (m_ActiveDome != nullptr) 0722 { 0723 if (parked == true) 0724 { 0725 if (m_ActiveDome->park()) 0726 emit domeStatusChanged(ISD::Dome::DOME_PARKING); 0727 else 0728 emit domeStatusChanged(ISD::Dome::DOME_ERROR); 0729 } 0730 else 0731 { 0732 if (m_ActiveDome->unpark() == false) 0733 emit domeStatusChanged(ISD::Dome::DOME_ERROR); 0734 } 0735 } 0736 0737 } 0738 0739 void CaptureDeviceAdaptor::flatSyncFocus(int targetFilterID) 0740 { 0741 if (getFilterManager()->syncAbsoluteFocusPosition(targetFilterID - 1)) 0742 emit flatSyncFocusChanged(true); 0743 else 0744 emit flatSyncFocusChanged(false); 0745 } 0746 0747 void CaptureDeviceAdaptor::queryHasShutter() 0748 { 0749 if (m_ActiveCamera == nullptr) 0750 { 0751 emit hasShutter(false); 0752 return; 0753 } 0754 QStringList shutterfulCCDs = Options::shutterfulCCDs(); 0755 QStringList shutterlessCCDs = Options::shutterlessCCDs(); 0756 QString deviceName = m_ActiveCamera->getDeviceName(); 0757 0758 bool shutterFound = shutterfulCCDs.contains(deviceName); 0759 // FIXME: what about || (captureISOS && captureISOS->count() > 0? 0760 bool noShutterFound = shutterlessCCDs.contains(deviceName); 0761 0762 if (shutterFound == true) 0763 emit hasShutter(true); 0764 else if (noShutterFound == true) 0765 emit hasShutter(false); 0766 else 0767 { 0768 // If we have no information, we ask before we proceed. 0769 QString deviceName = m_ActiveCamera->getDeviceName(); 0770 // Yes, has shutter 0771 connect(KSMessageBox::Instance(), &KSMessageBox::accepted, this, [this]() 0772 { 0773 KSMessageBox::Instance()->disconnect(this); 0774 QStringList shutterfulCCDs = Options::shutterfulCCDs(); 0775 shutterfulCCDs.append(m_ActiveCamera->getDeviceName()); 0776 Options::setShutterfulCCDs(shutterfulCCDs); 0777 emit hasShutter(true); 0778 }); 0779 // No, has no shutter 0780 connect(KSMessageBox::Instance(), &KSMessageBox::rejected, this, [this]() 0781 { 0782 KSMessageBox::Instance()->disconnect(this); 0783 QStringList shutterlessCCDs = Options::shutterlessCCDs(); 0784 shutterlessCCDs.append(m_ActiveCamera->getDeviceName()); 0785 Options::setShutterlessCCDs(shutterlessCCDs); 0786 emit hasShutter(false); 0787 }); 0788 0789 KSMessageBox::Instance()->questionYesNo(i18n("Does %1 have a shutter?", deviceName), 0790 i18n("Dark Exposure")); 0791 } 0792 } 0793 0794 } // namespace