Instrument Neutral Distributed Interface INDI 2.2.5
lx200_esp32go.cpp
Go to the documentation of this file.
1/*
2 LX200 esp32go
3 based on LX200 generic with some bits from LX200_onStep driver
4
5 Copyright (C) 2003 Jasem Mutlaq ([email protected])
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
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 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
21*/
22
23#include "lx200_esp32go.h"
24#include "lx200driver.h"
25
26#include <cstring>
27#include <mutex>
28#include <unistd.h>
29
30#define FIRMWARE_TAB "Firmware data"
31extern std::mutex lx200CommsLock;
32
48
50{
51 return "LX200 esp32go";
52}
53
55{
57
58 tcpConnection->setDefaultHost("192.168.4.1");
60
61 if (strstr(getDeviceName(), "WiFi"))
63
64 GuideRateNP[0].fill("GUIDE_RATE_WE", "W/E Rate", "%g", 0, 2, 0.05, 0.5);
65 GuideRateNP[1].fill("GUIDE_RATE_NS", "N/S Rate", "%g", 0, 2, 0.05, 0.5);
66 GuideRateNP.fill(getDeviceName(), "GUIDE_RATE", "Guide Rate", MOTION_TAB, IP_RO, 0, IPS_IDLE);
67
68 // ============== FIRMWARE_TAB
69 VersionTP[0].fill("Date", "", "");
70 VersionTP[1].fill("Time", "", "");
71 VersionTP[2].fill("Number", "", "");
72 VersionTP[3].fill("Name", "", "");
73 VersionTP.fill(getDeviceName(), "Firmware Info", "", FIRMWARE_TAB, IP_RO, 0, IPS_IDLE);
74
75 // Overwrite TRACK_CUSTOM label, with KING
76 TrackModeSP[TRACK_CUSTOM].fill("TRACK_CUSTOM", "King", ISS_OFF);
77
78 if(activeFocus)
79 {
80 //FocuserInterface
82 //Initial, these will be updated later.
83 FocusRelPosNP[0].setMin(0.);
84 FocusRelPosNP[0].setMax(5000.);
85 FocusRelPosNP[0].setValue(0);
86 FocusRelPosNP[0].setStep(10);
87 FocusAbsPosNP[0].setMin(0.);
88 FocusAbsPosNP[0].setMax(100000.);
89 FocusAbsPosNP[0].setValue(0);
90 FocusAbsPosNP[0].setStep(10);
91
93
95 }
96 return true;
97}
98
99void LX200_esp32go::ISGetProperties(const char *dev)
100{
101 if (dev != nullptr && strcmp(dev, getDeviceName()) != 0)
102 return;
103
104 // process parent first
106
107}
108
110{
112
113 if(activeFocus)
115
116 if (isConnected())
117 {
118 if(!picgotoMode)
119 {
122 }
123 }
124 else
125 {
128 }
129
130 return true;
131}
132
133bool LX200_esp32go::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
134{
135 return LX200Generic::ISNewNumber(dev, name, values, names, n);
136}
137
139{
140 SetParked(false);
141 SetTrackEnabled(true);
142
143 return true;
144}
145
147{
148 if(picgotoMode)
149 {
150 LOG_WARN("Parking is not implemented in PicGoto mode. Consider upgrading to ESP32go.");
151 return true;
152 }
153 return LX200Generic::Park();
154}
155
157{
158 if (!isConnected())
159 return false;
160
161 if (isSimulation())
162 {
163 mountSim();
164 return true;
165 }
166
167 bool longPoll = false;
168 bool _checkTracking = false;
171 {
172 longPollCounter = 0;
173 longPoll = true;
174 }
175
177
179 {
180 HomeSP.reset();
182 LOG_INFO("Arrived at home.");
183 HomeSP.apply();
185 }
186 else if (TrackState == SCOPE_SLEWING)
187 {
188 if (!picgotoMode && isSlewComplete())
189 {
193
195 LOG_INFO("Slew is complete. Tracking...");
196 }
197 if(picgotoMode)
198 {
199 //LOG_INFO("Blind slew. Will track when complete...");
200 }
201 }
202 else if (TrackState == SCOPE_PARKING)
203 {
204 if (!picgotoMode || isSlewComplete())
205 {
206 SetParked(true);
207 }
208 }
209 else
210 {
211 _checkTracking = true;
212 }
213
215 {
217 LOG_ERROR("Error reading RA/DEC.");
218 EqNP.apply();
219 return false;
220 }
222
223
224 if(canGetStatus) // :GU# supported
225 {
226 char statusData[RBB_MAX_LEN] = {0};
227 int error_or_fail = getCommandSingleCharErrorOrLongResponse(PortFD, statusData, ":GU#",false);
228 //char read_buffer[1024];
229 //snprintf(read_buffer,sizeof(read_buffer),"read: %d",error_or_fail);
230 //LOG_ERROR(read_buffer);
231 if (error_or_fail > 1)
232 {
233 //LOG_INFO(statusData);
234 if (strstr(statusData, "S")) //slewing (S/s)
235 {
238 _checkTracking = false;
239 }
240
241 if (strstr(statusData, "P")) //parked (P/p)
242 {
243 if(TrackState != SCOPE_PARKED && !strstr(statusData, "S"))
244 SetParked(true);
245 }
246 else
247 {
249 {
250 UnPark();
251 _checkTracking = false;
252 }
253 }
254
255 if (strstr(statusData, "W")) //pierSide (E/W)
257 else
259 // 1-4 tracking rates (0=track off)
260 TelescopeTrackMode _TrackingMode = TRACK_SIDEREAL;
261 TelescopeTrackMode _PreviousTrackingMode = TRACK_SIDEREAL;
262 if(TrackModeSP[TRACK_LUNAR].getState() == ISS_ON)
263 _PreviousTrackingMode = TRACK_LUNAR;
264 else if(TrackModeSP[TRACK_SOLAR].getState() == ISS_ON)
265 _PreviousTrackingMode = TRACK_SOLAR;
266 else if(TrackModeSP[TRACK_CUSTOM].getState() == ISS_ON)
267 _PreviousTrackingMode = TRACK_CUSTOM;
268
269 if (strstr(statusData, "4")) //KING/CUSTOM
270 _TrackingMode = TRACK_CUSTOM;
271 else if (strstr(statusData, "3")) //LUNAR
272 _TrackingMode = TRACK_LUNAR;
273 else if (strstr(statusData, "2")) //SOLAR
274 _TrackingMode = TRACK_SOLAR;
275
276 if(_TrackingMode != _PreviousTrackingMode)
277 {
279 TrackModeSP[_TrackingMode].setState(ISS_ON);
282 }
283
284 if(_checkTracking)
285 {
286 auto wasTracking = (TrackStateSP[INDI_ENABLED].getState() == ISS_ON);
287 auto nowTracking = ISS_ON;
288 if(strstr(statusData, "t"))
289 nowTracking = ISS_OFF;
290 if (wasTracking != nowTracking)
291 TrackState = nowTracking ? SCOPE_TRACKING : SCOPE_IDLE;
292 }
293 }
294 else
295 {
296 LOG_ERROR("Error reading mount status.");
297 return false;
298 }
299
300 }
301 else
302 {
303 // track mode
304 if(trackmodeUpdate || TrackModeSP[0].getState() != ISS_ON)
305 {
306 trackmodeUpdate = false;
312 LOG_WARN("SetTrackMode not supported in this mode. Please consider upgrading. Back to Sidereal");
313 }
314
315 // pier side
316 if(!picgotoMode)
317 {
318 if(longPoll)
319 {
320 char resp[64];
321 if(getCommandString(PortFD, resp, ":pS#") < 0)
322 {
323 LOG_ERROR("Error reading Pier side.");
324 return false;
325 }
326 if(!strcmp(resp,"EAST"))
328 else if (!strcmp(resp,"WEST"))
330 else
332 }
333 }
334 else
335 {
337 }
338
339 }
340 // guide rate
341 if(!picgotoMode && longPoll && guideUpdate)
342 {
343 double pulseguiderate = 0.0;
344 if(getCommandSexa(PortFD, &pulseguiderate, ":cg#") < 0)
345 {
346 LOG_ERROR("Error reading GuideRate for RA.");
347 return false;
348 }
349 GuideRateNP[0].setValue(pulseguiderate);
350 if(getCommandSexa(PortFD, &pulseguiderate, ":cj#") < 0)
351 {
352 LOG_ERROR("Error reading GuideRate for DEC.");
353 return false;
354 }
355 GuideRateNP[1].setValue(pulseguiderate);
357 }
358
359 // --- Focuser
360 if(activeFocus)
361 {
362 if (UpdateFocuser() != 0) // Update Focuser Position
363 {
364 LOG_WARN("Communication error on Focuser Update, this update aborted, will try again...");
365 return true; //COMMUNICATION ERROR, BUT DON'T PUT TELESCOPE IN ERROR STATE
366 }
367 }
368
369
370
371
372 return true;
373}
374
375
376// copied from LX200_OnStep driver
377int LX200_esp32go::getCommandSingleCharErrorOrLongResponse(int fd, char *data, const char *cmd, bool shortTimeout)
378{
379 char *term;
380 int error_type;
381 int nbytes_write = 0, nbytes_read = 0;
382
383 DEBUGF(DBG_SCOPE, "CMD <%s>", cmd);
384
385 flushIO(fd);
386 /* Add mutex */
387 std::unique_lock<std::mutex> guard(lx200CommsLock);
388 tcflush(fd, TCIFLUSH);
389
390 if ((error_type = tty_write_string(fd, cmd, &nbytes_write)) != TTY_OK)
391 return error_type;
392
393 long int timeout = OSTimeoutMicroSeconds;
394 if(shortTimeout)
395 timeout = timeout / 4;
396
397 error_type = tty_nread_section_expanded(fd, data, RBB_MAX_LEN, '#', OSTimeoutSeconds, timeout, &nbytes_read);
398 tcflush(fd, TCIFLUSH);
399
400 term = strchr(data, '#');
401 if (term)
402 *term = '\0';
403 if (nbytes_read < RBB_MAX_LEN) //If within buffer, terminate string with \0 (in case it didn't find the #)
404 {
405 data[nbytes_read] = '\0'; //Indexed at 0, so this is the byte passed it
406 }
407 else
408 {
409 LOG_DEBUG("got RBB_MAX_LEN bytes back, last byte set to null and possible overflow");
410 data[RBB_MAX_LEN - 1] = '\0';
411 }
412
413 DEBUGF(DBG_SCOPE, "RES <%s>", data);
414
415 if (error_type != TTY_OK)
416 {
417 LOGF_DEBUG("Error %d", error_type);
418 return error_type;
419 }
420 return nbytes_read;
421
422}
423
424// copied from LX200_OnStep driver
426{
427 tcflush(fd, TCIOFLUSH);
428 int error_type = 0;
429 int nbytes_read;
430 std::unique_lock<std::mutex> guard(lx200CommsLock);
431 tcflush(fd, TCIOFLUSH);
432 do
433 {
434 char discard_data[RBB_MAX_LEN] = {0};
435 error_type = tty_nread_section_expanded(fd, discard_data, sizeof(discard_data), '#', 0, 1000, &nbytes_read);
436 if (error_type >= 0)
437 {
438 LOGF_DEBUG("flushIO: Information in buffer: Bytes: %u, string: %s", nbytes_read, discard_data);
439 }
440 //LOGF_DEBUG("flushIO: error_type = %i", error_type);
441 }
442 while (error_type > 0);
443 return 0;
444}
445
446// copied from LX200_OnStep driver
447int LX200_esp32go::getCommandSingleCharResponse(int fd, char *data, const char *cmd)
448{
449 char *term;
450 int error_type;
451 int nbytes_write = 0, nbytes_read = 0;
452
453 DEBUGF(DBG_SCOPE, "CMD <%s>", cmd);
454
455 flushIO(fd);
456 /* Add mutex */
457 std::unique_lock<std::mutex> guard(lx200CommsLock);
458
459 if ((error_type = tty_write_string(fd, cmd, &nbytes_write)) != TTY_OK)
460 return error_type;
461
462 error_type = tty_read_expanded(fd, data, 1, OSTimeoutSeconds, OSTimeoutMicroSeconds, &nbytes_read);
463 tcflush(fd, TCIFLUSH);
464
465 if (error_type != TTY_OK)
466 return error_type;
467
468 term = strchr(data, '#');
469 if (term)
470 *term = '\0';
471 if (nbytes_read < RBB_MAX_LEN) //given this function that should always be true, as should nbytes_read always be 1
472 {
473 data[nbytes_read] = '\0';
474 }
475 else
476 {
477 LOG_DEBUG("got RB_MAX_LEN bytes back (which should never happen), last byte set to null and possible overflow");
478 data[RBB_MAX_LEN - 1] = '\0';
479 }
480
481 DEBUGF(DBG_SCOPE, "RES <%s>", data);
482
483 return nbytes_read;
484}
485
486
487void LX200_esp32go::splitString(const char *str, char array[][100], int *count) {
488 const char *start = str;
489 const char *end;
490 *count = 0;
491
492 while ((end = strchr(start, '\n')) != NULL) {
493 size_t length = end - start;
494 strncpy(array[*count], start, length);
495 array[*count][length] = '\0'; // Null-terminate the string
496 (*count)++;
497 start = end + 1; // Move past the newline
498 }
499 // Handle the last line if it doesn't end with a newline
500 if (*start) {
501 strcpy(array[*count], start);
502 (*count)++;
503 }
504}
505
506bool LX200_esp32go::SetTrackEnabled(bool enabled) //track On/Off events handled by inditelescope
507{
508 if (enabled)
509 {
510 sendCommandBlind(":Qw#");
512 LOG_INFO("Tracking enabled");
513 }
514 else
515 {
516 sendCommandBlind(":Mh#");
518 LOG_INFO("Tracking disabled");
519 }
520 return true;
521}
522
524{
525 if (isSimulation())
526 return true;
527
528 LOGF_DEBUG("SetTrackMode: %d", mode);
529
530 char buffer[1024];
531 //snprintf(buffer,sizeof(buffer),"SetTrackMode: %d",mode);
532 //LOG_WARN(buffer);
533
534 if(canGetStatus)
535 {
536 switch(mode)
537 {
538 case TRACK_SIDEREAL:
539 return sendCommandBlind(":TQ#");
540 break;
541 case TRACK_SOLAR:
542 return sendCommandBlind(":TS#");
543 break;
544 case TRACK_LUNAR:
545 return sendCommandBlind(":TL#");
546 break;
547 case TRACK_CUSTOM: // KING
548 return sendCommandBlind(":TK#");
549 break;
550 default:
551 snprintf(buffer,sizeof(buffer),"TrackMode: %d not supported",mode);
552 LOG_WARN(buffer);
553 }
554 }
555 return true;
556}
557
558
560{
561 return sendCommandBlind(":hP#");
562}
563
565{
566 return sendCommandBlind(":pH#");
567}
568
570{
571 switch (action)
572 {
573 case HOME_GO:
574 if(picgotoMode)
575 {
576 LOG_WARN("Going Home is not implemented in PicGoto mode. Consider upgrading to ESP32go.");
577 return IPS_OK;
578 }
579 if (goHome())
580 return IPS_BUSY;
581 else
582 return IPS_ALERT;
583
584 case HOME_SET:
585 if(picgotoMode)
586 {
587 LOG_WARN("Home reset is not implemented in PicGoto mode. Consider upgrading to ESP32go.");
588 return IPS_OK;
589 }
590 LOG_INFO("Resetting current position to Home");
591 if(setHome())
592 {
594 return IPS_OK;
595 }
596 else
597 {
598 return IPS_ALERT;
599 }
600
601 case HOME_FIND:
602 LOG_WARN("Finding home position is not supported.");
603 return IPS_ALERT;
604
605 default:
606 return IPS_ALERT;
607 }
608}
609
611{
612 // process parent
614
615 bool _MountTypeSP_Apply = false;
616 bool _TrackStateSP_Apply = false;
617 bool _VersionTP_Apply = false;
618 bool _GuideRateNP_Apply = false;
619 bool _SetParked = false;
620
621 guideUpdate = false;
622 trackmodeUpdate = false;
623 picgotoMode = false;
624 activeFocus = true;
625 canGetStatus = false;
626
627 if (!isSimulation())
628 {
629
630 char configData[RBB_MAX_LEN];
631 int error_or_fail = getCommandSingleCharErrorOrLongResponse(PortFD, configData, ":cA#",true);
632 if (error_or_fail > 1)
633 {
634 LOG_INFO("ESP32go config read");
635 //LOG_INFO(configData);
636 char lines[26][100];
637 int lineCount;
638 splitString(configData, lines, &lineCount);
639 // az guide rate index 2
640 GuideRateNP[0].setValue(atof(lines[2]));
641 // az guide rate index 6
642 GuideRateNP[1].setValue(atof(lines[6]));
643 _GuideRateNP_Apply=true;
644
645 // mount mode index 18
647 if(*lines[18]=='1')
648 {
649 //LOG_INFO("Mount AltAz");
651 }
652 else if(*lines[18]=='2')
653 {
654 //LOG_INFO("Mount FORK");
656 }
657 else // default GEM
658 {
659 //LOG_INFO("Mount DEFAULT/GEM");
661 }
662 _MountTypeSP_Apply=true;
663 }
664 else
665 {
666 LOG_WARN("Cannot check configuration. Activating limited PicGoto mode");
667 picgotoMode = true;
668 activeFocus = false;
669 char MountAlign[2];
670 *MountAlign = ACK(PortFD); // get mount type from ACK response
672 if(MountAlign[0] == 'A')
673 {
674 //LOG_INFO("Mount AltAz");
676 }
677 else
678 {
679 //LOG_INFO("Mount Default/GEM");
680 MountTypeSP[MOUNT_EQ_GEM].setState(ISS_ON); // Default GEM
681 }
682 _MountTypeSP_Apply=true;
683 }
684 double version = 0.0;
685 if(picgotoMode || getCommandSexa(PortFD, &version, ":GVN#") < 0)
686 {
687 if(!picgotoMode)
688 LOG_WARN("Cannot check FW version. Activating limited PicGoto mode");
689
690 picgotoMode = true;
691 activeFocus = false;
692 }
693 else
694 {
695 if(version > 5)
696 {
697 guideUpdate = true;
698 //LOG_INFO("Updated version");
699 // check :GU# support
700 canGetStatus = false;
701 char statusData[RBB_MAX_LEN] = {0};
702 error_or_fail = getCommandSingleCharErrorOrLongResponse(PortFD, statusData, ":GU#",false);
703 if (error_or_fail > 1)
704 {
705 canGetStatus = true;
706 //LOG_INFO("Status and TrackMode supported.");
707 // initial tracking state
708 if (strstr(statusData, "T"))
709 {
713 }
714 else
715 {
719 }
720 _TrackStateSP_Apply=true;
721 // initial parking status
722 if (strstr(statusData, "P")) //parked (P/p)
723 {
724 if(TrackState != SCOPE_PARKED && !strstr(statusData, "S"))
725 {
726 _SetParked = true;
727 }
728 }
729 }
730 else
731 {
732 LOG_INFO("Status and TrackMode NOT supported. Consider updating FW.");
733 }
734 }
735 else
736 {
737 //LOG_INFO("preDrv version");
738 LOG_INFO("Pre v06.3 FW. Dectivating guidePulse periodic check");
739 }
740 char buffer[128] = {0};
741 getVersionDate(PortFD, buffer);
742 VersionTP[0].setText(buffer);
743 getVersionTime(PortFD, buffer);
744 VersionTP[1].setText(buffer);
745 getVersionNumber(PortFD, buffer);
746 VersionTP[2].setText(buffer);
747 getProductName(PortFD, buffer);
748 VersionTP[3].setText(buffer);
749 _VersionTP_Apply=true;
750 }
751 if(!canGetStatus)
752 {
753 // initial tracking state
754 char isTracking[4];
755 if(!picgotoMode && getCommandSingleCharResponse(PortFD, isTracking, ":Gk#") < 0)
756 {
757 LOG_ERROR("Error reading tracking status.");
758 }
759 else
760 {
761 if (picgotoMode || strcmp(isTracking, "1")==0)
762 {
766 }
767 else
768 {
772 }
773 _TrackStateSP_Apply=true;
774 //LOG_INFO("TrackState read");
775 }
776 }
777 }
778 if(activeFocus)
779 LOG_INFO("Focuser is active");
780
781 if(_MountTypeSP_Apply)
783 if(_TrackStateSP_Apply)
785 if(_GuideRateNP_Apply)
787 if(_VersionTP_Apply)
789 if(_SetParked)
790 SetParked(true);
791
792}
793
794
796{
797 int error_type;
798 int nbytes_write = 0;
799
800 DEBUGF(DBG_SCOPE, "CMD <%s>", cmd);
801
803 /* Add mutex */
804 std::unique_lock<std::mutex> guard(lx200CommsLock);
805 tcflush(PortFD, TCIFLUSH);
806
807
808 if ((error_type = tty_write_string(PortFD, cmd, &nbytes_write)) != TTY_OK)
809 {
810 LOGF_ERROR("CHECK CONNECTION: Error sending command %s", cmd);
811 return 0; //Fail if we can't write
812 //return error_type;
813 }
814
815 return 1;
816}
817// -----------------
818// FOCUSER INTERFACE
819
821{
822 if(!activeFocus)
823 return IPS_OK;
824 //LOG_INFO("FOCUSER MoveAbsFocuser");
825 if (FocusAbsPosNP[0].getMax() >= int(targetTicks) && FocusAbsPosNP[0].getMin() <= int(targetTicks))
826 {
827 char read_buffer[32];
828 snprintf(read_buffer, sizeof(read_buffer), ":FA+%05d#", int(targetTicks));
829 //LOG_INFO(read_buffer);
830 sendCommandBlind(read_buffer);
831 return IPS_BUSY; // Normal case, should be set to normal by update.
832 }
833 else
834 {
835 LOG_INFO("Unable to move focuser, out of range");
836 return IPS_ALERT;
837 }
838}
839
841{
842 if(!activeFocus)
843 return IPS_OK;
844 //LOG_INFO("FOCUSER MoveRelFocuser");
845 char read_buffer[32];
846 char s = (dir == FOCUS_INWARD ? '-':'+');
847 snprintf(read_buffer, sizeof(read_buffer), ":FP%c%05d#", s, ticks);
848 //LOG_INFO(read_buffer);
849 sendCommandBlind(read_buffer);
850 return IPS_BUSY; // Normal case, should be set to normal by update.
851}
852
854{
855 LOG_INFO("FOCUSER AbortFocuser");
856 // :FQ# Stop the focuser
857 // Returns: Nothing
858 char cmd[CMDB_MAX_LEN] = {0};
859 strncpy(cmd, ":FQ#", sizeof(cmd));
860 return sendCommandBlind(cmd);
861}
862
864{
865 if(!activeFocus)
866 return false;
867
868 bool busy = false;
869 //char value[RBB_MAX_LEN] = {0};
870 int value_int;
871 if(getCommandInt(PortFD, &value_int, ":FB#") < 0)
872 {
873 LOG_ERROR("Error reading focuser status.");
874 return false;
875 }
876 if(value_int == 1) // moving
877 {
878 busy = true;
881 }
882 if(getCommandInt(PortFD, &value_int, ":Fp#") < 0)
883 {
888 LOG_ERROR("Error reading focuser position.");
889 return false;
890 }
891
892 if(FocusAbsPosNP[0].getValue() == value_int) // no change, no need to update
893 return 0;
894
895 //LOG_INFO("FOCUSER STATUS UPDATED");
896 FocusAbsPosNP[0].setValue(value_int);
897 //double current = FocusAbsPosNP[0].getValue();
898 if(!busy)
899 {
902 }
903 LOGF_DEBUG("Current focuser: %d, %f", value_int, FocusAbsPosNP[0].getValue());
904
907 //FI::updateProperties();
908
909 return 0;
910}
911
void setDefaultHost(const char *addressHost)
void setDefaultPort(uint32_t addressPort)
bool isConnected() const
void setActiveConnection(Connection::Interface *existingConnection)
setActiveConnection Switch the active connection to the passed connection plugin
void setDriverInterface(uint32_t value)
setInterface Set driver interface. By default the driver interface is set to GENERAL_DEVICE....
void setVersion(uint16_t vMajor, uint16_t vMinor)
Set driver version information to be defined in DRIVER_INFO property as vMajor.vMinor.
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
void defineProperty(INumberVectorProperty *property)
bool isSimulation() const
uint32_t getDriverInterface() const
INDI::PropertyNumber FocusRelPosNP
bool updateProperties()
updateProperties Define or Delete Rotator properties based on the connection status of the base devic...
void SetCapability(uint32_t cap)
FI::SetCapability sets the focuser capabilities. All capabilities must be initialized.
void initProperties(const char *groupName)
Initialize focuser properties. It is recommended to call this function within initProperties() of you...
INDI::PropertyNumber FocusAbsPosNP
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, ISRule rule, double timeout, IPState state)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
TelescopeStatus TrackState
void SetTelescopeCapability(uint32_t cap, uint8_t slewRateCount)
SetTelescopeCapability sets the Telescope capabilities. All capabilities must be initialized.
virtual void SetParked(bool isparked)
SetParked Change the mount parking status. The data park file (stored in ~/.indi/ParkData....
Connection::TCP * tcpConnection
void NewRaDec(double ra, double dec)
The child class calls this function when it has updates.
void setPierSide(TelescopePierSide side)
virtual bool initProperties() override
Called to initialize basic properties required all the time.
virtual bool Park() override
Park the telescope to its home position.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual bool isSlewComplete()
virtual bool updateProperties() override
Called when connected state changes, to add/remove properties.
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...
virtual void getBasicData()
void setLX200Capability(uint32_t cap)
void splitString(const char *str, char array[][100], int *count)
IPState MoveAbsFocuser(uint32_t targetTicks) override
MoveFocuser the focuser to an absolute position.
const char * getDefaultName() override
IPState MoveRelFocuser(FocusDirection dir, uint32_t ticks) override
MoveFocuser the focuser to an relative position.
bool initProperties() override
Called to initialize basic properties required all the time.
long int OSTimeoutMicroSeconds
long int longPollCounter
INDI::PropertyText VersionTP
bool sendCommandBlind(const char *cmd)
int getCommandSingleCharResponse(int fd, char *data, const char *cmd)
virtual void getBasicData() override
void ISGetProperties(const char *dev) override
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
int flushIO(int fd)
bool AbortFocuser() override
AbortFocuser all focus motion.
virtual bool SetTrackMode(uint8_t mode) override
SetTrackMode Set active tracking mode. Do not change track state.
int getCommandSingleCharErrorOrLongResponse(int fd, char *data, const char *cmd, bool shortTimeout)
virtual IPState ExecuteHomeAction(TelescopeHomeAction action) override
Execute a homing action.
virtual bool ReadScopeStatus() override
Read telescope status.
virtual bool UnPark() override
Unpark the telescope if already parked.
INDI::PropertyNumber GuideRateNP
bool updateProperties() override
Called when connected state changes, to add/remove properties.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
long int longPollCycle
long int OSTimeoutSeconds
virtual bool Park() override
Park the telescope to its home position.
virtual bool SetTrackEnabled(bool enabled) override
SetTrackEnabled Engages or disengages mount tracking. If there are no tracking modes available,...
const char * MOTION_TAB
MOTION_TAB Where all the motion control properties of the device are located.
const char * FOCUS_TAB
FOCUS_TAB Where all the properties for focuser are located.
INDI::PropertyNumber EqNP
INDI::PropertySwitch TrackStateSP
INDI::PropertySwitch HomeSP
INDI::PropertySwitch SlewRateSP
INDI::PropertySwitch TrackModeSP
INDI::PropertySwitch MountTypeSP
@ ISS_OFF
Definition indiapi.h:149
@ ISS_ON
Definition indiapi.h:150
@ IP_RO
Definition indiapi.h:182
IPState
Property state.
Definition indiapi.h:158
@ IPS_BUSY
Definition indiapi.h:161
@ IPS_ALERT
Definition indiapi.h:162
@ IPS_IDLE
Definition indiapi.h:159
@ IPS_OK
Definition indiapi.h:160
int tty_write_string(int fd, const char *buf, int *nbytes_written)
Writes a null terminated string to fd.
Definition indicom.c:473
int tty_read_expanded(int fd, char *buf, int nbytes, long timeout_seconds, long timeout_microseconds, int *nbytes_read)
read buffer from terminal with a delimiter
Definition indicom.c:553
int tty_nread_section_expanded(int fd, char *buf, int nsize, char stop_char, long timeout_seconds, long timeout_microseconds, int *nbytes_read)
read buffer from terminal with a delimiter
Definition indicom.c:764
@ TTY_OK
Definition indicom.h:54
#define LOG_DEBUG(txt)
Definition indilogger.h:75
#define LOG_WARN(txt)
Definition indilogger.h:73
#define LOGF_DEBUG(fmt,...)
Definition indilogger.h:83
#define LOG_ERROR(txt)
Shorter logging macros. In order to use these macros, the function (or method) "getDeviceName()" must...
Definition indilogger.h:72
#define LOGF_ERROR(fmt,...)
Definition indilogger.h:80
#define LOG_INFO(txt)
Definition indilogger.h:74
#define DEBUGF(priority, msg,...)
Definition indilogger.h:57
#define getDeviceName
int fd
std::mutex lx200CommsLock
#define FIRMWARE_TAB
#define RBB_MAX_LEN
#define CMDB_MAX_LEN
int getCommandInt(int fd, int *value, const char *cmd)
int getCommandSexa(int fd, double *value, const char *cmd)
int getCommandString(int fd, char *data, const char *cmd)
#define getVersionDate(fd, x)
#define getVersionTime(fd, x)
#define getLX200DEC(fd, x)
#define getVersionNumber(fd, x)
#define getLX200RA(fd, x)
#define getProductName(fd, x)
uint8_t cmd[4]
Definition pwc-ioctl.h:2
#define ACK
Definition stvdriver.h:35