26 #include <libnova/sidereal_time.h>
27 #include <libnova/transform.h>
43 :
DefaultDevice(), ScopeConfigFileName(GetHomeDirectory() +
"/.indi/ScopeConfig.xml"),
44 ParkDataFileName(GetHomeDirectory() +
"/.indi/ParkData.xml")
127 IUFillSwitchVector(&
PECStateSP,
PECStateS, 2,
getDeviceName(),
"PEC",
"PEC Playback",
MOTION_TAB,
IP_RW,
ISR_1OFMANY, 0,
179 char curTime[32] = {0};
180 std::time_t t = std::time(
nullptr);
181 struct std::tm *utctimeinfo = std::gmtime(&t);
182 strftime(curTime,
sizeof(curTime),
"%Y-%m-%dT%H:%M:%S", utctimeinfo);
289 double longitude = 0, latitude = 0, elevation = 0;
499 auto useJoystick =
getSwitch(
"USEJOYSTICK");
504 if (useJoystick[0].getState() ==
ISS_ON)
537 if (
HasLocation() && !strcmp(propName,
"GEOGRAPHIC_COORD"))
543 double longitude = -1, latitude = -1, elevation = -1;
549 if (!strcmp(elemName,
"LAT"))
551 else if (!strcmp(elemName,
"LONG"))
553 else if (!strcmp(elemName,
"ELEV"))
557 return processLocationInfo(latitude, longitude, elevation);
559 else if (
HasTime() && !strcmp(propName,
"TIME_UTC"))
571 if (!strcmp(elemName,
"UTC"))
573 else if (!strcmp(elemName,
"OFFSET"))
577 return processTimeInfo(utc, offset);
579 else if (!strcmp(propName,
"DOME_PARK"))
587 if ((DomeClosedLockT[2].s ==
ISS_ON || DomeClosedLockT[3].s ==
ISS_ON) && !IsLocked && !
IsParked)
592 if (( (!strcmp(elemName,
"SHUTTER_CLOSE") || !strcmp(elemName,
"PARK"))
597 LOG_INFO(
"Dome is closing, parking mount...");
606 bool prevState = IsLocked;
611 if (!IsLocked && (!strcmp(elemName,
"PARK")) && !strcmp(
pcdataXMLEle(ep),
"On"))
613 else if (IsLocked && (!strcmp(elemName,
"UNPARK")) && !strcmp(
pcdataXMLEle(ep),
"On"))
617 LOGF_INFO(
"Dome status changed. Lock is set to: %s", IsLocked ?
"locked" :
"unlock");
626 void Telescope::triggerSnoop(
const char *driverName,
const char *snoopedProp)
628 LOGF_DEBUG(
"Active Snoop, driver: %s, property: %s", driverName, snoopedProp);
634 return telescopeConnection;
641 if (value == 0 || (mask & value) == 0)
647 telescopeConnection = value;
723 if (std::abs(
EqN[
AXIS_RA].value -
ra) > EQ_NOTIFY_THRESHOLD ||
725 EqNP.
s != lastEqState)
729 lastEqState =
EqNP.
s;
778 return processTimeInfo(texts[utcindex], texts[offsetindex]);
796 if (name && std::string(name) ==
"SCOPE_CONFIG_NAME")
806 controller->
ISNewText(dev, name, texts, names, n);
822 if (strcmp(name,
"EQUATORIAL_EOD_COORD") == 0)
829 for (
int x = 0; x < n; x++)
841 if ((
ra >= 0) && (
ra <= 24) && (
dec >= -90) && (
dec <= 90))
849 "Please unpark the mount before issuing any motion/sync commands.");
861 if ((sw !=
nullptr) && (sw->s ==
ISS_ON))
897 if (strcmp(name,
"GEOGRAPHIC_COORD") == 0)
901 int elevationindex =
IUFindIndex(
"ELEV", names, n);
903 if (latindex == -1 || longindex == -1 || elevationindex == -1)
909 double targetLat = values[latindex];
910 double targetLong = values[longindex];
911 double targetElev = values[elevationindex];
913 return processLocationInfo(targetLat, targetLong, targetElev);
919 if (strcmp(name,
"TELESCOPE_INFO") == 0)
934 double axis1 = std::numeric_limits<double>::quiet_NaN(), axis2 = std::numeric_limits<double>::quiet_NaN();
935 for (
int x = 0; x < n; x++)
948 if (std::isnan(axis1) ==
false && std::isnan(axis2) ==
false)
992 LOG_ERROR(
"Cannot reverse tracking while tracking is engaged. Disengage tracking then try again.");
1011 LOG_INFO(
"Custom tracking rates set. Tracking mode must be set to Custom for these rates to take effect.");
1072 LOG_INFO(
"Parking/Unparking aborted.");
1087 LOG_INFO(
"Telescope already unparked.");
1098 LOG_WARN(
"Cannot unpark mount when dome is locking. See: Dome Policy in options tab.");
1109 LOG_INFO(
"Telescope already parked.");
1154 "Please unpark the mount before issuing any motion/sync commands.");
1227 "Please unpark the mount before issuing any motion/sync commands.");
1402 if (previousState == targetState)
1453 LOG_INFO(
"Can not change park position while slewing or already parked...");
1470 LOG_INFO(
"Saved Park Status/Position.");
1496 LOG_INFO(
"Dome Policy set to: Dome ignored. Mount can park or unpark regardless of dome parking state.");
1498 LOG_WARN(
"Dome Policy set to: Dome locks. This prevents the mount from unparking when dome is parked.");
1500 else if (!strcmp(names[0], DomeClosedLockT[2].name))
1501 LOG_INFO(
"Warning: Dome parking policy set to: Dome parks. This tells "
1502 "scope to park if dome is parking. This will disable the locking "
1503 "for dome parking, EVEN IF MOUNT PARKING FAILS");
1504 else if (!strcmp(names[0], DomeClosedLockT[3].name))
1505 LOG_INFO(
"Warning: Dome parking policy set to: Both. This disallows the "
1506 "scope from unparking when dome is parked, and tells scope to "
1507 "park if dome is parking. This will disable the locking for dome "
1508 "parking, EVEN IF MOUNT PARKING FAILS.");
1527 LOG_INFO(
"Cannot determine whether pier side simulation should be switched on or off.");
1532 bool pierSideEnabled = index == 0;
1534 LOGF_INFO(
"Simulating Pier Side %s.", (pierSideEnabled ?
"enabled" :
"disabled"));
1537 if (pierSideEnabled)
1555 LOG_INFO(
"Motion control is set to 4-way joystick.");
1557 LOG_INFO(
"Motion control is set to 2 separate axes.");
1572 LOG_INFO(
"Joystick motion is locked to West/East axis only.");
1574 LOG_INFO(
"Joystick motion is locked to North/South axis only.");
1576 LOG_INFO(
"Joystick motion is unlocked.");
1583 if (name && std::string(name) ==
"APPLY_SCOPE_CONFIG")
1593 bool rc = controller->
ISNewSwitch(dev, name, states, names, n);
1596 auto useJoystick =
getSwitch(
"USEJOYSTICK");
1597 if (useJoystick && useJoystick[0].getState() ==
ISS_ON)
1616 if (telescopeConnection > 0)
1726 bool Telescope::processTimeInfo(
const char *utc,
const char *offset)
1728 struct ln_date utc_date;
1729 double utc_offset = 0;
1738 utc_offset = atof(offset);
1756 bool Telescope::processLocationInfo(
double latitude,
double longitude,
double elevation)
1770 if (latitude == 0 && longitude == 0)
1772 LOG_DEBUG(
"Silently ignoring invalid latitude and longitude.");
1828 double display_longitude = longitude > 180 ? longitude - 360 : longitude;
1830 fs_sexa(lng_str, display_longitude, 2, 36000);
1846 nSlewRate = slewRateCount;
1869 for (
int i = 0; i < nSlewRate; i++)
1872 snprintf(name, 4,
"%dx", i + 1);
1980 LOGF_INFO(
"InitPark: No Park data in file %s: %s", ParkDataFileName.c_str(), loadres);
1987 LOGF_DEBUG(
"InitPark Axis1 %.2f Axis2 %.2f", Axis1ParkPosition, Axis2ParkPosition);
1995 const char *Telescope::LoadParkXML()
2000 static char errmsg[512];
2002 XMLEle *parkxml =
nullptr;
2004 bool devicefound =
false;
2007 ParkstatusXml =
nullptr;
2008 ParkdeviceXml =
nullptr;
2009 ParkpositionXml =
nullptr;
2010 ParkpositionAxis1Xml =
nullptr;
2011 ParkpositionAxis2Xml =
nullptr;
2013 if (wordexp(ParkDataFileName.c_str(), &wexp, 0))
2016 return "Badly formed filename.";
2019 if (!(fp = fopen(wexp.we_wordv[0],
"r")))
2022 return strerror(
errno);
2028 if (ParkdataXmlRoot)
2035 if (!ParkdataXmlRoot)
2041 return "Empty park file.";
2043 if (!strcmp(
tagXMLEle(parkxml),
"parkdata"))
2046 return "Not a park data file";
2051 if (strcmp(
tagXMLEle(parkxml),
"device"))
2057 if (ap && (!strcmp(
valuXMLAtt(ap), ParkDeviceName)))
2068 return "No park data found for this device";
2071 ParkdeviceXml = parkxml;
2072 ParkstatusXml =
findXMLEle(parkxml,
"parkstatus");
2073 ParkpositionXml =
findXMLEle(parkxml,
"parkposition");
2074 if (ParkpositionXml)
2075 ParkpositionAxis1Xml =
findXMLEle(ParkpositionXml,
"axis1position");
2076 if (ParkpositionXml)
2077 ParkpositionAxis2Xml =
findXMLEle(ParkpositionXml,
"axis2position");
2079 if (ParkstatusXml ==
nullptr || ParkpositionAxis1Xml ==
nullptr || ParkpositionAxis2Xml ==
nullptr)
2081 return "Park data invalid or missing.";
2091 const char *result = LoadParkXML();
2092 if (result !=
nullptr)
2098 double axis1Pos = std::numeric_limits<double>::quiet_NaN();
2099 double axis2Pos = std::numeric_limits<double>::quiet_NaN();
2101 int rc = sscanf(
pcdataXMLEle(ParkpositionAxis1Xml),
"%lf", &axis1Pos);
2104 return "Unable to parse Park Position Axis 1.";
2106 rc = sscanf(
pcdataXMLEle(ParkpositionAxis2Xml),
"%lf", &axis2Pos);
2109 return "Unable to parse Park Position Axis 2.";
2112 if (std::isnan(axis1Pos) ==
false && std::isnan(axis2Pos) ==
false)
2114 Axis1ParkPosition = axis1Pos;
2115 Axis2ParkPosition = axis2Pos;
2119 return "Failed to parse Park Position.";
2126 if (LoadParkXML() !=
nullptr)
2127 LOG_DEBUG(
"Failed to refresh parking data.");
2132 static char errmsg[512];
2134 XMLEle *parkxml =
nullptr;
2136 bool devicefound =
false;
2140 if (wordexp(ParkDataFileName.c_str(), &wexp, 0))
2146 if (!(fp = fopen(wexp.we_wordv[0],
"r")))
2156 if (ParkdataXmlRoot)
2163 if (!ParkdataXmlRoot)
2171 if (!strcmp(
tagXMLEle(parkxml),
"parkdata"))
2179 if (strcmp(
tagXMLEle(parkxml),
"device"))
2185 if (ap && (!strcmp(
valuXMLAtt(ap), ParkDeviceName)))
2198 ParkstatusXml =
nullptr;
2199 ParkdeviceXml =
nullptr;
2200 ParkpositionXml =
nullptr;
2201 ParkpositionAxis1Xml =
nullptr;
2202 ParkpositionAxis2Xml =
nullptr;
2204 wordexp(ParkDataFileName.c_str(), &wexp, 0);
2205 if (!(fp = fopen(wexp.we_wordv[0],
"w")))
2208 LOGF_INFO(
"WriteParkData: can not write file %s: %s", ParkDataFileName.c_str(), strerror(
errno));
2222 if (LoadParkXML() !=
nullptr)
2223 LOG_DEBUG(
"Failed to refresh parking data.");
2230 if (wordexp(ParkDataFileName.c_str(), &wexp, 0))
2233 LOGF_INFO(
"WriteParkData: can not write file %s: Badly formed filename.",
2234 ParkDataFileName.c_str());
2238 if (!(fp = fopen(wexp.we_wordv[0],
"w")))
2241 LOGF_INFO(
"WriteParkData: can not write file %s: %s", ParkDataFileName.c_str(),
2246 if (!ParkdataXmlRoot)
2247 ParkdataXmlRoot =
addXMLEle(
nullptr,
"parkdata");
2251 ParkdeviceXml =
addXMLEle(ParkdataXmlRoot,
"device");
2252 addXMLAtt(ParkdeviceXml,
"name", ParkDeviceName);
2256 ParkstatusXml =
addXMLEle(ParkdeviceXml,
"parkstatus");
2257 if (!ParkpositionXml)
2258 ParkpositionXml =
addXMLEle(ParkdeviceXml,
"parkposition");
2259 if (!ParkpositionAxis1Xml)
2260 ParkpositionAxis1Xml =
addXMLEle(ParkpositionXml,
"axis1position");
2261 if (!ParkpositionAxis2Xml)
2262 ParkpositionAxis2Xml =
addXMLEle(ParkpositionXml,
"axis2position");
2266 snprintf(pcdata,
sizeof(pcdata),
"%lf", Axis1ParkPosition);
2268 snprintf(pcdata,
sizeof(pcdata),
"%lf", Axis2ParkPosition);
2280 return Axis1ParkPosition;
2284 return Axis1DefaultParkPosition;
2288 return Axis2ParkPosition;
2292 return Axis2DefaultParkPosition;
2297 LOGF_DEBUG(
"Setting Park Axis1 to %.2f", value);
2298 Axis1ParkPosition = value;
2305 LOGF_DEBUG(
"Setting Default Park Axis1 to %.2f", value);
2306 Axis1DefaultParkPosition = value;
2311 LOGF_DEBUG(
"Setting Park Axis2 to %.2f", value);
2312 Axis2ParkPosition = value;
2319 LOGF_DEBUG(
"Setting Default Park Axis2 to %.2f", value);
2320 Axis2DefaultParkPosition = value;
2340 if (!strcmp(button_n,
"ABORTBUTTON"))
2342 auto trackSW =
getSwitch(
"TELESCOPE_TRACK_MODE");
2345 (trackSW && trackSW.getState() ==
IPS_BUSY))
2349 const char *names[1] = {
AbortS[0].name };
2353 else if (!strcmp(button_n,
"PARKBUTTON"))
2356 const char *names[2] = {
ParkS[0].name,
ParkS[1].name };
2359 else if (!strcmp(button_n,
"UNPARKBUTTON"))
2362 const char *names[2] = {
ParkS[0].name,
ParkS[1].name };
2365 else if (!strcmp(button_n,
"SLEWPRESETUP"))
2369 else if (!strcmp(button_n,
"SLEWPRESETDOWN"))
2387 else if (!strcmp(joystick_n,
"SLEWPRESET"))
2395 if (!strcmp(axis_n,
"MOTIONDIRNS") || !strcmp(axis_n,
"MOTIONDIRWE"))
2399 LOG_WARN(
"Cannot slew while mount is parking/parked.");
2403 if (!strcmp(axis_n,
"MOTIONDIRNS"))
2408 motionDirNSValue = -1;
2413 motionDirNSValue = 1;
2417 motionDirNSValue = 0;
2420 else if (!strcmp(axis_n,
"MOTIONDIRWE"))
2425 motionDirWEValue = 1;
2430 motionDirWEValue = -1;
2434 motionDirWEValue = 0;
2438 float x = motionDirWEValue * sqrt(1 - pow(motionDirNSValue, 2) / 2.0f);
2439 float y = motionDirNSValue * sqrt(1 - pow(motionDirWEValue, 2) / 2.0f);
2440 float angle = atan2(y, x) * (180.0 / 3.141592653589);
2441 float mag = sqrt(pow(y, 2) + pow(x, 2));
2498 if (angle >= 90 && angle <= 270)
2507 if (angle >= 0 && angle <= 180)
2515 if (angle > 75 && angle < 105)
2519 if (angle > 165 && angle < 195)
2523 if (angle > 255 && angle < 285)
2527 if (angle > 345 || angle < 15)
2533 if (angle > 0 && angle < 180)
2545 if (angle > 180 && angle < 360)
2557 if (angle < 90 || angle > 270)
2570 if (angle > 90 && angle < 270)
2593 if (angle > 0 && angle < 180)
2595 if (currentIndex <= 0)
2694 XMLEle *RootXmlNode =
nullptr;
2695 XMLEle *CurrentXmlNode =
nullptr;
2697 bool DeviceFound =
false;
2700 RootXmlNode =
readXMLFile(FilePtr, XmlHandle, ErrMsg);
2703 XmlHandle =
nullptr;
2717 while (CurrentXmlNode)
2740 XMLEle *XmlNode =
nullptr;
2742 double ScopeFoc = 0, ScopeAp = 0;
2743 double GScopeFoc = 0, GScopeAp = 0;
2744 std::string ConfigName;
2747 if (!CurrentXmlNode)
2750 "Config %d is not found in the XML file (%s). To save a new config, update and set scope properties and "
2757 if (!XmlNode || sscanf(
pcdataXMLEle(XmlNode),
"%lf", &ScopeFoc) != 1)
2759 LOGF_INFO(
"Can't read the telescope focal length from the XML file (%s)",
2765 if (!XmlNode || sscanf(
pcdataXMLEle(XmlNode),
"%lf", &ScopeAp) != 1)
2767 LOGF_INFO(
"Can't read the telescope aperture from the XML file (%s)",
2773 if (!XmlNode || sscanf(
pcdataXMLEle(XmlNode),
"%lf", &GScopeFoc) != 1)
2775 LOGF_INFO(
"Can't read the guide scope focal length from the XML file (%s)",
2781 if (!XmlNode || sscanf(
pcdataXMLEle(XmlNode),
"%lf", &GScopeAp) != 1)
2783 LOGF_INFO(
"Can't read the guide scope aperture from the XML file (%s)",
2791 LOGF_INFO(
"Can't read the telescope config name from the XML file (%s)",
2834 XMLEle *RootXmlNode =
nullptr;
2835 XMLEle *CurrentXmlNode =
nullptr;
2837 bool DeviceFound =
false;
2840 RootXmlNode =
readXMLFile(FilePtr, XmlHandle, ErrMsg);
2843 XmlHandle =
nullptr;
2855 while (CurrentXmlNode)
2876 CurrentXmlNode =
findXMLEle(CurrentXmlNode,
"config1");
2877 if (!CurrentXmlNode)
2889 double ScopeFoc = 0, ScopeAp = 0;
2890 double GScopeFoc = 0, GScopeAp = 0;
2891 std::string ConfigName;
2923 XMLEle *RootXmlNode =
nullptr;
2925 bool DeviceFound =
false;
2928 RootXmlNode =
readXMLFile(FilePtr, XmlHandle, ErrMsg);
2930 XmlHandle =
nullptr;
2933 XMLEle *CurrentXmlNode =
nullptr;
2934 XMLEle *XmlNode =
nullptr;
2942 while (CurrentXmlNode)
2970 CurrentXmlNode = XmlNode;
3018 const char *HomeDir = getenv(
"HOME");
3023 HomeDir = getpwuid(getuid())->pw_dir;
3025 return (HomeDir ? std::string(HomeDir) :
"");
3059 FILE *FilePtr = fopen(file_name.c_str(), (writable ?
"a" :
"r"));
3073 std::time_t t = std::time(
nullptr);
3074 struct std::tm *utctimeinfo = std::gmtime(&t);
3076 strftime(ts,
sizeof(ts),
"%Y-%m-%dT%H:%M:%S", utctimeinfo);
3079 struct std::tm *localtimeinfo = std::localtime(&t);
3080 snprintf(ts,
sizeof(ts),
"%4.2f", (localtimeinfo->tm_gmtoff / 3600.0));
3090 return m_simulatePierSide;
3102 return "PIER_UNKNOWN";
3125 m_simulatePierSide = simulate;
void registerHandshake(std::function< bool()> callback)
registerHandshake Register a handshake function to be called once the intial connection to the device...
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 successfull connectio...
const char * getDeviceName() const
INDI::PropertySwitch getSwitch(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()
void setAxisCallback(axisFunc axisCallback)
setAxisCallback Sets the callback function when a new axis input is detected.
virtual bool saveConfigItems(FILE *fp)
virtual void ISGetProperties(const char *dev)
virtual bool updateProperties()
void setJoystickCallback(joystickFunc joystickCallback)
setJoystickCallback Sets the callback function when a new joystick input is detected.
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
Class to provide extended functionality for devices in addition to the functionality provided by INDI...
void addPollPeriodControl()
Add Polling period control to the driver.
virtual bool saveConfig(bool silent=false, const char *property=nullptr)
Save the current properties in a configuration file.
virtual const char * getDefaultName()=0
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...
virtual bool loadConfig(bool silent=false, const char *property=nullptr)
Load the last saved configuration file.
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...
uint32_t getCurrentPollingPeriod() const
getCurrentPollingPeriod Return the current polling period.
virtual bool initProperties()
Initilize 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.
void setDriverInterface(uint16_t value)
setInterface Set driver interface. By default the driver interface is set to GENERAL_DEVICE....
Connection::Interface * getActiveConnection()
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
Process the client newSwitch command.
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
const char * getName() const
bool isNameMatch(const char *otherName) const
bool update(const ISState states[], const char *const names[], int n)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, ISRule rule, double timeout, IPState state)
const std::string ScopeConfigGScopeFocXmlNode
INumberVectorProperty TrackRateNP
TelescopeStatus TrackState
bool isLocked() const
isLocked is mount currently locked?
ISwitchVectorProperty SimulatePierSideSP
virtual bool SetTrackMode(uint8_t mode)
SetTrackMode Set active tracking mode. Do not change track state.
ISwitchVectorProperty TrackStateSP
ISwitchVectorProperty ParkOptionSP
void SetAxis1Park(double value)
SetRAPark Set current RA/AZ parking position. The data park file (stored in ~/.indi/ParkData....
ISwitchVectorProperty DomePolicySP
bool HasPierSideSimulation()
TelescopePierSide currentPierSide
@ MOTION_CONTROL_JOYSTICK
virtual bool Goto(double ra, double dec)
Move the scope to the supplied RA and DEC coordinates.
ISwitchVectorProperty MovementNSSP
ITextVectorProperty ScopeConfigNameTP
void processButton(const char *button_n, ISState state)
static void axisHelper(const char *axis_n, double value, void *context)
ISwitchVectorProperty AbortSP
void processAxis(const char *axis_n, double value)
bool CheckFile(const std::string &file_name, bool writable) const
Check if a file exists and it is readable.
void SetAxis1ParkDefault(double steps)
SetRAPark Set default RA/AZ parking position.
virtual bool ReadScopeStatus()=0
Read telescope status.
void SetTelescopeCapability(uint32_t cap, uint8_t slewRateCount)
SetTelescopeCapability sets the Telescope capabilities. All capabilities must be initialized.
virtual bool Park()
Park the telescope to its home position.
INumberVectorProperty LocationNP
int GetScopeConfigIndex() const
Get the scope config index.
virtual bool SetCurrentPark()
SetCurrentPark Set current coordinates/encoders value as the desired parking position.
@ SAT_PASS_WINDOW_COUNT
Number of indices.
@ SAT_PASS_WINDOW_END
Index for end of the window.
@ SAT_PASS_WINDOW_START
Index for start of the window.
TelescopeParkData parkDataType
INumberVectorProperty ScopeParametersNP
std::string GetHomeDirectory() const
Validate a file name.
virtual bool initProperties() override
Called to initialize basic properties required all the time.
ITextVectorProperty ActiveDeviceTP
const std::string ScopeConfigLabelApXmlNode
ITextVectorProperty TimeTP
virtual void TimerHit() override
Called when setTimer() time is up.
INumberVectorProperty TargetNP
ISwitch MotionControlModeT[2]
ITextVectorProperty SatPassWindowTP
Text Vector property defining the start and end of a satellite pass (window contains pass)....
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
TelescopePierSide lastPierSide
virtual bool SetTrackRate(double raRate, double deRate)
SetTrackRate Set custom tracking rates.
double GetAxis1Park() const
virtual bool UnPark()
Unpark the telescope if already parked.
const std::string ScopeConfigDeviceXmlNode
INumberVectorProperty ParkPositionNP
virtual bool SetSlewRate(int index)
SetSlewRate Set desired slew rate index.
bool getSimulatePierSide() const
ISwitchVectorProperty CoordSP
virtual bool SetDefaultPark()
SetDefaultPark Set default coordinates/encoders value as the desired parking 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...
void setTelescopeConnection(const uint8_t &value)
setTelescopeConnection Set telescope connection mode. Child class should call this in the constructor...
double GetAxis2Park() const
const std::string ScopeConfigScopeFocXmlNode
ISwitchVectorProperty ScopeConfigsSP
bool isParked()
isParked is mount currently parked?
ISwitchVectorProperty PECStateSP
void processNSWE(double mag, double angle)
virtual int AddTrackMode(const char *name, const char *label, bool isDefault=false)
AddTrackMode.
ISwitchVectorProperty TrackModeSP
ISwitchVectorProperty SlewRateSP
Connection::Serial * serialConnection
virtual bool updateProperties() override
Called when connected state changes, to add/remove properties.
ISwitchVectorProperty PierSideSP
static void joystickHelper(const char *joystick_n, double mag, double angle, void *context)
void updateObserverLocation(double latitude, double longitude, double elevation)
Update location settings of the observer.
const std::string ScopeConfigFileName
The telescope/guide scope configuration file name.
double GetAxis1ParkDefault() const
virtual bool Handshake()
perform handshake with device to check communication
virtual bool SetTrackEnabled(bool enabled)
SetTrackEnabled Engages or disengages mount tracking. If there are no tracking modes available,...
const std::string ScopeConfigRootXmlNode
virtual void SetParked(bool isparked)
SetParked Change the mount parking status. The data park file (stored in ~/.indi/ParkData....
virtual bool updateTime(ln_date *utc, double utc_offset)
Update telescope time, date, and UTC offset.
Connection::TCP * tcpConnection
INumberVectorProperty EqNP
static void buttonHelper(const char *button_n, ISState state, void *context)
uint8_t getTelescopeConnection() const
const char * LoadParkData()
void setPECState(TelescopePECState state)
ISwitchVectorProperty TrackSatSP
Switch Vector property defining the state of the satellite tracking of the mount. Example implementat...
ISwitchVectorProperty MotionControlModeTP
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual bool updateLocation(double latitude, double longitude, double elevation)
Update telescope location settings.
virtual bool ISSnoopDevice(XMLEle *root) override
Process a snoop event from INDI server. This function is called when a snooped property is updated in...
virtual bool SetParkPosition(double Axis1Value, double Axis2Value)
SetParkPosition Set desired parking position to the supplied value. This ONLY sets the desired park p...
ISwitchVectorProperty ParkSP
INumber ScopeParametersN[4]
const std::string ScopeConfigNameXmlNode
ISwitch TrackSatS[SAT_TRACK_COUNT]
INDI::PropertySwitch ReverseMovementSP
const std::string ScopeConfigGScopeApXmlNode
IGeographicCoordinates m_Location
ISwitchVectorProperty LockAxisSP
@ TELESCOPE_HAS_PIER_SIDE
void processJoystick(const char *joystick_n, double mag, double angle)
IText SatPassWindowT[SAT_PASS_WINDOW_COUNT]
bool callHandshake()
callHandshake Helper function that sets the port file descriptor before calling the actual Handshake ...
bool LoadScopeConfig()
Load scope settings from XML files.
void NewRaDec(double ra, double dec)
The child class calls this function when it has updates.
bool UpdateScopeConfig()
Save scope settings to XML files.
virtual void SyncParkStatus(bool isparked)
SyncParkStatus Update the state and switches for parking.
void setSimulatePierSide(bool value)
void setPierSide(TelescopePierSide side)
bool InitPark()
InitPark Loads parking data (stored in ~/.indi/ParkData.xml) that contains parking status and parking...
ISwitchVectorProperty MovementWESP
void sendTimeFromSystem()
virtual bool MoveWE(INDI_DIR_WE dir, TelescopeMotionCommand command)
Move the telescope in the direction dir.
TelescopeStatus RememberTrackState
RememberTrackState Remember last state of Track State to fall back to in case of errors or aborts.
virtual bool Abort()
Abort any telescope motion including tracking if possible.
double GetAxis2ParkDefault() const
TelescopePECState currentPECState
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
void SetAxis2Park(double steps)
SetDEPark Set current DEC/ALT parking position. The data park file (stored in ~/.indi/ParkData....
const std::string ScopeConfigScopeApXmlNode
virtual bool MoveNS(INDI_DIR_NS dir, TelescopeMotionCommand command)
Start or Stop the telescope motion in the direction dir.
ITextVectorProperty TLEtoTrackTP
Text Vector property defining the orbital elements of an artificial satellite (TLE)....
bool HasDefaultScopeConfig()
Load scope settings from XML files.
ISwitch SimulatePierSideS[2]
void processSlewPresets(double mag, double angle)
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
const char * getPierSideStr(TelescopePierSide ps)
void SetParkDataType(TelescopeParkData type)
setParkDataType Sets the type of parking data stored in the park data file and presented to the user.
TelescopePECState lastPECState
@ SAT_HALT
Halt signal (abort)
@ SAT_TRACK_COUNT
State counter.
TelescopePierSide expectedPierSide(double ra)
Calculate the expected pier side for scopes that do not report this property themselves.
IText ScopeConfigNameT[1]
void SetAxis2ParkDefault(double steps)
SetDEParkDefault Set default DEC/ALT parking position.
virtual bool Sync(double ra, double dec)
Set the telescope current RA and DEC coordinates to the supplied RA and DEC coordinates.
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
const char * SATELLITE_TAB
SATELLITE_TAB.
const char * MOTION_TAB
MOTION_TAB Where all the motion control properties of 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 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 sideral time given longitude and system clock.
int extractISOTime(const char *timestr, struct ln_date *iso_date)
Extract ISO 8601 time and store it in a tm struct.
#define TRACKRATE_SIDEREAL
void IUSaveConfigSwitch(FILE *fp, const ISwitchVectorProperty *svp)
Add a switch vector property value to the configuration file.
void IUFillNumberVector(INumberVectorProperty *nvp, INumber *np, int nnp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a number vector property. The vector's auxiliary elements will be set to NULL.
INumber * IUFindNumber(const INumberVectorProperty *nvp, const char *name)
Find an INumber member in a number text property.
int IUFindOnSwitchIndex(const ISwitchVectorProperty *svp)
Returns the index of first ON switch it finds in the vector switch property.
void IUResetSwitch(ISwitchVectorProperty *svp)
Reset all switches in a switch vector property to OFF.
void IUFillTextVector(ITextVectorProperty *tvp, IText *tp, int ntp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a text vector property. The vector's auxiliary elements will be set to NULL.
ISwitch * IUFindOnSwitch(const ISwitchVectorProperty *svp)
Returns the first ON switch it finds in the vector switch property.
void IUSaveText(IText *tp, const char *newtext)
Function to reliably save new text in a IText.
int IUFindIndex(const char *needle, char **hay, unsigned int n)
Returns the index of the string in a string array.
void IUSaveConfigNumber(FILE *fp, const INumberVectorProperty *nvp)
Add a number vector property value to the configuration file.
void IUFillSwitch(ISwitch *sp, const char *name, const char *label, ISState s)
Assign attributes for a switch property. The switch's auxiliary elements will be set to NULL.
void IUFillText(IText *tp, const char *name, const char *label, const char *initialText)
Assign attributes for a text property. The text's auxiliary elements will be set to NULL.
void IUFillNumber(INumber *np, const char *name, const char *label, const char *format, double min, double max, double step, double value)
Assign attributes for a number property. The number's auxiliary elements will be set to NULL.
void IUSaveConfigText(FILE *fp, const ITextVectorProperty *tvp)
Add a text vector property value to the configuration file.
void IUFillSwitchVector(ISwitchVectorProperty *svp, ISwitch *sp, int nsp, const char *dev, const char *name, const char *label, const char *group, IPerm p, ISRule r, double timeout, IPState s)
Assign attributes for a switch vector property. The vector's auxiliary elements will be set to NULL.
IText * IUFindText(const ITextVectorProperty *tvp, const char *name)
Find an IText member in a vector text property.
ISwitch * IUFindSwitch(const ISwitchVectorProperty *svp, const char *name)
Find an ISwitch member in a vector switch property.
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector property.
void IDSetNumber(const INumberVectorProperty *nvp, const char *fmt,...)
void IDSetSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
int IUUpdateText(ITextVectorProperty *tvp, char *texts[], char *names[], int n)
Update all text members in a text vector property.
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...
int IUGetConfigNumber(const char *dev, const char *property, const char *member, double *value)
IUGetConfigNumber Opens configuration file and reads single number property.
int IUUpdateNumber(INumberVectorProperty *nvp, double values[], char *names[], int n)
Update all numbers in a number vector property.
void IDSetText(const ITextVectorProperty *tvp, const char *fmt,...)
int IUGetConfigSwitch(const char *dev, const char *property, const char *member, ISState *value)
IUGetConfigSwitch Opens configuration file and reads single switch property.
#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_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,...)
#define DEBUGF(priority, msg,...)
XMLAtt * findXMLAtt(XMLEle *ep, const char *name)
Find an XML attribute within an XML element.
LilXML * newLilXML()
Create a new lilxml parser.
const char * findXMLAttValu(XMLEle *ep, const char *name)
Find an XML element's attribute value.
XMLAtt * addXMLAtt(XMLEle *ep, const char *name, const char *valu)
Add an XML attribute to an existing XML element.
char * pcdataXMLEle(XMLEle *ep)
Return the pcdata of an XML element.
void editXMLEle(XMLEle *ep, const char *pcdata)
set the pcdata of the given element
char * tagXMLEle(XMLEle *ep)
Return the tag of an XML element.
void prXMLEle(FILE *fp, XMLEle *ep, int level)
Print an XML element.
XMLEle * readXMLFile(FILE *fp, LilXML *lp, char ynot[])
Handy wrapper to read one xml file.
XMLEle * nextXMLEle(XMLEle *ep, int init)
Iterate an XML element for a list of nesetd XML elements.
void delXMLEle(XMLEle *ep)
delXMLEle Delete XML element.
void delLilXML(LilXML *lp)
Delete a lilxml parser.
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.
Namespace to encapsulate INDI client, drivers, and mediator classes.
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values