31#include <libnova/julian_day.h>
32#include <libnova/sidereal_time.h>
33#include <libnova/transform.h>
43#define DOME_SLAVING_TAB "Slaving"
44#define DOME_COORD_THRESHOLD \
53Dome::Dome() : ParkDataFileName(GetHomeDirectory() +
"/.indi/ParkData.xml")
69 ParkdataXmlRoot =
nullptr;
89std::string Dome::GetHomeDirectory()
const
92 const char * HomeDir = getenv(
"HOME");
97 HomeDir = getpwuid(getuid())->pw_dir;
99 return (HomeDir ? std::string(HomeDir) :
"");
110 PresetNP[0].
fill(
"Preset 1",
"",
"%6.2f", 0, 360.0, 1.0, 0);
111 PresetNP[1].
fill(
"Preset 2",
"",
"%6.2f", 0, 360.0, 1.0, 0);
112 PresetNP[2].
fill(
"Preset 3",
"",
"%6.2f", 0, 360.0, 1.0, 0);
170 DomeSpeedNP[0].
fill(
"DOME_SPEED_VALUE",
"RPM",
"%6.2f", 0.0, 10, 0.1, 1.0);
174 DomeSyncNP[0].
fill(
"DOME_SYNC_VALUE",
"Az",
"%.2f", 0.0, 360, 10, 0.0);
184 DomeAbsPosNP[0].
fill(
"DOME_ABSOLUTE_POSITION",
"Degrees",
"%6.2f", 0.0, 360.0, 1.0, 0.0);
188 DomeRelPosNP[0].
fill(
"DOME_RELATIVE_POSITION",
"Degrees",
"%6.2f", -180, 180.0, 10.0, 0.0);
196 DomeParamNP[0].
fill(
"AUTOSYNC_THRESHOLD",
"Autosync threshold (deg)",
"%6.2f", 0.0, 360.0, 1.0, 0.5);
249 return callHandshake();
259 return callHandshake();
394bool Dome::ISNewNumber(
const char * dev,
const char * name,
double values[],
char * names[],
int n)
432 LOGF_INFO(
"Dome slaving differential threshold updated to %.2f degrees.",
DomeParamNP[0].getValue());
438 auto newSpeed = values[0];
444 auto newPos = values[0];
450 auto newPos = values[0];
478 LOG_WARN(
"Dome backlash must be enabled first.");
482 auto steps =
static_cast<uint32_t
>(values[0]);
514 LOG_ERROR(
"Please unpark before issuing any motion commands.");
526 LOGF_INFO(
"Moving to Preset %d (%.2f degrees).", index + 1,
PresetNP[index].getValue());
545 LOGF_WARN(
"Dome will now be synced to mount azimuth position if the differential threshold exceeds %.2f degrees.",
549 m_MountUpdateTimer.
start(HORZ_UPDATE_TIMER);
553 LOG_WARN(
"Dome is no longer synced to mount azimuth position.");
555 m_MountUpdateTimer.
stop();
572 LOG_WARN(
"Dome shall be synced assuming OTA situated east of the pier");
576 LOG_WARN(
"Dome shall be synced assuming OTA situated west of the pier");
580 LOG_WARN(
"Dome shall be synced from pier side as reported by the mount.");
584 LOG_WARN(
"Dome shall be synced for OTA pier side derived from Hour Angle.");
588 LOG_WARN(
"Dome shall be synced by ignoring pier side as in a fork mount.");
602 for (
int i = 0; i < n; i++)
618 if (current_direction < 0)
643 for (
int i = 0; i < n; i++)
665 for (
int i = 0; i < n; i++)
669 if (
ParkSP[0].isNameMatch(names[i]))
700 if (sp->isNameMatch(
"PARK_CURRENT"))
704 else if (sp->isNameMatch(
"PARK_DEFAULT"))
708 else if (sp->isNameMatch(
"PARK_WRITE_DATA"))
712 LOG_INFO(
"Saved Park Status/Position.");
714 LOG_WARN(
"Can not save Park Status/Position.");
725 else if (!strcmp(name, AutoParkSP.name))
731 if (AutoParkS[0].s ==
ISS_ON)
732 LOG_WARN(
"Warning: Auto park is enabled. If weather conditions are in the "
733 "danger zone, the dome will be automatically parked. Only enable this "
734 "option is parking the dome at any time will not cause damage to any "
752 LOG_INFO(
"Mount Policy set to: Mount ignored. Dome can park regardless of mount parking state.");
754 LOG_WARN(
"Mount Policy set to: Mount locks. This prevents the dome from parking when mount is unparked.");
784 LOGF_INFO(
"Dome backlash is %s.", (enabled ?
"enabled" :
"disabled"));
791 LOG_ERROR(
"Failed to set trigger Dome backlash.");
800 controller->
ISNewSwitch(dev, name, states, names, n);
809bool Dome::ISNewText(
const char * dev,
const char * name,
char * texts[],
char * names[],
int n)
833 controller->
ISNewText(dev, name, texts, names, n);
850 int rc_ra = -1, rc_de = -1;
851 double ra = std::numeric_limits<double>::quiet_NaN(), de = std::numeric_limits<double>::quiet_NaN();
858 if (!strcmp(elemName,
"RA"))
860 else if (!strcmp(elemName,
"DEC"))
866 if (rc_ra == 0 && rc_de == 0 && !std::isnan(
ra) && !std::isnan(de))
873 if (
ra == 0 && de == 0)
884 LOGF_DEBUG(
"Calling Update mount to anticipate goto target: %g - DEC: %g",
888 UseHourAngle =
false;
897 int rc_ra = -1, rc_de = -1;
898 double ra = std::numeric_limits<double>::quiet_NaN(), de = std::numeric_limits<double>::quiet_NaN();
904 if (!strcmp(elemName,
"RA"))
906 else if (!strcmp(elemName,
"DEC"))
910 if (rc_ra == 0 && rc_de == 0 && !std::isnan(
ra) && !std::isnan(de))
917 if (
ra == 0 && de == 0)
920 char RAStr[64] = {0}, DEStr[64] = {0};
924 LOGF_DEBUG(
"Snooped RA %s DEC %s", RAStr, DEStr);
959 if (!strcmp(elemName,
"LONG"))
968 else if (!strcmp(elemName,
"LAT"))
984 bool prevState = IsLocked;
989 if ((!strcmp(elemName,
"PARK") && !strcmp(
pcdataXMLEle(ep),
"On")))
990 IsMountParked =
true;
991 else if ((!strcmp(elemName,
"UNPARK") && !strcmp(
pcdataXMLEle(ep),
"On")))
992 IsMountParked =
false;
994 if (IsLocked && !strcmp(elemName,
"PARK") && !strcmp(
pcdataXMLEle(ep),
"On"))
996 else if (!IsLocked && !strcmp(elemName,
"UNPARK") && !strcmp(
pcdataXMLEle(ep),
"On"))
1000 LOGF_INFO(
"Telescope status changed. Lock is set to: %s", IsLocked ?
"locked" :
"unlocked");
1008 if (!strcmp(
"WEATHER_STATUS", propName))
1019 if (AutoParkS[0].s ==
ISS_ON)
1021 LOG_WARN(
"Weather conditions in the danger zone! Parking dome...");
1026 LOG_WARN(
"Weather conditions in the danger zone! AutoPark is disabled. Please park the dome!");
1031 LOG_WARN(
"Weather conditions in the danger zone! Close the dome immediately!");
1044 if (!strcmp(elemName,
"PIER_EAST") && !strcmp(
pcdataXMLEle(ep),
"On"))
1046 else if (!strcmp(elemName,
"PIER_WEST") && !strcmp(
pcdataXMLEle(ep),
"On"))
1064 LOG_ERROR(
"Dome does not support backlash compensation.");
1114void Dome::triggerSnoop(
const char * driverName,
const char * snoopedProp)
1116 LOGF_DEBUG(
"Active Snoop, driver: %s, property: %s", driverName, snoopedProp);
1133 static_cast<Dome *
>(context)->processButton(button_n, state);
1139void Dome::processButton(
const char * button_n,
ISState state)
1146 if (!strcmp(button_n,
"Dome CW"))
1153 else if (!strcmp(button_n,
"Dome CCW"))
1160 else if (!strcmp(button_n,
"Dome Abort"))
1206 LOG_WARN(
"Unknown shutter status.");
1337 point3D MountCenter, OptCenter, OptVector, DomeIntersect;
1344 LOG_WARN(
"Geographic coordinates are not yet defined, triggering snoop...");
1348 double JD = ln_get_julian_from_sys();
1350 char lstStr[64], latStr[64], lonStr[64];
1351 fs_sexa(lstStr, LST, 2, 3600);
1356 LOGF_DEBUG(
"Coords - LST: %s, Lat: %s, Lon: %s", lstStr, latStr, lonStr);
1364 char raStr[64], decStr[64], haStr[64];
1367 fs_sexa(haStr, hourAngle, 2, 3600);
1371 char mountAzStr[64], mountAltStr[64];
1376 LOGF_DEBUG(
"Mount - RA: %s, Dec: %s, HA: %s --> Az: %s, Alt: %s", raStr, decStr, haStr, mountAzStr, mountAltStr);
1380 double effectiveHourAngle = hourAngle;
1381 const double poleThresholdDec = 89.0;
1385 const double POLE_AZIMUTH_DEVIATION_THRESHOLD = 30.0;
1388 auto performCalculations = [&](
double currentEffectiveHourAngle)
1399 double haForSide = nearPole ? currentEffectiveHourAngle : hourAngle;
1402 if (haForSide > 0.1 && haForSide < 11.9)
1424 fs_sexa(effHaStr, currentEffectiveHourAngle, 2, 3600);
1425 LOGF_DEBUG(
"Geom - Mount(E:%.2f,N:%.2f,Up:%.2f) OTA(SideSel:%d, SideUsed:%d, Off:%.2f, EffHA:%s) -> OptCenter(X:%.3f,Y:%.3f,Z:%.3f) OptVec(X:%.3f,Y:%.3f,Z:%.3f)",
1426 MountCenter.
x, MountCenter.
y, MountCenter.
z,
1428 OptCenter.
x, OptCenter.
y, OptCenter.
z,
1429 OptVector.
x, OptVector.
y, OptVector.
z);
1436 LOGF_DEBUG(
"Intersection mu1 < 0, using mu2 (%.3f)", mu2);
1440 DomeIntersect.
x = OptCenter.
x + mu1 * (OptVector.
x );
1441 DomeIntersect.
y = OptCenter.
y + mu1 * (OptVector.
y );
1442 DomeIntersect.
z = OptCenter.
z + mu1 * (OptVector.
z );
1443 LOGF_DEBUG(
"Intersection - Point(X:%.3f, Y:%.3f, Z:%.3f) Dist: %.3f", DomeIntersect.
x, DomeIntersect.
y, DomeIntersect.
z,
1447 Az = atan2(DomeIntersect.
x, DomeIntersect.
y) * 180.0 /
M_PI;
1459 if ((std::abs(DomeIntersect.
x) > 0.00001) || (std::abs(DomeIntersect.
y) > 0.00001))
1460 Alt = 180 * atan(DomeIntersect.
z / sqrt((DomeIntersect.
x * DomeIntersect.
x) + (DomeIntersect.
y * DomeIntersect.
y))) /
M_PI;
1469 minAz =
range360(Az - HalfApertureChordAngle);
1470 maxAz =
range360(Az + HalfApertureChordAngle);
1483 bool success = performCalculations(effectiveHourAngle);
1486 if (nearPole && success)
1488 double initialAz = Az;
1491 diff = 360.0 - diff;
1493 if (diff > POLE_AZIMUTH_DEVIATION_THRESHOLD)
1495 LOGF_DEBUG(
"Near pole, initial Az (%.2f) deviates from mount Az (%.2f) by %.2f degrees. Attempting alternative effectiveHourAngle.",
1499 effectiveHourAngle = (effectiveHourAngle == 0.0) ? 12.0 : 0.0;
1500 success = performCalculations(effectiveHourAngle);
1504 LOGF_DEBUG(
"Re-calculated Az (%.2f) with alternative effectiveHourAngle (%.2f).", Az, effectiveHourAngle);
1508 LOG_WARN(
"Re-calculation with alternative effectiveHourAngle failed.");
1516 char currentAzStr[64], targetAzStr[64], targetAltStr[64], minAzStr[64], maxAzStr[64];
1518 fs_sexa(targetAzStr, Az, 2, 3600);
1519 fs_sexa(targetAltStr, Alt, 2, 3600);
1520 fs_sexa(minAzStr, minAz, 2, 3600);
1521 fs_sexa(maxAzStr, maxAz, 2, 3600);
1522 LOGF_DEBUG(
"Result - Current Az:%s , Target Az: %s, Alt: %s --> Range Min: %s, Max: %s", currentAzStr, targetAzStr,
1523 targetAltStr, minAzStr, maxAzStr);
1528 LOG_WARN(
"Optical axis does not intersect dome sphere.");
1538 a = dp.
x * dp.
x + dp.
y * dp.
y + dp.
z * dp.
z;
1539 b = 2 * (dp.
x * p1.
x + dp.
y * p1.
y + dp.
z * p1.
z);
1541 c = c + p1.
x * p1.
x + p1.
y * p1.
y + p1.
z * p1.
z;
1543 bb4ac = b * b - 4 * a * c;
1544 if ((fabs(a) < 0.0000001) || (bb4ac < 0))
1551 mu1 = (-b + sqrt(bb4ac)) / (2 * a);
1552 mu2 = (-b - sqrt(bb4ac)) / (2 * a);
1560 double cosf, sinf, cosq, sinq;
1563 q =
M_PI * (90 - Lat) / 180;
1564 f = -
M_PI * (180 + Ah * 15) / 180;
1572 OP.
x = (dOpticalAxis * cosf + MountCenter.
x);
1573 OP.
y = (dOpticalAxis * sinf * cosq + MountCenter.
y);
1574 OP.
z = (dOpticalAxis * sinf * sinq + MountCenter.
z);
1583 q =
M_PI * Alt / 180;
1584 f =
M_PI * Az / 180;
1585 OV.
x = cos(q) * sin(f);
1586 OV.
y = cos(q) * cos(f);
1594 return 1.0 / sin(x);
1599 return 1.0 / cos(x);
1606 sinh_value = cos(lat) * cos(HA) * cos(
dec) + sin(lat) * sin(
dec);
1608 if (sinh_value >= 0.0)
1638 if (IsMountParked ==
false)
1651 if (AutoSyncWarning ==
false)
1653 LOG_WARN(
"Cannot perform autosync with dome parked. Please unpark to enable autosync operation.");
1654 AutoSyncWarning =
true;
1660 AutoSyncWarning =
false;
1661 double targetAz = 0, targetAlt = 0, minAz = 0, maxAz = 0;
1663 res =
GetTargetAz(targetAz, targetAlt, minAz, maxAz);
1666 LOGF_DEBUG(
"GetTargetAz failed %g", targetAz);
1670 double diff = std::abs(targetAz -
DomeAbsPosNP[0].getValue());
1672 diff = 360.0 - diff;
1677 LOGF_DEBUG(
"Dome synced to position %.2f degrees.", targetAz);
1679 LOGF_DEBUG(
"Dome is syncing to position %.2f degrees...", targetAz);
1681 LOG_ERROR(
"Dome failed to sync to new requested position.");
1702 return "Shutter is open.";
1704 return "Shutter is closed.";
1706 return "Shutter is moving.";
1708 return "Shutter has errors.";
1711 return "Shutter status is unknown.";
1741void Dome::SyncParkStatus(
bool isparked)
1743 IsParked = isparked;
1761 SyncParkStatus(isparked);
1775 LOGF_INFO(
"InitPark: No Park data in file %s: %s", ParkDataFileName.c_str(), loadres);
1776 SyncParkStatus(
false);
1784 LOGF_DEBUG(
"InitPark Axis1 %.2f", Axis1ParkPosition);
1799const char * Dome::LoadParkXML()
1808 bool devicefound =
false;
1811 ParkstatusXml =
nullptr;
1812 ParkdeviceXml =
nullptr;
1813 ParkpositionXml =
nullptr;
1814 ParkpositionAxis1Xml =
nullptr;
1816 if (wordexp(ParkDataFileName.c_str(), &wexp, 0))
1819 return "Badly formed filename.";
1822 if (!(fp = fopen(wexp.we_wordv[0],
"r")))
1825 return strerror(
errno);
1831 if (ParkdataXmlRoot)
1838 if (!ParkdataXmlRoot)
1842 return "Not a park data file";
1848 if (strcmp(
tagXMLEle(parkxml),
"device"))
1854 if (ap && (!strcmp(
valuXMLAtt(ap), ParkDeviceName)))
1863 return "No park data found for this device";
1865 ParkdeviceXml = parkxml;
1866 ParkstatusXml =
findXMLEle(parkxml,
"parkstatus");
1870 ParkpositionXml =
findXMLEle(parkxml,
"parkposition");
1871 ParkpositionAxis1Xml =
findXMLEle(ParkpositionXml,
"axis1position");
1873 if (ParkpositionAxis1Xml ==
nullptr)
1875 return "Park position invalid or missing.";
1878 else if (ParkstatusXml ==
nullptr)
1879 return "Park status invalid or missing.";
1888 const char * result = LoadParkXML();
1889 if (result !=
nullptr)
1898 double axis1Pos = std::numeric_limits<double>::quiet_NaN();
1900 int rc = sscanf(
pcdataXMLEle(ParkpositionAxis1Xml),
"%lf", &axis1Pos);
1903 return "Unable to parse Park Position Axis 1.";
1906 if (std::isnan(axis1Pos) ==
false)
1908 Axis1ParkPosition = axis1Pos;
1912 return "Failed to parse Park Position.";
1919 if (LoadParkXML() !=
nullptr)
1920 LOG_DEBUG(
"Failed to refresh parking data.");
1927 if (wordexp(ParkDataFileName.c_str(), &wexp, 0))
1930 LOGF_INFO(
"WriteParkData: can not write file %s: Badly formed filename.",
1931 ParkDataFileName.c_str());
1935 if (!(fp = fopen(wexp.we_wordv[0],
"w")))
1938 LOGF_INFO(
"WriteParkData: can not write file %s: %s", ParkDataFileName.c_str(),
1943 if (!ParkdataXmlRoot)
1944 ParkdataXmlRoot =
addXMLEle(
nullptr,
"parkdata");
1948 ParkdeviceXml =
addXMLEle(ParkdataXmlRoot,
"device");
1949 addXMLAtt(ParkdeviceXml,
"name", ParkDeviceName);
1953 ParkstatusXml =
addXMLEle(ParkdeviceXml,
"parkstatus");
1956 if (!ParkpositionXml)
1957 ParkpositionXml =
addXMLEle(ParkdeviceXml,
"parkposition");
1958 if (!ParkpositionAxis1Xml)
1959 ParkpositionAxis1Xml =
addXMLEle(ParkpositionXml,
"axis1position");
1962 editXMLEle(ParkstatusXml, (IsParked ?
"true" :
"false"));
1966 snprintf(pcdata,
sizeof(pcdata),
"%lf", Axis1ParkPosition);
1979 return Axis1ParkPosition;
1984 return Axis1DefaultParkPosition;
1989 Axis1ParkPosition = value;
1996 Axis1DefaultParkPosition = value;
2006 LOG_WARN(
"Please unpark the dome before issuing any motion commands.");
2014 LOG_WARN(
"Please stop dome before issuing any further motion commands.");
2043 LOG_ERROR(
"Dome does not support relative motion.");
2049 LOG_ERROR(
"Please unpark before issuing any motion commands.");
2057 LOG_WARN(
"Please stop dome before issuing any further motion commands.");
2070 LOGF_INFO(
"Dome moved %.2f degrees %s.", azDiff, (azDiff > 0) ?
"clockwise" :
"counter clockwise");
2084 LOGF_INFO(
"Dome moved %.2f degrees %s.", azDiff, (azDiff > 0) ?
"clockwise" :
"counter clockwise");
2102 LOG_WARN(
"Dome failed to move to new requested position.");
2111 LOG_ERROR(
"Dome does not support MoveAbs(). MoveAbs() must be implemented in the child class.");
2117 LOG_ERROR(
"Please unpark before issuing any motion commands.");
2125 LOG_WARN(
"Please stop dome before issuing any further motion commands.");
2133 LOGF_ERROR(
"Error: requested azimuth angle %.2f is out of range.", az);
2144 LOGF_INFO(
"Dome moved to position %.2f degrees azimuth.", az);
2153 LOGF_INFO(
"Dome is moving to position %.2f degrees azimuth...", az);
2167 LOG_INFO(
"Dome failed to move to new requested position.");
2175 LOG_WARN(
"Syncing is not supported.");
2183 LOG_ERROR(
"Dome does not support abort.");
2237 LOG_ERROR(
"Dome does not support variable speed.");
2258 LOG_ERROR(
"Dome does not have shutter control.");
2284 LOGF_INFO(
"Shutter is %s...", (operation == 0 ?
"opening" :
"closing"));
2290 LOGF_INFO(
"Shutter failed to %s.", (operation == 0 ?
"open" :
"close"));
2300 LOG_ERROR(
"Dome does not support parking.");
2321 LOG_INFO(
"Cannot Park Dome when mount is locking. See: Mount Policy in options tab.");
2353 LOG_ERROR(
"Dome does not support parking.");
2361 LOG_INFO(
"Dome already unparked.");
2380 LOG_WARN(
"Parking is not supported.");
2386 LOG_WARN(
"Parking is not supported.");
2395bool Dome::callHandshake()
2397 if (domeConnection > 0)
2410 return domeConnection;
2417 if (value == 0 || (mask & value) == 0)
2419 LOGF_ERROR(
"Invalid connection mode %d", value);
2423 domeConnection = value;
void registerHandshake(std::function< bool()> callback)
registerHandshake Register a handshake function to be called once the initial connection to the devic...
The Serial class manages connection with serial devices including Bluetooth. Serial communication is ...
The TCP class manages connection with devices over the network via TCP/IP. Upon successful connection...
const char * getDeviceName() const
INDI::PropertyText getText(const char *name) const
The Controller class provides functionality to access a controller (e.g. joystick) input and send it ...
void setButtonCallback(buttonFunc buttonCallback)
setButtonCallback Sets the callback function when a new button input is detected.
virtual bool ISSnoopDevice(XMLEle *root)
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
void mapController(const char *propertyName, const char *propertyLabel, ControllerType type, const char *initialValue)
mapController adds a new property to the joystick's settings.
virtual bool initProperties()
virtual bool saveConfigItems(FILE *fp)
virtual void ISGetProperties(const char *dev)
virtual bool updateProperties()
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
virtual bool saveConfig(bool silent=false, const char *property=nullptr)
Save the current properties in a configuration file.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process the client newSwitch command.
void registerConnection(Connection::Interface *newConnection)
registerConnection Add new connection plugin to the existing connection pool. The connection type sha...
virtual void ISGetProperties(const char *dev)
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
virtual bool ISSnoopDevice(XMLEle *root)
Process a snoop event from INDI server. This function is called when a snooped property is updated in...
void setDriverInterface(uint32_t value)
setInterface Set driver interface. By default the driver interface is set to GENERAL_DEVICE....
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
void defineProperty(INumberVectorProperty *property)
virtual bool saveConfigItems(FILE *fp)
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
virtual bool initProperties()
Initialize properties initial state and value. The child class must implement this function.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process the client newNumber command.
Connection::Interface * getActiveConnection()
void addDebugControl()
Add Debug control to the driver.
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
Process the client newSwitch command.
Class to provide general functionality of a Dome device.
INDI::PropertySwitch PresetGotoSP
INDI::IHorizontalCoordinates mountHoriztonalCoords
Connection::TCP * tcpConnection
virtual IPState UnPark()
UnPark dome. The action of the Unpark command is dome specific, but it may include opening the shutte...
void SetParked(bool isparked)
SetParked Change the mount parking status. The data park file (stored in ~/.indi/ParkData....
void SetDomeCapability(uint32_t cap)
SetDomeCapability set the dome capabilities. All capabilities must be initialized.
void setDomeConnection(const uint8_t &value)
setDomeConnection Set Dome connection mode. Child class should call this in the constructor before Do...
INDI::PropertySwitch ShutterParkPolicySP
INDI::PropertySwitch ParkOptionSP
const char * GetShutterStatusString(ShutterState status)
getShutterStatusString
INDI::IEquatorialCoordinates mountEquatorialCoords
bool CheckHorizon(double HA, double dec, double lat)
CheckHorizon Returns true if telescope points above horizon.
INDI::PropertyNumber DomeRelPosNP
bool isParked()
isParked is dome currently parked?
INDI::PropertyNumber DomeParamNP
bool OpticalCenter(point3D MountCenter, double dOpticalAxis, double Lat, double Ah, point3D &OP)
OpticalCenter This function calculates the distance from the optical axis to the Dome center.
INDI::PropertyNumber ParkPositionNP
virtual bool SetSpeed(double rpm)
SetSpeed Set Dome speed. This does not initiate motion, it sets the speed for the next motion command...
virtual bool Sync(double az)
Sync sets the dome current azimuth as the supplied azimuth position.
virtual void ISGetProperties(const char *dev) override
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
ShutterState m_ShutterState
void SetAxis1Park(double value)
SetRAPark Set current AZ parking position. The data park file (stored in ~/.indi/ParkData....
void UpdateMountCoords()
updateCoords updates the horizontal coordinates (Az & Alt) of the mount from the snooped RA,...
IPState getMountState() const
void SetAxis1ParkDefault(double steps)
SetAxis1Park Set default AZ parking position.
ShutterOperation
Shutter operation command.
INDI::PropertySwitch AbortSP
INDI::PropertyNumber DomeSpeedNP
virtual bool initProperties() override
Initialize properties initial state and value. The child class must implement this function.
INDI::PropertyNumber DomeMeasurementsNP
virtual void UpdateAutoSync()
UpdateAutoSync This function calculates the target dome azimuth from the mount's target coordinates g...
INDI::PropertyNumber DomeBacklashNP
virtual IPState MoveRel(double azDiff)
Move the Dome to an relative position.
bool isLocked()
isLocked, is the dome currently locked?
virtual void ActiveDevicesUpdated()
INDI::PropertySwitch ParkSP
virtual bool SetBacklash(int32_t steps)
SetBacklash Set the dome backlash compensation value.
double GetAxis1ParkDefault()
virtual IPState Park()
Goto Park Position. The park position is an absolute azimuth value.
const char * LoadParkData()
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
INDI::PropertyNumber DomeAbsPosNP
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual bool SetDefaultPark()
SetDefaultPark Set default coordinates/encoders value as the desired parking position.
bool Intersection(point3D p1, point3D p2, double r, double &mu1, double &mu2)
Intersection Calculate the intersection of a ray and a sphere. The line segment is defined from p1 to...
virtual bool SetBacklashEnabled(bool enabled)
SetBacklashEnabled Enables or disables the dome backlash compensation.
virtual IPState MoveAbs(double az)
Move the Dome to an absolute azimuth.
INDI::PropertySwitch DomeMotionSP
IGeographicCoordinates observer
virtual bool ISSnoopDevice(XMLEle *root) override
Process a snoop event from INDI server. This function is called when a snooped property is updated in...
static void buttonHelper(const char *button_n, ISState state, void *context)
INDI::PropertySwitch DomeBacklashSP
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Saves the Device Port and Dome Presets in the configuration file
virtual bool SetCurrentPark()
SetCurrentPark Set current coordinates/encoders value as the desired parking position.
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
void setShutterState(const ShutterState &value)
bool OpticalVector(double Az, double Alt, point3D &OV)
OpticalVector This function calculates a second point for determining the optical axis.
void setDomeState(const DomeState &value)
bool InitPark()
InitPark Loads parking data (stored in ~/.indi/ParkData.xml) that contains parking status and parking...
Connection::Serial * serialConnection
INDI::PropertySwitch MountPolicySP
void SetParkDataType(DomeParkData type)
setParkDataType Sets the type of parking data stored in the park data file and presented to the user.
INDI::PropertySwitch DomeAutoSyncSP
INDI::PropertySwitch DomeShutterSP
DomeParkData parkDataType
virtual bool Handshake()
perform handshake with device to check communication
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual IPState ControlShutter(ShutterOperation operation)
Open or Close shutter.
INDI::PropertyText ActiveDeviceTP
INDI::PropertySwitch OTASideSP
bool GetTargetAz(double &Az, double &Alt, double &minAz, double &maxAz)
GetTargetAz.
INDI::PropertyNumber DomeSyncNP
uint8_t getDomeConnection() const
virtual IPState Move(DomeDirection dir, DomeMotionCommand operation)
Move the Dome in a particular direction.
INDI::PropertyNumber PresetNP
virtual bool Abort()
Abort all dome motion.
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
bool load()
load Attempt to load property values from configuration file.
void save(FILE *f) const
save Save property to configuration file.
void setLabel(const char *label)
bool isNameMatch(const char *otherName) const
bool update(const double values[], const char *const names[], int n)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
bool update(const ISState states[], const char *const names[], int n)
INDI::WidgetViewSwitch * findOnSwitch() const
int findOnSwitchIndex() const
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, ISRule rule, double timeout, IPState state)
bool update(const char *const texts[], const char *const names[], int n)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
INDI::PropertyViewText * getText() const
void callOnTimeout(const std::function< void()> &callback)
void start()
Starts or restarts the timer with the timeout specified in interval.
void stop()
Stops the timer.
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
const char * SITE_TAB
SITE_TAB Where all site information setting are located.
const char * OPTIONS_TAB
OPTIONS_TAB Where all the driver's options are located. Those may include auxiliary controls,...
int f_scansexa(const char *str0, double *dp)
convert sexagesimal string str AxBxC to double. x can be anything non-numeric. Any missing A,...
double range360(double r)
range360 Limits an angle to be between 0-360 degrees.
int fs_sexa(char *out, double a, int w, int fracbase)
Converts a sexagesimal number to a string. sprint the variable a in sexagesimal format into out[].
double get_local_hour_angle(double sideral_time, double ra)
get_local_hour_angle Returns local hour angle of an object
Implementations for common driver routines.
double get_local_sidereal_time(double longitude)
get_local_sidereal_time Returns local sidereal time given longitude and system clock.
int crackIPState(const char *str, IPState *ip)
Extract property state (Idle, OK, Busy, Alert) from the supplied string.
#define DOME_COORD_THRESHOLD
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector property.
void IDSetSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
void IDSnoopDevice(const char *snooped_device, const char *snooped_property)
Function a Driver calls to snoop on another Device. Snooped messages will then arrive via ISSnoopDevi...
#define LOGF_INFO(fmt,...)
#define DEBUG(priority, msg)
Macro to print log messages. Example of usage of the Logger: DEBUG(DBG_DEBUG, "hello " << "world");.
#define LOGF_WARN(fmt,...)
#define LOGF_DEBUG(fmt,...)
#define LOG_ERROR(txt)
Shorter logging macros. In order to use these macros, the function (or method) "getDeviceName()" must...
#define LOGF_ERROR(fmt,...)
const char * findXMLAttValu(XMLEle *ep, const char *name)
Find an XML element's attribute value.
XMLEle * nextXMLEle(XMLEle *ep, int init)
Iterate an XML element for a list of nesetd XML elements.
XMLAtt * findXMLAtt(XMLEle *ep, const char *name)
Find an XML attribute within an XML element.
LilXML * newLilXML()
Create a new lilxml parser.
char * tagXMLEle(XMLEle *ep)
Return the tag of an XML element.
XMLEle * addXMLEle(XMLEle *parent, const char *tag)
add an element with the given tag to the given element. parent can be NULL to make a new root.
XMLEle * findXMLEle(XMLEle *ep, const char *tag)
Find an XML element within an XML element.
char * valuXMLAtt(XMLAtt *ap)
Return the value of an XML attribute.
void editXMLEle(XMLEle *ep, const char *pcdata)
set the pcdata of the given element
void prXMLEle(FILE *fp, XMLEle *ep, int level)
Print an XML element.
void delXMLEle(XMLEle *ep)
delXMLEle Delete XML element.
char * pcdataXMLEle(XMLEle *ep)
Return the pcdata of an XML element.
void delLilXML(LilXML *lp)
Delete a lilxml parser.
XMLAtt * addXMLAtt(XMLEle *ep, const char *name, const char *valu)
Add an XML attribute to an existing XML element.
XMLEle * readXMLFile(FILE *fp, LilXML *lp, char ynot[])
Handy wrapper to read one xml file.
Namespace to encapsulate INDI client, drivers, and mediator classes.
void EquatorialToHorizontal(IEquatorialCoordinates *object, IGeographicCoordinates *observer, double JD, IHorizontalCoordinates *position)
EquatorialToHorizontal Calculate horizontal coordinates from equatorial coordinates.