Instrument Neutral Distributed Interface INDI  2.0.2
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 
34 std::unique_ptr<USBDewpoint> usbDewpoint(new USBDewpoint());
35 
37 {
38  setVersion(1, 2);
39 }
40 
42 {
43  DefaultDevice::initProperties();
44 
45  /* Channel duty cycles */
46  OutputsNP[0].fill("CHANNEL1", "Channel 1", "%3.0f", 0., 100., 10., 0.);
47  OutputsNP[1].fill("CHANNEL2", "Channel 2", "%3.0f", 0., 100., 10., 0.);
48  OutputsNP[2].fill("CHANNEL3", "Channel 3", "%3.0f", 0., 100., 10., 0.);
49  OutputsNP.fill(getDeviceName(), "OUTPUT", "Outputs", MAIN_CONTROL_TAB, IP_RW, 0, IPS_IDLE);
50 
51  /* Temperatures */
52  TemperaturesNP[0].fill("CHANNEL1", "Channel 1", "%3.2f", -50., 70., 0., 0.);
53  TemperaturesNP[1].fill("CHANNEL2", "Channel 2", "%3.2f", -50., 70., 0., 0.);
54  TemperaturesNP[2].fill("AMBIENT", "Ambient", "%3.2f", -50., 70., 0., 0.);
55  TemperaturesNP.fill(getDeviceName(), "TEMPERATURES", "Temperatures", MAIN_CONTROL_TAB, IP_RO, 0, IPS_IDLE);
56 
57  /* Humidity */
58  HumidityNP[0].fill("HUMIDITY", "Humidity", "%3.2f", 0., 100., 0., 0.);
59  HumidityNP.fill(getDeviceName(), "HUMIDITY", "Humidity", MAIN_CONTROL_TAB, IP_RO, 0, IPS_IDLE);
60 
61  /* Dew point */
62  DewpointNP[0].fill("DEWPOINT", "Dew point", "%3.2f", -50., 70., 0., 0.);
63  DewpointNP.fill(getDeviceName(), "DEWPOINT", "Dew point", MAIN_CONTROL_TAB, IP_RO, 0, IPS_IDLE);
64 
65  /* Temperature calibration values */
66  CalibrationsNP[0].fill("CHANNEL1", "Channel 1", "%1.0f", 0., 9., 1., 0.);
67  CalibrationsNP[1].fill("CHANNEL2", "Channel 2", "%1.0f", 0., 9., 1., 0.);
68  CalibrationsNP[2].fill("AMBIENT", "Ambient", "%1.0f", 0., 9., 1., 0.);
69  CalibrationsNP.fill(getDeviceName(), "CALIBRATIONS", "Calibrations", OPTIONS_TAB, IP_RW, 0, IPS_IDLE);
70 
71  /* Temperature threshold values */
72  ThresholdsNP[0].fill("CHANNEL1", "Channel 1", "%1.0f", 0., 9., 1., 0.);
73  ThresholdsNP[1].fill("CHANNEL2", "Channel 2", "%1.0f", 0., 9., 1., 0.);
74  ThresholdsNP.fill(getDeviceName(), "THRESHOLDS", "Thresholds", OPTIONS_TAB, IP_RW, 0, IPS_IDLE);
75 
76  /* Heating aggressivity */
77  AggressivityNP[0].fill("AGGRESSIVITY", "Aggressivity", "%1.0f", 1., 4., 1., 1.);
78  AggressivityNP.fill(getDeviceName(), "AGGRESSIVITY", "Aggressivity", OPTIONS_TAB, IP_RW, 0, IPS_IDLE);
79 
80  /* Automatic mode enable */
81  AutoModeSP[0].fill("MANUAL", "Manual", ISS_OFF);
82  AutoModeSP[1].fill("AUTO", "Automatic", ISS_ON);
83  AutoModeSP.fill(getDeviceName(), "MODE", "Operating mode", MAIN_CONTROL_TAB, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
84 
85  /* Link channel 2 & 3 */
86  LinkOut23SP[0].fill("INDEPENDENT", "Independent", ISS_ON);
87  LinkOut23SP[1].fill("LINK", "Link", ISS_OFF);
88  LinkOut23SP.fill(getDeviceName(), "LINK23", "Link ch 2&3", OPTIONS_TAB, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
89 
90  /* Reset settings */
91  ResetSP[0].fill("Reset", "", ISS_OFF);
92  ResetSP.fill(getDeviceName(), "Reset", "", OPTIONS_TAB, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
93 
94  /* Firmware version */
95  FWversionNP[0].fill("FIRMWARE", "Firmware Version", "%4.0f", 0., 65535., 1., 0.);
96  FWversionNP.fill(getDeviceName(), "FW_VERSION", "Firmware", OPTIONS_TAB, IP_RO, 0, IPS_IDLE);
97 
99 
100  addDebugControl();
104 
105  // No simulation control for now
106 
107  serialConnection = new Connection::Serial(this);
108  serialConnection->registerHandshake([&]()
109  {
110  return Handshake();
111  });
112  registerConnection(serialConnection);
113 
114  return true;
115 }
116 
118 {
119  DefaultDevice::updateProperties();
120 
121  if (isConnected())
122  {
123  defineProperty(OutputsNP);
124  defineProperty(TemperaturesNP);
125  defineProperty(HumidityNP);
126  defineProperty(DewpointNP);
127  defineProperty(CalibrationsNP);
128  defineProperty(ThresholdsNP);
129  defineProperty(AggressivityNP);
130  defineProperty(AutoModeSP);
131  defineProperty(LinkOut23SP);
132  defineProperty(ResetSP);
133  defineProperty(FWversionNP);
134 
135  loadConfig(true);
136  readSettings();
137  LOG_INFO("USB_Dewpoint parameters updated, device ready for use.");
139  }
140  else
141  {
142  deleteProperty(OutputsNP);
143  deleteProperty(TemperaturesNP);
144  deleteProperty(HumidityNP);
145  deleteProperty(DewpointNP);
146  deleteProperty(CalibrationsNP);
147  deleteProperty(ThresholdsNP);
148  deleteProperty(AggressivityNP);
149  deleteProperty(AutoModeSP);
150  deleteProperty(LinkOut23SP);
151  deleteProperty(ResetSP);
152  deleteProperty(FWversionNP);
153  }
154 
155  return true;
156 }
157 
159 {
160  return "USB_Dewpoint";
161 }
162 
163 bool USBDewpoint::sendCommand(const char *cmd, char *resp)
164 {
165  int nbytes_written = 0, nbytes_read = 0, rc = -1;
166  char errstr[MAXRBUF];
167  LOGF_DEBUG("CMD: %s.", cmd);
168 
169  tcflush(PortFD, TCIOFLUSH);
170  if ((rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
171  {
172  tty_error_msg(rc, errstr, MAXRBUF);
173  LOGF_ERROR("Error writing command %s: %s.", cmd, errstr);
174  return false;
175  }
176 
177  if (resp)
178  {
179  if ((rc = tty_nread_section(PortFD, resp, UDP_RES_LEN, '\r', USBDEWPOINT_TIMEOUT, &nbytes_read)) != TTY_OK)
180  {
181  tty_error_msg(rc, errstr, MAXRBUF);
182  LOGF_ERROR("Error reading response for command %s: %s.", cmd, errstr);
183  return false;
184  }
185 
186  if (nbytes_read < 2)
187  {
188  LOGF_ERROR("Invalid response for command %s: %s.", cmd, resp);
189  return false;
190  }
191  resp[nbytes_read - 2] = '\0'; // Strip \n\r
192  LOGF_DEBUG("RES: %s.", resp);
193  }
194  return true;
195 }
196 
197 bool USBDewpoint::Resync()
198 {
199  char cmd[] = " "; // Illegal command to trigger error response
200  int nbytes_written = 0, nbytes_read = 0, rc = -1;
201  char errstr[MAXRBUF];
202  char resp[UDP_RES_LEN] = {};
203 
204  // Send up to 5 space characters and wait for error
205  // response ("ER=1") after which the communication
206  // is back in sync
207  tcflush(PortFD, TCIOFLUSH);
208 
209  for (int resync = 0; resync < UDP_CMD_LEN; resync++)
210  {
211  LOGF_INFO("Retry %d...", resync + 1);
212 
213  if ((rc = tty_write(PortFD, cmd, 1, &nbytes_written)) != TTY_OK)
214  {
215  tty_error_msg(rc, errstr, MAXRBUF);
216  LOGF_ERROR("Error writing resync: %s.", errstr);
217  return false;
218  }
219 
220  rc = tty_nread_section(PortFD, resp, UDP_RES_LEN, '\r', 3, &nbytes_read);
221  if (rc == TTY_OK && nbytes_read > 0)
222  {
223  // We got a response
224  return true;
225  }
226  // We didn't get response yet, retry
227  }
228  LOG_ERROR("No valid resync response.");
229  return false;
230 }
231 
232 bool USBDewpoint::Handshake()
233 {
234  PortFD = serialConnection->getPortFD();
235 
236  int tries = 2;
237  do
238  {
239  if (Ack())
240  {
241  LOG_INFO("USB_Dewpoint is online. Getting device parameters...");
242  return true;
243  }
244  LOG_INFO("Error retrieving data from USB_Dewpoint, trying resync...");
245  }
246  while (--tries > 0 && Resync());
247 
248  LOG_INFO("Error retrieving data from USB_Dewpoint, please ensure controller "
249  "is powered and the port is correct.");
250  return false;
251 }
252 
253 bool USBDewpoint::Ack()
254 {
255  char resp[UDP_RES_LEN] = {};
256  tcflush(PortFD, TCIOFLUSH);
257 
258  if (!sendCommand(UDP_IDENTIFY_CMD, resp))
259  return false;
260 
261  int firmware = -1;
262 
263  int ok = sscanf(resp, UDP_IDENTIFY_RESPONSE, &firmware);
264 
265  if (ok != 1)
266  {
267  LOGF_ERROR("USB_Dewpoint not properly identified! Answer was: %s.", resp);
268  return false;
269  }
270 
271  FWversionNP[0].setValue(firmware);
272  FWversionNP.setState(IPS_OK);
273  FWversionNP.apply();
274  return true;
275 }
276 
277 bool USBDewpoint::setOutput(unsigned int channel, unsigned int value)
278 {
279  char cmd[UDP_CMD_LEN + 1];
280  char resp[UDP_RES_LEN];
281 
282  snprintf(cmd, UDP_CMD_LEN + 1, UDP_OUTPUT_CMD, channel, value);
283  return sendCommand(cmd, resp);
284 }
285 
286 bool USBDewpoint::setCalibrations(unsigned int ch1, unsigned int ch2, unsigned int ambient)
287 {
288  char cmd[UDP_CMD_LEN + 1];
289  char resp[UDP_RES_LEN];
290 
291  snprintf(cmd, UDP_CMD_LEN + 1, UDP_CALIBRATION_CMD, ch1, ch2, ambient);
292  return sendCommand(cmd, resp);
293 }
294 
295 bool USBDewpoint::setThresholds(unsigned int ch1, unsigned int ch2)
296 {
297  char cmd[UDP_CMD_LEN + 1];
298  char resp[UDP_RES_LEN];
299 
300  snprintf(cmd, UDP_CMD_LEN + 1, UDP_THRESHOLD_CMD, ch1, ch2);
301  return sendCommand(cmd, resp);
302 }
303 
304 bool USBDewpoint::setAggressivity(unsigned int aggressivity)
305 {
306  char cmd[UDP_CMD_LEN + 1];
307  char resp[UDP_RES_LEN];
308 
309  snprintf(cmd, UDP_CMD_LEN + 1, UDP_AGGRESSIVITY_CMD, aggressivity);
310  return sendCommand(cmd, resp);
311 }
312 
313 bool USBDewpoint::reset()
314 {
315  char resp[UDP_RES_LEN];
316  return sendCommand(UDP_RESET_CMD, resp);
317 }
318 
319 bool USBDewpoint::setAutoMode(bool enable)
320 {
321  char cmd[UDP_CMD_LEN + 1];
322  char resp[UDP_RES_LEN];
323 
324  snprintf(cmd, UDP_CMD_LEN + 1, UDP_AUTO_CMD, enable ? 1 : 0);
325  return sendCommand(cmd, resp);
326 }
327 
328 bool USBDewpoint::setLinkMode(bool enable)
329 {
330  char cmd[UDP_CMD_LEN + 1];
331  char resp[UDP_RES_LEN];
332 
333  snprintf(cmd, UDP_CMD_LEN + 1, UDP_LINK_CMD, enable ? 1 : 0);
334  return sendCommand(cmd, resp);
335 }
336 
337 bool USBDewpoint::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
338 {
339  if (!dev || strcmp(dev, getDeviceName()))
340  return false;
341 
342  if (AutoModeSP.isNameMatch(name))
343  {
344  AutoModeSP.update(states, names, n);
345  int target_mode = AutoModeSP.findOnSwitchIndex();
346  AutoModeSP.setState(IPS_BUSY);
347  AutoModeSP.apply();
348  setAutoMode(target_mode == 1);
349  readSettings();
350  return true;
351  }
352  if (LinkOut23SP.isNameMatch(name))
353  {
354  LinkOut23SP.update(states, names, n);
355  int target_mode = LinkOut23SP.findOnSwitchIndex();
356  LinkOut23SP.setState(IPS_BUSY);
357  LinkOut23SP.apply();
358  setLinkMode(target_mode == 1);
359  readSettings();
360  return true;
361  }
362  if (ResetSP.isNameMatch(name))
363  {
364  ResetSP.reset();
365 
366  if (reset())
367  {
368  ResetSP.setState(IPS_OK);
369  readSettings();
370  }
371  else
372  {
373  ResetSP.setState(IPS_ALERT);
374  }
375 
376  ResetSP.apply();
377  return true;
378  }
379 
380  return INDI::DefaultDevice::ISNewSwitch(dev, name, states, names, n);
381 }
382 
383 bool USBDewpoint::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
384 {
385  if (!dev || strcmp(dev, getDeviceName()))
386  return false;
387 
388  if (OutputsNP.isNameMatch(name))
389  {
390  // Warn if we are in auto mode
391  if (AutoModeSP.findOnSwitchIndex() == 1)
392  {
393  LOG_WARN("Setting output power is ignored in auto mode!");
394  return true;
395  }
396  OutputsNP.update(values, names, n);
397  OutputsNP.setState(IPS_BUSY);
398  OutputsNP.apply();
399  setOutput(1, OutputsNP[0].getValue());
400  setOutput(2, OutputsNP[1].getValue());
401  setOutput(3, OutputsNP[2].getValue());
402  readSettings();
403  return true;
404  }
405  if (CalibrationsNP.isNameMatch(name))
406  {
407  CalibrationsNP.update(values, names, n);
408  CalibrationsNP.setState(IPS_BUSY);
409  CalibrationsNP.apply();
410  setCalibrations(CalibrationsNP[0].getValue(), CalibrationsNP[1].getValue(), CalibrationsNP[2].getValue());
411  readSettings();
412  return true;
413  }
414  if (ThresholdsNP.isNameMatch(name))
415  {
416  ThresholdsNP.update(values, names, n);
417  ThresholdsNP.setState(IPS_BUSY);
418  ThresholdsNP.apply();
419  setThresholds(ThresholdsNP[0].getValue(), ThresholdsNP[1].getValue());
420  readSettings();
421  return true;
422  }
423  if (AggressivityNP.isNameMatch(name))
424  {
425  AggressivityNP.update(values, names, n);
426  AggressivityNP.setState(IPS_BUSY);
427  AggressivityNP.apply();
428  setAggressivity(AggressivityNP[0].getValue());
429  readSettings();
430  return true;
431  }
432  if (FWversionNP.isNameMatch(name))
433  {
434  FWversionNP.update(values, names, n);
435  FWversionNP.setState(IPS_OK);
436  FWversionNP.apply();
437  return true;
438  }
439 
440  return INDI::DefaultDevice::ISNewNumber(dev, name, values, names, n);
441 }
442 
443 bool USBDewpoint::readSettings()
444 {
445  char resp[UDP_RES_LEN];
446 
447  if (!sendCommand(UDP_STATUS_CMD, resp))
448  return false;
449 
450  // Status response is like:
451  // ##22.37/22.62/23.35/50.77/12.55/0/0/0/0/0/0/2/2/0/0/4**
452 
453  float temp1, temp2, temp_ambient, humidity, dewpoint;
454  unsigned int output1, output2, output3;
455  unsigned int calibration1, calibration2, calibration_ambient;
456  unsigned int threshold1, threshold2;
457  unsigned int automode, linkout23, aggressivity;
458 
459  int ok = sscanf(resp, UDP_STATUS_RESPONSE, &temp1, &temp2, &temp_ambient, &humidity, &dewpoint, &output1, &output2,
460  &output3, &calibration1, &calibration2, &calibration_ambient, &threshold1, &threshold2, &automode,
461  &linkout23, &aggressivity);
462 
463  if (ok == 16)
464  {
465  TemperaturesNP[0].setValue(temp1);
466  TemperaturesNP[1].setValue(temp2);
467  TemperaturesNP[2].setValue(temp_ambient);
468  TemperaturesNP.setState(IPS_OK);
469  TemperaturesNP.apply();
470 
471  HumidityNP[0].setValue(humidity);
472  HumidityNP.setState(IPS_OK);
473  HumidityNP.apply();
474 
475  DewpointNP[0].setValue(dewpoint);
476  DewpointNP.setState(IPS_OK);
477  DewpointNP.apply();
478 
479  OutputsNP[0].setValue(output1);
480  OutputsNP[1].setValue(output2);
481  OutputsNP[2].setValue(output3);
482  OutputsNP.setState(IPS_OK);
483  OutputsNP.apply();
484 
485  CalibrationsNP[0].setValue(calibration1);
486  CalibrationsNP[1].setValue(calibration2);
487  CalibrationsNP[2].setValue(calibration_ambient);
488  CalibrationsNP.setState(IPS_OK);
489  CalibrationsNP.apply();
490 
491  ThresholdsNP[0].setValue(threshold1);
492  ThresholdsNP[1].setValue(threshold2);
493  ThresholdsNP.setState(IPS_OK);
494  ThresholdsNP.apply();
495 
496  AutoModeSP.reset();
497  AutoModeSP[automode].setState(ISS_ON);
498  AutoModeSP.setState(IPS_OK);
499  AutoModeSP.apply();
500 
501  LinkOut23SP.reset();
502  LinkOut23SP[linkout23].setState(ISS_ON);
503  LinkOut23SP.setState(IPS_OK);
504  LinkOut23SP.apply();
505 
506  AggressivityNP[0].setValue(aggressivity);
507  AggressivityNP.setState(IPS_OK);
508  AggressivityNP.apply();
509  }
510  return true;
511 }
512 
514 {
515  if (!isConnected())
516  {
517  return;
518  }
519 
520  // Get temperatures etc.
521  readSettings();
523 }
void registerHandshake(std::function< bool()> callback)
registerHandshake Register a handshake function to be called once the intial connection to the device...
The Serial class manages connection with serial devices including Bluetooth. Serial communication is ...
bool isConnected() const
Definition: basedevice.cpp:520
const char * getDeviceName() const
Definition: basedevice.cpp:821
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 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)
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.
void setDriverInterface(uint16_t value)
setInterface Set driver interface. By default the driver interface is set to GENERAL_DEVICE....
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
void addDebugControl()
Add Debug control to the driver.
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
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 initProperties() override
Initilize 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 const char * getDefaultName() override
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
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:150
@ ISS_OFF
Definition: indiapi.h:151
@ ISS_ON
Definition: indiapi.h:152
@ IP_RW
Definition: indiapi.h:186
@ IP_RO
Definition: indiapi.h:184
@ IPS_BUSY
Definition: indiapi.h:163
@ IPS_ALERT
Definition: indiapi.h:164
@ IPS_IDLE
Definition: indiapi.h:161
@ IPS_OK
Definition: indiapi.h:162
@ ISR_1OFMANY
Definition: indiapi.h:173
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
Definition: indicom.c:424
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
Definition: indicom.c:1167
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:666
Implementations for common driver routines.
@ TTY_OK
Definition: indicom.h:150
#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 MAXRBUF
Definition: indiserver.cpp:102
__u8 cmd[4]
Definition: pwc-ioctl.h:2
std::unique_ptr< USBDewpoint > usbDewpoint(new USBDewpoint())
#define USBDEWPOINT_TIMEOUT
#define UDP_CALIBRATION_CMD
Definition: usb_dewpoint.h:32
#define UDP_IDENTIFY_RESPONSE
Definition: usb_dewpoint.h:71
#define UDP_RES_LEN
Definition: usb_dewpoint.h:43
#define UDP_AUTO_CMD
Definition: usb_dewpoint.h:34
#define UDP_RESET_CMD
Definition: usb_dewpoint.h:37
#define UDP_IDENTIFY_CMD
Definition: usb_dewpoint.h:36
#define UDP_AGGRESSIVITY_CMD
Definition: usb_dewpoint.h:35
#define UDP_STATUS_CMD
Definition: usb_dewpoint.h:29
#define UDP_STATUS_RESPONSE
Definition: usb_dewpoint.h:66
#define UDP_CMD_LEN
Definition: usb_dewpoint.h:28
#define UDP_OUTPUT_CMD
Definition: usb_dewpoint.h:30
#define UDP_LINK_CMD
Definition: usb_dewpoint.h:33
#define UDP_THRESHOLD_CMD
Definition: usb_dewpoint.h:31