39static std::unique_ptr<WandererCoverV4EC> wanderercoverv4ec(
new WandererCoverV4EC());
45 static const std::vector<std::string> supportedFeatures = {
46 "cover_control",
"light_control",
"heater_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 ==
"WandererCoverV4")
76 int firmwareVersion = std::atoi(tokens[1].c_str());
79 return firmwareVersion < 20250404 && 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 !=
"WandererCoverV4")
125 if (deviceName ==
"ZXWBProV3" || deviceName ==
"ZXWBPlusV3" ||
126 deviceName ==
"UltimateV2" || deviceName ==
"PlusV2")
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)
214 static const std::vector<std::string> supportedFeatures = {
215 "cover_control",
"light_control",
"heater_control",
"position_setting",
216 "asiair_control",
"custom_brightness",
"auto_detect",
"extended_status"
218 return std::find(supportedFeatures.begin(), supportedFeatures.end(), feature) != supportedFeatures.end();
224 std::string dataStr(data);
225 std::vector<std::string> tokens;
227 std::istringstream tokenStream(dataStr);
229 while (std::getline(tokenStream, token,
'A'))
232 tokens.push_back(token);
236 if (tokens.size() < 2)
240 std::string deviceName = tokens[0];
243 if (deviceName ==
"WandererCoverV4")
246 int firmwareVersion = std::atoi(tokens[1].c_str());
249 return firmwareVersion >= 20250404;
259 std::vector<std::string> tokens;
261 std::istringstream tokenStream(data);
263 while (std::getline(tokenStream, token,
'A'))
266 tokens.push_back(token);
269 if (tokens.size() < 8)
273 std::string deviceName = tokens[0];
274 if (deviceName !=
"WandererCoverV4")
277 if (deviceName ==
"ZXWBProV3" || deviceName ==
"ZXWBPlusV3" ||
278 deviceName ==
"UltimateV2" || deviceName ==
"PlusV2")
290 device->firmware = std::atoi(tokens[1].c_str());
293 char firmwareStr[16];
294 snprintf(firmwareStr,
sizeof(firmwareStr),
"%d",
device->firmware);
295 device->FirmwareTP[
device->FIRMWARE_VERSION].setText(firmwareStr);
297 device->FirmwareTP.apply();
300 device->closesetread = std::strtod(tokens[2].c_str(), NULL);
301 device->opensetread = std::strtod(tokens[3].c_str(), NULL);
302 device->positionread = std::strtod(tokens[4].c_str(), NULL);
303 device->voltageread = std::strtod(tokens[5].c_str(), NULL);
306 if (tokens.size() >= 8)
308 device->flatpanelbrightnessread = std::atoi(tokens[6].c_str());
309 device->statusData.flatPanelBrightness =
device->flatpanelbrightnessread;
310 device->dewheaterpowerread = std::atoi(tokens[7].c_str());
311 device->statusData.dewHeaterPower =
device->dewheaterpowerread;
312 device->asiaircontrolenabledread = (tokens.size() > 8) ? (std::atoi(tokens[8].c_str()) == 1) :
false;
313 device->statusData.asiairControlEnabled =
device->asiaircontrolenabledread;
318 device->statusData.closePositionSet =
device->closesetread;
319 device->statusData.openPositionSet =
device->opensetread;
320 device->statusData.currentPosition =
device->positionread;
329 device->CloseSetNP.apply();
333 device->OpenSetNP.apply();
337 catch(std::exception &e)
366 return "WandererCover V4-EC";
383 DataNP[closeset_read].
fill(
"Closed_Position",
"Closed Position Set(°)",
"%4.2f", 0, 999, 100, 0);
384 DataNP[openset_read].
fill(
"Open_Position",
"Open Position Set(°)",
"%4.2f", 0, 999, 100, 0);
385 DataNP[position_read].
fill(
"Current_Position",
"Current Position(°)",
"%4.2f", 0, 999, 100, 0);
386 DataNP[voltage_read].
fill(
"Voltage",
"Voltage (V)",
"%4.2f", 0, 999, 100, 0);
387 DataNP[flat_panel_brightness_read].
fill(
"Flat_Panel_Brightness",
"Flat Panel Brightness",
"%4.2f", 0, 255, 1, 0);
388 DataNP[dew_heater_power_read].
fill(
"Dew_Heater_Power",
"Dew Heater Power",
"%4.2f", 0, 150, 1, 0);
389 DataNP[asiair_control_enabled_read].
fill(
"ASIAIR_Control_Enabled",
"ASIAIR Control Enabled",
"%4.2f", 0, 1, 1, 0);
393 FirmwareTP[FIRMWARE_VERSION].
fill(
"FIRMWARE_VERSION",
"Firmware Version",
"Unknown");
400 SetHeaterNP[Heat].
fill(
"Heater",
"PWM",
"%.2f", 0, 150, 50, 0);
404 CloseSetNP[CloseSet].
fill(
"CloseSet",
"10-90",
"%.2f", 10, 90, 0.01, 20);
408 OpenSetNP[OpenSet].
fill(
"OpenSet",
"100-300",
"%.2f", 100, 300, 0.01, 150);
412 ASIAIRControlSP[ASIAIR_ENABLE].
fill(
"ASIAIR_ENABLE",
"Enable ASIAIR Control",
ISS_OFF);
413 ASIAIRControlSP[ASIAIR_DISABLE].
fill(
"ASIAIR_DISABLE",
"Disable ASIAIR Control",
ISS_ON);
416 CustomBrightnessNP[CUSTOM_BRIGHTNESS_1].
fill(
"CUSTOM_BRIGHTNESS_1",
"Custom Brightness 1",
"%1.0f", 0, 255, 1, 1);
417 CustomBrightnessNP[CUSTOM_BRIGHTNESS_2].
fill(
"CUSTOM_BRIGHTNESS_2",
"Custom Brightness 2",
"%1.0f", 0, 255, 1, 50);
418 CustomBrightnessNP[CUSTOM_BRIGHTNESS_3].
fill(
"CUSTOM_BRIGHTNESS_3",
"Custom Brightness 3",
"%1.0f", 0, 255, 1, 255);
421 AutoDetectSP[AUTO_DETECT_OPEN].
fill(
"AUTO_DETECT_OPEN",
"Auto Detect Open Position",
ISS_OFF);
422 AutoDetectSP[AUTO_DETECT_CLOSE].
fill(
"AUTO_DETECT_CLOSE",
"Auto Detect Close Position",
ISS_OFF);
431 return detectProtocol();
448 char firmwareStr[16];
449 snprintf(firmwareStr,
sizeof(firmwareStr),
"%d", firmware);
450 FirmwareTP[FIRMWARE_VERSION].setText(firmwareStr);
454 CloseSetNP[CloseSet].setValue(closesetread);
455 OpenSetNP[OpenSet].setValue(opensetread);
464 if (currentProtocol && currentProtocol->supportsFeature(
"asiair_control"))
468 if (currentProtocol && currentProtocol->supportsFeature(
"custom_brightness"))
472 if (currentProtocol && currentProtocol->supportsFeature(
"auto_detect"))
515bool WandererCoverV4EC::detectProtocol()
519 LOG_DEBUG(
"Starting protocol detection...");
522 if (!serialPortMutex.try_lock_for(std::chrono::milliseconds(100)))
524 LOG_DEBUG(
"Serial port is busy during protocol detection");
528 std::lock_guard<std::timed_mutex> lock(serialPortMutex, std::adopt_lock);
531 tcflush(PortFD, TCIOFLUSH);
535 int nbytes_read = 0, rc = -1;
539 if (ioctl(PortFD, FIONREAD, &available) == 0)
541 LOGF_DEBUG(
"Bytes available for reading: %d", available);
548 LOG_DEBUG(
"Timeout reading from device during protocol detection");
549 LOG_DEBUG(
"Trying to read any available data without timeout...");
554 LOGF_DEBUG(
"Found %d bytes without timeout: '%s'", nbytes_read, buffer);
558 LOG_DEBUG(
"No data available without timeout either");
561 LOG_ERROR(
"Protocol detection failed: No data received from device");
567 LOGF_ERROR(
"Failed to read data from device during protocol detection. Error: %s", errorMessage);
571 LOGF_DEBUG(
"Raw data received from device: '%s' (length: %d)", buffer, nbytes_read);
574 std::string dataStr(buffer);
575 std::vector<std::string> tokens;
577 std::istringstream tokenStream(dataStr);
579 while (std::getline(tokenStream, token,
'A'))
582 tokens.push_back(token);
585 LOGF_DEBUG(
"Parsed %zu tokens from device data", tokens.size());
586 for (
size_t i = 0; i < tokens.size(); i++)
588 LOGF_DEBUG(
"Token[%zu]: '%s'", i, tokens[i].c_str());
592 if (tokens.size() < 2)
594 LOGF_ERROR(
"Invalid data format: Not enough tokens. Expected at least 2, got %zu", tokens.size());
599 std::string deviceName = tokens[0];
600 LOGF_DEBUG(
"Device identification: '%s'", deviceName.c_str());
603 if (deviceName ==
"WandererCoverV4")
605 LOG_INFO(
"WandererCover V4-EC device detected");
608 else if (deviceName ==
"ZXWBProV3" || deviceName ==
"ZXWBPlusV3" ||
609 deviceName ==
"UltimateV2" || deviceName ==
"PlusV2"|| deviceName ==
"WandererEclipse"|| deviceName ==
"WandererDewTerminator"|| deviceName ==
"WandererCoverV4Pro")
611 LOGF_ERROR(
"WandererAstro products detected, but the model does not match: '%s'. This driver is designed for WandererCover V4-EC only, please choose the right driver or try another serial port!", deviceName.c_str());
616 LOGF_ERROR(
"Unsupported device detected: '%s'. Expected 'WandererCoverV4'", deviceName.c_str());
617 LOG_ERROR(
"This driver is specifically designed for WandererCover V4-EC devices only.");
622 int firmwareVersion = std::atoi(tokens[1].c_str());
623 LOGF_INFO(
"Detected firmware version: %d", firmwareVersion);
626 if (firmwareVersion <= 0)
628 LOGF_ERROR(
"Invalid firmware version: %d. Cannot determine protocol.", firmwareVersion);
633 if (firmwareVersion >= 20250404)
635 std::unique_ptr<WandererCoverModernProtocol> modernProtocol = std::make_unique<WandererCoverModernProtocol>();
636 setProtocol(std::move(modernProtocol));
637 LOG_INFO(
"Using modern protocol (firmware >= 20250404) Please note that in the newer firmware, to protect dark conditions, the flat light will remain off whenever the Cover is open.");
640 else if (firmwareVersion > 0)
642 std::unique_ptr<WandererCoverLegacyProtocol> legacyProtocol = std::make_unique<WandererCoverLegacyProtocol>();
643 setProtocol(std::move(legacyProtocol));
644 LOG_INFO(
"Using legacy protocol (firmware < 20250404) Firmware update recommended.");
649 LOGF_ERROR(
"Invalid firmware version: %d. Cannot determine protocol.", firmwareVersion);
653 catch(std::exception &e)
655 LOGF_ERROR(
"Exception occurred during protocol detection: %s", e.what());
660void WandererCoverV4EC::setProtocol(std::unique_ptr<IWandererCoverProtocol> protocol)
662 currentProtocol = std::move(protocol);
669bool WandererCoverV4EC::getData()
672 if (!serialPortMutex.try_lock_for(std::chrono::milliseconds(100)))
674 LOG_DEBUG(
"Serial port is busy, skipping status update");
678 std::lock_guard<std::timed_mutex> lock(serialPortMutex, std::adopt_lock);
682 LOG_DEBUG(
"Reading data from device...");
685 tcflush(PortFD, TCIOFLUSH);
689 int nbytes_read = 0, rc = -1;
697 LOG_DEBUG(
"Timeout reading from device, will try again later");
703 LOGF_ERROR(
"Failed to read data from device. Error: %s", errorMessage);
707 LOGF_DEBUG(
"Data received from device: '%s' (length: %d)", buffer, nbytes_read);
710 bool parseResult = parseDeviceData(buffer);
711 LOGF_DEBUG(
"Data parsing result: %s", parseResult ?
"success" :
"failed");
714 catch(std::exception &e)
716 LOGF_ERROR(
"Exception occurred while reading data from device: %s", e.what());
723bool WandererCoverV4EC::parseDeviceData(
const char *data)
725 if (!currentProtocol)
727 LOG_ERROR(
"No protocol handler available");
731 LOGF_DEBUG(
"Parsing data with protocol: %s", currentProtocol->getProtocolName().c_str());
732 return currentProtocol->parseDeviceData(data,
this);
738void WandererCoverV4EC::updateData(
double closesetread,
double opensetread,
double positionread,
double voltageread,
double flatpanelbrightnessread,
double dewheaterpowerread,
double asiaircontrolenabledread)
741 DataNP[closeset_read].setValue(closesetread);
742 DataNP[openset_read].setValue(opensetread);
743 DataNP[position_read].setValue(positionread);
744 DataNP[voltage_read].setValue(voltageread);
747 if (currentProtocol && currentProtocol->supportsFeature(
"extended_status"))
749 DataNP[flat_panel_brightness_read].setValue(flatpanelbrightnessread);
750 DataNP[dew_heater_power_read].setValue(dewheaterpowerread);
751 DataNP[asiair_control_enabled_read].setValue(asiaircontrolenabledread);
756 DataNP[flat_panel_brightness_read].setValue(-1);
757 DataNP[dew_heater_power_read].setValue(-1);
758 DataNP[asiair_control_enabled_read].setValue(-1);
776 if ((prevParked != currentParked) || (prevState != currentState))
807 if (!currentProtocol || !currentProtocol->supportsFeature(
"asiair_control"))
809 LOG_ERROR(
"ASIAIR control not supported by current protocol");
811 ASIAIRControlSP.
apply();
816 for (
int i = 0; i < n; i++)
818 if (strcmp(names[i],
"ASIAIR_ENABLE") == 0 && states[i] ==
ISS_ON)
820 rc = sendCommand(currentProtocol->generateASIAIRControlCommand(
true));
822 else if (strcmp(names[i],
"ASIAIR_DISABLE") == 0 && states[i] ==
ISS_ON)
824 rc = sendCommand(currentProtocol->generateASIAIRControlCommand(
false));
830 ASIAIRControlSP.
update(states, names, n);
831 ASIAIRControlSP.
apply();
838 if (!currentProtocol || !currentProtocol->supportsFeature(
"auto_detect"))
840 LOG_ERROR(
"Auto detection not supported by current protocol");
842 AutoDetectSP.
apply();
847 for (
int i = 0; i < n; i++)
849 if (strcmp(names[i],
"AUTO_DETECT_OPEN") == 0 && states[i] ==
ISS_ON)
851 rc = sendCommand(currentProtocol->generateAutoDetectOpenPositionCommand());
853 else if (strcmp(names[i],
"AUTO_DETECT_CLOSE") == 0 && states[i] ==
ISS_ON)
855 rc = sendCommand(currentProtocol->generateAutoDetectClosePositionCommand());
861 AutoDetectSP.
update(states, names, n);
862 AutoDetectSP.
apply();
867 return DefaultDevice::ISNewSwitch(dev, name, states, names, n);
883 if (!currentProtocol)
885 LOG_ERROR(
"No protocol handler available");
892 for (
int i = 0; i < n; i++)
894 rc1 = setDewPWM(2,
static_cast<int>(values[i]));
899 SetHeaterNP.
update(values, names, n);
906 if (!currentProtocol)
908 LOG_ERROR(
"No protocol handler available");
916 for (
int i = 0; i < n; i++)
918 if(values[i] < 10 || values[i] > 90)
921 LOG_ERROR(
"Out of range! Allowed closed angle: 10-90 degrees.");
924 rc1 = sendCommand(currentProtocol->generateSetClosePositionCommand(values[i]));
930 CloseSetNP.
update(values, names, n);
939 if (!currentProtocol)
941 LOG_ERROR(
"No protocol handler available");
949 for (
int i = 0; i < n; i++)
951 if(values[i] < 100 || values[i] > 300)
954 LOG_ERROR(
"Out of range! Allowed open angle: 100-300 degrees.");
957 rc1 = sendCommand(currentProtocol->generateSetOpenPositionCommand(values[i]));
963 OpenSetNP.
update(values, names, n);
973 if (!currentProtocol || !currentProtocol->supportsFeature(
"custom_brightness"))
975 LOG_ERROR(
"Custom brightness not supported by current protocol");
977 CustomBrightnessNP.
apply();
982 for (
int i = 0; i < n; i++)
984 if (strcmp(names[i],
"CUSTOM_BRIGHTNESS_1") == 0)
986 rc = sendCommand(currentProtocol->generateCustomBrightnessCommand(
static_cast<int>(values[i]), 1));
988 else if (strcmp(names[i],
"CUSTOM_BRIGHTNESS_2") == 0)
990 rc = sendCommand(currentProtocol->generateCustomBrightnessCommand(
static_cast<int>(values[i]), 2));
992 else if (strcmp(names[i],
"CUSTOM_BRIGHTNESS_3") == 0)
994 rc = sendCommand(currentProtocol->generateCustomBrightnessCommand(
static_cast<int>(values[i]), 3));
1000 CustomBrightnessNP.
update(values, names, n);
1001 CustomBrightnessNP.
apply();
1011bool WandererCoverV4EC::toggleCover(
bool open)
1013 if (!currentProtocol)
1015 LOG_ERROR(
"No protocol handler available");
1019 std::string command = open ? currentProtocol->generateOpenCommand() : currentProtocol->generateCloseCommand();
1020 return sendCommand(command);
1032 if (toggleCover(
false))
1052 if (toggleCover(
true))
1068 if (!currentProtocol)
1070 LOG_ERROR(
"No protocol handler available");
1079 rc = sendCommand(currentProtocol->generateSetBrightnessCommand(value));
1098 if (!currentProtocol)
1100 LOG_ERROR(
"No protocol handler available");
1106 rc = sendCommand(currentProtocol->generateTurnOffLightCommand());
1108 rc = sendCommand(currentProtocol->generateSetBrightnessCommand(
static_cast<int>(
LightIntensityNP[0].getValue())));
1116bool WandererCoverV4EC::sendCommand(std::string command)
1119 std::lock_guard<std::timed_mutex> lock(serialPortMutex);
1121 int nbytes_written = 0, rc = -1;
1122 std::string command_termination =
"\n";
1128 LOGF_ERROR(
"Serial write error: %s", errorMessage);
1138bool WandererCoverV4EC::setDewPWM(
int id,
int value)
1140 if (!currentProtocol)
1142 LOG_ERROR(
"No protocol handler available");
1147 snprintf(
cmd, 64,
"%d%03d",
id, value);
1148 return sendCommand(
cmd);
1154bool WandererCoverV4EC::setClose(
double value)
1156 if (!currentProtocol)
1158 LOG_ERROR(
"No protocol handler available");
1162 return sendCommand(currentProtocol->generateSetClosePositionCommand(value));
1168bool WandererCoverV4EC::setOpen(
double value)
1170 if (!currentProtocol)
1172 LOG_ERROR(
"No protocol handler available");
1176 return sendCommand(currentProtocol->generateSetOpenPositionCommand(value));
1201 SetHeaterNP.
save(fp);
1202 CloseSetNP.
save(fp);
1204 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
std::string generateAutoDetectClosePositionCommand() const override
bool supportsFeature(const std::string &feature) const override
std::string generateSetOpenPositionCommand(double value) const override
std::string generateOpenCommand() const override
std::string generateDewHeaterCommand(int value) const override
std::string generateTurnOffLightCommand() const override
bool parseDeviceData(const char *data, WandererCoverV4EC *device) override
std::string generateAutoDetectOpenPositionCommand() const override
std::string generateASIAIRControlCommand(bool enable) const override
std::string generateTurnOffLightCommand() const override
std::string generateAutoDetectOpenPositionCommand() 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 generateDewHeaterCommand(int value) const override
std::string generateAutoDetectClosePositionCommand() 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 IPState ParkCap() override
Park dust cap (close cover). Must be implemented by child.
const char * getDefaultName() override
virtual bool initProperties() override
Initialize properties initial state and value. The child class must implement this function.
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 bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
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....
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
virtual IPState UnParkCap() override
unPark dust cap (open cover). Must be implemented by child.
virtual bool EnableLightBox(bool enable) override
EnableLightBox Turn on/off on a light box. Must be implemented in the child class.
virtual bool SetLightBoxBrightness(uint16_t value) override
setBrightness Set light level. Must be implemented in the child class, if supported.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
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...
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