39static std::unique_ptr<PegasusUPB> upb(
new PegasusUPB());
42 INDI::PowerInterface(this)
46 lastSensorData.reserve(21);
47 lastPowerData.reserve(4);
48 lastStepperData.reserve(4);
49 lastDewAggData.reserve(1);
72 RebootSP[0].
fill(
"REBOOT",
"Reboot Device",
ISS_OFF);
77 PowerConsumptionNP[CONSUMPTION_AVG_AMPS].
fill(
"CONSUMPTION_AVG_AMPS",
"Avg. Amps",
"%4.2f", 0, 999, 100, 0);
78 PowerConsumptionNP[CONSUMPTION_AMP_HOURS].
fill(
"CONSUMPTION_AMP_HOURS",
"Amp Hours",
"%4.2f", 0, 999, 100, 0);
79 PowerConsumptionNP[CONSUMPTION_WATT_HOURS].
fill(
"CONSUMPTION_WATT_HOURS",
"Watt Hours",
"%4.2f", 0, 999, 100, 0);
88 AutoDewAggNP[AUTO_DEW_AGG].
fill(
"AUTO_DEW_AGG_VALUE",
"Auto Dew Agg (50-250)",
"%.2f", 50, 250, 20, 0);
108 FocuserSettingsNP[SETTING_MAX_SPEED].
fill(
"SETTING_MAX_SPEED",
"Max Speed (%)",
"%.f", 0, 900, 100, 400);
114 FirmwareTP[FIRMWARE_VERSION].
fill(
"VERSION",
"Version",
"NA");
115 FirmwareTP[FIRMWARE_UPTIME].
fill(
"UPTIME",
"Uptime (h)",
"NA");
121 addParameter(
"WEATHER_TEMPERATURE",
"Temperature (C)", -15, 35, 15);
122 addParameter(
"WEATHER_HUMIDITY",
"Humidity %", 0, 100, 15);
123 addParameter(
"WEATHER_DEWPOINT",
"Dew Point (C)", 0, 100, 15);
173 setupComplete =
true;
201 setupComplete =
false;
209 return "Pegasus UPB";
215bool PegasusUPB::Handshake()
217 char response[PEGASUS_LEN] = {0};
225 snprintf(response, PEGASUS_LEN,
"UPB2_OK");
230 int tty_rc = 0, nbytes_written = 0;
231 char command[PEGASUS_LEN] = {0};
232 tcflush(PortFD, TCIOFLUSH);
233 strncpy(command,
"P#\n", PEGASUS_LEN);
238 LOGF_ERROR(
"Serial write error: %s", errorMessage);
248 tcflush(PortFD, TCIOFLUSH);
251 tty_rc =
tty_nread_section(PortFD, response, PEGASUS_LEN, stopChar, 1, &nbytes_read);
258 LOGF_ERROR(
"Serial read error: %s", errorMessage);
263 cleanupResponse(response);
264 tcflush(PortFD, TCIOFLUSH);
270 setupComplete =
false;
272 version = strstr(response,
"UPB2_OK") ?
UPB_V2 :
UPB_V1;
315 PowerOnBootSP.
update(states, names, n);
317 PowerOnBootSP.
apply();
323 if (strstr(name,
"FOCUS"))
331 return DefaultDevice::ISNewSwitch(dev, name, states, names, n);
344 if (setAutoDewAgg(values[0]))
346 AutoDewAggNP[0].setValue(values[0]);
354 AutoDewAggNP.
apply();
361 if (setFocuserMaxSpeed(values[0]))
363 FocuserSettingsNP[0].setValue(values[0]);
371 FocuserSettingsNP.
apply();
375 if (strstr(name,
"FOCUS_"))
378 if (strstr(name,
"WEATHER_"))
408bool PegasusUPB::sendCommand(
const char *
cmd,
char * res)
410 int nbytes_read = 0, nbytes_written = 0, tty_rc = 0;
415 if (!strcmp(
cmd,
"PS"))
417 strncpy(res,
"PS:1111:12", PEGASUS_LEN);
419 else if (!strcmp(
cmd,
"PA"))
421 strncpy(res,
"UPB2:12.0:0.9:10:24.8:37:9.1:1111:111111:153:153:0:0:0:0:0:70:0:0:0000000:0", PEGASUS_LEN);
423 else if (!strcmp(
cmd,
"PC"))
425 strncpy(res,
"0.40:0.00:0.03:26969", PEGASUS_LEN);
427 else if (!strcmp(
cmd,
"SA"))
429 strncpy(res,
"3000:0:0:10", PEGASUS_LEN);
431 else if (!strcmp(
cmd,
"SS"))
433 strncpy(res,
"999", PEGASUS_LEN);
435 else if (!strcmp(
cmd,
"PD"))
437 strncpy(res,
"210", PEGASUS_LEN);
439 else if (!strcmp(
cmd,
"PV"))
441 strncpy(res,
"Sim v1.0", PEGASUS_LEN);
445 snprintf(res, PEGASUS_LEN,
"%s",
cmd);
451 for (
int i = 0; i < 2; i++)
453 char command[PEGASUS_LEN] = {0};
454 tcflush(PortFD, TCIOFLUSH);
455 snprintf(command, PEGASUS_LEN,
"%s\n",
cmd);
461 tcflush(PortFD, TCIOFLUSH);
469 tcflush(PortFD, TCIOFLUSH);
471 cleanupResponse(res);
489 return setUSBPortEnabled(port, enabled);
497 char cmd[PEGASUS_LEN] = {0}, res[PEGASUS_LEN] = {0};
498 snprintf(
cmd, PEGASUS_LEN,
"SM:%u", targetTicks);
499 if (sendCommand(
cmd, res))
520 char res[PEGASUS_LEN] = {0};
521 if (sendCommand(
"SH", res))
523 return (!strcmp(res,
"SH"));
534 char cmd[PEGASUS_LEN] = {0}, res[PEGASUS_LEN] = {0};
535 snprintf(
cmd, PEGASUS_LEN,
"SR:%d", enabled ? 1 : 0);
536 if (sendCommand(
cmd, res))
538 return (!strcmp(res,
cmd));
549 char cmd[PEGASUS_LEN] = {0};
550 snprintf(
cmd, PEGASUS_LEN,
"SC:%u", ticks);
551 return sendCommand(
cmd,
nullptr);
559 char cmd[PEGASUS_LEN] = {0};
560 snprintf(
cmd, PEGASUS_LEN,
"SB:%d", steps);
561 return sendCommand(
cmd,
nullptr);
567bool PegasusUPB::setFocuserMaxSpeed(uint16_t maxSpeed)
569 char cmd[PEGASUS_LEN] = {0};
570 snprintf(
cmd, PEGASUS_LEN,
"SS:%d", maxSpeed);
571 return sendCommand(
cmd,
nullptr);
579 char cmd[PEGASUS_LEN] = {0};
580 snprintf(
cmd, PEGASUS_LEN,
"SB:%d", enabled ? 1 : 0);
581 return sendCommand(
cmd,
nullptr);
587bool PegasusUPB::setPowerEnabled(uint8_t port,
bool enabled)
589 char cmd[PEGASUS_LEN] = {0}, res[PEGASUS_LEN] = {0};
590 snprintf(
cmd, PEGASUS_LEN,
"P%d:%d", port, enabled ? 1 : 0);
591 if (sendCommand(
cmd, res))
593 return (!strcmp(res,
cmd));
602bool PegasusUPB::setPowerLEDEnabled(
bool enabled)
604 char cmd[PEGASUS_LEN] = {0}, res[PEGASUS_LEN] = {0};
605 snprintf(
cmd, PEGASUS_LEN,
"PL:%d", enabled ? 1 : 0);
606 if (sendCommand(
cmd, res))
608 return (!strcmp(res,
cmd));
617bool PegasusUPB::setAutoDewEnabled(
bool enabled)
619 char cmd[PEGASUS_LEN] = {0}, res[PEGASUS_LEN] = {0};
620 snprintf(
cmd, PEGASUS_LEN,
"PD:%d", enabled ? 1 : 0);
621 if (sendCommand(
cmd, res))
623 return (!strcmp(res,
cmd));
632bool PegasusUPB::setAutoDewAgg(uint8_t value)
634 char cmd[PEGASUS_LEN] = {0}, res[PEGASUS_LEN] = {0}, expected[PEGASUS_LEN] = {0};
635 snprintf(
cmd, PEGASUS_LEN,
"PD:%03d", value);
636 snprintf(expected, PEGASUS_LEN,
"PD:%d", value);
637 if (sendCommand(
cmd, res))
639 return (!strcmp(res, expected));
647bool PegasusUPB::setAdjustableOutput(uint8_t voltage)
649 char cmd[PEGASUS_LEN] = {0}, res[PEGASUS_LEN] = {0};
650 snprintf(
cmd, PEGASUS_LEN,
"P8:%d", voltage);
651 if (sendCommand(
cmd, res))
653 return (!strcmp(res,
cmd));
662bool PegasusUPB::setPowerOnBoot()
664 char cmd[PEGASUS_LEN] = {0}, res[PEGASUS_LEN] = {0};
665 snprintf(
cmd, PEGASUS_LEN,
"PE:%d%d%d%d", PowerOnBootSP[POWER_PORT_1].getState() ==
ISS_ON ? 1 : 0,
666 PowerOnBootSP[POWER_PORT_2].getState() ==
ISS_ON ? 1 : 0,
667 PowerOnBootSP[POWER_PORT_3].getState() ==
ISS_ON ? 1 : 0,
668 PowerOnBootSP[POWER_PORT_4].getState() ==
ISS_ON ? 1 : 0);
669 if (sendCommand(
cmd, res))
671 return (!strcmp(res,
"PE:1"));
680bool PegasusUPB::getPowerOnBoot()
682 char res[PEGASUS_LEN] = {0};
683 if (sendCommand(
"PS", res))
685 std::vector<std::string> result = split(res,
":");
686 if (result.size() != 3)
688 LOGF_WARN(
"Received wrong number (%i) of power on boot data (%s). Retrying...", result.size(), res);
692 const char *status = result[1].c_str();
713bool PegasusUPB::setDewPWM(uint8_t
id, uint8_t value)
715 char cmd[PEGASUS_LEN] = {0}, res[PEGASUS_LEN] = {0}, expected[PEGASUS_LEN] = {0};
716 snprintf(
cmd, PEGASUS_LEN,
"P%d:%03d",
id, value);
717 snprintf(expected, PEGASUS_LEN,
"P%d:%d",
id, value);
718 if (sendCommand(
cmd, res))
720 return (!strcmp(res, expected));
729bool PegasusUPB::setUSBHubEnabled(
bool enabled)
731 char cmd[PEGASUS_LEN] = {0}, expected[PEGASUS_LEN] = {0}, res[PEGASUS_LEN] = {0};
732 snprintf(
cmd, PEGASUS_LEN,
"PU:%d", enabled ? 1 : 0);
733 snprintf(expected, PEGASUS_LEN,
"PU:%d", enabled ? 0 : 1);
734 if (sendCommand(
cmd, res))
736 return (!strcmp(res, expected));
745bool PegasusUPB::setUSBPortEnabled(uint8_t port,
bool enabled)
747 char cmd[PEGASUS_LEN] = {0}, expected[PEGASUS_LEN] = {0}, res[PEGASUS_LEN] = {0};
748 snprintf(
cmd, PEGASUS_LEN,
"U%d:%d", port + 1, enabled ? 1 : 0);
749 snprintf(expected, PEGASUS_LEN,
"U%d:%d", port + 1, enabled ? 1 : 0);
750 if (sendCommand(
cmd, res))
752 return (!strcmp(res, expected));
761bool PegasusUPB::toggleAutoDewV2(
size_t port,
bool enabled)
763 char cmd[PEGASUS_LEN] = {0}, expected[PEGASUS_LEN] = {0}, res[PEGASUS_LEN] = {0};
772 if (port == 0) dewA_on = enabled;
773 else if (port == 1) dewB_on = enabled;
774 else if (port == 2) dewC_on = enabled;
776 if (!dewA_on && !dewB_on && !dewC_on)
778 else if (dewA_on && dewB_on && dewC_on)
780 else if (dewA_on && dewB_on)
782 else if (dewA_on && dewC_on)
784 else if (dewB_on && dewC_on)
793 snprintf(
cmd, PEGASUS_LEN,
"PD:%d", value);
794 snprintf(expected, PEGASUS_LEN,
"PD:%d", value);
795 if (sendCommand(
cmd, res))
797 return (!strcmp(res, expected));
816 AutoDewAggNP.
save(fp);
818 FocuserSettingsNP.
save(fp);
819 PowerOnBootSP.
save(fp);
849bool PegasusUPB::sendFirmware()
851 char res[PEGASUS_LEN] = {0};
852 if (sendCommand(
"PV", res))
855 FirmwareTP[FIRMWARE_VERSION].setText(res);
866bool PegasusUPB::sensorUpdated(
const std::vector<std::string> &result, uint8_t start, uint8_t end)
868 if (lastSensorData.empty())
871 for (uint8_t index = start; index <= end; index++)
873 if (index >= lastSensorData.size() or result[index] != lastSensorData[index])
883bool PegasusUPB::stepperUpdated(
const std::vector<std::string> &result, uint8_t index)
885 if (lastStepperData.empty())
888 return index >= lastStepperData.size() or result[index] != lastSensorData[index];
894bool PegasusUPB::getSensorData()
896 char res[PEGASUS_LEN] = {0};
897 if (sendCommand(
"PA", res))
899 std::vector<std::string> result = split(res,
":");
900 if ( (version ==
UPB_V1 && result.size() != 19) ||
901 (version ==
UPB_V2 && result.size() != 21))
903 LOGF_WARN(
"Received wrong number (%i) of detailed sensor data (%s). Retrying...", result.size(), res);
907 if (result == lastSensorData)
916 if (sensorUpdated(result, 0, 2))
924 if (sensorUpdated(result, 4, 6))
933 const char * portStatus = result[7].c_str();
942 if (sensorUpdated(result, 7, 7))
946 const char * usb_status = result[8].c_str();
953 if (sensorUpdated(result, 8, 8))
962 if (sensorUpdated(result, 8, 8))
981 if (sensorUpdated(result, index, version ==
UPB_V1 ? index + 1 : index + 2))
986 bool dewChannelChanged =
false;
989 auto newState = (std::stoi(result[index]) > 0) ?
ISS_ON :
ISS_OFF;
993 dewChannelChanged =
true;
998 auto newState = (std::stoi(result[index + 1]) > 0) ?
ISS_ON :
ISS_OFF;
1002 dewChannelChanged =
true;
1007 auto newState = (std::stoi(result[index + 2]) > 0) ?
ISS_ON :
ISS_OFF;
1011 dewChannelChanged =
true;
1014 if (dewChannelChanged)
1017 index = (version ==
UPB_V1) ? 11 : 12;
1019 const double ampDivision = (version ==
UPB_V1) ? 400.0 : 480.0;
1030 if (sensorUpdated(result, index, index + 3))
1033 index = (version ==
UPB_V1) ? 15 : 16;
1041 if (sensorUpdated(result, index, version ==
UPB_V1 ? index + 1 : index + 2))
1044 index = (version ==
UPB_V1) ? 17 : 19;
1048 if (sensorUpdated(result, index, index))
1050 const char * over_curent = result[index].c_str();
1062 OverCurrentLP.
apply();
1065 index = (version ==
UPB_V1) ? 18 : 20;
1071 if (sensorUpdated(result, index, index))
1080 if (sensorUpdated(result, index, index))
1082 int value = std::stoi(result[index]);
1137 lastSensorData = result;
1147bool PegasusUPB::getPowerData()
1149 char res[PEGASUS_LEN] = {0};
1150 if (sendCommand(
"PC", res))
1152 std::vector<std::string> result = split(res,
":");
1154 if (result.size() < 3)
1156 LOGF_WARN(
"Received wrong number (%i) of power sensor data (%s). Retrying...", result.size(), res);
1160 if (result == lastPowerData)
1163 PowerConsumptionNP[CONSUMPTION_AVG_AMPS].setValue(std::stod(result[0]));
1164 PowerConsumptionNP[CONSUMPTION_AMP_HOURS].setValue(std::stod(result[1]));
1165 PowerConsumptionNP[CONSUMPTION_WATT_HOURS].setValue(std::stod(result[2]));
1167 PowerConsumptionNP.
apply();
1169 if (result.size() == 4)
1173 std::chrono::milliseconds uptime(std::stol(result[3]));
1174 using dhours = std::chrono::duration<double, std::ratio<3600>>;
1175 std::stringstream ss;
1176 ss << std::fixed << std::setprecision(3) << dhours(uptime).count();
1177 FirmwareTP[FIRMWARE_UPTIME].setText(ss.str().c_str());
1182 FirmwareTP[FIRMWARE_UPTIME].setText(
"NA");
1183 LOGF_DEBUG(
"Failed to process uptime: %s", result[3].c_str());
1189 lastPowerData = result;
1199bool PegasusUPB::getStepperData()
1201 char res[PEGASUS_LEN] = {0};
1202 if (sendCommand(
"SA", res))
1204 std::vector<std::string> result = split(res,
":");
1205 if (result.size() != 4)
1207 LOGF_WARN(
"Received wrong number (%i) of stepper sensor data (%s). Retrying...", result.size(), res);
1211 if (result == lastStepperData)
1215 focusMotorRunning = (std::stoi(result[1]) == 1);
1224 else if (stepperUpdated(result, 0))
1230 if (stepperUpdated(result, 1))
1233 uint16_t backlash = std::stoi(result[3]);
1239 if (stepperUpdated(result, 3))
1242 FocuserSettingsNP.
apply();
1250 if (stepperUpdated(result, 3))
1253 FocuserSettingsNP.
apply();
1257 lastStepperData = result;
1263bool PegasusUPB::getDewAggData()
1265 char res[PEGASUS_LEN] = {0};
1266 if (sendCommand(
"DA", res))
1268 std::vector<std::string> result = split(res,
":");
1269 if (result.size() != 2)
1271 LOGF_WARN(
"Received wrong number (%i) of dew aggresiveness data (%s). Retrying...", result.size(), res);
1275 if (result == lastDewAggData)
1278 AutoDewAggNP[0].setValue(std::stod(result[1]));
1280 AutoDewAggNP.
apply();
1282 lastDewAggData = result;
1290bool PegasusUPB::reboot()
1292 return sendCommand(
"PF",
nullptr);
1298std::vector<std::string> PegasusUPB::split(
const std::string &input,
const std::string ®ex)
1301 std::regex re(regex);
1302 std::sregex_token_iterator
1303 first{input.begin(), input.end(), re, -1},
1305 return {first, last};
1311bool PegasusUPB::setupParams()
1319 char res[PEGASUS_LEN] = {0};
1320 if (sendCommand(
"SS", res))
1324 uint32_t value = std::stol(res);
1325 if (value == UINT16_MAX)
1327 LOGF_WARN(
"Invalid maximum speed detected: %u. Please set maximum speed appropriate for your motor focus type (0-900)",
1333 FocuserSettingsNP[SETTING_MAX_SPEED].setValue(value);
1339 LOGF_WARN(
"Failed to process focuser max speed: %s", res);
1350void PegasusUPB::cleanupResponse(
char *response)
1352 std::string s(response);
1353 s.erase(std::remove_if(s.begin(), s.end(),
1356 return std::isspace(x);
1358 snprintf(response, PEGASUS_LEN,
"%s", s.c_str());
1367 return setPowerEnabled(port + 1, enabled);
1374 auto pwmValue =
static_cast<uint8_t
>(dutyCycle / 100.0 * 255.0);
1375 return setDewPWM(port + 5, enabled ? pwmValue : 0);
1383 return setAdjustableOutput(0);
1385 return setAdjustableOutput(
static_cast<uint8_t
>(voltage));
1390 return setPowerLEDEnabled(enabled);
1399 return setAutoDewEnabled(enabled);
1405 return toggleAutoDewV2(port, enabled);
1412 char cmd[PEGASUS_LEN] = {0}, res[PEGASUS_LEN] = {0};
1413 snprintf(
cmd, PEGASUS_LEN,
"PZ:1");
1414 if (sendCommand(
cmd, res))
1416 return (!strcmp(
cmd, res));
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 ...
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 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...
uint32_t getCurrentPollingPeriod() const
getCurrentPollingPeriod Return the current polling period.
virtual bool initProperties()
Initialize properties initial state and value. The child class must implement this function.
bool isSimulation() const
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::PropertyNumber FocusRelPosNP
INDI::PropertySwitch FocusReverseSP
bool updateProperties()
updateProperties Define or Delete Rotator properties based on the connection status of the base devic...
void SetCapability(uint32_t cap)
FI::SetCapability sets the focuser capabilities. All capabilities must be initialized.
void initProperties(const char *groupName)
Initialize focuser properties. It is recommended to call this function within initProperties() of you...
bool saveConfigItems(FILE *fp)
saveConfigItems save focuser properties defined in the interface in config file
bool processNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process focus number properties.
bool processSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process focus switch properties.
INDI::PropertySwitch FocusBacklashSP
INDI::PropertyNumber FocusBacklashNP
INDI::PropertyNumber FocusAbsPosNP
INDI::PropertySwitch DewChannelsSP
bool saveConfigItems(FILE *fp)
saveConfigItems Save power properties in config file
INDI::PropertySwitch AutoDewSP
INDI::PropertyNumber VariableChannelVoltsNP
void SetCapability(uint32_t cap)
SetPowerCapability sets the Power capabilities. All capabilities must be initialized.
@ POWER_HAS_VOLTAGE_SENSOR
@ POWER_HAS_OVERALL_CURRENT
@ POWER_HAS_PER_PORT_CURRENT
INDI::PropertyNumber PowerSensorsNP
INDI::PropertyNumber PowerChannelCurrentNP
INDI::PropertyNumber DewChannelCurrentNP
bool processNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process Power number properties.
void initProperties(const char *groupName, size_t nPowerPorts=0, size_t nDewPorts=0, size_t nVariablePorts=0, size_t nAutoDewPorts=0, size_t nUSBPorts=0)
Initialize Power properties. It is recommended to call this function within initProperties() of your ...
bool processText(const char *dev, const char *name, char *texts[], char *names[], int n)
Process Power text properties.
bool processSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process Power switch properties.
INDI::PropertySwitch PowerChannelsSP
INDI::PropertySwitch USBPortSP
INDI::PropertyNumber DewChannelDutyCycleNP
INDI::PropertyText USBPortLabelsTP
bool updateProperties()
updateProperties Define or Delete Power properties based on the connection status of the base device
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.
void setLabel(const char *label)
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)
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)
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 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 void TimerHit() override
Callback function to be called once SetTimer duration elapses.
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
virtual IPState MoveRelFocuser(FocusDirection dir, uint32_t ticks) override
MoveFocuser the focuser to an relative position.
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
virtual bool initProperties() override
Initialize properties initial state and value. The child class must implement this function.
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 SetVariablePort(size_t port, bool enabled, double voltage) override
SetVariablePort Set variable voltage port.
virtual bool SetPowerPort(size_t port, bool enabled) override
Power Interface Implementations.
virtual bool SetDewPort(size_t port, bool enabled, double dutyCycle) override
SetDewPort Set DEW/Dew port duty cycle.
virtual bool SetFocuserBacklash(int32_t steps) override
SetFocuserBacklash Set the focuser backlash compensation value.
virtual bool SetLEDEnabled(bool enabled) override
SetLEDEnabled Enable/disable power LEDs.
virtual bool SetUSBPort(size_t port, bool enabled) override
SetUSBPort Set USB port on/off.
virtual bool CyclePower() override
CyclePower Cycle power to all ports.
virtual bool SyncFocuser(uint32_t ticks) override
SyncFocuser Set current position to ticks without moving the focuser.
virtual bool AbortFocuser() override
AbortFocuser all focus motion.
virtual bool SetFocuserBacklashEnabled(bool enabled) override
SetFocuserBacklashEnabled Enables or disables the focuser backlash compensation.
virtual bool ReverseFocuser(bool enabled) override
ReverseFocuser Reverse focuser motion direction.
const char * getDefaultName() override
virtual bool SetAutoDewEnabled(size_t port, bool enabled) override
SetAutoDewEnabled Enable/disable automatic dew control.
virtual IPState MoveAbsFocuser(uint32_t targetTicks) override
MoveFocuser the focuser to an absolute position.
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.
const char * FOCUS_TAB
FOCUS_TAB Where all the properties for focuser are located.
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.
int tty_nread_section(int fd, char *buf, int nsize, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
Implementations for common driver routines.
#define LOGF_INFO(fmt,...)
#define LOGF_WARN(fmt,...)
#define LOGF_DEBUG(fmt,...)
#define LOGF_ERROR(fmt,...)
Namespace to encapsulate INDI client, drivers, and mediator classes.