Instrument Neutral Distributed Interface INDI  1.9.5
mbox.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  Copyright(c) 2017 Jasem Mutlaq. All rights reserved.
3 
4  INDI MBox 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 "mbox.h"
26 
27 #include "indicom.h"
29 
30 #include <memory>
31 #include <regex>
32 #include <cstring>
33 #include <termios.h>
34 #include <unistd.h>
35 
36 #define MBOX_TIMEOUT 6
37 #define MBOX_BUF 64
38 
39 // We declare an auto pointer to MBox.
40 static std::unique_ptr<MBox> mbox(new MBox());
41 
43 {
44  setVersion(1, 1);
45 }
46 
47 const char *MBox::getDefaultName()
48 {
49  return "MBox";
50 }
51 
53 {
55 
56  addParameter("WEATHER_TEMPERATURE", "Temperature (C)", -10, 30, 15);
57  addParameter("WEATHER_BAROMETER", "Barometer (mbar)", 20, 32.5, 15);
58  addParameter("WEATHER_HUMIDITY", "Humidity %", 0, 100, 15);
59  addParameter("WEATHER_DEWPOINT", "Dew Point (C)", 0, 100, 15);
60 
61  setCriticalParameter("WEATHER_TEMPERATURE");
62 
63  // Reset Calibration
64  IUFillSwitch(&ResetS[0], "RESET", "Reset", ISS_OFF);
65  IUFillSwitchVector(&ResetSP, ResetS, 1, getDeviceName(), "CALIBRATION_RESET", "Reset", MAIN_CONTROL_TAB, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
66 
67  // Calibration Properties
68  IUFillNumber(&CalibrationN[CAL_TEMPERATURE], "CAL_TEMPERATURE", "Temperature", "%.f", -50, 50, 1, 0);
69  IUFillNumber(&CalibrationN[CAL_PRESSURE], "CAL_PRESSURE", "Pressure", "%.f", -100, 100, 10, 0);
70  IUFillNumber(&CalibrationN[CAL_HUMIDITY], "CAL_HUMIDITY", "Humidity", "%.f", -50, 50, 1, 0);
71  IUFillNumberVector(&CalibrationNP, CalibrationN, 3, getDeviceName(), "CALIBRATION", "Calibration", MAIN_CONTROL_TAB, IP_RW, 0, IPS_IDLE);
72 
73  // Firmware Information
74  IUFillText(&FirmwareT[0], "VERSION", "Version", "--");
75  IUFillTextVector(&FirmwareTP, FirmwareT, 1, getDeviceName(), "DEVICE_FIRMWARE", "Firmware", MAIN_CONTROL_TAB, IP_RO, 0, IPS_IDLE);
76 
78 
80 
81  return true;
82 }
83 
85 {
87 
88  if (isConnected())
89  {
90  defineProperty(&CalibrationNP);
91  defineProperty(&ResetSP);
92  defineProperty(&FirmwareTP);
93  }
94  else
95  {
96  deleteProperty(CalibrationNP.name);
97  deleteProperty(ResetSP.name);
98  deleteProperty(FirmwareTP.name);
99  }
100 
101  return true;
102 }
103 
105 {
106  //tty_set_debug(1);
107 
108  AckResponse rc = ACK_ERROR;
109 
110  for (int i = 0; i < 3; i++)
111  {
112  rc = ack();
113  if (rc != ACK_ERROR)
114  break;
115  }
116 
117  if (rc == ACK_OK_STARTUP)
118  {
119  getCalibration(false);
120  return true;
121  }
122  else if (rc == ACK_OK_INIT)
123  {
124  //getCalibration(true);
125  CalibrationNP.s = IPS_BUSY;
126  return true;
127  }
128 
129  return false;
130 }
131 
133 {
134  char response[MBOX_BUF];
135 
136  if (CalibrationNP.s == IPS_BUSY)
137  {
138  if (getCalibration(true))
139  {
140  CalibrationNP.s = IPS_OK;
141  IDSetNumber(&CalibrationNP, nullptr);
142  }
143  }
144 
145  int nbytes_read = 0;
146 
147  if (isSimulation())
148  {
149  strncpy(response, "$PXDR,P,96276.0,P,0,C,31.8,C,1,H,40.8,P,2,C,16.8,C,3,1.1*31\r\n", MBOX_BUF);
150  nbytes_read = strlen(response);
151  }
152  else
153  {
154  int rc = -1;
155  if ((rc = tty_read_section(PortFD, response, 0xA, MBOX_TIMEOUT, &nbytes_read)) != TTY_OK)
156  {
157  char errstr[MAXRBUF];
158  tty_error_msg(rc, errstr, MAXRBUF);
159  LOGF_ERROR("%s error: %s.", __FUNCTION__, errstr);
160  return IPS_ALERT;
161  }
162 
163  tcflush(PortFD, TCIOFLUSH);
164  }
165 
166  // Remove \r\n
167  response[nbytes_read - 2] = '\0';
168 
169  LOGF_DEBUG("RES <%s>", response);
170 
171  if (verifyCRC(response) == false)
172  {
173  LOG_ERROR("CRC check failed!");
174  return IPS_ALERT;
175  }
176 
177  // Remove * and checksum
178  char *end = strstr(response, "*");
179  *end = '\0';
180 
181  // PXDR
182  std::vector<std::string> result = split(response, ",");
183  // Convert Pascal to mbar
184  setParameterValue("WEATHER_BAROMETER", std::stod(result[SENSOR_PRESSURE]) / 100.0);
185  setParameterValue("WEATHER_TEMPERATURE", std::stod(result[SENSOR_TEMPERATURE]));
186  setParameterValue("WEATHER_HUMIDITY", std::stod(result[SENSOR_HUMIDITY]));
187  setParameterValue("WEATHER_DEWPOINT", std::stod(result[SENSOR_DEW]));
188  if (strcmp(result[FIRMWARE].c_str(), FirmwareT[0].text))
189  {
190  IUSaveText(&FirmwareT[0], result[FIRMWARE].c_str());
191  FirmwareTP.s = IPS_OK;
192  IDSetText(&FirmwareTP, nullptr);
193  }
194 
195  return IPS_OK;
196 }
197 
198 MBox::AckResponse MBox::ack()
199 {
200  char response[MBOX_BUF] = {0};
201  int nbytes_read = 0;
202 
203  if (isSimulation())
204  {
205  strncpy(response, "MBox by Astromi.ch\r\n", 64);
206  nbytes_read = strlen(response);
207  }
208  else
209  {
210  char errstr[MAXRBUF] = {0};
211  int rc = -1;
212 
213  if ((rc = tty_read_section(PortFD, response, 0xA, MBOX_TIMEOUT, &nbytes_read)) != TTY_OK)
214  {
215  tty_error_msg(rc, errstr, MAXRBUF);
216  LOGF_ERROR("%s error: %s.", __FUNCTION__, errstr);
217  return ACK_ERROR;
218  }
219 
220  // Read again if we only recieved a newline character
221  if (response[0] == '\n')
222  {
223  if ((rc = tty_read_section(PortFD, response, 0xA, MBOX_TIMEOUT, &nbytes_read)) != TTY_OK)
224  {
225  tty_error_msg(rc, errstr, MAXRBUF);
226  LOGF_ERROR("%s error: %s.", __FUNCTION__, errstr);
227  return ACK_ERROR;
228  }
229  }
230  }
231 
232  // Remove \r\n
233  response[nbytes_read - 2] = '\0';
234 
235  LOGF_DEBUG("RES <%s>", response);
236 
237  if (strstr(response, "MBox"))
238  return ACK_OK_STARTUP;
239  // Check if already initialized
240  else if (strstr(response, "PXDR"))
241  return ACK_OK_INIT;
242 
243  return ACK_ERROR;
244 }
245 
246 bool MBox::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
247 {
248  if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
249  {
250  if (!strcmp(name, CalibrationNP.name))
251  {
252  double prevPressure = CalibrationN[CAL_PRESSURE].value;
253  double prevTemperature = CalibrationN[CAL_TEMPERATURE].value;
254  double prevHumidaty = CalibrationN[CAL_HUMIDITY].value;
255  IUUpdateNumber(&CalibrationNP, values, names, n);
256  double targetPressure = CalibrationN[CAL_PRESSURE].value;
257  double targetTemperature = CalibrationN[CAL_TEMPERATURE].value;
258  double targetHumidity = CalibrationN[CAL_HUMIDITY].value;
259 
260  bool rc = true;
261  if (targetPressure != prevPressure)
262  {
263  rc = setCalibration(CAL_PRESSURE);
264  usleep(200000);
265  }
266  if (targetTemperature != prevTemperature)
267  {
268  rc = setCalibration(CAL_TEMPERATURE);
269  usleep(200000);
270  }
271  if (targetHumidity != prevHumidaty)
272  {
273  rc = setCalibration(CAL_HUMIDITY);
274  }
275 
276  CalibrationNP.s = rc ? IPS_OK : IPS_ALERT;
277  IDSetNumber(&CalibrationNP, nullptr);
278  return true;
279  }
280  }
281 
282  return INDI::Weather::ISNewNumber(dev, name, values, names, n);
283 }
284 
285 bool MBox::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
286 {
287  if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
288  {
289  if (!strcmp(name, ResetSP.name))
290  {
291  if (resetCalibration())
292  {
293  ResetSP.s = IPS_OK;
294  IDSetSwitch(&ResetSP, nullptr);
295  LOG_INFO("Calibration values are reset.");
296 
297  CalibrationN[CAL_PRESSURE].value = 0;
298  CalibrationN[CAL_TEMPERATURE].value = 0;
299  CalibrationN[CAL_HUMIDITY].value = 0;
300  CalibrationNP.s = IPS_IDLE;
301  IDSetNumber(&CalibrationNP, nullptr);
302  }
303  else
304  {
305  ResetSP.s = IPS_ALERT;
306  IDSetSwitch(&ResetSP, nullptr);
307  }
308 
309 
310  return true;
311  }
312  }
313 
314  return INDI::Weather::ISNewSwitch(dev, name, states, names, n);
315 }
316 
317 bool MBox::getCalibration(bool sendCommand)
318 {
319  int nbytes_written = 0, nbytes_read = 0;
320 
321  const char *command = ":calget*";
322  char response[MBOX_BUF];
323 
324  if (sendCommand)
325  LOGF_DEBUG("CMD <%s>", command);
326 
327  if (isSimulation())
328  {
329  strncpy(response, "$PCAL,P,20,T,50,H,-10*79\r\n", 64);
330  nbytes_read = strlen(response);
331  }
332  else
333  {
334  int rc = -1;
335  char errstr[MAXRBUF] = {0};
336 
337  if (sendCommand)
338  {
339  tcflush(PortFD, TCIOFLUSH);
340 
341  if ((rc = tty_write(PortFD, command, strlen(command), &nbytes_written)) != TTY_OK)
342  {
343  tty_error_msg(rc, errstr, MAXRBUF);
344  LOGF_ERROR("%s write error: %s.", __FUNCTION__, errstr);
345  return false;
346  }
347  }
348 
349  if ((rc = tty_read_section(PortFD, response, 0xA, MBOX_TIMEOUT, &nbytes_read)) != TTY_OK)
350  {
351  tty_error_msg(rc, errstr, MAXRBUF);
352  LOGF_ERROR("%s read error: %s.", __FUNCTION__, errstr);
353  return false;
354  }
355 
356  // If token is invalid, read again
357  if (strstr(response, "$PCAL") == nullptr)
358  {
359  if ((rc = tty_read_section(PortFD, response, 0xA, MBOX_TIMEOUT, &nbytes_read)) != TTY_OK)
360  {
361  tty_error_msg(rc, errstr, MAXRBUF);
362  LOGF_ERROR("%s read error: %s.", __FUNCTION__, errstr);
363  return false;
364  }
365  }
366  }
367 
368  // Remove \r\n
369  response[nbytes_read - 2] = '\0';
370 
371  LOGF_DEBUG("RES <%s>", response);
372 
373  if (verifyCRC(response) == false)
374  {
375  LOG_ERROR("CRC check failed!");
376  return false;
377  }
378 
379  // Remove * and checksum
380  char *end = strstr(response, "*");
381  *end = '\0';
382 
383  // PCAL
384  std::vector<std::string> result = split(response, ",");
385  CalibrationN[CAL_PRESSURE].value = std::stod(result[SENSOR_PRESSURE]) / 10.0;
386  CalibrationN[CAL_TEMPERATURE].value = std::stod(result[SENSOR_PRESSURE + 2]) / 10.0;
387  CalibrationN[CAL_HUMIDITY].value = std::stod(result[SENSOR_PRESSURE + 4]) / 10.0;
388  return true;
389 }
390 
391 bool MBox::setCalibration(CalibrationType type)
392 {
393  int nbytes_written = 0, rc = -1;
394  char errstr[MAXRBUF];
395  char command[16] = {0};
396 
397  if (type == CAL_PRESSURE)
398  {
399  // Pressure.
400  snprintf(command, 16, ":calp,%d*", static_cast<int32_t>(CalibrationN[CAL_PRESSURE].value * 10.0));
401 
402  LOGF_DEBUG("CMD <%s>", command);
403 
404  if (isSimulation() == false)
405  {
406  tcflush(PortFD, TCIOFLUSH);
407 
408  if ((rc = tty_write(PortFD, command, strlen(command), &nbytes_written)) != TTY_OK)
409  {
410  tty_error_msg(rc, errstr, MAXRBUF);
411  LOGF_ERROR("%s error: %s.", __FUNCTION__, errstr);
412  return false;
413  }
414 
415  }
416  }
417  else if (type == CAL_TEMPERATURE)
418  {
419  // Temperature
420  snprintf(command, 16, ":calt,%d*", static_cast<int32_t>(CalibrationN[CAL_TEMPERATURE].value * 10.0));
421 
422  LOGF_DEBUG("CMD <%s>", command);
423 
424  if (isSimulation() == false)
425  {
426  tcflush(PortFD, TCIOFLUSH);
427 
428  if ((rc = tty_write(PortFD, command, strlen(command), &nbytes_written)) != TTY_OK)
429  {
430  tty_error_msg(rc, errstr, MAXRBUF);
431  LOGF_ERROR("%s error: %s.", __FUNCTION__, errstr);
432  return false;
433  }
434  }
435  }
436  else
437  {
438  // Humidity
439  snprintf(command, 16, ":calh,%d*", static_cast<int32_t>(CalibrationN[CAL_HUMIDITY].value * 10.0));
440 
441  LOGF_DEBUG("CMD <%s>", command);
442 
443  if (isSimulation() == false)
444  {
445  tcflush(PortFD, TCIOFLUSH);
446 
447  if ((rc = tty_write(PortFD, command, strlen(command), &nbytes_written)) != TTY_OK)
448  {
449  tty_error_msg(rc, errstr, MAXRBUF);
450  LOGF_ERROR("%s error: %s.", __FUNCTION__, errstr);
451  return false;
452  }
453 
454  }
455  }
456 
457  return getCalibration(false);
458 }
459 
460 bool MBox::resetCalibration()
461 {
462  const char *command = ":calreset*";
463  LOGF_DEBUG("CMD <%s>", command);
464 
465  if (isSimulation() == false)
466  {
467  int nbytes_written = 0, rc = -1;
468  tcflush(PortFD, TCIOFLUSH);
469 
470  if ((rc = tty_write(PortFD, command, strlen(command), &nbytes_written)) != TTY_OK)
471  {
472  char errstr[MAXRBUF];
473  tty_error_msg(rc, errstr, MAXRBUF);
474  LOGF_ERROR("%s error: %s.", __FUNCTION__, errstr);
475  return false;
476  }
477  }
478 
479  return true;
480 }
481 
482 bool MBox::verifyCRC(const char *response)
483 {
484  // Start with $ and ends with * followed by checksum value of the response
485  uint8_t calculated_checksum = 0, response_checksum = 0;
486  // Skip starting $. Copy string
487  char checksum_string[MBOX_BUF] = {0};
488  strncpy(checksum_string, response + 1, MBOX_BUF);
489 
490  std::vector<std::string> result = split(checksum_string, R"(\*)");
491 
492  // Hex value
493  try
494  {
495  response_checksum = std::stoi(result[1], nullptr, 16);
496  }
497  catch (...)
498  {
499  return false;
500  }
501 
502 
503  // Calculate checksum of message XOR
504  for (auto oneByte : result[0])
505  calculated_checksum ^= oneByte;
506 
507  return (calculated_checksum == response_checksum);
508 }
509 
513 std::vector<std::string> MBox::split(const std::string &input, const std::string &regex)
514 {
515  // passing -1 as the submatch index parameter performs splitting
516  std::regex re(regex);
517  std::sregex_token_iterator
518  first{input.begin(), input.end(), re, -1},
519  last;
520  return {first, last};
521 }
IP_RO
@ IP_RO
Definition: indiapi.h:183
MBox::updateProperties
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
Definition: mbox.cpp:84
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
MBox::updateWeather
virtual IPState updateWeather() override
updateWeather Update weather conditions from device or service. The function should not change the st...
Definition: mbox.cpp:132
IPState
IPState
Property state.
Definition: indiapi.h:158
LOGF_ERROR
#define LOGF_ERROR(fmt,...)
Definition: indilogger.h:80
Connection::Serial::B_38400
@ B_38400
Definition: connectionserial.h:82
IPS_OK
@ IPS_OK
Definition: indiapi.h:161
_INumberVectorProperty::s
IPState s
Definition: indiapi.h:332
INDI::Weather::initProperties
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
Definition: indiweather.cpp:41
ISS_OFF
@ ISS_OFF
Definition: indiapi.h:150
indicom.h
Implementations for common driver routines.
IDSetText
void IDSetText(const ITextVectorProperty *t, const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(2
Tell client to update an existing text vector property.
IPS_ALERT
@ IPS_ALERT
Definition: indiapi.h:163
INDI::DefaultDevice::isSimulation
bool isSimulation() const
Definition: defaultdevice.cpp:734
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
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
MBox::MBox
MBox()
Definition: mbox.cpp:42
IUFillTextVector
void IUFillTextVector(ITextVectorProperty *tvp, IText *tp, int ntp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a text vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidriver.c:477
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_read_section
int tty_read_section(int fd, char *buf, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
Definition: indicom.c:557
IUFillText
void IUFillText(IText *tp, const char *name, const char *label, const char *initialText)
Assign attributes for a text property. The text's auxiliary elements will be set to NULL.
Definition: indidriver.c:369
INDI::Weather::ISNewSwitch
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
Definition: indiweather.cpp:133
MBox::ISNewSwitch
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
Definition: mbox.cpp:285
LOG_INFO
#define LOG_INFO(txt)
Definition: indilogger.h:74
MAXRBUF
#define MAXRBUF
Definition: indidriver.c:52
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:1156
LOGF_DEBUG
#define LOGF_DEBUG(fmt,...)
Definition: indilogger.h:83
type
__le16 type
Definition: pwc-ioctl.h:2
Connection::Serial::setDefaultBaudRate
void setDefaultBaudRate(BaudRate newRate)
setDefaultBaudRate Set default baud rate. The default baud rate is 9600 unless otherwise changed by t...
Definition: connectionserial.cpp:381
MBox::ISNewNumber
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
Definition: mbox.cpp:246
INDI::Weather::PortFD
int PortFD
Definition: indiweather.h:154
INDI::Weather::ISNewNumber
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
Definition: indiweather.cpp:176
mbox.h
tty_write
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
Definition: indicom.c:415
INDI::Weather::updateProperties
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
Definition: indiweather.cpp:101
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
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
IPS_BUSY
@ IPS_BUSY
Definition: indiapi.h:162
ISR_1OFMANY
@ ISR_1OFMANY
Definition: indiapi.h:172
MBox::getDefaultName
virtual const char * getDefaultName() override
Definition: mbox.cpp:47
connectionserial.h
IPS_IDLE
@ IPS_IDLE
Definition: indiapi.h:160
_INumberVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:322
MBox::initProperties
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
Definition: mbox.cpp:52
end
JsonIterator end(JsonValue)
Definition: gason.h:108
_ITextVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:249
INDI::BaseDevice::isConnected
bool isConnected() const
Definition: basedevice.cpp:518
MBox::Handshake
virtual bool Handshake() override
perform handshake with device to check communication
Definition: mbox.cpp:104
MBOX_BUF
#define MBOX_BUF
Definition: mbox.cpp:37
LOG_ERROR
#define LOG_ERROR(txt)
Shorter logging macros. In order to use these macros, the function (or method) "getDeviceName()" must...
Definition: indilogger.h:72
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
IUSaveText
void IUSaveText(IText *tp, const char *newtext)
Function to reliably save new text in a IText.
Definition: indicom.c:1449
name
const char * name
Definition: indiserver.c:116
_ISwitchVectorProperty::s
IPState s
Definition: indiapi.h:382
INDI::Weather::serialConnection
Connection::Serial * serialConnection
Definition: indiweather.h:151
_ITextVectorProperty::s
IPState s
Definition: indiapi.h:259
IUUpdateNumber
int IUUpdateNumber(INumberVectorProperty *nvp, double values[], char *names[], int n)
Update all numbers in a number vector property.
Definition: indidriver.c:225
MBox
Definition: mbox.h:29
IP_RW
@ IP_RW
Definition: indiapi.h:185
ISState
ISState
Switch state.
Definition: indiapi.h:148
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.
MBOX_TIMEOUT
#define MBOX_TIMEOUT
Definition: mbox.cpp:36
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
_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