37static std::unique_ptr<WandererEclipse> wanderereclipse(
new WandererEclipse());
49 return "Wanderer Eclipse";
66 DataNP[torque_read].
fill(
"Motor_Torque",
"Motor_Torque",
"%4.2f", 0, 999, 100, 0);
67 DataNP[voltage_read].
fill(
"Voltage",
"Voltage (V)",
"%4.2f", 0, 999, 100, 0);
71 FirmwareTP[FIRMWARE_VERSION].
fill(
"FIRMWARE_VERSION",
"Firmware Version",
"Unknown");
106 char firmwareStr[16];
107 snprintf(firmwareStr,
sizeof(firmwareStr),
"%d", firmware);
108 FirmwareTP[FIRMWARE_VERSION].setText(firmwareStr);
110 if(firmware >= 20240101)
112 LOGF_INFO(
"Firmware version: %d", firmware);
116 LOGF_INFO(
"Firmware version: %d", firmware);
117 LOG_INFO(
"New firmware available!");
138bool WandererEclipse::getData()
140 if (!serialPortMutex.try_lock_for(std::chrono::milliseconds(100)))
142 LOG_DEBUG(
"Serial port is busy, skipping status update");
146 std::lock_guard<std::timed_mutex> lock(serialPortMutex, std::adopt_lock);
151 tcflush(PortFD, TCIOFLUSH);
154 const char *command =
"1500001\n";
155 int bytes_written = write(PortFD, command, strlen(command));
156 if (bytes_written < 0)
158 LOG_ERROR(
"Failed to write command to device");
164 int nbytes_read = 0, rc = -1;
170 LOG_DEBUG(
"Timeout reading from device, will try again later");
176 LOGF_ERROR(
"Failed to read data from device. Error: %s", errorMessage);
180 return parseDeviceData(buffer);
182 catch (std::exception &e)
184 LOG_ERROR(
"Exception occurred while reading data from device");
192bool WandererEclipse::parseDeviceData(
const char *data)
197 std::vector<std::string> tokens;
199 std::istringstream tokenStream(data);
202 while (std::getline(tokenStream, token,
'A'))
205 tokens.push_back(token);
209 if (tokens.size() < 3)
215 if (tokens[0] !=
"WandererEclipse")
217 if (tokens[0] ==
"ZXWBProV3" || tokens[0] ==
"ZXWBPlusV3" ||
218 tokens[0] ==
"UltimateV2" || tokens[0] ==
"PlusV2"|| tokens[0] ==
"WandererCoverV4"|| tokens[0] ==
"WandererCoverV4Pro")
220 LOG_WARN(
"The device is not Wanderer Eclipse!");
230 firmware = std::atoi(tokens[1].c_str());
233 char firmwareStr[16];
234 snprintf(firmwareStr,
sizeof(firmwareStr),
"%d", firmware);
235 FirmwareTP[FIRMWARE_VERSION].setText(firmwareStr);
240 torqueLevel = std::strtod(tokens[2].c_str(), NULL);
244 if (tokens.size() > 3)
246 voltageread = std::strtod(tokens[3].c_str(), NULL);
248 if (voltageread <= 7)
255 updateData(torqueLevel, voltageread);
260 catch(std::exception &e)
262 LOG_ERROR(
"Failed to parse device data");
267void WandererEclipse::updateData(
double torqueLevel,
double voltageread)
269 if (torqueLevel <= 0)
272 DataNP[torque_read].setValue(torqueLevel);
273 DataNP[voltage_read].setValue(voltageread);
278 if (torqueLevel <= 110)
280 else if (torqueLevel <= 160)
285 for (
int i = 0; i < 3; i++)
299 if ((prevParked != currentParked) || (prevState != currentState))
321 const char *
cmd =
nullptr;
323 for (
int i = 0; i < n; i++)
327 if (strcmp(names[i],
"TORQUE_LOW") == 0)
332 else if (strcmp(names[i],
"TORQUE_MEDIUM") == 0)
337 else if (strcmp(names[i],
"TORQUE_HIGH") == 0)
345 if (newTorque != -1 && newTorque != torqueLevel)
347 if (
cmd && sendCommand(
cmd))
349 torqueLevel = newTorque;
350 for (
int i = 0; i < 3; i++)
373bool WandererEclipse::toggleCover(
bool open)
376 snprintf(
cmd, 128,
"100%d", open ? 1 : 0);
377 if (sendCommand(
cmd))
395 if (toggleCover(
false))
415 if (toggleCover(
true))
430bool WandererEclipse::sendCommand(std::string command)
433 std::lock_guard<std::timed_mutex> lock(serialPortMutex);
435 int nbytes_written = 0, rc = -1;
436 std::string command_termination =
"\n";
442 LOGF_ERROR(
"Serial write error: %s", errorMessage);
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 ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process the client newSwitch command.
void registerConnection(Connection::Interface *newConnection)
registerConnection Add new connection plugin to the existing connection pool. The connection type sha...
void setDefaultPollingPeriod(uint32_t msec)
setDefaultPollingPeriod Change the default polling period to call TimerHit() function in the driver.
void setDriverInterface(uint32_t value)
setInterface Set driver interface. By default the driver interface is set to GENERAL_DEVICE....
void setVersion(uint16_t vMajor, uint16_t vMinor)
Set driver version information to be defined in DRIVER_INFO property as vMajor.vMinor.
virtual bool 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 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.
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
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 setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
bool isNameMatch(const char *otherName) const
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
void fill(const char *device, const char *name, const char *label, const char *group, IPerm permission, double timeout, IPState state)
virtual bool initProperties() override
Initialize properties initial state and value. The child class must implement this function.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual IPState UnParkCap() override
unPark dust cap (open cover). Must be implemented by child.
const char * getDefaultName() override
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 ParkCap() override
Park dust cap (close cover). Must be implemented by child.
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 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