1 /******************************************************************************* 2 Copyright(c) 2010-2018 Jasem Mutlaq. All rights reserved. 3 4 Copyright(c) 2010, 2011 Gerry Rozema. All rights reserved. 5 6 Rapid Guide support added by CloudMakers, s. r. o. 7 Copyright(c) 2013 CloudMakers, s. r. o. All rights reserved. 8 9 Star detection algorithm is based on PHD Guiding by Craig Stark 10 Copyright (c) 2006-2010 Craig Stark. All rights reserved. 11 12 This library is free software; you can redistribute it and/or 13 modify it under the terms of the GNU Library General Public 14 License version 2 as published by the Free Software Foundation. 15 16 This library is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 Library General Public License for more details. 20 21 You should have received a copy of the GNU Library General Public License 22 along with this library; see the file COPYING.LIB. If not, write to 23 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 24 Boston, MA 02110-1301, USA. 25 *******************************************************************************/ 26 27 #pragma once 28 29 #include "indiccdchip.h" 30 #include "defaultdevice.h" 31 #include "indiguiderinterface.h" 32 #include "indipropertynumber.h" 33 #include "inditimer.h" 34 #include "indielapsedtimer.h" 35 #include "dsp/manager.h" 36 #include "stream/streammanager.h" 37 38 #ifdef HAVE_WEBSOCKET 39 #include "indiwsserver.h" 40 #endif 41 42 #include <fitsio.h> 43 44 #include <memory> 45 #include <cstring> 46 #include <chrono> 47 #include <stdint.h> 48 #include <mutex> 49 #include <thread> 50 51 //JM 2019-01-17: Disabled until further notice 52 //#define WITH_EXPOSURE_LOOPING 53 54 extern const char * IMAGE_SETTINGS_TAB; 55 extern const char * IMAGE_INFO_TAB; 56 extern const char * GUIDE_HEAD_TAB; 57 //extern const char * RAPIDGUIDE_TAB; 58 59 namespace DSP 60 { 61 class Manager; 62 } 63 namespace INDI 64 { 65 66 class StreamManager; 67 68 /** 69 * \class CCD 70 * \brief Class to provide general functionality of CCD cameras with a single CCD sensor, or a 71 * primary CCD sensor in addition to a secondary CCD guide head. 72 * 73 * The CCD capabilities must be set to select which features are exposed to the clients. 74 * SetCCDCapability() is typically set in the constructor or initProperties(), but can also be 75 * called after connection is established with the CCD, but must be called /em before returning 76 * true in Connect(). 77 * 78 * It also implements the interface to perform guiding. The class enable the ability to \e snoop 79 * on telescope equatorial coordinates and record them in the FITS file before upload. It also 80 * snoops Sky-Quality-Meter devices to record sky quality in units of Magnitudes-Per-Arcsecond-Squared 81 * (MPASS) in the FITS header. 82 * 83 * Support for streaming and recording is available and is handled by the StreamManager class. 84 * 85 * Developers need to subclass INDI::CCD to implement any driver for CCD cameras within INDI. 86 * 87 * Data binary transfers are supported using two methods: 88 * # INDI BLOBs: This is the and recommended default configuration. 89 * # Websockets: This requires INDI to be built with websocket support. There is marginal 90 * improvement in throughput with Websockets when compared with INDI base64 BLOB encoding. 91 * It requires the client to explicitly support websockets. It is not recommended to use this 92 * approach unless for the most demanding and FPS sensitive tasks. 93 * 94 * INDI::CCD and INDI::StreamManager both upload frames asynchrounously in a worker thread. 95 * The CCD Buffer data is protected by the ccdBufferLock mutex. When reading the camera data 96 * and writing to the buffer, it must be first locked by the mutex. After the write is complete 97 * release the lock. For example: 98 * 99 * \code{.cpp} 100 * std::unique_lock<std::mutex> guard(ccdBufferLock); 101 * get_ccd_frame(PrimaryCCD.getFrameBuffer); 102 * guard.unlock(); 103 * ExposureComplete(); 104 * \endcode 105 * 106 * Similiary, before calling Streamer->newFrame, the buffer needs to be protected in a similiar fashion using 107 * the same ccdBufferLock mutex. 108 * 109 * \example CCD Simulator 110 * \version 1.1 111 * \author Jasem Mutlaq 112 * \author Gerry Rozema 113 * 114 */ 115 class CCD : public DefaultDevice, GuiderInterface 116 { 117 public: 118 CCD(); 119 virtual ~CCD(); 120 121 enum 122 { 123 CCD_CAN_BIN = 1 << 0, /*!< Does the CCD support binning? */ 124 CCD_CAN_SUBFRAME = 1 << 1, /*!< Does the CCD support setting ROI? */ 125 CCD_CAN_ABORT = 1 << 2, /*!< Can the CCD exposure be aborted? */ 126 CCD_HAS_GUIDE_HEAD = 1 << 3, /*!< Does the CCD have a guide head? */ 127 CCD_HAS_ST4_PORT = 1 << 4, /*!< Does the CCD have an ST4 port? */ 128 CCD_HAS_SHUTTER = 1 << 5, /*!< Does the CCD have a mechanical shutter? */ 129 CCD_HAS_COOLER = 1 << 6, /*!< Does the CCD have a cooler and temperature control? */ 130 CCD_HAS_BAYER = 1 << 7, /*!< Does the CCD send color data in bayer format? */ 131 CCD_HAS_STREAMING = 1 << 8, /*!< Does the CCD support live video streaming? */ 132 CCD_HAS_WEB_SOCKET = 1 << 9, /*!< Does the CCD support web socket transfers? */ 133 CCD_HAS_DSP = 1 << 10 /*!< Does the CCD support image processing? */ 134 } CCDCapability; 135 136 typedef enum { UPLOAD_CLIENT, UPLOAD_LOCAL, UPLOAD_BOTH } CCD_UPLOAD_MODE; 137 138 virtual bool initProperties() override; 139 virtual bool updateProperties() override; 140 virtual void ISGetProperties(const char * dev) override; 141 virtual bool ISNewNumber(const char * dev, const char * name, double values[], char * names[], int n) override; 142 virtual bool ISNewSwitch(const char * dev, const char * name, ISState * states, char * names[], int n) override; 143 virtual bool ISNewText(const char * dev, const char * name, char * texts[], char * names[], int n) override; 144 virtual bool ISNewBLOB(const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], 145 char *names[], int n) override; 146 virtual bool ISSnoopDevice(XMLEle * root) override; 147 148 static void wsThreadHelper(void * context); 149 150 ///////////////////////////////////////////////////////////////////////////// 151 /// Group Names 152 ///////////////////////////////////////////////////////////////////////////// 153 static constexpr const char *GUIDE_CONTROL_TAB = "Guider Control"; 154 static constexpr const char * WCS_TAB = "WCS"; 155 156 157 protected: 158 /** 159 * @brief GetCCDCapability returns the CCD capabilities. 160 */ GetCCDCapability()161 uint32_t GetCCDCapability() const 162 { 163 return capability; 164 } 165 166 /** 167 * @brief SetCCDCapability Set the CCD capabilities. Al fields must be initilized. 168 * @param cap pointer to CCDCapability struct. 169 */ 170 void SetCCDCapability(uint32_t cap); 171 172 /** 173 * @return True if CCD can abort exposure. False otherwise. 174 */ CanAbort()175 bool CanAbort() 176 { 177 return capability & CCD_CAN_ABORT; 178 } 179 180 /** 181 * @return True if CCD supports binning. False otherwise. 182 */ CanBin()183 bool CanBin() 184 { 185 return capability & CCD_CAN_BIN; 186 } 187 188 /** 189 * @return True if CCD supports subframing. False otherwise. 190 */ CanSubFrame()191 bool CanSubFrame() 192 { 193 return capability & CCD_CAN_SUBFRAME; 194 } 195 196 /** 197 * @return True if CCD has guide head. False otherwise. 198 */ HasGuideHead()199 bool HasGuideHead() 200 { 201 return capability & CCD_HAS_GUIDE_HEAD; 202 } 203 204 /** 205 * @return True if CCD has mechanical or electronic shutter. False otherwise. 206 */ HasShutter()207 bool HasShutter() 208 { 209 return capability & CCD_HAS_SHUTTER; 210 } 211 212 /** 213 * @return True if CCD has ST4 port for guiding. False otherwise. 214 */ HasST4Port()215 bool HasST4Port() 216 { 217 return capability & CCD_HAS_ST4_PORT; 218 } 219 220 /** 221 * @return True if CCD has cooler and temperature can be controlled. False otherwise. 222 */ HasCooler()223 bool HasCooler() 224 { 225 return capability & CCD_HAS_COOLER; 226 } 227 228 /** 229 * @return True if CCD sends image data in bayer format. False otherwise. 230 */ HasBayer()231 bool HasBayer() 232 { 233 return capability & CCD_HAS_BAYER; 234 } 235 236 /** 237 * @return True if the CCD supports live video streaming. False otherwise. 238 */ HasStreaming()239 bool HasStreaming() 240 { 241 if (capability & CCD_HAS_STREAMING) 242 { 243 if(Streamer.get() == nullptr) 244 { 245 Streamer.reset(new StreamManager(this)); 246 Streamer->initProperties(); 247 } 248 return true; 249 } 250 return false; 251 } 252 253 /** 254 * @return True if the CCD supports native Web Socket transfers. False otherwise. 255 */ HasWebSocket()256 bool HasWebSocket() 257 { 258 return capability & CCD_HAS_WEB_SOCKET; 259 } 260 261 /** 262 * @return True if the CCD wants DSP processing. False otherwise. 263 */ HasDSP()264 bool HasDSP() 265 { 266 if (capability & CCD_HAS_DSP) 267 { 268 if(DSP.get() == nullptr) 269 { 270 DSP.reset(new DSP::Manager(this)); 271 } 272 return true; 273 } 274 return false; 275 } 276 277 /** 278 * @brief Set CCD temperature 279 * @param temperature CCD temperature in degrees celcius. 280 * @return 0 or 1 if setting the temperature call to the hardware is successful. -1 if an 281 * error is encountered. 282 * Return 0 if setting the temperature to the requested value takes time. 283 * Return 1 if setting the temperature to the requested value is complete. 284 * \note Upon returning 0, the property becomes BUSY. Once the temperature reaches the requested 285 * value, change the state to OK. 286 * \note This function is not implemented in CCD, it must be implemented in the child class 287 */ 288 virtual int SetTemperature(double temperature); 289 290 /** 291 * \brief Start exposing primary CCD chip 292 * \param duration Duration in seconds 293 * \return true if OK and exposure will take some time to complete, false on error. 294 * \note This function is not implemented in CCD, it must be implemented in the child class 295 */ 296 virtual bool StartExposure(float duration); 297 298 /** 299 * \brief Uploads target Chip exposed buffer as FITS to the client. Dervied classes should class 300 * this function when an exposure is complete. 301 * @param targetChip chip that contains upload image data 302 * \note This function is not implemented in CCD, it must be implemented in the child class 303 */ 304 virtual bool ExposureComplete(CCDChip * targetChip); 305 306 /** 307 * \brief Abort ongoing exposure 308 * \return true is abort is successful, false otherwise. 309 * \note This function is not implemented in CCD, it must be implemented in the child class 310 */ 311 virtual bool AbortExposure(); 312 313 /** 314 * \brief Start exposing guide CCD chip 315 * \param duration Duration in seconds 316 * \return true if OK and exposure will take some time to complete, false on error. 317 * \note This function is not implemented in CCD, it must be implemented in the child class 318 */ 319 virtual bool StartGuideExposure(float duration); 320 321 /** 322 * \brief Abort ongoing exposure 323 * \return true is abort is successful, false otherwise. 324 * \note This function is not implemented in CCD, it must be implemented in the child class 325 */ 326 virtual bool AbortGuideExposure(); 327 328 /** 329 * \brief CCD calls this function when CCD Frame dimension needs to be updated in the 330 * hardware. Derived classes should implement this function 331 * \param x Subframe X coordinate in pixels. 332 * \param y Subframe Y coordinate in pixels. 333 * \param w Subframe width in pixels. 334 * \param h Subframe height in pixels. 335 * \note (0,0) is defined as most left, top pixel in the subframe. 336 * \return true is CCD chip update is successful, false otherwise. 337 * \note This function is not implemented in CCD, it must be implemented in the child class 338 */ 339 virtual bool UpdateCCDFrame(int x, int y, int w, int h); 340 341 /** 342 * \brief CCD calls this function when Guide head frame dimension is updated by the 343 * client. Derived classes should implement this function 344 * \param x Subframe X coordinate in pixels. 345 * \param y Subframe Y coordinate in pixels. 346 * \param w Subframe width in pixels. 347 * \param h Subframe height in pixels. 348 * \note (0,0) is defined as most left, top pixel in the subframe. 349 * \return true is CCD chip update is successful, false otherwise. 350 * \note This function is not implemented in CCD, it must be implemented in the child class 351 */ 352 virtual bool UpdateGuiderFrame(int x, int y, int w, int h); 353 354 /** 355 * \brief CCD calls this function when CCD Binning needs to be updated in the hardware. 356 * Derived classes should implement this function 357 * \param hor Horizontal binning. 358 * \param ver Vertical binning. 359 * \return true is CCD chip update is successful, false otherwise. 360 * \note This function is not implemented in CCD, it must be implemented in the child class 361 */ 362 virtual bool UpdateCCDBin(int hor, int ver); 363 364 /** 365 * \brief CCD calls this function when Guide head binning is updated by the client. 366 * Derived classes should implement this function 367 * \param hor Horizontal binning. 368 * \param ver Vertical binning. 369 * \return true is CCD chip update is successful, false otherwise. 370 * \note This function is not implemented in CCD, it must be implemented in the child class 371 */ 372 virtual bool UpdateGuiderBin(int hor, int ver); 373 374 /** 375 * \brief CCD calls this function when CCD frame type needs to be updated in the hardware. 376 * \param fType Frame type 377 * \return true is CCD chip update is successful, false otherwise. 378 * \note It is \e not mandatory to implement this function in the child class. The CCD hardware 379 * layer may either set the frame type when this function is called, or (optionally) before an 380 * exposure is started. 381 */ 382 virtual bool UpdateCCDFrameType(CCDChip::CCD_FRAME fType); 383 384 /** 385 * \brief CCD calls this function when client upload mode switch is updated. 386 * \param mode upload mode. UPLOAD_CLIENT only sends the upload the client application. UPLOAD_BOTH saves the frame and uploads it to the client. UPLOAD_LOCAL only saves 387 * the frame locally. 388 * \return true if mode is changed successfully, false otherwise. 389 * \note By default this function is implemented in the base class and returns true. Override if necessary. 390 */ UpdateCCDUploadMode(CCD_UPLOAD_MODE mode)391 virtual bool UpdateCCDUploadMode(CCD_UPLOAD_MODE mode) 392 { 393 INDI_UNUSED(mode); 394 return true; 395 } 396 397 /** 398 * \brief CCD calls this function when Guide frame type is updated by the client. 399 * \param fType Frame type 400 * \return true is CCD chip update is successful, false otherwise. 401 * \note It is \e not mandatory to implement this function in the child class. The CCD hardware 402 * layer may either set the frame type when this function is called, or (optionally) before an 403 * exposure is started. 404 */ 405 virtual bool UpdateGuiderFrameType(CCDChip::CCD_FRAME fType); 406 407 /** 408 * \brief Setup CCD paramters for primary CCD. Child classes call this function to update 409 * CCD parameters 410 * \param x Frame X coordinates in pixels. 411 * \param y Frame Y coordinates in pixels. 412 * \param bpp Bits Per Pixels. 413 * \param xf X pixel size in microns. 414 * \param yf Y pixel size in microns. 415 */ 416 virtual void SetCCDParams(int x, int y, int bpp, float xf, float yf); 417 418 /** 419 * \brief Setup CCD paramters for guide head CCD. Child classes call this function to update 420 * CCD parameters 421 * \param x Frame X coordinates in pixels. 422 * \param y Frame Y coordinates in pixels. 423 * \param bpp Bits Per Pixels. 424 * \param xf X pixel size in microns. 425 * \param yf Y pixel size in microns. 426 */ 427 virtual void SetGuiderParams(int x, int y, int bpp, float xf, float yf); 428 429 /** 430 * \brief Guide northward for ms milliseconds 431 * \param ms Duration in milliseconds. 432 * \note This function is not implemented in CCD, it must be implemented in the child class 433 * \return True if successful, false otherwise. 434 */ 435 virtual IPState GuideNorth(uint32_t ms) override; 436 437 /** 438 * \brief Guide southward for ms milliseconds 439 * \param ms Duration in milliseconds. 440 * \note This function is not implemented in CCD, it must be implemented in the child class 441 * \return 0 if successful, -1 otherwise. 442 */ 443 virtual IPState GuideSouth(uint32_t ms) override; 444 445 /** 446 * \brief Guide easward for ms milliseconds 447 * \param ms Duration in milliseconds. 448 * \note This function is not implemented in CCD, it must be implemented in the child class 449 * \return 0 if successful, -1 otherwise. 450 */ 451 virtual IPState GuideEast(uint32_t ms) override; 452 453 /** 454 * \brief Guide westward for ms milliseconds 455 * \param ms Duration in milliseconds. 456 * \note This function is not implemented in CCD, it must be implemented in the child class 457 * \return 0 if successful, -1 otherwise. 458 */ 459 virtual IPState GuideWest(uint32_t ms) override; 460 461 /** 462 * @brief StartStreaming Start live video streaming 463 * @return True if successful, false otherwise. 464 */ 465 virtual bool StartStreaming(); 466 467 /** 468 * @brief StopStreaming Stop live video streaming 469 * @return True if successful, false otherwise. 470 */ 471 virtual bool StopStreaming(); 472 473 /** 474 * \brief Add FITS keywords to a fits file 475 * \param fptr pointer to a valid FITS file. 476 * \param targetChip The target chip to extract the keywords from. 477 * \note In additional to the standard FITS keywords, this function write the following 478 * keywords the FITS file: 479 * <ul> 480 * <li>EXPTIME: Total Exposure Time (s)</li> 481 * <li>DARKTIME (if applicable): Total Exposure Time (s)</li> 482 * <li>PIXSIZE1: Pixel Size 1 (microns)</li> 483 * <li>PIXSIZE2: Pixel Size 2 (microns)</li> 484 * <li>BINNING: Binning HOR x VER</li> 485 * <li>FRAME: Frame Type</li> 486 * <li>DATAMIN: Minimum value</li> 487 * <li>DATAMAX: Maximum value</li> 488 * <li>INSTRUME: CCD Name</li> 489 * <li>DATE-OBS: UTC start date of observation</li> 490 * </ul> 491 * 492 * To add additional information, override this function in the child class and ensure to call 493 * CCD::addFITSKeywords. 494 */ 495 virtual void addFITSKeywords(fitsfile * fptr, CCDChip * targetChip); 496 497 /** A function to just remove GCC warnings about deprecated conversion */ 498 void fits_update_key_s(fitsfile * fptr, int type, std::string name, void * p, std::string explanation, int * status); 499 500 /** 501 * @brief activeDevicesUpdated Inform children that ActiveDevices property was updated so they can 502 * snoop on the updated devices if desired. 503 */ activeDevicesUpdated()504 virtual void activeDevicesUpdated() {} 505 506 /** 507 * @brief saveConfigItems Save configuration items in XML file. 508 * @param fp pointer to file to write to 509 * @return True if successful, false otherwise 510 */ 511 virtual bool saveConfigItems(FILE * fp) override; 512 513 /** 514 * @brief GuideComplete Signal guide pulse completion 515 * @param axis which axis the guide pulse was acting on 516 */ 517 virtual void GuideComplete(INDI_EQ_AXIS axis) override; 518 519 /** 520 * @brief checkTemperatureTarget Checks the current temperature against target temperature and calculates 521 * the next required temperature if there is a ramp. If the current temperature is within threshold of 522 * target temperature, it sets the state as OK. 523 */ 524 virtual void checkTemperatureTarget(); 525 526 527 // Epoch Position 528 double RA, Dec; 529 530 // pier side, read from mount if available, set to -1 if not available 531 int pierSide; // West = 0, East =1. No enum available 532 533 // J2000 Position 534 double J2000RA; 535 double J2000DE; 536 537 double primaryFocalLength, primaryAperture, guiderFocalLength, guiderAperture; 538 bool InExposure; 539 bool InGuideExposure; 540 //bool RapidGuideEnabled; 541 //bool GuiderRapidGuideEnabled; 542 543 bool AutoLoop; 544 bool GuiderAutoLoop; 545 bool SendImage; 546 bool GuiderSendImage; 547 bool ShowMarker; 548 bool GuiderShowMarker; 549 550 double ExposureTime; 551 double GuiderExposureTime; 552 553 // Sky Quality 554 double MPSAS; 555 556 // Rotator Angle 557 double RotatorAngle; 558 559 // JJ ed 2019-12-10 current focuser position 560 long FocuserPos; 561 double FocuserTemp; 562 563 // Airmass 564 double Airmass; 565 double Latitude; 566 double Longitude; 567 double Azimuth; 568 double Altitude; 569 570 // Temperature Control 571 double m_TargetTemperature {0}; 572 INDI::Timer m_TemperatureCheckTimer; 573 INDI::ElapsedTimer m_TemperatureElapsedTimer; 574 575 // Threading 576 std::mutex ccdBufferLock; 577 578 std::vector<std::string> FilterNames; 579 int CurrentFilterSlot {-1}; 580 581 std::unique_ptr<StreamManager> Streamer; 582 std::unique_ptr<DSP::Manager> DSP; 583 CCDChip PrimaryCCD; 584 CCDChip GuideCCD; 585 586 /////////////////////////////////////////////////////////////////////////////// 587 /// Properties 588 /////////////////////////////////////////////////////////////////////////////// 589 590 591 /** 592 * @brief EqNP Snoop property to read the equatorial coordinates of the mount. 593 * ActiveDeviceTP defines snoop devices and the driver listens to this property emitted 594 * by the mount driver if specified. It is important to generate a proper FITS header. 595 */ 596 INumberVectorProperty EqNP; 597 INumber EqN[2]; 598 599 /** 600 * @brief ActiveDeviceTP defines 4 devices the camera driver can listen to (snoop) for 601 * properties of interest so that it can generate a proper FITS header. 602 * + **Mount**: Listens for equatorial coordinates in JNow epoch. 603 * + **Rotator**: Listens for Rotator Absolute Rotation Angle (E of N) in degrees. 604 * + **Filter Wheel**: Listens for FILTER_SLOT and FILTER_NAME properties. 605 * + **SQM**: Listens for sky quality meter magnitude. 606 */ 607 ITextVectorProperty ActiveDeviceTP; 608 609 // JJ ed 2019-12-10 610 IText ActiveDeviceT[5] {}; 611 enum 612 { 613 ACTIVE_TELESCOPE, 614 ACTIVE_ROTATOR, 615 ACTIVE_FOCUSER, 616 ACTIVE_FILTER, 617 ACTIVE_SKYQUALITY 618 }; 619 620 /** 621 * @brief TemperatureNP Camera Temperature in Celcius. 622 */ 623 INumberVectorProperty TemperatureNP; 624 INumber TemperatureN[1]; 625 626 /** 627 * @brief Temperature Ramp in C/Min with configurable threshold 628 */ 629 INDI::PropertyNumber TemperatureRampNP {2}; 630 enum 631 { 632 RAMP_SLOPE, 633 RAMP_THRESHOLD 634 }; 635 636 /** 637 *@brief BayerTP Bayer pattern offset and type 638 */ 639 ITextVectorProperty BayerTP; 640 IText BayerT[3] {}; 641 642 /** 643 *@brief FileNameTP File name of locally-saved images. By default, images are uploaded to the client 644 * but when upload option is set to either @a Both or @a Local, then they are saved on the local disk with 645 * this name. 646 */ 647 ITextVectorProperty FileNameTP; 648 IText FileNameT[1] {}; 649 650 ISwitch UploadS[3]; 651 ISwitchVectorProperty UploadSP; 652 653 IText UploadSettingsT[2] {}; 654 ITextVectorProperty UploadSettingsTP; 655 enum 656 { 657 UPLOAD_DIR, 658 UPLOAD_PREFIX 659 }; 660 661 ISwitch TelescopeTypeS[2]; 662 ISwitchVectorProperty TelescopeTypeSP; 663 enum 664 { 665 TELESCOPE_PRIMARY, 666 TELESCOPE_GUIDE 667 }; 668 669 // Websocket Support 670 ISwitch WebSocketS[2]; 671 ISwitchVectorProperty WebSocketSP; 672 enum 673 { 674 WEBSOCKET_ENABLED, 675 WEBSOCKET_DISABLED, 676 }; 677 678 679 // Websocket Settings 680 INumber WebSocketSettingsN[1]; 681 INumberVectorProperty WebSocketSettingsNP; 682 enum 683 { 684 WS_SETTINGS_PORT, 685 }; 686 687 // WCS 688 ISwitch WorldCoordS[2]; 689 ISwitchVectorProperty WorldCoordSP; 690 691 // WCS CCD Rotation 692 INumber CCDRotationN[1]; 693 INumberVectorProperty CCDRotationNP; 694 695 #ifdef WITH_EXPOSURE_LOOPING 696 // Exposure Looping 697 ISwitch ExposureLoopS[2]; 698 ISwitchVectorProperty ExposureLoopSP; 699 enum 700 { 701 EXPOSURE_LOOP_ON, 702 EXPOSURE_LOOP_OFF 703 }; 704 705 // Exposure Looping Count 706 INumber ExposureLoopCountN[1]; 707 INumberVectorProperty ExposureLoopCountNP; 708 double uploadTime = { 0 }; 709 std::chrono::system_clock::time_point exposureLoopStartup; 710 #endif 711 712 // FITS Header 713 IText FITSHeaderT[2] {}; 714 ITextVectorProperty FITSHeaderTP; 715 enum 716 { 717 FITS_OBSERVER, 718 FITS_OBJECT 719 }; 720 721 private: 722 uint32_t capability; 723 724 bool m_ValidCCDRotation; 725 726 /////////////////////////////////////////////////////////////////////////////// 727 /// Utility Functions 728 /////////////////////////////////////////////////////////////////////////////// 729 bool uploadFile(CCDChip * targetChip, const void * fitsData, size_t totalBytes, bool sendImage, bool saveImage); 730 void getMinMax(double * min, double * max, CCDChip * targetChip); 731 int getFileIndex(const char * dir, const char * prefix, const char * ext); 732 bool ExposureCompletePrivate(CCDChip * targetChip); 733 734 // Threading for Websocket 735 #ifdef HAVE_WEBSOCKET 736 std::thread wsThread; 737 void wsThreadEntry(); 738 INDIWSServer wsServer; 739 #endif 740 741 ///////////////////////////////////////////////////////////////////////////// 742 /// Misc. 743 ///////////////////////////////////////////////////////////////////////////// 744 friend class StreamManager; 745 friend class StreamManagerPrivate; 746 }; 747 } 748