Instrument Neutral Distributed Interface INDI 2.2.5
myDewControllerPro.cpp
Go to the documentation of this file.
1/*
2 myDewControllerPro Driver
3 Copyright (C) 2017-2023 Chemistorge
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 USA
18
19*/
20
21#include "myDewControllerPro.h"
23#include "indicom.h"
24
25#include <termios.h>
26
27#define MYDEWHEATERPRO_TIMEOUT 3
28#define BOARD_FAN_TAB "Board Fan"
29#define TEMPERATURE_OFFSETS_TAB "Temperature/Tracking Offsets"
30#define LCD_DISPLAY_TAB "LCD Display"
31
32std::unique_ptr<myDewControllerPro> mydewcontrollerpro(new myDewControllerPro());
33
34
35myDewControllerPro::myDewControllerPro() : INDI::PowerInterface(this), INDI::WeatherInterface(this)
36{
37 setVersion(1, 0);
38}
39
41{
42 DefaultDevice::initProperties();
43
45
46 // Initialize PowerInterface with 3 dew ports and 1 auto dew port (for tracking mode)
47 PI::initProperties(POWER_TAB, 0, 3, 0, 1, 0);
48 // Initialize WeatherInterface
49 WI::initProperties(ENVIRONMENT_TAB, ENVIRONMENT_TAB);
50
51 // Set PowerInterface capabilities
53
54 // Add WeatherInterface parameters
55 WI::addParameter("AMBIENT_TEMPERATURE", "Ambient Temperature", -50, 70, 15);
56 WI::addParameter("HUMIDITY", "Humidity", 0, 100, 15);
57 WI::addParameter("DEWPOINT", "Dew Point", -50, 70, 15);
58 WI::setCriticalParameter("AMBIENT_TEMPERATURE");
59
60 FanSpeedNP[0].fill("Fan Power", "Fan Speed", "%4.0f %%", 0., 100., 1., 0.);
61 FanSpeedNP.fill(getDeviceName(), "FanSpeed", "Board Fan", BOARD_FAN_TAB, IP_RW, 0, IPS_IDLE);
62
63 FanModeSP[BOARD_TEMP].fill("Board Temp", "Board Temp Sensor", ISS_OFF);
64 FanModeSP[MANUAL_FAN].fill("Manual", "Manual", ISS_ON);
65 FanModeSP.fill(getDeviceName(), "Fan_Mode", "Fan Mode", BOARD_FAN_TAB, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
66
67 EEPROMSP[RESET_EEPROM].fill("Reset EEPROM", "Reset EEPROM to Defaults", ISS_OFF);
68 EEPROMSP[SAVE_TO_EEPROM].fill("Save to EEPROM", "Save to EEPROM", ISS_OFF);
69 EEPROMSP.fill(getDeviceName(), "EEPROM", "EEPROM", OPTIONS_TAB, IP_WO, ISR_ATMOST1, 0, IPS_IDLE);
70
71 FanTempTriggerNP[FANTEMPOFF].fill("Board_Temp_Off", "Board Fan Temp Off", "%4.0f \u2103", 0., 100., 1., 0.);
72 FanTempTriggerNP[FANTEMPON].fill("Board_Temp_On", "Board Fan Temp On", "%4.0f \u2103", 0., 100., 1., 0.);
73 FanTempTriggerNP.fill(getDeviceName(), "Fan Trigger Temps", "Fan Trigger", BOARD_FAN_TAB, IP_RW, 0, IPS_IDLE);
74
75 LCDPageRefreshNP[0].fill("Page Refresh Rate", "Page Refresh Rate", "%4.0f ms", 500., 5000., 500., 0.);
76 LCDPageRefreshNP.fill(getDeviceName(), "LCD Page", "LCD Page", LCD_DISPLAY_TAB, IP_RW, 0, IPS_IDLE);
77
78 LCDDisplayTempUnitsSP[CELCIUS].fill("Celsius", "Celsius", ISS_ON);
79 LCDDisplayTempUnitsSP[FAHRENHEIT].fill("Fahrenheit", "Fahrenheit", ISS_OFF);
80 LCDDisplayTempUnitsSP.fill(getDeviceName(), "Temp Units", "Temp Units", LCD_DISPLAY_TAB, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
81
82 EnableLCDDisplaySP[DISABLE_LCD].fill("Disabled", "Disabled", ISS_ON);
83 EnableLCDDisplaySP[ENABLE_LCD].fill("Enabled", "Enabled", ISS_OFF);
84 EnableLCDDisplaySP.fill(getDeviceName(), "LCD Status", "LCD Status", LCD_DISPLAY_TAB, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
85
86 /* Channel Manual and Boost */
87 CH1CH2BoostSP[CH1_BOOST_100].fill("BOOST_CH1", "Strap 1 Boost 100%", ISS_OFF);
88 CH1CH2BoostSP[CH2_BOOST_100].fill("BOOST_CH2", "Strap 2 Boost 100%", ISS_OFF);
89 CH1CH2BoostSP.fill(getDeviceName(), "CHANNEL_BOOST", "Heat Boost", MAIN_CONTROL_TAB, IP_RW, ISR_NOFMANY, 0, IPS_IDLE);
90
91 CH3_ModeSP[DISABLED_STRAP].fill("STRAP_DISABLED", "Strap Disabled", ISS_ON);
92 CH3_ModeSP[DEWSTRAP_ONE].fill("SHADOW STRAP 1", "Shadow Strap 1", ISS_OFF);
93 CH3_ModeSP[DEWSTRAP_TWO].fill("SHADOW STRAP 2", "Shadow Strap 2", ISS_OFF);
94 CH3_ModeSP[MANUAL_STRAP].fill("Manual", "Manual", ISS_OFF);
95 CH3_ModeSP[TEMP_PROBE_THREE].fill("TEMP_PROBE", "Temp Probe", ISS_OFF);
96 CH3_ModeSP.fill(getDeviceName(), "CHANEL 3 SHAWDOW", "Strap 3 Mode", MAIN_CONTROL_TAB, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
97
98 CH3_Manual_PowerNP[0].fill("MANUAL_POWER", "Strap 3 Manual Power", "%4.0f %%", 0., 100., 1., 0.);
99 CH3_Manual_PowerNP.fill(getDeviceName(), "CH3_POWER", "Strap 3 Power", MAIN_CONTROL_TAB, IP_RW, 0, IPS_IDLE);
100
101 /* Temperatures */
102 TemperaturesNP[PROBE_1].fill("CHANNEL1", "Strap 1", "%3.2f \u2103", -50., 70., 0., 0.);
103 TemperaturesNP[PROBE_2].fill("CHANNEL2", "Strap 2", "%3.2f \u2103", -50., 70., 0., 0.);
104 TemperaturesNP[PROBE_3].fill("CHANNEL3", "Strap 3", "%3.2f \u2103", -50., 70., 0., 0.);
105 TemperaturesNP[BOARD_PROBE].fill("BOARD Temp", "Board", "%3.2f \u2103", -50., 100., 0., 0.);
106 TemperaturesNP.fill(getDeviceName(), "TEMPERATURES", "Temperatures", MAIN_CONTROL_TAB, IP_RO, 0, IPS_IDLE);
107
108 /* Temperature calibration values */
109 TemperatureOffsetsNP[TEMP_PROBE_ONE_OFFSET].fill("CHANNEL1", "Strap 1", "%1.0f \u2103", -10., 10., 1., 0.);
110 TemperatureOffsetsNP[TEMP_PROBE_TWO_OFFSET].fill("CHANNEL2", "Strap 2", "%1.0f \u2103", -10., 10., 1., 0.);
111 TemperatureOffsetsNP[TEMP_PROBE_THREE_OFFSET].fill("CHANNEL3", "Strap 3", "%1.0f \u2103", -10., 10., 1., 0.);
112 TemperatureOffsetsNP[AMBIENT_TEMP_PROBE_OFFSET].fill("AMBIENT", "Ambient", "%4.0f \u2103", -4, 3, 1, 0);
113 TemperatureOffsetsNP.fill(getDeviceName(), "TEMP_CALIBRATIONS", "Temp Offsets", TEMPERATURE_OFFSETS_TAB, IP_RW, 0,
114 IPS_IDLE);
115
116 ZeroTempOffsetsSP[0].fill("Zero_Temp", "Zero Temperature Offsets", ISS_OFF);
117 ZeroTempOffsetsSP.fill(getDeviceName(), "Zero Offsets", "Zero Offsets", TEMPERATURE_OFFSETS_TAB, IP_RW, ISR_ATMOST1, 0,
118 IPS_IDLE);
119
120 /* Tracking Mode Options */
121
122 TrackingModeSP[AMBIENT].fill("AMBIENT", "Ambient", ISS_OFF);
123 TrackingModeSP[DEWPOINT].fill("DEWPOINT", "Dew Point", ISS_ON);
124 TrackingModeSP[MIDPOINT].fill("MIDPOINT", "Mid Point", ISS_OFF);
125 TrackingModeSP.fill(getDeviceName(), "Tracking Mode", "Tracking Mode", TEMPERATURE_OFFSETS_TAB, IP_RW, ISR_1OFMANY, 0,
126 IPS_IDLE);
127
128 TrackingModeOffsetNP[0].fill("Offset", "Offset", "%4.0f \u2103", -4, 3, 1, 0);
129 TrackingModeOffsetNP.fill(getDeviceName(), "Tracking Offset", "Tracking Offset", TEMPERATURE_OFFSETS_TAB, IP_RW, 0,
130 IPS_IDLE);
131 /* Firmware version */
132 FWVersionNP[0].fill("FIRMWARE", "Firmware Version", "%4.0f", 0., 65535., 1., 0.);
133 FWVersionNP.fill(getDeviceName(), "FW_VERSION", "Firmware", OPTIONS_TAB, IP_RO, 0, IPS_IDLE);
134
139
140 // No simulation control for now
141
142
143 serialConnection = new Connection::Serial(this);
144
145 serialConnection->setDefaultBaudRate(serialConnection->B_57600);
146 serialConnection->registerHandshake([&]()
147 {
148 return Handshake();
149 });
150 registerConnection(serialConnection);
151
152 return true;
153}
154
155bool myDewControllerPro::SetDewPort(size_t port, bool enabled, double dutyCycle)
156{
157 INDI_UNUSED(port);
158 // DEW ports are 0, 1, 2 for dew heaters 1, 2, 3 (device uses 1-based indexing)
159 // Convert duty cycle percentage (0-100) to 0-255 range
160 auto pwmValue = static_cast<uint8_t>(dutyCycle / 100.0 * 255.0);
161 return setInt(enabled ? pwmValue : 0, "S%d#", "Failed to set Dew Port Power");
162}
163
164bool myDewControllerPro::SetAutoDewEnabled(size_t port, bool enabled)
165{
166 INDI_UNUSED(port); // myDewControllerPro has a single auto dew control (Tracking Mode)
167 int mode = enabled ? DEWPOINT : AMBIENT; // Map enabled to DEWPOINT, disabled to AMBIENT
168 return setInt(mode, MDCP_SET_TRACKING_MODE, "Failed to set Tracking Mode");
169}
170
171bool myDewControllerPro::cancelOutputBoost()
172{
173 if (sendCommand(MDCP_CANCEL_BOOST, nullptr))
174 {
175 return true;
176 }
177 else
178 {
179 LOG_INFO("Failed to cancel Boost");
181 return false;
182 }
183
184}
185
187{
188 DefaultDevice::updateProperties();
189
190 if (isConnected())
191 {
192 // Update PowerInterface properties
194 // Update WeatherInterface properties
196
197 defineProperty(CH1CH2BoostSP);
198 defineProperty(CH3_ModeSP);
199 defineProperty(CH3_Manual_PowerNP);
200 defineProperty(TemperaturesNP);
201 defineProperty(HumidityNP);
202 defineProperty(DewpointNP);
203 defineProperty(FanSpeedNP);
204 defineProperty(FanModeSP);
205 defineProperty(TemperatureOffsetsNP);
206 defineProperty(ZeroTempOffsetsSP);
207 defineProperty(TrackingModeSP);
208 defineProperty(TrackingModeOffsetNP);
209 defineProperty(FanTempTriggerNP);
210 defineProperty(EnableLCDDisplaySP);
211 defineProperty(LCDDisplayTempUnitsSP);
212 defineProperty(LCDPageRefreshNP);
213 defineProperty(EEPROMSP);
214 defineProperty(FWVersionNP);
215
216
217 cancelOutputBoost();
218
219 loadConfig(true);
220 if (!readMainValues())
221 {
222 LOG_INFO("Reading Main Values Error");
223 }
224 if (!readLCDDisplayValues())
225 {
226 LOG_INFO("Reading LCD Display Values Error");
227 }
228 if (!readBoardFanValues())
229 {
230 LOG_INFO("Reading Board Fan Values Error");
231 }
232 if (!readOffsetValues())
233 {
234 LOG_INFO("Reading Offset Values Error");
235 }
236 LOG_INFO("myDewControllerPro parameters updated, device ready for use.");
238 }
239 else
240 {
241 // Delete PowerInterface properties
243 // Delete WeatherInterface properties
245
246 deleteProperty(CH1CH2BoostSP);
247 deleteProperty(CH3_ModeSP);
248 deleteProperty(CH3_Manual_PowerNP);
249 deleteProperty(TemperaturesNP);
250 deleteProperty(HumidityNP);
251 deleteProperty(DewpointNP);
252 deleteProperty(FanSpeedNP);
253 deleteProperty(FanModeSP);
254 deleteProperty(TemperatureOffsetsNP);
255 deleteProperty(ZeroTempOffsetsSP);
256 deleteProperty(TrackingModeSP);
257 deleteProperty(TrackingModeOffsetNP);
258 deleteProperty(FanTempTriggerNP);
259 deleteProperty(EnableLCDDisplaySP);
260 deleteProperty(LCDDisplayTempUnitsSP);
261 deleteProperty(LCDPageRefreshNP);
262 deleteProperty(EEPROMSP);
263 deleteProperty(FWVersionNP);
264 }
265
266 return true;
267}
268
269// Add saveConfigItems implementation
271{
272 DefaultDevice::saveConfigItems(fp);
275
276 // Save custom properties
277 CH1CH2BoostSP.save(fp);
278 CH3_ModeSP.save(fp);
279 CH3_Manual_PowerNP.save(fp);
280 TemperaturesNP.save(fp);
281 HumidityNP.save(fp);
282 DewpointNP.save(fp);
283 FanSpeedNP.save(fp);
284 FanModeSP.save(fp);
285 TemperatureOffsetsNP.save(fp);
286 ZeroTempOffsetsSP.save(fp);
287 TrackingModeSP.save(fp);
288 TrackingModeOffsetNP.save(fp);
289 FanTempTriggerNP.save(fp);
290 EnableLCDDisplaySP.save(fp);
291 LCDDisplayTempUnitsSP.save(fp);
292 LCDPageRefreshNP.save(fp);
293 EEPROMSP.save(fp);
294 FWVersionNP.save(fp);
295
296 return true;
297}
298
300{
301 return "myDewContollerPro";
302}
303
304bool myDewControllerPro::sendCommand(const char *cmd, char *resp)
305{
306 int nbytes_written = 0, nbytes_read = 0, rc = -1;
307 char errstr[MAXRBUF];
308 LOGF_DEBUG("CMD: %s.", cmd);
309
310 tcflush(PortFD, TCIOFLUSH);
311 if ((rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
312 {
313 tty_error_msg(rc, errstr, MAXRBUF);
314 LOGF_ERROR("Error writing command %s: %s.", cmd, errstr);
315 return false;
316 }
317
318 if (resp)
319 {
320 if ((rc = tty_nread_section(PortFD, resp, MDCP_RES_LEN, '$', MYDEWHEATERPRO_TIMEOUT, &nbytes_read)) != TTY_OK)
321 {
322 tty_error_msg(rc, errstr, MAXRBUF);
323 LOGF_ERROR("Error reading response for command %s: %s.", cmd, errstr);
324 return false;
325 }
326 }
327 return true;
328}
329
330
331
332bool myDewControllerPro::Handshake()
333{
334 PortFD = serialConnection->getPortFD();
335
336 int tries = 3;
337 do
338 {
339 if (Ack())
340 {
341 LOG_INFO("myDewControllerPro is online. Getting device parameters...");
342 return true;
343 }
344 LOG_INFO("Error retrieving data from myDewControllerPro, trying resync...");
345 }
346 while (--tries > 0);
347
348 //LOG_INFO("Error retrieving data from myDewControllerPro, please ensure controller "
349 // "is powered and the port is correct.");
350 return false;
351}
352
353bool myDewControllerPro::Ack()
354{
355 char resp[MDCP_RES_LEN] = {};
356 tcflush(PortFD, TCIOFLUSH);
357
358 if (!sendCommand(MDCP_GET_VERSION, resp))
359 return false;
360
361 int firmware = -1;
362 int ok = sscanf(resp, MDCP_IDENTIFY_RESPONSE, &firmware);
363 snprintf(resp, 40, "Firmware Version: %d", firmware);
364 LOG_INFO(resp);
365
366 if (ok != 1)
367 {
368 LOGF_ERROR("myDewControllerPro not properly identified! Answer was: %s.", resp);
369 return false;
370 }
371 if (firmware < 340)
372 {
373 LOG_INFO("Please update myDewControllerPro firmware");
374 LOG_INFO("https://sourceforge.net/projects/arduinonanodewcontrollerpro/files/myDewControllerPro%20v300%203channel/CODE%20ARDUINO/");
375 return false;
376 }
377 int numberProbes = 0;
378 if (!sendCommand(MDCP_GET_NUMBER_OF_PROBES, resp))
379 return false;
380 sscanf(resp, "g%u$", &numberProbes);
381 snprintf(resp, 40, "The number of Temperature Probes are: %d", numberProbes);
382 LOG_INFO(resp);
383 if (numberProbes < 1)
384 {
385 LOG_INFO("Warning no temperature probes detected");
386 }
387 FWVersionNP.setState(IPS_BUSY);
388 FWVersionNP[0].setValue(firmware);
389 FWVersionNP.setState(IPS_OK);
390 FWVersionNP.apply();
391
392 return true;
393
394}
395
396bool myDewControllerPro::setOutputBoost(unsigned int channel)
397{
398
399
400
401 if (channel == 0)
402 {
403 return sendCommand(MDCP_BOOST_CH1, nullptr);
404 }
405 else if (channel == 1)
406 {
407 return sendCommand(MDCP_BOOST_CH2, nullptr);
408 }
409 else
410 {
411 LOG_INFO("No Channel Set");
412 return false;
413 }
414
415}
416
417bool myDewControllerPro::setInt(int mode, const char *mask, const char *errMessage)
418{
419 char cmd[MDCP_CMD_LEN + 1];
420
421 snprintf(cmd, MDCP_CMD_LEN + 1, mask, mode);
422 if (!sendCommand(cmd, nullptr))
423 {
424 LOG_INFO(errMessage);
425 LOG_INFO(cmd);
426 return false;
427 }
428 return true;
429
430}
431
432bool myDewControllerPro::setChoice(int testInt, const char *positiveChoice, const char *negativeChoice,
433 const char *errMessage)
434{
435 const char* mask = testInt == 1 ? positiveChoice : negativeChoice;
436 if (!sendCommand(mask, nullptr))
437 {
438 LOG_INFO(errMessage);
439
440 return false;
441 }
442 return true;
443}
444
445
446
447bool myDewControllerPro::setTempCalibrations(float ch1, float ch2, float ch3, int ambient)
448{
449 char cmd[MDCP_CMD_LEN + 1];
450
451
452 snprintf(cmd, MDCP_CMD_LEN + 1, MDCP_SET_TEMP_CH1_OFFSET, ch1);
453 if (!sendCommand(cmd, nullptr))
454 {
455 LOG_INFO("Failed to set CH1 offset");
456 LOG_INFO(cmd);
457 return false;
458 }
459 snprintf(cmd, MDCP_CMD_LEN + 1, MDCP_SET_TEMP_CH2_OFFSET, ch2);
460 if (!sendCommand(cmd, nullptr))
461 {
462 LOG_INFO("Failed to set CH2 offset");
463 LOG_INFO(cmd);
464 return false;
465 }
466 snprintf(cmd, MDCP_CMD_LEN + 1, MDCP_SET_TEMP_CH3_OFFSET, ch3);
467 if (!sendCommand(cmd, nullptr))
468 {
469 LOG_INFO("Failed to set CH3 offset");
470 LOG_INFO(cmd);
471 return false;
472 }
473
474 snprintf(cmd, MDCP_CMD_LEN + 1, MDCP_SET_AMB_TEMP_OFFSET, ambient);
475 if (!sendCommand(cmd, nullptr))
476 {
477 LOG_INFO("Failed to set CH3 offset");
478 LOG_INFO(cmd);
479 return false;
480 }
481 return true;
482
483
484
485}
486
487bool myDewControllerPro::setFanTempTrigger(int tempOn, int tempOff)
488{
489 char cmd[MDCP_CMD_LEN + 1];
490
491
492 snprintf(cmd, MDCP_CMD_LEN + 1, MDCP_SET_FAN_ON_TEMP, tempOn);
493 if (!sendCommand(cmd, nullptr))
494 {
495 LOG_INFO("Failed to set temp on");
496 LOG_INFO(cmd);
497 return false;
498 }
499 snprintf(cmd, MDCP_CMD_LEN + 1, MDCP_SET_FAN_OFF_TEMP, tempOff);
500 if (!sendCommand(cmd, nullptr))
501 {
502 LOG_INFO("Failed to set CH2 offset");
503 LOG_INFO(cmd);
504 return false;
505 }
506
507 return true;
508
509
510
511}
512
513bool myDewControllerPro::zeroTempCalibrations()
514{
515
516 if (!sendCommand(MDCP_CLEAR_TEMP_OFFSETS, nullptr))
517 {
518 LOG_INFO("Failed to zero temp offset");
519
520 return false;
521 }
522 if (!sendCommand("e0#", nullptr))
523 {
524 LOG_INFO("Failed to zero ambtemp offset");
525
526 return false;
527 }
528 return true;
529
530
531}
532
533
534
535
536
537
538
539
540bool myDewControllerPro::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
541{
542 if (!dev || strcmp(dev, getDeviceName()))
543 return false;
544
545 // Process PowerInterface switches
546 if (PI::processSwitch(dev, name, states, names, n))
547 return true;
548
549 // Process WeatherInterface switches
550 if (WI::processSwitch(dev, name, states, names, n))
551 return true;
552
553 if (CH1CH2BoostSP.isNameMatch(name))
554 {
555 CH1CH2BoostSP.update( states, names, n);
556 CH1CH2BoostSP.setState(IPS_BUSY);
557 cancelOutputBoost();
558 if (CH1CH2BoostSP[CH1_BOOST_100].getState() == ISS_ON)
559 {
560 setOutputBoost(CH1_BOOST_100);
561 }
562 if (CH1CH2BoostSP[CH2_BOOST_100].getState() == ISS_ON)
563 {
564 setOutputBoost(CH2_BOOST_100);
565 }
566 CH1CH2BoostSP.setState(IPS_OK);
567 CH1CH2BoostSP.apply();
568 readMainValues();
569 return true;
570
571 }
572
573 if (CH3_ModeSP.isNameMatch(name))
574 {
575 CH3_ModeSP.update(states, names, n);
576 CH3_ModeSP.setState(IPS_BUSY);
577 int mode = CH3_ModeSP.findOnSwitchIndex();
578 setInt(mode, MDCP_SET_CH3_SETTINGS, "Failed to set CH3 mode");
579 CH3_ModeSP.setState(IPS_OK);
580 CH3_ModeSP.apply();
581 readMainValues();
582 return true;
583
584 }
585
586 if (ZeroTempOffsetsSP.isNameMatch(name))
587 {
588 ZeroTempOffsetsSP.update(states, names, n);
589 ZeroTempOffsetsSP.setState(IPS_BUSY);
590 zeroTempCalibrations();
591 ZeroTempOffsetsSP.setState(IPS_OK);
592 ZeroTempOffsetsSP[0].setState(ISS_OFF);
593 ZeroTempOffsetsSP.apply();
594 readOffsetValues();
595 return true;
596 }
597
598 if (TrackingModeSP.isNameMatch(name))
599 {
600 TrackingModeSP.update(states, names, n);
601 TrackingModeSP.setState(IPS_BUSY);
602 int mode = TrackingModeSP.findOnSwitchIndex();
603 setInt(mode, MDCP_SET_TRACKING_MODE, "Failed to set Tracking Mode");
604 TrackingModeSP.setState(IPS_OK);
605 TrackingModeSP.apply();
606 readOffsetValues();
607 return true;
608 }
609
610 if (FanModeSP.isNameMatch(name))
611 {
612 FanModeSP.update(states, names, n);
613 FanModeSP.setState(IPS_BUSY);
614 int mode = FanModeSP.findOnSwitchIndex();
615 setInt(mode, MDCP_SET_FAN_MODE, "Failed to set Fan Mode");
616 FanModeSP.setState(IPS_OK);
617 FanModeSP.apply();
618 readBoardFanValues();
619 return true;
620 }
621
622 if (EnableLCDDisplaySP.isNameMatch(name))
623 {
624 EnableLCDDisplaySP.update(states, names, n);
625 EnableLCDDisplaySP.setState(IPS_BUSY);
626 int mode = EnableLCDDisplaySP.findOnSwitchIndex();
627 setChoice(mode, MDCP_LCD_ENABLE, MDCP_LCD_DISABLE, "Failed to set LCD enable");
628 EnableLCDDisplaySP.setState(IPS_OK);
629 EnableLCDDisplaySP.apply();
630 readLCDDisplayValues();
631 return true;
632
633 }
634
635 if (LCDDisplayTempUnitsSP.isNameMatch(name))
636 {
637 LCDDisplayTempUnitsSP.update(states, names, n);
638 LCDDisplayTempUnitsSP.setState(IPS_BUSY);
639 int mode = LCDDisplayTempUnitsSP.findOnSwitchIndex();
640 setChoice(mode, MDCP_LCD_DISPLAY_FAHRENHEIT, MDCP_LCD_DISPLAY_CELSIUS, "Failed to set temp display mode");
641 LCDDisplayTempUnitsSP.setState(IPS_OK);
642 LCDDisplayTempUnitsSP.apply();
643 readLCDDisplayValues();
644 return true;
645
646 }
647
648 if (EEPROMSP.isNameMatch(name))
649 {
650 EEPROMSP.update(states, names, n);
651 EEPROMSP.setState(IPS_BUSY);
652 int mode = EEPROMSP.findOnSwitchIndex();
653 if (setChoice(mode, MDCP_SAVE_TO_EEPROM, MDCP_RESET_EEPROM_TO_DEFAULT, "Failed to Save/reset EEPROM"))
654 {
655 const char* message = mode == 1 ? "Saved to EEPPROM Successfully" : "Reset EEPROM to Default";
656 LOG_INFO(message);
657 }
658 readMainValues();
659 readOffsetValues();
660 readBoardFanValues();
661 readLCDDisplayValues();
662 EEPROMSP.setState(IPS_OK);
663 EEPROMSP.apply();
664 return true;
665
666 }
667 return INDI::DefaultDevice::ISNewSwitch(dev, name, states, names, n);
668}
669
670bool myDewControllerPro::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
671{
672 if (!dev || strcmp(dev, getDeviceName()))
673 return false;
674
675 // Process PowerInterface numbers
676 if (PI::processNumber(dev, name, values, names, n))
677 return true;
678
679 // Process WeatherInterface numbers
680 if (WI::processNumber(dev, name, values, names, n))
681 return true;
682
683 if (CH3_Manual_PowerNP.isNameMatch(name))
684 {
685 if (CH3_ModeSP.findOnSwitchIndex() == 3)
686 {
687 CH3_Manual_PowerNP.update(values, names, n);
688 CH3_Manual_PowerNP.setState(IPS_BUSY);
689 int power = CH3_Manual_PowerNP[0].getValue();
690 setInt(power, MDCP_SET_CH3_MANUAL_POWER, "Failed to set CH3 Power");
691 CH3_Manual_PowerNP.setState(IPS_OK);
692 CH3_Manual_PowerNP.apply();
693 }
694 else
695 {
696 LOG_INFO("Power can only be manually adjusted in Strap 3 manual mode");
697 }
698 readMainValues();
699 return true;
700 }
701
702 if (TemperatureOffsetsNP.isNameMatch(name))
703 {
704 TemperatureOffsetsNP.update(values, names, n);
705 TemperatureOffsetsNP.setState(IPS_BUSY);
706 int ch1 = TemperatureOffsetsNP[TEMP_PROBE_ONE_OFFSET].getValue();
707 int ch2 = TemperatureOffsetsNP[TEMP_PROBE_TWO_OFFSET].getValue();
708 int ch3 = TemperatureOffsetsNP[TEMP_PROBE_THREE_OFFSET].getValue();
709 int ambient = TemperatureOffsetsNP[AMBIENT_TEMP_PROBE_OFFSET].getValue();
710 setTempCalibrations(ch1, ch2, ch3, ambient);
711 TemperatureOffsetsNP.setState(IPS_OK);
712 TemperatureOffsetsNP.apply();
713 readOffsetValues();
714 return true;
715
716 }
717
718 if (TrackingModeOffsetNP.isNameMatch(name))
719 {
720 TrackingModeOffsetNP.update(values, names, n);
721 TrackingModeOffsetNP.setState(IPS_BUSY);
722 int offset = TrackingModeOffsetNP[0].getValue();
723 setInt(offset, MDCP_SET_TRACKING_MODE_OFFSET, "Failed to set Tracking Mode offsets");
724 TrackingModeOffsetNP.setState(IPS_OK);
725 TrackingModeOffsetNP.apply();
726 readOffsetValues();
727 return true;
728 }
729
730 if (FanTempTriggerNP.isNameMatch(name))
731 {
732 FanTempTriggerNP.update(values, names, n);
733 FanTempTriggerNP.setState(IPS_BUSY);
734 int tempOn = FanTempTriggerNP[FANTEMPON].getValue();
735 int tempOff = FanTempTriggerNP[FANTEMPOFF].getValue();
736 setFanTempTrigger(tempOn, tempOff);
737 FanTempTriggerNP.setState(IPS_OK);
738 FanTempTriggerNP.apply();
739 readBoardFanValues();
740 return true;
741
742 }
743 if (FanSpeedNP.isNameMatch(name))
744 {
745 FanSpeedNP.update(values, names, n);
746 FanSpeedNP.setState(IPS_BUSY);
747 int speed = FanSpeedNP[0].getValue();
748 setInt(speed, MDCP_SET_FAN_SPEED, "Failed to set Fan Speed");
749 FanSpeedNP.setState(IPS_OK);
750 FanSpeedNP.apply();
751 readBoardFanValues();
752 return true;
753
754 }
755
756 if (LCDPageRefreshNP.isNameMatch(name))
757 {
758 LCDPageRefreshNP.update(values, names, n);
759 LCDPageRefreshNP.setState(IPS_BUSY);
760 int time = LCDPageRefreshNP[0].getValue();
761 setInt(time, MDCP_SET_LCD_DISPLAY_TIME, "Failed to set LCD Page refressh");
762 LCDPageRefreshNP.setState(IPS_OK);
763 LCDPageRefreshNP.apply();
764 readLCDDisplayValues();
765 return true;
766
767 }
768
769 return INDI::DefaultDevice::ISNewNumber(dev, name, values, names, n);
770}
771
772bool myDewControllerPro::readMainValues()
773{
774
775 char resp[MDCP_RES_LEN];
776 float temp1, temp2, temp3, temp_ambient, dewpoint, humidity;
777
778
779 if (!sendCommand(MDCP_GET_PROBE_TEMPS, resp))
780 {
781 LOG_INFO(resp);
782 return false;
783 }
784
785 if (sscanf(resp, MDCP_GET_TEMP_RESPONSE, &temp1, &temp2, &temp3) == 3)
786 {
787 TemperaturesNP[PROBE_1].setValue(temp1);
788 TemperaturesNP[PROBE_2].setValue(temp2);
789 TemperaturesNP[PROBE_3].setValue(temp3);
790 TemperaturesNP.setState(IPS_OK);
791 TemperaturesNP.apply();
792 }
793
794 if (!sendCommand(MDCP_GET_AMB_TEMP, resp))
795 {
796 LOG_INFO(resp);
797 return false;
798 }
799
800 if (sscanf(resp, MDCP_GET_AMB_TEMP_REPSONSE, &temp_ambient) == 1)
801 {
802 TemperaturesNP[AMBIENT_PROBE].setValue(temp_ambient);
803 TemperaturesNP.setState(IPS_OK);
804 TemperaturesNP.apply();
805 }
806
807 if (!sendCommand(MDCP_GET_BOARD_TEMP, resp))
808 {
809 LOG_INFO(resp);
810 return false;
811 }
812
813 if (sscanf(resp, MDCP_GET_BOARD_TEMP_RESPONSE, &temp_ambient) == 1)
814 {
815 TemperaturesNP[BOARD_PROBE].setValue(temp_ambient);
816 TemperaturesNP.setState(IPS_OK);
817 TemperaturesNP.apply();
818 }
819
820 if (!sendCommand(MDCP_GET_REL_HUMIDITY, resp))
821 {
822 LOG_INFO(resp);
823 return false;
824 }
825
826 if (sscanf(resp, MDCP_GET_REL_HUMIDITY_REPSONSE, &humidity) == 1)
827 {
828
829 HumidityNP[0].setValue(humidity);
830 HumidityNP.setState(IPS_OK);
831 HumidityNP.apply();
832 }
833 else
834 {
835 LOG_INFO(resp);
836 }
837
838 if (!sendCommand(MDCP_GET_DEW_POINT, resp))
839 {
840 LOG_INFO(resp);
841 return false;
842 }
843
844 if (sscanf(resp, MDCP_GET_DEW_POINT_RESPONSE, &dewpoint) == 1)
845 {
846 DewpointNP[0].setValue(dewpoint);
847 DewpointNP.setState(IPS_OK);
848 DewpointNP.apply();
849 }
850
851 int power1, power2, power3;
852
853 if (!sendCommand(MDCP_GET_CHANNEL_POWER, resp))
854 {
855 LOG_INFO(resp);
856 return false;
857 }
858
859 if (sscanf(resp, MDCP_GET_CHANNEL_POWER_RESPONSE, &power1, &power2, &power3) == 3)
860 {
861 OutputsNP[DEW_STRAP_ONE_POWER].setValue(power1);
862 OutputsNP[DEW_STRAP_TWO_POWER].setValue(power2);
863 OutputsNP[DEW_STRAP_THREE_POWER].setValue(power3);
864 OutputsNP.setState(IPS_OK);
865 OutputsNP.apply();
866 CH3_Manual_PowerNP[0].setValue(power3);
867 CH3_Manual_PowerNP.apply();
868 }
869 else
870 {
871 LOG_INFO(resp);
872 }
873
874 int mode;
875
876 if (!sendCommand(MDCP_GET_CH3_SETTINGS, resp))
877 {
878 LOG_INFO(resp);
879 return false;
880 }
881
882 if (sscanf(resp, MDCP_GET_CH3_SETTINGS_RESPONSE, &mode) == 1)
883 {
884 CH3_ModeSP.reset();
885 CH3_ModeSP[mode].setState(ISS_ON);
886 CH3_ModeSP.setState(IPS_OK);
887 CH3_ModeSP.apply();
888 }
889 else
890 {
891 LOG_INFO(resp);
892 }
893
894 if (!sendCommand(MDCP_GET_FAN_SPEED, resp))
895 {
896 LOG_INFO(resp);
897 return false;
898 }
899 int fanSpeed;
900
901 if (sscanf(resp, "F%d$", &fanSpeed) == 1)
902 {
903 FanSpeedNP[0].setValue(fanSpeed);
904 FanSpeedNP.setState(IPS_OK);
905 FanSpeedNP.apply();
906 }
907
908 return true;
909}
910
911bool myDewControllerPro::readOffsetValues()
912{
913 char resp[MDCP_RES_LEN];
914 float temp1, temp2, temp3;
915
916
917 if (!sendCommand(MDCP_GET_TEMP_OFFSETS, resp))
918 {
919 LOG_INFO(resp);
920 return false;
921 }
922
923 if (sscanf(resp, MDCP_GET_TEMP_OFFSETS_RESPONSE, &temp1, &temp2, &temp3) == 3)
924 {
925 TemperatureOffsetsNP[TEMP_PROBE_ONE_OFFSET].setValue(temp1);
926 TemperatureOffsetsNP[TEMP_PROBE_TWO_OFFSET].setValue(temp2);
927 TemperatureOffsetsNP[TEMP_PROBE_THREE_OFFSET].setValue(temp3);
928 TemperatureOffsetsNP.setState(IPS_OK);
929 TemperatureOffsetsNP.apply();
930 }
931
932 if (!sendCommand(MDCP_GET_AMB_TEMP_OFFSET, resp))
933 {
934 LOG_INFO(resp);
935 return false;
936 }
937 int atBias = 0;
938 if (sscanf(resp, MDCP_GET_AMB_TEMP_OFFSET_RESPONSE, &atBias) == 1)
939 {
940 TemperatureOffsetsNP[AMBIENT_TEMP_PROBE_OFFSET].setValue(atBias);
941 TemperatureOffsetsNP.setState(IPS_OK);
942 TemperatureOffsetsNP.apply();
943 }
944 if (!sendCommand(MDCP_GET_TRACKING_MODE, resp))
945 {
946 LOG_INFO(resp);
947 return false;
948 }
949 int mode;
950
951 if (sscanf(resp, MDCP_GET_TRACKING_MODE_RESPONSE, &mode) == 1)
952 {
953 TrackingModeSP.reset();
954 TrackingModeSP[mode].setState(ISS_ON);
955 TrackingModeSP.setState(IPS_OK);
956 TrackingModeSP.apply();
957 }
958
959 if (!sendCommand(MDCP_GET_TRACKING_MODE_OFFSET, resp))
960 {
961 LOG_INFO(resp);
962 return false;
963 }
964 int toffset = 0;
965
966 if (sscanf(resp, "y%d$", &toffset) == 1)
967 {
968 TrackingModeOffsetNP[0].setValue(toffset);
969 TrackingModeOffsetNP.setState(IPS_OK);
970 TrackingModeOffsetNP.apply();
971 }
972 return true;
973}
974
975
976bool myDewControllerPro::readBoardFanValues()
977{
978 char resp[MDCP_RES_LEN];
979
980 if (!sendCommand(MDCP_GET_FAN_SPEED, resp))
981 {
982 LOG_INFO(resp);
983 return false;
984 }
985 int fanSpeed;
986
987 if (sscanf(resp, "F%d$", &fanSpeed) == 1)
988 {
989 FanSpeedNP[0].setValue(fanSpeed);
990 FanSpeedNP.setState(IPS_OK);
991 FanSpeedNP.apply();
992 }
993
994 if (!sendCommand(MDCP_GET_FAN_MODE, resp))
995 {
996 LOG_INFO(resp);
997 return false;
998 }
999 int mode;
1000 if (sscanf(resp, MDCP_GET_FAN_MODE_RESPONSE, &mode) == 1)
1001 {
1002 FanModeSP.reset();
1003 FanModeSP[mode].setState(ISS_ON);
1004 FanModeSP.setState(IPS_OK);
1005 FanModeSP.apply();
1006 }
1007
1008 if (!sendCommand(MDCP_GET_FAN_ON_TEMP, resp))
1009 {
1010 LOG_INFO(resp);
1011 return false;
1012 }
1013
1014 int fanTemp;
1015
1016 if (sscanf(resp, MDCP_GET_FAN_ON_TEMP_RESPONSE, &fanTemp) == 1)
1017 {
1018 FanTempTriggerNP[FANTEMPON].setValue(fanTemp);
1019 FanTempTriggerNP.setState(IPS_OK);
1020 FanTempTriggerNP.apply();
1021 }
1022
1023 if (!sendCommand(MDCP_GET_FAN_OFF_TEMP, resp))
1024 {
1025 LOG_INFO(resp);
1026 return false;
1027 }
1028
1029 if (sscanf(resp, MDCP_GET_FAN_OFF_TEMP_RESPONSE, &fanTemp) == 1)
1030 {
1031 FanTempTriggerNP[FANTEMPOFF].setValue(fanTemp);
1032 FanTempTriggerNP.setState(IPS_OK);
1033 FanTempTriggerNP.apply();
1034 }
1035
1036 return true;
1037}
1038
1039bool myDewControllerPro::readLCDDisplayValues()
1040{
1041 char resp[MDCP_RES_LEN];
1042 int value;
1043
1044 if (!sendCommand(MDCP_GET_LCD_DISPLAY_TIME, resp))
1045 {
1046 LOG_INFO(resp);
1047 return false;
1048 }
1049 if (sscanf(resp, MDCP_GET_LCD_DISPLAY_TIME_RESPONSE, &value) == 1)
1050 {
1051 LCDPageRefreshNP[0].setValue(value);
1052 LCDPageRefreshNP.setState(IPS_OK);
1053 LCDPageRefreshNP.apply();
1054 }
1055
1056 if (!sendCommand(MDCP_GET_LCD_STATE, resp))
1057 {
1058 LOG_INFO(resp);
1059 return false;
1060 }
1061
1062 if (sscanf(resp, MDCP_GET_LCD_STATE_RESPONSE, &value) == 1)
1063 {
1064 EnableLCDDisplaySP.reset();
1065 EnableLCDDisplaySP[value].setState(ISS_ON);
1066 EnableLCDDisplaySP.setState(IPS_OK);
1067 EnableLCDDisplaySP.apply();
1068 }
1069
1070 if (!sendCommand(MDCP_GET_TEMP_DISPLAY, resp))
1071 {
1072 LOG_INFO(resp);
1073 return false;
1074 }
1075
1076 if (sscanf(resp, MDCP_GET_TEMP_DISPLAY_RESPONSE, &value) == 1)
1077 {
1078 LCDDisplayTempUnitsSP.reset();
1079 LCDDisplayTempUnitsSP[value - 1].setState(ISS_ON);
1080 LCDDisplayTempUnitsSP.setState(IPS_OK);
1081 LCDDisplayTempUnitsSP.apply();
1082 }
1083 return true;
1084}
1085
1087{
1088 if (!isConnected())
1089 {
1090 return;
1091 }
1092
1093 // Get temperatures etc.
1094 readMainValues();
1096}
double humidity
void registerHandshake(std::function< bool()> callback)
registerHandshake Register a handshake function to be called once the initial connection to the devic...
The Serial class manages connection with serial devices including Bluetooth. Serial communication is ...
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
void addPollPeriodControl()
Add Polling period control to the driver.
void addConfigurationControl()
Add Configuration control to the driver.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process the client newSwitch command.
void registerConnection(Connection::Interface *newConnection)
registerConnection Add new connection plugin to the existing connection pool. The connection type sha...
void setDefaultPollingPeriod(uint32_t msec)
setDefaultPollingPeriod Change the default polling period to call TimerHit() function in the driver.
void setDriverInterface(uint32_t value)
setInterface Set driver interface. By default the driver interface is set to GENERAL_DEVICE....
void setVersion(uint16_t vMajor, uint16_t vMinor)
Set driver version information to be defined in DRIVER_INFO property as vMajor.vMinor.
virtual bool loadConfig(bool silent=false, const char *property=nullptr)
Load the last saved configuration file.
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
void defineProperty(INumberVectorProperty *property)
uint32_t getCurrentPollingPeriod() const
getCurrentPollingPeriod Return the current polling period.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process the client newNumber command.
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
void addDebugControl()
Add Debug control to the driver.
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.
bool processNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process Power number properties.
void initProperties(const char *groupName, size_t nPowerPorts=0, size_t nDewPorts=0, size_t nVariablePorts=0, size_t nAutoDewPorts=0, size_t nUSBPorts=0)
Initialize Power properties. It is recommended to call this function within initProperties() of your ...
bool processSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process Power switch properties.
bool updateProperties()
updateProperties Define or Delete Power properties based on the connection status of the base device
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
void save(FILE *f) const
save Save property to configuration file.
bool isNameMatch(const char *otherName) const
bool update(const double values[], const char *const names[], int n)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
bool update(const ISState states[], const char *const names[], int n)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, ISRule rule, double timeout, IPState state)
void addParameter(std::string name, std::string label, double numMinOk, double numMaxOk, double percWarning, bool flipWarning=false)
Add a physical weather measurable parameter to the weather driver.
bool processSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process weather switch properties.
bool setCriticalParameter(std::string name)
setCriticalParameter Set parameter that is considered critical to the operation of the observatory....
bool processNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process weather number properties.
virtual bool saveConfigItems(FILE *fp)
saveConfigItems Save parameters ranges in the config file.
void initProperties(const char *statusGroup, const char *paramsGroup)
Initialize focuser properties. It is recommended to call this function within initProperties() of you...
bool updateProperties()
updateProperties Define or Delete Rotator properties based on the connection status of the base devic...
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual const char * getDefaultName() override
virtual bool SetDewPort(size_t port, bool enabled, double dutyCycle) override
SetDewPort Set DEW/Dew port duty cycle.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
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 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.
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
const char * OPTIONS_TAB
OPTIONS_TAB Where all the driver's options are located. Those may include auxiliary controls,...
ISState
Switch state.
Definition indiapi.h:148
@ ISS_OFF
Definition indiapi.h:149
@ ISS_ON
Definition indiapi.h:150
@ IP_RW
Definition indiapi.h:184
@ IP_RO
Definition indiapi.h:182
@ IP_WO
Definition indiapi.h:183
@ IPS_BUSY
Definition indiapi.h:161
@ IPS_IDLE
Definition indiapi.h:159
@ IPS_OK
Definition indiapi.h:160
@ ISR_1OFMANY
Definition indiapi.h:171
@ ISR_NOFMANY
Definition indiapi.h:173
@ ISR_ATMOST1
Definition indiapi.h:172
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
Definition indicom.c:418
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
Definition indicom.c:1243
int tty_nread_section(int fd, char *buf, int nsize, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
Definition indicom.c:759
Implementations for common driver routines.
@ TTY_OK
Definition indicom.h:54
#define INDI_UNUSED(x)
Definition indidevapi.h:132
#define MAXRBUF
Definition indidriver.c:52
#define LOGF_DEBUG(fmt,...)
Definition indilogger.h:83
#define LOGF_ERROR(fmt,...)
Definition indilogger.h:80
#define LOG_INFO(txt)
Definition indilogger.h:74
#define MYDEWHEATERPRO_TIMEOUT
#define LCD_DISPLAY_TAB
#define BOARD_FAN_TAB
#define TEMPERATURE_OFFSETS_TAB
std::unique_ptr< myDewControllerPro > mydewcontrollerpro(new myDewControllerPro())
#define MDCP_GET_TEMP_DISPLAY_RESPONSE
#define MDCP_GET_PROBE_TEMPS
#define MDCP_GET_AMB_TEMP_OFFSET
#define MDCP_GET_FAN_ON_TEMP_RESPONSE
#define MDCP_SET_TRACKING_MODE
#define MDCP_SET_TRACKING_MODE_OFFSET
#define MDCP_SAVE_TO_EEPROM
#define MDCP_GET_TRACKING_MODE
#define MDCP_GET_CH3_SETTINGS_RESPONSE
#define MDCP_GET_TRACKING_MODE_OFFSET
#define MDCP_GET_BOARD_TEMP_RESPONSE
#define MDCP_GET_CHANNEL_POWER_RESPONSE
#define MDCP_GET_FAN_OFF_TEMP_RESPONSE
#define MDCP_GET_AMB_TEMP
#define MDCP_GET_FAN_OFF_TEMP
#define MDCP_GET_VERSION
#define MDCP_CLEAR_TEMP_OFFSETS
#define MDCP_GET_TEMP_DISPLAY
#define MDCP_GET_REL_HUMIDITY_REPSONSE
#define MDCP_LCD_DISABLE
#define MDCP_GET_REL_HUMIDITY
#define MDCP_LCD_ENABLE
#define MDCP_GET_TEMP_OFFSETS
#define MDCP_GET_FAN_MODE_RESPONSE
#define MDCP_CANCEL_BOOST
#define MDCP_GET_NUMBER_OF_PROBES
#define MDCP_LCD_DISPLAY_CELSIUS
#define MDCP_SET_LCD_DISPLAY_TIME
#define MDCP_LCD_DISPLAY_FAHRENHEIT
#define MDCP_SET_CH3_SETTINGS
#define MDCP_GET_LCD_STATE
#define MDCP_SET_CH3_MANUAL_POWER
#define MDCP_GET_FAN_SPEED
#define MDCP_GET_AMB_TEMP_REPSONSE
#define MDCP_CMD_LEN
#define MDCP_GET_DEW_POINT_RESPONSE
#define MDCP_BOOST_CH1
#define MDCP_GET_AMB_TEMP_OFFSET_RESPONSE
#define MDCP_SET_TEMP_CH1_OFFSET
#define MDCP_IDENTIFY_RESPONSE
#define MDCP_GET_LCD_DISPLAY_TIME
#define MDCP_SET_FAN_SPEED
#define MDCP_SET_TEMP_CH2_OFFSET
#define MDCP_GET_CHANNEL_POWER
#define MDCP_GET_LCD_STATE_RESPONSE
#define MDCP_GET_FAN_ON_TEMP
#define MDCP_GET_FAN_MODE
#define MDCP_GET_TEMP_RESPONSE
#define MDCP_SET_FAN_MODE
#define MDCP_GET_LCD_DISPLAY_TIME_RESPONSE
#define MDCP_RES_LEN
#define MDCP_GET_BOARD_TEMP
#define MDCP_GET_TRACKING_MODE_RESPONSE
#define MDCP_SET_FAN_ON_TEMP
#define MDCP_GET_CH3_SETTINGS
#define MDCP_BOOST_CH2
#define MDCP_GET_DEW_POINT
#define MDCP_SET_TEMP_CH3_OFFSET
#define MDCP_SET_FAN_OFF_TEMP
#define MDCP_RESET_EEPROM_TO_DEFAULT
#define MDCP_GET_TEMP_OFFSETS_RESPONSE
#define MDCP_SET_AMB_TEMP_OFFSET
Namespace to encapsulate INDI client, drivers, and mediator classes.
uint8_t cmd[4]
Definition pwc-ioctl.h:2