13 #include <unordered_map>
15 #include <mx/app/application.hpp>
17 #include "../MagAOXApp.hpp"
26 #define CAMCTRL_E_NOCONFIGS (-10)
52 mx::app::appConfigurator & config
285 template<
class derivedT>
642 const pcf::IndiProperty &
ipRecv
771 int setFPS( const mx::meta::trueFalseT<true> & t );
777 int setFPS( const mx::meta::trueFalseT<false> & f );
958 const mx::meta::trueFalseT<true> & t
966 const mx::meta::trueFalseT<false> & f
1022 return *
static_cast<derivedT *
>(
this);
1026 template<
class derivedT>
1034 template<
class derivedT>
1037 if(derivedT::c_stdCamera_tempControl)
1039 config.add(
"camera.startupTemp",
"",
"camera.startupTemp", argType::Required,
"camera",
"startupTemp",
false,
"float",
"The temperature setpoint to set after a power-on [C]. Default is 20 C.");
1042 if(derivedT::c_stdCamera_readoutSpeed)
1044 config.add(
"camera.defaultReadoutSpeed",
"",
"camera.defaultReadoutSpeed", argType::Required,
"camera",
"defaultReadoutSpeed",
false,
"string",
"The default amplifier and readout speed.");
1047 if(derivedT::c_stdCamera_vShiftSpeed)
1049 config.add(
"camera.defaultVShiftSpeed",
"",
"camera.defaultVShiftSpeed", argType::Required,
"camera",
"defaultVShiftSpeed",
false,
"string",
"The default vertical shift speed.");
1052 if(derivedT::c_stdCamera_emGain)
1054 config.add(
"camera.maxEMGain",
"",
"camera.maxEMGain", argType::Required,
"camera",
"maxEMGain",
false,
"unsigned",
"The maximum EM gain which can be set by the user.");
1057 if(derivedT::c_stdCamera_usesModes)
1059 config.add(
"camera.startupMode",
"",
"camera.startupMode", argType::Required,
"camera",
"startupMode",
false,
"string",
"The mode to set upon power on or application startup.");
1062 if(derivedT::c_stdCamera_usesROI)
1064 config.add(
"camera.default_x",
"",
"camera.default_x", argType::Required,
"camera",
"default_x",
false,
"float",
"The default ROI x position.");
1065 config.add(
"camera.default_y",
"",
"camera.default_y", argType::Required,
"camera",
"default_y",
false,
"float",
"The default ROI y position.");
1066 config.add(
"camera.default_w",
"",
"camera.default_w", argType::Required,
"camera",
"default_w",
false,
"int",
"The default ROI width.");
1067 config.add(
"camera.default_h",
"",
"camera.default_h", argType::Required,
"camera",
"default_h",
false,
"int",
"The default ROI height.");
1068 config.add(
"camera.default_bin_x",
"",
"camera.default_bin_x", argType::Required,
"camera",
"default_bin_x",
false,
"int",
"The default ROI x binning.");
1069 config.add(
"camera.default_bin_y",
"",
"camera.default_bin_y", argType::Required,
"camera",
"default_bin_y",
false,
"int",
"The default ROI y binning.");
1073 template<
class derivedT>
1076 if(derivedT::c_stdCamera_tempControl)
1078 config(m_startupTemp,
"camera.startupTemp");
1081 if(derivedT::c_stdCamera_readoutSpeed)
1083 config(m_defaultReadoutSpeed,
"camera.defaultReadoutSpeed");
1086 if(derivedT::c_stdCamera_vShiftSpeed)
1088 config(m_defaultVShiftSpeed,
"camera.defaultVShiftSpeed");
1091 if(derivedT::c_stdCamera_emGain)
1093 config(m_maxEMGain,
"camera.maxEMGain");
1096 if(derivedT::c_stdCamera_usesModes)
1108 config(m_startupMode,
"camera.startupMode");
1112 if(derivedT::c_stdCamera_usesROI)
1114 config(m_default_x,
"camera.default_x");
1115 config(m_default_y,
"camera.default_y");
1116 config(m_default_w,
"camera.default_w");
1117 config(m_default_h,
"camera.default_h");
1118 config(m_default_bin_x,
"camera.default_bin_x");
1119 config(m_default_bin_y,
"camera.default_bin_y");
1123 template<
class derivedT>
1126 static_cast<void>(t);
1128 derived().createStandardIndiSelectionSw(m_indiP_readoutSpeed,
"readout_speed", m_readoutSpeedNames,
"Readout Speed");
1131 if(m_readoutSpeedNameLabels.size() == m_readoutSpeedNames.size())
1133 for(
size_t n=0; n< m_readoutSpeedNames.size(); ++n) m_indiP_readoutSpeed[m_readoutSpeedNames[n]].setLabel(m_readoutSpeedNameLabels[n]);
1136 derived().registerIndiPropertyNew(m_indiP_readoutSpeed, st_newCallBack_stdCamera);
1141 template<
class derivedT>
1144 static_cast<void>(f);
1149 template<
class derivedT>
1152 static_cast<void>(t);
1154 derived().createStandardIndiSelectionSw(m_indiP_vShiftSpeed,
"vshift_speed", m_vShiftSpeedNames,
"Vert. Shift Speed");
1156 if(m_vShiftSpeedNameLabels.size() == m_vShiftSpeedNames.size())
1158 for(
size_t n=0; n< m_vShiftSpeedNames.size(); ++n) m_indiP_vShiftSpeed[m_vShiftSpeedNames[n]].setLabel(m_vShiftSpeedNameLabels[n]);
1161 derived().registerIndiPropertyNew(m_indiP_vShiftSpeed, st_newCallBack_stdCamera);
1166 template<
class derivedT>
1169 static_cast<void>(f);
1174 template<
class derivedT>
1178 if(derivedT::c_stdCamera_tempControl)
1181 derived().createStandardIndiNumber( m_indiP_temp,
"temp_ccd", m_minTemp, m_maxTemp, m_stepTemp,
"%0.1f",
"CCD Temperature",
"CCD Temperature");
1182 m_indiP_temp[
"current"].set(m_ccdTemp);
1183 m_indiP_temp[
"target"].set(m_ccdTempSetpt);
1184 if( derived().registerIndiPropertyNew( m_indiP_temp, st_newCallBack_stdCamera) < 0)
1186 #ifndef STDCAMERA_TEST_NOLOG
1187 derivedT::template log<software_error>({__FILE__,__LINE__});
1192 derived().createStandardIndiToggleSw( m_indiP_tempcont,
"temp_controller",
"CCD Temperature",
"Control On/Off");
1193 m_indiP_tempcont[
"toggle"].set(pcf::IndiElement::Off);
1194 if( derived().registerIndiPropertyNew( m_indiP_tempcont, st_newCallBack_stdCamera) < 0)
1196 #ifndef STDCAMERA_TEST_NOLOG
1197 derivedT::template log<software_error>({__FILE__,__LINE__});
1202 derived().createROIndiText( m_indiP_tempstat,
"temp_control",
"status",
"CCD Temperature",
"",
"CCD Temperature");
1203 if( derived().registerIndiPropertyReadOnly( m_indiP_tempstat ) < 0)
1205 #ifndef STDCAMERA_TEST_NOLOG
1206 derivedT::template log<software_error>({__FILE__,__LINE__});
1211 else if(derivedT::c_stdCamera_temp)
1213 derived().createROIndiNumber( m_indiP_temp,
"temp_ccd",
"CCD Temperature",
"CCD Temperature");
1214 m_indiP_temp.add(pcf::IndiElement(
"current"));
1215 m_indiP_temp[
"current"].set(m_ccdTemp);
1216 if( derived().registerIndiPropertyReadOnly( m_indiP_temp) < 0)
1218 #ifndef STDCAMERA_TEST_NOLOG
1219 derivedT::template log<software_error>({__FILE__,__LINE__});
1225 if(derivedT::c_stdCamera_readoutSpeed)
1227 mx::meta::trueFalseT<derivedT::c_stdCamera_readoutSpeed> tf;
1228 if(createReadoutSpeed(tf) < 0)
1230 #ifndef STDCAMERA_TEST_NOLOG
1231 derivedT::template log<software_error>({__FILE__,__LINE__});
1238 if(derivedT::c_stdCamera_vShiftSpeed)
1240 mx::meta::trueFalseT<derivedT::c_stdCamera_vShiftSpeed> tf;
1241 if(createVShiftSpeed(tf) < 0)
1243 #ifndef STDCAMERA_TEST_NOLOG
1244 derivedT::template log<software_error>({__FILE__,__LINE__});
1251 if(derivedT::c_stdCamera_emGain)
1253 derived().createStandardIndiNumber( m_indiP_emGain,
"emgain", 0, 1000, 1,
"%0.3f");
1254 if( derived().registerIndiPropertyNew( m_indiP_emGain, st_newCallBack_stdCamera) < 0)
1256 #ifndef STDCAMERA_TEST_NOLOG
1257 derivedT::template log<software_error>({__FILE__,__LINE__});
1263 if(derivedT::c_stdCamera_exptimeCtrl)
1265 derived().createStandardIndiNumber( m_indiP_exptime,
"exptime", m_minExpTime, m_maxExpTime, m_stepExpTime,
"%0.3f");
1266 if( derived().registerIndiPropertyNew( m_indiP_exptime, st_newCallBack_stdCamera) < 0)
1268 #ifndef STDCAMERA_TEST_NOLOG
1269 derivedT::template log<software_error>({__FILE__,__LINE__});
1275 if(derivedT::c_stdCamera_fpsCtrl)
1277 derived().createStandardIndiNumber( m_indiP_fps,
"fps", m_minFPS, m_maxFPS, m_stepFPS,
"%0.2f");
1278 if( derived().registerIndiPropertyNew( m_indiP_fps, st_newCallBack_stdCamera) < 0)
1280 #ifndef STDCAMERA_TEST_NOLOG
1281 derivedT::template log<software_error>({__FILE__,__LINE__});
1286 else if(derivedT::c_stdCamera_fps)
1288 derived().createROIndiNumber( m_indiP_fps,
"fps");
1289 m_indiP_fps.add(pcf::IndiElement(
"current"));
1290 m_indiP_fps[
"current"].setMin(m_minFPS);
1291 m_indiP_fps[
"current"].setMax(m_maxFPS);
1292 m_indiP_fps[
"current"].setStep(m_stepFPS);
1293 m_indiP_fps[
"current"].setFormat(
"%0.2f");
1295 if( derived().registerIndiPropertyReadOnly( m_indiP_fps ) < 0)
1297 #ifndef STDCAMERA_TEST_NOLOG
1298 derivedT::template log<software_error>({__FILE__,__LINE__});
1304 if(derivedT::c_stdCamera_synchro)
1306 derived().createStandardIndiToggleSw( m_indiP_synchro,
"synchro",
"Synchronization",
"Synchronization");
1307 if( derived().registerIndiPropertyNew( m_indiP_synchro, st_newCallBack_stdCamera) < 0)
1309 #ifndef STDCAMERA_TEST_NOLOG
1310 derivedT::template log<software_error>({__FILE__,__LINE__});
1316 if(derivedT::c_stdCamera_usesModes)
1318 std::vector<std::string> modeNames;
1319 for(
auto it = m_cameraModes.begin();
it!=m_cameraModes.end(); ++
it)
1321 modeNames.push_back(
it->first);
1324 if(derived().createStandardIndiSelectionSw( m_indiP_mode,
"mode", modeNames) < 0)
1326 derivedT::template log<software_critical>({__FILE__, __LINE__});
1329 if( derived().registerIndiPropertyNew( m_indiP_mode, st_newCallBack_stdCamera) < 0)
1331 #ifndef STDCAMERA_TEST_NOLOG
1332 derivedT::template log<software_error>({__FILE__,__LINE__});
1338 derived().createStandardIndiRequestSw( m_indiP_reconfig,
"reconfigure");
1339 if( derived().registerIndiPropertyNew( m_indiP_reconfig, st_newCallBack_stdCamera) < 0)
1341 #ifndef STDCAMERA_TEST_NOLOG
1342 derivedT::template log<software_error>({__FILE__,__LINE__});
1347 if(derivedT::c_stdCamera_usesROI)
1350 derived().createStandardIndiNumber( m_indiP_roi_x,
"roi_region_x", m_minROIx, m_maxROIx, m_stepROIx,
"%0.1f");
1351 if( derived().registerIndiPropertyNew( m_indiP_roi_x, st_newCallBack_stdCamera) < 0)
1353 #ifndef STDCAMERA_TEST_NOLOG
1354 derivedT::template log<software_error>({__FILE__,__LINE__});
1359 derived().createStandardIndiNumber( m_indiP_roi_y,
"roi_region_y", m_minROIy, m_maxROIy, m_stepROIy,
"%0.1f");
1360 if( derived().registerIndiPropertyNew( m_indiP_roi_y, st_newCallBack_stdCamera) < 0)
1362 #ifndef STDCAMERA_TEST_NOLOG
1363 derivedT::template log<software_error>({__FILE__,__LINE__});
1368 derived().createStandardIndiNumber( m_indiP_roi_w,
"roi_region_w", m_minROIWidth, m_maxROIWidth, m_stepROIWidth,
"%d");
1369 if( derived().registerIndiPropertyNew( m_indiP_roi_w, st_newCallBack_stdCamera) < 0)
1371 #ifndef STDCAMERA_TEST_NOLOG
1372 derivedT::template log<software_error>({__FILE__,__LINE__});
1377 derived().createStandardIndiNumber( m_indiP_roi_h,
"roi_region_h", m_minROIHeight, m_maxROIHeight, m_stepROIHeight,
"%d");
1378 if( derived().registerIndiPropertyNew( m_indiP_roi_h, st_newCallBack_stdCamera) < 0)
1380 #ifndef STDCAMERA_TEST_NOLOG
1381 derivedT::template log<software_error>({__FILE__,__LINE__});
1386 derived().createStandardIndiNumber( m_indiP_roi_bin_x,
"roi_region_bin_x", m_minROIBinning_x, m_maxROIBinning_x, m_stepROIBinning_x,
"%f");
1387 if( derived().registerIndiPropertyNew( m_indiP_roi_bin_x, st_newCallBack_stdCamera) < 0)
1389 #ifndef STDCAMERA_TEST_NOLOG
1390 derivedT::template log<software_error>({__FILE__,__LINE__});
1395 derived().createStandardIndiNumber( m_indiP_roi_bin_y,
"roi_region_bin_y", m_minROIBinning_y, m_maxROIBinning_y, m_stepROIBinning_y,
"%f");
1396 if( derived().registerIndiPropertyNew( m_indiP_roi_bin_y, st_newCallBack_stdCamera) < 0)
1398 #ifndef STDCAMERA_TEST_NOLOG
1399 derivedT::template log<software_error>({__FILE__,__LINE__});
1404 derived().createROIndiNumber( m_indiP_fullROI,
"roi_full_region");
1405 m_indiP_fullROI.add(pcf::IndiElement(
"x"));
1406 m_indiP_fullROI[
"x"] = 0;
1407 m_indiP_fullROI.add(pcf::IndiElement(
"y"));
1408 m_indiP_fullROI[
"y"] = 0;
1409 m_indiP_fullROI.add(pcf::IndiElement(
"w"));
1410 m_indiP_fullROI[
"w"] = 0;
1411 m_indiP_fullROI.add(pcf::IndiElement(
"h"));
1412 m_indiP_fullROI[
"h"] = 0;
1413 if( derived().registerIndiPropertyReadOnly( m_indiP_fullROI ) < 0)
1415 #ifndef STDCAMERA_TEST_NOLOG
1416 derivedT::template log<software_error>({__FILE__,__LINE__});
1421 derived().createStandardIndiRequestSw( m_indiP_roi_check,
"roi_region_check");
1422 if( derived().registerIndiPropertyNew( m_indiP_roi_check, st_newCallBack_stdCamera) < 0)
1424 #ifndef STDCAMERA_TEST_NOLOG
1425 derivedT::template log<software_error>({__FILE__,__LINE__});
1430 derived().createStandardIndiRequestSw( m_indiP_roi_set,
"roi_set");
1431 if( derived().registerIndiPropertyNew( m_indiP_roi_set, st_newCallBack_stdCamera) < 0)
1433 #ifndef STDCAMERA_TEST_NOLOG
1434 derivedT::template log<software_error>({__FILE__,__LINE__});
1439 derived().createStandardIndiRequestSw( m_indiP_roi_full,
"roi_set_full");
1440 if( derived().registerIndiPropertyNew( m_indiP_roi_full, st_newCallBack_stdCamera) < 0)
1442 #ifndef STDCAMERA_TEST_NOLOG
1443 derivedT::template log<software_error>({__FILE__,__LINE__});
1448 derived().createStandardIndiRequestSw( m_indiP_roi_fullbin,
"roi_set_full_bin");
1449 if( derived().registerIndiPropertyNew( m_indiP_roi_fullbin, st_newCallBack_stdCamera) < 0)
1451 #ifndef STDCAMERA_TEST_NOLOG
1452 derivedT::template log<software_error>({__FILE__,__LINE__});
1457 derived().createStandardIndiRequestSw( m_indiP_roi_loadlast,
"roi_load_last");
1458 if( derived().registerIndiPropertyNew( m_indiP_roi_loadlast, st_newCallBack_stdCamera) < 0)
1460 #ifndef STDCAMERA_TEST_NOLOG
1461 derivedT::template log<software_error>({__FILE__,__LINE__});
1466 derived().createStandardIndiRequestSw( m_indiP_roi_last,
"roi_set_last");
1467 if( derived().registerIndiPropertyNew( m_indiP_roi_last, st_newCallBack_stdCamera) < 0)
1469 #ifndef STDCAMERA_TEST_NOLOG
1470 derivedT::template log<software_error>({__FILE__,__LINE__});
1475 derived().createStandardIndiRequestSw( m_indiP_roi_default,
"roi_set_default");
1476 if( derived().registerIndiPropertyNew( m_indiP_roi_default, st_newCallBack_stdCamera) < 0)
1478 #ifndef STDCAMERA_TEST_NOLOG
1479 derivedT::template log<software_error>({__FILE__,__LINE__});
1485 if(derivedT::c_stdCamera_cropMode)
1487 derived().createStandardIndiToggleSw( m_indiP_cropMode,
"roi_crop_mode",
"Crop Mode",
"Crop Mode");
1488 if( derived().registerIndiPropertyNew( m_indiP_cropMode, st_newCallBack_stdCamera) < 0)
1490 #ifndef STDCAMERA_TEST_NOLOG
1491 derivedT::template log<software_error>({__FILE__,__LINE__});
1498 if(derivedT::c_stdCamera_hasShutter)
1500 derived().createROIndiText( m_indiP_shutterStatus,
"shutter_status",
"status",
"Shutter Status",
"Shutter",
"Status");
1501 m_indiP_shutterStatus[
"status"] = m_shutterStatus;
1502 if( derived().registerIndiPropertyReadOnly( m_indiP_shutterStatus ) < 0)
1504 #ifndef STDCAMERA_TEST_NOLOG
1505 derivedT::template log<software_error>({__FILE__,__LINE__});
1510 derived().createStandardIndiToggleSw( m_indiP_shutter,
"shutter",
"Shutter",
"Shutter");
1511 if( derived().registerIndiPropertyNew( m_indiP_shutter, st_newCallBack_stdCamera) < 0)
1513 #ifndef STDCAMERA_TEST_NOLOG
1514 derivedT::template log<software_error>({__FILE__,__LINE__});
1521 if(derivedT::c_stdCamera_usesStateString)
1523 derived().createROIndiText( m_indiP_stateString,
"state_string",
"current",
"State String",
"State",
"String");
1524 m_indiP_stateString.add(pcf::IndiElement(
"valid"));
1525 m_indiP_stateString[
"valid"] =
"no";
1526 if( derived().registerIndiPropertyReadOnly( m_indiP_stateString ) < 0)
1528 #ifndef STDCAMERA_TEST_NOLOG
1529 derivedT::template log<software_error>({__FILE__,__LINE__});
1538 template<
class derivedT>
1543 if(derived().powerOnWaitElapsed())
1548 derived().powerOnDefaults();
1550 if(derivedT::c_stdCamera_tempControl)
1553 if(m_startupTemp > -999) m_ccdTempSetpt = m_startupTemp;
1554 derived().updateIfChanged(m_indiP_temp,
"target", m_ccdTempSetpt,
INDI_IDLE);
1557 if(derivedT::c_stdCamera_usesROI)
1560 m_nextROI.x = m_currentROI.x;
1561 m_nextROI.y = m_currentROI.y;
1562 m_nextROI.w = m_currentROI.w;
1563 m_nextROI.h = m_currentROI.h;
1564 m_nextROI.bin_x = m_currentROI.bin_x;
1565 m_nextROI.bin_y = m_currentROI.bin_y;
1567 derived().updateIfChanged(m_indiP_roi_x,
"current", m_currentROI.x,
INDI_IDLE);
1568 derived().updateIfChanged(m_indiP_roi_x,
"target", m_nextROI.x,
INDI_IDLE);
1570 derived().updateIfChanged(m_indiP_roi_y,
"current", m_currentROI.y,
INDI_IDLE);
1571 derived().updateIfChanged(m_indiP_roi_y,
"target", m_nextROI.y,
INDI_IDLE);
1573 derived().updateIfChanged(m_indiP_roi_w,
"current", m_currentROI.w,
INDI_IDLE);
1574 derived().updateIfChanged(m_indiP_roi_w,
"target", m_nextROI.w,
INDI_IDLE);
1576 derived().updateIfChanged(m_indiP_roi_h,
"current", m_currentROI.h,
INDI_IDLE);
1577 derived().updateIfChanged(m_indiP_roi_h,
"target", m_nextROI.h,
INDI_IDLE);
1579 derived().updateIfChanged(m_indiP_roi_bin_x,
"current", m_currentROI.bin_x,
INDI_IDLE);
1580 derived().updateIfChanged(m_indiP_roi_bin_x,
"target", m_nextROI.bin_x,
INDI_IDLE);
1582 derived().updateIfChanged(m_indiP_roi_bin_y,
"current", m_currentROI.bin_y,
INDI_IDLE);
1583 derived().updateIfChanged(m_indiP_roi_bin_y,
"target", m_nextROI.bin_y,
INDI_IDLE);
1586 if(derivedT::c_stdCamera_hasShutter)
1588 if(m_shutterStatus ==
"OPERATING")
1590 derived().updateIfChanged(m_indiP_shutterStatus,
"status", m_shutterStatus,
INDI_BUSY);
1592 if(m_shutterStatus ==
"POWERON" || m_shutterStatus ==
"READY")
1594 derived().updateIfChanged(m_indiP_shutterStatus,
"status", m_shutterStatus,
INDI_OK);
1598 derived().updateIfChanged(m_indiP_shutterStatus,
"status", m_shutterStatus,
INDI_IDLE);
1601 if(m_shutterState == 1)
1603 derived().updateSwitchIfChanged(m_indiP_shutter,
"toggle", pcf::IndiElement::On,
INDI_OK);
1607 derived().updateSwitchIfChanged(m_indiP_shutter,
"toggle", pcf::IndiElement::Off,
INDI_IDLE);
1620 if(derivedT::c_stdCamera_usesROI)
1622 derived().updateIfChanged(m_indiP_roi_x,
"current", m_currentROI.x,
INDI_IDLE);
1623 derived().updateIfChanged(m_indiP_roi_x,
"target", m_nextROI.x,
INDI_IDLE);
1625 derived().updateIfChanged(m_indiP_roi_y,
"current", m_currentROI.y,
INDI_IDLE);
1626 derived().updateIfChanged(m_indiP_roi_y,
"target", m_nextROI.y,
INDI_IDLE);
1628 derived().updateIfChanged(m_indiP_roi_w,
"current", m_currentROI.w,
INDI_IDLE);
1629 derived().updateIfChanged(m_indiP_roi_w,
"target", m_nextROI.w,
INDI_IDLE);
1631 derived().updateIfChanged(m_indiP_roi_h,
"current", m_currentROI.h,
INDI_IDLE);
1632 derived().updateIfChanged(m_indiP_roi_h,
"target", m_nextROI.h,
INDI_IDLE);
1634 derived().updateIfChanged(m_indiP_roi_bin_x,
"current", m_currentROI.bin_x,
INDI_IDLE);
1635 derived().updateIfChanged(m_indiP_roi_bin_x,
"target", m_nextROI.bin_x,
INDI_IDLE);
1637 derived().updateIfChanged(m_indiP_roi_bin_y,
"current", m_currentROI.bin_y,
INDI_IDLE);
1638 derived().updateIfChanged(m_indiP_roi_bin_y,
"target", m_nextROI.bin_y,
INDI_IDLE);
1646 template<
class derivedT>
1649 if( !derived().m_indiDriver )
return 0;
1651 if(derivedT::c_stdCamera_usesModes)
1653 for(
auto it = m_cameraModes.begin();
it!=m_cameraModes.end();++
it)
1655 derived().updateSwitchIfChanged(m_indiP_mode,
it->first, pcf::IndiElement::Off,
INDI_IDLE);
1659 if(derivedT::c_stdCamera_usesROI)
1681 if(derivedT::c_stdCamera_hasShutter)
1683 if(m_shutterStatus ==
"OPERATING")
1685 derived().updateIfChanged(m_indiP_shutterStatus,
"status", m_shutterStatus,
INDI_BUSY);
1687 if(m_shutterStatus ==
"POWERON" || m_shutterStatus ==
"READY")
1689 derived().updateIfChanged(m_indiP_shutterStatus,
"status", m_shutterStatus,
INDI_OK);
1693 derived().updateIfChanged(m_indiP_shutterStatus,
"status", m_shutterStatus,
INDI_IDLE);
1696 if(m_shutterState == 0)
1698 derived().updateSwitchIfChanged(m_indiP_shutter,
"toggle", pcf::IndiElement::On,
INDI_OK);
1702 derived().updateSwitchIfChanged(m_indiP_shutter,
"toggle", pcf::IndiElement::Off,
INDI_IDLE);
1709 template<
class derivedT>
1713 if(derivedT::c_stdCamera_hasShutter)
1715 if(m_shutterStatus ==
"OPERATING")
1717 derived().updateIfChanged(m_indiP_shutterStatus,
"status", m_shutterStatus,
INDI_BUSY);
1719 if(m_shutterStatus ==
"POWERON" || m_shutterStatus ==
"READY")
1721 derived().updateIfChanged(m_indiP_shutterStatus,
"status", m_shutterStatus,
INDI_OK);
1725 derived().updateIfChanged(m_indiP_shutterStatus,
"status", m_shutterStatus,
INDI_IDLE);
1728 if(m_shutterState == 0)
1730 derived().updateSwitchIfChanged(m_indiP_shutter,
"toggle", pcf::IndiElement::On,
INDI_OK);
1734 derived().updateSwitchIfChanged(m_indiP_shutter,
"toggle", pcf::IndiElement::Off,
INDI_IDLE);
1741 template<
class derivedT>
1748 template<
class derivedT>
1750 const pcf::IndiProperty &
ipRecv
1753 derivedT * _app =
static_cast<derivedT *
>(app);
1754 return _app->newCallBack_stdCamera(
ipRecv);
1757 template<
class derivedT>
1761 if(
ipRecv.getDevice() != derived().configName())
1763 #ifndef XWCTEST_INDI_CALLBACK_VALIDATION
1764 derivedT::template log<software_error>({__FILE__, __LINE__,
"unknown INDI property"});
1770 std::string name =
ipRecv.getName();
1772 if( name ==
"reconfigure")
return newCallBack_reconfigure(
ipRecv);
1773 else if(derivedT::c_stdCamera_temp && name ==
"temp_ccd")
return newCallBack_temp(
ipRecv);
1774 else if(derivedT::c_stdCamera_tempControl && name ==
"temp_ccd")
return newCallBack_temp(
ipRecv);
1775 else if(derivedT::c_stdCamera_tempControl && name ==
"temp_controller")
return newCallBack_temp_controller(
ipRecv);
1776 else if(derivedT::c_stdCamera_readoutSpeed && name ==
"readout_speed")
return newCallBack_readoutSpeed(
ipRecv);
1777 else if(derivedT::c_stdCamera_vShiftSpeed && name ==
"vshift_speed")
return newCallBack_vShiftSpeed(
ipRecv);
1778 else if(derivedT::c_stdCamera_emGain && name ==
"emgain")
return newCallBack_emgain(
ipRecv);
1779 else if(derivedT::c_stdCamera_exptimeCtrl && name ==
"exptime")
return newCallBack_exptime(
ipRecv);
1780 else if(derivedT::c_stdCamera_fpsCtrl && name ==
"fps")
return newCallBack_fps(
ipRecv);
1781 else if(derivedT::c_stdCamera_synchro && name ==
"synchro")
return newCallBack_synchro(
ipRecv);
1782 else if(derivedT::c_stdCamera_usesModes && name ==
"mode")
return newCallBack_mode(
ipRecv);
1783 else if(derivedT::c_stdCamera_cropMode && name ==
"roi_crop_mode")
return newCallBack_cropMode(
ipRecv);
1784 else if(derivedT::c_stdCamera_usesROI && name ==
"roi_region_x")
return newCallBack_roi_x(
ipRecv);
1785 else if(derivedT::c_stdCamera_usesROI && name ==
"roi_region_y")
return newCallBack_roi_y(
ipRecv);
1786 else if(derivedT::c_stdCamera_usesROI && name ==
"roi_region_w")
return newCallBack_roi_w(
ipRecv);
1787 else if(derivedT::c_stdCamera_usesROI && name ==
"roi_region_h")
return newCallBack_roi_h(
ipRecv);
1788 else if(derivedT::c_stdCamera_usesROI && name ==
"roi_region_bin_x")
return newCallBack_roi_bin_x(
ipRecv);
1789 else if(derivedT::c_stdCamera_usesROI && name ==
"roi_region_bin_y")
return newCallBack_roi_bin_y(
ipRecv);
1790 else if(derivedT::c_stdCamera_usesROI && name ==
"roi_region_check")
return newCallBack_roi_check(
ipRecv);
1791 else if(derivedT::c_stdCamera_usesROI && name ==
"roi_set")
return newCallBack_roi_set(
ipRecv);
1792 else if(derivedT::c_stdCamera_usesROI && name ==
"roi_set_full")
return newCallBack_roi_full(
ipRecv);
1793 else if(derivedT::c_stdCamera_usesROI && name ==
"roi_set_full_bin")
return newCallBack_roi_fullbin(
ipRecv);
1794 else if(derivedT::c_stdCamera_usesROI && name ==
"roi_load_last")
return newCallBack_roi_loadlast(
ipRecv);
1795 else if(derivedT::c_stdCamera_usesROI && name ==
"roi_set_last")
return newCallBack_roi_last(
ipRecv);
1796 else if(derivedT::c_stdCamera_usesROI && name ==
"roi_set_default")
return newCallBack_roi_default(
ipRecv);
1797 else if(derivedT::c_stdCamera_hasShutter && name ==
"shutter")
return newCallBack_shutter(
ipRecv);
1799 #ifndef XWCTEST_INDI_CALLBACK_VALIDATION
1800 derivedT::template log<software_error>({__FILE__,__LINE__,
"unknown INDI property"});
1806 template<
class derivedT>
1809 static_cast<void>(t);
1810 return derived().setTempSetPt();
1813 template<
class derivedT>
1816 static_cast<void>(f);
1820 template<
class derivedT>
1823 if(derivedT::c_stdCamera_tempControl)
1825 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
1831 std::unique_lock<std::mutex>
lock(derived().m_indiMutex);
1833 if (derived().indiTargetUpdate(m_indiP_temp, target,
ipRecv,
true) < 0)
1835 derivedT::template log<software_error>({__FILE__, __LINE__});
1839 m_ccdTempSetpt = target;
1841 mx::meta::trueFalseT<derivedT::c_stdCamera_tempControl> tf;
1842 return setTempSetPt(tf);
1850 template<
class derivedT>
1853 static_cast<void>(t);
1854 return derived().setTempControl();
1857 template<
class derivedT>
1860 static_cast<void>(f);
1864 template<
class derivedT>
1867 if(derivedT::c_stdCamera_tempControl)
1869 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
1873 if(!
ipRecv.find(
"toggle"))
return 0;
1875 m_tempControlStatusSet =
false;
1877 std::unique_lock<std::mutex>
lock(derived().m_indiMutex);
1879 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::On)
1881 m_tempControlStatusSet =
true;
1882 derived().updateSwitchIfChanged(m_indiP_tempcont,
"toggle", pcf::IndiElement::On,
INDI_BUSY);
1884 else if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::Off)
1886 m_tempControlStatusSet =
false;
1887 derived().updateSwitchIfChanged(m_indiP_tempcont,
"toggle", pcf::IndiElement::Off,
INDI_BUSY);
1890 mx::meta::trueFalseT<derivedT::c_stdCamera_emGain> tf;
1891 return setTempControl(tf);
1899 template<
class derivedT>
1902 static_cast<void>(t);
1903 return derived().setReadoutSpeed();
1906 template<
class derivedT>
1909 static_cast<void>(f);
1913 template<
class derivedT>
1916 if(derivedT::c_stdCamera_readoutSpeed)
1918 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
1922 std::unique_lock<std::mutex>
lock(derived().m_indiMutex);
1924 std::string newspeed;
1926 for(
size_t i=0; i< m_readoutSpeedNames.size(); ++i)
1928 if(!
ipRecv.find(m_readoutSpeedNames[i]))
continue;
1930 if(
ipRecv[m_readoutSpeedNames[i]].getSwitchState() == pcf::IndiElement::On)
1934 derivedT::template log<text_log>(
"More than one readout speed selected",
logPrio::LOG_ERROR);
1938 newspeed = m_readoutSpeedNames[i];
1945 m_readoutSpeedNameSet = m_readoutSpeedName;
1949 m_readoutSpeedNameSet = newspeed;
1952 mx::meta::trueFalseT<derivedT::c_stdCamera_readoutSpeed> tf;
1953 return setReadoutSpeed(tf);
1959 template<
class derivedT>
1962 static_cast<void>(t);
1963 return derived().setVShiftSpeed();
1966 template<
class derivedT>
1969 static_cast<void>(f);
1973 template<
class derivedT>
1976 if(derivedT::c_stdCamera_vShiftSpeed)
1978 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
1982 std::unique_lock<std::mutex>
lock(derived().m_indiMutex);
1984 std::string newspeed;
1986 for(
size_t i=0; i< m_vShiftSpeedNames.size(); ++i)
1988 if(!
ipRecv.find(m_vShiftSpeedNames[i]))
continue;
1990 if(
ipRecv[m_vShiftSpeedNames[i]].getSwitchState() == pcf::IndiElement::On)
1994 derivedT::template log<text_log>(
"More than one vShift speed selected",
logPrio::LOG_ERROR);
1998 newspeed = m_vShiftSpeedNames[i];
2005 m_vShiftSpeedNameSet = m_vShiftSpeedName;
2009 m_vShiftSpeedNameSet = newspeed;
2012 mx::meta::trueFalseT<derivedT::c_stdCamera_vShiftSpeed> tf;
2013 return setVShiftSpeed(tf);
2019 template<
class derivedT>
2022 static_cast<void>(t);
2023 return derived().setEMGain();
2026 template<
class derivedT>
2029 static_cast<void>(f);
2033 template<
class derivedT>
2036 if(derivedT::c_stdCamera_emGain)
2038 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2044 std::unique_lock<std::mutex>
lock(derived().m_indiMutex);
2046 if( derived().indiTargetUpdate( m_indiP_emGain, target,
ipRecv,
true) < 0)
2048 derivedT::template log<software_error>({__FILE__,__LINE__});
2052 m_emGainSet = target;
2054 mx::meta::trueFalseT<derivedT::c_stdCamera_emGain> tf;
2055 return setEMGain(tf);
2061 template<
class derivedT>
2064 static_cast<void>(t);
2065 return derived().setExpTime();
2068 template<
class derivedT>
2071 static_cast<void>(f);
2075 template<
class derivedT>
2078 if(derivedT::c_stdCamera_exptimeCtrl)
2080 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2086 std::unique_lock<std::mutex>
lock(derived().m_indiMutex);
2088 if( derived().indiTargetUpdate( m_indiP_exptime, target,
ipRecv,
true) < 0)
2090 derivedT::template log<software_error>({__FILE__,__LINE__});
2094 m_expTimeSet = target;
2096 mx::meta::trueFalseT<derivedT::c_stdCamera_exptimeCtrl> tf;
2097 return setExpTime(tf);
2103 template<
class derivedT>
2106 static_cast<void>(t);
2107 return derived().setFPS();
2110 template<
class derivedT>
2113 static_cast<void>(f);
2117 template<
class derivedT>
2120 if(derivedT::c_stdCamera_fpsCtrl)
2122 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2128 std::unique_lock<std::mutex>
lock(derived().m_indiMutex);
2130 if( derived().indiTargetUpdate( m_indiP_fps, target,
ipRecv,
true) < 0)
2132 derivedT::template log<software_error>({__FILE__,__LINE__});
2138 mx::meta::trueFalseT<derivedT::c_stdCamera_fpsCtrl> tf;
2145 template<
class derivedT>
2148 static_cast<void>(t);
2149 return derived().setSynchro();
2152 template<
class derivedT>
2155 static_cast<void>(f);
2159 template<
class derivedT>
2162 if(derivedT::c_stdCamera_synchro)
2164 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2168 if(!
ipRecv.find(
"toggle"))
return 0;
2170 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::Off )
2172 m_synchroSet =
false;
2175 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::On )
2177 m_synchroSet =
true;
2180 std::unique_lock<std::mutex>
lock(derived().m_indiMutex);
2182 mx::meta::trueFalseT<derivedT::c_stdCamera_synchro> tf;
2183 return setSynchro(tf);
2189 template<
class derivedT>
2192 if(derivedT::c_stdCamera_usesModes)
2194 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2198 std::unique_lock<std::mutex>
lock(derived().m_indiMutex);
2200 if(
ipRecv.getName() != m_indiP_mode.getName())
2202 derivedT::template log<software_error>({__FILE__, __LINE__,
"invalid indi property received"});
2207 std::string newName =
"";
2208 for(
auto it=m_cameraModes.begin();
it != m_cameraModes.end(); ++
it)
2210 if(!
ipRecv.find(
it->first))
continue;
2212 if(
ipRecv[
it->first].getSwitchState() == pcf::IndiElement::On)
2216 derivedT::template log<text_log>(
"More than one camera mode selected",
logPrio::LOG_ERROR);
2220 newName =
it->first;
2230 m_nextMode = newName;
2231 derived().m_reconfig =
true;
2241 template<
class derivedT>
2244 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2248 if(!
ipRecv.find(
"request"))
return 0;
2250 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
2252 std::unique_lock<std::mutex>
lock(derived().m_indiMutex);
2256 m_nextMode = m_modeName;
2257 derived().m_reconfig =
true;
2264 template<
class derivedT>
2267 static_cast<void>(t);
2268 return derived().setCropMode();
2271 template<
class derivedT>
2274 static_cast<void>(f);
2278 template<
class derivedT>
2281 if(derivedT::c_stdCamera_cropMode)
2283 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2287 if(!
ipRecv.find(
"toggle"))
return 0;
2289 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::Off )
2291 m_cropModeSet =
false;
2294 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::On )
2296 m_cropModeSet =
true;
2299 std::unique_lock<std::mutex>
lock(derived().m_indiMutex);
2301 mx::meta::trueFalseT<derivedT::c_stdCamera_cropMode> tf;
2302 return setCropMode(tf);
2309 template<
class derivedT>
2312 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2318 std::unique_lock<std::mutex>
lock(derived().m_indiMutex);
2320 if( derived().indiTargetUpdate( m_indiP_roi_x, target,
ipRecv,
false) < 0)
2322 m_nextROI.x = m_currentROI.x;
2323 derivedT::template log<software_error>({__FILE__,__LINE__});
2327 m_nextROI.x = target;
2332 template<
class derivedT>
2335 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2341 std::unique_lock<std::mutex>
lock(derived().m_indiMutex);
2343 if( derived().indiTargetUpdate( m_indiP_roi_y, target,
ipRecv,
false) < 0)
2345 m_nextROI.y = m_currentROI.y;
2346 derivedT::template log<software_error>({__FILE__,__LINE__});
2350 m_nextROI.y = target;
2355 template<
class derivedT>
2358 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2364 std::unique_lock<std::mutex>
lock(derived().m_indiMutex);
2366 if( derived().indiTargetUpdate( m_indiP_roi_w, target,
ipRecv,
false) < 0)
2368 m_nextROI.w = m_currentROI.w;
2369 derivedT::template log<software_error>({__FILE__,__LINE__});
2373 m_nextROI.w = target;
2378 template<
class derivedT>
2381 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2387 std::unique_lock<std::mutex>
lock(derived().m_indiMutex);
2389 if( derived().indiTargetUpdate( m_indiP_roi_h, target,
ipRecv,
false) < 0)
2391 derivedT::template log<software_error>({__FILE__,__LINE__});
2392 m_nextROI.h = m_currentROI.h;
2396 m_nextROI.h = target;
2401 template<
class derivedT>
2404 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2410 std::unique_lock<std::mutex>
lock(derived().m_indiMutex);
2412 if( derived().indiTargetUpdate( m_indiP_roi_bin_x, target,
ipRecv,
false) < 0)
2414 derivedT::template log<software_error>({__FILE__,__LINE__});
2415 m_nextROI.bin_x = m_currentROI.bin_x;
2419 m_nextROI.bin_x = target;
2424 template<
class derivedT>
2427 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2433 std::unique_lock<std::mutex>
lock(derived().m_indiMutex);
2435 if( derived().indiTargetUpdate( m_indiP_roi_bin_y, target,
ipRecv,
false) < 0)
2437 derivedT::template log<software_error>({__FILE__,__LINE__});
2438 m_nextROI.bin_y = m_currentROI.bin_y;
2442 m_nextROI.bin_y = target;
2447 template<
class derivedT>
2450 static_cast<void>(t);
2451 return derived().checkNextROI();
2454 template<
class derivedT>
2457 static_cast<void>(f);
2461 template<
class derivedT>
2464 if(derivedT::c_stdCamera_usesROI)
2466 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2470 if(!
ipRecv.find(
"request"))
return 0;
2472 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
2474 std::unique_lock<std::mutex>
lock(derived().m_indiMutex);
2478 mx::meta::trueFalseT<derivedT::c_stdCamera_usesROI> tf;
2479 return checkNextROI(tf);
2488 template<
class derivedT>
2491 static_cast<void>(t);
2492 return derived().setNextROI();
2495 template<
class derivedT>
2498 static_cast<void>(f);
2502 template<
class derivedT>
2505 if(derivedT::c_stdCamera_usesROI)
2507 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2511 if(!
ipRecv.find(
"request"))
return 0;
2513 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
2515 std::unique_lock<std::mutex>
lock(derived().m_indiMutex);
2519 m_lastROI = m_currentROI;
2521 mx::meta::trueFalseT<derivedT::c_stdCamera_usesROI> tf;
2522 return setNextROI(tf);
2531 template<
class derivedT>
2534 if(derivedT::c_stdCamera_usesROI)
2536 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2540 if(!
ipRecv.find(
"request"))
return 0;
2542 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
2544 std::unique_lock<std::mutex>
lock(derived().m_indiMutex);
2548 m_nextROI.x = m_full_x;
2549 m_nextROI.y = m_full_y;
2550 m_nextROI.w = m_full_w;
2551 m_nextROI.h = m_full_h;
2552 m_nextROI.bin_x = m_full_bin_x;
2553 m_nextROI.bin_y = m_full_bin_y;
2554 m_lastROI = m_currentROI;
2555 mx::meta::trueFalseT<derivedT::c_stdCamera_usesROI> tf;
2556 return setNextROI(tf);
2565 template<
class derivedT>
2568 if(derivedT::c_stdCamera_usesROI)
2570 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2574 if(!
ipRecv.find(
"request"))
return 0;
2576 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
2578 std::unique_lock<std::mutex>
lock(derived().m_indiMutex);
2584 if(m_full_currbin_x == 0)
2586 derivedT::template log<text_log>(
"current-binning full ROI not implemented for this camera",
logPrio::LOG_WARNING);
2587 m_full_currbin_x = m_full_x;
2588 m_full_currbin_y = m_full_y;
2589 m_full_currbin_w = m_full_w;
2590 m_full_currbin_h = m_full_h;
2596 m_nextROI.x = m_full_currbin_x;
2597 m_nextROI.y = m_full_currbin_y;
2598 m_nextROI.w = m_full_currbin_w;
2599 m_nextROI.h = m_full_currbin_h;
2603 m_nextROI.bin_x = m_full_bin_x;
2604 m_nextROI.bin_y = m_full_bin_y;
2607 m_full_currbin_x = 0;
2608 m_full_currbin_y = 0;
2609 m_full_currbin_w = 0;
2610 m_full_currbin_h = 0;
2614 m_nextROI.bin_x = m_currentROI.bin_x;
2615 m_nextROI.bin_y = m_currentROI.bin_y;
2618 m_lastROI = m_currentROI;
2619 mx::meta::trueFalseT<derivedT::c_stdCamera_usesROI> tf;
2620 return setNextROI(tf);
2629 template<
class derivedT>
2632 if(derivedT::c_stdCamera_usesROI)
2634 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2638 if(!
ipRecv.find(
"request"))
return 0;
2640 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
2642 std::unique_lock<std::mutex>
lock(derived().m_indiMutex);
2646 m_nextROI = m_lastROI;
2656 template<
class derivedT>
2659 if(derivedT::c_stdCamera_usesROI)
2661 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2664 if(!
ipRecv.find(
"request"))
return 0;
2666 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
2668 std::unique_lock<std::mutex>
lock(derived().m_indiMutex);
2672 m_nextROI = m_lastROI;
2673 m_lastROI = m_currentROI;
2674 mx::meta::trueFalseT<derivedT::c_stdCamera_usesROI> tf;
2675 return setNextROI(tf);
2684 template<
class derivedT>
2687 if(derivedT::c_stdCamera_usesROI)
2689 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2693 if(!
ipRecv.find(
"request"))
return 0;
2695 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
2697 std::unique_lock<std::mutex>
lock(derived().m_indiMutex);
2701 m_nextROI.x = m_default_x;
2702 m_nextROI.y = m_default_y;
2703 m_nextROI.w = m_default_w;
2704 m_nextROI.h = m_default_h;
2705 m_nextROI.bin_x = m_default_bin_x;
2706 m_nextROI.bin_y = m_default_bin_y;
2707 m_lastROI = m_currentROI;
2708 mx::meta::trueFalseT<derivedT::c_stdCamera_usesROI> tf;
2709 return setNextROI(tf);
2718 template<
class derivedT>
2720 const mx::meta::trueFalseT<true> & t
2723 static_cast<void>(t);
2724 return derived().setShutter(ss);
2727 template<
class derivedT>
2729 const mx::meta::trueFalseT<false> & f
2732 static_cast<void>(ss);
2733 static_cast<void>(f);
2737 template<
class derivedT>
2740 if(derivedT::c_stdCamera_hasShutter)
2742 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2746 if(!
ipRecv.find(
"toggle"))
return 0;
2748 mx::meta::trueFalseT<derivedT::c_stdCamera_hasShutter> tf;
2750 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::Off )
2755 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::On )
2765 template<
class derivedT>
2768 static_cast<void>(t);
2769 return derived().stateString();
2772 template<
class derivedT>
2775 static_cast<void>(f);
2779 template<
class derivedT>
2782 static_cast<void>(t);
2783 return derived().stateStringValid();
2786 template<
class derivedT>
2789 static_cast<void>(f);
2793 template<
class derivedT>
2796 if( !derived().m_indiDriver )
return 0;
2798 if(derivedT::c_stdCamera_readoutSpeed)
2803 if(derivedT::c_stdCamera_vShiftSpeed)
2808 if(derivedT::c_stdCamera_emGain)
2810 derived().updateIfChanged(m_indiP_emGain,
"current", m_emGain,
INDI_IDLE);
2811 derived().updateIfChanged(m_indiP_emGain,
"target", m_emGainSet,
INDI_IDLE);
2814 if(derivedT::c_stdCamera_exptimeCtrl)
2816 derived().updateIfChanged(m_indiP_exptime,
"current", m_expTime,
INDI_IDLE);
2817 derived().updateIfChanged(m_indiP_exptime,
"target", m_expTimeSet,
INDI_IDLE);
2820 if(derivedT::c_stdCamera_fpsCtrl)
2822 derived().updateIfChanged(m_indiP_fps,
"current", m_fps,
INDI_IDLE);
2823 derived().updateIfChanged(m_indiP_fps,
"target", m_fpsSet,
INDI_IDLE);
2825 else if(derivedT::c_stdCamera_fps)
2827 derived().updateIfChanged(m_indiP_fps,
"current", m_fps,
INDI_IDLE);
2830 if(derivedT::c_stdCamera_synchro)
2832 if(m_synchro ==
false)
2834 derived().updateSwitchIfChanged(m_indiP_synchro,
"toggle", pcf::IndiElement::Off,
INDI_IDLE);
2838 derived().updateSwitchIfChanged(m_indiP_synchro,
"toggle", pcf::IndiElement::On,
INDI_OK);
2842 if(derivedT::c_stdCamera_usesModes)
2844 auto st = pcf::IndiProperty::Ok;
2845 if(m_nextMode !=
"") st = pcf::IndiProperty::Busy;
2847 for(
auto it = m_cameraModes.begin();
it!=m_cameraModes.end();++
it)
2849 if(
it->first == m_modeName) derived().updateSwitchIfChanged(m_indiP_mode,
it->first, pcf::IndiElement::On, st);
2850 else derived().updateSwitchIfChanged(m_indiP_mode,
it->first, pcf::IndiElement::Off, st);
2855 if(derivedT::c_stdCamera_cropMode)
2857 if(m_cropMode ==
false)
2859 derived().updateSwitchIfChanged(m_indiP_cropMode,
"toggle", pcf::IndiElement::Off,
INDI_IDLE);
2863 derived().updateSwitchIfChanged(m_indiP_cropMode,
"toggle", pcf::IndiElement::On,
INDI_OK);
2867 if(derivedT::c_stdCamera_usesROI)
2871 derived().updateIfChanged(m_indiP_fullROI,
"x", m_full_x,
INDI_IDLE);
2872 derived().updateIfChanged(m_indiP_fullROI,
"y", m_full_y,
INDI_IDLE);
2873 derived().updateIfChanged(m_indiP_fullROI,
"w", m_full_w,
INDI_IDLE);
2874 derived().updateIfChanged(m_indiP_fullROI,
"h", m_full_h,
INDI_IDLE);
2877 if(derivedT::c_stdCamera_tempControl)
2879 if(m_tempControlStatus ==
false)
2881 derived().updateSwitchIfChanged( m_indiP_tempcont,
"toggle", pcf::IndiElement::Off,
INDI_IDLE);
2882 derived().updateIfChanged(m_indiP_temp,
"current", m_ccdTemp,
INDI_IDLE);
2883 derived().updateIfChanged(m_indiP_temp,
"target", m_ccdTempSetpt,
INDI_IDLE);
2884 derived().updateIfChanged( m_indiP_tempstat,
"status", m_tempControlStatusStr,
INDI_IDLE);
2888 if(m_tempControlOnTarget)
2890 derived().updateSwitchIfChanged( m_indiP_tempcont,
"toggle", pcf::IndiElement::On,
INDI_OK);
2891 derived().updateIfChanged(m_indiP_temp,
"current", m_ccdTemp,
INDI_OK);
2892 derived().updateIfChanged(m_indiP_temp,
"target", m_ccdTempSetpt,
INDI_OK);
2893 derived().updateIfChanged( m_indiP_tempstat,
"status", m_tempControlStatusStr,
INDI_OK);
2897 derived().updateSwitchIfChanged( m_indiP_tempcont,
"toggle", pcf::IndiElement::On,
INDI_BUSY);
2898 derived().updateIfChanged(m_indiP_temp,
"current", m_ccdTemp,
INDI_BUSY);
2899 derived().updateIfChanged(m_indiP_temp,
"target", m_ccdTempSetpt,
INDI_BUSY);
2900 derived().updateIfChanged( m_indiP_tempstat,
"status", m_tempControlStatusStr,
INDI_BUSY);
2904 else if(derivedT::c_stdCamera_temp)
2906 derived().updateIfChanged(m_indiP_temp,
"current", m_ccdTemp,
INDI_IDLE);
2911 if(derivedT::c_stdCamera_hasShutter)
2913 if(m_shutterStatus ==
"OPERATING")
2915 derived().updateIfChanged(m_indiP_shutterStatus,
"status", m_shutterStatus,
INDI_BUSY);
2917 if(m_shutterStatus ==
"POWERON" || m_shutterStatus ==
"READY")
2919 derived().updateIfChanged(m_indiP_shutterStatus,
"status", m_shutterStatus,
INDI_IDLE);
2923 derived().updateIfChanged(m_indiP_shutterStatus,
"status", m_shutterStatus,
INDI_IDLE);
2926 if(m_shutterState == 0)
2928 derived().updateSwitchIfChanged(m_indiP_shutter,
"toggle", pcf::IndiElement::On,
INDI_OK);
2932 derived().updateSwitchIfChanged(m_indiP_shutter,
"toggle", pcf::IndiElement::Off,
INDI_IDLE);
2936 if(derivedT::c_stdCamera_usesStateString)
2938 mx::meta::trueFalseT<derivedT::c_stdCamera_usesStateString> tf;
2939 derived().updateIfChanged(m_indiP_stateString,
"current", stateString(tf),
INDI_IDLE);
2940 if(stateStringValid(tf))
2942 derived().updateIfChanged(m_indiP_stateString,
"valid",
"yes",
INDI_IDLE);
2946 derived().updateIfChanged(m_indiP_stateString,
"valid",
"no",
INDI_IDLE);
2952 template<
class derivedT>
2955 static std::string last_mode;
2956 static roi last_roi;
2957 static float last_expTime = -1e30;
2958 static float last_fps = 0;
2959 static float last_adcSpeed = -1;
2960 static float last_emGain = -1;
2961 static float last_ccdTemp = 0;
2962 static float last_ccdTempSetpt = 0;
2963 static bool last_tempControlStatus = 0;
2964 static bool last_tempControlOnTarget = 0;
2965 static std::string last_tempControlStatusStr;
2966 static std::string last_shutterStatus;
2967 static int last_shutterState =
false;
2968 static bool last_synchro =
false;
2969 static float last_vshiftSpeed = -1;
2970 static bool last_cropMode =
false;
2973 if(force || m_modeName != last_mode ||
2974 m_currentROI.x != last_roi.
x ||
2975 m_currentROI.y != last_roi.
y ||
2976 m_currentROI.w != last_roi.
w ||
2977 m_currentROI.h != last_roi.
h ||
2978 m_currentROI.bin_x != last_roi.
bin_x ||
2979 m_currentROI.bin_y != last_roi.
bin_y ||
2980 m_expTime != last_expTime ||
2981 m_fps != last_fps ||
2982 m_emGain != last_emGain ||
2983 m_adcSpeed != last_adcSpeed ||
2984 m_ccdTemp != last_ccdTemp ||
2985 m_ccdTempSetpt != last_ccdTempSetpt ||
2986 m_tempControlStatus != last_tempControlStatus ||
2987 m_tempControlOnTarget != last_tempControlOnTarget ||
2988 m_tempControlStatusStr != last_tempControlStatusStr ||
2989 m_shutterStatus != last_shutterStatus ||
2990 m_shutterState != last_shutterState ||
2991 m_synchro != last_synchro ||
2992 m_vshiftSpeed != last_vshiftSpeed ||
2993 m_cropMode != last_cropMode)
2995 derived().template telem<telem_stdcam>({m_modeName, m_currentROI.x, m_currentROI.y,
2996 m_currentROI.w, m_currentROI.h, m_currentROI.bin_x, m_currentROI.bin_y,
2997 m_expTime, m_fps, m_emGain, m_adcSpeed, m_ccdTemp, m_ccdTempSetpt, (uint8_t) m_tempControlStatus,
2998 (uint8_t) m_tempControlOnTarget, m_tempControlStatusStr, m_shutterStatus, (int8_t) m_shutterState,
2999 (uint8_t) m_synchro, m_vshiftSpeed, (uint8_t) m_cropMode});
3001 last_mode = m_modeName;
3002 last_roi = m_currentROI;
3003 last_expTime = m_expTime;
3005 last_emGain = m_emGain;
3006 last_adcSpeed = m_adcSpeed;
3007 last_ccdTemp = m_ccdTemp;
3008 last_ccdTempSetpt = m_ccdTempSetpt;
3009 last_tempControlStatus = m_tempControlStatus;
3010 last_tempControlOnTarget = m_tempControlOnTarget;
3011 last_tempControlStatusStr = m_tempControlStatusStr;
3012 last_shutterStatus = m_shutterStatus;
3013 last_shutterState = m_shutterState;
3014 last_synchro = m_synchro;
3015 last_vshiftSpeed = m_vshiftSpeed;
3016 last_cropMode = m_cropMode;
MagAO-X standard camera interface.
float m_maxEMGain
The configurable maximum EM gain. To be enforced in derivedT.
std::vector< std::string > m_readoutSpeedNames
float m_minExpTime
The minimum exposure time, used for INDI attributes.
pcf::IndiProperty m_indiP_roi_fullbin
Property used to trigger setting the full in current binning ROI.
float m_fpsSet
The commanded fps, as set by user.
int newCallBack_temp(const pcf::IndiProperty &ipRecv)
Callback to process a NEW CCD temp request.
int newCallBack_cropMode(const pcf::IndiProperty &ipRecv)
Callback to process a NEW cropMode request.
bool m_synchroSet
Target status of m_synchro.
pcf::IndiProperty m_indiP_roi_y
Property used to set the ROI x center coordinate.
int createReadoutSpeed(const mx::meta::trueFalseT< true > &t)
int m_full_currbin_w
The current-binning full ROI width.
int setShutter(int ss, const mx::meta::trueFalseT< true > &t)
Interface to setShutter when the derivedT has a shutter.
float m_default_x
Power-on ROI center x coordinate.
std::string m_tempControlStatusStr
Camera specific description of temperature control status.
float m_emGain
The camera's current EM gain (if available).
int m_full_bin_x
The x-binning in the full ROI.
int newCallBack_readoutSpeed(const pcf::IndiProperty &ipRecv)
Callback to process a NEW readout speed request.
std::vector< std::string > m_readoutSpeedNameLabels
float m_full_currbin_x
The current-binning full ROI center x coordinate.
int m_full_w
The full ROI width.
float m_emGainSet
The camera's EM gain, as set by the user.
std::string m_vShiftSpeedNameSet
The user requested vshift speed name, to be set by derived()
bool m_cropModeSet
Desired status of crop mode ROIs, if enabled for this camera.
int newCallBack_roi_bin_y(const pcf::IndiProperty &ipRecv)
Callback to process a NEW bin_y request.
std::string m_defaultReadoutSpeed
The default readout speed of the camera.
pcf::IndiProperty m_indiP_shutterStatus
State of the shutter. 0 = shut, 1 = open, -1 = unknown.
float m_expTime
The current exposure time, in seconds.
int setExpTime(const mx::meta::trueFalseT< true > &t)
Interface to setExpTime when the derivedT uses exposure time controls.
std::string m_nextMode
The mode to be set by the next reconfiguration.
pcf::IndiProperty m_indiP_tempstat
int m_default_bin_x
Power-on ROI x binning.
int m_default_w
Power-on ROI width.
int setTempControl(const mx::meta::trueFalseT< true > &t)
Interface to setTempControl when the derivedT has temperature control.
int newCallBack_roi_h(const pcf::IndiProperty &ipRecv)
Callback to process a NEW roi_h request.
int recordCamera(bool force=false)
bool m_cropMode
Status of crop mode ROIs, if enabled for this camera.
float m_maxExpTime
The maximum exposure time, used for INDI attributes.
float m_stepFPS
The FPS step size, used for INDI attributes.
int newCallBack_mode(const pcf::IndiProperty &ipRecv)
Callback to process a NEW mode request.
int m_default_h
Power-on ROI height.
pcf::IndiProperty m_indiP_roi_last
Property used to trigger setting the last ROI.
pcf::IndiProperty m_indiP_temp
float m_expTimeSet
The exposure time, in seconds, as set by user.
pcf::IndiProperty m_indiP_roi_h
Property used to set the ROI height.
void setupConfig(mx::app::appConfigurator &config)
Setup the configuration system.
int m_full_h
The full ROI height.
pcf::IndiProperty m_indiP_synchro
int m_full_bin_y
The y-binning in the full ROI.
int checkNextROI(const mx::meta::trueFalseT< true > &t)
Interface to checkNextROI when the derivedT uses ROIs.
int setVShiftSpeed(const mx::meta::trueFalseT< true > &t)
Interface to setVShiftSpeed when the derivedT has vshift speed control.
float m_full_y
The full ROI center y coordinate.
static int st_newCallBack_stdCamera(void *app, const pcf::IndiProperty &ipRecv)
The static callback function to be registered for stdCamera properties.
float m_maxFPS
The maximum FPS, used for INDI attributes.
std::string m_readoutSpeedName
The current readout speed name.
float m_ccdTempSetpt
The desired temperature, in C.
bool m_tempControlStatus
Whether or not temperature control is active.
pcf::IndiProperty m_indiP_fps
int newCallBack_roi_last(const pcf::IndiProperty &ipRecv)
Callback to process a NEW roi_last request.
pcf::IndiProperty m_indiP_roi_loadlast
Property used to trigger loading the last ROI as the target.
pcf::IndiProperty m_indiP_roi_w
Property used to set the ROI width.
int newCallBack_roi_set(const pcf::IndiProperty &ipRecv)
Callback to process a NEW roi_set request.
pcf::IndiProperty m_indiP_roi_default
Property used to trigger setting the default and startup ROI.
int newCallBack_stdCamera(const pcf::IndiProperty &ipRecv)
The callback function for stdCamera properties.
std::string m_modeName
The current mode name.
pcf::IndiProperty m_indiP_reconfig
Request switch which forces the framegrabber to go through the reconfigure process.
int setSynchro(const mx::meta::trueFalseT< true > &t)
Interface to setSynchro when the derivedT has synchronization.
pcf::IndiProperty m_indiP_roi_bin_x
Property used to set the ROI x binning.
int newCallBack_roi_loadlast(const pcf::IndiProperty &ipRecv)
Callback to process a NEW roi_loadlast request.
pcf::IndiProperty m_indiP_readoutSpeed
int setEMGain(const mx::meta::trueFalseT< true > &t)
Interface to setEMGain when the derivedT has EM Gain.
int newCallBack_vShiftSpeed(const pcf::IndiProperty &ipRecv)
Callback to process a NEW vshift speed request.
std::string m_startupMode
The camera mode to load during first init after a power-on.
pcf::IndiProperty m_indiP_roi_check
Property used to trigger checking the target ROI.
pcf::IndiProperty m_indiP_vShiftSpeed
int newCallBack_roi_check(const pcf::IndiProperty &ipRecv)
Callback to process a NEW roi_check request.
int newCallBack_roi_x(const pcf::IndiProperty &ipRecv)
Callback to process a NEW roi_x request.
float m_full_x
The full ROI center x coordinate.
float m_startupTemp
The temperature to set after a power-on. Set to <= -999 to not use [default].
int appLogic()
Application logic.
int m_full_currbin_h
The current-binning full ROI height.
std::string m_shutterStatus
pcf::IndiProperty m_indiP_exptime
int newCallBack_shutter(const pcf::IndiProperty &ipRecv)
Callback to process a NEW shutter request.
bool m_synchro
Status of synchronization, true is on, false is off.
std::string m_vShiftSpeedName
The current vshift speed name.
int newCallBack_roi_full(const pcf::IndiProperty &ipRecv)
Callback to process a NEW roi_full request.
int setCropMode(const mx::meta::trueFalseT< true > &t)
Interface to setCropMode when the derivedT has crop mode.
pcf::IndiProperty m_indiP_emGain
float m_ccdTemp
The current temperature, in C.
int updateINDI()
Update the INDI properties for this device controller.
std::vector< std::string > m_vShiftSpeedNames
int newCallBack_fps(const pcf::IndiProperty &ipRecv)
Callback to process a NEW fps request.
std::string m_defaultVShiftSpeed
The default readout speed of the camera.
int newCallBack_roi_y(const pcf::IndiProperty &ipRecv)
Callback to process a NEW roi_y request.
pcf::IndiProperty m_indiP_tempcont
bool m_tempControlOnTarget
Whether or not the temperature control system is on its target temperature.
int createVShiftSpeed(const mx::meta::trueFalseT< true > &t)
cameraConfigMap m_cameraModes
Map holding the possible camera mode configurations.
float m_stepExpTime
The maximum exposure time stepsize, used for INDI attributes.
void loadConfig(mx::app::appConfigurator &config)
load the configuration system results
int whilePowerOff()
Actions while powered off.
int setFPS(const mx::meta::trueFalseT< true > &t)
Interface to setFPS when the derivedT uses FPS controls.
int newCallBack_reconfigure(const pcf::IndiProperty &ipRecv)
Callback to process a NEW reconfigure request.
int newCallBack_emgain(const pcf::IndiProperty &ipRecv)
Callback to process a NEW EM gain request.
float m_full_currbin_y
The current-binning full ROI center y coordinate.
int appStartup()
Startup function.
int newCallBack_roi_bin_x(const pcf::IndiProperty &ipRecv)
Callback to process a NEW bin_x request.
std::vector< std::string > m_vShiftSpeedNameLabels
int setTempSetPt(const mx::meta::trueFalseT< true > &t)
Interface to setTempSetPt when the derivedT has temperature control.
pcf::IndiProperty m_indiP_roi_full
Property used to trigger setting the full ROI.
int newCallBack_synchro(const pcf::IndiProperty &ipRecv)
Callback to process a NEW synchro request.
int newCallBack_roi_default(const pcf::IndiProperty &ipRecv)
Callback to process a NEW roi_default request.
pcf::IndiProperty m_indiP_roi_set
Property used to trigger setting the ROI.
int appShutdown()
Application shutdown.
pcf::IndiProperty m_indiP_shutter
Property used to control the shutter, a switch.
int newCallBack_roi_w(const pcf::IndiProperty &ipRecv)
Callback to process a NEW roi_w request.
pcf::IndiProperty m_indiP_stateString
pcf::IndiProperty m_indiP_mode
Property used to report the current mode.
pcf::IndiProperty m_indiP_cropMode
Property used to toggle crop mode on and off.
float m_default_y
Power-on ROI center y coordinate.
int setNextROI(const mx::meta::trueFalseT< true > &t)
Interface to setNextROI when the derivedT uses ROIs.
pcf::IndiProperty m_indiP_fullROI
Property used to preset the full ROI dimensions.
bool stateStringValid(const mx::meta::trueFalseT< true > &t)
Interface to stateStringValid when the derivedT provides it.
float m_fps
The current FPS.
std::string stateString(const mx::meta::trueFalseT< true > &t)
Interface to stateString when the derivedT provides it.
pcf::IndiProperty m_indiP_roi_bin_y
Property used to set the ROI y binning.
pcf::IndiProperty m_indiP_roi_x
Property used to set the ROI x center coordinate.
int newCallBack_roi_fullbin(const pcf::IndiProperty &ipRecv)
Callback to process a NEW roi_fullbin request.
int newCallBack_temp_controller(const pcf::IndiProperty &ipRecv)
Callback to process a NEW CCD temp control request.
int newCallBack_exptime(const pcf::IndiProperty &ipRecv)
Callback to process a NEW exposure time request.
int setReadoutSpeed(const mx::meta::trueFalseT< true > &t)
Interface to setReadoutSpeed when the derivedT has readout speed control.
int m_default_bin_y
Power-on ROI y binning.
bool m_tempControlStatusSet
Desired state of temperature control.
float m_minFPS
The minimum FPS, used for INDI attributes.
int onPowerOff()
Actions on power off.
std::string m_readoutSpeedNameSet
The user requested readout speed name, to be set by derived()
~stdCamera() noexcept
Destructor.
@ OPERATING
The device is operating, other than homing.
@ READY
The device is ready for operation, but is not operating.
@ NOTCONNECTED
The application is not connected to the device or service.
@ POWERON
The device power is on.
std::unordered_map< std::string, cameraConfig > cameraConfigMap
int loadCameraConfig(cameraConfigMap &ccmap, mx::app::appConfigurator &config)
Load the camera configurations contained in the app configuration into a map.
std::string m_serialCommand
The command to send to the camera to place it in this mode.
std::string m_configFile
The file to use for this mode, e.g. an EDT configuration file.
void updateIfChanged(pcf::IndiProperty &p, const std::string &el, const T &newVal, indiDriverT *indiDriver, pcf::IndiProperty::PropertyStateType newState=pcf::IndiProperty::Ok)
Update the value of the INDI element, but only if it has changed.
void updateSelectionSwitchIfChanged(pcf::IndiProperty &p, const std::string &el, indiDriverT *indiDriver, pcf::IndiProperty::PropertyStateType newState=pcf::IndiProperty::Ok)
Update the values of a one-of-many INDI switch vector, but only if it has changed.
void updateSwitchIfChanged(pcf::IndiProperty &p, const std::string &el, const pcf::IndiElement::SwitchStateType &newVal, indiDriverT *indiDriver, pcf::IndiProperty::PropertyStateType newState=pcf::IndiProperty::Ok)
Update the value of the INDI element, but only if it has changed.
const pcf::IndiProperty & ipRecv
std::unique_lock< std::mutex > lock(m_indiMutex)
constexpr static logPrioT LOG_CRITICAL
The process can not continue and will shut down (fatal)
constexpr static logPrioT LOG_ERROR
An error has occured which the software will attempt to correct.
constexpr static logPrioT LOG_WARNING
A condition has occurred which may become an error, but the process continues.
#define CAMCTRL_E_NOCONFIGS