Instrument Neutral Distributed Interface INDI  1.9.2
pegasus_ppb.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  Copyright(c) 2019 Jasem Mutlaq. All rights reserved.
3 
4  Pegasus Pocket Power Box Driver.
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 "pegasus_ppb.h"
26 #include "indicom.h"
28 
29 #include <memory>
30 #include <regex>
31 #include <termios.h>
32 #include <cstring>
33 #include <sys/ioctl.h>
34 
35 // We declare an auto pointer to PegasusPPB.
36 static std::unique_ptr<PegasusPPB> pocket_power_box(new PegasusPPB());
37 
39 {
40  setVersion(1, 1);
41  lastSensorData.reserve(PA_N);
42 }
43 
45 {
47 
49 
50  WI::initProperties(ENVIRONMENT_TAB, ENVIRONMENT_TAB);
51 
53 
57  // Cycle all power on/off
58  IUFillSwitch(&PowerCycleAllS[POWER_CYCLE_OFF], "POWER_CYCLE_OFF", "All Off", ISS_OFF);
59  IUFillSwitch(&PowerCycleAllS[POWER_CYCLE_ON], "POWER_CYCLE_ON", "All On", ISS_OFF);
60  IUFillSwitchVector(&PowerCycleAllSP, PowerCycleAllS, 2, getDeviceName(), "POWER_CYCLE", "Cycle Power", MAIN_CONTROL_TAB,
61  IP_RW, ISR_ATMOST1, 60, IPS_IDLE);
62 
63  // DSLR on/off
64  IUFillSwitch(&DSLRPowerS[DSLR_OFF], "DSLR_OFF", "Off", ISS_OFF);
65  IUFillSwitch(&DSLRPowerS[DSLR_ON], "DSLR_ON", "On", ISS_OFF);
66  IUFillSwitchVector(&DSLRPowerSP, DSLRPowerS, 2, getDeviceName(), "DSLR_POWER", "DSLR Power", MAIN_CONTROL_TAB, IP_RW,
67  ISR_ATMOST1, 60, IPS_IDLE);
68 
69  // Reboot
70  IUFillSwitch(&RebootS[0], "REBOOT", "Reboot Device", ISS_OFF);
71  IUFillSwitchVector(&RebootSP, RebootS, 1, getDeviceName(), "REBOOT_DEVICE", "Device", MAIN_CONTROL_TAB, IP_RW, ISR_ATMOST1,
72  60, IPS_IDLE);
73 
74  // Power Sensors
75  IUFillNumber(&PowerSensorsN[SENSOR_VOLTAGE], "SENSOR_VOLTAGE", "Voltage (V)", "%4.2f", 0, 999, 100, 0);
76  IUFillNumber(&PowerSensorsN[SENSOR_CURRENT], "SENSOR_CURRENT", "Current (A)", "%4.2f", 0, 999, 100, 0);
77  IUFillNumberVector(&PowerSensorsNP, PowerSensorsN, 2, getDeviceName(), "POWER_SENSORS", "Sensors", MAIN_CONTROL_TAB, IP_RO,
78  60, IPS_IDLE);
79 
83 
84  // Power on Boot
85  IUFillSwitch(&PowerOnBootS[0], "POWER_PORT_1", "Port 1", ISS_ON);
86  IUFillSwitch(&PowerOnBootS[1], "POWER_PORT_2", "Port 2", ISS_ON);
87  IUFillSwitch(&PowerOnBootS[2], "POWER_PORT_3", "Port 3", ISS_ON);
88  IUFillSwitch(&PowerOnBootS[3], "POWER_PORT_4", "Port 4", ISS_ON);
89  IUFillSwitchVector(&PowerOnBootSP, PowerOnBootS, 4, getDeviceName(), "POWER_ON_BOOT", "Power On Boot", MAIN_CONTROL_TAB,
90  IP_RW, ISR_NOFMANY, 60, IPS_IDLE);
91 
95 
96  // Automatic Dew
97  IUFillSwitch(&AutoDewS[INDI_ENABLED], "INDI_ENABLED", "Enabled", ISS_OFF);
98  IUFillSwitch(&AutoDewS[INDI_DISABLED], "INDI_DISABLED", "Disabled", ISS_ON);
99  IUFillSwitchVector(&AutoDewSP, AutoDewS, 2, getDeviceName(), "AUTO_DEW", "Auto Dew", DEW_TAB, IP_RW, ISR_1OFMANY, 60,
100  IPS_IDLE);
101 
102  // Dew PWM
103  IUFillNumber(&DewPWMN[DEW_PWM_A], "DEW_A", "Dew A (%)", "%.2f", 0, 100, 10, 0);
104  IUFillNumber(&DewPWMN[DEW_PWM_B], "DEW_B", "Dew B (%)", "%.2f", 0, 100, 10, 0);
105  IUFillNumberVector(&DewPWMNP, DewPWMN, 2, getDeviceName(), "DEW_PWM", "Dew PWM", DEW_TAB, IP_RW, 60, IPS_IDLE);
106 
110  addParameter("WEATHER_TEMPERATURE", "Temperature (C)", -15, 35, 15);
111  addParameter("WEATHER_HUMIDITY", "Humidity %", 0, 100, 15);
112  addParameter("WEATHER_DEWPOINT", "Dew Point (C)", 0, 100, 15);
113  setCriticalParameter("WEATHER_TEMPERATURE");
114 
118  serialConnection = new Connection::Serial(this);
119  serialConnection->registerHandshake([&]()
120  {
121  return Handshake();
122  });
123  registerConnection(serialConnection);
124 
125  return true;
126 }
127 
129 {
131 
132  if (isConnected())
133  {
134  // Main Control
135  defineProperty(&PowerCycleAllSP);
136  defineProperty(&DSLRPowerSP);
137  defineProperty(&PowerSensorsNP);
138  defineProperty(&PowerOnBootSP);
139  defineProperty(&RebootSP);
140 
141  // Dew
142  defineProperty(&AutoDewSP);
143  defineProperty(&DewPWMNP);
144 
146 
147  setupComplete = true;
148  }
149  else
150  {
151  // Main Control
152  deleteProperty(PowerCycleAllSP.name);
153  deleteProperty(DSLRPowerSP.name);
154  deleteProperty(PowerSensorsNP.name);
155  deleteProperty(PowerOnBootSP.name);
156  deleteProperty(RebootSP.name);
157 
158  // Dew
159  deleteProperty(AutoDewSP.name);
160  deleteProperty(DewPWMNP.name);
161 
163 
164  setupComplete = false;
165  }
166 
167  return true;
168 }
169 
171 {
172  return "Pegasus PPB";
173 }
174 
175 bool PegasusPPB::Handshake()
176 {
177  int tty_rc = 0, nbytes_written = 0, nbytes_read = 0;
178  char command[PEGASUS_LEN] = {0}, response[PEGASUS_LEN] = {0};
179 
180  PortFD = serialConnection->getPortFD();
181 
182  LOG_DEBUG("CMD <P#>");
183 
184  tcflush(PortFD, TCIOFLUSH);
185  strncpy(command, "P#\n", PEGASUS_LEN);
186  if ( (tty_rc = tty_write_string(PortFD, command, &nbytes_written)) != TTY_OK)
187  {
188  char errorMessage[MAXRBUF];
189  tty_error_msg(tty_rc, errorMessage, MAXRBUF);
190  LOGF_ERROR("Serial write error: %s", errorMessage);
191  return false;
192  }
193 
194  // Try first with stopChar as the stop character
195  if ( (tty_rc = tty_nread_section(PortFD, response, PEGASUS_LEN, stopChar, 1, &nbytes_read)) != TTY_OK)
196  {
197  // Try 0xA as the stop character
198  if (tty_rc == TTY_OVERFLOW || tty_rc == TTY_TIME_OUT)
199  {
200  tcflush(PortFD, TCIOFLUSH);
201  tty_write_string(PortFD, command, &nbytes_written);
202  stopChar = 0xA;
203  tty_rc = tty_nread_section(PortFD, response, PEGASUS_LEN, stopChar, 1, &nbytes_read);
204  }
205 
206  if (tty_rc != TTY_OK)
207  {
208  char errorMessage[MAXRBUF];
209  tty_error_msg(tty_rc, errorMessage, MAXRBUF);
210  LOGF_ERROR("Serial read error: %s", errorMessage);
211  return false;
212  }
213  }
214 
215  tcflush(PortFD, TCIOFLUSH);
216  response[nbytes_read - 1] = '\0';
217  LOGF_DEBUG("RES <%s>", response);
218 
219  setupComplete = false;
220 
221  return !strcmp(response, "PPB_OK");
222 }
223 
224 bool PegasusPPB::ISNewSwitch(const char * dev, const char * name, ISState * states, char * names[], int n)
225 {
226  if (dev && !strcmp(dev, getDeviceName()))
227  {
228  // Cycle all power on or off
229  if (!strcmp(name, PowerCycleAllSP.name))
230  {
231  IUUpdateSwitch(&PowerCycleAllSP, states, names, n);
232 
233  PowerCycleAllSP.s = IPS_ALERT;
234  char cmd[PEGASUS_LEN] = {0}, res[PEGASUS_LEN] = {0};
235  snprintf(cmd, PEGASUS_LEN, "P1:%d", IUFindOnSwitchIndex(&PowerCycleAllSP));
236  if (sendCommand(cmd, res))
237  {
238  PowerCycleAllSP.s = !strcmp(cmd, res) ? IPS_OK : IPS_ALERT;
239  }
240 
241  IUResetSwitch(&PowerCycleAllSP);
242  IDSetSwitch(&PowerCycleAllSP, nullptr);
243  return true;
244  }
245 
246  // DSLR
247  if (!strcmp(name, DSLRPowerSP.name))
248  {
249  IUUpdateSwitch(&DSLRPowerSP, states, names, n);
250 
251  DSLRPowerSP.s = IPS_ALERT;
252  char cmd[PEGASUS_LEN] = {0}, res[PEGASUS_LEN] = {0};
253  snprintf(cmd, PEGASUS_LEN, "P2:%d", IUFindOnSwitchIndex(&DSLRPowerSP));
254  if (sendCommand(cmd, res))
255  {
256  DSLRPowerSP.s = !strcmp(cmd, res) ? IPS_OK : IPS_ALERT;
257  }
258 
259  IUResetSwitch(&DSLRPowerSP);
260  IDSetSwitch(&DSLRPowerSP, nullptr);
261  return true;
262  }
263 
264  // Reboot
265  if (!strcmp(name, RebootSP.name))
266  {
267  RebootSP.s = reboot() ? IPS_OK : IPS_ALERT;
268  IDSetSwitch(&RebootSP, nullptr);
269  LOG_INFO("Rebooting device...");
270  return true;
271  }
272 
273  // Power on boot
274  if (!strcmp(name, PowerOnBootSP.name))
275  {
276  IUUpdateSwitch(&PowerOnBootSP, states, names, n);
277  PowerOnBootSP.s = setPowerOnBoot() ? IPS_OK : IPS_ALERT;
278  IDSetSwitch(&PowerOnBootSP, nullptr);
279  saveConfig(true, PowerOnBootSP.name);
280  return true;
281  }
282 
283  // Auto Dew
284  if (!strcmp(name, AutoDewSP.name))
285  {
286  int prevIndex = IUFindOnSwitchIndex(&AutoDewSP);
287  IUUpdateSwitch(&AutoDewSP, states, names, n);
288  if (setAutoDewEnabled(AutoDewS[INDI_ENABLED].s == ISS_ON))
289  {
290  AutoDewSP.s = IPS_OK;
291  }
292  else
293  {
294  IUResetSwitch(&AutoDewSP);
295  AutoDewS[prevIndex].s = ISS_ON;
296  AutoDewSP.s = IPS_ALERT;
297  }
298 
299  IDSetSwitch(&AutoDewSP, nullptr);
300  return true;
301  }
302  }
303 
304  return DefaultDevice::ISNewSwitch(dev, name, states, names, n);
305 }
306 
307 bool PegasusPPB::ISNewNumber(const char * dev, const char * name, double values[], char * names[], int n)
308 {
309  if (dev && !strcmp(dev, getDeviceName()))
310  {
311  // Dew PWM
312  if (!strcmp(name, DewPWMNP.name))
313  {
314  bool rc1 = false, rc2 = false;
315  for (int i = 0; i < n; i++)
316  {
317  if (!strcmp(names[i], DewPWMN[DEW_PWM_A].name))
318  rc1 = setDewPWM(3, static_cast<uint8_t>(values[i] / 100.0 * 255.0));
319  else if (!strcmp(names[i], DewPWMN[DEW_PWM_B].name))
320  rc2 = setDewPWM(4, static_cast<uint8_t>(values[i] / 100.0 * 255.0));
321  }
322 
323  DewPWMNP.s = (rc1 && rc2) ? IPS_OK : IPS_ALERT;
324  if (DewPWMNP.s == IPS_OK)
325  IUUpdateNumber(&DewPWMNP, values, names, n);
326  IDSetNumber(&DewPWMNP, nullptr);
327  return true;
328  }
329 
330  if (strstr(name, "WEATHER_"))
331  return WI::processNumber(dev, name, values, names, n);
332  }
333  return INDI::DefaultDevice::ISNewNumber(dev, name, values, names, n);
334 }
335 
336 bool PegasusPPB::sendCommand(const char * cmd, char * res)
337 {
338  int nbytes_read = 0, nbytes_written = 0, tty_rc = 0;
339  char command[PEGASUS_LEN] = {0};
340  LOGF_DEBUG("CMD <%s>", cmd);
341 
342  for (int i = 0; i < 2; i++)
343  {
344  tcflush(PortFD, TCIOFLUSH);
345  snprintf(command, PEGASUS_LEN, "%s\n", cmd);
346  if ( (tty_rc = tty_write_string(PortFD, command, &nbytes_written)) != TTY_OK)
347  continue;
348 
349  if (!res)
350  {
351  tcflush(PortFD, TCIOFLUSH);
352  return true;
353  }
354 
355  if ( (tty_rc = tty_nread_section(PortFD, res, PEGASUS_LEN, stopChar, PEGASUS_TIMEOUT, &nbytes_read)) != TTY_OK
356  || nbytes_read == 1)
357  continue;
358 
359  tcflush(PortFD, TCIOFLUSH);
360  res[nbytes_read - 1] = '\0';
361  LOGF_DEBUG("RES <%s>", res);
362  return true;
363  }
364 
365  if (tty_rc != TTY_OK)
366  {
367  char errorMessage[MAXRBUF];
368  tty_error_msg(tty_rc, errorMessage, MAXRBUF);
369  LOGF_ERROR("Serial error: %s", errorMessage);
370  }
371 
372  return false;
373 }
374 
375 bool PegasusPPB::setAutoDewEnabled(bool enabled)
376 {
377  char cmd[PEGASUS_LEN] = {0}, res[PEGASUS_LEN] = {0};
378  snprintf(cmd, PEGASUS_LEN, "PD:%d", enabled ? 1 : 0);
379  if (sendCommand(cmd, res))
380  {
381  return (!strcmp(res, cmd));
382  }
383 
384  return false;
385 }
386 
387 bool PegasusPPB::setPowerOnBoot()
388 {
389  char cmd[PEGASUS_LEN] = {0}, res[PEGASUS_LEN] = {0};
390  snprintf(cmd, PEGASUS_LEN, "PE:%d%d%d%d", PowerOnBootS[0].s == ISS_ON ? 1 : 0,
391  PowerOnBootS[1].s == ISS_ON ? 1 : 0,
392  PowerOnBootS[2].s == ISS_ON ? 1 : 0,
393  PowerOnBootS[3].s == ISS_ON ? 1 : 0);
394  if (sendCommand(cmd, res))
395  {
396  return (!strcmp(res, "PE:1"));
397  }
398 
399  return false;
400 }
401 
402 bool PegasusPPB::setDewPWM(uint8_t id, uint8_t value)
403 {
404  char cmd[PEGASUS_LEN] = {0}, res[PEGASUS_LEN] = {0}, expected[PEGASUS_LEN] = {0};
405  snprintf(cmd, PEGASUS_LEN, "P%d:%03d", id, value);
406  snprintf(expected, PEGASUS_LEN, "P%d:%d", id, value);
407  if (sendCommand(cmd, res))
408  {
409  return (!strcmp(res, expected));
410  }
411 
412  return false;
413 }
414 
416 {
419  IUSaveConfigSwitch(fp, &AutoDewSP);
420 
421  return true;
422 }
423 
425 {
426  if (!isConnected() || setupComplete == false)
427  {
429  return;
430  }
431 
432  getSensorData();
434 }
435 
436 bool PegasusPPB::sendFirmware()
437 {
438  char res[PEGASUS_LEN] = {0};
439  if (sendCommand("PV", res))
440  {
441  LOGF_INFO("Detected firmware %s", res);
442  return true;
443  }
444 
445  return false;
446 }
447 
448 bool PegasusPPB::getSensorData()
449 {
450  char res[PEGASUS_LEN] = {0};
451  if (sendCommand("PA", res))
452  {
453  std::vector<std::string> result = split(res, ":");
454  if (result.size() < PA_N)
455  {
456  LOG_WARN("Received wrong number of detailed sensor data. Retrying...");
457  return false;
458  }
459 
460  if (result == lastSensorData)
461  return true;
462 
463  // Power Sensors
464  PowerSensorsN[SENSOR_VOLTAGE].value = std::stod(result[PA_VOLTAGE]);
465  PowerSensorsN[SENSOR_CURRENT].value = std::stod(result[PA_CURRENT]) / 65.0;
466  PowerSensorsNP.s = IPS_OK;
467  if (lastSensorData[PA_VOLTAGE] != result[PA_VOLTAGE] || lastSensorData[PA_CURRENT] != result[PA_CURRENT])
468  IDSetNumber(&PowerSensorsNP, nullptr);
469 
470  // Environment Sensors
471  setParameterValue("WEATHER_TEMPERATURE", std::stod(result[PA_TEMPERATURE]));
472  setParameterValue("WEATHER_HUMIDITY", std::stod(result[PA_HUMIDITY]));
473  setParameterValue("WEATHER_DEWPOINT", std::stod(result[PA_DEW_POINT]));
474  if (lastSensorData[PA_TEMPERATURE] != result[PA_TEMPERATURE] ||
475  lastSensorData[PA_HUMIDITY] != result[PA_HUMIDITY] ||
476  lastSensorData[PA_DEW_POINT] != result[PA_DEW_POINT])
477  {
479  IDSetLight(&critialParametersLP, nullptr);
481  IDSetNumber(&ParametersNP, nullptr);
482  }
483 
484  // Power Status
485  PowerCycleAllS[POWER_CYCLE_ON].s = (std::stoi(result[PA_PORT_STATUS]) == 1) ? ISS_ON : ISS_OFF;
486  PowerCycleAllS[POWER_CYCLE_ON].s = (std::stoi(result[PA_PORT_STATUS]) == 0) ? ISS_ON : ISS_OFF;
487  PowerCycleAllSP.s = (std::stoi(result[6]) == 1) ? IPS_OK : IPS_IDLE;
488  if (lastSensorData[PA_PORT_STATUS] != result[PA_PORT_STATUS])
489  IDSetSwitch(&PowerCycleAllSP, nullptr);
490 
491  // DSLR Power Status
492  DSLRPowerS[POWER_CYCLE_ON].s = (std::stoi(result[PA_DSLR_STATUS]) == 1) ? ISS_ON : ISS_OFF;
493  DSLRPowerS[POWER_CYCLE_ON].s = (std::stoi(result[PA_DSLR_STATUS]) == 0) ? ISS_ON : ISS_OFF;
494  DSLRPowerSP.s = (std::stoi(result[PA_DSLR_STATUS]) == 1) ? IPS_OK : IPS_IDLE;
495  if (lastSensorData[PA_DSLR_STATUS] != result[PA_DSLR_STATUS])
496  IDSetSwitch(&DSLRPowerSP, nullptr);
497 
498  // Dew PWM
499  DewPWMN[0].value = std::stod(result[PA_DEW_1]) / 255.0 * 100.0;
500  DewPWMN[1].value = std::stod(result[PA_DEW_2]) / 255.0 * 100.0;
501  if (lastSensorData[PA_DEW_1] != result[PA_DEW_1] || lastSensorData[PA_DEW_2] != result[PA_DEW_2])
502  IDSetNumber(&DewPWMNP, nullptr);
503 
504  // Auto Dew
505  AutoDewS[INDI_ENABLED].s = (std::stoi(result[PA_AUTO_DEW]) == 1) ? ISS_ON : ISS_OFF;
506  AutoDewS[INDI_DISABLED].s = (std::stoi(result[PA_AUTO_DEW]) == 1) ? ISS_OFF : ISS_ON;
507  if (lastSensorData[PA_AUTO_DEW] != result[PA_AUTO_DEW])
508  IDSetSwitch(&AutoDewSP, nullptr);
509 
510  lastSensorData = result;
511 
512  return true;
513  }
514 
515  return false;
516 }
517 
518 // Device Control
519 bool PegasusPPB::reboot()
520 {
521  return sendCommand("PF", nullptr);
522 }
523 
524 std::vector<std::string> PegasusPPB::split(const std::string &input, const std::string &regex)
525 {
526  // passing -1 as the submatch index parameter performs splitting
527  std::regex re(regex);
528  std::sregex_token_iterator
529  first{input.begin(), input.end(), re, -1},
530  last;
531  return {first, last};
532 }
533 
IP_RO
@ IP_RO
Definition: indiapi.h:183
INDI::WeatherInterface::initProperties
void initProperties(const char *statusGroup, const char *paramsGroup)
Initilize focuser properties. It is recommended to call this function within initProperties() of your...
Definition: indiweatherinterface.cpp:48
TTY_TIME_OUT
@ TTY_TIME_OUT
Definition: indicom.h:98
cmd
__u8 cmd[4]
Definition: pwc-ioctl.h:4
INDI::WeatherInterface::setCriticalParameter
bool setCriticalParameter(std::string param)
setCriticalParameter Set parameter that is considered critical to the operation of the observatory....
Definition: indiweatherinterface.cpp:167
INDI::DefaultDevice::addAuxControls
void addAuxControls()
Add Debug, Simulation, and Configuration options to the driver.
Definition: defaultdevice.cpp:665
tty_nread_section
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:636
LOGF_ERROR
#define LOGF_ERROR(fmt,...)
Definition: indilogger.h:80
IPS_OK
@ IPS_OK
Definition: indiapi.h:161
_INumberVectorProperty::s
IPState s
Definition: indiapi.h:332
ISS_OFF
@ ISS_OFF
Definition: indiapi.h:150
indicom.h
Implementations for common driver routines.
IPS_ALERT
@ IPS_ALERT
Definition: indiapi.h:163
Connection::Serial
The Serial class manages connection with serial devices including Bluetooth. Serial communication is ...
Definition: connectionserial.h:56
IUFillNumber
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: indidriver.c:348
ISR_NOFMANY
@ ISR_NOFMANY
Definition: indiapi.h:174
INDI::DefaultDevice::defineProperty
void defineProperty(INumberVectorProperty *property)
Definition: defaultdevice.cpp:997
MAIN_CONTROL_TAB
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
Definition: defaultdevice.cpp:34
INDI::WeatherInterface::syncCriticalParameters
bool syncCriticalParameters()
updateWeatherState Send update weather state to client
Definition: indiweatherinterface.cpp:230
INDI::DefaultDevice::setVersion
void setVersion(uint16_t vMajor, uint16_t vMinor)
Set driver version information to be defined in DRIVER_INFO property as vMajor.vMinor.
Definition: defaultdevice.cpp:1219
INDI::BaseDevice::getDeviceName
const char * getDeviceName() const
Definition: basedevice.cpp:799
TTY_OVERFLOW
@ TTY_OVERFLOW
Definition: indicom.h:102
PegasusPPB::ISNewSwitch
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
Definition: pegasus_ppb.cpp:224
LOG_INFO
#define LOG_INFO(txt)
Definition: indilogger.h:74
MAXRBUF
#define MAXRBUF
Definition: indidriver.c:52
INDI::WeatherInterface::ParametersNP
INumberVectorProperty ParametersNP
Definition: indiweatherinterface.h:150
INDI::DefaultDevice::initProperties
virtual bool initProperties()
Initilize properties initial state and value. The child class must implement this function.
Definition: defaultdevice.cpp:917
IUResetSwitch
void IUResetSwitch(ISwitchVectorProperty *svp)
Reset all switches in a switch vector property to OFF.
Definition: indicom.c:1421
tty_error_msg
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
Definition: indicom.c:1135
INDI::DefaultDevice::getCurrentPollingPeriod
uint32_t getCurrentPollingPeriod() const
getCurrentPollingPeriod Return the current polling period.
Definition: defaultdevice.cpp:1139
LOGF_DEBUG
#define LOGF_DEBUG(fmt,...)
Definition: indilogger.h:83
INDI::DefaultDevice::SetTimer
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
Definition: defaultdevice.cpp:865
IDSetLight
void void void void void void void IDSetLight(const ILightVectorProperty *l, const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(2
Tell client to update an existing light vector property.
PegasusPPB
Definition: pegasus_ppb.h:38
INDI::DefaultDevice::ISNewNumber
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process the client newNumber command.
Definition: defaultdevice.cpp:593
IUFillSwitchVector
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: indidriver.c:412
PegasusPPB::PegasusPPB
PegasusPPB()
Definition: pegasus_ppb.cpp:38
IUFillNumberVector
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: indidriver.c:455
ISR_1OFMANY
@ ISR_1OFMANY
Definition: indiapi.h:172
INDI::WeatherInterface::critialParametersLP
ILightVectorProperty critialParametersLP
Definition: indiweatherinterface.h:158
connectionserial.h
IPS_IDLE
@ IPS_IDLE
Definition: indiapi.h:160
INDI::DefaultDevice::registerConnection
void registerConnection(Connection::Interface *newConnection)
registerConnection Add new connection plugin to the existing connection pool. The connection type sha...
Definition: defaultdevice.cpp:1107
ISR_ATMOST1
@ ISR_ATMOST1
Definition: indiapi.h:173
_INumberVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:322
PegasusPPB::initProperties
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
Definition: pegasus_ppb.cpp:44
IUUpdateSwitch
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector property.
Definition: indidriver.c:171
INDI::BaseDevice::isConnected
bool isConnected() const
Definition: basedevice.cpp:518
ISNewSwitch
void ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Update the value of an existing switch vector property.
Definition: defaultdevice.cpp:60
PegasusPPB::saveConfigItems
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
Definition: pegasus_ppb.cpp:415
PegasusPPB::ISNewNumber
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
Definition: pegasus_ppb.cpp:307
LOG_DEBUG
#define LOG_DEBUG(txt)
Definition: indilogger.h:75
LOGF_INFO
#define LOGF_INFO(fmt,...)
Definition: indilogger.h:82
INDI::WeatherInterface::saveConfigItems
virtual bool saveConfigItems(FILE *fp)
saveConfigItems Save parameters ranges in the config file.
Definition: indiweatherinterface.cpp:312
INDI::WeatherInterface::processNumber
bool processNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process focus number properties.
Definition: indiweatherinterface.cpp:96
INDI::BaseDevice::INDI_ENABLED
@ INDI_ENABLED
Definition: basedevice.h:64
PegasusPPB::updateProperties
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
Definition: pegasus_ppb.cpp:128
INDI::WeatherInterface::addParameter
void addParameter(std::string name, std::string label, double numMinOk, double numMaxOk, double percWarning)
addParameter Add a physical weather measurable parameter to the weather driver. The weather value has...
Definition: indiweatherinterface.cpp:131
PegasusPPB::getDefaultName
const char * getDefaultName() override
Definition: pegasus_ppb.cpp:170
_ISwitchVectorProperty::s
IPState s
Definition: indiapi.h:382
INDI::DefaultDevice::saveConfig
virtual bool saveConfig(bool silent=false, const char *property=nullptr)
Save the current properties in a configuration file.
Definition: defaultdevice.cpp:221
Connection::Interface::registerHandshake
void registerHandshake(std::function< bool()> callback)
registerHandshake Register a handshake function to be called once the intial connection to the device...
Definition: connectioninterface.cpp:108
IUUpdateNumber
int IUUpdateNumber(INumberVectorProperty *nvp, double values[], char *names[], int n)
Update all numbers in a number vector property.
Definition: indidriver.c:225
INDI::DefaultDevice::saveConfigItems
virtual bool saveConfigItems(FILE *fp)
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
Definition: defaultdevice.cpp:175
IP_RW
@ IP_RW
Definition: indiapi.h:185
LOG_WARN
#define LOG_WARN(txt)
Definition: indilogger.h:73
INDI::BaseDevice::INDI_DISABLED
@ INDI_DISABLED
Definition: basedevice.h:65
ISState
ISState
Switch state.
Definition: indiapi.h:148
Connection::Serial::getPortFD
int getPortFD() const
Definition: connectionserial.h:136
INDI::WeatherInterface
Provides interface to implement weather reporting functionality.
Definition: indiweatherinterface.h:55
IUFindOnSwitchIndex
int IUFindOnSwitchIndex(const ISwitchVectorProperty *sp)
Returns the index of first ON switch it finds in the vector switch property.
Definition: indicom.c:1403
INDI::BaseDevice::AUX_INTERFACE
@ AUX_INTERFACE
Definition: basedevice.h:87
IUSaveConfigSwitch
void IUSaveConfigSwitch(FILE *fp, const ISwitchVectorProperty *svp)
Add a switch vector property value to the configuration file.
Definition: indicom.c:1444
tty_write_string
int tty_write_string(int fd, const char *buf, int *nbytes_written)
Writes a null terminated string to fd.
Definition: indicom.c:454
TTY_OK
@ TTY_OK
Definition: indicom.h:94
INDI::DefaultDevice::deleteProperty
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
Definition: defaultdevice.cpp:965
IDSetNumber
void void void IDSetNumber(const INumberVectorProperty *n, const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(2
Tell client to update an existing number vector property.
IDSetSwitch
void void void void void IDSetSwitch(const ISwitchVectorProperty *s, const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(2
Tell client to update an existing switch vector property.
pegasus_ppb.h
INDI::DefaultDevice::setDriverInterface
void setDriverInterface(uint16_t value)
setInterface Set driver interface. By default the driver interface is set to GENERAL_DEVICE....
Definition: defaultdevice.cpp:902
INDI::WeatherInterface::updateProperties
bool updateProperties()
updateProperties Define or Delete Rotator properties based on the connection status of the base devic...
Definition: indiweatherinterface.cpp:61
IUFillSwitch
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: indidriver.c:320
INDI::BaseDevice::WEATHER_INTERFACE
@ WEATHER_INTERFACE
Definition: basedevice.h:79
INDI::DefaultDevice::updateProperties
virtual bool updateProperties()
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
Definition: defaultdevice.cpp:890
_ISwitchVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:370
INDI::WeatherInterface::setParameterValue
void setParameterValue(std::string name, double value)
setParameterValue Update weather parameter value
Definition: indiweatherinterface.cpp:155
ISS_ON
@ ISS_ON
Definition: indiapi.h:151
PegasusPPB::TimerHit
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
Definition: pegasus_ppb.cpp:424