Instrument Neutral Distributed Interface INDI 2.2.5
usb_dewpoint.cpp
Go to the documentation of this file.
1/*
2 USB_Dewpoint
3 Copyright (C) 2017-2023 Jarno Paananen
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
18 USA
19
20*/
21
22#include "usb_dewpoint.h"
24#include "indicom.h"
25
26#include <cstring>
27#include <memory>
28
29#include <termios.h>
30#include <unistd.h>
31
32#define USBDEWPOINT_TIMEOUT 3
33
34std::unique_ptr<USBDewpoint> usbDewpoint(new USBDewpoint());
35
36USBDewpoint::USBDewpoint() : INDI::PowerInterface(this)
37{
38 setVersion(1, 2);
39}
40
42{
43 DefaultDevice::initProperties();
44
47 // Auto Dew is overall operation
48 AutoDewSP[0].fill("DEW_CHANNEL_1", "(Overall Operation)", ISS_OFF);
49
50 /* Channel duty cycles */
51 // OutputsNP[0].fill("CHANNEL1", "Channel 1", "%3.0f", 0., 100., 10., 0.);
52 // OutputsNP[1].fill("CHANNEL2", "Channel 2", "%3.0f", 0., 100., 10., 0.);
53 // OutputsNP[2].fill("CHANNEL3", "Channel 3", "%3.0f", 0., 100., 10., 0.);
54 // OutputsNP.fill(getDeviceName(), "OUTPUT", "Outputs", MAIN_CONTROL_TAB, IP_RW, 0, IPS_IDLE);
55
56 /* Temperatures */
57 TemperaturesNP[0].fill("CHANNEL1", "Channel 1", "%3.2f", -50., 70., 0., 0.);
58 TemperaturesNP[1].fill("CHANNEL2", "Channel 2", "%3.2f", -50., 70., 0., 0.);
59 TemperaturesNP[2].fill("AMBIENT", "Ambient", "%3.2f", -50., 70., 0., 0.);
60 TemperaturesNP.fill(getDeviceName(), "TEMPERATURES", "Temperatures", MAIN_CONTROL_TAB, IP_RO, 0, IPS_IDLE);
61
62 /* Humidity */
63 HumidityNP[0].fill("HUMIDITY", "Humidity", "%3.2f", 0., 100., 0., 0.);
64 HumidityNP.fill(getDeviceName(), "HUMIDITY", "Humidity", MAIN_CONTROL_TAB, IP_RO, 0, IPS_IDLE);
65
66 /* Dew point */
67 DewpointNP[0].fill("DEWPOINT", "Dew point", "%3.2f", -50., 70., 0., 0.);
68 DewpointNP.fill(getDeviceName(), "DEWPOINT", "Dew point", MAIN_CONTROL_TAB, IP_RO, 0, IPS_IDLE);
69
70 /* Temperature calibration values */
71 CalibrationsNP[0].fill("CHANNEL1", "Channel 1", "%1.0f", 0., 9., 1., 0.);
72 CalibrationsNP[1].fill("CHANNEL2", "Channel 2", "%1.0f", 0., 9., 1., 0.);
73 CalibrationsNP[2].fill("AMBIENT", "Ambient", "%1.0f", 0., 9., 1., 0.);
74 CalibrationsNP.fill(getDeviceName(), "CALIBRATIONS", "Calibrations", OPTIONS_TAB, IP_RW, 0, IPS_IDLE);
75
76 /* Temperature threshold values */
77 ThresholdsNP[0].fill("CHANNEL1", "Channel 1", "%1.0f", 0., 9., 1., 0.);
78 ThresholdsNP[1].fill("CHANNEL2", "Channel 2", "%1.0f", 0., 9., 1., 0.);
79 ThresholdsNP.fill(getDeviceName(), "THRESHOLDS", "Thresholds", OPTIONS_TAB, IP_RW, 0, IPS_IDLE);
80
81 /* Heating aggressivity */
82 AggressivityNP[0].fill("AGGRESSIVITY", "Aggressivity", "%1.0f", 1., 4., 1., 1.);
83 AggressivityNP.fill(getDeviceName(), "AGGRESSIVITY", "Aggressivity", OPTIONS_TAB, IP_RW, 0, IPS_IDLE);
84
85 /* Automatic mode enable */
86 // AutoModeSP[0].fill("MANUAL", "Manual", ISS_OFF);
87 // AutoModeSP[1].fill("AUTO", "Automatic", ISS_ON);
88 // AutoModeSP.fill(getDeviceName(), "MODE", "Operating mode", MAIN_CONTROL_TAB, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
89
90 /* Link channel 2 & 3 */
91 LinkOut23SP[0].fill("INDEPENDENT", "Independent", ISS_ON);
92 LinkOut23SP[1].fill("LINK", "Link", ISS_OFF);
93 LinkOut23SP.fill(getDeviceName(), "LINK23", "Link ch 2&3", OPTIONS_TAB, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
94
95 /* Reset settings */
96 ResetSP[0].fill("Reset", "", ISS_OFF);
97 ResetSP.fill(getDeviceName(), "Reset", "", OPTIONS_TAB, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
98
99 /* Firmware version */
100 FWversionNP[0].fill("FIRMWARE", "Firmware Version", "%4.0f", 0., 65535., 1., 0.);
101 FWversionNP.fill(getDeviceName(), "FW_VERSION", "Firmware", OPTIONS_TAB, IP_RO, 0, IPS_IDLE);
102
104
109
110 // No simulation control for now
111
112 serialConnection = new Connection::Serial(this);
113 serialConnection->registerHandshake([&]()
114 {
115 return Handshake();
116 });
117 registerConnection(serialConnection);
118
119 return true;
120}
121
123{
124 DefaultDevice::updateProperties();
126
127 if (isConnected())
128 {
129 // defineProperty(OutputsNP); // Handled by PowerInterface
130 defineProperty(TemperaturesNP);
131 defineProperty(HumidityNP);
132 defineProperty(DewpointNP);
133 defineProperty(CalibrationsNP);
134 defineProperty(ThresholdsNP);
135 defineProperty(AggressivityNP);
136 // defineProperty(AutoModeSP); // Handled by PowerInterface
137 defineProperty(LinkOut23SP);
138 defineProperty(ResetSP);
139 defineProperty(FWversionNP);
140
141 loadConfig(true);
142 readSettings();
143 LOG_INFO("USB_Dewpoint parameters updated, device ready for use.");
145 }
146 else
147 {
148 // deleteProperty(OutputsNP); // Handled by PowerInterface
149 deleteProperty(TemperaturesNP);
150 deleteProperty(HumidityNP);
151 deleteProperty(DewpointNP);
152 deleteProperty(CalibrationsNP);
153 deleteProperty(ThresholdsNP);
154 deleteProperty(AggressivityNP);
155 // deleteProperty(AutoModeSP); // Handled by PowerInterface
156 deleteProperty(LinkOut23SP);
157 deleteProperty(ResetSP);
158 deleteProperty(FWversionNP);
159 }
160
161 return true;
162}
163
165{
166 return "USB_Dewpoint";
167}
168
169bool USBDewpoint::sendCommand(const char *cmd, char *resp)
170{
171 int nbytes_written = 0, nbytes_read = 0, rc = -1;
172 char errstr[MAXRBUF];
173 LOGF_DEBUG("CMD: %s.", cmd);
174
175 tcflush(PortFD, TCIOFLUSH);
176 if ((rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
177 {
178 tty_error_msg(rc, errstr, MAXRBUF);
179 LOGF_ERROR("Error writing command %s: %s.", cmd, errstr);
180 return false;
181 }
182
183 if (resp)
184 {
185 if ((rc = tty_nread_section(PortFD, resp, UDP_RES_LEN, '\r', USBDEWPOINT_TIMEOUT, &nbytes_read)) != TTY_OK)
186 {
187 tty_error_msg(rc, errstr, MAXRBUF);
188 LOGF_ERROR("Error reading response for command %s: %s.", cmd, errstr);
189 return false;
190 }
191
192 if (nbytes_read < 2)
193 {
194 LOGF_ERROR("Invalid response for command %s: %s.", cmd, resp);
195 return false;
196 }
197 resp[nbytes_read - 2] = '\0'; // Strip \n\r
198 LOGF_DEBUG("RES: %s.", resp);
199 }
200 return true;
201}
202
203bool USBDewpoint::Resync()
204{
205 char cmd[] = " "; // Illegal command to trigger error response
206 int nbytes_written = 0, nbytes_read = 0, rc = -1;
207 char errstr[MAXRBUF];
208 char resp[UDP_RES_LEN] = {};
209
210 // Send up to 5 space characters and wait for error
211 // response ("ER=1") after which the communication
212 // is back in sync
213 tcflush(PortFD, TCIOFLUSH);
214
215 for (int resync = 0; resync < UDP_CMD_LEN; resync++)
216 {
217 LOGF_INFO("Retry %d...", resync + 1);
218
219 if ((rc = tty_write(PortFD, cmd, 1, &nbytes_written)) != TTY_OK)
220 {
221 tty_error_msg(rc, errstr, MAXRBUF);
222 LOGF_ERROR("Error writing resync: %s.", errstr);
223 return false;
224 }
225
226 rc = tty_nread_section(PortFD, resp, UDP_RES_LEN, '\r', 3, &nbytes_read);
227 if (rc == TTY_OK && nbytes_read > 0)
228 {
229 // We got a response
230 return true;
231 }
232 // We didn't get response yet, retry
233 }
234 LOG_ERROR("No valid resync response.");
235 return false;
236}
237
238bool USBDewpoint::Handshake()
239{
240 PortFD = serialConnection->getPortFD();
241
242 int tries = 2;
243 do
244 {
245 if (Ack())
246 {
247 LOG_INFO("USB_Dewpoint is online. Getting device parameters...");
248 return true;
249 }
250 LOG_INFO("Error retrieving data from USB_Dewpoint, trying resync...");
251 }
252 while (--tries > 0 && Resync());
253
254 LOG_INFO("Error retrieving data from USB_Dewpoint, please ensure controller "
255 "is powered and the port is correct.");
256 return false;
257}
258
259bool USBDewpoint::Ack()
260{
261 char resp[UDP_RES_LEN] = {};
262 tcflush(PortFD, TCIOFLUSH);
263
264 if (!sendCommand(UDP_IDENTIFY_CMD, resp))
265 return false;
266
267 int firmware = -1;
268
269 int ok = sscanf(resp, UDP_IDENTIFY_RESPONSE, &firmware);
270
271 if (ok != 1)
272 {
273 LOGF_ERROR("USB_Dewpoint not properly identified! Answer was: %s.", resp);
274 return false;
275 }
276
277 FWversionNP[0].setValue(firmware);
278 FWversionNP.setState(IPS_OK);
279 FWversionNP.apply();
280 return true;
281}
282
283bool USBDewpoint::setOutput(unsigned int channel, unsigned int value)
284{
285 char cmd[UDP_CMD_LEN + 1];
286 char resp[UDP_RES_LEN];
287
288 snprintf(cmd, UDP_CMD_LEN + 1, UDP_OUTPUT_CMD, channel, value);
289 return sendCommand(cmd, resp);
290}
291
292bool USBDewpoint::setCalibrations(unsigned int ch1, unsigned int ch2, unsigned int ambient)
293{
294 char cmd[UDP_CMD_LEN + 1];
295 char resp[UDP_RES_LEN];
296
297 snprintf(cmd, UDP_CMD_LEN + 1, UDP_CALIBRATION_CMD, ch1, ch2, ambient);
298 return sendCommand(cmd, resp);
299}
300
301bool USBDewpoint::setThresholds(unsigned int ch1, unsigned int ch2)
302{
303 char cmd[UDP_CMD_LEN + 1];
304 char resp[UDP_RES_LEN];
305
306 snprintf(cmd, UDP_CMD_LEN + 1, UDP_THRESHOLD_CMD, ch1, ch2);
307 return sendCommand(cmd, resp);
308}
309
310bool USBDewpoint::setAggressivity(unsigned int aggressivity)
311{
312 char cmd[UDP_CMD_LEN + 1];
313 char resp[UDP_RES_LEN];
314
315 snprintf(cmd, UDP_CMD_LEN + 1, UDP_AGGRESSIVITY_CMD, aggressivity);
316 return sendCommand(cmd, resp);
317}
318
319bool USBDewpoint::reset()
320{
321 char resp[UDP_RES_LEN];
322 return sendCommand(UDP_RESET_CMD, resp);
323}
324
325bool USBDewpoint::setAutoMode(bool enable)
326{
327 char cmd[UDP_CMD_LEN + 1];
328 char resp[UDP_RES_LEN];
329
330 snprintf(cmd, UDP_CMD_LEN + 1, UDP_AUTO_CMD, enable ? 1 : 0);
331 return sendCommand(cmd, resp);
332}
333
334bool USBDewpoint::SetAutoDewEnabled(size_t port, bool enabled)
335{
336 INDI_UNUSED(port);
337 return setAutoMode(enabled);
338}
339
340bool USBDewpoint::SetDewPort(size_t port, bool enabled, double dutyCycle)
341{
342 INDI_UNUSED(enabled);
343 return setOutput(port + 1, static_cast<unsigned int>(dutyCycle));
344}
345
346bool USBDewpoint::setLinkMode(bool enable)
347{
348 char cmd[UDP_CMD_LEN + 1];
349 char resp[UDP_RES_LEN];
350
351 snprintf(cmd, UDP_CMD_LEN + 1, UDP_LINK_CMD, enable ? 1 : 0);
352 return sendCommand(cmd, resp);
353}
354
355bool USBDewpoint::SetPowerPort(size_t port, bool enabled)
356{
357 INDI_UNUSED(port);
358 INDI_UNUSED(enabled);
359 LOG_DEBUG("SetPowerPort not supported by USB_Dewpoint.");
360 return false;
361}
362
363bool USBDewpoint::SetVariablePort(size_t port, bool enabled, double voltage)
364{
365 INDI_UNUSED(port);
366 INDI_UNUSED(enabled);
367 INDI_UNUSED(voltage);
368 LOG_DEBUG("SetVariablePort not supported by USB_Dewpoint.");
369 return false;
370}
371
373{
374 INDI_UNUSED(enabled);
375 LOG_DEBUG("SetLEDEnabled not supported by USB_Dewpoint.");
376 return false;
377}
378
380{
381 LOG_DEBUG("CyclePower not supported by USB_Dewpoint.");
382 return false;
383}
384
385bool USBDewpoint::SetUSBPort(size_t port, bool enabled)
386{
387 INDI_UNUSED(port);
388 INDI_UNUSED(enabled);
389 LOG_DEBUG("SetUSBPort not supported by USB_Dewpoint.");
390 return false;
391}
392
393bool USBDewpoint::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
394{
395 if (!dev || strcmp(dev, getDeviceName()))
396 return false;
397
398 if (INDI::PowerInterface::processSwitch(dev, name, states, names, n))
399 return true;
400
401 // AutoModeSP is now handled by PowerInterface
402 // if (AutoModeSP.isNameMatch(name))
403 // {
404 // AutoModeSP.update(states, names, n);
405 // int target_mode = AutoModeSP.findOnSwitchIndex();
406 // AutoModeSP.setState(IPS_BUSY);
407 // AutoModeSP.apply();
408 // setAutoMode(target_mode == 1);
409 // readSettings();
410 // return true;
411 // }
412 if (LinkOut23SP.isNameMatch(name))
413 {
414 LinkOut23SP.update(states, names, n);
415 int target_mode = LinkOut23SP.findOnSwitchIndex();
416 LinkOut23SP.setState(IPS_BUSY);
417 LinkOut23SP.apply();
418 setLinkMode(target_mode == 1);
419 readSettings();
420 return true;
421 }
422 if (ResetSP.isNameMatch(name))
423 {
424 ResetSP.reset();
425
426 if (reset())
427 {
428 ResetSP.setState(IPS_OK);
429 readSettings();
430 }
431 else
432 {
433 ResetSP.setState(IPS_ALERT);
434 }
435
436 ResetSP.apply();
437 return true;
438 }
439
440 return INDI::DefaultDevice::ISNewSwitch(dev, name, states, names, n);
441}
442
443bool USBDewpoint::ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
444{
445 if (!dev || strcmp(dev, getDeviceName()))
446 return false;
447
448 if (INDI::PowerInterface::processText(dev, name, texts, names, n))
449 return true;
450
451 return INDI::DefaultDevice::ISNewText(dev, name, texts, names, n);
452}
453
454bool USBDewpoint::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
455{
456 if (!dev || strcmp(dev, getDeviceName()))
457 return false;
458
459 if (INDI::PowerInterface::processNumber(dev, name, values, names, n))
460 return true;
461
462 // OutputsNP is now handled by PowerInterface
463 // if (OutputsNP.isNameMatch(name))
464 // {
465 // // Warn if we are in auto mode
466 // if (AutoModeSP.findOnSwitchIndex() == 1)
467 // {
468 // LOG_WARN("Setting output power is ignored in auto mode!");
469 // return true;
470 // }
471 // OutputsNP.update(values, names, n);
472 // OutputsNP.setState(IPS_BUSY);
473 // OutputsNP.apply();
474 // setOutput(1, OutputsNP[0].getValue());
475 // setOutput(2, OutputsNP[1].getValue());
476 // setOutput(3, OutputsNP[2].getValue());
477 // readSettings();
478 // return true;
479 // }
480 if (CalibrationsNP.isNameMatch(name))
481 {
482 CalibrationsNP.update(values, names, n);
483 CalibrationsNP.setState(IPS_BUSY);
484 CalibrationsNP.apply();
485 setCalibrations(CalibrationsNP[0].getValue(), CalibrationsNP[1].getValue(), CalibrationsNP[2].getValue());
486 readSettings();
487 return true;
488 }
489 if (ThresholdsNP.isNameMatch(name))
490 {
491 ThresholdsNP.update(values, names, n);
492 ThresholdsNP.setState(IPS_BUSY);
493 ThresholdsNP.apply();
494 setThresholds(ThresholdsNP[0].getValue(), ThresholdsNP[1].getValue());
495 readSettings();
496 return true;
497 }
498 if (AggressivityNP.isNameMatch(name))
499 {
500 AggressivityNP.update(values, names, n);
501 AggressivityNP.setState(IPS_BUSY);
502 AggressivityNP.apply();
503 setAggressivity(AggressivityNP[0].getValue());
504 readSettings();
505 return true;
506 }
507 if (FWversionNP.isNameMatch(name))
508 {
509 FWversionNP.update(values, names, n);
510 FWversionNP.setState(IPS_OK);
511 FWversionNP.apply();
512 return true;
513 }
514
515 return INDI::DefaultDevice::ISNewNumber(dev, name, values, names, n);
516}
517
518bool USBDewpoint::readSettings()
519{
520 char resp[UDP_RES_LEN];
521
522 if (!sendCommand(UDP_STATUS_CMD, resp))
523 return false;
524
525 // Status response is like:
526 // ##22.37/22.62/23.35/50.77/12.55/0/0/0/0/0/0/2/2/0/0/4**
527
528 float temp1, temp2, temp_ambient, humidity, dewpoint;
529 unsigned int output1, output2, output3;
530 unsigned int calibration1, calibration2, calibration_ambient;
531 unsigned int threshold1, threshold2;
532 unsigned int automode, linkout23, aggressivity;
533
534 int ok = sscanf(resp, UDP_STATUS_RESPONSE, &temp1, &temp2, &temp_ambient, &humidity, &dewpoint, &output1,
535 &output2,&output3, &calibration1, &calibration2, &calibration_ambient, &threshold1, &threshold2,
536 &automode, &linkout23, &aggressivity);
537
538 if (ok == 16)
539 {
540 TemperaturesNP[0].setValue(temp1);
541 TemperaturesNP[1].setValue(temp2);
542 TemperaturesNP[2].setValue(temp_ambient);
543 TemperaturesNP.setState(IPS_OK);
544 TemperaturesNP.apply();
545
546 HumidityNP[0].setValue(humidity);
547 HumidityNP.setState(IPS_OK);
548 HumidityNP.apply();
549
550 DewpointNP[0].setValue(dewpoint);
551 DewpointNP.setState(IPS_OK);
552 DewpointNP.apply();
553
554 /* handled by PowerInterface
555 DewChannelsSP[0].setState(output1 > 0 ? ISS_ON : ISS_OFF);
556 DewChannelsSP[1].setState(output2 > 0 ? ISS_ON : ISS_OFF);
557 DewChannelsSP[2].setState(output3 > 0 ? ISS_ON : ISS_OFF);
558 DewChannelsSP.setState(IPS_OK);
559 DewChannelsSP.apply();
560 */
561
562 if (automode)
563 {
564 if (DewChannelsSP[0].getState())
565 {
566 SetDewPort(0, true, output1);
567 DewChannelDutyCycleNP[0].setValue(output1);
568 }
569 if (DewChannelsSP[1].getState())
570 {
571 SetDewPort(1, true, output2);
572 DewChannelDutyCycleNP[1].setValue(output2);
573 }
574 if (DewChannelsSP[2].getState() && LinkOut23SP[1].getState())
575 {
576 SetDewPort(2, true, output3);
577 DewChannelDutyCycleNP[2].setValue(output3);
578 }
580 }
581
582 CalibrationsNP[0].setValue(calibration1);
583 CalibrationsNP[1].setValue(calibration2);
584 CalibrationsNP[2].setValue(calibration_ambient);
585 CalibrationsNP.setState(IPS_OK);
586 CalibrationsNP.apply();
587
588 ThresholdsNP[0].setValue(threshold1);
589 ThresholdsNP[1].setValue(threshold2);
590 ThresholdsNP.setState(IPS_OK);
591 ThresholdsNP.apply();
592
593 /* handled by PowerInterface
594 AutoDewSP.reset();
595 AutoDewSP[automode].setState(ISS_ON);
596 AutoDewSP.setState(IPS_OK);
597 AutoDewSP.apply();
598 */
599
600 LinkOut23SP.reset();
601 LinkOut23SP[linkout23].setState(ISS_ON);
602 LinkOut23SP.setState(IPS_OK);
603 LinkOut23SP.apply();
604
605 AggressivityNP[0].setValue(aggressivity);
606 AggressivityNP.setState(IPS_OK);
607 AggressivityNP.apply();
608 }
609 return true;
610}
611
613{
614 if (!isConnected())
615 {
616 return;
617 }
618
619 // Get temperatures etc.
620 readSettings();
622}
623
625{
628 LinkOut23SP.save(fp);
629 AggressivityNP.save(fp);
630 CalibrationsNP.save(fp);
631 ThresholdsNP.save(fp);
632 return true;
633}
double humidity
void registerHandshake(std::function< bool()> callback)
registerHandshake Register a handshake function to be called once the initial connection to the devic...
The Serial class manages connection with serial devices including Bluetooth. Serial communication is ...
bool isConnected() const
const char * getDeviceName() const
void addPollPeriodControl()
Add Polling period control to the driver.
void addConfigurationControl()
Add Configuration control to the driver.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process the client newSwitch command.
void registerConnection(Connection::Interface *newConnection)
registerConnection Add new connection plugin to the existing connection pool. The connection type sha...
void setDefaultPollingPeriod(uint32_t msec)
setDefaultPollingPeriod Change the default polling period to call TimerHit() function in the driver.
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 loadConfig(bool silent=false, const char *property=nullptr)
Load the last saved configuration file.
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
void defineProperty(INumberVectorProperty *property)
virtual bool saveConfigItems(FILE *fp)
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
uint32_t getCurrentPollingPeriod() const
getCurrentPollingPeriod Return the current polling period.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process the client newNumber command.
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
void addDebugControl()
Add Debug control to the driver.
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
Process the client newSwitch command.
INDI::PropertySwitch DewChannelsSP
bool saveConfigItems(FILE *fp)
saveConfigItems Save power properties in config file
INDI::PropertySwitch AutoDewSP
void SetCapability(uint32_t cap)
SetPowerCapability sets the Power capabilities. All capabilities must be initialized.
bool processNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process Power number properties.
void initProperties(const char *groupName, size_t nPowerPorts=0, size_t nDewPorts=0, size_t nVariablePorts=0, size_t nAutoDewPorts=0, size_t nUSBPorts=0)
Initialize Power properties. It is recommended to call this function within initProperties() of your ...
bool processText(const char *dev, const char *name, char *texts[], char *names[], int n)
Process Power text properties.
bool processSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process Power switch properties.
INDI::PropertyNumber DewChannelDutyCycleNP
bool updateProperties()
updateProperties Define or Delete Power properties based on the connection status of the base device
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
void save(FILE *f) const
save Save property to configuration file.
bool isNameMatch(const char *otherName) const
bool update(const double values[], const char *const names[], int n)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
bool update(const ISState states[], const char *const names[], int n)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, ISRule rule, double timeout, IPState state)
virtual bool SetUSBPort(size_t port, bool enabled) override
SetUSBPort Set USB port on/off.
virtual bool SetVariablePort(size_t port, bool enabled, double voltage) override
SetVariablePort Set variable voltage port.
virtual bool SetAutoDewEnabled(size_t port, bool enabled) override
SetAutoDewEnabled Enable/disable automatic dew control.
virtual bool SetPowerPort(size_t port, bool enabled) override
SetPowerPort Set power port on/off.
virtual bool initProperties() override
Initialize properties initial state and value. The child class must implement this function.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual bool CyclePower() override
CyclePower Cycle power to all ports.
virtual bool SetLEDEnabled(bool enabled) override
SetLEDEnabled Enable/disable power LEDs.
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
virtual const char * getDefaultName() override
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
virtual bool SetDewPort(size_t port, bool enabled, double dutyCycle) override
SetDewPort Set DEW/Dew port duty cycle.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
const char * OPTIONS_TAB
OPTIONS_TAB Where all the driver's options are located. Those may include auxiliary controls,...
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
@ 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_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
int tty_nread_section(int fd, char *buf, int nsize, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
Definition indicom.c:759
Implementations for common driver routines.
@ TTY_OK
Definition indicom.h:54
#define INDI_UNUSED(x)
Definition indidevapi.h:132
#define MAXRBUF
Definition indidriver.c:52
#define LOGF_INFO(fmt,...)
Definition indilogger.h:82
#define LOG_DEBUG(txt)
Definition indilogger.h:75
#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 USBDEWPOINT_TIMEOUT
Namespace to encapsulate INDI client, drivers, and mediator classes.
uint8_t cmd[4]
Definition pwc-ioctl.h:2
std::unique_ptr< USBDewpoint > usbDewpoint(new USBDewpoint())
#define UDP_CALIBRATION_CMD
#define UDP_IDENTIFY_RESPONSE
#define UDP_RES_LEN
#define UDP_AUTO_CMD
#define UDP_RESET_CMD
#define UDP_IDENTIFY_CMD
#define UDP_AGGRESSIVITY_CMD
#define UDP_STATUS_CMD
#define UDP_STATUS_RESPONSE
#define UDP_CMD_LEN
#define UDP_OUTPUT_CMD
#define UDP_LINK_CMD
#define UDP_THRESHOLD_CMD