1 /******************************************************************************* 2 INDI Dome Base Class 3 Copyright(c) 2014 Jasem Mutlaq. All rights reserved. 4 5 The code used calculate dome target AZ and ZD is written by Ferran Casarramona, and adapted from code from Markus Wildi. 6 The transformations are based on the paper Matrix Method for Coodinates Transformation written by Toshimi Taki (http://www.asahi-net.or.jp/~zs3t-tk). 7 8 This library is free software; you can redistribute it and/or 9 modify it under the terms of the GNU Library General Public 10 License version 2 as published by the Free Software Foundation. 11 12 This library is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 Library General Public License for more details. 16 17 You should have received a copy of the GNU Library General Public License 18 along with this library; see the file COPYING.LIB. If not, write to 19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 20 Boston, MA 02110-1301, USA. 21 *******************************************************************************/ 22 23 #pragma once 24 25 #include "defaultdevice.h" 26 #include "libastro.h" 27 #include "inditimer.h" 28 29 #include <string> 30 31 // Defines a point in a 3 dimension space 32 typedef struct 33 { 34 double x, y, z; 35 } point3D; 36 37 namespace Connection 38 { 39 class Serial; 40 class TCP; 41 } 42 43 /** 44 * \class INDI::Dome 45 \brief Class to provide general functionality of a Dome device. 46 47 Both relative and absolute position domes are supported. Furthermore, if no position feedback is available from the dome, an open-loop control is possible with simple direction commands (Clockwise and counter clockwise). 48 49 Before using any of the dome functions, you must define the capabilities of the dome by calling SetDomeCapability() function. All positions are represented as degrees of azimuth. 50 51 Relative motion is specified in degrees as either positive (clock wise direction), or negative (counter clock-wise direction). 52 53 Slaving is used to synchronizes the dome's azimuth position with that of the mount. The mount's coordinates are snooped from the active mount that has its name specified in ACTIVE_TELESCOPE property in the ACTIVE_DEVICES vector. 54 Dome motion begins when it receives TARGET_EOD_COORD property from the mount driver when the mount starts slewing to the desired target coordinates /em OR 55 when the mount's current tracking position exceeds the AutoSync threshold. Therefore, slaving is performed while slewing and tracking. The user is required to fill in all required parameters before slaving can be used. 56 The AutoSync threshold is the difference in degrees between the dome's azimuth angle and the mount's azimuth angle that should trigger a dome motion. 57 By default, it is set to 0.5 degrees which would trigger dome motion due to any difference between the dome and mount azimuth angles that exceeds 0.5 degrees. 58 For example, if the threshold is set to 5 degrees, the dome will only start moving to sync with the mount's azimuth angle once the difference in azimuth angles is equal or exceeds 5 degrees. 59 60 Custom parking position is available for absolute/relative position domes. 61 62 For roll-off observatories, parking state reflects whether the roof is closed or open. 63 64 Developers need to subclass INDI::Dome to implement any driver for Domes within INDI. 65 66 \note The code used calculate dome target AZ and ZD is written by Ferran Casarramona, and adapted from code from Markus Wildi. The transformations are based on the paper Matrix Method for Coodinates 67 Transformation written by Toshimi Taki (http://www.asahi-net.or.jp/~zs3t-tk). 68 69 \author Jasem Mutlaq 70 */ 71 namespace INDI 72 { 73 74 class Dome : public DefaultDevice 75 { 76 public: 77 /** \typedef DomeMeasurements 78 \brief Measurements necessary for dome-slit synchronization. All values are in meters. The displacements are measured from the true dome centre, and the dome is assumed spherical. 79 \note: The mount centre is the point where RA and Dec. axis crosses, no matter the kind of mount. For example, for a fork mount this displacement is typically 0 if it's perfectly centred with RA axis. 80 */ 81 typedef enum 82 { 83 DM_DOME_RADIUS, /*!< Dome RADIUS */ 84 DM_SHUTTER_WIDTH, /*!< Shutter width */ 85 DM_NORTH_DISPLACEMENT, /*!< Displacement to north of the mount center */ 86 DM_EAST_DISPLACEMENT, /*!< Displacement to east of the mount center */ 87 DM_UP_DISPLACEMENT, /*!< Up Displacement of the mount center */ 88 DM_OTA_OFFSET /*!< Distance from the optical axis to the mount center*/ 89 } DomeMeasurements; 90 91 enum DomeDirection 92 { 93 DOME_CW, 94 DOME_CCW 95 }; 96 enum DomeMotionCommand 97 { 98 MOTION_START, 99 MOTION_STOP 100 }; 101 102 /*! Dome Parking data type enum */ 103 enum DomeParkData 104 { 105 PARK_NONE, /*!< 2-state parking (Open or Closed only) */ 106 PARK_AZ, /*!< Parking via azimuth angle control */ 107 PARK_AZ_ENCODER, /*!< Parking via azimuth encoder control */ 108 }; 109 110 /** \typedef ShutterOperation 111 \brief Shutter operation command. 112 */ 113 typedef enum 114 { 115 SHUTTER_OPEN, /*!< Open Shutter */ 116 SHUTTER_CLOSE /*!< Close Shutter */ 117 } ShutterOperation; 118 119 /*! Mount Locking Policy */ 120 enum MountLockingPolicy 121 { 122 MOUNT_IGNORED, /*!< Mount is ignored. Dome can park or unpark irrespective of mount parking status */ 123 MOUNT_LOCKS, /*!< Mount Locks. Dome can park if mount is completely parked first. */ 124 }; 125 126 /** \typedef DomeState 127 \brief Dome status 128 */ 129 typedef enum 130 { 131 DOME_IDLE, /*!< Dome is idle */ 132 DOME_MOVING, /*!< Dome is in motion */ 133 DOME_SYNCED, /*!< Dome is synced */ 134 DOME_PARKING, /*!< Dome is parking */ 135 DOME_UNPARKING, /*!< Dome is unparking */ 136 DOME_PARKED, /*!< Dome is parked */ 137 DOME_UNPARKED, /*!< Dome is unparked */ 138 DOME_UNKNOWN, /*!< Dome state is known */ 139 DOME_ERROR, /*!< Dome has errors */ 140 } DomeState; 141 142 /** \typedef ShutterStatus 143 \brief Shutter Status 144 */ 145 typedef enum 146 { 147 SHUTTER_OPENED, /*!< Shutter is open */ 148 SHUTTER_CLOSED, /*!< Shutter is closed */ 149 SHUTTER_MOVING, /*!< Shutter in motion (opening or closing) */ 150 SHUTTER_UNKNOWN, /*!< Shutter status is unknown */ 151 SHUTTER_ERROR /*!< Shutter status is unknown */ 152 } ShutterState; 153 154 enum 155 { 156 DOME_CAN_ABORT = 1 << 0, /*!< Can the dome motion be aborted? */ 157 DOME_CAN_ABS_MOVE = 1 << 1, /*!< Can the dome move to an absolute azimuth position? */ 158 DOME_CAN_REL_MOVE = 1 << 2, /*!< Can the dome move to a relative position a number of degrees away from current position? Positive degress is Clockwise direction. Negative Degrees is counter clock wise direction */ 159 DOME_CAN_PARK = 1 << 3, /*!< Can the dome park and unpark itself? */ 160 DOME_CAN_SYNC = 1 << 4, /*!< Can the dome sync to arbitrary postion? */ 161 DOME_HAS_SHUTTER = 1 << 5, /*!< Does the dome has a shutter than can be opened and closed electronically? */ 162 DOME_HAS_VARIABLE_SPEED = 1 << 6, /*!< Can the dome move in different configurable speeds? */ 163 DOME_HAS_BACKLASH = 1 << 7 /*!< Can the dome compensate for backlash? */ 164 }; 165 166 /** \struct DomeConnection 167 \brief Holds the connection mode of the Dome. 168 */ 169 enum 170 { 171 CONNECTION_NONE = 1 << 0, /** Do not use any connection plugin */ 172 CONNECTION_SERIAL = 1 << 1, /** For regular serial and bluetooth connections */ 173 CONNECTION_TCP = 1 << 2 /** For Wired and WiFI connections */ 174 } DomeConnection; 175 176 Dome(); 177 virtual ~Dome(); 178 179 virtual bool initProperties() override; 180 virtual void ISGetProperties(const char * dev) override; 181 virtual bool updateProperties() override; 182 virtual bool ISNewNumber(const char * dev, const char * name, double values[], char * names[], int n) override; 183 virtual bool ISNewSwitch(const char * dev, const char * name, ISState * states, char * names[], int n) override; 184 virtual bool ISNewText(const char * dev, const char * name, char * texts[], char * names[], int n) override; 185 virtual bool ISSnoopDevice(XMLEle * root) override; 186 187 static void buttonHelper(const char * button_n, ISState state, void * context); 188 189 /** 190 * @brief setDomeConnection Set Dome connection mode. Child class should call this in the constructor before Dome registers 191 * any connection interfaces 192 * @param value ORed combination of DomeConnection values. 193 */ 194 void setDomeConnection(const uint8_t &value); 195 196 /** 197 * @return Get current Dome connection mode 198 */ 199 uint8_t getDomeConnection() const; 200 201 /** 202 * @brief GetDomeCapability returns the capability of the dome 203 */ GetDomeCapability()204 uint32_t GetDomeCapability() const 205 { 206 return capability; 207 } 208 209 /** 210 * @brief SetDomeCapability set the dome capabilities. All capabilities must be initialized. 211 * @param cap pointer to dome capability 212 */ 213 void SetDomeCapability(uint32_t cap); 214 215 /** 216 * @return True if dome support aborting motion 217 */ CanAbort()218 bool CanAbort() 219 { 220 return capability & DOME_CAN_ABORT; 221 } 222 223 /** 224 * @return True if dome has absolute postion encoders. 225 */ CanAbsMove()226 bool CanAbsMove() 227 { 228 return capability & DOME_CAN_ABS_MOVE; 229 } 230 231 /** 232 * @return True if dome has relative position encoders. 233 */ CanRelMove()234 bool CanRelMove() 235 { 236 return capability & DOME_CAN_REL_MOVE; 237 } 238 239 /** 240 * @return True if dome can park. 241 */ CanPark()242 bool CanPark() 243 { 244 return capability & DOME_CAN_PARK; 245 } 246 247 /** 248 * @return True if dome can sync. 249 */ CanSync()250 bool CanSync() 251 { 252 return capability & DOME_CAN_SYNC; 253 } 254 255 /** 256 * @return True if dome has controllable shutter door 257 */ HasShutter()258 bool HasShutter() 259 { 260 return capability & DOME_HAS_SHUTTER; 261 } 262 263 /** 264 * @return True if dome support multiple speeds 265 */ HasVariableSpeed()266 bool HasVariableSpeed() 267 { 268 return capability & DOME_HAS_VARIABLE_SPEED; 269 } 270 271 /** 272 * @return True if the dome supports backlash 273 */ HasBacklash()274 bool HasBacklash() 275 { 276 return capability & DOME_HAS_BACKLASH; 277 } 278 279 /** 280 * @brief isLocked, is the dome currently locked? 281 * @return True if lock status equals true, and TelescopeClosedLockTP is Telescope Locks. 282 */ 283 bool isLocked(); 284 getDomeState()285 DomeState getDomeState() const 286 { 287 return m_DomeState; 288 } 289 void setDomeState(const DomeState &value); 290 getShutterState()291 ShutterState getShutterState() const 292 { 293 return m_ShutterState; 294 } 295 void setShutterState(const ShutterState &value); 296 297 IPState getMountState() const; 298 299 protected: 300 /** 301 * @brief SetSpeed Set Dome speed. This does not initiate motion, it sets the speed for the next motion command. If motion is in progress, then change speed accordingly. 302 * @param rpm Dome speed (RPM) 303 * @return true if successful, false otherwise 304 */ 305 virtual bool SetSpeed(double rpm); 306 307 /** \brief Move the Dome in a particular direction. 308 \param dir Direction of Dome, either DOME_CW or DOME_CCW. 309 \return Return IPS_OK if dome operation is complete. IPS_BUSY if operation is in progress. IPS_ALERT on error. 310 */ 311 virtual IPState Move(DomeDirection dir, DomeMotionCommand operation); 312 313 /** \brief Move the Dome to an absolute azimuth. 314 \param az The new position of the Dome. 315 \return Return IPS_OK if motion is completed and Dome reached requested position. Return IPS_BUSY if Dome started motion to requested position and is in progress. 316 Return IPS_ALERT if there is an error. 317 */ 318 virtual IPState MoveAbs(double az); 319 320 /** \brief Move the Dome to an relative position. 321 \param azDiff The relative azimuth angle to move. Positive degree is clock-wise direction. Negative degrees is counter clock-wise direction. 322 \return Return IPS_OK if motion is completed and Dome reached requested position. Return IPS_BUSY if Dome started motion to requested position and is in progress. 323 Return IPS_ALERT if there is an error. 324 */ 325 virtual IPState MoveRel(double azDiff); 326 327 /** 328 * \brief Sync sets the dome current azimuth as the supplied azimuth position 329 * \return True if sync is successful, false otherwise. 330 */ 331 virtual bool Sync(double az); 332 333 /** 334 * \brief Abort all dome motion 335 * \return True if abort is successful, false otherwise. 336 */ 337 virtual bool Abort(); 338 339 /** 340 * \brief Goto Park Position. The park position is an absolute azimuth value. 341 * \return Return IPS_OK if motion is completed and Dome reached park position. Return IPS_BUSY if Dome started motion to park requested position and is in progress. 342 Return -IPS_ALERT if there is an error. 343 */ 344 virtual IPState Park(); 345 346 /** 347 * \brief UnPark dome. The action of the Unpark command is dome specific, but it may include opening the shutter and moving to home position. When UnPark() is successful 348 * The observatory should be in a ready state to utilize the mount to perform observations. 349 * \return Return IPS_OK if motion is completed and Dome is unparked. Return IPS_BUSY if Dome unparking is in progress. 350 Return -IPS_ALERT if there is an error. 351 */ 352 virtual IPState UnPark(); 353 354 /** 355 * @brief SetBacklash Set the dome backlash compensation value 356 * @param steps value in absolute steps to compensate 357 * @return True if successful, false otherwise. 358 */ 359 virtual bool SetBacklash(int32_t steps); 360 361 /** 362 * @brief SetBacklashEnabled Enables or disables the dome backlash compensation 363 * @param enable flag to enable or disable backlash compensation 364 * @return True if successful, false otherwise. 365 */ 366 virtual bool SetBacklashEnabled(bool enabled); 367 368 /** 369 * \brief Open or Close shutter 370 * \param operation Either open or close the shutter. 371 * \return Return IPS_OK if shutter operation is complete. Return IPS_BUSY if shutter operation is in progress. 372 Return IPS_ALERT if there is an error. 373 */ 374 virtual IPState ControlShutter(ShutterOperation operation); 375 376 /** 377 * @brief getShutterStatusString 378 * @param status Status of shutter 379 * @return Returns string representation of the shutter status 380 */ 381 const char * GetShutterStatusString(ShutterState status); 382 383 /** 384 * \brief setParkDataType Sets the type of parking data stored in the park data file and presented to the user. 385 * \param type parking data type. If PARK_NONE then no properties will be presented to the user for custom parking position. 386 */ 387 void SetParkDataType(DomeParkData type); 388 389 /** 390 * @brief InitPark Loads parking data (stored in ~/.indi/ParkData.xml) that contains parking status 391 * and parking position. InitPark() should be called after successful connection to the dome on startup. 392 * @return True if loading is successful and data is read, false otherwise. On success, you must call 393 * SetAzParkDefault() to set the default parking values. On failure, you must call 394 * SetAzParkDefault() to set the default parking values in addition to SetAzPark() 395 * to set the current parking position. 396 */ 397 bool InitPark(); 398 399 /** 400 * @brief isParked is dome currently parked? 401 * @return True if parked, false otherwise. 402 */ 403 bool isParked(); 404 405 /** 406 * @brief SetParked Change the mount parking status. The data park file (stored in ~/.indi/ParkData.xml) is updated in the process. 407 * @param isparked set to true if parked, false otherwise. 408 */ 409 void SetParked(bool isparked); 410 411 /** 412 * @return Get current AZ parking position. 413 */ 414 double GetAxis1Park(); 415 416 /** 417 * @return Get default AZ parking position. 418 */ 419 double GetAxis1ParkDefault(); 420 421 /** 422 * @brief SetRAPark Set current AZ parking position. The data park file (stored in ~/.indi/ParkData.xml) is updated in the process. 423 * @param value current Axis 1 value (AZ either in angles or encoder values as specificed by the DomeParkData type). 424 */ 425 void SetAxis1Park(double value); 426 427 /** 428 * @brief SetAxis1Park Set default AZ parking position. 429 * @param value Default Axis 1 value (AZ either in angles or encoder values as specificed by the DomeParkData type). 430 */ 431 void SetAxis1ParkDefault(double steps); 432 433 /** 434 * @brief SetCurrentPark Set current coordinates/encoders value as the desired parking position 435 * \note This function performs no action unless subclassed by the child class if required. 436 */ 437 virtual bool SetCurrentPark(); 438 439 /** 440 * @brief SetDefaultPark Set default coordinates/encoders value as the desired parking position 441 * \note This function performs no action unless subclassed by the child class if required. 442 */ 443 virtual bool SetDefaultPark(); 444 445 //Park 446 const char * LoadParkData(); 447 bool WriteParkData(); 448 449 /** 450 * @brief GetTargetAz 451 * @param Az Returns Azimuth required to the dome in order to center the shutter aperture with telescope 452 * @param Alt 453 * @param minAz Returns Minimum azimuth in order to avoid any dome interference to the full aperture of the telescope 454 * @param maxAz Returns Maximum azimuth in order to avoid any dome interference to the full aperture of the telescope 455 * @return Returns false if it can't solve it due bad geometry of the observatory 456 */ 457 bool GetTargetAz(double &Az, double &Alt, double &minAz, double &maxAz); 458 459 /** 460 * @brief Intersection Calculate the intersection of a ray and a sphere. The line segment is defined from p1 to p2. The sphere is of radius r and centered at (0,0,0). 461 * From http://local.wasp.uwa.edu.au/~pbourke/geometry/sphereline/ 462 * There are potentially two points of intersection given by 463 * p := p1 + mu1 (p2 - p1) 464 * p := p1 + mu2 (p2 - p1) 465 * @param p1 First point 466 * @param p2 Direction of the ray 467 * @param r RADIUS of sphere 468 * @param mu1 First point of potentional intersection. 469 * @param mu2 Second point of potentional intersection. 470 * @return Returns FALSE if the ray doesn't intersect the sphere. 471 */ 472 bool Intersection(point3D p1, point3D p2, double r, double &mu1, double &mu2); 473 474 /** 475 * @brief OpticalCenter This function calculates the distance from the optical axis to the Dome center 476 * @param MountCenter Distance from the Dome center to the point where mount axis crosses 477 * @param dOpticalAxis Distance from the mount center to the optical axis. 478 * @param Lat Latitude 479 * @param Ah Hour Angle (in hours) 480 * @param OP a 3D point from the optical center to the Dome center. 481 * @return false in case of error. 482 */ 483 bool OpticalCenter(point3D MountCenter, double dOpticalAxis, double Lat, double Ah, point3D &OP); 484 485 /** 486 * @brief OpticalVector This function calculates a second point for determining the optical axis 487 * @param Az Azimuth 488 * @param Alt Altitude 489 * @param OV a 3D point that determines the optical line. 490 * @return false in case of error. 491 */ 492 bool OpticalVector(double Az, double Alt, point3D &OV); 493 494 /** 495 * @brief CheckHorizon Returns true if telescope points above horizon. 496 * @param HA Hour angle 497 * @param dec Declination 498 * @param lat observer's latitude 499 * @return True if telescope points above horizon, false otherwise. 500 */ 501 bool CheckHorizon(double HA, double dec, double lat); 502 503 /** 504 * @brief saveConfigItems Saves the Device Port and Dome Presets in the configuration file 505 * @param fp pointer to configuration file 506 * @return true if successful, false otherwise. 507 */ 508 virtual bool saveConfigItems(FILE * fp) override; 509 510 /** 511 * @brief updateCoords updates the horizontal coordinates (Az & Alt) of the mount from the snooped RA, DEC and observer's location. 512 */ 513 void UpdateMountCoords(); 514 515 /** 516 * @brief UpdateAutoSync This function calculates the target dome azimuth from the mount's target coordinates given the dome parameters. 517 * If the difference between the dome's and mount's azimuth angles exceeds the AutoSync threshold, the dome will be commanded to sync to the mount azimuth position. 518 */ 519 virtual void UpdateAutoSync(); 520 521 /** \brief perform handshake with device to check communication */ 522 virtual bool Handshake(); 523 524 double Csc(double x); 525 double Sec(double x); 526 527 INumberVectorProperty DomeSpeedNP; 528 INumber DomeSpeedN[1]; 529 530 ISwitchVectorProperty DomeMotionSP; 531 ISwitch DomeMotionS[2]; 532 533 INumberVectorProperty DomeAbsPosNP; 534 INumber DomeAbsPosN[1]; 535 536 INumberVectorProperty DomeRelPosNP; 537 INumber DomeRelPosN[1]; 538 539 ISwitchVectorProperty AbortSP; 540 ISwitch AbortS[1]; 541 542 INumberVectorProperty DomeParamNP; 543 INumber DomeParamN[1]; 544 545 INumberVectorProperty DomeSyncNP; 546 INumber DomeSyncN[1]; 547 548 ISwitchVectorProperty DomeShutterSP; 549 ISwitch DomeShutterS[2]; 550 551 ISwitchVectorProperty ParkSP; 552 ISwitch ParkS[2]; 553 554 INumber ParkPositionN[1]; 555 INumberVectorProperty ParkPositionNP; 556 557 ISwitch ParkOptionS[3]; 558 ISwitchVectorProperty ParkOptionSP; 559 560 // ISwitch AutoParkS[2]; 561 // ISwitchVectorProperty AutoParkSP; 562 563 uint32_t capability; 564 DomeParkData parkDataType; 565 566 ITextVectorProperty ActiveDeviceTP; 567 IText ActiveDeviceT[1] {}; 568 569 // Switch to lock id mount is unparked 570 ISwitchVectorProperty MountPolicySP; 571 ISwitch MountPolicyS[2]; 572 573 // Shutter control on Park/Unpark 574 ISwitchVectorProperty ShutterParkPolicySP; 575 ISwitch ShutterParkPolicyS[2]; 576 enum 577 { 578 SHUTTER_CLOSE_ON_PARK, 579 SHUTTER_OPEN_ON_UNPARK, 580 }; 581 582 INumber PresetN[3]; 583 INumberVectorProperty PresetNP; 584 ISwitch PresetGotoS[3]; 585 ISwitchVectorProperty PresetGotoSP; 586 INumber DomeMeasurementsN[6]; 587 INumberVectorProperty DomeMeasurementsNP; 588 589 ISwitchVectorProperty OTASideSP; 590 ISwitch OTASideS[5]; 591 // 0 is East, 1 is West, 2 is as reported by mout, 3 as deducted by Hour Angle 592 // 4 ignore pier side and perform as in a fork mount 593 enum 594 { 595 DM_OTA_SIDE_EAST, 596 DM_OTA_SIDE_WEST, 597 DM_OTA_SIDE_MOUNT, 598 DM_OTA_SIDE_HA, 599 DM_OTA_SIDE_IGNORE 600 }; 601 602 int mountOTASide = 0; // Side of the telescope with respect of the mount, 1: west, -1: east, 0 not reported 603 ISwitchVectorProperty DomeAutoSyncSP; 604 ISwitch DomeAutoSyncS[2]; 605 606 // Backlash toogle 607 ISwitchVectorProperty DomeBacklashSP; 608 ISwitch DomeBacklashS[2]; 609 610 // Backlash steps 611 INumberVectorProperty DomeBacklashNP; 612 INumber DomeBacklashN[1]; 613 614 double prev_az, prev_alt, prev_ra, prev_dec; 615 616 // For Serial and TCP connections 617 int PortFD = -1; 618 619 Connection::Serial * serialConnection = nullptr; 620 Connection::TCP * tcpConnection = nullptr; 621 622 // States 623 DomeState m_DomeState; 624 ShutterState m_ShutterState; 625 IPState m_MountState; 626 627 // Observer geographic coords. Snooped from mount driver. 628 IGeographicCoordinates observer; 629 // Do we have valid geographic coords from mount driver? 630 bool HaveLatLong = false; 631 632 // Mount horizontal and equatorial coords. Snoops from mount driver. 633 INDI::IHorizontalCoordinates mountHoriztonalCoords; 634 INDI::IEquatorialCoordinates mountEquatorialCoords; 635 // Do we have valid coords from mount driver? 636 bool HaveRaDec = false; 637 638 private: 639 void processButton(const char * button_n, ISState state); 640 void triggerSnoop(const char * driverName, const char * propertyName); 641 /** 642 * @brief SyncParkStatus Update the state and switches for parking 643 * @param isparked True if parked, false otherwise. 644 */ 645 void SyncParkStatus(bool isparked); 646 /** 647 * @brief LoadParkXML Read and process park XML data. 648 * @return error string if there is problem opening the file 649 */ 650 const char * LoadParkXML(); 651 652 /** 653 * @brief Validate a file name 654 * @param file_name File name 655 * @return True if the file name is valid otherwise false. 656 */ 657 std::string GetHomeDirectory() const; 658 659 Controller * controller = nullptr; 660 661 bool IsParked = false; 662 bool IsMountParked = false; 663 bool IsLocked = true; 664 bool AutoSyncWarning = false; 665 666 const char * ParkDeviceName; 667 const std::string ParkDataFileName; 668 INDI::Timer m_MountUpdateTimer; 669 //int m_HorizontalUpdateTimerID { -1 }; 670 XMLEle * ParkdataXmlRoot, *ParkdeviceXml, *ParkstatusXml, *ParkpositionXml, *ParkpositionAxis1Xml; 671 672 double Axis1ParkPosition; 673 double Axis1DefaultParkPosition; 674 675 bool callHandshake(); 676 uint8_t domeConnection = CONNECTION_SERIAL | CONNECTION_TCP; 677 678 // How often we update horizontal coordinates (10 seconds). 679 static constexpr uint32_t HORZ_UPDATE_TIMER { 10000 }; 680 }; 681 682 } 683