35 static std::unique_ptr<PegasusPPBA> ppba(
new PegasusPPBA());
40 lastSensorData.reserve(PA_N);
41 lastConsumptionData.reserve(PS_N);
42 lastMetricsData.reserve(PC_N);
94 IUFillNumber(&PowerSensorsN[SENSOR_VOLTAGE],
"SENSOR_VOLTAGE",
"Voltage (V)",
"%4.2f", 0, 999, 100, 0);
95 IUFillNumber(&PowerSensorsN[SENSOR_CURRENT],
"SENSOR_CURRENT",
"Current (A)",
"%4.2f", 0, 999, 100, 0);
96 IUFillNumber(&PowerSensorsN[SENSOR_AVG_AMPS],
"SENSOR_AVG_AMPS",
"Average Current (A)",
"%4.2f", 0, 999, 100, 0);
97 IUFillNumber(&PowerSensorsN[SENSOR_AMP_HOURS],
"SENSOR_AMP_HOURS",
"Amp hours (Ah)",
"%4.2f", 0, 999, 100, 0);
98 IUFillNumber(&PowerSensorsN[SENSOR_WATT_HOURS],
"SENSOR_WATT_HOURS",
"Watt hours (Wh)",
"%4.2f", 0, 999, 100, 0);
99 IUFillNumber(&PowerSensorsN[SENSOR_TOTAL_CURRENT],
"SENSOR_TOTAL_CURRENT",
"Total current (A)",
"%4.2f", 0, 999, 100, 0);
100 IUFillNumber(&PowerSensorsN[SENSOR_12V_CURRENT],
"SENSOR_12V_CURRENT",
"12V current (A)",
"%4.2f", 0, 999, 100, 0);
101 IUFillNumber(&PowerSensorsN[SENSOR_DEWA_CURRENT],
"SENSOR_DEWA_CURRENT",
"DewA current (A)",
"%4.2f", 0, 999, 100, 0);
102 IUFillNumber(&PowerSensorsN[SENSOR_DEWB_CURRENT],
"SENSOR_DEWB_CURRENT",
"DewB current (A)",
"%4.2f", 0, 999, 100, 0);
135 IUFillSwitchVector(&AutoDewSP, AutoDewS, 2,
getDeviceName(),
"AUTO_DEW",
"Auto Dew", DEW_TAB,
IP_RW,
ISR_1OFMANY, 60,
139 IUFillNumber(&DewPWMN[DEW_PWM_A],
"DEW_A",
"Dew A (%)",
"%.2f", 0, 100, 10, 0);
140 IUFillNumber(&DewPWMN[DEW_PWM_B],
"DEW_B",
"Dew B (%)",
"%.2f", 0, 100, 10, 0);
146 IUFillText(&FirmwareT[FIRMWARE_VERSION],
"VERSION",
"Version",
"NA");
147 IUFillText(&FirmwareT[FIRMWARE_UPTIME],
"UPTIME",
"Uptime (h)",
"NA");
154 addParameter(
"WEATHER_TEMPERATURE",
"Temperature (C)", -15, 35, 15);
155 addParameter(
"WEATHER_HUMIDITY",
"Humidity %", 0, 100, 15);
156 addParameter(
"WEATHER_DEWPOINT",
"Dew Point (C)", 0, 100, 15);
164 IUFillNumber(&FocuserSettingsN[SETTING_MAX_SPEED],
"SETTING_MAX_SPEED",
"Max Speed (%)",
"%.f", 0, 900, 100, 400);
195 m_HasExternalMotor = findExternalMotorController();
197 if (m_HasExternalMotor)
219 if (m_HasExternalMotor)
231 setupComplete =
true;
249 if (m_HasExternalMotor)
260 setupComplete =
false;
268 return "Pegasus PPBA";
271 bool PegasusPPBA::Handshake()
273 int tty_rc = 0, nbytes_written = 0, nbytes_read = 0;
274 char command[PEGASUS_LEN] = {0}, response[PEGASUS_LEN] = {0};
280 tcflush(PortFD, TCIOFLUSH);
281 strncpy(command,
"P#\n", PEGASUS_LEN);
286 LOGF_ERROR(
"Serial write error: %s", errorMessage);
296 tcflush(PortFD, TCIOFLUSH);
299 tty_rc =
tty_nread_section(PortFD, response, PEGASUS_LEN, stopChar, 1, &nbytes_read);
306 LOGF_ERROR(
"Serial read error: %s", errorMessage);
311 tcflush(PortFD, TCIOFLUSH);
312 response[nbytes_read - 1] =
'\0';
315 setupComplete =
false;
317 return (!strcmp(response,
"PPBA_OK") || !strcmp(response,
"PPBM_OK"));
325 if (!strcmp(name, QuadOutSP.
name))
330 char cmd[PEGASUS_LEN] = {0}, res[PEGASUS_LEN] = {0};
332 if (sendCommand(
cmd, res))
361 if (!strcmp(name, AdjOutVoltSP.
name))
390 char cmd[PEGASUS_LEN] = {0}, res[PEGASUS_LEN] = {0};
391 snprintf(
cmd, PEGASUS_LEN,
"P2:%d", adjv);
392 if (sendCommand(
cmd, res))
397 AdjOutVoltS[previous_index].s =
ISS_ON;
406 if (!strcmp(name, RebootSP.
name))
415 if (!strcmp(name, LedIndicatorSP.
name))
418 char cmd[PEGASUS_LEN] = {0}, res[PEGASUS_LEN] = {0};
420 if (sendCommand(
cmd, res))
430 if (!strcmp(name, PowerOnBootSP.
name))
440 if (!strcmp(name, AutoDewSP.
name))
451 AutoDewS[prevIndex].s =
ISS_ON;
460 if (!strcmp(name, FocuserDriveSP.
name))
471 FocuserDriveS[prevIndex].s =
ISS_ON;
479 if (strstr(name,
"FOCUS"))
491 if (!strcmp(name, DewPWMNP.
name))
493 bool rc1 =
false, rc2 =
false;
494 for (
int i = 0; i < n; i++)
496 if (!strcmp(names[i], DewPWMN[DEW_PWM_A].name))
497 rc1 = setDewPWM(3,
static_cast<uint8_t
>(values[i] / 100.0 * 255.0));
498 else if (!strcmp(names[i], DewPWMN[DEW_PWM_B].name))
499 rc2 = setDewPWM(4,
static_cast<uint8_t
>(values[i] / 100.0 * 255.0));
510 if (!strcmp(name, FocuserSettingsNP.
name))
512 if (setFocuserMaxSpeed(values[0]))
514 FocuserSettingsN[0].value = values[0];
526 if (strstr(name,
"FOCUS_"))
529 if (strstr(name,
"WEATHER_"))
535 bool PegasusPPBA::sendCommand(
const char *
cmd,
char * res)
537 int nbytes_read = 0, nbytes_written = 0, tty_rc = 0;
538 char command[PEGASUS_LEN] = {0};
541 for (
int i = 0; i < 2; i++)
543 tcflush(PortFD, TCIOFLUSH);
544 snprintf(command, PEGASUS_LEN,
"%s\n",
cmd);
550 tcflush(PortFD, TCIOFLUSH);
558 tcflush(PortFD, TCIOFLUSH);
559 res[nbytes_read - 1] =
'\0';
574 bool PegasusPPBA::findExternalMotorController()
576 char res[PEGASUS_LEN] = {0};
577 if (!sendCommand(
"XS", res))
581 return strstr(res,
"200");
584 bool PegasusPPBA::setAutoDewEnabled(
bool enabled)
586 char cmd[PEGASUS_LEN] = {0}, res[PEGASUS_LEN] = {0};
587 snprintf(
cmd, PEGASUS_LEN,
"PD:%d", enabled ? 1 : 0);
588 if (sendCommand(
cmd, res))
590 return (!strcmp(res,
cmd));
596 bool PegasusPPBA::setPowerOnBoot()
598 char cmd[PEGASUS_LEN] = {0}, res[PEGASUS_LEN] = {0};
599 snprintf(
cmd, PEGASUS_LEN,
"PE:%d%d%d%d", PowerOnBootS[0].s ==
ISS_ON ? 1 : 0,
600 PowerOnBootS[1].s ==
ISS_ON ? 1 : 0,
601 PowerOnBootS[2].s ==
ISS_ON ? 1 : 0,
602 PowerOnBootS[3].s ==
ISS_ON ? 1 : 0);
603 if (sendCommand(
cmd, res))
605 return (!strcmp(res,
"PE:1"));
611 bool PegasusPPBA::setDewPWM(uint8_t
id, uint8_t value)
613 char cmd[PEGASUS_LEN] = {0}, res[PEGASUS_LEN] = {0}, expected[PEGASUS_LEN] = {0};
614 snprintf(
cmd, PEGASUS_LEN,
"P%d:%03d",
id, value);
615 snprintf(expected, PEGASUS_LEN,
"P%d:%d",
id, value);
616 if (sendCommand(
cmd, res))
618 return (!strcmp(res, expected));
627 if (m_HasExternalMotor)
647 getConsumptionData();
650 if (m_HasExternalMotor)
656 bool PegasusPPBA::sendFirmware()
658 char res[PEGASUS_LEN] = {0};
659 if (sendCommand(
"PV", res))
662 IUSaveText(&FirmwareT[FIRMWARE_VERSION], res);
670 bool PegasusPPBA::getSensorData()
672 char res[PEGASUS_LEN] = {0};
673 if (sendCommand(
"PA", res))
675 std::vector<std::string> result = split(res,
":");
676 if (result.size() < PA_N)
678 LOG_WARN(
"Received wrong number of detailed sensor data. Retrying...");
682 if (result == lastSensorData)
686 PowerSensorsN[SENSOR_VOLTAGE].value = std::stod(result[PA_VOLTAGE]);
687 PowerSensorsN[SENSOR_CURRENT].value = std::stod(result[PA_CURRENT]) / 65.0;
689 if (lastSensorData[PA_VOLTAGE] != result[PA_VOLTAGE] || lastSensorData[PA_CURRENT] != result[PA_CURRENT])
696 if (lastSensorData[PA_TEMPERATURE] != result[PA_TEMPERATURE] ||
697 lastSensorData[PA_HUMIDITY] != result[PA_HUMIDITY] ||
698 lastSensorData[PA_DEW_POINT] != result[PA_DEW_POINT])
710 if (lastSensorData[PA_PORT_STATUS] != result[PA_PORT_STATUS])
722 if (std::stoi(result[PA_ADJ_STATUS]) == 0)
723 AdjOutVoltS[ADJOUT_OFF].s =
ISS_ON;
726 AdjOutVoltS[ADJOUT_3V].s = (std::stoi(result[PA_PWRADJ]) == 3) ?
ISS_ON :
ISS_OFF;
727 AdjOutVoltS[ADJOUT_5V].s = (std::stoi(result[PA_PWRADJ]) == 5) ?
ISS_ON :
ISS_OFF;
728 AdjOutVoltS[ADJOUT_8V].s = (std::stoi(result[PA_PWRADJ]) == 8) ?
ISS_ON :
ISS_OFF;
729 AdjOutVoltS[ADJOUT_9V].s = (std::stoi(result[PA_PWRADJ]) == 9) ?
ISS_ON :
ISS_OFF;
730 AdjOutVoltS[ADJOUT_12V].s = (std::stoi(result[PA_PWRADJ]) == 12) ?
ISS_ON :
ISS_OFF;
732 if (lastSensorData[PA_PWRADJ] != result[PA_PWRADJ] || lastSensorData[PA_ADJ_STATUS] != result[PA_ADJ_STATUS])
736 PowerWarnL[0].s = (std::stoi(result[PA_PWR_WARN]) == 1) ?
IPS_ALERT :
IPS_OK;
738 if (lastSensorData[PA_PWR_WARN] != result[PA_PWR_WARN])
742 DewPWMN[0].value = std::stod(result[PA_DEW_1]) / 255.0 * 100.0;
743 DewPWMN[1].value = std::stod(result[PA_DEW_2]) / 255.0 * 100.0;
744 if (lastSensorData[PA_DEW_1] != result[PA_DEW_1] || lastSensorData[PA_DEW_2] != result[PA_DEW_2])
750 AutoDewSP.
s = (std::stoi(result[PA_AUTO_DEW]) == 1) ?
IPS_OK :
IPS_IDLE;
751 if (lastSensorData[PA_AUTO_DEW] != result[PA_AUTO_DEW])
754 lastSensorData = result;
762 bool PegasusPPBA::getConsumptionData()
764 char res[PEGASUS_LEN] = {0};
765 if (sendCommand(
"PS", res))
767 std::vector<std::string> result = split(res,
":");
768 if (result.size() < PS_N)
770 LOG_WARN(
"Received wrong number of detailed consumption data. Retrying...");
774 if (result == lastConsumptionData)
778 PowerSensorsN[SENSOR_AVG_AMPS].value = std::stod(result[PS_AVG_AMPS]);
779 PowerSensorsN[SENSOR_AMP_HOURS].value = std::stod(result[PS_AMP_HOURS]);
780 PowerSensorsN[SENSOR_WATT_HOURS].value = std::stod(result[PS_WATT_HOURS]);
782 if (lastConsumptionData[PS_AVG_AMPS] != result[PS_AVG_AMPS] || lastConsumptionData[PS_AMP_HOURS] != result[PS_AMP_HOURS]
783 || lastConsumptionData[PS_WATT_HOURS] != result[PS_WATT_HOURS])
786 lastConsumptionData = result;
794 bool PegasusPPBA::getMetricsData()
796 char res[PEGASUS_LEN] = {0};
797 if (sendCommand(
"PC", res))
799 std::vector<std::string> result = split(res,
":");
800 if (result.size() < PC_N)
802 LOG_WARN(
"Received wrong number of detailed metrics data. Retrying...");
806 if (result == lastMetricsData)
810 PowerSensorsN[SENSOR_TOTAL_CURRENT].value = std::stod(result[PC_TOTAL_CURRENT]);
811 PowerSensorsN[SENSOR_12V_CURRENT].value = std::stod(result[PC_12V_CURRENT]);
812 PowerSensorsN[SENSOR_DEWA_CURRENT].value = std::stod(result[PC_DEWA_CURRENT]);
813 PowerSensorsN[SENSOR_DEWB_CURRENT].value = std::stod(result[PC_DEWB_CURRENT]);
815 if (lastMetricsData[PC_TOTAL_CURRENT] != result[PC_TOTAL_CURRENT] ||
816 lastMetricsData[PC_12V_CURRENT] != result[PC_12V_CURRENT] ||
817 lastMetricsData[PC_DEWA_CURRENT] != result[PC_DEWA_CURRENT] ||
818 lastMetricsData[PC_DEWB_CURRENT] != result[PC_DEWB_CURRENT])
821 std::chrono::milliseconds uptime(std::stol(result[PC_UPTIME]));
822 using dhours = std::chrono::duration<double, std::ratio<3600>>;
823 std::stringstream ss;
824 ss << std::fixed << std::setprecision(3) << dhours(uptime).count();
825 IUSaveText(&FirmwareT[FIRMWARE_UPTIME], ss.str().c_str());
828 lastMetricsData = result;
836 bool PegasusPPBA::reboot()
838 return sendCommand(
"PF",
nullptr);
846 char cmd[PEGASUS_LEN] = {0}, res[PEGASUS_LEN] = {0};
847 snprintf(
cmd, PEGASUS_LEN,
"XS:3#%u", targetTicks);
864 return sendCommand(
"XS:6",
nullptr);
872 char cmd[PEGASUS_LEN] = {0};
873 snprintf(
cmd, PEGASUS_LEN,
"XS:8#%d", enabled ? 1 : 0);
874 return sendCommand(
cmd,
nullptr);
882 char cmd[PEGASUS_LEN] = {0};
883 snprintf(
cmd, PEGASUS_LEN,
"XS:5#%u", ticks);
884 return sendCommand(
cmd,
nullptr);
892 char cmd[PEGASUS_LEN] = {0};
893 snprintf(
cmd, PEGASUS_LEN,
"XS:10#%d", steps);
894 return sendCommand(
cmd,
nullptr);
900 bool PegasusPPBA::setFocuserMaxSpeed(uint16_t maxSpeed)
902 char cmd[PEGASUS_LEN] = {0};
903 snprintf(
cmd, PEGASUS_LEN,
"XS:7#%d", maxSpeed);
904 return sendCommand(
cmd,
nullptr);
907 bool PegasusPPBA::setFocuserMicrosteps(
int value)
909 char cmd[PEGASUS_LEN] = {0};
910 snprintf(
cmd, PEGASUS_LEN,
"XS:9#%d", value);
911 return sendCommand(
cmd,
nullptr);
919 char cmd[PEGASUS_LEN] = {0};
920 snprintf(
cmd, PEGASUS_LEN,
"XS:8#%d", enabled ? 1 : 0);
921 return sendCommand(
cmd,
nullptr);
927 bool PegasusPPBA::getXMCStartupData()
929 char res[PEGASUS_LEN] = {0};
932 if (sendCommand(
"XS:2", res))
934 uint32_t position = 0;
935 sscanf(res,
"%*[^#]#%d", &position);
940 if (sendCommand(
"XS:7", res))
943 sscanf(res,
"%*[^#]#%d", &speed);
944 FocuserSettingsN[0].value = speed;
953 void PegasusPPBA::queryXMC()
955 char res[PEGASUS_LEN] = {0};
956 uint32_t position = 0;
957 uint32_t motorRunning = 0;
960 if (sendCommand(
"XS:1", res))
961 sscanf(res,
"%*[^#]#%d", &motorRunning);
963 if (sendCommand(
"XS:2", res))
964 sscanf(res,
"%*[^#]#%d", &position);
976 else if (lastPosition != position)
983 std::vector<std::string> PegasusPPBA::split(
const std::string &input,
const std::string ®ex)
986 std::regex re(regex);
987 std::sregex_token_iterator
988 first{input.begin(), input.end(), re, -1},
990 return {first, last};
void registerHandshake(std::function< bool()> callback)
registerHandshake Register a handshake function to be called once the intial connection to the device...
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 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()
Initilize properties initial state and value. The child class must implement this function.
void syncDriverInfo()
syncDriverInfo sends the current driver information to the client.
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.
void setDriverInterface(uint16_t value)
setInterface Set driver interface. By default the driver interface is set to GENERAL_DEVICE....
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
uint16_t getDriverInterface() const
Provides interface to implement focuser functionality.
INumberVectorProperty FocusAbsPosNP
INumberVectorProperty FocusRelPosNP
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)
Initilize focuser properties. It is recommended to call this function within initProperties() of your...
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.
Provides interface to implement weather reporting functionality.
bool syncCriticalParameters()
updateWeatherState Send update weather state to client
void setParameterValue(std::string name, double value)
setParameterValue Update weather parameter value
bool setCriticalParameter(std::string param)
setCriticalParameter Set parameter that is considered critical to the operation of the observatory....
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.
ILightVectorProperty critialParametersLP
INumberVectorProperty ParametersNP
void addParameter(std::string name, std::string label, double numMinOk, double numMaxOk, double percWarning)
addParameter Add a physical weather measurable parameter to the weather driver. The weather value has...
void initProperties(const char *statusGroup, const char *paramsGroup)
Initilize focuser properties. It is recommended to call this function within initProperties() of your...
bool updateProperties()
updateProperties Define or Delete Rotator properties based on the connection status of the base devic...
virtual bool AbortFocuser() override
AbortFocuser all focus motion.
const char * getDefaultName() override
virtual bool SyncFocuser(uint32_t ticks) override
SyncFocuser Set current position to ticks without moving the focuser.
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.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
virtual IPState MoveRelFocuser(FocusDirection dir, uint32_t ticks) override
MoveFocuser the focuser to an relative position.
virtual bool initProperties() override
Initilize 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 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 bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
virtual IPState MoveAbsFocuser(uint32_t targetTicks) override
MoveFocuser the focuser to an absolute position.
virtual bool SetFocuserBacklash(int32_t steps) override
SetFocuserBacklash Set the focuser backlash compensation value.
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
void ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Update the value of an existing switch vector property.
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.
void IUSaveConfigSwitch(FILE *fp, const ISwitchVectorProperty *svp)
Add a switch vector property value to the configuration file.
void IUFillLight(ILight *lp, const char *name, const char *label, IPState s)
Assign attributes for a light property. The light's auxiliary elements will be set to NULL.
void IUFillNumberVector(INumberVectorProperty *nvp, INumber *np, int nnp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a number vector property. The vector's auxiliary elements will be set to NULL.
int IUFindOnSwitchIndex(const ISwitchVectorProperty *svp)
Returns the index of first ON switch it finds in the vector switch property.
void IUResetSwitch(ISwitchVectorProperty *svp)
Reset all switches in a switch vector property to OFF.
void IUFillLightVector(ILightVectorProperty *lvp, ILight *lp, int nlp, const char *dev, const char *name, const char *label, const char *group, IPState s)
Assign attributes for a light vector property. The vector's auxiliary elements will be set to NULL.
void IUFillTextVector(ITextVectorProperty *tvp, IText *tp, int ntp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a text vector property. The vector's auxiliary elements will be set to NULL.
void IUSaveText(IText *tp, const char *newtext)
Function to reliably save new text in a IText.
void IUSaveConfigNumber(FILE *fp, const INumberVectorProperty *nvp)
Add a number vector property value to the configuration file.
void IUFillSwitch(ISwitch *sp, const char *name, const char *label, ISState s)
Assign attributes for a switch property. The switch's auxiliary elements will be set to NULL.
void IUFillText(IText *tp, const char *name, const char *label, const char *initialText)
Assign attributes for a text property. The text's auxiliary elements will be set to NULL.
void IUFillNumber(INumber *np, const char *name, const char *label, const char *format, double min, double max, double step, double value)
Assign attributes for a number property. The number's auxiliary elements will be set to NULL.
void IUFillSwitchVector(ISwitchVectorProperty *svp, ISwitch *sp, int nsp, const char *dev, const char *name, const char *label, const char *group, IPerm p, ISRule r, double timeout, IPState s)
Assign attributes for a switch vector property. The vector's auxiliary elements will be set to NULL.
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector property.
void IDSetLight(const ILightVectorProperty *lvp, const char *fmt,...)
void IDSetNumber(const INumberVectorProperty *nvp, const char *fmt,...)
void IDSetSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
int IUUpdateNumber(INumberVectorProperty *nvp, double values[], char *names[], int n)
Update all numbers in a number vector property.
void IDSetText(const ITextVectorProperty *tvp, const char *fmt,...)
#define LOGF_INFO(fmt,...)
#define LOGF_DEBUG(fmt,...)
#define LOGF_ERROR(fmt,...)