Instrument Neutral Distributed Interface INDI 2.2.5
wandererbox_pro_v3.cpp
Go to the documentation of this file.
1/*******************************************************************************
2 Copyright(c) 2024 Frank Wang. All rights reserved.
3
4 WandererBox Pro V3
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 "wandererbox_pro_v3.h"
26#include "indicom.h"
28#include <cerrno>
29#include <cstring>
30#include <string>
31#include <memory>
32#include <termios.h>
33#include <unistd.h>
34#include <inttypes.h>
35#include <sys/ioctl.h>
36#include <cmath>
37
38// We declare an auto pointer to WandererBoxProV3.
39static std::unique_ptr<WandererBoxProV3> wandererboxprov3(new WandererBoxProV3());
40
41
42
43WandererBoxProV3::WandererBoxProV3() : INDI::DefaultDevice(), INDI::WeatherInterface(this)
44{
45 setVersion(1, 1);
46}
47
49{
50
53
54 WI::initProperties(ENVIRONMENT_TAB, ENVIRONMENT_TAB);
55
57
58
59 // Calibrate
60 CalibrateSP[0].fill("Calibrate", "Calibrate Current", ISS_OFF);
61 CalibrateSP.fill(getDeviceName(), "Calibrate_DEVICE", "Calibrate Current", MAIN_CONTROL_TAB, IP_RW, ISR_ATMOST1,60, IPS_IDLE);
62
63 // Power Monitor
64 PowerMonitorNP[VOLTAGE].fill("VOLTAGE", "Voltage (V)", "%4.2f", 0, 999, 100, 0);
65 PowerMonitorNP[TOTAL_CURRENT].fill("TOTAL_CURRENT", "Total Current (A)", "%4.2f", 0, 999, 100, 0);
66 PowerMonitorNP[V19_CURRENT].fill("V19_CURRENT", "DC2 Current (A))", "%4.2f", 0, 999, 100, 0);
67 PowerMonitorNP[AR_CURRENT].fill("AR_CURRENT", "DC3-4 Current (A)", "%4.2f", 0, 999, 100, 0);
68 PowerMonitorNP.fill(getDeviceName(), "POWER_Monitor", "Power Monitor", MAIN_CONTROL_TAB, IP_RO,60, IPS_IDLE);
69
70
71 // USB31 Control
72 usb31ControlSP[INDI_ENABLED].fill("INDI_ENABLED", "On", ISS_OFF);
73 usb31ControlSP[INDI_DISABLED].fill("INDI_DISABLED", "Off", ISS_OFF);
74 usb31ControlSP.fill(getDeviceName(), "USB3.0_1", "USB3.0_1", MAIN_CONTROL_TAB, IP_RW,ISR_1OFMANY, 60, IPS_IDLE);
75
76
77 // USB32 Control
78 usb32ControlSP[INDI_ENABLED].fill("INDI_ENABLED", "On", ISS_OFF);
79 usb32ControlSP[INDI_DISABLED].fill("INDI_DISABLED", "Off", ISS_OFF);
80 usb32ControlSP.fill(getDeviceName(), "USB3.0_2", "USB3.0_2", MAIN_CONTROL_TAB, IP_RW,ISR_1OFMANY, 60, IPS_IDLE);
81
82
83 // USB33 Control
84 usb33ControlSP[INDI_ENABLED].fill("INDI_ENABLED", "On", ISS_OFF);
85 usb33ControlSP[INDI_DISABLED].fill("INDI_DISABLED", "Off", ISS_OFF);
86 usb33ControlSP.fill(getDeviceName(), "USB3.0_3", "USB3.0_3", MAIN_CONTROL_TAB, IP_RW,ISR_1OFMANY, 60, IPS_IDLE);
87
88 // USB21 Control
89 usb21ControlSP[INDI_ENABLED].fill("INDI_ENABLED", "On", ISS_OFF);
90 usb21ControlSP[INDI_DISABLED].fill("INDI_DISABLED", "Off", ISS_OFF);
91 usb21ControlSP.fill(getDeviceName(), "USB2.0_1-3", "USB2.0_1-3", MAIN_CONTROL_TAB, IP_RW,ISR_1OFMANY, 60, IPS_IDLE);
92
93 // USB22 Control
94 usb22ControlSP[INDI_ENABLED].fill("INDI_ENABLED", "On", ISS_OFF);
95 usb22ControlSP[INDI_DISABLED].fill("INDI_DISABLED", "Off", ISS_ON);
96 usb22ControlSP.fill(getDeviceName(), "USB2.0_4-6", "USB2.0_4-6", MAIN_CONTROL_TAB, IP_RW,ISR_1OFMANY, 60, IPS_IDLE);
97
98 // DC567
99
100
101 dc5ControlNP[DC5].fill( "DC5", "Dew Heater (PWM)", "%.2f", 0, 255, 5, 0);
102 dc5ControlNP.fill(getDeviceName(), "PWM", "DC5", DC5_TAB, IP_RW, 60, IPS_IDLE);
103
104 dc6ControlNP[DC6].fill( "DC6", "Dew Heater (PWM)", "%.2f", 0, 255, 5, 0);
105 dc6ControlNP.fill( getDeviceName(), "DC6", "DC6", DC6_TAB, IP_RW, 60, IPS_IDLE);
106
107 dc7ControlNP[DC7].fill( "DC7", "Dew Heater (PWM)", "%.2f", 0, 255, 5, 0);
108 dc7ControlNP.fill(getDeviceName(), "DC7", "DC7", DC7_TAB, IP_RW, 60, IPS_IDLE);
109 // DC34SET
110 setDC34voltageNP[setDC34voltage].fill( "DC34SET", "Adjustable Voltage", "%.2f", 5, 13.2, 0.1, 0);
111 setDC34voltageNP.fill(getDeviceName(), "DC34voltageSET", "Set DC3-4", MAIN_CONTROL_TAB, IP_RW, 60, IPS_IDLE);
112 // DC3-4 Control
113 dc3_4ControlSP[INDI_ENABLED].fill( "INDI_ENABLED", "On", ISS_OFF);
114 dc3_4ControlSP[INDI_DISABLED].fill( "INDI_DISABLED", "Off", ISS_ON);
115 dc3_4ControlSP.fill(getDeviceName(), "DC3-4", "DC3-4", MAIN_CONTROL_TAB, IP_RW,ISR_1OFMANY, 60, IPS_IDLE);
116
117 // DC8-9 Control
118 dc8_9ControlSP[INDI_ENABLED].fill( "INDI_ENABLED", "On", ISS_OFF);
119 dc8_9ControlSP[INDI_DISABLED].fill( "INDI_DISABLED", "Off", ISS_ON);
120 dc8_9ControlSP.fill(getDeviceName(), "DC8-9", "DC8-9", MAIN_CONTROL_TAB, IP_RW,ISR_1OFMANY, 60, IPS_IDLE);
121
122 // DC10-11 Control
123 dc10_11ControlSP[INDI_ENABLED].fill( "INDI_ENABLED", "On", ISS_OFF);
124 dc10_11ControlSP[INDI_DISABLED].fill( "INDI_DISABLED", "Off", ISS_ON);
125 dc10_11ControlSP.fill(getDeviceName(), "DC10-11", "DC10-11", MAIN_CONTROL_TAB, IP_RW,ISR_1OFMANY, 60, IPS_IDLE);
126
127 // DC5 TEMP Difference Control
128 dc5diffSP[DC5_Manual].fill( "Manual", "Manual", ISS_ON);
129 dc5diffSP[DC5_DPD_Mode].fill( "DPD_Mode", "DPD Mode", ISS_OFF);
130 dc5diffSP[DC5_CT_Mode].fill( "CT_Mode", "CT Mode", ISS_OFF);
131 dc5diffSP.fill(getDeviceName(), "DC5_DIFF", "DC5 Dew Mode", DC5_TAB, IP_RW,ISR_1OFMANY, 60, IPS_IDLE);
132
133 dc5diffSETNP[DC5DIFFSET].fill( "DC5 Auto Control", "Dew Point Difference(C)", "%.2f", 10, 30, 1, 0);
134 dc5diffSETNP.fill(getDeviceName(), "DC5_DIFF_SET", "DPD Mode", DC5_TAB, IP_RW, 60, IPS_IDLE);
135
136 dc5constSETNP[DC5CONSTSET].fill( "DC5 Auto Control", "Temperature(C)", "%.2f", 0, 40, 1, 0);
137 dc5constSETNP.fill(getDeviceName(), "DC5_CONST_SET", "CT Mode", DC5_TAB, IP_RW, 60, IPS_IDLE);
138
139 // DC6 TEMP Difference Control
140 dc6diffSP[DC6_Manual].fill( "Manual", "Manual", ISS_ON);
141 dc6diffSP[DC6_DPD_Mode].fill( "DPD_Mode", "DPD Mode", ISS_OFF);
142 dc6diffSP[DC6_CT_Mode].fill( "CT_Mode", "CT Mode", ISS_OFF);
143 dc6diffSP.fill(getDeviceName(), "DC6_DIFF", "DC6 Dew Mode", DC6_TAB, IP_RW,ISR_1OFMANY, 60, IPS_IDLE);
144
145 dc6diffSETNP[DC6DIFFSET].fill( "DC6 Auto Control", "Dew Point Difference(C)", "%.2f", 10, 30, 1, 0);
146 dc6diffSETNP.fill(getDeviceName(), "DC6_DIFF_SET", "DPD Mode", DC6_TAB, IP_RW, 60, IPS_IDLE);
147
148 dc6constSETNP[DC6CONSTSET].fill( "DC6 Auto Control", "Temperature(C)", "%.2f", 0, 40, 1, 0);
149 dc6constSETNP.fill(getDeviceName(), "DC6_CONST_SET", "CT Mode", DC6_TAB, IP_RW, 60, IPS_IDLE);
150
151 // DC7 TEMP Difference Control
152 dc7diffSP[DC7_Manual].fill( "Manual", "Manual", ISS_ON);
153 dc7diffSP[DC7_DPD_Mode].fill( "DPD_Mode", "DPD Mode", ISS_OFF);
154 dc7diffSP[DC7_CT_Mode].fill( "CT_Mode", "CT Mode", ISS_OFF);
155 dc7diffSP.fill(getDeviceName(), "DC7_DIFF", "DC7 Dew Mode", DC7_TAB, IP_RW,ISR_1OFMANY, 60, IPS_IDLE);
156
157 dc7diffSETNP[DC7DIFFSET].fill( "DC7 Auto Control", "Dew Point Difference(C)", "%.2f", 10, 30, 1, 0);
158 dc7diffSETNP.fill(getDeviceName(), "DC7_DIFF_SET", "DPD Mode", DC7_TAB, IP_RW, 60, IPS_IDLE);
159
160 dc7constSETNP[DC7CONSTSET].fill( "DC7 Auto Control", "Temperature(C)", "%.2f", 0, 40, 1, 0);
161 dc7constSETNP.fill(getDeviceName(), "DC7_CONST_SET", "CT Mode", DC7_TAB, IP_RW, 60, IPS_IDLE);
162
163 //ENV
164 ENVMonitorNP[Probe1_Temp].fill( "Probe1_Temp", "Probe1 Temperature (C)", "%4.2f", 0, 999, 100, 0);
165 ENVMonitorNP[Probe2_Temp].fill( "Probe2_Temp", "Probe2 Temperature (C)", "%4.2f", 0, 999, 100, 0);
166 ENVMonitorNP[Probe3_Temp].fill( "Probe3_Temp", "Probe3 Temperature (C)", "%4.2f", 0, 999, 100, 0);
167 ENVMonitorNP[ENV_Humidity].fill( "ENV_Humidity", "Ambient Humidity %", "%4.2f", 0, 999, 100, 0);
168 ENVMonitorNP[ENV_Temp].fill( "ENV_Temp", "Ambient Temperature (C)", "%4.2f", 0, 999, 100, 0);
169 ENVMonitorNP[DEW_Point].fill( "DEW_Point", "Dew Point (C)", "%4.2f", 0, 999, 100, 0);
170 ENVMonitorNP.fill(getDeviceName(), "ENV_Monitor", "Environment", SENSORS_TAB, IP_RO,60, IPS_IDLE);
171
172 // Weather Interface Parameters
173 addParameter("WEATHER_TEMPERATURE", "Temperature (C)", -15, 35, 15);
174 addParameter("WEATHER_HUMIDITY", "Humidity %", 0, 100, 15);
175 addParameter("WEATHER_DEWPOINT", "Dew Point (C)", 0, 100, 15);
176 setCriticalParameter("WEATHER_TEMPERATURE");
177 serialConnection = new Connection::Serial(this);
179 serialConnection->registerHandshake([&]()
180 {
181 return getData();
182 });
183 registerConnection(serialConnection);
184
185 return true;
186}
187
188bool WandererBoxProV3::getData()
189{
190 try
191 {
192 PortFD = serialConnection->getPortFD();
193 tcflush(PortFD, TCIOFLUSH);
194 int nbytes_read_name = 0,rc=-1;
195 char name[64] = {0};
196
197 //Device Model//////////////////////////////////////////////////////////////////////////////////////////////////////
198 if ((rc = tty_read_section(PortFD, name, 'A', 3, &nbytes_read_name)) != TTY_OK)
199 {
200 char errorMessage[MAXRBUF];
201 tty_error_msg(rc, errorMessage, MAXRBUF);
202 LOGF_INFO("No data received, the device may not be WandererBox Pro V3, please check the serial port!","Updated");
203 LOGF_ERROR("Device read error: %s", errorMessage);
204 return false;
205 }
206 name[nbytes_read_name - 1] = '\0';
207 if(strcmp(name, "ZXWBPlusV3")==0||strcmp(name, "WandererCoverV4")==0||strcmp(name, "UltimateV2")==0||strcmp(name, "PlusV2")==0)
208 {
209 LOGF_INFO("The device is not WandererBox Pro V3!","Updated");
210 return false;
211 }
212 if(strcmp(name, "ZXWBProV3")!=0)
213 {
214 LOGF_ERROR("Device is not WandererBox Pro V3 (got '%s'). Wrong port or device.", name);
215 return false;
216 }
217 // Frimware version/////////////////////////////////////////////////////////////////////////////////////////////
218 int nbytes_read_version = 0;
219 char version[64] = {0};
220 tty_read_section(PortFD, version, 'A', 5, &nbytes_read_version);
221
222 version[nbytes_read_version - 1] = '\0';
223 firmware=std::atoi(version);
224
225
226 // Temp probe 1//////////////////////////////////////////////////////////////////////////////////////////
227 char temp1[64] = {0};
228 int nbytes_read_temp1= 0;
229 tty_read_section(PortFD, temp1, 'A', 5, &nbytes_read_temp1);
230 temp1[nbytes_read_temp1 - 1] = '\0';
231 temp1read = std::strtod(temp1,NULL);
232
233 // Temp probe 2//////////////////////////////////////////////////////////////////////////////////////////
234 char temp2[64] = {0};
235 int nbytes_read_temp2= 0;
236 tty_read_section(PortFD, temp2, 'A', 5, &nbytes_read_temp2);
237 temp2[nbytes_read_temp2 - 1] = '\0';
238 temp2read = std::strtod(temp2,NULL);
239
240 // Temp probe 3//////////////////////////////////////////////////////////////////////////////////////////
241 char temp3[64] = {0};
242 int nbytes_read_temp3= 0;
243 tty_read_section(PortFD, temp3, 'A', 5, &nbytes_read_temp3);
244 temp3[nbytes_read_temp3 - 1] = '\0';
245 temp3read = std::strtod(temp3,NULL);
246
247 // DHTH//////////////////////////////////////////////////////////////////////////////////////////
248 char DHTH[64] = {0};
249 int nbytes_read_DHTH= 0;
250 tty_read_section(PortFD, DHTH, 'A', 5, &nbytes_read_DHTH);
251 DHTH[nbytes_read_DHTH - 1] = '\0';
252 DHTHread = std::strtod(DHTH,NULL);
253
254 // DHTT//////////////////////////////////////////////////////////////////////////////////////////
255 char DHTT[64] = {0};
256 int nbytes_read_DHTT= 0;
257 tty_read_section(PortFD, DHTT, 'A', 5, &nbytes_read_DHTT);
258 DHTT[nbytes_read_DHTT - 1] = '\0';
259 DHTTread = std::strtod(DHTT,NULL);
260 updateENV(temp1read,temp2read,temp3read,DHTHread,DHTTread);
261
262 // Total current//////////////////////////////////////////////////////////////////////////////////////////
263 char Tcurrent[64] = {0};
264 int nbytes_read_Tcurrent= 0;
265 tty_read_section(PortFD, Tcurrent, 'A', 5, &nbytes_read_Tcurrent);
266 Tcurrent[nbytes_read_Tcurrent - 1] = '\0';
267 Tcurrentread = std::strtod(Tcurrent,NULL);
268
269 // 19V current//////////////////////////////////////////////////////////////////////////////////////////
270 char V19current[64] = {0};
271 int nbytes_read_V19current= 0;
272 tty_read_section(PortFD, V19current, 'A', 5, &nbytes_read_V19current);
273 V19current[nbytes_read_V19current - 1] = '\0';
274 V19currentread = std::strtod(V19current,NULL);
275
276
277 // Adjustable Regulator current//////////////////////////////////////////////////////////////////////////////////////////
278 char ARcurrent[64] = {0};
279 int nbytes_read_ARcurrent= 0;
280 tty_read_section(PortFD, ARcurrent, 'A', 5, &nbytes_read_ARcurrent);
281 ARcurrent[nbytes_read_ARcurrent - 1] = '\0';
282 ARcurrentread = std::strtod(ARcurrent,NULL);
283
284
285 // Voltage//////////////////////////////////////////////////////////////////////////////////////////
286 char voltage[64] = {0};
287 int nbytes_read_voltage= 0;
288 tty_read_section(PortFD, voltage, 'A', 5, &nbytes_read_voltage);
289 voltage[nbytes_read_voltage - 1] = '\0';
290 voltageread = std::strtod(voltage,NULL);
291 updatePower(Tcurrentread,V19currentread,ARcurrentread,voltageread);
292
293 // USB31//////////////////////////////////////////////////////////////////////////////////////////
294 char USB31[64] = {0};
295 int nbytes_read_USB31= 0;
296 tty_read_section(PortFD, USB31, 'A', 5, &nbytes_read_USB31);
297 USB31[nbytes_read_USB31 - 1] = '\0';
298 USB31read = std::stoi(USB31);
299 updateUSB31(USB31read);
300
301 // USB32//////////////////////////////////////////////////////////////////////////////////////////
302 char USB32[64] = {0};
303 int nbytes_read_USB32= 0;
304 tty_read_section(PortFD, USB32, 'A', 5, &nbytes_read_USB32);
305 USB32[nbytes_read_USB32 - 1] = '\0';
306 USB32read = std::stoi(USB32);
307 updateUSB32(USB32read);
308
309 // USB33//////////////////////////////////////////////////////////////////////////////////////////
310 char USB33[64] = {0};
311 int nbytes_read_USB33= 0;
312 tty_read_section(PortFD, USB33, 'A', 5, &nbytes_read_USB33);
313 USB33[nbytes_read_USB33 - 1] = '\0';
314 USB33read = std::stoi(USB33);
315 updateUSB33(USB33read);
316
317 // USB21//////////////////////////////////////////////////////////////////////////////////////////
318 char USB21[64] = {0};
319 int nbytes_read_USB21= 0;
320 tty_read_section(PortFD, USB21, 'A', 5, &nbytes_read_USB21);
321 USB21[nbytes_read_USB21 - 1] = '\0';
322 USB21read = std::stoi(USB21);
323 updateUSB21(USB21read);
324
325 // USB22//////////////////////////////////////////////////////////////////////////////////////////
326 char USB22[64] = {0};
327 int nbytes_read_USB22= 0;
328 tty_read_section(PortFD, USB22, 'A', 5, &nbytes_read_USB22);
329 USB22[nbytes_read_USB22 - 1] = '\0';
330 USB22read = std::stoi(USB22);
331 updateUSB22(USB22read);
332
333 // DC34//////////////////////////////////////////////////////////////////////////////////////////
334 char DC34[64] = {0};
335 int nbytes_read_DC34= 0;
336 tty_read_section(PortFD, DC34, 'A', 5, &nbytes_read_DC34);
337 DC34[nbytes_read_DC34 - 1] = '\0';
338 DC34read = std::stoi(DC34);
339 updateDC34(DC34read);
340
341 // DC5//////////////////////////////////////////////////////////////////////////////////////////
342 char DC5[64] = {0};
343 int nbytes_read_DC5= 0;
344 tty_read_section(PortFD, DC5, 'A', 5, &nbytes_read_DC5);
345 DC5[nbytes_read_DC5 - 1] = '\0';
346 DC5read = std::stoi(DC5);
347 updateDC5(DC5read);
348
349 // DC6//////////////////////////////////////////////////////////////////////////////////////////
350 char DC6[64] = {0};
351 int nbytes_read_DC6= 0;
352 tty_read_section(PortFD, DC6, 'A', 5, &nbytes_read_DC6);
353 DC6[nbytes_read_DC6 - 1] = '\0';
354 DC6read = std::stoi(DC6);
355 updateDC6(DC6read);
356
357 // DC7//////////////////////////////////////////////////////////////////////////////////////////
358 char DC7[64] = {0};
359 int nbytes_read_DC7= 0;
360 tty_read_section(PortFD, DC7, 'A', 5, &nbytes_read_DC7);
361 DC7[nbytes_read_DC7 - 1] = '\0';
362 DC7read = std::stoi(DC7);
363 updateDC7(DC7read);
364
365 // DC8_9//////////////////////////////////////////////////////////////////////////////////////////
366 char DC8_9[64] = {0};
367 int nbytes_read_DC8_9= 0;
368 tty_read_section(PortFD, DC8_9, 'A', 5, &nbytes_read_DC8_9);
369 DC8_9[nbytes_read_DC8_9 - 1] = '\0';
370 DC8_9read =std::stoi(DC8_9);
371 updateDC8_9(DC8_9read);
372
373 // DC10_11//////////////////////////////////////////////////////////////////////////////////////////
374 char DC10_11[64] = {0};
375 int nbytes_read_DC10_11= 0;
376 tty_read_section(PortFD, DC10_11, 'A', 5, &nbytes_read_DC10_11);
377 DC10_11[nbytes_read_DC10_11 - 1] = '\0';
378 DC10_11read =std::stoi(DC10_11);
379 updateDC10_11(DC10_11read);
380
381 // DC34SET//////////////////////////////////////////////////////////////////////////////////////////
382 char DC34SET[64] = {0};
383 int nbytes_read_DC34SET= 0;
384 tty_read_section(PortFD, DC34SET, 'A', 5, &nbytes_read_DC34SET);
385 DC34SET[nbytes_read_DC34SET - 1] = '\0';
386 //LOGF_INFO("All Data Updated","Updated");
387 DC34SETread = std::stoi(DC34SET);
388 updateDC34SET(DC34SETread);
389
390
391 //DC5 DEW CONTROL
392 if(dc5diffSP[DC5_DPD_Mode].getState() == ISS_ON)
393 {
394 if(temp1read<ENVMonitorNP[DEW_Point].value+dc5diffSETNP[DC5DIFFSET].value)
395 sendCommand("5255");
396 else
397 sendCommand("5000");
398 }
399
400 if(DC5CONSTMODE==true )
401 {
402 if(temp1read<dc5constSETNP[DC5CONSTSET].value)
403 sendCommand("5255");
404 else
405 sendCommand("5000");
406 }
407 if (dc5diffSP[DC5_DPD_Mode].getState() == ISS_ON&&ENVMonitorNP[Probe1_Temp].value==-127)
408 {
409 DC5DIFFMODE=false;
410 DC5CONSTMODE=false;
411 defineProperty(dc5ControlNP);
412 deleteProperty(dc5diffSETNP);
413 deleteProperty(dc5constSETNP);
414 LOGF_ERROR("Temp probe 1 not connected, Dew Point Difference Mode for DC5 has exited!","Updated");
415 LOGF_INFO("You need to insert the probe firmly to the end!","Updated");
416 dc5diffSP[DC5_Manual].setState( ISS_ON);
417 dc5diffSP[DC5_DPD_Mode].setState( ISS_OFF);
418 dc5diffSP[DC5_CT_Mode].setState( ISS_OFF);
419 dc5diffSP.setState(IPS_OK);
420 dc5diffSP.apply();
421 }
422 if (dc5diffSP[DC5_DPD_Mode].getState() == ISS_ON&&isnan(ENVMonitorNP[DEW_Point].value)==1)
423 {
424 DC5DIFFMODE=false;
425 DC5CONSTMODE=false;
426 defineProperty(dc5ControlNP);
427 deleteProperty(dc5diffSETNP);
428 deleteProperty(dc5constSETNP);
429 LOGF_ERROR("DHT22 Humidity&Temperature sensor not connected, Dew Point Difference Mode for DC5 has exited!","Updated");
430 dc5diffSP[DC5_Manual].setState( ISS_ON);
431 dc5diffSP[DC5_DPD_Mode].setState( ISS_OFF);
432 dc5diffSP[DC5_CT_Mode].setState( ISS_OFF);
433 dc5diffSP.setState(IPS_OK);
434 dc5diffSP.apply();
435 }
436 if (dc5diffSP[DC5_CT_Mode].getState() == ISS_ON&&ENVMonitorNP[Probe1_Temp].value==-127)
437 {
438 DC5DIFFMODE=false;
439 DC5CONSTMODE=false;
440 defineProperty(dc5ControlNP);
441 deleteProperty(dc5diffSETNP);
442 deleteProperty(dc5constSETNP);
443 LOGF_ERROR("Temp probe 1 not connected, Constant Temperature Mode for DC5 has exited!","Updated");
444 LOGF_INFO("You need to insert the probe firmly to the end!","Updated");
445 dc5diffSP[DC5_Manual].setState( ISS_ON);
446 dc5diffSP[DC5_DPD_Mode].setState( ISS_OFF);
447 dc5diffSP[DC5_CT_Mode].setState( ISS_OFF);
448 dc5diffSP.setState(IPS_OK);
449 dc5diffSP.apply();
450 }
451
452
453
454 //DC6 DEW CONTROL
455 if(DC6DIFFMODE==true )
456 {
457 if(temp2read<ENVMonitorNP[DEW_Point].value+dc6diffSETNP[DC6DIFFSET].value)
458 sendCommand("6255");
459 else
460 sendCommand("6000");
461 }
462 if(DC6CONSTMODE==true )
463 {
464 if(temp2read<dc6constSETNP[DC6CONSTSET].value)
465 sendCommand("6255");
466 else
467 sendCommand("6000");
468 }
469 if (dc6diffSP[DC6_DPD_Mode].getState() == ISS_ON&&ENVMonitorNP[Probe2_Temp].value==-127)
470 {
471 DC6DIFFMODE=false;
472 DC6CONSTMODE=false;
473 defineProperty(dc6ControlNP);
474 deleteProperty(dc6diffSETNP);
475 deleteProperty(dc6constSETNP);
476 LOGF_ERROR("Temp probe 2 not connected, Dew Point Difference Mode for DC6 has exited!","Updated");
477 LOGF_INFO("You need to insert the probe firmly to the end!","Updated");
478 dc6diffSP[DC6_Manual].setState( ISS_ON);
479 dc6diffSP[DC6_DPD_Mode].setState( ISS_OFF);
480 dc6diffSP[DC6_CT_Mode].setState( ISS_OFF);
481 dc6diffSP.setState(IPS_OK);
482 dc6diffSP.apply();
483 }
484 if (dc6diffSP[DC6_DPD_Mode].getState() == ISS_ON&&isnan(ENVMonitorNP[DEW_Point].value)==1)
485 {
486 DC6DIFFMODE=false;
487 DC6CONSTMODE=false;
488 defineProperty(dc6ControlNP);
489 deleteProperty(dc6diffSETNP);
490 deleteProperty(dc6constSETNP);
491 LOGF_ERROR("DHT22 Humidity&Temperature sensor not connected, Dew Point Difference Mode for DC6 has exited!","Updated");
492 dc6diffSP[DC6_Manual].setState( ISS_ON);
493 dc6diffSP[DC6_DPD_Mode].setState( ISS_OFF);
494 dc6diffSP[DC6_CT_Mode].setState( ISS_OFF);
495 dc6diffSP.setState(IPS_OK);
496 dc6diffSP.apply();
497 }
498 if (dc6diffSP[DC6_CT_Mode].getState() == ISS_ON&&ENVMonitorNP[Probe2_Temp].value==-127)
499 {
500 DC6DIFFMODE=false;
501 DC6CONSTMODE=false;
502 defineProperty(dc6ControlNP);
503 deleteProperty(dc6diffSETNP);
504 deleteProperty(dc6constSETNP);
505 LOGF_ERROR("Temp probe 2 not connected, Constant Temperature Mode for DC6 has exited!","Updated");
506 LOGF_INFO("You need to insert the probe firmly to the end!","Updated");
507 dc6diffSP[DC6_Manual].setState( ISS_ON);
508 dc6diffSP[DC6_DPD_Mode].setState( ISS_OFF);
509 dc6diffSP[DC6_CT_Mode].setState( ISS_OFF);
510 dc6diffSP.setState(IPS_OK);
511 dc6diffSP.apply();
512 }
513
514
515 //DC7 DEW CONTROL
516 if(DC7DIFFMODE==true )
517 {
518 if(temp3read<ENVMonitorNP[DEW_Point].value+dc7diffSETNP[DC7DIFFSET].value)
519 sendCommand("7255");
520 else
521 sendCommand("7000");
522 }
523 if(DC7CONSTMODE==true )
524 {
525 if(temp3read<dc7constSETNP[DC7CONSTSET].value)
526 sendCommand("7255");
527 else
528 sendCommand("7000");
529 }
530 if (dc7diffSP[DC7_DPD_Mode].getState() == ISS_ON&&ENVMonitorNP[Probe3_Temp].value==-127)
531 {
532 DC7DIFFMODE=false;
533 DC7CONSTMODE=false;
534 defineProperty(dc7ControlNP);
535 deleteProperty(dc7diffSETNP);
536 deleteProperty(dc7constSETNP);
537 LOGF_ERROR("Temp probe 3 not connected, Dew Point Difference Mode for DC7 has exited!","Updated");
538 LOGF_INFO("You need to insert the probe firmly to the end!","Updated");
539 dc7diffSP[DC7_Manual].setState( ISS_ON);
540 dc7diffSP[DC7_DPD_Mode].setState( ISS_OFF);
541 dc7diffSP[DC7_CT_Mode].setState( ISS_OFF);
542 dc7diffSP.setState(IPS_OK);
543 dc7diffSP.apply();
544 }
545 if (dc7diffSP[DC7_DPD_Mode].getState() == ISS_ON&&isnan(ENVMonitorNP[DEW_Point].value)==1)
546 {
547 DC7DIFFMODE=false;
548 DC7CONSTMODE=false;
549 defineProperty(dc7ControlNP);
550 deleteProperty(dc7diffSETNP);
551 deleteProperty(dc7constSETNP);
552 LOGF_ERROR("DHT22 Humidity&Temperature sensor not connected, Dew Point Difference Mode for DC7 has exited!","Updated");
553 dc7diffSP[DC7_Manual].setState( ISS_ON);
554 dc7diffSP[DC7_DPD_Mode].setState( ISS_OFF);
555 dc7diffSP[DC7_CT_Mode].setState( ISS_OFF);
556 dc7diffSP.setState(IPS_OK);
557 dc7diffSP.apply();
558 }
559 if (dc7diffSP[DC7_CT_Mode].getState() == ISS_ON&&ENVMonitorNP[Probe3_Temp].value==-127)
560 {
561 DC7DIFFMODE=false;
562 DC7CONSTMODE=false;
563 defineProperty(dc7ControlNP);
564 deleteProperty(dc7diffSETNP);
565 deleteProperty(dc7constSETNP);
566 LOGF_ERROR("Temp probe 3 not connected, Constant Temperature Mode for DC7 has exited!","Updated");
567 LOGF_INFO("You need to insert the probe firmly to the end!","Updated");
568 dc7diffSP[DC7_Manual].setState( ISS_ON);
569 dc7diffSP[DC7_DPD_Mode].setState( ISS_OFF);
570 dc7diffSP[DC7_CT_Mode].setState( ISS_OFF);
571 dc7diffSP.setState(IPS_OK);
572 dc7diffSP.apply();
573 }
574
575 }
576 catch(std::exception& e)
577 {
578 //LOGF_INFO("Data read failed","failed");
579 }
580 return true;
581}
582
583
584
585void WandererBoxProV3::updateENV(double temp1,double temp2,double temp3,double DHTH,double DHTT)
586{
587 ENVMonitorNP[Probe1_Temp].setValue(temp1);
588 ENVMonitorNP[Probe2_Temp].setValue(temp2);
589 ENVMonitorNP[Probe3_Temp].setValue(temp3);
590 ENVMonitorNP[ENV_Humidity].setValue(DHTH);
591 ENVMonitorNP[ENV_Temp].setValue(DHTT);
592 double dewPoint = (237.7 * ((17.27 * DHTT) / (237.7 + DHTT) + std::log((DHTH / 100)))) / (17.27 - ((17.27 * DHTT) / (237.7 + DHTT) + std::log((DHTH / 100))));
593 ENVMonitorNP[DEW_Point].setValue(dewPoint);
594 ENVMonitorNP.setState(IPS_OK);
595 ENVMonitorNP.apply();
596
597 // Update Weather Interface parameters
598 setParameterValue("WEATHER_TEMPERATURE", DHTT);
599 setParameterValue("WEATHER_HUMIDITY", DHTH);
600 setParameterValue("WEATHER_DEWPOINT", dewPoint);
605}
606
607
608void WandererBoxProV3::updatePower(double Tcurrent,double V19_current,double AR_current,double voltage)
609{
610 // Power Monitor
611 PowerMonitorNP[VOLTAGE].setValue(voltage);
612 PowerMonitorNP[TOTAL_CURRENT].setValue(Tcurrent);
613 PowerMonitorNP[V19_CURRENT].setValue(V19_current);
614 PowerMonitorNP[AR_CURRENT].setValue(AR_current);
615 PowerMonitorNP.setState(IPS_OK);
616 PowerMonitorNP.apply();
617}
618
619void WandererBoxProV3::updateUSB31(int res)
620{
621 usb31ControlSP[INDI_ENABLED].setState( (res== 1) ? ISS_ON : ISS_OFF);
622 usb31ControlSP[INDI_DISABLED].setState( (res== 0) ? ISS_ON : ISS_OFF);
623 usb31ControlSP.setState((res== 1) ? IPS_OK : IPS_IDLE);
624 usb31ControlSP.apply();
625}
626
627void WandererBoxProV3::updateUSB32(int res)
628{
629 usb32ControlSP[INDI_ENABLED].setState( (res== 1) ? ISS_ON : ISS_OFF);
630 usb32ControlSP[INDI_DISABLED].setState( (res== 0) ? ISS_ON : ISS_OFF);
631 usb32ControlSP.setState((res== 1) ? IPS_OK : IPS_IDLE);
632 usb32ControlSP.apply();
633}
634
635void WandererBoxProV3::updateUSB33(int res)
636{
637 usb33ControlSP[INDI_ENABLED].setState( (res== 1) ? ISS_ON : ISS_OFF);
638 usb33ControlSP[INDI_DISABLED].setState( (res== 0) ? ISS_ON : ISS_OFF);
639 usb33ControlSP.setState((res== 1) ? IPS_OK : IPS_IDLE);
640 usb33ControlSP.apply();
641}
642
643void WandererBoxProV3::updateUSB21(int res)
644{
645 usb21ControlSP[INDI_ENABLED].setState( (res== 1) ? ISS_ON : ISS_OFF);
646 usb21ControlSP[INDI_DISABLED].setState( (res== 0) ? ISS_ON : ISS_OFF);
647 usb21ControlSP.setState((res== 1) ? IPS_OK : IPS_IDLE);
648 usb21ControlSP.apply();
649}
650
651void WandererBoxProV3::updateUSB22(int res)
652{
653 usb22ControlSP[INDI_ENABLED].setState( (res== 1) ? ISS_ON : ISS_OFF);
654 usb22ControlSP[INDI_DISABLED].setState( (res== 0) ? ISS_ON : ISS_OFF);
655 usb22ControlSP.setState((res== 1) ? IPS_OK : IPS_IDLE);
656 usb22ControlSP.apply();
657}
658
659void WandererBoxProV3::updateDC34(int res)
660{
661 dc3_4ControlSP[INDI_ENABLED].setState( (res== 1) ? ISS_ON : ISS_OFF);
662 dc3_4ControlSP[INDI_DISABLED].setState( (res== 0) ? ISS_ON : ISS_OFF);
663 dc3_4ControlSP.setState((res== 1) ? IPS_OK : IPS_IDLE);
664 dc3_4ControlSP.apply();
665}
666
667void WandererBoxProV3::updateDC5(int res)
668{
669 dc5ControlNP[0].setValue(res);
670 dc5ControlNP.setState(IPS_OK);
671 dc5ControlNP.apply();
672}
673
674void WandererBoxProV3::updateDC6(int res)
675{
676 dc6ControlNP[0].setValue(res);
677 dc6ControlNP.setState(IPS_OK);
678 dc6ControlNP.apply();
679}
680
681void WandererBoxProV3::updateDC7(int res)
682{
683 dc7ControlNP[0].setValue(res);
684 dc7ControlNP.setState(IPS_OK);
685 dc7ControlNP.apply();
686}
687
688void WandererBoxProV3::updateDC8_9(int res)
689{
690 dc8_9ControlSP[INDI_ENABLED].setState( (res== 1) ? ISS_ON : ISS_OFF);
691 dc8_9ControlSP[INDI_DISABLED].setState( (res== 0) ? ISS_ON : ISS_OFF);
692 dc8_9ControlSP.setState((res== 1) ? IPS_OK : IPS_IDLE);
693 dc8_9ControlSP.apply();
694}
695
696void WandererBoxProV3::updateDC10_11(int res)
697{
698 dc10_11ControlSP[INDI_ENABLED].setState( (res== 1) ? ISS_ON : ISS_OFF);
699 dc10_11ControlSP[INDI_DISABLED].setState( (res== 0) ? ISS_ON : ISS_OFF);
700 dc10_11ControlSP.setState((res== 1) ? IPS_OK : IPS_IDLE);
701 dc10_11ControlSP.apply();
702}
703
704void WandererBoxProV3::updateDC34SET(double res)
705{
706 setDC34voltageNP[setDC34voltage].setValue(res/10);
707 setDC34voltageNP.setState(IPS_OK);
708 setDC34voltageNP.apply();
709}
710
711
712
714{
716
717 if (isConnected())
718 {
719
720 if(firmware>=20240216)
721 {
722 defineProperty(CalibrateSP);
723 LOGF_INFO("Firmware version: %d", firmware);
724 }
725 else
726 {
727 LOGF_INFO("The firmware is outdated, please upgrade to the latest firmware, or power reading calibration will be unavailable.","failed");
728 }
729 defineProperty(PowerMonitorNP);
730
731
732 defineProperty(usb31ControlSP);
733 defineProperty(usb32ControlSP);
734 defineProperty(usb33ControlSP);
735 defineProperty(usb21ControlSP);
736 defineProperty(usb22ControlSP);
737
738 defineProperty(setDC34voltageNP);
739 defineProperty(dc3_4ControlSP);
740
741 defineProperty(dc8_9ControlSP);
742 defineProperty(dc10_11ControlSP);
743
744 defineProperty(dc5diffSP);
745 defineProperty(dc6diffSP);
746 defineProperty(dc7diffSP);
747
748
749 //DC5////////////////////
750 if(dc5diffSP[DC5_DPD_Mode].getState() == ISS_ON)
751 {
752 deleteProperty(dc5constSETNP);
753 deleteProperty(dc5ControlNP);
754 defineProperty(dc5diffSETNP);
755 }
756 else if(dc5diffSP[DC5_CT_Mode].getState() == ISS_ON)
757 {
758 deleteProperty(dc5ControlNP);
759 deleteProperty(dc5diffSETNP);
760 defineProperty(dc5constSETNP);
761 }
762 else
763 {
764 defineProperty(dc5ControlNP);
765 deleteProperty(dc5diffSETNP);
766 deleteProperty(dc5constSETNP);
767 }
768 //DC6////////////////
769 if(dc6diffSP[DC6_DPD_Mode].getState() == ISS_ON)
770 {
771 deleteProperty(dc6constSETNP);
772 deleteProperty(dc6ControlNP);
773 defineProperty(dc6diffSETNP);
774 }
775 else if(dc6diffSP[DC6_CT_Mode].getState() == ISS_ON)
776 {
777 deleteProperty(dc6ControlNP);
778 deleteProperty(dc6diffSETNP);
779 defineProperty(dc6constSETNP);
780 }
781 else
782 {
783 defineProperty(dc6ControlNP);
784 deleteProperty(dc6diffSETNP);
785 deleteProperty(dc6constSETNP);
786 }
787 //DC7////////////////
788 if(dc7diffSP[DC7_DPD_Mode].getState() == ISS_ON)
789 {
790 deleteProperty(dc7constSETNP);
791 deleteProperty(dc7ControlNP);
792 defineProperty(dc7diffSETNP);
793 }
794 else if(dc7diffSP[DC7_CT_Mode].getState() == ISS_ON)
795 {
796 deleteProperty(dc7ControlNP);
797 deleteProperty(dc7diffSETNP);
798 defineProperty(dc7constSETNP);
799 }
800 else
801 {
802 defineProperty(dc7ControlNP);
803 deleteProperty(dc7diffSETNP);
804 deleteProperty(dc7constSETNP);
805 }
806
807
808 defineProperty(ENVMonitorNP);
809
810 // Weather
812
813 }
814 else
815 {
816
817 deleteProperty(CalibrateSP);
818 deleteProperty(PowerMonitorNP);
819 deleteProperty(ENVMonitorNP);
820
821 // Weather
823
824 deleteProperty(dc3_4ControlSP);
825 deleteProperty(setDC34voltageNP);
826 deleteProperty(dc8_9ControlSP);
827 deleteProperty(dc10_11ControlSP);
828 deleteProperty(usb31ControlSP);
829 deleteProperty(usb32ControlSP);
830 deleteProperty(usb33ControlSP);
831 deleteProperty(usb21ControlSP);
832 deleteProperty(usb22ControlSP);
833
834 deleteProperty(dc5ControlNP);
835 deleteProperty(dc6ControlNP);
836 deleteProperty(dc7ControlNP);
837
838 deleteProperty(dc5diffSP);
839 deleteProperty(dc5diffSETNP);
840
841 deleteProperty(dc6diffSP);
842 deleteProperty(dc6diffSETNP);
843
844 deleteProperty(dc7diffSP);
845 deleteProperty(dc7diffSETNP);
846
847
848 }
849 return true;
850}
851
852bool WandererBoxProV3::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
853{
854 if (dev && !strcmp(dev, getDeviceName()))
855 {
856 if (strstr(name, "WEATHER_"))
857 return WI::processSwitch(dev, name, states, names, n);
858 }
859
860 // Calibrate
861 if (CalibrateSP.isNameMatch(name))
862 {
863 CalibrateSP.setState(sendCommand("66300744") ? IPS_OK : IPS_ALERT);
864 CalibrateSP.apply();
865 LOG_INFO("Calibrating Current Readings...");
866 return true;
867 }
868
869
870 // DC3-4 Control
871 if (dc3_4ControlSP.isNameMatch(name))
872 {
873 dc3_4ControlSP.update(states, names, n);
874 dc3_4ControlSP.setState(IPS_ALERT);
875 char cmd[128] = {0};
876 snprintf(cmd, 128, "10%d", (dc3_4ControlSP[INDI_ENABLED].getState() == ISS_ON) ? 1 : 0);
877 dc3_4ControlSP.setState( sendCommand(cmd) ? IPS_OK : IPS_ALERT);
878 dc3_4ControlSP.apply();
879
880 return true;
881 }
882 // DC8-9 Control
883 if (dc8_9ControlSP.isNameMatch(name))
884 {
885 dc8_9ControlSP.update(states, names, n);
886 dc8_9ControlSP.setState(IPS_ALERT);
887 char cmd[128] = {0};
888 snprintf(cmd, 128, "20%d", (dc8_9ControlSP[INDI_ENABLED].getState() == ISS_ON) ? 1 : 0);
889 dc8_9ControlSP.setState( sendCommand(cmd) ? IPS_OK : IPS_ALERT);
890 dc8_9ControlSP.apply();
891
892 return true;
893 }
894 // DC10-11 Control
895 if (dc10_11ControlSP.isNameMatch(name))
896 {
897 dc10_11ControlSP.update(states, names, n);
898 dc10_11ControlSP.setState(IPS_ALERT);
899 char cmd[128] = {0};
900 snprintf(cmd, 128, "21%d", (dc10_11ControlSP[INDI_ENABLED].getState() == ISS_ON) ? 1 : 0);
901 dc10_11ControlSP.setState( sendCommand(cmd) ? IPS_OK : IPS_ALERT);
902 dc10_11ControlSP.apply();
903
904 return true;
905 }
906
907 // USB31 Control
908 if (usb31ControlSP.isNameMatch(name))
909 {
910 usb31ControlSP.update(states, names, n);
911 usb31ControlSP.setState(IPS_ALERT);
912 char cmd[128] = {0};
913 snprintf(cmd, 128, "11%d", (usb31ControlSP[INDI_ENABLED].getState() == ISS_ON) ? 1 : 0);
914 usb31ControlSP.setState( sendCommand(cmd) ? IPS_OK : IPS_ALERT);
915
916 return true;
917 }
918 // USB32 Control
919 if (usb32ControlSP.isNameMatch(name))
920 {
921 usb32ControlSP.update(states, names, n);
922 usb32ControlSP.setState(IPS_ALERT);
923 char cmd[128] = {0};
924 snprintf(cmd, 128, "12%d", (usb32ControlSP[INDI_ENABLED].getState() == ISS_ON) ? 1 : 0);
925 usb32ControlSP.setState( sendCommand(cmd) ? IPS_OK : IPS_ALERT);
926 usb32ControlSP.apply();
927
928 return true;
929 }
930 // USB33 Control
931 if (usb33ControlSP.isNameMatch(name))
932 {
933 usb33ControlSP.update(states, names, n);
934 usb33ControlSP.setState(IPS_ALERT);
935 char cmd[128] = {0};
936 snprintf(cmd, 128, "13%d", (usb33ControlSP[INDI_ENABLED].getState() == ISS_ON) ? 1 : 0);
937 usb33ControlSP.setState( sendCommand(cmd) ? IPS_OK : IPS_ALERT);
938 usb33ControlSP.apply();
939
940 return true;
941 }
942 // USB21 Control
943 if (usb21ControlSP.isNameMatch(name))
944 {
945 usb21ControlSP.update(states, names, n);
946 usb21ControlSP.setState(IPS_ALERT);
947 char cmd[128] = {0};
948 snprintf(cmd, 128, "14%d", (usb21ControlSP[INDI_ENABLED].getState() == ISS_ON) ? 1 : 0);
949 usb21ControlSP.setState( sendCommand(cmd) ? IPS_OK : IPS_ALERT);
950 usb21ControlSP.apply();
951
952 return true;
953 }
954 // USB22 Control
955 if (usb22ControlSP.isNameMatch(name))
956 {
957 usb22ControlSP.update(states, names, n);
958 usb22ControlSP.setState(IPS_ALERT);
959 char cmd[128] = {0};
960 snprintf(cmd, 128, "15%d", (usb22ControlSP[INDI_ENABLED].getState() == ISS_ON) ? 1 : 0);
961 usb22ControlSP.setState( sendCommand(cmd) ? IPS_OK : IPS_ALERT);
962 usb22ControlSP.apply();
963
964 return true;
965 }
966
967 // DC5 DEW
968 if (dc5diffSP.isNameMatch(name))
969 {
970 dc5diffSP.update(states, names, n);
971 dc5diffSP.setState(IPS_ALERT);
972 if(dc5diffSP[DC5_DPD_Mode].getState() == ISS_ON&&ENVMonitorNP[Probe1_Temp].value!=-127&&isnan(ENVMonitorNP[DEW_Point].value)==0)
973 {
974 DC5DIFFMODE=true;
975 DC5CONSTMODE=false;
976 deleteProperty(dc5ControlNP);
977 deleteProperty(dc5constSETNP);
978 defineProperty(dc5diffSETNP);
979
980 dc5diffSETNP.setState(IPS_OK);
981 dc5diffSETNP.apply();
982 dc5diffSP.setState(IPS_OK) ;
983 dc5diffSP.apply();
984 LOGF_INFO("Dew Point Difference Mode for DC5 activated! WandererBox will keep the dew heater at the temperature higher than the dew point by the set value.","Updated");
985 return true;
986 }
987 else if(dc5diffSP[DC5_DPD_Mode].getState() == ISS_ON&&(ENVMonitorNP[Probe1_Temp].value==-127||isnan(ENVMonitorNP[DEW_Point].value)==1))
988 {
989 DC5DIFFMODE=false;
990 DC5CONSTMODE=false;
991 dc5diffSP[DC5_Manual].setState( ISS_ON);
992 LOGF_INFO("Manual Mode for DC5 activated! Please adjust the duty cycle manually, you can also use DC5 as an ordinary switch.","Updated");
993 dc5diffSP.apply();
994 }
995 else if(dc5diffSP[DC5_CT_Mode].getState() == ISS_ON&&ENVMonitorNP[Probe1_Temp].value!=-127)
996 {
997 DC5CONSTMODE=true;
998 DC5DIFFMODE=false;
999 deleteProperty(dc5diffSETNP);
1000 deleteProperty(dc5ControlNP);
1001 defineProperty(dc5constSETNP);
1002
1003 dc5constSETNP.setState(IPS_OK);
1004 dc5constSETNP.apply();
1005 dc5diffSP.setState(IPS_OK) ;
1006 dc5diffSP.apply();
1007 LOGF_INFO("Constant Temperature Mode for DC5 activated! WandererBox will keep the dew heater at the set temperature.","Updated");
1008 return true;
1009 }
1010 else if(dc5diffSP[DC5_CT_Mode].getState() == ISS_ON&&ENVMonitorNP[Probe1_Temp].value==-127)
1011 {
1012 DC5DIFFMODE=false;
1013 DC5CONSTMODE=false;
1014 dc5diffSP[DC5_Manual].setState( ISS_ON);
1015 LOGF_INFO("Manual Mode for DC5 activated! Please adjust the duty cycle manually, you can also use DC5 as an ordinary switch.","Updated");
1016 dc5diffSP.apply();
1017 }
1018 else
1019 {
1020 DC5DIFFMODE=false;
1021 DC5CONSTMODE=false;
1022 defineProperty(dc5ControlNP);
1023 deleteProperty(dc5diffSETNP);
1024 deleteProperty(dc5constSETNP);
1025 dc5diffSP.setState(IPS_OK) ;
1026 dc5diffSP.apply();
1027 LOGF_INFO("Manual Mode for DC5 activated! Please adjust the duty cycle manually, you can also use DC5 as an ordinary switch.","Updated");
1028 return true;
1029 }
1030
1031 }
1032
1033 // DC6 DEW
1034 if (dc6diffSP.isNameMatch(name))
1035 {
1036 dc6diffSP.update(states, names, n);
1037 dc6diffSP.setState(IPS_ALERT);
1038 if(dc6diffSP[DC6_DPD_Mode].getState() == ISS_ON&&ENVMonitorNP[Probe2_Temp].value!=-127&&isnan(ENVMonitorNP[DEW_Point].value)==0)
1039 {
1040 DC6DIFFMODE=true;
1041 DC6CONSTMODE=false;
1042 deleteProperty(dc6ControlNP);
1043 deleteProperty(dc6constSETNP);
1044 defineProperty(dc6diffSETNP);
1045
1046 dc6diffSETNP.setState(IPS_OK);
1047 dc6diffSETNP.apply();
1048 dc6diffSP.setState(IPS_OK) ;
1049 dc6diffSP.apply();
1050 LOGF_INFO("Dew Point Difference Mode for DC6 activated! WandererBox will keep the dew heater at the temperature higher than the dew point by the set value.","Updated");
1051 return true;
1052 }
1053 else if(dc6diffSP[DC6_DPD_Mode].getState() == ISS_ON&&(ENVMonitorNP[Probe2_Temp].value==-127||isnan(ENVMonitorNP[DEW_Point].value)==1))
1054 {
1055 DC6DIFFMODE=false;
1056 DC6CONSTMODE=false;
1057 dc6diffSP[DC6_Manual].setState( ISS_ON);
1058 LOGF_INFO("Manual Mode for DC6 activated! Please adjust the duty cycle manually, you can also use DC6 as an ordinary switch.","Updated");
1059 dc6diffSP.apply();
1060 }
1061 else if(dc6diffSP[DC6_CT_Mode].getState() == ISS_ON&&ENVMonitorNP[Probe2_Temp].value!=-127)
1062 {
1063 DC6CONSTMODE=true;
1064 DC6DIFFMODE=false;
1065 deleteProperty(dc6diffSETNP);
1066 deleteProperty(dc6ControlNP);
1067 defineProperty(dc6constSETNP);
1068
1069 dc6constSETNP.setState(IPS_OK);
1070 dc6constSETNP.apply();
1071 dc6diffSP.setState(IPS_OK) ;
1072 dc6diffSP.apply();
1073 LOGF_INFO("Constant Temperature Mode for DC6 activated! WandererBox will keep the dew heater at the set temperature.","Updated");
1074 return true;
1075 }
1076 else if(dc6diffSP[DC6_CT_Mode].getState() == ISS_ON&&ENVMonitorNP[Probe2_Temp].value==-127)
1077 {
1078 DC6DIFFMODE=false;
1079 DC6CONSTMODE=false;
1080 dc6diffSP[DC6_Manual].setState( ISS_ON);
1081 LOGF_INFO("Manual Mode for DC6 activated! Please adjust the duty cycle manually, you can also use DC6 as an ordinary switch.","Updated");
1082 dc6diffSP.apply();
1083 }
1084 else
1085 {
1086 DC6DIFFMODE=false;
1087 DC6CONSTMODE=false;
1088 defineProperty(dc6ControlNP);
1089 deleteProperty(dc6diffSETNP);
1090 deleteProperty(dc6constSETNP);
1091 dc6diffSP.setState(IPS_OK) ;
1092 dc6diffSP.apply();
1093 LOGF_INFO("Manual Mode for DC6 activated! Please adjust the duty cycle manually, you can also use DC6 as an ordinary switch.","Updated");
1094 return true;
1095 }
1096
1097 }
1098
1099 // DC7 DEW
1100 if (dc7diffSP.isNameMatch(name))
1101 {
1102 dc7diffSP.update(states, names, n);
1103 dc7diffSP.setState(IPS_ALERT);
1104 if(dc7diffSP[DC7_DPD_Mode].getState() == ISS_ON&&ENVMonitorNP[Probe3_Temp].value!=-127&&isnan(ENVMonitorNP[DEW_Point].value)==0)
1105 {
1106 DC7DIFFMODE=true;
1107 DC7CONSTMODE=false;
1108 deleteProperty(dc7ControlNP);
1109 deleteProperty(dc7constSETNP);
1110 defineProperty(dc7diffSETNP);
1111
1112 dc7diffSETNP.setState(IPS_OK);
1113 dc7diffSETNP.apply();
1114 dc7diffSP.setState(IPS_OK) ;
1115 dc7diffSP.apply();
1116 LOGF_INFO("Dew Point Difference Mode for DC7 activated! WandererBox will keep the dew heater at the temperature higher than the dew point by the set value.","Updated");
1117 return true;
1118 }
1119 else if(dc7diffSP[DC7_DPD_Mode].getState() == ISS_ON&&(ENVMonitorNP[Probe3_Temp].value==-127||isnan(ENVMonitorNP[DEW_Point].value)==1))
1120 {
1121 DC7DIFFMODE=false;
1122 DC7CONSTMODE=false;
1123 dc7diffSP[DC7_Manual].setState( ISS_ON);
1124 LOGF_INFO("Manual Mode for DC7 activated! Please adjust the duty cycle manually, you can also use DC7 as an ordinary switch.","Updated");
1125 dc7diffSP.apply();
1126 }
1127 else if(dc7diffSP[DC7_CT_Mode].getState() == ISS_ON&&ENVMonitorNP[Probe3_Temp].value!=-127)
1128 {
1129 DC7CONSTMODE=true;
1130 DC7DIFFMODE=false;
1131 deleteProperty(dc7diffSETNP);
1132 deleteProperty(dc7ControlNP);
1133 defineProperty(dc7constSETNP);
1134
1135 dc7constSETNP.setState(IPS_OK);
1136 dc7constSETNP.apply();
1137 dc7diffSP.setState(IPS_OK) ;
1138 dc7diffSP.apply();
1139 LOGF_INFO("Constant Temperature Mode for DC7 activated! WandererBox will keep the dew heater at the set temperature.","Updated");
1140 return true;
1141 }
1142 else if(dc7diffSP[DC7_CT_Mode].getState() == ISS_ON&&ENVMonitorNP[Probe3_Temp].value==-127)
1143 {
1144 DC7DIFFMODE=false;
1145 DC7CONSTMODE=false;
1146 dc7diffSP[DC7_Manual].setState( ISS_ON);
1147 LOGF_INFO("Manual Mode for DC7 activated! Please adjust the duty cycle manually, you can also use DC7 as an ordinary switch.","Updated");
1148 dc7diffSP.apply();
1149 }
1150 else
1151 {
1152 DC7DIFFMODE=false;
1153 DC7CONSTMODE=false;
1154 defineProperty(dc7ControlNP);
1155 deleteProperty(dc7diffSETNP);
1156 deleteProperty(dc7constSETNP);
1157 dc7diffSP.setState(IPS_OK) ;
1158 dc7diffSP.apply();
1159 LOGF_INFO("Manual Mode for DC7 activated! Please adjust the duty cycle manually, you can also use DC7 as an ordinary switch.","Updated");
1160 return true;
1161 }
1162
1163 }
1164
1165 return DefaultDevice::ISNewSwitch(dev, name, states, names, n);
1166}
1167
1168bool WandererBoxProV3::ISNewNumber(const char * dev, const char * name, double values[], char * names[], int n)
1169{
1170 if (dev && !strcmp(dev, getDeviceName()))
1171 {
1172 if (strstr(name, "WEATHER_"))
1173 return WI::processNumber(dev, name, values, names, n);
1174 // DC5
1175 if (dc5ControlNP.isNameMatch(name))
1176 {
1177 bool rc1 = false;
1178 for (int i = 0; i < n; i++)
1179 {
1180 rc1 = setDewPWM(5, static_cast<uint8_t>(values[i]));
1181 }
1182
1183 dc5ControlNP.setState( (rc1) ? IPS_OK : IPS_ALERT);
1184 if (dc5ControlNP.getState() == IPS_OK)
1185 dc5ControlNP.update(values, names, n);
1186 dc5ControlNP.apply();
1187 return true;
1188 }
1189 if (dc5diffSETNP.isNameMatch(name))
1190 {
1191
1192 dc5diffSETNP.setState(IPS_OK) ;
1193 if (dc5diffSETNP.getState() == IPS_OK)
1194 dc5diffSETNP.update(values, names, n);
1195 dc5diffSETNP.apply();
1196 return true;
1197 }
1198 if (dc5constSETNP.isNameMatch(name))
1199 {
1200
1201 dc5constSETNP.setState(IPS_OK) ;
1202 if (dc5constSETNP.getState() == IPS_OK)
1203 dc5constSETNP.update(values, names, n);
1204 dc5constSETNP.apply();
1205 return true;
1206 }
1207 // DC6
1208 if (dc6ControlNP.isNameMatch(name))
1209 {
1210 bool rc1 = false;
1211 for (int i = 0; i < n; i++)
1212 {
1213 rc1 = setDewPWM(6, static_cast<uint8_t>(values[i]));
1214 }
1215
1216 dc6ControlNP.setState( (rc1) ? IPS_OK : IPS_ALERT);
1217 if (dc6ControlNP.getState() == IPS_OK)
1218 dc6ControlNP.update(values, names, n);
1219 dc6ControlNP.apply();
1220 return true;
1221 }
1222 if (dc6diffSETNP.isNameMatch(name))
1223 {
1224
1225 dc6diffSETNP.setState(IPS_OK) ;
1226 if (dc6diffSETNP.getState() == IPS_OK)
1227 dc6diffSETNP.update(values, names, n);
1228 dc6diffSETNP.apply();
1229 return true;
1230 }
1231 if (dc6constSETNP.isNameMatch(name))
1232 {
1233
1234 dc6constSETNP.setState(IPS_OK) ;
1235 if (dc6constSETNP.getState() == IPS_OK)
1236 dc6constSETNP.update(values, names, n);
1237 dc6constSETNP.apply();
1238 return true;
1239 }
1240 // DC7
1241 if (dc7ControlNP.isNameMatch(name))
1242 {
1243 bool rc1 = false;
1244 for (int i = 0; i < n; i++)
1245 {
1246 rc1 = setDewPWM(7, static_cast<uint8_t>(values[i]));
1247 }
1248
1249 dc7ControlNP.setState( (rc1) ? IPS_OK : IPS_ALERT);
1250 if (dc7ControlNP.getState() == IPS_OK)
1251 dc7ControlNP.update(values, names, n);
1252 dc7ControlNP.apply();
1253 return true;
1254 }
1255 if (dc7diffSETNP.isNameMatch(name))
1256 {
1257
1258 dc7diffSETNP.setState(IPS_OK) ;
1259 if (dc7diffSETNP.getState() == IPS_OK)
1260 dc7diffSETNP.update(values, names, n);
1261 dc7diffSETNP.apply();
1262 return true;
1263 }
1264 if (dc7constSETNP.isNameMatch(name))
1265 {
1266
1267 dc7constSETNP.setState(IPS_OK) ;
1268 if (dc7constSETNP.getState() == IPS_OK)
1269 dc7constSETNP.update(values, names, n);
1270 dc7constSETNP.apply();
1271 return true;
1272 }
1273 // DC34voltageSET
1274 if (setDC34voltageNP.isNameMatch(name))
1275 {
1276 bool rc1 = false;
1277 for (int i = 0; i < n; i++)
1278 {
1279 rc1 = setDewPWM(20, static_cast<uint8_t>(10*values[i]));
1280 }
1281
1282 setDC34voltageNP.setState( (rc1) ? IPS_OK : IPS_ALERT);
1283 if (setDC34voltageNP.getState() == IPS_OK)
1284 setDC34voltageNP.update(values, names, n);
1285 setDC34voltageNP.apply();
1286 return true;
1287 }
1288
1289
1290 }
1291 return INDI::DefaultDevice::ISNewNumber(dev, name, values, names, n);
1292}
1293
1294bool WandererBoxProV3::setDewPWM(uint8_t id, uint8_t value)
1295{
1296 char cmd[64] = {0};
1297 snprintf(cmd, 64, "%d%03d", id, value);
1298 if (sendCommand(cmd))
1299 {
1300 return true;
1301 }
1302
1303 return false;
1304}
1305
1307{
1308 return "WandererBox Pro V3";
1309}
1310
1311
1312bool WandererBoxProV3::sendCommand(std::string command)
1313{
1314 int nbytes_written = 0, rc = -1;
1315 std::string command_termination = "\n";
1316 LOGF_DEBUG("CMD: %s", command.c_str());
1317 if ((rc = tty_write_string(PortFD, (command + command_termination).c_str(), &nbytes_written)) != TTY_OK)
1318 {
1319 char errorMessage[MAXRBUF];
1320 tty_error_msg(rc, errorMessage, MAXRBUF);
1321 LOGF_ERROR("Serial write error: %s", errorMessage);
1322 return false;
1323 }
1324 return true;
1325}
1326
1328{
1329 if (!isConnected())
1330 {
1331 SetTimer(2500);
1332 return;
1333 }
1334
1335 getData();
1336 SetTimer(2500);
1337}
1338
1340{
1343
1344 dc5diffSP.save(fp);
1345 dc5diffSETNP.save(fp);
1346 dc5constSETNP.save(fp);
1347 dc5ControlNP.save(fp);
1348
1349 dc6diffSP.save(fp);
1350 dc6diffSETNP.save(fp);
1351 dc6constSETNP.save(fp);
1352 dc6ControlNP.save(fp);
1353
1354 dc7diffSP.save(fp);
1355 dc7diffSETNP.save(fp);
1356 dc7constSETNP.save(fp);
1357 dc7ControlNP.save(fp);
1358
1359 setDC34voltageNP.save(fp);
1360 return true;
1361}
1362
1364{
1365 // Weather is updated in updateENV() which is called from getData()
1366 // This method is required by WeatherInterface but we update weather
1367 // synchronously with sensor data, so we just return OK
1368 return IPS_OK;
1369}
1370
double dewPoint
void registerHandshake(std::function< bool()> callback)
registerHandshake Register a handshake function to be called once the initial connection to the devic...
The Serial class manages connection with serial devices including Bluetooth. Serial communication is ...
void setDefaultBaudRate(BaudRate newRate)
setDefaultBaudRate Set default baud rate. The default baud rate is 9600 unless otherwise changed by t...
bool isConnected() const
const char * getDeviceName() const
virtual bool updateProperties()
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
void registerConnection(Connection::Interface *newConnection)
registerConnection Add new connection plugin to the existing connection pool. The connection type sha...
void setDriverInterface(uint32_t value)
setInterface Set driver interface. By default the driver interface is set to GENERAL_DEVICE....
void setVersion(uint16_t vMajor, uint16_t vMinor)
Set driver version information to be defined in DRIVER_INFO property as vMajor.vMinor.
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
void defineProperty(INumberVectorProperty *property)
virtual bool saveConfigItems(FILE *fp)
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
virtual bool initProperties()
Initialize properties initial state and value. The child class must implement this function.
void addAuxControls()
Add Debug, Simulation, and Configuration options to the driver.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process the client newNumber command.
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
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 syncCriticalParameters()
Synchronize and update the state of all critical parameters.
void setParameterValue(std::string name, double value)
setParameterValue Update weather parameter value
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.
INDI::PropertyNumber ParametersNP
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...
INDI::PropertyLight critialParametersLP
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 * getDefaultName() override
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 ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual IPState updateWeather() override
updateWeather Update weather conditions from device or service. The function should not change the st...
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
ISState
Switch state.
Definition indiapi.h:148
@ ISS_OFF
Definition indiapi.h:149
@ ISS_ON
Definition indiapi.h:150
@ IP_RW
Definition indiapi.h:184
@ IP_RO
Definition indiapi.h:182
IPState
Property state.
Definition indiapi.h:158
@ IPS_ALERT
Definition indiapi.h:162
@ IPS_IDLE
Definition indiapi.h:159
@ IPS_OK
Definition indiapi.h:160
@ ISR_1OFMANY
Definition indiapi.h:171
@ ISR_ATMOST1
Definition indiapi.h:172
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:653
int tty_write_string(int fd, const char *buf, int *nbytes_written)
Writes a null terminated string to fd.
Definition indicom.c:473
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
Definition indicom.c:1243
Implementations for common driver routines.
@ TTY_OK
Definition indicom.h:54
#define MAXRBUF
Definition indidriver.c:52
#define LOGF_INFO(fmt,...)
Definition indilogger.h:82
#define LOGF_DEBUG(fmt,...)
Definition indilogger.h:83
#define LOGF_ERROR(fmt,...)
Definition indilogger.h:80
#define LOG_INFO(txt)
Definition indilogger.h:74
Namespace to encapsulate INDI client, drivers, and mediator classes.
uint8_t cmd[4]
Definition pwc-ioctl.h:2