63 it->defaultDevice->ISGetProperties(dev);
70 if (dev ==
nullptr || strcmp(dev, it->defaultDevice->getDeviceName()) == 0)
71 it->defaultDevice->ISNewSwitch(dev, name, states, names, n);
74 void ISNewNumber(
const char *dev,
const char *name,
double values[],
char *names[],
int n)
78 if (dev ==
nullptr || strcmp(dev, it->defaultDevice->getDeviceName()) == 0)
79 it->defaultDevice->ISNewNumber(dev, name, values, names, n);
82 void ISNewText(
const char *dev,
const char *name,
char *texts[],
char *names[],
int n)
86 if (dev ==
nullptr || strcmp(dev, it->defaultDevice->getDeviceName()) == 0)
87 it->defaultDevice->ISNewText(dev, name, texts, names, n);
91 int sizes[],
int blobsizes[],
char *blobs[],
char *formats[],
char *names[],
int n
96 if (dev ==
nullptr || strcmp(dev, it->defaultDevice->getDeviceName()) == 0)
97 it->defaultDevice->ISNewBLOB(dev, name, sizes, blobsizes, blobs, formats, names, n);
104 it->defaultDevice->ISSnoopDevice(root);
127static struct WeakIDLoader
152 if (devPtr !=
nullptr)
170static inline void ltrim(std::string &s)
175 s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](
unsigned char ch)
177 return !std::isspace(ch);
182static inline void rtrim(std::string &s)
187 s.erase(std::find_if(s.rbegin(), s.rend(), [](
unsigned char ch)
189 return !std::isspace(ch);
194static void trim(std::string &s)
200static std::string GetHomeDirectory()
203 const char *HomeDir = getenv(
"HOME");
208 HomeDir = getpwuid(getuid())->pw_dir;
210 return (HomeDir ? std::string(HomeDir) :
"");
243#define NICKNAME_FILE "/.indi/Nicknames.xml"
244#define NICK_TAG_ROOT "INDINicknames"
245#define NICK_TAG_DEVICE "device"
246#define NICK_ATTR_NAME "name"
247#define NICK_TAG_ENTRY "nickname"
248#define NICK_ATTR_ID "identifier"
252 const std::string filename = GetHomeDirectory() +
NICKNAME_FILE;
256 XMLEle *NickXmlRoot =
nullptr;
257 XMLEle *devicexml =
nullptr;
258 XMLEle *nickxml =
nullptr;
260 memset(errmsg, 0,
sizeof(errmsg));
261 FILE *fp = fopen(filename.c_str(),
"r");
271 if (!NickXmlRoot || errmsg[0])
284 for (; devicexml != NULL; devicexml =
nextXMLEle(NickXmlRoot, 0))
289 printf(
"Skipping XML Non-Device: %s\n",
tagXMLEle(devicexml));
296 if (devname && strcmp(devname, devicename) == 0)
304 for (; nickxml != NULL; nickxml =
nextXMLEle(devicexml, 0))
315 std::string sId{pId}, sVal{pVal};
318 if (!sId.empty() && !sVal.empty())
340 const std::string filename = GetHomeDirectory() +
NICKNAME_FILE;
343 XMLEle *NickXmlRoot =
nullptr;
344 XMLEle *devicexml =
nullptr;
345 XMLEle *nickxml =
nullptr;
347 memset(errmsg, 0,
sizeof(errmsg));
348 FILE *fp = fopen(filename.c_str(),
"r+");
368 for (; devicexml != NULL; devicexml =
nextXMLEle(NickXmlRoot, 0))
377 if (devname && strcmp(devname, devicename) == 0)
393 while ((nickxml =
nextXMLEle(devicexml, 1)) != 0)
409 fp = freopen(filename.c_str(),
"w+", fp);
411 fp = fopen(filename.c_str(),
"w+");
424 : defaultDevice(defaultDevice)
440 d->m_MainLoopTimer.setSingleShot(
true);
454 d->isConfigLoading =
true;
456 d->isConfigLoading =
false;
462 LOG_DEBUG(
"Configuration successfully loaded.");
465 LOG_INFO(
"No previous configuration found. To save driver configuration, click Save Configuration in Options tab.");
470 if (d->isDefaultConfigLoaded ==
false)
482 d->PollPeriodNP.save(fp);
483 if (!d->ConnectionModeSP.isEmpty())
484 d->ConnectionModeSP.save(fp);
486 if (d->activeConnection !=
nullptr)
487 d->activeConnection->saveConfigItems(fp);
498 const auto &svp = oneProperty.getSwitch();
502 (svp->getRule() ==
ISR_1OFMANY && svp->findOnSwitch() ==
nullptr)
506 oneProperty.save(fp);
520 LOG_INFO(
"Configuration file successfully purged.");
532 if (d->isConfigLoading)
539 if (property ==
nullptr)
546 LOGF_WARN(
"Failed to save configuration. %s", errmsg);
559 if (d->isDefaultConfigLoaded ==
false)
564 LOG_DEBUG(
"Configuration successfully saved.");
589 bool propertySaved =
false;
594 auto savedLayoutMatches = [&ep](
const auto &oneProperty)
596 size_t savedCount = 0;
599 if (oneProperty.findWidgetByName(
findXMLAttValu(oneElement,
"name")) ==
nullptr)
602 return savedCount == oneProperty.count();
610 if (strcmp(elemName, property))
613 if (!strcmp(tagName,
"newSwitchVector"))
622 if (!savedLayoutMatches(svp))
631 auto oneSwitch = svp.findWidgetByName(
findXMLAttValu(sw,
"name"));
638 snprintf(formatString,
MAXRBUF,
" %s\n", oneSwitch->getStateAsString());
642 propertySaved =
true;
645 else if (!strcmp(tagName,
"newNumberVector"))
654 if (!savedLayoutMatches(nvp))
663 auto oneNumber = nvp.findWidgetByName(
findXMLAttValu(np,
"name"));
668 snprintf(formatString,
MAXRBUF,
" %.20g\n", oneNumber->getValue());
672 propertySaved =
true;
675 else if (!strcmp(tagName,
"newTextVector"))
684 if (!savedLayoutMatches(tvp))
698 snprintf(formatString,
MAXRBUF,
" %s\n", oneText->getText() ? oneText->getText() :
"");
702 propertySaved =
true;
714 LOGF_DEBUG(
"Configuration successfully saved for %s.", property);
730 char configDefaultFileName[
MAXRBUF];
732 bool pResult =
false;
734 if (getenv(
"INDICONFIG"))
735 snprintf(configDefaultFileName,
MAXRBUF,
"%s.default", getenv(
"INDICONFIG"));
737 snprintf(configDefaultFileName,
MAXRBUF,
"%s/.indi/%s_config.xml.default", getenv(
"HOME"),
getDeviceName());
739 LOGF_DEBUG(
"Requesting to load default config with: %s", configDefaultFileName);
744 LOG_INFO(
"Default configuration loaded.");
746 LOGF_INFO(
"Error loading default configuration. %s", errmsg);
760 if (!property.isValid())
768 property.isNameMatch(
"DEBUG_LEVEL") ||
769 property.isNameMatch(
"LOGGING_LEVEL") ||
770 property.isNameMatch(
"LOG_OUTPUT"))
774 if (property.isNameMatch(
"LOG_OUTPUT"))
776 auto sw =
property.findWidgetByName(
"FILE_DEBUG");
777 if (sw !=
nullptr && sw->getState() ==
ISS_ON)
784 property.update(states, names, n);
785 if (property.hasUpdateCallback())
790 rc |= oneConnection->ISNewSwitch(dev, name, states, names, n);
801 if (!property.isValid())
804 property.update(values, names, n);
805 if (property.hasUpdateCallback())
809 oneConnection->ISNewNumber(dev, name, values, names, n);
820 if (!property.isValid())
823 property.update(texts, names, n);
824 if (property.hasUpdateCallback())
828 oneConnection->ISNewText(dev, name, texts, names, n);
834 char *formats[],
char *names[],
int n)
840 if (!property.isValid())
843 property.update(sizes, blobsizes, blobs, formats, names, n);
844 if (property.hasUpdateCallback())
848 oneConnection->ISNewBLOB(dev, name, sizes, blobsizes, blobs, formats, names, n);
863 d->watchDevice.watchDevice(name, callback);
878 d->isSimulation =
false;
910 if (d->isDebug == enable)
912 d->DebugSP.setState(
IPS_OK);
919 auto sp = d->DebugSP.findWidgetByName(enable ?
"ENABLE" :
"DISABLE");
923 LOGF_INFO(
"Debug is %s.", enable ?
"enabled" :
"disabled");
933 d->DebugSP.setState(
IPS_OK);
940 if (d->isSimulation == enable)
942 d->SimulationSP.setState(
IPS_OK);
943 d->SimulationSP.apply();
947 d->SimulationSP.reset();
949 auto sp = d->SimulationSP.findWidgetByName(enable ?
"ENABLE" :
"DISABLE");
952 LOGF_INFO(
"Simulation is %s.", enable ?
"enabled" :
"disabled");
956 d->isSimulation = enable;
958 d->SimulationSP.setState(
IPS_OK);
959 d->SimulationSP.apply();
971 return d->isSimulation;
992 if (d->isInit ==
false)
998 char *envDev = getenv(
"INDIDEV");
999 if (envDev !=
nullptr)
1010 if (d->connections.size() == 0)
1011 d->DriverInfoTP.setGroupName(
INFO_TAB);
1016 if (d->defineDynamicProperties ==
false && oneProperty.isDynamic())
1019 oneProperty.define();
1023 if (d->isInit ==
false)
1032 if (d->ConnectionModeSP.isEmpty())
1034 if (d->connections.size() > 0)
1036 d->ConnectionModeSP.resize(d->connections.size());
1037 auto sp = &d->ConnectionModeSP[0];
1040 (sp++)->fill(oneConnection->name(), oneConnection->label(),
ISS_OFF);
1048 d->ConnectionModeSP[d->m_ConfigConnectionMode].setState(
ISS_ON);
1049 d->activeConnection = d->connections[d->m_ConfigConnectionMode];
1052 else if (d->activeConnection !=
nullptr)
1054 auto it = std::find(d->connections.begin(), d->connections.end(), d->activeConnection);
1055 if (it != d->connections.end())
1057 int index = std::distance(d->connections.begin(), it);
1059 d->ConnectionModeSP[index].setState(
ISS_ON);
1065 d->ConnectionModeSP[0].setState(
ISS_ON);
1066 d->activeConnection = d->connections[0];
1070 d->activeConnection->Activated();
1082 oneProperty.apply();
1094 svp.setState(state);
1099 svp.apply(
"%s", msg);
1107 d->m_MainLoopTimer.start(ms);
1117 d->m_MainLoopTimer.stop();
1145 return atoi(d->DriverInfoTP[3 ].getText());
1151 d->DriverInfoTP[3 ].setText(std::to_string(value));
1157 d->DriverInfoTP.apply();
1163 char versionStr[16];
1164 char interfaceStr[16];
1166 snprintf(versionStr, 16,
"%d.%d", d->majorVersion, d->minorVersion);
1170 d->ConnectionModeSP.onUpdate([d]()
1172 int activeConnectionMode = d->ConnectionModeSP.findOnSwitchIndex();
1174 if (activeConnectionMode >= 0 && activeConnectionMode <
static_cast<int>(d->connections.size()))
1176 d->activeConnection = d->connections[activeConnectionMode];
1177 d->activeConnection->Activated();
1179 for (Connection::Interface *oneConnection : d->connections)
1181 if (oneConnection == d->activeConnection)
1184 oneConnection->Deactivated();
1187 d->ConnectionModeSP.setState(
IPS_OK);
1190 d->ConnectionModeSP.setState(
IPS_ALERT);
1192 d->ConnectionModeSP.apply();
1197 d->ConnectionSP[INDI_ENABLED ].fill(
"CONNECT",
"Connect",
ISS_OFF);
1198 d->ConnectionSP[INDI_DISABLED].fill(
"DISCONNECT",
"Disconnect",
ISS_ON);
1205 if (isConnected() ==
false)
1224 if (isConnected() ==
true)
1241 registerProperty(d->ConnectionSP);
1243 d->DriverInfoTP[0].fill(
"DRIVER_NAME",
"Name", getDriverName());
1244 d->DriverInfoTP[1].fill(
"DRIVER_EXEC",
"Exec", getDriverExec());
1245 d->DriverInfoTP[2].fill(
"DRIVER_VERSION",
"Version", versionStr);
1246 d->DriverInfoTP[3].fill(
"DRIVER_INTERFACE",
"Interface", interfaceStr);
1248 registerProperty(d->DriverInfoTP);
1251 d->DebugSP[INDI_ENABLED ].fill(
"ENABLE",
"Enable",
ISS_OFF);
1252 d->DebugSP[INDI_DISABLED].fill(
"DISABLE",
"Disable",
ISS_ON);
1254 d->DebugSP.onUpdate([
this, d]()
1256 auto sp = d->DebugSP.findOnSwitch();
1257 assert(sp !=
nullptr);
1258 setDebug(sp->isNameMatch(
"ENABLE") ?
true : false);
1262 d->SimulationSP[INDI_ENABLED ].fill(
"ENABLE",
"Enable",
ISS_OFF);
1263 d->SimulationSP[INDI_DISABLED].fill(
"DISABLE",
"Disable",
ISS_ON);
1265 d->SimulationSP.onUpdate([
this, d]()
1267 auto sp = d->SimulationSP.findOnSwitch();
1268 assert(sp !=
nullptr);
1269 setSimulation(sp->isNameMatch(
"ENABLE") ?
true : false);
1273 d->ConfigProcessSP[0].fill(
"CONFIG_LOAD",
"Load",
ISS_OFF);
1274 d->ConfigProcessSP[1].fill(
"CONFIG_SAVE",
"Save",
ISS_OFF);
1275 d->ConfigProcessSP[2].fill(
"CONFIG_DEFAULT",
"Default",
ISS_OFF);
1276 d->ConfigProcessSP[3].fill(
"CONFIG_PURGE",
"Purge",
ISS_OFF);
1278 d->ConfigProcessSP.onUpdate([
this, d]()
1280 auto svp = d->ConfigProcessSP;
1281 auto sp = svp.findOnSwitch();
1283 bool pResult =
false;
1293 if (sp->isNameMatch(
"CONFIG_LOAD"))
1294 pResult = loadConfig();
1295 else if (sp->isNameMatch(
"CONFIG_SAVE"))
1296 pResult = saveConfig();
1297 else if (sp->isNameMatch(
"CONFIG_DEFAULT"))
1298 pResult = loadDefaultConfig();
1299 else if (sp->isNameMatch(
"CONFIG_PURGE"))
1300 pResult = purgeConfig();
1307 d->PollPeriodNP[0].fill(
"PERIOD_MS",
"Period (ms)",
"%.f", 10, 600000, 1000, d->pollingPeriod);
1309 d->PollPeriodNP.onUpdate([d]()
1311 d->PollPeriodNP.setState(
IPS_OK);
1312 d->pollingPeriod =
static_cast<uint32_t
>(d->PollPeriodNP[0].getValue());
1313 d->PollPeriodNP.apply();
1316 d->NicknameTP[0].fill(
"nickname",
"nickname", d->deviceNickname.c_str());
1318 d->NicknameTP.onUpdate([d,
this]()
1320 setDeviceNickname(d->NicknameTP[0].getText());
1321 d->NicknameTP[0].setText(d->deviceNickname);
1322 d->NicknameTP.setState(
IPS_OK);
1323 d->NicknameTP.apply();
1324 nicknameSet(d->deviceNickname.c_str());
1330 std::string logFile = getDriverExec();
1339 return deleteProperty(property.
getName());
1342bool DefaultDevice::deleteProperty(
const char *propertyName)
1347 if (propertyName ==
nullptr)
1355 if (d->deleteDynamicProperties ==
false)
1365 if (removeProperty(propertyName, errmsg) == 0)
1406 registerProperty(property);
1412 defineProperty(nvp);
1417 defineProperty(tvp);
1422 defineProperty(svp);
1427 defineProperty(lvp);
1432 defineProperty(bvp);
1435bool DefaultDevice::Connect()
1441 if (d->activeConnection ==
nullptr)
1443 LOG_ERROR(
"No active connection defined.");
1447 bool rc = d->activeConnection->Connect();
1451 if (d->ConnectionModeSP.findOnSwitchIndex() != d->m_ConfigConnectionMode)
1452 saveConfig(
true, d->ConnectionModeSP.getName());
1453 if (d->pollingPeriod > 0)
1454 SetTimer(d->pollingPeriod);
1460bool DefaultDevice::Disconnect()
1469 if (d->activeConnection)
1471 bool rc = d->activeConnection->Disconnect();
1487 d->connections.push_back(newConnection);
1494 auto i = std::begin(d->connections);
1496 while (i != std::end(d->connections))
1498 if (*i == existingConnection)
1500 i = d->connections.erase(i);
1510void DefaultDevice::setCurrentPollingPeriod(uint32_t msec)
1513 d->pollingPeriod = msec;
1516uint32_t DefaultDevice::getCurrentPollingPeriod()
const
1519 return d->pollingPeriod;
1522uint32_t &DefaultDevice::refCurrentPollingPeriod()
1525 return d->pollingPeriod;
1528uint32_t DefaultDevice::refCurrentPollingPeriod()
const
1531 return d->pollingPeriod;
1534void DefaultDevice::setDefaultPollingPeriod(uint32_t msec)
1537 d->PollPeriodNP[0].setValue(msec);
1538 d->pollingPeriod = msec;
1541void DefaultDevice::setPollingPeriodRange(uint32_t minimum, uint32_t maximum)
1545 d->PollPeriodNP[0].setMinMax(minimum, maximum);
1546 d->PollPeriodNP.updateMinMax();
1553 if (existingConnection == d->activeConnection)
1558 if (oneConnection == d->activeConnection)
1560 oneConnection->Deactivated();
1565 d->activeConnection = existingConnection;
1566 if (!d->ConnectionModeSP.isEmpty())
1568 auto it = std::find(d->connections.begin(), d->connections.end(), d->activeConnection);
1569 if (it != d->connections.end())
1571 int index = std::distance(d->connections.begin(), it);
1574 d->ConnectionModeSP.reset();
1575 d->ConnectionModeSP[index].setState(
ISS_ON);
1576 d->ConnectionModeSP.setState(
IPS_OK);
1579 if (connectionProperty && connectionProperty.
getRegistered())
1580 d->ConnectionModeSP.apply();
1586const char *DefaultDevice::getDriverExec()
1591const char *DefaultDevice::getDriverName()
1593 return getDefaultName();
1596void DefaultDevice::setDeviceNickname(
const char *nick)
1599 std::string def{getDefaultName()};
1601 std::string n, full;
1605 if (n.rfind(def, 0) == 0)
1607 n = n.substr(def.length());
1611 d->deviceNickname = n;
1617 if (d->deviceNickname.empty())
1620 full = def +
" " + d->deviceNickname;
1621 setDeviceName(full.c_str());
1625const char *DefaultDevice::getDeviceNickname()
1628 return d->deviceNickname.c_str();
1631const char *DefaultDevice::lookupDeviceNicknameFromId(
const char *identifier,
const char *
device)
1645 std::string
id{identifier};
1647 if (!d->nicknamesLoaded)
1648 d->loadINDINicknamesXML(getDefaultName());
1650 auto search = d->nicknameMap.find(
id);
1651 if (search != d->nicknameMap.end())
1652 return search->second.c_str();
1657bool DefaultDevice::setDeviceNicknameFromId(
const char *identifier)
1659 const char *nick = lookupDeviceNicknameFromId(identifier);
1660 bool hasNickname = (nick && *nick);
1661 setDeviceNickname(nick);
1665void DefaultDevice::saveNicknameId(
const char *nickname,
const char *identifier)
1671 std::string
id{identifier};
1673 std::string nick = (nickname) ? nickname : d->deviceNickname;
1674 if (nick.empty() ||
id.empty())
1677 if (!d->nicknamesLoaded)
1678 d->loadINDINicknamesXML(getDefaultName());
1680 d->nicknameMap[id] = nick;
1681 d->saveINDINicknamesXML(getDefaultName());
1684void DefaultDevice::setVersion(uint16_t vMajor, uint16_t vMinor)
1687 d->majorVersion = vMajor;
1688 d->minorVersion = vMinor;
1691uint16_t DefaultDevice::getMajorVersion()
const
1694 return d->majorVersion;
1697uint16_t DefaultDevice::getMinorVersion()
const
1700 return d->minorVersion;
1703void DefaultDevice::setDynamicPropertiesBehavior(
bool defineEnabled,
bool deleteEnabled)
1706 d->defineDynamicProperties = defineEnabled;
1707 d->deleteDynamicProperties = deleteEnabled;
1713 return d->activeConnection;
1716uint32_t DefaultDevice::getPollingPeriod()
const
1719 return static_cast<uint32_t
>(d->PollPeriodNP[0].getValue());
1722bool DefaultDevice::isConfigLoading()
const
1725 return d->isConfigLoading;
1728bool DefaultDevice::isInitializationComplete()
const
1734bool DefaultDevice::ISNewProperty(
INDI::Property &property,
const std::string &elementName,
const std::any &value)
1736 if (!property.
isValid() || elementName.empty())
1743 strncpy(mutableElementName, elementName.c_str(),
sizeof(mutableElementName) - 1);
1744 mutableElementName[
sizeof(mutableElementName) - 1] =
'\0';
1745 char *names[] = { mutableElementName };
1753 ISState newState = std::any_cast<ISState>(value);
1754 ISState states[] = { newState };
1757 catch (
const std::bad_any_cast &e)
1759 LOGF_ERROR(
"ISNewProperty: Type mismatch for Switch property '%s'. Expected ISState. Got: %s",
1760 property.
getName(), e.what());
1768 double newValue = 0;
1769 if (value.type() ==
typeid(
int))
1771 newValue =
static_cast<double>(std::any_cast<int>(value));
1773 else if (value.type() ==
typeid(long))
1775 newValue =
static_cast<double>(std::any_cast<long>(value));
1777 else if (value.type() ==
typeid(double))
1779 newValue = std::any_cast<double>(value);
1783 throw std::bad_any_cast();
1786 double values[] = { newValue };
1789 catch (
const std::bad_any_cast &e)
1791 LOGF_ERROR(
"ISNewProperty: Type mismatch for Number property '%s'. Expected double, int, or long. Got: %s",
1792 property.
getName(), e.what());
1800 char mutableTextValue[1024];
1801 memset(mutableTextValue, 0,
sizeof(mutableTextValue));
1803 if (value.type() ==
typeid(
const char *))
1805 const char *text = std::any_cast<const char *>(value);
1806 if (text) strncpy(mutableTextValue, text,
sizeof(mutableTextValue) - 1);
1808 else if (value.type() ==
typeid(std::string))
1810 const std::string &text = std::any_cast<std::string>(value);
1811 strncpy(mutableTextValue, text.c_str(),
sizeof(mutableTextValue) - 1);
1815 throw std::bad_any_cast();
1817 mutableTextValue[
sizeof(mutableTextValue) - 1] =
'\0';
1819 char *texts[] = { mutableTextValue };
1822 catch (
const std::bad_any_cast &e)
1824 LOGF_ERROR(
"ISNewProperty: Type mismatch for Text property '%s'. Expected const char* or std::string. Got: %s",
1825 property.
getName(), e.what());
1830 LOGF_WARN(
"ISNewProperty: Unsupported property type for property '%s'.", property.
getName());
The Interface class is the base class for all INDI connection plugins.
Class to provide basic INDI device functionality.
INDI::PropertyNumber getNumber(const char *name) const
const char * getDeviceName() const
Property getProperty(const char *name, INDI_PROPERTY_TYPE type=INDI_UNKNOWN) const
Return a property and its type given its name.
INDI::PropertySwitch getSwitch(const char *name) const
void setDeviceName(const char *dev)
Set the device name.
void registerProperty(const INDI::Property &property)
Register the property to be able to observe and update.
INDI::PropertyText getText(const char *name) const
Properties getProperties()
Return a list of all properties in the device.
int loadINDINicknamesXML(const char *devicename)
int saveINDINicknamesXML(const char *devicename)
Save Nickname data to XML.
static std::list< DefaultDevicePrivate * > devices
virtual ~DefaultDevicePrivate()
static std::recursive_mutex devicesLock
std::map< std::string, std::string > nicknameMap
DefaultDevicePrivate(DefaultDevice *defaultDevice)
Class to provide extended functionality for devices in addition to the functionality provided by INDI...
void addPollPeriodControl()
Add Polling period control to the driver.
virtual bool purgeConfig()
purgeConfig Remove config file from disk.
virtual bool updateProperties()
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
void setSimulation(bool enable)
Toggle driver simulation status A driver can run in simulation mode if Simulation option is enabled b...
virtual bool saveConfig(bool silent=false, const char *property=nullptr)
Save the current properties in a configuration file.
void addConfigurationControl()
Add Configuration control to the driver.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process the client newSwitch command.
void addSimulationControl()
Add Simulation control to 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 void setConnected(bool status, IPState state=IPS_OK, const char *msg=nullptr)
Set connection switch status in the client.
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....
virtual bool loadConfig(bool silent=false, const char *property=nullptr)
Load the last saved configuration file.
void watchDevice(const char *deviceName, const std::function< void(INDI::BaseDevice)> &callback)
Add a device to the watch list.
uint32_t getPollingPeriod() const
getPollingPeriod Return the polling period.
virtual void simulationTriggered(bool enable)
Inform driver that the simulation option was triggered. This function is called after setSimulation i...
void defineProperty(INumberVectorProperty *property)
virtual bool saveConfigItems(FILE *fp)
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
virtual void TimerHit()
Callback function to be called once SetTimer duration elapses.
virtual const char * getDefaultName()=0
void setDebug(bool enable)
Toggle driver debug status A driver can be more verbose if Debug option is enabled by the client.
virtual bool initProperties()
Initialize properties initial state and value. The child class must implement this function.
bool isSimulation() const
void syncDriverInfo()
syncDriverInfo sends the current driver information to the client.
void addAuxControls()
Add Debug, Simulation, and Configuration options to the driver.
virtual bool saveAllConfigItems(FILE *fp)
saveAllConfigItems Save all the drivers' properties in the configuration file
uint32_t getDriverInterface() const
virtual bool ISNewBLOB(const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
Process the client newBLOB command.
virtual bool loadDefaultConfig()
Load the default configuration file.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process the client newNumber command.
void resetProperties()
Set all properties to IDLE state.
virtual void debugTriggered(bool enable)
Inform driver that the debug option was triggered. This function is called after setDebug is triggere...
void RemoveTimer(int id)
Remove timer added with SetTimer.
void addNicknameControl()
Add Nickname text property to the driver.
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
virtual void nicknameSet(const char *nickname)
Inform driver that the nickname has been set.
void addDebugControl()
Add Debug control to the driver.
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
Process the client newSwitch command.
The class is used to create device instances. Class copying is not allowed. When an object is destroy...
Provides generic container for INDI properties.
const char * getName() const
bool getRegistered() const
INDI_PROPERTY_TYPE getType() const
void(* WeakIDSetBLOBVA)(const IBLOBVectorProperty *, const char *, va_list)
const char * GUIDE_TAB
GUIDE_TAB Where all the properties for guiding are located.
const char * CONNECTION_TAB
CONNECTION_TAB Where all device connection settings (serial, usb, ethernet) are defined and controlle...
int(* WeakIUUpdateText)(ITextVectorProperty *, char *[], char *[], int)
int(* WeakIUUpdateNumber)(INumberVectorProperty *, double[], char *[], int n)
void ISNewBLOB(const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
Update data of an existing blob vector property.
int(* WeakIUUpdateBLOB)(IBLOBVectorProperty *, int[], int[], char *[], char *[], char *[], int n)
void(* WeakIDSetLightVA)(const ILightVectorProperty *, const char *, va_list)
void(* WeakIDDefSwitchVA)(const ISwitchVectorProperty *, const char *, va_list)
void(* WeakIDDefTextVA)(const ITextVectorProperty *, const char *, va_list)
const char * FILTER_TAB
FILTER_TAB Where all the properties for filter wheels are located.
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
void(* WeakIDSetTextVA)(const ITextVectorProperty *, const char *, va_list)
void(* WeakIDDefBLOBVA)(const IBLOBVectorProperty *, const char *, va_list)
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 * DATETIME_TAB
DATETIME_TAB Where all date and time setting properties are located.
void ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
Update the value of an existing text vector property.
const char * SATELLITE_TAB
SATELLITE_TAB.
const char * COMMUNICATION_TAB
COMMUNICATION_TAB Where all the properties required to connect/disconnect from a device are located....
const char * INFO_TAB
INFO_TAB Where all the properties for general information are located.
void ISGetProperties(const char *dev)
Get Device Properties.
void(* WeakIDDefNumberVA)(const INumberVectorProperty *, const char *, va_list)
void(* WeakIDDefLightVA)(const ILightVectorProperty *, const char *, va_list)
const char * MOTION_TAB
MOTION_TAB Where all the motion control properties of the device are located.
int(* WeakIUUpdateSwitch)(ISwitchVectorProperty *, ISState *, char *[], int n)
const char * ALIGNMENT_TAB
ALIGNMENT_TAB Where all the properties for guiding are located.
void ISSnoopDevice(XMLEle *root)
Function defined by Drivers that is called when another Driver it is snooping (by having previously c...
void(* WeakIDSetNumberVA)(const INumberVectorProperty *, const char *, va_list)
void ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
void(* WeakIDSetSwitchVA)(const ISwitchVectorProperty *, const char *, va_list)
void(* WeakIUUpdateMinMax)(const INumberVectorProperty *)
const char * SITE_TAB
SITE_TAB Where all site information setting are located.
const char * FOCUS_TAB
FOCUS_TAB Where all the properties for focuser are located.
const char * OPTIONS_TAB
OPTIONS_TAB Where all the driver's options are located. Those may include auxiliary controls,...
Constants and Data structure definitions for the interface to the reference INDI C API implementation...
Implementations for common driver routines.
int IUUpdateBLOB(IBLOBVectorProperty *bvp, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
Update all BLOB members in a BLOB vector property.
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector property.
void IDSetNumberVA(const INumberVectorProperty *nvp, const char *fmt, va_list ap)
void IDDefSwitchVA(const ISwitchVectorProperty *svp, const char *fmt, va_list ap)
void IDDefNumberVA(const INumberVectorProperty *nvp, const char *fmt, va_list ap)
FILE * IUGetConfigFP(const char *filename, const char *dev, const char *mode, char errmsg[])
Open a configuration file for writing and return a configuration file FILE pointer.
void IDDelete(const char *dev, const char *name, const char *fmt,...)
int IUUpdateText(ITextVectorProperty *tvp, char *texts[], char *names[], int n)
Update all text members in a text vector property.
void IDDefTextVA(const ITextVectorProperty *tvp, const char *fmt, va_list ap)
void IDSetBLOBVA(const IBLOBVectorProperty *bvp, const char *fmt, va_list ap)
void IUSaveConfigTag(FILE *fp, int ctag, const char *dev, int silent)
Add opening or closing tag to a configuration file. A configuration file root XML element is <INDIDri...
void IDSetTextVA(const ITextVectorProperty *tvp, const char *fmt, va_list ap)
void IDSnoopDevice(const char *snooped_device, const char *snooped_property)
Function a Driver calls to snoop on another Device. Snooped messages will then arrive via ISSnoopDevi...
int IUReadConfig(const char *filename, const char *dev, const char *property, int silent, char errmsg[])
Loads and processes a configuration file. Once a configuration file is successful loaded,...
void IDDefLightVA(const ILightVectorProperty *lvp, const char *fmt, va_list ap)
int IUUpdateNumber(INumberVectorProperty *nvp, double values[], char *names[], int n)
Update all numbers in a number vector property.
int IUPurgeConfig(const char *filename, const char *dev, char errmsg[])
void IDDefBLOBVA(const IBLOBVectorProperty *bvp, const char *fmt, va_list ap)
int IUSaveDefaultConfig(const char *source_config, const char *dest_config, const char *dev)
Copies an existing configuration file into a default configuration file. If no default configuration ...
int IUGetConfigOnSwitchIndex(const char *dev, const char *property, int *index)
IUGetConfigOnSwitchIndex Opens configuration file and reads single switch property to find ON switch ...
void IUUpdateMinMax(const INumberVectorProperty *nvp)
Function to update the min and max elements of a number in the client.
void IDSetSwitchVA(const ISwitchVectorProperty *svp, const char *fmt, va_list ap)
void IDSetLightVA(const ILightVectorProperty *lvp, const char *fmt, va_list ap)
#define DEBUG_CONF(outputFile, configuration, fileVerbosityLevel, screenVerbosityLevel)
Macro to configure the logger. Example of configuration of the Logger: DEBUG_CONF("outputfile",...
#define LOGF_INFO(fmt,...)
#define DEBUG(priority, msg)
Macro to print log messages. Example of usage of the Logger: DEBUG(DBG_DEBUG, "hello " << "world");.
#define LOGF_WARN(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,...)
#define DEBUGF(priority, msg,...)
const char * findXMLAttValu(XMLEle *ep, const char *name)
Find an XML element's attribute value.
XMLEle * nextXMLEle(XMLEle *ep, int init)
Iterate an XML element for a list of nesetd XML elements.
LilXML * newLilXML()
Create a new lilxml parser.
char * tagXMLEle(XMLEle *ep)
Return the tag of an XML element.
XMLEle * addXMLEle(XMLEle *parent, const char *tag)
add an element with the given tag to the given element. parent can be NULL to make a new root.
void editXMLEle(XMLEle *ep, const char *pcdata)
set the pcdata of the given element
void prXMLEle(FILE *fp, XMLEle *ep, int level)
Print an XML element.
void delXMLEle(XMLEle *ep)
delXMLEle Delete XML element.
char * pcdataXMLEle(XMLEle *ep)
Return the pcdata of an XML element.
void delLilXML(LilXML *lp)
Delete a lilxml parser.
XMLAtt * addXMLAtt(XMLEle *ep, const char *name, const char *valu)
Add an XML attribute to an existing XML element.
XMLEle * readXMLFile(FILE *fp, LilXML *lp, char ynot[])
Handy wrapper to read one xml file.
const char * CONNECTION
Connect to and disconnect from device.
Namespace to encapsulate INDI client, drivers, and mediator classes.
static const loggerConf screen_on
static const loggerConf file_off
static bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
static bool initProperties(INDI::DefaultDevice *device)
static bool updateProperties(bool enable)
static bool saveConfigItems(FILE *fp)
static std::string getLogFile()
static const unsigned int defaultlevel
bool contains(const std::string &key, const ISState &state) const
BLOB (Binary Large Object) vector property descriptor.
Light vector property descriptor.
Number vector property descriptor.
Switch vector property descriptor.
Text vector property descriptor.