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
230 template<
class derivedT>
587 const pcf::IndiProperty &
ipRecv
716 int setFPS( const mx::meta::trueFalseT<true> & t );
722 int setFPS( const mx::meta::trueFalseT<false> & f );
903 const mx::meta::trueFalseT<true> & t
911 const mx::meta::trueFalseT<false> & f
967 return *
static_cast<derivedT *
>(
this);
971 template<
class derivedT>
979 template<
class derivedT>
982 if(derivedT::c_stdCamera_tempControl)
984 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.");
987 if(derivedT::c_stdCamera_readoutSpeed)
989 config.add(
"camera.defaultReadoutSpeed",
"",
"camera.defaultReadoutSpeed", argType::Required,
"camera",
"defaultReadoutSpeed",
false,
"string",
"The default amplifier and readout speed.");
992 if(derivedT::c_stdCamera_vShiftSpeed)
994 config.add(
"camera.defaultVShiftSpeed",
"",
"camera.defaultVShiftSpeed", argType::Required,
"camera",
"defaultVShiftSpeed",
false,
"string",
"The default vertical shift speed.");
997 if(derivedT::c_stdCamera_emGain)
999 config.add(
"camera.maxEMGain",
"",
"camera.maxEMGain", argType::Required,
"camera",
"maxEMGain",
false,
"unsigned",
"The maximum EM gain which can be set by the user.");
1002 if(derivedT::c_stdCamera_usesModes)
1004 config.add(
"camera.startupMode",
"",
"camera.startupMode", argType::Required,
"camera",
"startupMode",
false,
"string",
"The mode to set upon power on or application startup.");
1007 if(derivedT::c_stdCamera_usesROI)
1009 config.add(
"camera.default_x",
"",
"camera.default_x", argType::Required,
"camera",
"default_x",
false,
"float",
"The default ROI x position.");
1010 config.add(
"camera.default_y",
"",
"camera.default_y", argType::Required,
"camera",
"default_y",
false,
"float",
"The default ROI y position.");
1011 config.add(
"camera.default_w",
"",
"camera.default_w", argType::Required,
"camera",
"default_w",
false,
"int",
"The default ROI width.");
1012 config.add(
"camera.default_h",
"",
"camera.default_h", argType::Required,
"camera",
"default_h",
false,
"int",
"The default ROI height.");
1013 config.add(
"camera.default_bin_x",
"",
"camera.default_bin_x", argType::Required,
"camera",
"default_bin_x",
false,
"int",
"The default ROI x binning.");
1014 config.add(
"camera.default_bin_y",
"",
"camera.default_bin_y", argType::Required,
"camera",
"default_bin_y",
false,
"int",
"The default ROI y binning.");
1018 template<
class derivedT>
1021 if(derivedT::c_stdCamera_tempControl)
1023 config(m_startupTemp,
"camera.startupTemp");
1026 if(derivedT::c_stdCamera_readoutSpeed)
1028 config(m_defaultReadoutSpeed,
"camera.defaultReadoutSpeed");
1031 if(derivedT::c_stdCamera_vShiftSpeed)
1033 config(m_defaultVShiftSpeed,
"camera.defaultVShiftSpeed");
1036 if(derivedT::c_stdCamera_emGain)
1038 config(m_maxEMGain,
"camera.maxEMGain");
1041 if(derivedT::c_stdCamera_usesModes)
1053 config(m_startupMode,
"camera.startupMode");
1057 if(derivedT::c_stdCamera_usesROI)
1059 config(m_default_x,
"camera.default_x");
1060 config(m_default_y,
"camera.default_y");
1061 config(m_default_w,
"camera.default_w");
1062 config(m_default_h,
"camera.default_h");
1063 config(m_default_bin_x,
"camera.default_bin_x");
1064 config(m_default_bin_y,
"camera.default_bin_y");
1068 template<
class derivedT>
1071 static_cast<void>(t);
1073 derived().createStandardIndiSelectionSw(m_indiP_readoutSpeed,
"readout_speed", m_readoutSpeedNames,
"Readout Speed");
1076 if(m_readoutSpeedNameLabels.size() == m_readoutSpeedNames.size())
1078 for(
size_t n=0; n< m_readoutSpeedNames.size(); ++n) m_indiP_readoutSpeed[m_readoutSpeedNames[n]].setLabel(m_readoutSpeedNameLabels[n]);
1081 derived().registerIndiPropertyNew(m_indiP_readoutSpeed, st_newCallBack_stdCamera);
1086 template<
class derivedT>
1089 static_cast<void>(f);
1094 template<
class derivedT>
1097 static_cast<void>(t);
1099 derived().createStandardIndiSelectionSw(m_indiP_vShiftSpeed,
"vshift_speed", m_vShiftSpeedNames,
"Vert. Shift Speed");
1101 if(m_vShiftSpeedNameLabels.size() == m_vShiftSpeedNames.size())
1103 for(
size_t n=0; n< m_vShiftSpeedNames.size(); ++n) m_indiP_vShiftSpeed[m_vShiftSpeedNames[n]].setLabel(m_vShiftSpeedNameLabels[n]);
1106 derived().registerIndiPropertyNew(m_indiP_vShiftSpeed, st_newCallBack_stdCamera);
1111 template<
class derivedT>
1114 static_cast<void>(f);
1119 template<
class derivedT>
1123 if(derivedT::c_stdCamera_tempControl)
1126 derived().createStandardIndiNumber( m_indiP_temp,
"temp_ccd", m_minTemp, m_maxTemp, m_stepTemp,
"%0.1f",
"CCD Temperature",
"CCD Temperature");
1127 m_indiP_temp[
"current"].set(m_ccdTemp);
1128 m_indiP_temp[
"target"].set(m_ccdTempSetpt);
1129 if( derived().registerIndiPropertyNew( m_indiP_temp, st_newCallBack_stdCamera) < 0)
1131 #ifndef STDCAMERA_TEST_NOLOG
1132 derivedT::template log<software_error>({__FILE__,__LINE__});
1137 derived().createStandardIndiToggleSw( m_indiP_tempcont,
"temp_controller",
"CCD Temperature",
"Control On/Off");
1138 m_indiP_tempcont[
"toggle"].set(pcf::IndiElement::Off);
1139 if( derived().registerIndiPropertyNew( m_indiP_tempcont, st_newCallBack_stdCamera) < 0)
1141 #ifndef STDCAMERA_TEST_NOLOG
1142 derivedT::template log<software_error>({__FILE__,__LINE__});
1147 derived().createROIndiText( m_indiP_tempstat,
"temp_control",
"status",
"CCD Temperature",
"",
"CCD Temperature");
1148 if( derived().registerIndiPropertyReadOnly( m_indiP_tempstat ) < 0)
1150 #ifndef STDCAMERA_TEST_NOLOG
1151 derivedT::template log<software_error>({__FILE__,__LINE__});
1156 else if(derivedT::c_stdCamera_temp)
1158 derived().createROIndiNumber( m_indiP_temp,
"temp_ccd",
"CCD Temperature",
"CCD Temperature");
1159 m_indiP_temp.add(pcf::IndiElement(
"current"));
1160 m_indiP_temp[
"current"].set(m_ccdTemp);
1161 if( derived().registerIndiPropertyReadOnly( m_indiP_temp) < 0)
1163 #ifndef STDCAMERA_TEST_NOLOG
1164 derivedT::template log<software_error>({__FILE__,__LINE__});
1170 if(derivedT::c_stdCamera_readoutSpeed)
1172 mx::meta::trueFalseT<derivedT::c_stdCamera_readoutSpeed> tf;
1173 if(createReadoutSpeed(tf) < 0)
1175 #ifndef STDCAMERA_TEST_NOLOG
1176 derivedT::template log<software_error>({__FILE__,__LINE__});
1183 if(derivedT::c_stdCamera_vShiftSpeed)
1185 mx::meta::trueFalseT<derivedT::c_stdCamera_vShiftSpeed> tf;
1186 if(createVShiftSpeed(tf) < 0)
1188 #ifndef STDCAMERA_TEST_NOLOG
1189 derivedT::template log<software_error>({__FILE__,__LINE__});
1196 if(derivedT::c_stdCamera_emGain)
1198 derived().createStandardIndiNumber( m_indiP_emGain,
"emgain", 0, 1000, 1,
"%0.3f");
1199 if( derived().registerIndiPropertyNew( m_indiP_emGain, st_newCallBack_stdCamera) < 0)
1201 #ifndef STDCAMERA_TEST_NOLOG
1202 derivedT::template log<software_error>({__FILE__,__LINE__});
1208 if(derivedT::c_stdCamera_exptimeCtrl)
1210 derived().createStandardIndiNumber( m_indiP_exptime,
"exptime", m_minExpTime, m_maxExpTime, m_stepExpTime,
"%0.3f");
1211 if( derived().registerIndiPropertyNew( m_indiP_exptime, st_newCallBack_stdCamera) < 0)
1213 #ifndef STDCAMERA_TEST_NOLOG
1214 derivedT::template log<software_error>({__FILE__,__LINE__});
1220 if(derivedT::c_stdCamera_fpsCtrl)
1222 derived().createStandardIndiNumber( m_indiP_fps,
"fps", m_minFPS, m_maxFPS, m_stepFPS,
"%0.2f");
1223 if( derived().registerIndiPropertyNew( m_indiP_fps, st_newCallBack_stdCamera) < 0)
1225 #ifndef STDCAMERA_TEST_NOLOG
1226 derivedT::template log<software_error>({__FILE__,__LINE__});
1231 else if(derivedT::c_stdCamera_fps)
1233 derived().createROIndiNumber( m_indiP_fps,
"fps");
1234 m_indiP_fps.add(pcf::IndiElement(
"current"));
1235 m_indiP_fps[
"current"].setMin(m_minFPS);
1236 m_indiP_fps[
"current"].setMax(m_maxFPS);
1237 m_indiP_fps[
"current"].setStep(m_stepFPS);
1238 m_indiP_fps[
"current"].setFormat(
"%0.2f");
1240 if( derived().registerIndiPropertyReadOnly( m_indiP_fps ) < 0)
1242 #ifndef STDCAMERA_TEST_NOLOG
1243 derivedT::template log<software_error>({__FILE__,__LINE__});
1249 if(derivedT::c_stdCamera_synchro)
1251 derived().createStandardIndiToggleSw( m_indiP_synchro,
"synchro",
"Synchronization",
"Synchronization");
1252 if( derived().registerIndiPropertyNew( m_indiP_synchro, st_newCallBack_stdCamera) < 0)
1254 #ifndef STDCAMERA_TEST_NOLOG
1255 derivedT::template log<software_error>({__FILE__,__LINE__});
1261 if(derivedT::c_stdCamera_usesModes)
1263 std::vector<std::string> modeNames;
1264 for(
auto it = m_cameraModes.begin();
it!=m_cameraModes.end(); ++
it)
1266 modeNames.push_back(
it->first);
1269 if(derived().createStandardIndiSelectionSw( m_indiP_mode,
"mode", modeNames) < 0)
1271 derivedT::template log<software_critical>({__FILE__, __LINE__});
1274 if( derived().registerIndiPropertyNew( m_indiP_mode, st_newCallBack_stdCamera) < 0)
1276 #ifndef STDCAMERA_TEST_NOLOG
1277 derivedT::template log<software_error>({__FILE__,__LINE__});
1283 derived().createStandardIndiRequestSw( m_indiP_reconfig,
"reconfigure");
1284 if( derived().registerIndiPropertyNew( m_indiP_reconfig, st_newCallBack_stdCamera) < 0)
1286 #ifndef STDCAMERA_TEST_NOLOG
1287 derivedT::template log<software_error>({__FILE__,__LINE__});
1292 if(derivedT::c_stdCamera_usesROI)
1295 derived().createStandardIndiNumber( m_indiP_roi_x,
"roi_region_x", m_minROIx, m_maxROIx, m_stepROIx,
"%0.1f");
1296 if( derived().registerIndiPropertyNew( m_indiP_roi_x, st_newCallBack_stdCamera) < 0)
1298 #ifndef STDCAMERA_TEST_NOLOG
1299 derivedT::template log<software_error>({__FILE__,__LINE__});
1304 derived().createStandardIndiNumber( m_indiP_roi_y,
"roi_region_y", m_minROIy, m_maxROIy, m_stepROIy,
"%0.1f");
1305 if( derived().registerIndiPropertyNew( m_indiP_roi_y, st_newCallBack_stdCamera) < 0)
1307 #ifndef STDCAMERA_TEST_NOLOG
1308 derivedT::template log<software_error>({__FILE__,__LINE__});
1313 derived().createStandardIndiNumber( m_indiP_roi_w,
"roi_region_w", m_minROIWidth, m_maxROIWidth, m_stepROIWidth,
"%d");
1314 if( derived().registerIndiPropertyNew( m_indiP_roi_w, st_newCallBack_stdCamera) < 0)
1316 #ifndef STDCAMERA_TEST_NOLOG
1317 derivedT::template log<software_error>({__FILE__,__LINE__});
1322 derived().createStandardIndiNumber( m_indiP_roi_h,
"roi_region_h", m_minROIHeight, m_maxROIHeight, m_stepROIHeight,
"%d");
1323 if( derived().registerIndiPropertyNew( m_indiP_roi_h, st_newCallBack_stdCamera) < 0)
1325 #ifndef STDCAMERA_TEST_NOLOG
1326 derivedT::template log<software_error>({__FILE__,__LINE__});
1331 derived().createStandardIndiNumber( m_indiP_roi_bin_x,
"roi_region_bin_x", m_minROIBinning_x, m_maxROIBinning_x, m_stepROIBinning_x,
"%f");
1332 if( derived().registerIndiPropertyNew( m_indiP_roi_bin_x, st_newCallBack_stdCamera) < 0)
1334 #ifndef STDCAMERA_TEST_NOLOG
1335 derivedT::template log<software_error>({__FILE__,__LINE__});
1340 derived().createStandardIndiNumber( m_indiP_roi_bin_y,
"roi_region_bin_y", m_minROIBinning_y, m_maxROIBinning_y, m_stepROIBinning_y,
"%f");
1341 if( derived().registerIndiPropertyNew( m_indiP_roi_bin_y, st_newCallBack_stdCamera) < 0)
1343 #ifndef STDCAMERA_TEST_NOLOG
1344 derivedT::template log<software_error>({__FILE__,__LINE__});
1349 derived().createROIndiNumber( m_indiP_fullROI,
"roi_full_region");
1350 m_indiP_fullROI.add(pcf::IndiElement(
"x"));
1351 m_indiP_fullROI[
"x"] = 0;
1352 m_indiP_fullROI.add(pcf::IndiElement(
"y"));
1353 m_indiP_fullROI[
"y"] = 0;
1354 m_indiP_fullROI.add(pcf::IndiElement(
"w"));
1355 m_indiP_fullROI[
"w"] = 0;
1356 m_indiP_fullROI.add(pcf::IndiElement(
"h"));
1357 m_indiP_fullROI[
"h"] = 0;
1358 if( derived().registerIndiPropertyReadOnly( m_indiP_fullROI ) < 0)
1360 #ifndef STDCAMERA_TEST_NOLOG
1361 derivedT::template log<software_error>({__FILE__,__LINE__});
1366 derived().createStandardIndiRequestSw( m_indiP_roi_check,
"roi_region_check");
1367 if( derived().registerIndiPropertyNew( m_indiP_roi_check, st_newCallBack_stdCamera) < 0)
1369 #ifndef STDCAMERA_TEST_NOLOG
1370 derivedT::template log<software_error>({__FILE__,__LINE__});
1375 derived().createStandardIndiRequestSw( m_indiP_roi_set,
"roi_set");
1376 if( derived().registerIndiPropertyNew( m_indiP_roi_set, st_newCallBack_stdCamera) < 0)
1378 #ifndef STDCAMERA_TEST_NOLOG
1379 derivedT::template log<software_error>({__FILE__,__LINE__});
1384 derived().createStandardIndiRequestSw( m_indiP_roi_full,
"roi_set_full");
1385 if( derived().registerIndiPropertyNew( m_indiP_roi_full, st_newCallBack_stdCamera) < 0)
1387 #ifndef STDCAMERA_TEST_NOLOG
1388 derivedT::template log<software_error>({__FILE__,__LINE__});
1393 derived().createStandardIndiRequestSw( m_indiP_roi_fullbin,
"roi_set_full_bin");
1394 if( derived().registerIndiPropertyNew( m_indiP_roi_fullbin, st_newCallBack_stdCamera) < 0)
1396 #ifndef STDCAMERA_TEST_NOLOG
1397 derivedT::template log<software_error>({__FILE__,__LINE__});
1402 derived().createStandardIndiRequestSw( m_indiP_roi_loadlast,
"roi_load_last");
1403 if( derived().registerIndiPropertyNew( m_indiP_roi_loadlast, st_newCallBack_stdCamera) < 0)
1405 #ifndef STDCAMERA_TEST_NOLOG
1406 derivedT::template log<software_error>({__FILE__,__LINE__});
1411 derived().createStandardIndiRequestSw( m_indiP_roi_last,
"roi_set_last");
1412 if( derived().registerIndiPropertyNew( m_indiP_roi_last, st_newCallBack_stdCamera) < 0)
1414 #ifndef STDCAMERA_TEST_NOLOG
1415 derivedT::template log<software_error>({__FILE__,__LINE__});
1420 derived().createStandardIndiRequestSw( m_indiP_roi_default,
"roi_set_default");
1421 if( derived().registerIndiPropertyNew( m_indiP_roi_default, st_newCallBack_stdCamera) < 0)
1423 #ifndef STDCAMERA_TEST_NOLOG
1424 derivedT::template log<software_error>({__FILE__,__LINE__});
1430 if(derivedT::c_stdCamera_cropMode)
1432 derived().createStandardIndiToggleSw( m_indiP_cropMode,
"roi_crop_mode",
"Crop Mode",
"Crop Mode");
1433 if( derived().registerIndiPropertyNew( m_indiP_cropMode, st_newCallBack_stdCamera) < 0)
1435 #ifndef STDCAMERA_TEST_NOLOG
1436 derivedT::template log<software_error>({__FILE__,__LINE__});
1443 if(derivedT::c_stdCamera_hasShutter)
1445 derived().createROIndiText( m_indiP_shutterStatus,
"shutter_status",
"status",
"Shutter Status",
"Shutter",
"Status");
1446 m_indiP_shutterStatus[
"status"] = m_shutterStatus;
1447 if( derived().registerIndiPropertyReadOnly( m_indiP_shutterStatus ) < 0)
1449 #ifndef STDCAMERA_TEST_NOLOG
1450 derivedT::template log<software_error>({__FILE__,__LINE__});
1455 derived().createStandardIndiToggleSw( m_indiP_shutter,
"shutter",
"Shutter",
"Shutter");
1456 if( derived().registerIndiPropertyNew( m_indiP_shutter, st_newCallBack_stdCamera) < 0)
1458 #ifndef STDCAMERA_TEST_NOLOG
1459 derivedT::template log<software_error>({__FILE__,__LINE__});
1466 if(derivedT::c_stdCamera_usesStateString)
1468 derived().createROIndiText( m_indiP_stateString,
"state_string",
"current",
"State String",
"State",
"String");
1469 m_indiP_stateString.add(pcf::IndiElement(
"valid"));
1470 m_indiP_stateString[
"valid"] =
"no";
1471 if( derived().registerIndiPropertyReadOnly( m_indiP_stateString ) < 0)
1473 #ifndef STDCAMERA_TEST_NOLOG
1474 derivedT::template log<software_error>({__FILE__,__LINE__});
1483 template<
class derivedT>
1488 if(derived().powerOnWaitElapsed())
1493 derived().powerOnDefaults();
1495 if(derivedT::c_stdCamera_tempControl)
1498 if(m_startupTemp > -999) m_ccdTempSetpt = m_startupTemp;
1499 derived().updateIfChanged(m_indiP_temp,
"target", m_ccdTempSetpt,
INDI_IDLE);
1502 if(derivedT::c_stdCamera_usesROI)
1505 m_nextROI.x = m_currentROI.x;
1506 m_nextROI.y = m_currentROI.y;
1507 m_nextROI.w = m_currentROI.w;
1508 m_nextROI.h = m_currentROI.h;
1509 m_nextROI.bin_x = m_currentROI.bin_x;
1510 m_nextROI.bin_y = m_currentROI.bin_y;
1512 derived().updateIfChanged(m_indiP_roi_x,
"current", m_currentROI.x,
INDI_IDLE);
1513 derived().updateIfChanged(m_indiP_roi_x,
"target", m_nextROI.x,
INDI_IDLE);
1515 derived().updateIfChanged(m_indiP_roi_y,
"current", m_currentROI.y,
INDI_IDLE);
1516 derived().updateIfChanged(m_indiP_roi_y,
"target", m_nextROI.y,
INDI_IDLE);
1518 derived().updateIfChanged(m_indiP_roi_w,
"current", m_currentROI.w,
INDI_IDLE);
1519 derived().updateIfChanged(m_indiP_roi_w,
"target", m_nextROI.w,
INDI_IDLE);
1521 derived().updateIfChanged(m_indiP_roi_h,
"current", m_currentROI.h,
INDI_IDLE);
1522 derived().updateIfChanged(m_indiP_roi_h,
"target", m_nextROI.h,
INDI_IDLE);
1524 derived().updateIfChanged(m_indiP_roi_bin_x,
"current", m_currentROI.bin_x,
INDI_IDLE);
1525 derived().updateIfChanged(m_indiP_roi_bin_x,
"target", m_nextROI.bin_x,
INDI_IDLE);
1527 derived().updateIfChanged(m_indiP_roi_bin_y,
"current", m_currentROI.bin_y,
INDI_IDLE);
1528 derived().updateIfChanged(m_indiP_roi_bin_y,
"target", m_nextROI.bin_y,
INDI_IDLE);
1531 if(derivedT::c_stdCamera_hasShutter)
1533 if(m_shutterStatus ==
"OPERATING")
1535 derived().updateIfChanged(m_indiP_shutterStatus,
"status", m_shutterStatus,
INDI_BUSY);
1537 if(m_shutterStatus ==
"POWERON" || m_shutterStatus ==
"READY")
1539 derived().updateIfChanged(m_indiP_shutterStatus,
"status", m_shutterStatus,
INDI_OK);
1543 derived().updateIfChanged(m_indiP_shutterStatus,
"status", m_shutterStatus,
INDI_IDLE);
1546 if(m_shutterState == 1)
1548 derived().updateSwitchIfChanged(m_indiP_shutter,
"toggle", pcf::IndiElement::On,
INDI_OK);
1552 derived().updateSwitchIfChanged(m_indiP_shutter,
"toggle", pcf::IndiElement::Off,
INDI_IDLE);
1565 if(derivedT::c_stdCamera_usesROI)
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);
1591 template<
class derivedT>
1594 if( !derived().m_indiDriver )
return 0;
1596 if(derivedT::c_stdCamera_usesModes)
1598 for(
auto it = m_cameraModes.begin();
it!=m_cameraModes.end();++
it)
1600 derived().updateSwitchIfChanged(m_indiP_mode,
it->first, pcf::IndiElement::Off,
INDI_IDLE);
1604 if(derivedT::c_stdCamera_usesROI)
1626 if(derivedT::c_stdCamera_hasShutter)
1628 if(m_shutterStatus ==
"OPERATING")
1630 derived().updateIfChanged(m_indiP_shutterStatus,
"status", m_shutterStatus,
INDI_BUSY);
1632 if(m_shutterStatus ==
"POWERON" || m_shutterStatus ==
"READY")
1634 derived().updateIfChanged(m_indiP_shutterStatus,
"status", m_shutterStatus,
INDI_OK);
1638 derived().updateIfChanged(m_indiP_shutterStatus,
"status", m_shutterStatus,
INDI_IDLE);
1641 if(m_shutterState == 0)
1643 derived().updateSwitchIfChanged(m_indiP_shutter,
"toggle", pcf::IndiElement::On,
INDI_OK);
1647 derived().updateSwitchIfChanged(m_indiP_shutter,
"toggle", pcf::IndiElement::Off,
INDI_IDLE);
1654 template<
class derivedT>
1658 if(derivedT::c_stdCamera_hasShutter)
1660 if(m_shutterStatus ==
"OPERATING")
1662 derived().updateIfChanged(m_indiP_shutterStatus,
"status", m_shutterStatus,
INDI_BUSY);
1664 if(m_shutterStatus ==
"POWERON" || m_shutterStatus ==
"READY")
1666 derived().updateIfChanged(m_indiP_shutterStatus,
"status", m_shutterStatus,
INDI_OK);
1670 derived().updateIfChanged(m_indiP_shutterStatus,
"status", m_shutterStatus,
INDI_IDLE);
1673 if(m_shutterState == 0)
1675 derived().updateSwitchIfChanged(m_indiP_shutter,
"toggle", pcf::IndiElement::On,
INDI_OK);
1679 derived().updateSwitchIfChanged(m_indiP_shutter,
"toggle", pcf::IndiElement::Off,
INDI_IDLE);
1686 template<
class derivedT>
1693 template<
class derivedT>
1695 const pcf::IndiProperty &
ipRecv
1698 derivedT * _app =
static_cast<derivedT *
>(app);
1699 return _app->newCallBack_stdCamera(
ipRecv);
1702 template<
class derivedT>
1706 if(
ipRecv.getDevice() != derived().configName())
1708 #ifndef XWCTEST_INDI_CALLBACK_VALIDATION
1709 derivedT::template log<software_error>({__FILE__, __LINE__,
"unknown INDI property"});
1715 std::string name =
ipRecv.getName();
1717 if( name ==
"reconfigure")
return newCallBack_reconfigure(
ipRecv);
1718 else if(derivedT::c_stdCamera_temp && name ==
"temp_ccd")
return newCallBack_temp(
ipRecv);
1719 else if(derivedT::c_stdCamera_tempControl && name ==
"temp_ccd")
return newCallBack_temp(
ipRecv);
1720 else if(derivedT::c_stdCamera_tempControl && name ==
"temp_controller")
return newCallBack_temp_controller(
ipRecv);
1721 else if(derivedT::c_stdCamera_readoutSpeed && name ==
"readout_speed")
return newCallBack_readoutSpeed(
ipRecv);
1722 else if(derivedT::c_stdCamera_vShiftSpeed && name ==
"vshift_speed")
return newCallBack_vShiftSpeed(
ipRecv);
1723 else if(derivedT::c_stdCamera_emGain && name ==
"emgain")
return newCallBack_emgain(
ipRecv);
1724 else if(derivedT::c_stdCamera_exptimeCtrl && name ==
"exptime")
return newCallBack_exptime(
ipRecv);
1725 else if(derivedT::c_stdCamera_fpsCtrl && name ==
"fps")
return newCallBack_fps(
ipRecv);
1726 else if(derivedT::c_stdCamera_synchro && name ==
"synchro")
return newCallBack_synchro(
ipRecv);
1727 else if(derivedT::c_stdCamera_usesModes && name ==
"mode")
return newCallBack_mode(
ipRecv);
1728 else if(derivedT::c_stdCamera_cropMode && name ==
"roi_crop_mode")
return newCallBack_cropMode(
ipRecv);
1729 else if(derivedT::c_stdCamera_usesROI && name ==
"roi_region_x")
return newCallBack_roi_x(
ipRecv);
1730 else if(derivedT::c_stdCamera_usesROI && name ==
"roi_region_y")
return newCallBack_roi_y(
ipRecv);
1731 else if(derivedT::c_stdCamera_usesROI && name ==
"roi_region_w")
return newCallBack_roi_w(
ipRecv);
1732 else if(derivedT::c_stdCamera_usesROI && name ==
"roi_region_h")
return newCallBack_roi_h(
ipRecv);
1733 else if(derivedT::c_stdCamera_usesROI && name ==
"roi_region_bin_x")
return newCallBack_roi_bin_x(
ipRecv);
1734 else if(derivedT::c_stdCamera_usesROI && name ==
"roi_region_bin_y")
return newCallBack_roi_bin_y(
ipRecv);
1735 else if(derivedT::c_stdCamera_usesROI && name ==
"roi_region_check")
return newCallBack_roi_check(
ipRecv);
1736 else if(derivedT::c_stdCamera_usesROI && name ==
"roi_set")
return newCallBack_roi_set(
ipRecv);
1737 else if(derivedT::c_stdCamera_usesROI && name ==
"roi_set_full")
return newCallBack_roi_full(
ipRecv);
1738 else if(derivedT::c_stdCamera_usesROI && name ==
"roi_set_full_bin")
return newCallBack_roi_fullbin(
ipRecv);
1739 else if(derivedT::c_stdCamera_usesROI && name ==
"roi_load_last")
return newCallBack_roi_loadlast(
ipRecv);
1740 else if(derivedT::c_stdCamera_usesROI && name ==
"roi_set_last")
return newCallBack_roi_last(
ipRecv);
1741 else if(derivedT::c_stdCamera_usesROI && name ==
"roi_set_default")
return newCallBack_roi_default(
ipRecv);
1742 else if(derivedT::c_stdCamera_hasShutter && name ==
"shutter")
return newCallBack_shutter(
ipRecv);
1744 #ifndef XWCTEST_INDI_CALLBACK_VALIDATION
1745 derivedT::template log<software_error>({__FILE__,__LINE__,
"unknown INDI property"});
1751 template<
class derivedT>
1754 static_cast<void>(t);
1755 return derived().setTempSetPt();
1758 template<
class derivedT>
1761 static_cast<void>(f);
1765 template<
class derivedT>
1768 if(derivedT::c_stdCamera_tempControl)
1770 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
1776 std::unique_lock<std::mutex> lock(derived().m_indiMutex);
1778 if (derived().indiTargetUpdate(m_indiP_temp, target,
ipRecv,
true) < 0)
1780 derivedT::template log<software_error>({__FILE__, __LINE__});
1784 m_ccdTempSetpt = target;
1786 mx::meta::trueFalseT<derivedT::c_stdCamera_tempControl> tf;
1787 return setTempSetPt(tf);
1795 template<
class derivedT>
1798 static_cast<void>(t);
1799 return derived().setTempControl();
1802 template<
class derivedT>
1805 static_cast<void>(f);
1809 template<
class derivedT>
1812 if(derivedT::c_stdCamera_tempControl)
1814 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
1818 if(!
ipRecv.find(
"toggle"))
return 0;
1820 m_tempControlStatusSet =
false;
1822 std::unique_lock<std::mutex> lock(derived().m_indiMutex);
1824 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::On)
1826 m_tempControlStatusSet =
true;
1827 derived().updateSwitchIfChanged(m_indiP_tempcont,
"toggle", pcf::IndiElement::On,
INDI_BUSY);
1829 else if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::Off)
1831 m_tempControlStatusSet =
false;
1832 derived().updateSwitchIfChanged(m_indiP_tempcont,
"toggle", pcf::IndiElement::Off,
INDI_BUSY);
1835 mx::meta::trueFalseT<derivedT::c_stdCamera_emGain> tf;
1836 return setTempControl(tf);
1844 template<
class derivedT>
1847 static_cast<void>(t);
1848 return derived().setReadoutSpeed();
1851 template<
class derivedT>
1854 static_cast<void>(f);
1858 template<
class derivedT>
1861 if(derivedT::c_stdCamera_readoutSpeed)
1863 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
1867 std::unique_lock<std::mutex> lock(derived().m_indiMutex);
1869 std::string newspeed;
1871 for(
size_t i=0; i< m_readoutSpeedNames.size(); ++i)
1873 if(!
ipRecv.find(m_readoutSpeedNames[i]))
continue;
1875 if(
ipRecv[m_readoutSpeedNames[i]].getSwitchState() == pcf::IndiElement::On)
1879 derivedT::template log<text_log>(
"More than one readout speed selected",
logPrio::LOG_ERROR);
1883 newspeed = m_readoutSpeedNames[i];
1890 m_readoutSpeedNameSet = m_readoutSpeedName;
1894 m_readoutSpeedNameSet = newspeed;
1897 mx::meta::trueFalseT<derivedT::c_stdCamera_readoutSpeed> tf;
1898 return setReadoutSpeed(tf);
1904 template<
class derivedT>
1907 static_cast<void>(t);
1908 return derived().setVShiftSpeed();
1911 template<
class derivedT>
1914 static_cast<void>(f);
1918 template<
class derivedT>
1921 if(derivedT::c_stdCamera_vShiftSpeed)
1923 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
1927 std::unique_lock<std::mutex> lock(derived().m_indiMutex);
1929 std::string newspeed;
1931 for(
size_t i=0; i< m_vShiftSpeedNames.size(); ++i)
1933 if(!
ipRecv.find(m_vShiftSpeedNames[i]))
continue;
1935 if(
ipRecv[m_vShiftSpeedNames[i]].getSwitchState() == pcf::IndiElement::On)
1939 derivedT::template log<text_log>(
"More than one vShift speed selected",
logPrio::LOG_ERROR);
1943 newspeed = m_vShiftSpeedNames[i];
1950 m_vShiftSpeedNameSet = m_vShiftSpeedName;
1954 m_vShiftSpeedNameSet = newspeed;
1957 mx::meta::trueFalseT<derivedT::c_stdCamera_vShiftSpeed> tf;
1958 return setVShiftSpeed(tf);
1964 template<
class derivedT>
1967 static_cast<void>(t);
1968 return derived().setEMGain();
1971 template<
class derivedT>
1974 static_cast<void>(f);
1978 template<
class derivedT>
1981 if(derivedT::c_stdCamera_emGain)
1983 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
1989 std::unique_lock<std::mutex> lock(derived().m_indiMutex);
1991 if( derived().indiTargetUpdate( m_indiP_emGain, target,
ipRecv,
true) < 0)
1993 derivedT::template log<software_error>({__FILE__,__LINE__});
1997 m_emGainSet = target;
1999 mx::meta::trueFalseT<derivedT::c_stdCamera_emGain> tf;
2000 return setEMGain(tf);
2006 template<
class derivedT>
2009 static_cast<void>(t);
2010 return derived().setExpTime();
2013 template<
class derivedT>
2016 static_cast<void>(f);
2020 template<
class derivedT>
2023 if(derivedT::c_stdCamera_exptimeCtrl)
2025 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2031 std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2033 if( derived().indiTargetUpdate( m_indiP_exptime, target,
ipRecv,
true) < 0)
2035 derivedT::template log<software_error>({__FILE__,__LINE__});
2039 m_expTimeSet = target;
2041 mx::meta::trueFalseT<derivedT::c_stdCamera_exptimeCtrl> tf;
2042 return setExpTime(tf);
2048 template<
class derivedT>
2051 static_cast<void>(t);
2052 return derived().setFPS();
2055 template<
class derivedT>
2058 static_cast<void>(f);
2062 template<
class derivedT>
2065 if(derivedT::c_stdCamera_fpsCtrl)
2067 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2073 std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2075 if( derived().indiTargetUpdate( m_indiP_fps, target,
ipRecv,
true) < 0)
2077 derivedT::template log<software_error>({__FILE__,__LINE__});
2083 mx::meta::trueFalseT<derivedT::c_stdCamera_fpsCtrl> tf;
2090 template<
class derivedT>
2093 static_cast<void>(t);
2094 return derived().setSynchro();
2097 template<
class derivedT>
2100 static_cast<void>(f);
2104 template<
class derivedT>
2107 if(derivedT::c_stdCamera_synchro)
2109 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2113 if(!
ipRecv.find(
"toggle"))
return 0;
2115 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::Off )
2117 m_synchroSet =
false;
2120 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::On )
2122 m_synchroSet =
true;
2125 std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2127 mx::meta::trueFalseT<derivedT::c_stdCamera_synchro> tf;
2128 return setSynchro(tf);
2134 template<
class derivedT>
2137 if(derivedT::c_stdCamera_usesModes)
2139 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2143 std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2145 if(
ipRecv.getName() != m_indiP_mode.getName())
2147 derivedT::template log<software_error>({__FILE__, __LINE__,
"invalid indi property received"});
2152 std::string newName =
"";
2153 for(
auto it=m_cameraModes.begin();
it != m_cameraModes.end(); ++
it)
2155 if(!
ipRecv.find(
it->first))
continue;
2157 if(
ipRecv[
it->first].getSwitchState() == pcf::IndiElement::On)
2161 derivedT::template log<text_log>(
"More than one camera mode selected",
logPrio::LOG_ERROR);
2165 newName =
it->first;
2175 m_nextMode = newName;
2176 derived().m_reconfig =
true;
2186 template<
class derivedT>
2189 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2193 if(!
ipRecv.find(
"request"))
return 0;
2195 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
2197 std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2201 m_nextMode = m_modeName;
2202 derived().m_reconfig =
true;
2209 template<
class derivedT>
2212 static_cast<void>(t);
2213 return derived().setCropMode();
2216 template<
class derivedT>
2219 static_cast<void>(f);
2223 template<
class derivedT>
2226 if(derivedT::c_stdCamera_cropMode)
2228 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2232 if(!
ipRecv.find(
"toggle"))
return 0;
2234 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::Off )
2236 m_cropModeSet =
false;
2239 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::On )
2241 m_cropModeSet =
true;
2244 std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2246 mx::meta::trueFalseT<derivedT::c_stdCamera_cropMode> tf;
2247 return setCropMode(tf);
2254 template<
class derivedT>
2257 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2263 std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2265 if( derived().indiTargetUpdate( m_indiP_roi_x, target,
ipRecv,
false) < 0)
2267 m_nextROI.x = m_currentROI.x;
2268 derivedT::template log<software_error>({__FILE__,__LINE__});
2272 m_nextROI.x = target;
2277 template<
class derivedT>
2280 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2286 std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2288 if( derived().indiTargetUpdate( m_indiP_roi_y, target,
ipRecv,
false) < 0)
2290 m_nextROI.y = m_currentROI.y;
2291 derivedT::template log<software_error>({__FILE__,__LINE__});
2295 m_nextROI.y = target;
2300 template<
class derivedT>
2303 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2309 std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2311 if( derived().indiTargetUpdate( m_indiP_roi_w, target,
ipRecv,
false) < 0)
2313 m_nextROI.w = m_currentROI.w;
2314 derivedT::template log<software_error>({__FILE__,__LINE__});
2318 m_nextROI.w = target;
2323 template<
class derivedT>
2326 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2332 std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2334 if( derived().indiTargetUpdate( m_indiP_roi_h, target,
ipRecv,
false) < 0)
2336 derivedT::template log<software_error>({__FILE__,__LINE__});
2337 m_nextROI.h = m_currentROI.h;
2341 m_nextROI.h = target;
2346 template<
class derivedT>
2349 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2355 std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2357 if( derived().indiTargetUpdate( m_indiP_roi_bin_x, target,
ipRecv,
false) < 0)
2359 derivedT::template log<software_error>({__FILE__,__LINE__});
2360 m_nextROI.bin_x = m_currentROI.bin_x;
2364 m_nextROI.bin_x = target;
2369 template<
class derivedT>
2372 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2378 std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2380 if( derived().indiTargetUpdate( m_indiP_roi_bin_y, target,
ipRecv,
false) < 0)
2382 derivedT::template log<software_error>({__FILE__,__LINE__});
2383 m_nextROI.bin_y = m_currentROI.bin_y;
2387 m_nextROI.bin_y = target;
2392 template<
class derivedT>
2395 static_cast<void>(t);
2396 return derived().checkNextROI();
2399 template<
class derivedT>
2402 static_cast<void>(f);
2406 template<
class derivedT>
2409 if(derivedT::c_stdCamera_usesROI)
2411 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2415 if(!
ipRecv.find(
"request"))
return 0;
2417 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
2419 std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2423 mx::meta::trueFalseT<derivedT::c_stdCamera_usesROI> tf;
2424 return checkNextROI(tf);
2433 template<
class derivedT>
2436 static_cast<void>(t);
2437 return derived().setNextROI();
2440 template<
class derivedT>
2443 static_cast<void>(f);
2447 template<
class derivedT>
2450 if(derivedT::c_stdCamera_usesROI)
2452 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2456 if(!
ipRecv.find(
"request"))
return 0;
2458 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
2460 std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2464 m_lastROI = m_currentROI;
2466 mx::meta::trueFalseT<derivedT::c_stdCamera_usesROI> tf;
2467 return setNextROI(tf);
2476 template<
class derivedT>
2479 if(derivedT::c_stdCamera_usesROI)
2481 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2485 if(!
ipRecv.find(
"request"))
return 0;
2487 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
2489 std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2493 m_nextROI.x = m_full_x;
2494 m_nextROI.y = m_full_y;
2495 m_nextROI.w = m_full_w;
2496 m_nextROI.h = m_full_h;
2497 m_nextROI.bin_x = m_full_bin_x;
2498 m_nextROI.bin_y = m_full_bin_y;
2499 m_lastROI = m_currentROI;
2500 mx::meta::trueFalseT<derivedT::c_stdCamera_usesROI> tf;
2501 return setNextROI(tf);
2510 template<
class derivedT>
2513 if(derivedT::c_stdCamera_usesROI)
2515 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2519 if(!
ipRecv.find(
"request"))
return 0;
2521 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
2523 std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2529 if(m_full_currbin_x == 0)
2531 derivedT::template log<text_log>(
"current-binning full ROI not implemented for this camera",
logPrio::LOG_WARNING);
2532 m_full_currbin_x = m_full_x;
2533 m_full_currbin_y = m_full_y;
2534 m_full_currbin_w = m_full_w;
2535 m_full_currbin_h = m_full_h;
2541 m_nextROI.x = m_full_currbin_x;
2542 m_nextROI.y = m_full_currbin_y;
2543 m_nextROI.w = m_full_currbin_w;
2544 m_nextROI.h = m_full_currbin_h;
2548 m_nextROI.bin_x = m_full_bin_x;
2549 m_nextROI.bin_y = m_full_bin_y;
2552 m_full_currbin_x = 0;
2553 m_full_currbin_y = 0;
2554 m_full_currbin_w = 0;
2555 m_full_currbin_h = 0;
2559 m_nextROI.bin_x = m_currentROI.bin_x;
2560 m_nextROI.bin_y = m_currentROI.bin_y;
2563 m_lastROI = m_currentROI;
2564 mx::meta::trueFalseT<derivedT::c_stdCamera_usesROI> tf;
2565 return setNextROI(tf);
2574 template<
class derivedT>
2577 if(derivedT::c_stdCamera_usesROI)
2579 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2583 if(!
ipRecv.find(
"request"))
return 0;
2585 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
2587 std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2591 m_nextROI = m_lastROI;
2601 template<
class derivedT>
2604 if(derivedT::c_stdCamera_usesROI)
2606 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2609 if(!
ipRecv.find(
"request"))
return 0;
2611 if(
ipRecv[
"request"].getSwitchState() == pcf::IndiElement::On)
2613 std::unique_lock<std::mutex> lock(derived().m_indiMutex);
2617 m_nextROI = m_lastROI;
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.x = m_default_x;
2647 m_nextROI.y = m_default_y;
2648 m_nextROI.w = m_default_w;
2649 m_nextROI.h = m_default_h;
2650 m_nextROI.bin_x = m_default_bin_x;
2651 m_nextROI.bin_y = m_default_bin_y;
2652 m_lastROI = m_currentROI;
2653 mx::meta::trueFalseT<derivedT::c_stdCamera_usesROI> tf;
2654 return setNextROI(tf);
2663 template<
class derivedT>
2665 const mx::meta::trueFalseT<true> & t
2668 static_cast<void>(t);
2669 return derived().setShutter(ss);
2672 template<
class derivedT>
2674 const mx::meta::trueFalseT<false> & f
2677 static_cast<void>(ss);
2678 static_cast<void>(f);
2682 template<
class derivedT>
2685 if(derivedT::c_stdCamera_hasShutter)
2687 #ifdef XWCTEST_INDI_CALLBACK_VALIDATION
2691 if(!
ipRecv.find(
"toggle"))
return 0;
2693 mx::meta::trueFalseT<derivedT::c_stdCamera_hasShutter> tf;
2695 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::Off )
2700 if(
ipRecv[
"toggle"].getSwitchState() == pcf::IndiElement::On )
2710 template<
class derivedT>
2713 static_cast<void>(t);
2714 return derived().stateString();
2717 template<
class derivedT>
2720 static_cast<void>(f);
2724 template<
class derivedT>
2727 static_cast<void>(t);
2728 return derived().stateStringValid();
2731 template<
class derivedT>
2734 static_cast<void>(f);
2738 template<
class derivedT>
2741 if( !derived().m_indiDriver )
return 0;
2743 if(derivedT::c_stdCamera_readoutSpeed)
2748 if(derivedT::c_stdCamera_vShiftSpeed)
2753 if(derivedT::c_stdCamera_emGain)
2755 derived().updateIfChanged(m_indiP_emGain,
"current", m_emGain,
INDI_IDLE);
2756 derived().updateIfChanged(m_indiP_emGain,
"target", m_emGainSet,
INDI_IDLE);
2759 if(derivedT::c_stdCamera_exptimeCtrl)
2761 derived().updateIfChanged(m_indiP_exptime,
"current", m_expTime,
INDI_IDLE);
2762 derived().updateIfChanged(m_indiP_exptime,
"target", m_expTimeSet,
INDI_IDLE);
2765 if(derivedT::c_stdCamera_fpsCtrl)
2767 derived().updateIfChanged(m_indiP_fps,
"current", m_fps,
INDI_IDLE);
2768 derived().updateIfChanged(m_indiP_fps,
"target", m_fpsSet,
INDI_IDLE);
2770 else if(derivedT::c_stdCamera_fps)
2772 derived().updateIfChanged(m_indiP_fps,
"current", m_fps,
INDI_IDLE);
2775 if(derivedT::c_stdCamera_synchro)
2777 if(m_synchro ==
false)
2779 derived().updateSwitchIfChanged(m_indiP_synchro,
"toggle", pcf::IndiElement::Off,
INDI_IDLE);
2783 derived().updateSwitchIfChanged(m_indiP_synchro,
"toggle", pcf::IndiElement::On,
INDI_OK);
2787 if(derivedT::c_stdCamera_usesModes)
2789 auto st = pcf::IndiProperty::Ok;
2790 if(m_nextMode !=
"") st = pcf::IndiProperty::Busy;
2792 for(
auto it = m_cameraModes.begin();
it!=m_cameraModes.end();++
it)
2794 if(
it->first == m_modeName) derived().updateSwitchIfChanged(m_indiP_mode,
it->first, pcf::IndiElement::On, st);
2795 else derived().updateSwitchIfChanged(m_indiP_mode,
it->first, pcf::IndiElement::Off, st);
2800 if(derivedT::c_stdCamera_cropMode)
2802 if(m_cropMode ==
false)
2804 derived().updateSwitchIfChanged(m_indiP_cropMode,
"toggle", pcf::IndiElement::Off,
INDI_IDLE);
2808 derived().updateSwitchIfChanged(m_indiP_cropMode,
"toggle", pcf::IndiElement::On,
INDI_OK);
2812 if(derivedT::c_stdCamera_usesROI)
2816 derived().updateIfChanged(m_indiP_fullROI,
"x", m_full_x,
INDI_IDLE);
2817 derived().updateIfChanged(m_indiP_fullROI,
"y", m_full_y,
INDI_IDLE);
2818 derived().updateIfChanged(m_indiP_fullROI,
"w", m_full_w,
INDI_IDLE);
2819 derived().updateIfChanged(m_indiP_fullROI,
"h", m_full_h,
INDI_IDLE);
2822 if(derivedT::c_stdCamera_tempControl)
2824 if(m_tempControlStatus ==
false)
2826 derived().updateSwitchIfChanged( m_indiP_tempcont,
"toggle", pcf::IndiElement::Off,
INDI_IDLE);
2827 derived().updateIfChanged(m_indiP_temp,
"current", m_ccdTemp,
INDI_IDLE);
2828 derived().updateIfChanged(m_indiP_temp,
"target", m_ccdTempSetpt,
INDI_IDLE);
2829 derived().updateIfChanged( m_indiP_tempstat,
"status", m_tempControlStatusStr,
INDI_IDLE);
2833 if(m_tempControlOnTarget)
2835 derived().updateSwitchIfChanged( m_indiP_tempcont,
"toggle", pcf::IndiElement::On,
INDI_OK);
2836 derived().updateIfChanged(m_indiP_temp,
"current", m_ccdTemp,
INDI_OK);
2837 derived().updateIfChanged(m_indiP_temp,
"target", m_ccdTempSetpt,
INDI_OK);
2838 derived().updateIfChanged( m_indiP_tempstat,
"status", m_tempControlStatusStr,
INDI_OK);
2842 derived().updateSwitchIfChanged( m_indiP_tempcont,
"toggle", pcf::IndiElement::On,
INDI_BUSY);
2843 derived().updateIfChanged(m_indiP_temp,
"current", m_ccdTemp,
INDI_BUSY);
2844 derived().updateIfChanged(m_indiP_temp,
"target", m_ccdTempSetpt,
INDI_BUSY);
2845 derived().updateIfChanged( m_indiP_tempstat,
"status", m_tempControlStatusStr,
INDI_BUSY);
2849 else if(derivedT::c_stdCamera_temp)
2851 derived().updateIfChanged(m_indiP_temp,
"current", m_ccdTemp,
INDI_IDLE);
2856 if(derivedT::c_stdCamera_hasShutter)
2858 if(m_shutterStatus ==
"OPERATING")
2860 derived().updateIfChanged(m_indiP_shutterStatus,
"status", m_shutterStatus,
INDI_BUSY);
2862 if(m_shutterStatus ==
"POWERON" || m_shutterStatus ==
"READY")
2864 derived().updateIfChanged(m_indiP_shutterStatus,
"status", m_shutterStatus,
INDI_IDLE);
2868 derived().updateIfChanged(m_indiP_shutterStatus,
"status", m_shutterStatus,
INDI_IDLE);
2871 if(m_shutterState == 0)
2873 derived().updateSwitchIfChanged(m_indiP_shutter,
"toggle", pcf::IndiElement::On,
INDI_OK);
2877 derived().updateSwitchIfChanged(m_indiP_shutter,
"toggle", pcf::IndiElement::Off,
INDI_IDLE);
2881 if(derivedT::c_stdCamera_usesStateString)
2883 mx::meta::trueFalseT<derivedT::c_stdCamera_usesStateString> tf;
2884 derived().updateIfChanged(m_indiP_stateString,
"current", stateString(tf),
INDI_IDLE);
2885 if(stateStringValid(tf))
2887 derived().updateIfChanged(m_indiP_stateString,
"valid",
"yes",
INDI_IDLE);
2891 derived().updateIfChanged(m_indiP_stateString,
"valid",
"no",
INDI_IDLE);
2897 template<
class derivedT>
2900 static std::string last_mode;
2901 static roi last_roi;
2902 static float last_expTime = -1e30;
2903 static float last_fps = 0;
2904 static float last_adcSpeed = -1;
2905 static float last_emGain = -1;
2906 static float last_ccdTemp = 0;
2907 static float last_ccdTempSetpt = 0;
2908 static bool last_tempControlStatus = 0;
2909 static bool last_tempControlOnTarget = 0;
2910 static std::string last_tempControlStatusStr;
2911 static std::string last_shutterStatus;
2912 static int last_shutterState =
false;
2913 static bool last_synchro =
false;
2914 static float last_vshiftSpeed = -1;
2915 static bool last_cropMode =
false;
2918 if(force || m_modeName != last_mode ||
2919 m_currentROI.x != last_roi.
x ||
2920 m_currentROI.y != last_roi.
y ||
2921 m_currentROI.w != last_roi.
w ||
2922 m_currentROI.h != last_roi.
h ||
2923 m_currentROI.bin_x != last_roi.
bin_x ||
2924 m_currentROI.bin_y != last_roi.
bin_y ||
2925 m_expTime != last_expTime ||
2926 m_fps != last_fps ||
2927 m_emGain != last_emGain ||
2928 m_adcSpeed != last_adcSpeed ||
2929 m_ccdTemp != last_ccdTemp ||
2930 m_ccdTempSetpt != last_ccdTempSetpt ||
2931 m_tempControlStatus != last_tempControlStatus ||
2932 m_tempControlOnTarget != last_tempControlOnTarget ||
2933 m_tempControlStatusStr != last_tempControlStatusStr ||
2934 m_shutterStatus != last_shutterStatus ||
2935 m_shutterState != last_shutterState ||
2936 m_synchro != last_synchro ||
2937 m_vshiftSpeed != last_vshiftSpeed ||
2938 m_cropMode != last_cropMode)
2940 derived().template telem<telem_stdcam>({m_modeName, m_currentROI.x, m_currentROI.y,
2941 m_currentROI.w, m_currentROI.h, m_currentROI.bin_x, m_currentROI.bin_y,
2942 m_expTime, m_fps, m_emGain, m_adcSpeed, m_ccdTemp, m_ccdTempSetpt, (uint8_t) m_tempControlStatus,
2943 (uint8_t) m_tempControlOnTarget, m_tempControlStatusStr, m_shutterStatus, (int8_t) m_shutterState,
2944 (uint8_t) m_synchro, m_vshiftSpeed, (uint8_t) m_cropMode});
2946 last_mode = m_modeName;
2947 last_roi = m_currentROI;
2948 last_expTime = m_expTime;
2950 last_emGain = m_emGain;
2951 last_adcSpeed = m_adcSpeed;
2952 last_ccdTemp = m_ccdTemp;
2953 last_ccdTempSetpt = m_ccdTempSetpt;
2954 last_tempControlStatus = m_tempControlStatus;
2955 last_tempControlOnTarget = m_tempControlOnTarget;
2956 last_tempControlStatusStr = m_tempControlStatusStr;
2957 last_shutterStatus = m_shutterStatus;
2958 last_shutterState = m_shutterState;
2959 last_synchro = m_synchro;
2960 last_vshiftSpeed = m_vshiftSpeed;
2961 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, destroys the PdvDev structure.
@ 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
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