45 static const std::vector<std::string> supportedFeatures = {
46 "cover_control",
"light_control",
"position_setting"
48 return std::find(supportedFeatures.begin(), supportedFeatures.end(), feature) != supportedFeatures.end();
54 std::string dataStr(data);
55 std::vector<std::string> tokens;
57 std::istringstream tokenStream(dataStr);
59 while (std::getline(tokenStream, token,
'A'))
62 tokens.push_back(token);
66 if (tokens.size() < 2)
70 std::string deviceName = tokens[0];
73 if (deviceName ==
"WandererCoverV4Pro")
76 int firmwareVersion = std::atoi(tokens[1].c_str());
79 return firmwareVersion < 20250405 && firmwareVersion > 0;
91 std::string dataStr(data);
94 dataStr.erase(std::remove(dataStr.begin(), dataStr.end(),
'\n'), dataStr.end());
95 dataStr.erase(std::remove(dataStr.begin(), dataStr.end(),
'\r'), dataStr.end());
98 std::vector<std::string> tokens;
100 std::istringstream tokenStream(dataStr);
102 while (std::getline(tokenStream, token,
'A'))
105 tokens.push_back(token);
109 for (
size_t i = 0; i < tokens.size(); i++)
115 if (tokens.size() < 4)
121 std::string deviceName = tokens[0];
122 if (deviceName !=
"WandererCoverV4Pro")
125 if (deviceName ==
"ZXWBProV3" || deviceName ==
"ZXWBPlusV3" ||
126 deviceName ==
"UltimateV2" || deviceName ==
"PlusV2"|| deviceName ==
"WandererEclipse"|| deviceName ==
"WandererCoverV4")
138 device->firmware = std::atoi(tokens[1].c_str());
141 char firmwareStr[16];
142 snprintf(firmwareStr,
sizeof(firmwareStr),
"%d",
device->firmware);
143 device->FirmwareTP[
device->FIRMWARE_VERSION].setText(firmwareStr);
145 device->FirmwareTP.apply();
149 if (tokens.size() >= 5)
152 device->closesetread = std::strtod(tokens[2].c_str(), NULL);
153 device->opensetread = std::strtod(tokens[3].c_str(), NULL);
154 device->positionread = std::strtod(tokens[4].c_str(), NULL);
156 if (tokens.size() > 5)
158 device->voltageread = std::strtod(tokens[5].c_str(), NULL);
162 device->voltageread = 0.0;
172 device->statusData.closePositionSet =
device->closesetread;
173 device->statusData.openPositionSet =
device->opensetread;
174 device->statusData.currentPosition =
device->positionread;
183 device->CloseSetNP.apply();
187 device->OpenSetNP.apply();
191 catch(std::exception &e)
211 static const std::vector<std::string> supportedFeatures = {
212 "cover_control",
"light_control",
"position_setting",
213 "asiair_control",
"custom_brightness",
"extended_status"
215 return std::find(supportedFeatures.begin(), supportedFeatures.end(), feature) != supportedFeatures.end();
221 std::string dataStr(data);
222 std::vector<std::string> tokens;
224 std::istringstream tokenStream(dataStr);
226 while (std::getline(tokenStream, token,
'A'))
229 tokens.push_back(token);
233 if (tokens.size() < 2)
237 std::string deviceName = tokens[0];
240 if (deviceName ==
"WandererCoverV4Pro")
243 int firmwareVersion = std::atoi(tokens[1].c_str());
246 return firmwareVersion >= 20250405;
256 std::vector<std::string> tokens;
258 std::istringstream tokenStream(data);
260 while (std::getline(tokenStream, token,
'A'))
263 tokens.push_back(token);
266 if (tokens.size() < 8)
270 std::string deviceName = tokens[0];
271 if (deviceName !=
"WandererCoverV4Pro")
274 if (deviceName ==
"ZXWBProV3" || deviceName ==
"ZXWBPlusV3" ||
275 deviceName ==
"UltimateV2" || deviceName ==
"PlusV2"|| deviceName ==
"WandererEclipse"|| deviceName ==
"WandererDewTerminator"|| deviceName ==
"WandererCoverV4")
287 device->firmware = std::atoi(tokens[1].c_str());
290 char firmwareStr[16];
291 snprintf(firmwareStr,
sizeof(firmwareStr),
"%d",
device->firmware);
292 device->FirmwareTP[
device->FIRMWARE_VERSION].setText(firmwareStr);
294 device->FirmwareTP.apply();
297 device->closesetread = std::strtod(tokens[2].c_str(), NULL);
298 device->opensetread = std::strtod(tokens[3].c_str(), NULL);
299 device->positionread = std::strtod(tokens[4].c_str(), NULL);
300 device->voltageread = std::strtod(tokens[5].c_str(), NULL);
303 if (tokens.size() >= 8)
305 device->flatpanelbrightnessread = std::atoi(tokens[6].c_str());
306 device->statusData.flatPanelBrightness =
device->flatpanelbrightnessread;
308 device->asiaircontrolenabledread = (tokens.size() > 8) ? (std::atoi(tokens[8].c_str()) == 1) :
false;
309 device->statusData.asiairControlEnabled =
device->asiaircontrolenabledread;
316 device->statusData.closePositionSet =
device->closesetread;
317 device->statusData.openPositionSet =
device->opensetread;
318 device->statusData.currentPosition =
device->positionread;
327 device->CloseSetNP.apply();
331 device->OpenSetNP.apply();
335 catch(std::exception &e)
361 return "WandererCover V4 Pro-EC";
378 DataNP[closeset_read].
fill(
"Closed_Position",
"Closed Position Set(°)",
"%4.2f", 0, 999, 100, 0);
379 DataNP[openset_read].
fill(
"Open_Position",
"Open Position Set(°)",
"%4.2f", 0, 999, 100, 0);
380 DataNP[position_read].
fill(
"Current_Position",
"Current Position(°)",
"%4.2f", 0, 999, 100, 0);
381 DataNP[voltage_read].
fill(
"Voltage",
"Voltage (V)",
"%4.2f", 0, 999, 100, 0);
382 DataNP[flat_panel_brightness_read].
fill(
"Flat_Panel_Brightness",
"Flat Panel Brightness",
"%4.2f", 0, 255, 1, 0);
383 DataNP[asiair_control_enabled_read].
fill(
"ASIAIR_Control_Enabled",
"ASIAIR Control Enabled",
"%4.2f", 0, 1, 1, 0);
387 FirmwareTP[FIRMWARE_VERSION].
fill(
"FIRMWARE_VERSION",
"Firmware Version",
"Unknown");
395 CloseSetNP[CloseSet].
fill(
"CloseSet",
"10-90",
"%.2f", 10, 90, 0.01, 20);
399 OpenSetNP[OpenSet].
fill(
"OpenSet",
"100-300",
"%.2f", 100, 300, 0.01, 150);
403 ASIAIRControlSP[ASIAIR_ENABLE].
fill(
"ASIAIR_ENABLE",
"Enable ASIAIR Control",
ISS_OFF);
404 ASIAIRControlSP[ASIAIR_DISABLE].
fill(
"ASIAIR_DISABLE",
"Disable ASIAIR Control",
ISS_ON);
407 CustomBrightnessNP[CUSTOM_BRIGHTNESS_1].
fill(
"CUSTOM_BRIGHTNESS_1",
"Custom Brightness 1",
"%1.0f", 0, 255, 1, 1);
408 CustomBrightnessNP[CUSTOM_BRIGHTNESS_2].
fill(
"CUSTOM_BRIGHTNESS_2",
"Custom Brightness 2",
"%1.0f", 0, 255, 1, 50);
409 CustomBrightnessNP[CUSTOM_BRIGHTNESS_3].
fill(
"CUSTOM_BRIGHTNESS_3",
"Custom Brightness 3",
"%1.0f", 0, 255, 1, 255);
419 return detectProtocol();
436 char firmwareStr[16];
437 snprintf(firmwareStr,
sizeof(firmwareStr),
"%d", firmware);
438 FirmwareTP[FIRMWARE_VERSION].setText(firmwareStr);
442 CloseSetNP[CloseSet].setValue(closesetread);
443 OpenSetNP[OpenSet].setValue(opensetread);
451 if (currentProtocol && currentProtocol->supportsFeature(
"asiair_control"))
455 if (currentProtocol && currentProtocol->supportsFeature(
"custom_brightness"))
497bool WandererCoverV4ProEC::detectProtocol()
501 LOG_DEBUG(
"Starting protocol detection...");
504 if (!serialPortMutex.try_lock_for(std::chrono::milliseconds(100)))
506 LOG_DEBUG(
"Serial port is busy during protocol detection");
510 std::lock_guard<std::timed_mutex> lock(serialPortMutex, std::adopt_lock);
513 tcflush(PortFD, TCIOFLUSH);
517 int nbytes_read = 0, rc = -1;
521 if (ioctl(PortFD, FIONREAD, &available) == 0)
523 LOGF_DEBUG(
"Bytes available for reading: %d", available);
530 LOG_DEBUG(
"Timeout reading from device during protocol detection");
531 LOG_DEBUG(
"Trying to read any available data without timeout...");
536 LOGF_DEBUG(
"Found %d bytes without timeout: '%s'", nbytes_read, buffer);
540 LOG_DEBUG(
"No data available without timeout either");
543 LOG_ERROR(
"Protocol detection failed: No data received from device");
549 LOGF_ERROR(
"Failed to read data from device during protocol detection. Error: %s", errorMessage);
553 LOGF_DEBUG(
"Raw data received from device: '%s' (length: %d)", buffer, nbytes_read);
556 std::string dataStr(buffer);
557 std::vector<std::string> tokens;
559 std::istringstream tokenStream(dataStr);
561 while (std::getline(tokenStream, token,
'A'))
564 tokens.push_back(token);
567 LOGF_DEBUG(
"Parsed %zu tokens from device data", tokens.size());
568 for (
size_t i = 0; i < tokens.size(); i++)
570 LOGF_DEBUG(
"Token[%zu]: '%s'", i, tokens[i].c_str());
574 if (tokens.size() < 2)
576 LOGF_ERROR(
"Invalid data format: Not enough tokens. Expected at least 2, got %zu", tokens.size());
581 std::string deviceName = tokens[0];
582 LOGF_DEBUG(
"Device identification: '%s'", deviceName.c_str());
585 if (deviceName ==
"WandererCoverV4Pro")
587 LOG_INFO(
"WandererCover V4 Pro-EC device detected");
590 else if (deviceName ==
"ZXWBProV3" || deviceName ==
"ZXWBPlusV3" ||
591 deviceName ==
"UltimateV2" || deviceName ==
"PlusV2"|| deviceName ==
"WandererEclipse"|| deviceName ==
"WandererDewTerminator"|| deviceName ==
"WandererCoverV4")
593 LOGF_ERROR(
"WandererAstro products detected, but the model does not match:'%s'. This driver is designed for WandererCover V4 Pro-EC, please choose the right driver or try another serial port!", deviceName.c_str());
598 LOGF_ERROR(
"Unsupported device detected: '%s'. Expected 'WandererCoverV4Pro'", deviceName.c_str());
599 LOG_ERROR(
"This driver is specifically designed for WandererCover V4 Pro-EC devices only.");
604 int firmwareVersion = std::atoi(tokens[1].c_str());
605 LOGF_INFO(
"Detected firmware version: %d", firmwareVersion);
608 if (firmwareVersion <= 0)
610 LOGF_ERROR(
"Invalid firmware version: %d. Cannot determine protocol.", firmwareVersion);
615 if (firmwareVersion >= 20250405)
617 std::unique_ptr<WandererCoverModernProtocol> modernProtocol = std::make_unique<WandererCoverModernProtocol>();
618 setProtocol(std::move(modernProtocol));
619 LOG_INFO(
"Using modern protocol (firmware >= 20250405) Please note that in the newer firmware, to protect dark conditions, the flat light will remain off whenever the Cover is open.");
622 else if (firmwareVersion > 0)
624 std::unique_ptr<WandererCoverLegacyProtocol> legacyProtocol = std::make_unique<WandererCoverLegacyProtocol>();
625 setProtocol(std::move(legacyProtocol));
626 LOG_INFO(
"Using legacy protocol (firmware < 20250405) Firmware update recommended.");
631 LOGF_ERROR(
"Invalid firmware version: %d. Cannot determine protocol.", firmwareVersion);
635 catch(std::exception &e)
637 LOGF_ERROR(
"Exception occurred during protocol detection: %s", e.what());
642void WandererCoverV4ProEC::setProtocol(std::unique_ptr<IWandererCoverProtocol> protocol)
644 currentProtocol = std::move(protocol);
651bool WandererCoverV4ProEC::getData()
654 if (!serialPortMutex.try_lock_for(std::chrono::milliseconds(100)))
656 LOG_DEBUG(
"Serial port is busy, skipping status update");
660 std::lock_guard<std::timed_mutex> lock(serialPortMutex, std::adopt_lock);
664 LOG_DEBUG(
"Reading data from device...");
667 tcflush(PortFD, TCIOFLUSH);
671 int nbytes_read = 0, rc = -1;
679 LOG_DEBUG(
"Timeout reading from device, will try again later");
685 LOGF_ERROR(
"Failed to read data from device. Error: %s", errorMessage);
689 LOGF_DEBUG(
"Data received from device: '%s' (length: %d)", buffer, nbytes_read);
692 bool parseResult = parseDeviceData(buffer);
693 LOGF_DEBUG(
"Data parsing result: %s", parseResult ?
"success" :
"failed");
696 catch(std::exception &e)
698 LOGF_ERROR(
"Exception occurred while reading data from device: %s", e.what());
705bool WandererCoverV4ProEC::parseDeviceData(
const char *data)
707 if (!currentProtocol)
709 LOG_ERROR(
"No protocol handler available");
713 LOGF_DEBUG(
"Parsing data with protocol: %s", currentProtocol->getProtocolName().c_str());
714 return currentProtocol->parseDeviceData(data,
this);
720void WandererCoverV4ProEC::updateData(
double closesetread,
double opensetread,
double positionread,
double voltageread,
double flatpanelbrightnessread,
double asiaircontrolenabledread)
723 DataNP[closeset_read].setValue(closesetread);
724 DataNP[openset_read].setValue(opensetread);
725 DataNP[position_read].setValue(positionread);
726 DataNP[voltage_read].setValue(voltageread);
730 if (currentProtocol && currentProtocol->supportsFeature(
"extended_status"))
732 DataNP[flat_panel_brightness_read].setValue(flatpanelbrightnessread);
733 DataNP[asiair_control_enabled_read].setValue(asiaircontrolenabledread);
738 DataNP[flat_panel_brightness_read].setValue(-1);
739 DataNP[asiair_control_enabled_read].setValue(-1);
758 if ((prevParked != currentParked) || (prevState != currentState))
789 if (!currentProtocol || !currentProtocol->supportsFeature(
"asiair_control"))
791 LOG_ERROR(
"ASIAIR control not supported by current protocol");
793 ASIAIRControlSP.
apply();
798 for (
int i = 0; i < n; i++)
800 if (strcmp(names[i],
"ASIAIR_ENABLE") == 0 && states[i] ==
ISS_ON)
802 rc = sendCommand(currentProtocol->generateASIAIRControlCommand(
true));
804 else if (strcmp(names[i],
"ASIAIR_DISABLE") == 0 && states[i] ==
ISS_ON)
806 rc = sendCommand(currentProtocol->generateASIAIRControlCommand(
false));
812 ASIAIRControlSP.
update(states, names, n);
813 ASIAIRControlSP.
apply();
820 return DefaultDevice::ISNewSwitch(dev, name, states, names, n);
837 if (!currentProtocol)
839 LOG_ERROR(
"No protocol handler available");
847 for (
int i = 0; i < n; i++)
849 if(values[i] < 10 || values[i] > 90)
852 LOG_ERROR(
"Out of range! Allowed closed angle: 10-90 degrees.");
855 rc1 = sendCommand(currentProtocol->generateSetClosePositionCommand(values[i]));
861 CloseSetNP.
update(values, names, n);
870 if (!currentProtocol)
872 LOG_ERROR(
"No protocol handler available");
880 for (
int i = 0; i < n; i++)
882 if(values[i] < 100 || values[i] > 300)
885 LOG_ERROR(
"Out of range! Allowed open angle: 100-300 degrees.");
888 rc1 = sendCommand(currentProtocol->generateSetOpenPositionCommand(values[i]));
894 OpenSetNP.
update(values, names, n);
904 if (!currentProtocol || !currentProtocol->supportsFeature(
"custom_brightness"))
906 LOG_ERROR(
"Custom brightness not supported by current protocol");
908 CustomBrightnessNP.
apply();
913 for (
int i = 0; i < n; i++)
915 if (strcmp(names[i],
"CUSTOM_BRIGHTNESS_1") == 0)
917 rc = sendCommand(currentProtocol->generateCustomBrightnessCommand(
static_cast<int>(values[i]), 1));
919 else if (strcmp(names[i],
"CUSTOM_BRIGHTNESS_2") == 0)
921 rc = sendCommand(currentProtocol->generateCustomBrightnessCommand(
static_cast<int>(values[i]), 2));
923 else if (strcmp(names[i],
"CUSTOM_BRIGHTNESS_3") == 0)
925 rc = sendCommand(currentProtocol->generateCustomBrightnessCommand(
static_cast<int>(values[i]), 3));
931 CustomBrightnessNP.
update(values, names, n);
932 CustomBrightnessNP.
apply();
942bool WandererCoverV4ProEC::toggleCover(
bool open)
944 if (!currentProtocol)
946 LOG_ERROR(
"No protocol handler available");
950 std::string command = open ? currentProtocol->generateOpenCommand() : currentProtocol->generateCloseCommand();
951 return sendCommand(command);
963 if (toggleCover(
false))
983 if (toggleCover(
true))
999 if (!currentProtocol)
1001 LOG_ERROR(
"No protocol handler available");
1010 rc = sendCommand(currentProtocol->generateSetBrightnessCommand(value));
1029 if (!currentProtocol)
1031 LOG_ERROR(
"No protocol handler available");
1037 rc = sendCommand(currentProtocol->generateTurnOffLightCommand());
1039 rc = sendCommand(currentProtocol->generateSetBrightnessCommand(
static_cast<int>(
LightIntensityNP[0].getValue())));
1047bool WandererCoverV4ProEC::sendCommand(std::string command)
1050 std::lock_guard<std::timed_mutex> lock(serialPortMutex);
1052 int nbytes_written = 0, rc = -1;
1053 std::string command_termination =
"\n";
1059 LOGF_ERROR(
"Serial write error: %s", errorMessage);
1070bool WandererCoverV4ProEC::setClose(
double value)
1072 if (!currentProtocol)
1074 LOG_ERROR(
"No protocol handler available");
1078 return sendCommand(currentProtocol->generateSetClosePositionCommand(value));
1084bool WandererCoverV4ProEC::setOpen(
double value)
1086 if (!currentProtocol)
1088 LOG_ERROR(
"No protocol handler available");
1092 return sendCommand(currentProtocol->generateSetOpenPositionCommand(value));
1117 CloseSetNP.
save(fp);
1119 CustomBrightnessNP.
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...
Provides interface to implement remotely controlled dust cover.
const char * getDeviceName() const
virtual bool updateProperties()
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual bool saveConfig(bool silent=false, const char *property=nullptr)
Save the current properties in a configuration file.
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.
virtual void ISGetProperties(const char *dev)
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
virtual bool ISSnoopDevice(XMLEle *root)
Process a snoop event from INDI server. This function is called when a snooped property is updated in...
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.
uint32_t getPollingPeriod() const
getPollingPeriod Return the polling period.
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.
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
Process the client newSwitch command.
INDI::PropertySwitch ParkCapSP
bool updateProperties()
updateProperties Defines or Delete properties based on default device connection status
void initProperties(const char *group, uint32_t capabilities=0)
Initialize dust cap properties. It is recommended to call this function within initProperties() of yo...
bool processSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process dust cap switch properties.
void initProperties(const char *group, uint32_t capabilities)
Initialize light box properties. It is recommended to call this function within initProperties() of y...
void ISGetProperties(const char *deviceName)
isGetLightBoxProperties Get light box properties
INDI::PropertyNumber LightIntensityNP
bool saveConfigItems(FILE *fp)
bool processSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process light box switch properties.
bool processText(const char *dev, const char *name, char *texts[], char *names[], int n)
Process light box text properties.
bool processNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process light box number properties.
INDI::PropertySwitch LightSP
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 fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
Provides interface to implement controllable light box/switch device.
bool detectProtocol(const char *data) override
std::string generateSetBrightnessCommand(uint16_t value) const override
std::string generateCustomBrightnessCommand(int brightness, int customNumber) const override
std::string generateCloseCommand() const override
std::string generateSetClosePositionCommand(double value) const override
bool supportsFeature(const std::string &feature) const override
std::string generateSetOpenPositionCommand(double value) const override
std::string generateOpenCommand() const override
std::string generateTurnOffLightCommand() const override
bool parseDeviceData(const char *data, WandererCoverV4EC *device) override
std::string generateASIAIRControlCommand(bool enable) const override
std::string generateTurnOffLightCommand() const override
bool supportsFeature(const std::string &feature) const override
std::string generateASIAIRControlCommand(bool enable) const override
bool parseDeviceData(const char *data, WandererCoverV4EC *device) override
bool detectProtocol(const char *data) override
std::string generateCloseCommand() const override
std::string generateSetBrightnessCommand(uint16_t value) const override
std::string generateSetOpenPositionCommand(double value) const override
std::string generateCustomBrightnessCommand(int brightness, int customNumber) const override
std::string generateOpenCommand() const override
std::string generateSetClosePositionCommand(double value) const override
virtual bool initProperties() override
Initialize properties initial state and value. The child class must implement this function.
virtual IPState ParkCap() override
Park dust cap (close cover). Must be implemented by child.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
const char * getDefaultName() override
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
virtual bool SetLightBoxBrightness(uint16_t value) override
setBrightness Set light level. Must be implemented in the child class, if supported.
virtual void ISGetProperties(const char *dev) override
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
virtual bool ISSnoopDevice(XMLEle *root) override
Process a snoop event from INDI server. This function is called when a snooped property is updated in...
virtual IPState UnParkCap() override
unPark dust cap (open cover). Must be implemented by child.
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
virtual bool EnableLightBox(bool enable) override
EnableLightBox Turn on/off on a light box. Must be implemented in the child class.
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_read(int fd, char *buf, int nbytes, int timeout, int *nbytes_read)
read buffer from terminal
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 LOG_ERROR(txt)
Shorter logging macros. In order to use these macros, the function (or method) "getDeviceName()" must...
#define LOGF_ERROR(fmt,...)
std::vector< uint8_t > buffer