Instrument Neutral Distributed Interface INDI 2.2.5
pegasus_focuscube.cpp
Go to the documentation of this file.
1/*******************************************************************************
2 Copyright(c) 2021 Chrysikos Efstathios. All rights reserved.
3
4 Pegasus FocusCube
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2 of the License, or (at your option)
9 any later version.
10
11 This program is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20
21 The full GNU General Public License is included in this distribution in the
22 file called LICENSE.
23*******************************************************************************/
24#include "pegasus_focuscube.h"
25
26#include "indicom.h"
28
29#include <cmath>
30#include <cstring>
31#include <memory>
32
33#include <termios.h>
34#include <unistd.h>
35
36#define DMFC_TIMEOUT 3
37#define FOCUS_SETTINGS_TAB "Settings"
38#define TEMPERATURE_THRESHOLD 0.1
39
40static std::unique_ptr<PegasusFocusCube> focusCube(new PegasusFocusCube());
41
43{
44 // Can move in Absolute & Relative motions, can AbortFocuser motion.
51}
52
54{
56
57 // Focuser temperature
58 IUFillNumber(&TemperatureN[0], "TEMPERATURE", "Celsius", "%6.2f", -50, 70., 0., 0.);
59 IUFillNumberVector(&TemperatureNP, TemperatureN, 1, getDeviceName(), "FOCUS_TEMPERATURE", "Temperature",
61
62 // Max Speed
63 IUFillNumber(&MaxSpeedN[0], "Value", "", "%6.2f", 100, 1000., 100., 400.);
64 IUFillNumberVector(&MaxSpeedNP, MaxSpeedN, 1, getDeviceName(), "MaxSpeed", "", FOCUS_SETTINGS_TAB, IP_RW, 0, IPS_IDLE);
65
66 // Encoders
67 IUFillSwitch(&EncoderS[ENCODERS_ON], "On", "", ISS_ON);
68 IUFillSwitch(&EncoderS[ENCODERS_OFF], "Off", "", ISS_OFF);
69 IUFillSwitchVector(&EncoderSP, EncoderS, 2, getDeviceName(), "Encoders", "", FOCUS_SETTINGS_TAB, IP_RW, ISR_1OFMANY, 0,
70 IPS_IDLE);
71
72 // LED
73 IUFillSwitch(&LEDS[LED_OFF], "Off", "", ISS_ON);
74 IUFillSwitch(&LEDS[LED_ON], "On", "", ISS_OFF);
76
77 // Firmware Version
78 IUFillText(&FirmwareVersionT[0], "Version", "Version", "");
79 IUFillTextVector(&FirmwareVersionTP, FirmwareVersionT, 1, getDeviceName(), "Firmware", "Firmware", MAIN_CONTROL_TAB, IP_RO,
80 0, IPS_IDLE);
81
82 // Relative and absolute movement
83 FocusRelPosNP[0].setMin(0.);
84 FocusRelPosNP[0].setMax(50000.);
85 FocusRelPosNP[0].setValue(0);
86 FocusRelPosNP[0].setStep(1000);
87
88 FocusAbsPosNP[0].setMin(0.);
89 FocusAbsPosNP[0].setValue(0);
90 FocusAbsPosNP[0].setStep(1000);
91
92 // Backlash compensation
93 FocusBacklashNP[0].setMin(1); // 0 is off.
94 FocusBacklashNP[0].setMax(10000);
95 FocusBacklashNP[0].setValue(1);
96 FocusBacklashNP[0].setStep(1);
97
98 FocusMaxPosNP[0].setMax(1317500);
99 FocusMaxPosNP[0].setValue(1317500);
100 FocusAbsPosNP[0].setMax(1317500);
101
102 //LED Default ON
103 LEDS[LED_ON].s = ISS_ON;
104 LEDS[LED_OFF].s = ISS_OFF;
105
110
111 return true;
112}
113
115{
117
118 if (isConnected())
119 {
120 defineProperty(&MaxSpeedNP);
121 defineProperty(&TemperatureNP);
122 defineProperty(&EncoderSP);
123 defineProperty(&LEDSP);
124 defineProperty(&FirmwareVersionTP);
125 }
126 else
127 {
128 deleteProperty(MaxSpeedNP.name);
129 deleteProperty(TemperatureNP.name);
130 deleteProperty(EncoderSP.name);
131 deleteProperty(LEDSP.name);
132 deleteProperty(FirmwareVersionTP.name);
133 }
134
135 return true;
136}
137
139{
140 if (ack())
141 {
142 LOGF_INFO("%s is online. Getting focus parameters...", this->getDeviceName());
143 return true;
144 }
145
146 LOGF_INFO(
147 "Error retrieving data from %s, please ensure device is powered and the port is correct.", this->getDeviceName());
148 return false;
149}
150
152{
153 return "Pegasus FocusCube";
154}
155
156bool PegasusFocusCube::ack()
157{
158 int nbytes_written = 0, nbytes_read = 0, rc = -1;
159 char errstr[MAXRBUF];
160 char cmd[2] = {0};
161 char res[16] = {0};
162
163 cmd[0] = '#';
164 cmd[1] = 0xA;
165
166 LOGF_DEBUG("CMD <%#02X>", cmd[0]);
167
168 tcflush(PortFD, TCIOFLUSH);
169
170 if ((rc = tty_write(PortFD, cmd, 2, &nbytes_written)) != TTY_OK)
171 {
172 tty_error_msg(rc, errstr, MAXRBUF);
173 LOGF_ERROR("Ack error: %s.", errstr);
174 return false;
175 }
176
177 if ((rc = tty_read_section(PortFD, res, 0xA, DMFC_TIMEOUT, &nbytes_read)) != TTY_OK)
178 {
179 tty_error_msg(rc, errstr, MAXRBUF);
180 LOGF_ERROR("Ack error: %s.", errstr);
181 return false;
182 }
183
184 // Get rid of 0xA
185 res[nbytes_read - 1] = 0;
186
187
188 if( res[nbytes_read - 2] == '\r') res[nbytes_read - 2] = 0;
189
190 LOGF_DEBUG("RES <%s>", res);
191
192 tcflush(PortFD, TCIOFLUSH);
193
194 if(strstr(res, "OK_FC") != nullptr)
195 return true;
196
197 return false;
198}
199
200
202{
203 int nbytes_written = 0, rc = -1;
204 char cmd[16] = {0};
205
206 snprintf(cmd, 16, "W:%ud", ticks);
207 cmd[strlen(cmd)] = 0xA;
208
209 LOGF_DEBUG("CMD <%s>", cmd);
210
211 // Set Position
212 if ((rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
213 {
214 char errstr[MAXRBUF];
215 tty_error_msg(rc, errstr, MAXRBUF);
216 LOGF_ERROR("sync error: %s.", errstr);
217 return false;
218 }
219
220 this->ignoreResponse();
221
222 return true;
223}
224
225bool PegasusFocusCube::move(uint32_t newPosition)
226{
227 int nbytes_written = 0, rc = -1;
228 char cmd[16] = {0};
229
230 snprintf(cmd, 16, "M:%ud", newPosition);
231 cmd[strlen(cmd)] = 0xA;
232
233 LOGF_DEBUG("CMD <%s>", cmd);
234
235 // Set Position
236 if ((rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
237 {
238 char errstr[MAXRBUF];
239 tty_error_msg(rc, errstr, MAXRBUF);
240 LOGF_ERROR("move error: %s.", errstr);
241 return false;
242 }
243
244 this->ignoreResponse();
245
246 return true;
247}
248
249bool PegasusFocusCube::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
250{
251 if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
252 {
253
254 // Encoders
255 if (!strcmp(name, EncoderSP.name))
256 {
257 IUUpdateSwitch(&EncoderSP, states, names, n);
258 bool rc = setEncodersEnabled(EncoderS[ENCODERS_ON].s == ISS_ON);
259 EncoderSP.s = rc ? IPS_OK : IPS_ALERT;
260 IDSetSwitch(&EncoderSP, nullptr);
261 return true;
262 }
263
264 // LED
265 if (!strcmp(name, LEDSP.name))
266 {
267 IUUpdateSwitch(&LEDSP, states, names, n);
268 bool rc = setLedEnabled(LEDS[LED_ON].s == ISS_ON);
269 LEDSP.s = rc ? IPS_OK : IPS_ALERT;
270 IDSetSwitch(&LEDSP, nullptr);
271 return true;
272 }
273 }
274 return INDI::Focuser::ISNewSwitch(dev, name, states, names, n);
275}
276
277bool PegasusFocusCube::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
278{
279 if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
280 {
281 // MaxSpeed
282 if (strcmp(name, MaxSpeedNP.name) == 0)
283 {
284 IUUpdateNumber(&MaxSpeedNP, values, names, n);
285 bool rc = setMaxSpeed(MaxSpeedN[0].value);
286 MaxSpeedNP.s = rc ? IPS_OK : IPS_ALERT;
287 IDSetNumber(&MaxSpeedNP, nullptr);
288 return true;
289 }
290
291 }
292
293 return INDI::Focuser::ISNewNumber(dev, name, values, names, n);
294}
295
296void PegasusFocusCube::ignoreResponse()
297{
298 int nbytes_read = 0;
299 char res[64];
300 tty_read_section(PortFD, res, 0xA, DMFC_TIMEOUT, &nbytes_read);
301}
302
303bool PegasusFocusCube::updateFocusParams()
304{
305 int nbytes_written = 0, nbytes_read = 0, rc = -1;
306 char errstr[MAXRBUF];
307 char cmd[3] = {0};
308 char res[64];
309 cmd[0] = 'A';
310 cmd[1] = 0xA;
311
312 LOGF_DEBUG("CMD <%#02X>", cmd[0]);
313
314 tcflush(PortFD, TCIOFLUSH);
315
316 if ((rc = tty_write(PortFD, cmd, 2, &nbytes_written)) != TTY_OK)
317 {
318 tty_error_msg(rc, errstr, MAXRBUF);
319 LOGF_ERROR("GetFocusParams error: %s.", errstr);
320 return false;
321 }
322
323
324 if ((rc = tty_read_section(PortFD, res, 0xA, DMFC_TIMEOUT, &nbytes_read)) != TTY_OK)
325 {
326 tty_error_msg(rc, errstr, MAXRBUF);
327 LOGF_ERROR("GetFocusParams error: %s.", errstr);
328 return false;
329 }
330
331 res[nbytes_read - 1] = 0;
332
333 // Check for '\r' at end of string and replace with nullptr (DMFC firmware version 2.8)
334 if( res[nbytes_read - 2] == '\r') res[nbytes_read - 2] = 0;
335
336 LOGF_DEBUG("RES <%s>", res);
337
338 tcflush(PortFD, TCIOFLUSH);
339
340 char *token = std::strtok(res, ":");
341
342 // #1 Status
343 if (token == nullptr || (strstr(token, "OK_FC") == nullptr))
344 {
345 LOGF_ERROR("Invalid status response. %s", res);
346 return false;
347 }
348
349 // #2 Version
350 token = std::strtok(nullptr, ":");
351
352 if (token == nullptr)
353 {
354 LOG_ERROR("Invalid version response.");
355 return false;
356 }
357
358 if (FirmwareVersionT[0].text == nullptr || strcmp(FirmwareVersionT[0].text, token))
359 {
360 IUSaveText(&FirmwareVersionT[0], token);
361 FirmwareVersionTP.s = IPS_OK;
362 IDSetText(&FirmwareVersionTP, nullptr);
363 }
364
365 // #3 Motor Type
366 token = std::strtok(nullptr, ":");
367
368 // #4 Temperature
369 token = std::strtok(nullptr, ":");
370
371 if (token == nullptr)
372 {
373 LOG_ERROR("Invalid temperature response.");
374 return false;
375 }
376
377 double temperature = atof(token);
378 if (temperature == -127)
379 {
380 TemperatureNP.s = IPS_ALERT;
381 IDSetNumber(&TemperatureNP, nullptr);
382 }
383 else
384 {
385 if (fabs(temperature - TemperatureN[0].value) > TEMPERATURE_THRESHOLD)
386 {
387 TemperatureN[0].value = temperature;
388 TemperatureNP.s = IPS_OK;
389 IDSetNumber(&TemperatureNP, nullptr);
390 }
391 }
392
393 // #5 Position
394 token = std::strtok(nullptr, ":");
395
396 if (token == nullptr)
397 {
398 LOG_ERROR("Invalid position response.");
399 return false;
400 }
401
402 currentPosition = atoi(token);
403 if (currentPosition != FocusAbsPosNP[0].getValue())
404 {
405 FocusAbsPosNP[0].setValue(currentPosition);
407 }
408
409 // #6 Moving Status
410 token = std::strtok(nullptr, ":");
411
412 if (token == nullptr)
413 {
414 LOG_ERROR("Invalid moving status response.");
415 return false;
416 }
417
418 isMoving = (token[0] == '1');
419
420 // #7 LED Status
421 token = std::strtok(nullptr, ":");
422
423 if (token == nullptr)
424 {
425 LOG_ERROR("Invalid LED response.");
426 return false;
427 }
428
429 int ledStatus = atoi(token);
430 if (ledStatus >= 0 && ledStatus <= 1)
431 {
432 IUResetSwitch(&LEDSP);
433 LEDS[ledStatus].s = ISS_ON;
434 LEDSP.s = IPS_OK;
435 IDSetSwitch(&LEDSP, nullptr);
436 }
437
438 // #8 Reverse Status
439 token = std::strtok(nullptr, ":");
440
441 if (token == nullptr)
442 {
443 LOG_ERROR("Invalid reverse response.");
444 return false;
445 }
446
447 int reverseStatus = atoi(token);
448 if (reverseStatus >= 0 && reverseStatus <= 1)
449 {
451 FocusReverseSP[INDI_ENABLED].setState((reverseStatus == 1) ? ISS_ON : ISS_OFF);
452 FocusReverseSP[INDI_DISABLED].setState((reverseStatus == 0) ? ISS_ON : ISS_OFF);
455 }
456
457 // #9 Encoder status
458 token = std::strtok(nullptr, ":");
459
460 if (token == nullptr)
461 {
462 LOG_ERROR("Invalid encoder response.");
463 return false;
464 }
465
466 int encoderStatus = atoi(token);
467 if (encoderStatus >= 0 && encoderStatus <= 1)
468 {
469 IUResetSwitch(&EncoderSP);
470 EncoderS[encoderStatus].s = ISS_ON;
471 EncoderSP.s = IPS_OK;
472 IDSetSwitch(&EncoderSP, nullptr);
473 }
474
475 // #10 Backlash
476 token = std::strtok(nullptr, ":");
477
478 if (token == nullptr)
479 {
480 LOG_ERROR("Invalid encoder response.");
481 return false;
482 }
483
484 int backlash = atoi(token);
485 // If backlash is zero then compensation is disabled
486 if (backlash == 0 && FocusBacklashSP[INDI_ENABLED].getState() == ISS_ON)
487 {
488 LOG_WARN("Backlash value is zero, disabling backlash switch...");
489
494 }
495 else if (backlash > 0 && (FocusBacklashSP[INDI_DISABLED].getState() == ISS_ON || backlash != FocusBacklashNP[0].getValue()))
496 {
497 if (backlash != FocusBacklashNP[0].getValue())
498 {
499 FocusBacklashNP[0].setValue(backlash);
502 }
503
504 if (FocusBacklashSP[INDI_DISABLED].getState() == ISS_ON)
505 {
510 }
511 }
512
513 return true;
514}
515
516bool PegasusFocusCube::setMaxSpeed(uint16_t speed)
517{
518 int nbytes_written = 0, rc = -1;
519 char cmd[16] = {0};
520
521 snprintf(cmd, 16, "S:%d", speed);
522 cmd[strlen(cmd)] = 0xA;
523
524 LOGF_DEBUG("CMD <%s>", cmd);
525
526 tcflush(PortFD, TCIOFLUSH);
527
528 // Set Speed
529 if ((rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
530 {
531 char errstr[MAXRBUF];
532 tty_error_msg(rc, errstr, MAXRBUF);
533 LOGF_ERROR("setMaxSpeed error: %s.", errstr);
534 return false;
535 }
536
537 this->ignoreResponse();
538 return true;
539}
540
542{
543 int nbytes_written = 0, rc = -1;
544 char cmd[16] = {0};
545
546 snprintf(cmd, 16, "N:%d", enabled ? 1 : 0);
547 cmd[strlen(cmd)] = 0xA;
548
549 LOGF_DEBUG("CMD <%s>", cmd);
550
551 tcflush(PortFD, TCIOFLUSH);
552
553 // Reverse
554 if ((rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
555 {
556 char errstr[MAXRBUF];
557 tty_error_msg(rc, errstr, MAXRBUF);
558 LOGF_ERROR("Reverse error: %s.", errstr);
559 return false;
560 }
561
562 this->ignoreResponse();
563
564 return true;
565}
566
567bool PegasusFocusCube::setLedEnabled(bool enable)
568{
569 int nbytes_written = 0, rc = -1;
570 char cmd[16] = {0};
571
572 snprintf(cmd, 16, "L:%d", enable ? 2 : 1);
573 cmd[strlen(cmd)] = 0xA;
574
575 LOGF_DEBUG("CMD <%s>", cmd);
576
577 tcflush(PortFD, TCIOFLUSH);
578
579 // Led
580 if ((rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
581 {
582 char errstr[MAXRBUF];
583 tty_error_msg(rc, errstr, MAXRBUF);
584 LOGF_ERROR("Led error: %s.", errstr);
585 return false;
586 }
587
588 this->ignoreResponse();
589 return true;
590}
591
592bool PegasusFocusCube::setEncodersEnabled(bool enable)
593{
594 int nbytes_written = 0, rc = -1;
595 char cmd[16] = {0};
596
597 snprintf(cmd, 16, "E:%d", enable ? 0 : 1);
598 cmd[strlen(cmd)] = 0xA;
599
600 LOGF_DEBUG("CMD <%s>", cmd);
601
602 tcflush(PortFD, TCIOFLUSH);
603
604 // Encoders
605 if ((rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
606 {
607 char errstr[MAXRBUF];
608 tty_error_msg(rc, errstr, MAXRBUF);
609 LOGF_ERROR("Encoder error: %s.", errstr);
610 return false;
611 }
612
613 this->ignoreResponse();
614 return true;
615}
616
618{
619 int nbytes_written = 0, rc = -1;
620 char cmd[16] = {0};
621
622 snprintf(cmd, 16, "C:%d", steps);
623 cmd[strlen(cmd)] = 0xA;
624
625 LOGF_DEBUG("CMD <%s>", cmd);
626
627 tcflush(PortFD, TCIOFLUSH);
628
629 // Backlash
630 if ((rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
631 {
632 char errstr[MAXRBUF];
633 tty_error_msg(rc, errstr, MAXRBUF);
634 LOGF_ERROR("Backlash error: %s.", errstr);
635 return false;
636 }
637
638 this->ignoreResponse();
639 return true;
640}
641
643{
644 if (!enabled)
645 return SetFocuserBacklash(0);
646
647 return SetFocuserBacklash(FocusBacklashNP[0].getValue() > 0 ? FocusBacklashNP[0].getValue() : 1);
648}
649
650
652{
653 targetPosition = targetTicks;
654
655 bool rc = move(targetPosition);
656
657 if (!rc)
658 return IPS_ALERT;
659
661
662 return IPS_BUSY;
663}
664
666{
667 double newPosition = 0;
668 bool rc = false;
669
670 if (dir == FOCUS_INWARD)
671 newPosition = FocusAbsPosNP[0].getValue() - ticks;
672 else
673 newPosition = FocusAbsPosNP[0].getValue() + ticks;
674
675 rc = move(newPosition);
676
677 if (!rc)
678 return IPS_ALERT;
679
680 FocusRelPosNP[0].setValue(ticks);
682
683 return IPS_BUSY;
684}
685
687{
688 if (!isConnected())
689 {
691 return;
692 }
693
694 bool rc = updateFocusParams();
695
696 if (rc)
697 {
699 {
700 if (isMoving == false)
701 {
706 LOG_INFO("Focuser reached requested position.");
707 }
708 }
709 }
710
712}
713
715{
716 int nbytes_written;
717 char cmd[2] = { 'H', 0xA };
718
719 if (tty_write(PortFD, cmd, 2, &nbytes_written) == TTY_OK)
720 {
725 this->ignoreResponse();
726 return true;
727 }
728 else
729 return false;
730}
731
733{
735 IUSaveConfigSwitch(fp, &EncoderSP);
736 IUSaveConfigNumber(fp, &MaxSpeedNP);
737 IUSaveConfigSwitch(fp, &LEDSP);
738
739 return true;
740}
double temperature
void setPortMatchPattern(const std::string &pattern)
setPortMatchPattern Set a regex pattern used to automatically select a serial port from the discovere...
void setDefaultBaudRate(BaudRate newRate)
setDefaultBaudRate Set default baud rate. The default baud rate is 9600 unless otherwise changed by t...
bool isConnected() const
void setDefaultPollingPeriod(uint32_t msec)
setDefaultPollingPeriod Change the default polling period to call TimerHit() function in the driver.
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
void defineProperty(INumberVectorProperty *property)
uint32_t getCurrentPollingPeriod() const
getCurrentPollingPeriod Return the current polling period.
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
void addDebugControl()
Add Debug control to the driver.
INDI::PropertyNumber FocusRelPosNP
INDI::PropertySwitch FocusReverseSP
void SetCapability(uint32_t cap)
FI::SetCapability sets the focuser capabilities. All capabilities must be initialized.
INDI::PropertyNumber FocusMaxPosNP
INDI::PropertySwitch FocusBacklashSP
INDI::PropertyNumber FocusBacklashNP
INDI::PropertyNumber FocusAbsPosNP
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Processes incoming new switch states from the client for this device. Handles updates to FocuserInter...
virtual bool saveConfigItems(FILE *fp) override
virtual bool updateProperties() override
Updates the state and definition of properties based on the current connection status....
virtual bool initProperties() override
Initializes the default properties for the focuser device. Sets up standard INDI properties,...
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Processes incoming new number values from the client for this device. Handles updates to FocuserInter...
Connection::Serial * serialConnection
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
virtual bool updateProperties() override
Updates the state and definition of properties based on the current connection status....
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Processes incoming new switch states from the client for this device. Handles updates to FocuserInter...
virtual IPState MoveAbsFocuser(uint32_t targetTicks) override
MoveFocuser the focuser to an absolute position.
const char * getDefaultName() override
virtual bool SetFocuserBacklashEnabled(bool enabled) override
SetFocuserBacklashEnabled Enables or disables the focuser backlash compensation.
virtual bool saveConfigItems(FILE *fp) override
virtual bool ReverseFocuser(bool enabled) override
ReverseFocuser Reverse focuser motion direction.
virtual bool initProperties() override
Initializes the default properties for the focuser device. Sets up standard INDI properties,...
virtual IPState MoveRelFocuser(FocusDirection dir, uint32_t ticks) override
MoveFocuser the focuser to an relative position.
virtual bool AbortFocuser() override
AbortFocuser all focus motion.
virtual bool SyncFocuser(uint32_t ticks) override
SyncFocuser Set current position to ticks without moving the focuser.
virtual bool SetFocuserBacklash(int32_t steps) override
SetFocuserBacklash Set the focuser backlash compensation value.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Processes incoming new number values from the client for this device. Handles updates to FocuserInter...
virtual bool Handshake() override
Performs a device-specific handshake after a connection is established. This method should be overrid...
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
#define DMFC_TIMEOUT
Definition dmfc.cpp:33
#define TEMPERATURE_THRESHOLD
Definition dmfc.cpp:35
#define FOCUS_SETTINGS_TAB
Definition dmfc.cpp:34
ISState
Switch state.
Definition indiapi.h:148
@ ISS_OFF
Definition indiapi.h:149
@ ISS_ON
Definition indiapi.h:150
@ IP_RW
Definition indiapi.h:184
@ 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
@ ISR_1OFMANY
Definition indiapi.h:171
int tty_read_section(int fd, char *buf, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
Definition indicom.c:653
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
Definition indicom.c:418
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
Definition indicom.c:1243
Implementations for common driver routines.
@ TTY_OK
Definition indicom.h:54
void IUSaveConfigSwitch(FILE *fp, const ISwitchVectorProperty *svp)
Add a switch vector property value to the configuration file.
Definition indidevapi.c:33
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.
Definition indidevapi.c:490
void IUResetSwitch(ISwitchVectorProperty *svp)
Reset all switches in a switch vector property to OFF.
Definition indidevapi.c:366
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.
Definition indidevapi.c:509
void IUSaveText(IText *tp, const char *newtext)
Function to reliably save new text in a IText.
Definition indidevapi.c:44
void IUSaveConfigNumber(FILE *fp, const INumberVectorProperty *nvp)
Add a number vector property value to the configuration file.
Definition indidevapi.c:23
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.
Definition indidevapi.c:376
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.
Definition indidevapi.c:416
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.
Definition indidevapi.c:398
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.
Definition indidevapi.c:453
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,...)
#define MAXRBUF
Definition indidriver.c:52
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,...)
#define LOGF_INFO(fmt,...)
Definition indilogger.h:82
#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 getDeviceName
uint8_t cmd[4]
Definition pwc-ioctl.h:2
char name[MAXINDINAME]
Definition indiapi.h:321
char name[MAXINDINAME]
Definition indiapi.h:369
char name[MAXINDINAME]
Definition indiapi.h:248