39static std::unique_ptr<WandererBoxPlusV3> WandererBoxplusv3(
new WandererBoxPlusV3());
60 CalibrateSP[0].
fill(
"Calibrate",
"Calibrate Current",
ISS_OFF);
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);
76 DC3ControlNP[DC3].
fill(
"DC3",
"Dew Heater (PWM)",
"%.2f", 0, 255, 5, 0);
80 setDC2voltageNP[setDC2voltage].
fill(
"DC2SET",
"Adjustable Voltage",
"%.2f", 5, 13.2, 0.1, 0);
93 DC3diffSP[DC3_Manual].
fill(
"Manual",
"Manual",
ISS_ON);
94 DC3diffSP[DC3_DPD_Mode].
fill(
"DPD_Mode",
"DPD Mode",
ISS_OFF);
95 DC3diffSP[DC3_CT_Mode].
fill(
"CT_Mode",
"CT Mode",
ISS_OFF);
98 DC3diffSETNP[DC3DIFFSET].
fill(
"DC3 Auto Control",
"Dew Point Difference(C)",
"%.2f", 10, 30, 1, 0);
101 DC3constSETNP[DC3CONSTSET].
fill(
"DC3 Auto Control",
"Temperature(C)",
"%.2f", 0, 40, 1, 0);
105 ENVMonitorNP[Probe1_Temp].
fill(
"Probe1_Temp",
"Probe1 Temperature (C)",
"%4.2f", 0, 999, 100, 0);
106 ENVMonitorNP[ENV_Humidity].
fill(
"ENV_Humidity",
"Ambient Humidity %",
"%4.2f", 0, 999, 100, 0);
107 ENVMonitorNP[ENV_Temp].
fill(
"ENV_Temp",
"Ambient Temperature (C)",
"%4.2f", 0, 999, 100, 0);
108 ENVMonitorNP[DEW_Point].
fill(
"DEW_Point",
"Dew Point (C)",
"%4.2f", 0, 999, 100, 0);
112 addParameter(
"WEATHER_TEMPERATURE",
"Temperature (C)", -15, 35, 15);
113 addParameter(
"WEATHER_HUMIDITY",
"Humidity %", 0, 100, 15);
114 addParameter(
"WEATHER_DEWPOINT",
"Dew Point (C)", 0, 100, 15);
127bool WandererBoxPlusV3::getData()
132 tcflush(PortFD, TCIOFLUSH);
133 int nbytes_read_name = 0,rc=-1;
141 LOGF_INFO(
"No data received, the device may not be WandererBox Plus V3, please check the serial port!",
"Updated");
142 LOGF_ERROR(
"Device read error: %s", errorMessage);
145 name[nbytes_read_name - 1] =
'\0';
146 if(strcmp(name,
"ZXWBProV3")==0||strcmp(name,
"WandererCoverV4")==0||strcmp(name,
"UltimateV2")==0||strcmp(name,
"PlusV2")==0)
148 LOGF_INFO(
"The device is not WandererBox Plus V3!",
"Updated");
151 if(strcmp(name,
"ZXWBPlusV3")!=0)
153 LOGF_ERROR(
"Device is not WandererBox Plus V3 (got '%s'). Wrong port or device.", name);
157 int nbytes_read_version = 0;
158 char version[64] = {0};
161 version[nbytes_read_version - 1] =
'\0';
162 firmware=std::atoi(version);
166 char temp1[64] = {0};
167 int nbytes_read_temp1= 0;
169 temp1[nbytes_read_temp1 - 1] =
'\0';
170 temp1read = std::strtod(temp1,NULL);
174 int nbytes_read_DHTH= 0;
176 DHTH[nbytes_read_DHTH - 1] =
'\0';
177 DHTHread = std::strtod(DHTH,NULL);
181 int nbytes_read_DHTT= 0;
183 DHTT[nbytes_read_DHTT - 1] =
'\0';
184 DHTTread = std::strtod(DHTT,NULL);
185 updateENV(temp1read,DHTHread,DHTTread);
188 char Tcurrent[64] = {0};
189 int nbytes_read_Tcurrent= 0;
191 Tcurrent[nbytes_read_Tcurrent - 1] =
'\0';
192 Tcurrentread = std::strtod(Tcurrent,NULL);
195 char voltage[64] = {0};
196 int nbytes_read_voltage= 0;
198 voltage[nbytes_read_voltage - 1] =
'\0';
199 voltageread = std::strtod(voltage,NULL);
200 updatePower(Tcurrentread,voltageread);
204 int nbytes_read_USB= 0;
206 USB[nbytes_read_USB - 1] =
'\0';
207 USBread = std::stoi(USB);
213 int nbytes_read_DC2= 0;
215 DC2[nbytes_read_DC2 - 1] =
'\0';
216 DC2read = std::stoi(DC2);
221 int nbytes_read_DC3= 0;
223 DC3[nbytes_read_DC3 - 1] =
'\0';
224 DC3read = std::stoi(DC3);
229 char DC4_6[64] = {0};
230 int nbytes_read_DC4_6= 0;
232 DC4_6[nbytes_read_DC4_6 - 1] =
'\0';
233 DC4_6read =std::stoi(DC4_6);
234 updateDC4_6(DC4_6read);
238 char DC2SET[64] = {0};
239 int nbytes_read_DC2SET= 0;
241 DC2SET[nbytes_read_DC2SET - 1] =
'\0';
243 DC2SETread = std::stoi(DC2SET);
244 updateDC2SET(DC2SETread);
248 if(DC3diffSP[DC3_DPD_Mode].getState() ==
ISS_ON)
250 if(temp1read<ENVMonitorNP[DEW_Point].value+DC3diffSETNP[DC3DIFFSET].value)
256 if(DC3CONSTMODE==
true )
258 if(temp1read<DC3constSETNP[DC3CONSTSET].value)
263 if (DC3diffSP[DC3_DPD_Mode].getState() ==
ISS_ON&&ENVMonitorNP[Probe1_Temp].value==-127)
270 LOGF_ERROR(
"Temp probe 1 not connected, Dew Point Difference Mode for DC3 has exited!",
"Updated");
271 LOGF_INFO(
"You need to insert the probe firmly to the end!",
"Updated");
278 if (DC3diffSP[DC3_DPD_Mode].getState() ==
ISS_ON&&isnan(ENVMonitorNP[DEW_Point].value)==1)
285 LOGF_ERROR(
"DHT22 Humidity&Temperature sensor not connected, Dew Point Difference Mode for DC3 has exited!",
"Updated");
292 if (DC3diffSP[DC3_CT_Mode].getState() ==
ISS_ON&&ENVMonitorNP[Probe1_Temp].value==-127)
299 LOGF_ERROR(
"Temp probe 1 not connected, Constant Temperature Mode for DC3 has exited!",
"Updated");
300 LOGF_INFO(
"You need to insert the probe firmly to the end!",
"Updated");
309 catch(std::exception& e)
318void WandererBoxPlusV3::updateENV(
double temp1,
double DHTH,
double DHTT)
320 ENVMonitorNP[Probe1_Temp].setValue(temp1);
321 ENVMonitorNP[ENV_Humidity].setValue(DHTH);
322 ENVMonitorNP[ENV_Temp].setValue(DHTT);
323 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))));
324 ENVMonitorNP[DEW_Point].setValue(
dewPoint);
326 ENVMonitorNP.
apply();
339void WandererBoxPlusV3::updatePower(
double Tcurrent,
double voltage)
342 PowerMonitorNP[VOLTAGE].setValue(voltage);
343 PowerMonitorNP[TOTAL_CURRENT].setValue(Tcurrent);
346 PowerMonitorNP.
apply();
349void WandererBoxPlusV3::updateUSB(
int res)
354 USBControlSP.
apply();
357void WandererBoxPlusV3::updateDC2(
int res)
362 dc2ControlSP.
apply();
365void WandererBoxPlusV3::updateDC3(
int res)
367 DC3ControlNP[0].setValue(res);
369 DC3ControlNP.
apply();
373void WandererBoxPlusV3::updateDC4_6(
int res)
378 DC4_6ControlSP.
apply();
382void WandererBoxPlusV3::updateDC2SET(
double res)
384 setDC2voltageNP[setDC2voltage].setValue(res/10);
386 setDC2voltageNP.
apply();
398 if(firmware>=20240216)
401 LOGF_INFO(
"Firmware version: %d", firmware);
405 LOGF_INFO(
"The firmware is outdated, please upgrade to the latest firmware, or power reading calibration will be unavailable.",
"failed");
423 if(DC3diffSP[DC3_DPD_Mode].getState() ==
ISS_ON)
429 else if(DC3diffSP[DC3_CT_Mode].getState() ==
ISS_ON)
480 if (strstr(name,
"WEATHER_"))
489 LOG_INFO(
"Calibrating Current Readings...");
497 dc2ControlSP.
update(states, names, n);
502 dc2ControlSP.
apply();
509 DC4_6ControlSP.
update(states, names, n);
514 DC4_6ControlSP.
apply();
522 USBControlSP.
update(states, names, n);
534 DC3diffSP.
update(states, names, n);
536 if(DC3diffSP[DC3_DPD_Mode].getState() ==
ISS_ON&&ENVMonitorNP[Probe1_Temp].value!=-127&&isnan(ENVMonitorNP[DEW_Point].value)==0)
545 DC3diffSETNP.
apply();
548 LOGF_INFO(
"Dew Point Difference Mode for DC3 activated! WandererBox will keep the dew heater at the temperature higher than the dew point by the set value.",
"Updated");
551 else if(DC3diffSP[DC3_DPD_Mode].getState() ==
ISS_ON&&(ENVMonitorNP[Probe1_Temp].value==-127||isnan(ENVMonitorNP[DEW_Point].value)==1))
556 LOGF_INFO(
"Manual Mode for DC3 activated! Please adjust the duty cycle manually, you can also use DC3 as an ordinary switch.",
"Updated");
559 else if(DC3diffSP[DC3_CT_Mode].getState() ==
ISS_ON&&ENVMonitorNP[Probe1_Temp].value!=-127)
568 DC3constSETNP.
apply();
571 LOGF_INFO(
"Constant Temperature Mode for DC3 activated! WandererBox will keep the dew heater at the set temperature.",
"Updated");
574 else if(DC3diffSP[DC3_CT_Mode].getState() ==
ISS_ON&&ENVMonitorNP[Probe1_Temp].value==-127)
579 LOGF_INFO(
"Manual Mode for DC3 activated! Please adjust the duty cycle manually, you can also use DC3 as an ordinary switch.",
"Updated");
591 LOGF_INFO(
"Manual Mode for DC3 activated! Please adjust the duty cycle manually, you can also use DC3 as an ordinary switch.",
"Updated");
598 return DefaultDevice::ISNewSwitch(dev, name, states, names, n);
605 if (strstr(name,
"WEATHER_"))
611 for (
int i = 0; i < n; i++)
613 rc1 = setDewPWM(3,
static_cast<uint8_t
>(values[i]));
618 DC3ControlNP.
update(values, names, n);
619 DC3ControlNP.
apply();
627 DC3diffSETNP.
update(values, names, n);
628 DC3diffSETNP.
apply();
636 DC3constSETNP.
update(values, names, n);
637 DC3constSETNP.
apply();
645 for (
int i = 0; i < n; i++)
647 rc1 = setDewPWM(20,
static_cast<uint8_t
>(10*values[i]));
652 setDC2voltageNP.
update(values, names, n);
653 setDC2voltageNP.
apply();
662bool WandererBoxPlusV3::setDewPWM(uint8_t
id, uint8_t value)
665 snprintf(
cmd, 64,
"%d%03d",
id, value);
666 if (sendCommand(
cmd))
676 return "WandererBox Pro V3";
680bool WandererBoxPlusV3::sendCommand(std::string command)
682 int nbytes_written = 0, rc = -1;
683 std::string command_termination =
"\n";
689 LOGF_ERROR(
"Serial write error: %s", errorMessage);
713 DC3diffSETNP.
save(fp);
714 DC3constSETNP.
save(fp);
715 DC3ControlNP.
save(fp);
717 setDC2voltageNP.
save(fp);
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...
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 updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
virtual IPState updateWeather() override
updateWeather Update weather conditions from device or service. The function should not change the st...
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
virtual bool initProperties() override
Initialize properties initial state and value. The child class must implement this function.
const char * getDefaultName() override
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
int tty_read_section(int fd, char *buf, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
int tty_write_string(int fd, const char *buf, int *nbytes_written)
Writes a null terminated string to fd.
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
Implementations for common driver routines.
#define LOGF_INFO(fmt,...)
#define LOGF_DEBUG(fmt,...)
#define LOGF_ERROR(fmt,...)
Namespace to encapsulate INDI client, drivers, and mediator classes.