Instrument Neutral Distributed Interface INDI 2.2.5
Terrans_PowerBoxGo_V2.cpp
Go to the documentation of this file.
1/*******************************************************************************
2 Copyright(c) 2015 Jasem Mutlaq. All rights reserved.
3
4 TerransPowerBoxGoV2
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
25#include "config.h"
27
28#include "indicom.h"
30
31#include <cerrno>
32#include <cstring>
33#include <memory>
34#include <termios.h>
35#include <unistd.h>
36#include <inttypes.h>
37#include <sys/ioctl.h>
38
39// We declare an auto pointer to TerransPowerBoxGoV2.
40static std::unique_ptr<TerransPowerBoxGoV2> terranspowerboxgov2(new TerransPowerBoxGoV2());
41
42#define CMD_LEN 8
43#define TIMEOUT 500
44#define TAB_INFO "Status"
45#define TAB_RENAME "Rename"
46
47double ch1_shuntv = 0;
48double ch1_current = 0;
49double ch1_bus = 0;
50double humidity = 0;
51double temperature = 0;
52double dewPoint = 0;
53double mcu_temp = 0;
54
55
57{
58 setVersion(1, 1);
59}
60
62{
64
65 setDriverInterface(AUX_INTERFACE | POWER_INTERFACE); // Add POWER_INTERFACE
66
68
69 // Populate PI::PowerChannelLabelsTP and PI::USBPortLabelsTP
70 if (PI::PowerChannelLabelsTP.size() >= 5)
71 {
77 }
78 if (PI::USBPortLabelsTP.size() >= 4)
79 {
80 PI::USBPortLabelsTP[0].setLabel("USB3.0 A");
81 PI::USBPortLabelsTP[1].setLabel("USB3.0 B");
82 PI::USBPortLabelsTP[2].setLabel("USB2.0 E");
83 PI::USBPortLabelsTP[3].setLabel("USB2.0 F");
84 }
85
86 // Removed ConfigRenameDCA to ConfigRenameUSBF as they are no longer needed
87
88 // Removed manual Power Switch declarations (DCASP, DCBSP, etc.) as they are handled by PI::PowerChannelsSP and PI::USBPortSP
89 // Removed StateSaveSP as it's not part of INDI::PowerInterface directly, but can be re-added as a custom property if needed.
90
94 // InputVotageNP, InputCurrentNP, PowerNP are now handled by PI::PowerSensorsNP
95 MCUTempNP[0].fill("MCU_Temp", "MCU Temperature (C)", "%.2f", 0, 200, 0.01, 0);
96 MCUTempNP.fill(getDeviceName(), "MCU_Temp", "MCU", MAIN_CONTROL_TAB, IP_RO, 60, IPS_IDLE);
97
98 StateSaveSP[0].fill("SAVE_STATE", "Save State", ISS_ON);
99 StateSaveSP[1].fill("DISABLE_SAVE", "Disable Save", ISS_OFF);
100 StateSaveSP.fill(getDeviceName(), "STATE_SAVE", "State Save", MAIN_CONTROL_TAB, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
101
105 serialConnection = new Connection::Serial(this);
106 serialConnection->registerHandshake([&]()
107 {
108 return Handshake();
109 });
111 registerConnection(serialConnection);
112
113 return true;
114}
115
117{
119
120 if (isConnected())
121 {
122 // PowerInterface properties
124
125 // Main Control
126 defineProperty(MCUTempNP);
127 defineProperty(StateSaveSP);
128
129 setupComplete = true;
130 }
131 else
132 {
133 // PowerInterface properties
135
136 // Main Control
137 deleteProperty(MCUTempNP);
138 deleteProperty(StateSaveSP);
139
140 setupComplete = false;
141 }
142
143 return true;
144}
145
147{
150 StateSaveSP.save(fp);
151 return true;
152}
153
154bool TerransPowerBoxGoV2::Handshake()
155{
156 char res[CMD_LEN] = {0};
157 if (isSimulation())
158 {
159 LOGF_INFO("Connected successfuly to simulated %s.", getDeviceName());
160 // For simulation, assume full capabilities
163 // 5 DC ports, 0 DEW ports, 0 Variable port, 0 Auto Dew ports, 4 USB ports
164 PI::initProperties(POWER_TAB, 5, 0, 0, 0, 4);
165 return true;
166 }
167
168 for(int HS = 0 ; HS < 3 ; HS++)
169 {
170 if (sendCommand(">VR#", res))
171 {
172 if(!strcmp(res, "*TPGNNN"))
173 {
174 if (sendCommand(">VN#", res))
175 {
176 if(!strcmp(res, "*V001"))
177 {
178 LOG_INFO("Handshake successfully!");
179 // Set capabilities based on device knowledge
182 // 5 DC ports, 0 DEW ports, 0 Variable port, 0 Auto Dew ports, 4 USB ports
183 PI::initProperties(POWER_TAB, 5, 0, 0, 0, 4);
184 return true;
185 }
186 else
187 {
188 LOG_INFO("The firmware version does not match the driver. Please use the latest firmware and driver!");
189 return false;
190 }
191 }
192 }
193 else
194 {
195 LOG_INFO("Handshake failed!");
196 LOG_INFO("Retry...");
197 }
198 }
199 }
200 LOG_INFO("Handshake failed!");
201 return false;
202}
203
204bool TerransPowerBoxGoV2::SetPowerPort(size_t port, bool enabled)
205{
206 char cmd[CMD_LEN] = {0};
207 char res[CMD_LEN] = {0};
208 // Ports are 0-indexed in INDI::PowerInterface, but device expects 1-indexed.
209 // Also, the device uses specific commands for each port (SDA, SDB, etc.)
210 // Assuming port 0 -> SDA, 1 -> SDB, 2 -> SDC, 3 -> SDD, 4 -> SDE
211 const char *portCmds[] = {">SDA", ">SDB", ">SDC", ">SDD", ">SDE"};
212 if (port < sizeof(portCmds) / sizeof(portCmds[0]))
213 {
214 snprintf(cmd, CMD_LEN, "%s%d#", portCmds[port], enabled ? 1 : 0);
215 if (sendCommand(cmd, res))
216 {
217 // Check response based on command sent
218 char expectedRes[CMD_LEN] = {0};
219 snprintf(expectedRes, CMD_LEN, "*D%c%dNNN", static_cast<int>(('A' + port)), enabled ? 1 : 0);
220 return !strcmp(res, expectedRes);
221 }
222 }
223 return false;
224}
225
226bool TerransPowerBoxGoV2::SetDewPort(size_t port, bool enabled, double dutyCycle)
227{
228 INDI_UNUSED(port);
229 INDI_UNUSED(enabled);
230 INDI_UNUSED(dutyCycle);
231 // TerransPowerBoxGoV2 does not appear to have dew heater ports based on the original code.
232 // If it did, this would be implemented here.
233 LOG_WARN("SetDewPort not implemented for TerransPowerBoxGoV2.");
234 return false;
235}
236
237bool TerransPowerBoxGoV2::SetVariablePort(size_t port, bool enabled, double voltage)
238{
239 INDI_UNUSED(port);
240 INDI_UNUSED(enabled);
241 INDI_UNUSED(voltage);
242 // TerransPowerBoxGoV2 does not appear to have variable voltage ports.
243 // If it did, this would be implemented here.
244 LOG_WARN("SetVariablePort not implemented for TerransPowerBoxGoV2.");
245 return false;
246}
247
249{
250 INDI_UNUSED(enabled);
251 // TerransPowerBoxGoV2 does not appear to have LED control.
252 // If it did, this would be implemented here.
253 LOG_WARN("SetLEDEnabled not implemented for TerransPowerBoxGoV2.");
254 return false;
255}
256
257bool TerransPowerBoxGoV2::SetAutoDewEnabled(size_t port, bool enabled)
258{
259 INDI_UNUSED(port);
260 INDI_UNUSED(enabled);
261 // TerransPowerBoxGoV2 does not appear to have auto dew control.
262 // If it did, this would be implemented here.
263 LOG_WARN("SetAutoDewEnabled not implemented for TerransPowerBoxGoV2.");
264 return false;
265}
266
268{
269 // TerransPowerBoxGoV2 does not appear to have a direct power cycle command.
270 // If it did, this would be implemented here.
271 LOG_WARN("CyclePower not implemented for TerransPowerBoxGoV2.");
272 return false;
273}
274
275bool TerransPowerBoxGoV2::SetUSBPort(size_t port, bool enabled)
276{
277 char cmd[CMD_LEN] = {0};
278 char res[CMD_LEN] = {0};
279 // Ports are 0-indexed in INDI::PowerInterface, but device expects 1-indexed.
280 // Also, the device uses specific commands for each port (SUA, SUB, SUE, SUF)
281 // Assuming port 0 -> SUA, 1 -> SUB, 2 -> SUE, 3 -> SUF
282 const char *usbCmds[] = {">SUA", ">SUB", ">SUE", ">SUF"};
283 if (port < sizeof(usbCmds) / sizeof(usbCmds[0]))
284 {
285 // The original code uses SUA1A#, SUA0A#, SUB1A#, SUB0A#, SUE1A#, SUE0A#, SUF1A#, SUF0A#
286 // This implies a fixed 'A' suffix.
287 snprintf(cmd, CMD_LEN, "%s%d%c#", usbCmds[port], enabled ? 1 : 0, 'A');
288 if (sendCommand(cmd, res))
289 {
290 // Check response based on command sent
291 char expectedRes[CMD_LEN] = {0};
292 if (port == 0 || port == 1) // USB3.0 A, B
293 snprintf(expectedRes, CMD_LEN, "*U%c%d11N", static_cast<int>('A' + port), enabled ? 1 : 0);
294 else // USB2.0 E, F
295 snprintf(expectedRes, CMD_LEN, "*U%c%d1NN", static_cast<int>('E' + (port - 2)), enabled ? 1 : 0);
296 return !strcmp(res, expectedRes);
297 }
298 }
299 return false;
300}
301
302
304{
305 LOG_INFO("GET Name");
306 return "TerransPowerBoxGoV2";
307}
308
309bool TerransPowerBoxGoV2::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
310{
311 if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
312 {
313 // Process power-related switches via PowerInterface
314 if (PI::processSwitch(dev, name, states, names, n))
315 return true;
316
317 // Handle custom switches not part of PowerInterface
318 if (StateSaveSP.isNameMatch(name))
319 {
320 StateSaveSP.update(states, names, n);
321 if (StateSaveSP[0].getState() == ISS_ON)
322 {
323 if (sendCommand(">SS1#", nullptr)) // Assuming SS1# saves state
324 {
325 StateSaveSP.setState(IPS_OK);
326 LOG_INFO("Save Switch State Enable");
327 }
328 else
329 {
330 StateSaveSP.setState(IPS_ALERT);
331 LOG_INFO("Save Switch State Set Fail");
332 }
333 }
334 else if (StateSaveSP[1].getState() == ISS_ON)
335 {
336 if (sendCommand(">SS0#", nullptr)) // Assuming SS0# disables state save
337 {
338 StateSaveSP.setState(IPS_OK);
339 LOG_INFO("Save Switch State Disable");
340 }
341 else
342 {
343 StateSaveSP.setState(IPS_ALERT);
344 LOG_INFO("Save Switch State Set Fail");
345 }
346 }
347 StateSaveSP.apply();
348 return true;
349 }
350 }
351
352 return INDI::DefaultDevice::ISNewSwitch(dev, name, states, names, n);
353}
354
355bool TerransPowerBoxGoV2::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
356{
357 // Process power-related numbers via PowerInterface
358 if (PI::processNumber(dev, name, values, names, n))
359 return true;
360
361 return INDI::DefaultDevice::ISNewNumber(dev, name, values, names, n);
362}
363
364bool TerransPowerBoxGoV2::ISNewText(const char * dev, const char * name, char * texts[], char * names[], int n)
365{
366 // Process power-related text via PowerInterface
367 if (PI::processText(dev, name, texts, names, n))
368 return true;
369
370
371 return INDI::DefaultDevice::ISNewText(dev, name, texts, names, n);
372}
373
374bool TerransPowerBoxGoV2::sendCommand(const char * cmd, char * res)
375{
376
377 int nbytes_read = 0, nbytes_written = 0, tty_rc = 0;
378 char command[CMD_LEN] = {0};
379 PortFD = serialConnection->getPortFD();
380 LOGF_DEBUG("CMD <%s>", cmd);
381
382 for (int i = 0; i < 2; i++)
383 {
384 tcflush(PortFD, TCIOFLUSH);
385 snprintf(command, CMD_LEN, "%s", cmd);
386 if ( (tty_rc = tty_write_string(PortFD, command, &nbytes_written)) != TTY_OK)
387 continue;
388
389 if (!res)
390 {
391 tcflush(PortFD, TCIOFLUSH);
392 return true;
393 }
394
395 if ( (tty_rc = tty_nread_section(PortFD, res, CMD_LEN, '#', TIMEOUT, &nbytes_read)) != TTY_OK || nbytes_read == 1)
396 continue;
397
398 tcflush(PortFD, TCIOFLUSH);
399 res[nbytes_read - 1] = '\0';
400 LOGF_DEBUG("RES <%s>", res);
401 return true;
402 }
403
404 if (tty_rc != TTY_OK)
405 {
406 char errorMessage[MAXRBUF];
407 tty_error_msg(tty_rc, errorMessage, MAXRBUF);
408 LOGF_ERROR("Serial error: %s", errorMessage);
409 }
410
411 return false;
412}
413
415{
416 if (!isConnected() || setupComplete == false)
417 {
418 SetTimer(100);
419 return;
420 }
421
422 // Update PowerInterface properties
423 char res[CMD_LEN] = {0};
424 bool powerChanged = false;
425 bool usbChanged = false;
426 bool stateSaveChanged = false;
427 bool sensorsChanged = false;
428 bool mcuTempChanged = false;
429
430 // Get Power Channel States
431 for (size_t i = 0; i < PI::PowerChannelsSP.size(); ++i)
432 {
433 const char *portCmds[] = {">GDA#", ">GDB#", ">GDC#", ">GDD#", ">GDE#"};
434 if (i < sizeof(portCmds) / sizeof(portCmds[0]))
435 {
436 if (sendCommand(portCmds[i], res))
437 {
438 // Response format: *DA1NNN (channel A, state 1), *DB0NNN (channel B, state 0), etc.
439 // res[2] is the channel letter (A, B, C, D, E)
440 // res[3] is the state ('1' for ON, '0' for OFF)
441 char expectedChannel = 'A' + i;
442 if (strlen(res) >= 4 && res[2] == expectedChannel)
443 {
444 ISState newState = (res[3] == '1') ? ISS_ON : ISS_OFF;
445 if (PI::PowerChannelsSP[i].getState() != newState)
446 {
447 PI::PowerChannelsSP[i].setState(newState);
448 powerChanged = true;
449 }
450 }
451 }
452 }
453 }
454 if (powerChanged)
455 {
457 }
458
459 // Get USB Port States
460 for (size_t i = 0; i < PI::USBPortSP.size(); ++i)
461 {
462 const char *usbCmds[] = {">GUA#", ">GUB#", ">GUE#", ">GUF#"};
463 if (i < sizeof(usbCmds) / sizeof(usbCmds[0]))
464 {
465 if (sendCommand(usbCmds[i], res))
466 {
467 // Response format: *UA000N (USB A, OFF), *UB111N (USB B, ON) for USB3.0 A/B
468 // Response format: *UE00NN (USB E, OFF), *UF11NN (USB F, ON) for USB2.0 E/F
469 // res[2] is the USB port letter (A, B, E, F)
470 // res[3] is the first state bit ('1' for ON, '0' for OFF)
471 const char *portLetters = "ABEF";
472 char expectedPort = portLetters[i];
473 if (strlen(res) >= 4 && res[2] == expectedPort)
474 {
475 ISState newState = (res[3] == '1') ? ISS_ON : ISS_OFF;
476 if (PI::USBPortSP[i].getState() != newState)
477 {
478 PI::USBPortSP[i].setState(newState);
479 usbChanged = true;
480 }
481 }
482 }
483 }
484 }
485 if (usbChanged)
486 {
488 }
489
490 // Get State Save Switch
491 if (sendCommand(">GS#", res))
492 {
493 // Response format: *SS1NNN (save enabled), *SS0NNN (save disabled)
494 if (!strcmp(res, "*SS1NNN"))
495 {
496 if (StateSaveSP[0].getState() != ISS_ON || StateSaveSP[1].getState() != ISS_OFF)
497 {
498 StateSaveSP[0].setState(ISS_ON);
499 StateSaveSP[1].setState(ISS_OFF);
500 stateSaveChanged = true;
501 }
502 }
503 else if (!strcmp(res, "*SS0NNN"))
504 {
505 if (StateSaveSP[0].getState() != ISS_OFF || StateSaveSP[1].getState() != ISS_ON)
506 {
507 StateSaveSP[0].setState(ISS_OFF);
508 StateSaveSP[1].setState(ISS_ON);
509 stateSaveChanged = true;
510 }
511 }
512 }
513 if (stateSaveChanged)
514 {
515 StateSaveSP.apply();
516 }
517
518 // Get Input Voltage, Current, Power
519 double newVoltage = PI::PowerSensorsNP[PI::SENSOR_VOLTAGE].getValue();
520 double newCurrent = PI::PowerSensorsNP[PI::SENSOR_CURRENT].getValue();
521 double newPower = PI::PowerSensorsNP[PI::SENSOR_POWER].getValue();
522
523 if (sendCommand(">GPA#", res))
524 {
525 ch1_bus = (res[6] - 0x30) + ((res[5] - 0x30) * 10) + ((res[4] - 0x30) * 100) + ((res[3] - 0x30) * 1000);
526 ch1_bus = ch1_bus * 4 / 1000;
527 newVoltage = ch1_bus;
528 }
529
530 if (sendCommand(">GPB#", res))
531 {
532 ch1_shuntv = (res[6] - 0x30) + ((res[5] - 0x30) * 10) + ((res[4] - 0x30) * 100) + ((res[3] - 0x30) * 1000);
533 ch1_current = ch1_shuntv * 10 / 1000000 / 0.002;
534 newCurrent = ch1_current;
535 newPower = ch1_current * ch1_bus; // Calculate power
536 }
537
538 if (PI::PowerSensorsNP[PI::SENSOR_VOLTAGE].getValue() != newVoltage ||
539 PI::PowerSensorsNP[PI::SENSOR_CURRENT].getValue() != newCurrent ||
540 PI::PowerSensorsNP[PI::SENSOR_POWER].getValue() != newPower)
541 {
542 PI::PowerSensorsNP[PI::SENSOR_VOLTAGE].setValue(newVoltage);
543 PI::PowerSensorsNP[PI::SENSOR_CURRENT].setValue(newCurrent);
544 PI::PowerSensorsNP[PI::SENSOR_POWER].setValue(newPower);
546 sensorsChanged = true;
547 }
548 if (sensorsChanged)
549 {
551 }
552
553 // Get MCU Temperature
554 if (sendCommand(">GC#", res))
555 {
556 double newMcuTemp = MCUTempNP[0].getValue();
557 mcu_temp = (res[6] - 0x30) + ((res[5] - 0x30) * 10) + ((res[4] - 0x30) * 100) + ((res[3] - 0x30) * 1000);
558 if (mcu_temp == 0)
559 {
560 newMcuTemp = 0;
561 }
562 else
563 {
564 if (res[2] == 'A')
565 {
566 mcu_temp = mcu_temp / 100;
567 newMcuTemp = mcu_temp;
568 }
569 else if (res[2] == 'B')
570 {
571 mcu_temp = mcu_temp / 100;
572 mcu_temp = mcu_temp * (-1);
573 newMcuTemp = mcu_temp;
574 }
575 }
576
577 if (MCUTempNP[0].getValue() != newMcuTemp)
578 {
579 MCUTempNP[0].setValue(newMcuTemp);
580 MCUTempNP.setState(IPS_OK);
581 mcuTempChanged = true;
582 }
583 }
584 if (mcuTempChanged)
585 {
586 MCUTempNP.apply();
587 }
588
589 SetTimer(100);
590}
591
592// Removed the original Get_State() function as its functionality is now integrated into TimerHit()
double mcu_temp
#define TIMEOUT
double ch1_bus
double ch1_shuntv
double humidity
double dewPoint
double temperature
#define CMD_LEN
double ch1_current
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 ...
void setDefaultBaudRate(BaudRate newRate)
setDefaultBaudRate Set default baud rate. The default baud rate is 9600 unless otherwise changed by t...
bool isConnected() const
const char * getDeviceName() const
virtual bool updateProperties()
updateProperties is called whenever there is a change in the CONNECTION status of 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 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)
virtual bool saveConfigItems(FILE *fp)
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
virtual bool initProperties()
Initialize properties initial state and value. The child class must implement this function.
bool isSimulation() const
void addAuxControls()
Add Debug, Simulation, and Configuration options to the driver.
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.
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
Process the client newSwitch command.
bool saveConfigItems(FILE *fp)
saveConfigItems Save power properties in config file
void SetCapability(uint32_t cap)
SetPowerCapability sets the Power capabilities. All capabilities must be initialized.
INDI::PropertyNumber PowerSensorsNP
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 ...
INDI::PropertyText PowerChannelLabelsTP
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::PropertySwitch PowerChannelsSP
INDI::PropertySwitch USBPortSP
INDI::PropertyText USBPortLabelsTP
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.
void setLabel(const char *label)
bool isNameMatch(const char *otherName) const
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 SetPowerPort(size_t port, bool enabled) override
SetPowerPort Set power port on/off.
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 initProperties() override
Initialize properties initial state and value. The child class must implement this function.
virtual bool CyclePower() override
CyclePower Cycle power to all ports.
virtual const char * getDefaultName() override
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual bool SetVariablePort(size_t port, bool enabled, double voltage) override
SetVariablePort Set variable voltage port.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
virtual bool SetAutoDewEnabled(size_t port, bool enabled) override
SetAutoDewEnabled Enable/disable automatic dew control.
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
virtual bool SetLEDEnabled(bool enabled) override
SetLEDEnabled Enable/disable power LEDs.
virtual bool SetUSBPort(size_t port, bool enabled) override
SetUSBPort Set USB port on/off.
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
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_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_string(int fd, const char *buf, int *nbytes_written)
Writes a null terminated string to fd.
Definition indicom.c:473
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_WARN(txt)
Definition indilogger.h:73
#define LOGF_DEBUG(fmt,...)
Definition indilogger.h:83
#define LOGF_ERROR(fmt,...)
Definition indilogger.h:80
#define LOG_INFO(txt)
Definition indilogger.h:74
Namespace to encapsulate INDI client, drivers, and mediator classes.
uint8_t cmd[4]
Definition pwc-ioctl.h:2