Instrument Neutral Distributed Interface INDI  1.9.2
simpleskeleton.cpp

A skeleton file is an external XML file with the driver properties already defined. This tutorial illustrates how to create a driver from a skeleton file and parse/process the properties. The skeleton file name is tutorial_four_sk.xml

Note
Please note that if you create your own skeleton file, you must append _sk postfix to your skeleton file name.
#if 0
Simple Skeleton - Tutorial Four
Demonstration of libindi v0.7 capabilities.
Copyright (C) 2010 Jasem Mutlaq (mutlaqja@ikarustech.com)
This library is free software;
you can redistribute it and / or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation;
either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY;
without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library;
if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110 - 1301 USA
#endif
#include "simpleskeleton.h"
#include <cstdlib>
#include <cstring>
#include <memory>
#include <sys/stat.h>
/* Our simpleSkeleton auto pointer */
std::unique_ptr<SimpleSkeleton> simpleSkeleton(new SimpleSkeleton());
//const int POLLMS = 1000; // Period of update, 1 second.
/**************************************************************************************
** Initialize all properties & set default values.
**************************************************************************************/
{
DefaultDevice::initProperties();
// This is the default driver skeleton file location
// Convention is: drivername_sk_xml
// Default location is /usr/share/indi
const char *skelFileName = "/usr/share/indi/tutorial_four_sk.xml";
struct stat st;
char *skel = getenv("INDISKEL");
if (skel != nullptr)
else if (stat(skelFileName, &st) == 0)
buildSkeleton(skelFileName);
else
"No skeleton file was specified. Set environment variable INDISKEL to the skeleton path and try again.\n");
// Optional: Add aux controls for configuration, debug & simulation that get added in the Options tab
// of the driver.
// Let's print a list of all device properties
int i = 0;
for(const auto &oneProperty: *getProperties())
IDLog("Property #%d: %s\n", i++, oneProperty->getName());
return true;
}
/**************************************************************************************
** Define Basic properties to clients.
***************************************************************************************/
void SimpleSkeleton::ISGetProperties(const char *dev)
{
static int configLoaded = 0;
// Ask the default driver first to send properties.
// If no configuration is load before, then load it now.
if (configLoaded == 0)
{
configLoaded = 1;
}
}
/**************************************************************************************
** Process Text properties
***************************************************************************************/
bool SimpleSkeleton::ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
{
INDI_UNUSED(name);
INDI_UNUSED(texts);
INDI_UNUSED(names);
// Ignore if not ours
if (dev != nullptr && strcmp(dev, getDeviceName()) != 0)
return false;
return false;
}
/**************************************************************************************
**
***************************************************************************************/
bool SimpleSkeleton::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
{
// Ignore if not ours
if (dev != nullptr && strcmp(dev, getDeviceName()) != 0)
return false;
if (nvp == nullptr)
return false;
if (!isConnected())
{
nvp->s = IPS_ALERT;
IDSetNumber(nvp, "Cannot change property while device is disconnected.");
return false;
}
if (strcmp(nvp->name, "Number Property") != 0)
{
IUUpdateNumber(nvp, values, names, n);
nvp->s = IPS_OK;
IDSetNumber(nvp, nullptr);
return true;
}
return false;
}
/**************************************************************************************
**
***************************************************************************************/
bool SimpleSkeleton::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
{
int lightState = 0;
int lightIndex = 0;
// ignore if not ours
if (dev != nullptr && strcmp(dev, getDeviceName()) != 0)
return false;
if (INDI::DefaultDevice::ISNewSwitch(dev, name, states, names, n))
return true;
ILightVectorProperty *lvp = getLight("Light Property");
if (!isConnected())
{
svp->s = IPS_ALERT;
IDSetSwitch(svp, "Cannot change property while device is disconnected.");
return false;
}
if (svp == nullptr || lvp == nullptr)
return false;
if (strcmp(svp->name, "Menu") == 0)
{
IUUpdateSwitch(svp, states, names, n);
ISwitch *onSW = IUFindOnSwitch(svp);
lightIndex = IUFindOnSwitchIndex(svp);
if (lightIndex < 0 || lightIndex > lvp->nlp)
return false;
if (onSW != nullptr)
{
lightState = rand() % 4;
svp->s = IPS_OK;
lvp->s = IPS_OK;
lvp->lp[lightIndex].s = (IPState)lightState;
IDSetSwitch(svp, "Setting to switch %s is successful. Changing corresponding light property to %s.",
onSW->name, pstateStr(lvp->lp[lightIndex].s));
IDSetLight(lvp, nullptr);
}
return true;
}
return false;
}
bool SimpleSkeleton::ISNewBLOB(const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[],
char *formats[], char *names[], int n)
{
if (dev != nullptr && strcmp(dev, getDeviceName()) != 0)
return false;
if (bvp == nullptr)
return false;
if (!isConnected())
{
bvp->s = IPS_ALERT;
IDSetBLOB(bvp, "Cannot change property while device is disconnected.");
return false;
}
if (strcmp(bvp->name, "BLOB Test") == 0)
{
IUUpdateBLOB(bvp, sizes, blobsizes, blobs, formats, names, n);
IBLOB *bp = IUFindBLOB(bvp, names[0]);
if (bp == nullptr)
return false;
IDLog("Received BLOB with name %s, format %s, and size %d, and bloblen %d\n", bp->name, bp->format, bp->size,
bp->bloblen);
char *blobBuffer = new char[bp->bloblen + 1];
strncpy(blobBuffer, ((char *)bp->blob), bp->bloblen);
blobBuffer[bp->bloblen] = '\0';
IDLog("BLOB Content:\n##################################\n%s\n##################################\n",
blobBuffer);
delete[] blobBuffer;
bp->size = 0;
bvp->s = IPS_OK;
IDSetBLOB(bvp, nullptr);
}
return true;
}
/**************************************************************************************
**
***************************************************************************************/
{
return true;
}
{
return true;
}
{
return "Simple Skeleton";
}
INDI::BaseDevice::getProperties
Properties getProperties()
Return a list of all properties in the device.
Definition: basedevice.cpp:168
SimpleSkeleton::Connect
bool Connect() override
Connect to the device. INDI::DefaultDevice implementation connects to appropriate connection interfac...
Definition: simpleskeleton.cpp:256
INDI::DefaultDevice::addAuxControls
void addAuxControls()
Add Debug, Simulation, and Configuration options to the driver.
Definition: defaultdevice.cpp:665
IPState
IPState
Property state.
Definition: indiapi.h:158
_IBLOBVectorProperty::s
IPState s
Definition: indiapi.h:484
Aux::ANY
@ ANY
Definition: celestronauxpacket.h:86
IPS_OK
@ IPS_OK
Definition: indiapi.h:161
_INumberVectorProperty::s
IPState s
Definition: indiapi.h:332
_ILightVectorProperty
Light vector property descriptor.
Definition: indiapi.h:415
ISwitch
One switch descriptor.
SimpleSkeleton::ISNewNumber
bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
Definition: simpleskeleton.cpp:122
IPS_ALERT
@ IPS_ALERT
Definition: indiapi.h:163
_IBLOBVectorProperty
BLOB (Binary Large Object) vector property descriptor.
Definition: indiapi.h:469
INDI::BaseDevice::getBLOB
INDI::PropertyView< IBLOB > * getBLOB(const char *name) const
Definition: basedevice.cpp:119
INDI::BaseDevice::getNumber
INDI::PropertyView< INumber > * getNumber(const char *name) const
Definition: basedevice.cpp:99
INDI::BaseDevice::buildSkeleton
bool buildSkeleton(const char *filename)
Build driver properties from a skeleton file.
Definition: basedevice.cpp:223
IUFindBLOB
IBLOB * IUFindBLOB(const IBLOBVectorProperty *bvp, const char *name)
Find an IBLOB member in a vector BLOB property.
Definition: indicom.c:1381
INDI_UNUSED
#define INDI_UNUSED(x)
Definition: indidevapi.h:799
SimpleSkeleton::initProperties
bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
Definition: simpleskeleton.cpp:53
INDI::BaseDevice::getDeviceName
const char * getDeviceName() const
Definition: basedevice.cpp:799
_ILightVectorProperty::s
IPState s
Definition: indiapi.h:426
IDSetBLOB
void void void void void void void void void IDSetBLOB(const IBLOBVectorProperty *b, const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(2
Tell client to update an existing BLOB vector property.
_ILightVectorProperty::nlp
int nlp
Definition: indiapi.h:430
INDI::BaseDevice::getSwitch
INDI::PropertyView< ISwitch > * getSwitch(const char *name) const
Definition: basedevice.cpp:109
IDLog
void void void void void IDLog(const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(1
Function Drivers call to log a message locally.
IUFindOnSwitch
ISwitch * IUFindOnSwitch(const ISwitchVectorProperty *sp)
Returns the first ON switch it finds in the vector switch property.
Definition: indicom.c:1393
_INumberVectorProperty
Number vector property descriptor.
Definition: indiapi.h:317
SimpleSkeleton::ISNewSwitch
bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
Definition: simpleskeleton.cpp:155
pstateStr
const char * pstateStr(IPState s)
Definition: indicom.c:1194
IDSetLight
void void void void void void void IDSetLight(const ILightVectorProperty *l, const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(2
Tell client to update an existing light vector property.
SimpleSkeleton::ISGetProperties
void ISGetProperties(const char *dev) override
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
Definition: simpleskeleton.cpp:88
_INumberVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:322
INDI::DefaultDevice::loadConfig
virtual bool loadConfig(bool silent=false, const char *property=nullptr)
Load the last saved configuration file.
Definition: defaultdevice.cpp:147
IUUpdateSwitch
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector property.
Definition: indidriver.c:171
INDI::BaseDevice::isConnected
bool isConnected() const
Definition: basedevice.cpp:518
SimpleSkeleton::Disconnect
bool Disconnect() override
Disconnect from device.
Definition: simpleskeleton.cpp:261
SimpleSkeleton::getDefaultName
const char * getDefaultName() override
Definition: simpleskeleton.cpp:266
INDI::DefaultDevice::ISGetProperties
virtual void ISGetProperties(const char *dev)
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
Definition: defaultdevice.cpp:750
simpleSkeleton
std::unique_ptr< SimpleSkeleton > simpleSkeleton(new SimpleSkeleton())
_ISwitchVectorProperty::s
IPState s
Definition: indiapi.h:382
_ILightVectorProperty::lp
ILight * lp
Definition: indiapi.h:428
IUUpdateNumber
int IUUpdateNumber(INumberVectorProperty *nvp, double values[], char *names[], int n)
Update all numbers in a number vector property.
Definition: indidriver.c:225
_IBLOBVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:474
simpleskeleton.h
Construct a basic INDI CCD device that demonstrates ability to define properties from a skeleton file...
IUUpdateBLOB
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.
Definition: indidriver.c:285
ISState
ISState
Switch state.
Definition: indiapi.h:148
SimpleSkeleton
Definition: simpleskeleton.h:35
INDI::DefaultDevice::ISNewSwitch
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process the client newSwitch command.
Definition: defaultdevice.cpp:409
IUFindOnSwitchIndex
int IUFindOnSwitchIndex(const ISwitchVectorProperty *sp)
Returns the index of first ON switch it finds in the vector switch property.
Definition: indicom.c:1403
SimpleSkeleton::ISNewText
bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
Definition: simpleskeleton.cpp:106
IDSetNumber
void void void IDSetNumber(const INumberVectorProperty *n, const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(2
Tell client to update an existing number vector property.
IDSetSwitch
void void void void void IDSetSwitch(const ISwitchVectorProperty *s, const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(2
Tell client to update an existing switch vector property.
IBLOB
One Blob (Binary Large Object) descriptor.
INDI::BaseDevice::getLight
INDI::PropertyView< ILight > * getLight(const char *name) const
Definition: basedevice.cpp:114
SimpleSkeleton::ISNewBLOB
bool ISNewBLOB(const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n) override
Process the client newBLOB command.
Definition: simpleskeleton.cpp:206
_ISwitchVectorProperty
Switch vector property descriptor.
Definition: indiapi.h:365
_ISwitchVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:370